- mov R64_R14(%r15), %r14
- mov R64_R13(%r15), %r13
- mov R64_R12(%r15), %r12
- mov R64_R11(%r15), %r11
- mov R64_R10(%r15), %r10
- mov R64_R9(%r15), %r9
- mov R64_R8(%r15), %r8
- mov R64_RSI(%r15), %rsi
- mov R64_RDI(%r15), %rdi
- mov R64_RBP(%r15), %rbp
- mov R64_RDX(%r15), %rdx
- mov R64_RCX(%r15), %rcx
- mov R64_RBX(%r15), %rbx
- mov R64_RAX(%r15), %rax
-
- /*
- * We must swap GS base if we're returning to user-space,
- * or we're returning from an NMI that occurred in a trampoline
- * before the user GS had been swapped. In the latter case, the NMI
- * handler will have flagged the high-order 32-bits of the CS.
- */
- cmpq $(KERNEL64_CS), R64_CS(%r15)
- jz 1f
- swapgs
-1:
- mov R64_R15(%r15), %rsp
- xchg %r15, %rsp
- add $(ISS64_OFFSET)+24, %rsp /* pop saved state */
- /* + trapno/trapfn/error */
- cmpl $(SYSCALL_CS),ISF64_CS-24(%rsp)
- /* test for fast entry/exit */
- je L_sysret
-.globl _dump_iretq
-EXT(ret64_iret):
- iretq /* return from interrupt */
-
-L_sysret:
- /*
- * Here to load rcx/r11/rsp and perform the sysret back to user-space.
- * rcx user rip
- * r11 user rflags
- * rsp user stack pointer
- */
- mov ISF64_RIP-24(%rsp), %rcx
- mov ISF64_RFLAGS-24(%rsp), %r11
- mov ISF64_RSP-24(%rsp), %rsp
- sysretq /* return from systen call */
-
-
-
-/*
- * System call handlers.
- * These are entered via a syscall interrupt. The system call number in %rax
- * is saved to the error code slot in the stack frame. We then branch to the
- * common state saving code.
- */
-
-#ifndef UNIX_INT
-#error NO UNIX INT!!!
-#endif
-Entry(idt64_unix_scall)
- swapgs /* switch to kernel gs (cpu_data) */
- pushq %rax /* save system call number */
- PUSH_FUNCTION(HNDL_UNIX_SCALL)
- pushq $(UNIX_INT)
- jmp L_32bit_entry_check
-
-
-Entry(idt64_mach_scall)
- swapgs /* switch to kernel gs (cpu_data) */
- pushq %rax /* save system call number */
- PUSH_FUNCTION(HNDL_MACH_SCALL)
- pushq $(MACH_INT)
- jmp L_32bit_entry_check
-
-
-Entry(idt64_mdep_scall)
- swapgs /* switch to kernel gs (cpu_data) */
- pushq %rax /* save system call number */
- PUSH_FUNCTION(HNDL_MDEP_SCALL)
- pushq $(MACHDEP_INT)
- jmp L_32bit_entry_check
-
-/* Programmed into MSR_IA32_LSTAR by mp_desc.c */
-Entry(hi64_syscall)
-Entry(idt64_syscall)
-L_syscall_continue:
- swapgs /* Kapow! get per-cpu data area */
- mov %rsp, %gs:CPU_UBER_TMP /* save user stack */
- mov %gs:CPU_UBER_ISF, %rsp /* switch stack to pcb */
-
- /*
- * Save values in the ISF frame in the PCB
- * to cons up the saved machine state.
- */
- movl $(USER_DS), ISF64_SS(%rsp)
- movl $(SYSCALL_CS), ISF64_CS(%rsp) /* cs - a pseudo-segment */
- mov %r11, ISF64_RFLAGS(%rsp) /* rflags */
- mov %rcx, ISF64_RIP(%rsp) /* rip */
- mov %gs:CPU_UBER_TMP, %rcx
- mov %rcx, ISF64_RSP(%rsp) /* user stack */
- mov %rax, ISF64_ERR(%rsp) /* err/rax - syscall code */
- movq $(T_SYSCALL), ISF64_TRAPNO(%rsp) /* trapno */
- leaq HNDL_SYSCALL(%rip), %r11;
- movq %r11, ISF64_TRAPFN(%rsp)
- mov ISF64_RFLAGS(%rsp), %r11 /* Avoid leak, restore R11 */
- jmp L_dispatch_U64 /* this can only be 64-bit */
-
-/*
- * sysenter entry point
- * Requires user code to set up:
- * edx: user instruction pointer (return address)
- * ecx: user stack pointer
- * on which is pushed stub ret addr and saved ebx
- * Return to user-space is made using sysexit.
- * Note: sysenter/sysexit cannot be used for calls returning a value in edx,
- * or requiring ecx to be preserved.
- */
-Entry(hi64_sysenter)
-Entry(idt64_sysenter)
- movq (%rsp), %rsp
- /*
- * Push values on to the PCB stack
- * to cons up the saved machine state.
- */
- push $(USER_DS) /* ss */
- push %rcx /* uesp */
- pushf /* flags */
- /*
- * Clear, among others, the Nested Task (NT) flags bit;
- * this is zeroed by INT, but not by SYSENTER.
- */
- push $0
- popf
- push $(SYSENTER_CS) /* cs */
-L_sysenter_continue:
- swapgs /* switch to kernel gs (cpu_data) */
- push %rdx /* eip */
- push %rax /* err/eax - syscall code */
- PUSH_FUNCTION(HNDL_SYSENTER)
- pushq $(T_SYSENTER)
- orl $(EFL_IF), ISF64_RFLAGS(%rsp)
- jmp L_32bit_entry_check
-
-
-Entry(idt64_page_fault)
- PUSH_FUNCTION(HNDL_ALLTRAPS)
- push $(T_PAGE_FAULT)
- push %rax /* save %rax temporarily */
- testb $3, 8+ISF64_CS(%rsp) /* was trap from kernel? */
- jz L_kernel_trap /* - yes, handle with care */
- pop %rax /* restore %rax, swapgs, and continue */
- swapgs
- jmp L_dispatch_user
-
-
-/*
- * Debug trap. Check for single-stepping across system call into
- * kernel. If this is the case, taking the debug trap has turned
- * off single-stepping - save the flags register with the trace
- * bit set.
- */
-Entry(idt64_debug)
- push $0 /* error code */
- PUSH_FUNCTION(HNDL_ALLTRAPS)
- pushq $(T_DEBUG)
-
- testb $3, ISF64_CS(%rsp)
- jnz L_dispatch