nes-proj/drivers/cpu/x86/mm/syscalls-int-asm.S

134 lines
4.3 KiB
ArmAsm

/*
* Copyright (C) 2015, Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "syscalls-int.h"
#include "prot-domains.h"
#include "gdt-layout.h"
#include "stacks.h"
/* Must match definitions (plus the trailing 's') in multi-segment.h */
#define SEG_MMIO fs
#define SEG_KERN fs
.text
/* Invoke the system call return dispatcher from the default privilege
* level
*/
.global prot_domains_sysret_stub
prot_domains_sysret_stub:
int $PROT_DOMAINS_SYSRET_DISPATCH_INT
.macro save_segs
#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG
/* Save (and restore, in restore_segs) MMIO segment register into
* callee-saved register in case a system call was invoked from a region in
* which MMIO is enabled.
*/
push %SEG_MMIO
#endif
.endm
.macro restore_segs
#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG
pop %SEG_MMIO
#endif
.endm
/* Refresh most of the segment registers in case they were corrupted by
* userspace code to prevent that from corrupting the operation of the
* privileged code.
*/
.macro load_kern_segs
#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG
mov $GDT_SEL_DATA, %eax
mov %eax, %ds
mov %eax, %es
mov $GDT_SEL_DATA_KERN_EXC, %eax
mov %eax, %SEG_KERN
#endif
.endm
/* Invoke the system call dispatcher C routine */
.global prot_domains_syscall_dispatcher
prot_domains_syscall_dispatcher:
mov %esp, %ecx /*< interrupt_stack_t *intr_stk */
/* EDX already set to "dom_client_data_t to_dcd" by syscall stub */
save_segs
push %eax /*< syscalls_entrypoint_t *syscall */
load_kern_segs
call prot_domains_syscall_dispatcher_impl
/* fastcall convention, so callee pops arguments */
restore_segs
iret
/* Invoke the system call return dispatcher C routine */
.global prot_domains_sysret_dispatcher
prot_domains_sysret_dispatcher:
mov %esp, %ecx /*< interrupt_stack_t *intr_stk */
save_segs
load_kern_segs
call prot_domains_sysret_dispatcher_impl
restore_segs
/* Zero caller-saved registers in case they contain secrets. The system call
* handlers and dispatchers need to preserve the callee-saved registers.
*/
xor %eax, %eax
xor %ecx, %ecx
xor %edx, %edx
iret
.global prot_domains_launch_kernel
prot_domains_launch_kernel:
#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING
mov $GDT_SEL_DATA, %eax
mov %eax, %ds
mov %eax, %es
mov %eax, %fs
mov %eax, %gs
#else
mov $GDT_SEL_LDT(DOM_ID_kern), %eax
lldt %ax
call multi_segment_launch_kernel
#endif
/* init interrupt return stack: */
pushl $GDT_SEL_STK
lea stacks_main, %eax
/* matches STACKS_INIT_TOP, plus 4 since an address has been consumed: */
add $(STACKS_SIZE_MAIN - 4), %eax
pushl %eax
pushl $EFLAGS_IOPL(PRIV_LVL_INT)
pushl $GDT_SEL_CODE
pushl $0 /* will be overwritten by syscall_dispatcher_impl */
/* fastcall convention: */
mov %esp, %ecx
call prot_domains_launch_kernel_impl
iretl