+Entry(idt64_page_fault)
+ pushq $(HNDL_ALLTRAPS)
+ push $(T_PAGE_FAULT)
+ jmp L_dispatch
+
+Entry(idt64_debug)
+ push $0 /* error code */
+ pushq $(HNDL_ALLTRAPS)
+ pushq $(T_DEBUG)
+ jmp L_dispatch
+/*
+ * Legacy interrupt gate 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)
+ pushq %rax /* save system call number */
+ pushq $(HNDL_UNIX_SCALL)
+ pushq $(UNIX_INT)
+ jmp L_dispatch
+
+Entry(idt64_mach_scall)
+ pushq %rax /* save system call number */
+ pushq $(HNDL_MACH_SCALL)
+ pushq $(MACH_INT)
+ jmp L_dispatch
+
+Entry(idt64_mdep_scall)
+ pushq %rax /* save system call number */
+ pushq $(HNDL_MDEP_SCALL)
+ pushq $(MACHDEP_INT)
+ jmp L_dispatch
+
+/*
+ * For GP/NP/SS faults, we use the IST1 stack.
+ * For faults from user-space, we have to copy the machine state to the
+ * PCB stack and then dispatch as normal.
+ * For faults in kernel-space, we need to scrub for kernel exit faults and
+ * treat these as user-space faults. But for all other kernel-space faults
+ * we continue to run on the IST1 stack and we dispatch to handle the fault
+ * as fatal.
+ */
+Entry(idt64_gen_prot)
+ pushq $(HNDL_ALLTRAPS)
+ pushq $(T_GENERAL_PROTECTION)
+ jmp L_dispatch
+
+Entry(idt64_stack_fault)
+ pushq $(HNDL_ALLTRAPS)
+ pushq $(T_STACK_FAULT)
+ jmp L_dispatch
+
+Entry(idt64_segnp)
+ pushq $(HNDL_ALLTRAPS)
+ pushq $(T_SEGMENT_NOT_PRESENT)
+ jmp L_dispatch
+
+/*
+ * Fatal exception handlers:
+ */
+Entry(idt64_db_task_dbl_fault)
+ pushq $(HNDL_DOUBLE_FAULT)
+ pushq $(T_DOUBLE_FAULT)
+ jmp L_dispatch
+
+Entry(idt64_db_task_stk_fault)
+ pushq $(HNDL_DOUBLE_FAULT)
+ pushq $(T_STACK_FAULT)
+ jmp L_dispatch
+
+Entry(idt64_mc)
+ push $(0) /* Error */
+ pushq $(HNDL_MACHINE_CHECK)
+ pushq $(T_MACHINE_CHECK)
+ jmp L_dispatch
+
+/*
+ * NMI
+ * This may or may not be fatal but extreme care is required
+ * because it may fall when control was already in another trampoline.
+ *
+ * We get here on IST2 stack which is used for NMIs only.
+ */
+Entry(idt64_nmi)
+ push %rax /* save RAX to ISF64_ERR */
+ push %rcx /* save RCX to ISF64_TRAPFN */
+ push %rdx /* save RDX to ISF64_TRAPNO */
+ jmp L_dispatch
+
+Entry(idt64_double_fault)
+ pushq $(HNDL_DOUBLE_FAULT)
+ pushq $(T_DOUBLE_FAULT)
+ jmp L_dispatch
+
+Entry(hi64_syscall)
+Entry(idt64_syscall)
+ swapgs
+ /* Use RAX as a temporary by shifting its contents into R11[32:63]
+ * The systemcall number is defined to be a 32-bit quantity, as is
+ * RFLAGS.
+ */
+ shlq $32, %rax
+ or %rax, %r11
+.globl EXT(dblsyscall_patch_point)
+EXT(dblsyscall_patch_point):
+// movabsq $0x12345678ABCDEFFFULL, %rax
+ /* Generate offset to the double-mapped per-CPU data shadow
+ * into RAX
+ */
+ leaq EXT(idt64_hndl_table0)(%rip), %rax
+ mov 16(%rax), %rax
+ mov %rsp, %gs:CPU_UBER_TMP(%rax) /* save user stack */
+ mov %gs:CPU_ESTACK(%rax), %rsp /* switch stack to per-cpu estack */
+ sub $(ISF64_SIZE), %rsp
+
+ /*
+ * Synthesize an ISF frame on the exception stack
+ */
+ movl $(USER_DS), ISF64_SS(%rsp)
+ mov %rcx, ISF64_RIP(%rsp) /* rip */
+
+ mov %gs:CPU_UBER_TMP(%rax), %rcx
+ mov %rcx, ISF64_RSP(%rsp) /* user stack --changed */
+
+ mov %r11, %rax
+ shrq $32, %rax /* Restore RAX */
+ mov %r11d, %r11d /* Clear r11[32:63] */
+
+ mov %r11, ISF64_RFLAGS(%rsp) /* rflags */
+ movl $(SYSCALL_CS), ISF64_CS(%rsp) /* cs - a pseudo-segment */
+ mov %rax, ISF64_ERR(%rsp) /* err/rax - syscall code */
+ movq $(HNDL_SYSCALL), ISF64_TRAPFN(%rsp)
+ movq $(T_SYSCALL), ISF64_TRAPNO(%rsp) /* trapno */
+ swapgs
+ jmp L_dispatch /* this can only be 64-bit */
+
+Entry(hi64_sysenter)
+Entry(idt64_sysenter)
+ /* Synthesize an interrupt stack frame onto the
+ * exception stack.
+ */
+ 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:
+ push %rdx /* eip */
+ push %rax /* err/eax - syscall code */
+ pushq $(HNDL_SYSENTER)
+ pushq $(T_SYSENTER)
+ orl $(EFL_IF), ISF64_RFLAGS(%rsp)
+ jmp L_dispatch
+