Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/amd64/exception.S
Show First 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | X\l: | ||||
.endm | .endm | ||||
TRAP div, T_DIVIDE | TRAP div, T_DIVIDE | ||||
TRAP ofl, T_OFLOW | TRAP ofl, T_OFLOW | ||||
TRAP bnd, T_BOUND | TRAP bnd, T_BOUND | ||||
TRAP ill, T_PRIVINFLT | TRAP ill, T_PRIVINFLT | ||||
TRAP dna, T_DNA | TRAP dna, T_DNA | ||||
TRAP fpusegm, T_FPOPFLT | TRAP fpusegm, T_FPOPFLT | ||||
TRAP mchk, T_MCHK | |||||
TRAP rsvd, T_RESERVED | TRAP rsvd, T_RESERVED | ||||
TRAP fpu, T_ARITHTRAP | TRAP fpu, T_ARITHTRAP | ||||
TRAP xmm, T_XMMFLT | TRAP xmm, T_XMMFLT | ||||
/* This group of traps have tf_err already pushed by the cpu. */ | /* This group of traps have tf_err already pushed by the cpu. */ | ||||
.macro TRAP_ERR l, trapno | .macro TRAP_ERR l, trapno | ||||
PTI_ENTRY \l,X\l,has_err=1 | PTI_ENTRY \l,X\l,has_err=1 | ||||
.globl X\l | .globl X\l | ||||
▲ Show 20 Lines • Show All 505 Lines • ▼ Show 20 Lines | outofnmi: | ||||
movq PCPU(CURTHREAD),%rdi /* thread */ | movq PCPU(CURTHREAD),%rdi /* thread */ | ||||
movq $PMC_FN_USER_CALLCHAIN,%rsi /* command */ | movq $PMC_FN_USER_CALLCHAIN,%rsi /* command */ | ||||
movq %rsp,%rdx /* frame */ | movq %rsp,%rdx /* frame */ | ||||
sti | sti | ||||
call *%rax | call *%rax | ||||
cli | cli | ||||
nocallchain: | nocallchain: | ||||
#endif | #endif | ||||
testl %ebx,%ebx /* %ebx == 0 => return to userland */ | |||||
jnz doreti_exit | |||||
/* | |||||
* Put back the preserved MSR_GSBASE value. | |||||
*/ | |||||
movl $MSR_GSBASE,%ecx | |||||
movq %r12,%rdx | |||||
movl %edx,%eax | |||||
shrq $32,%rdx | |||||
wrmsr | |||||
movq %r13,%cr3 | |||||
RESTORE_REGS | |||||
addq $TF_RIP,%rsp | |||||
jmp doreti_iret | |||||
/* | |||||
* MC# handling is similar to NMI. | |||||
* | |||||
* As with NMIs, machine check exceptions do not respect RFLAGS.IF and | |||||
* can occur at any time with a GS.base value that does not correspond | |||||
* to the privilege level in CS. | |||||
* | |||||
* Machine checks are not unblocked by iretq, but it is best to run | |||||
* the handler with interrupts disabled since the exception may have | |||||
* interrupted a critical section. | |||||
* | |||||
* The MC# handler runs on its own stack (tss_ist3). The canonical | |||||
* GS.base value for the processor is stored just above the bottom of | |||||
* its MC# stack. For exceptions taken from kernel mode, the current | |||||
* value in the processor's GS.base is saved at entry to C-preserved | |||||
* register %r12, the canonical value for GS.base is then loaded into | |||||
* the processor, and the saved value is restored at exit time. For | |||||
* exceptions taken from user mode, the cheaper 'SWAPGS' instructions | |||||
* are used for swapping GS.base. | |||||
*/ | |||||
IDTVEC(mchk) | |||||
subq $TF_RIP,%rsp | |||||
movl $(T_MCHK),TF_TRAPNO(%rsp) | |||||
movq $0,TF_ADDR(%rsp) | |||||
movq $0,TF_ERR(%rsp) | |||||
movq %rdi,TF_RDI(%rsp) | |||||
movq %rsi,TF_RSI(%rsp) | |||||
movq %rdx,TF_RDX(%rsp) | |||||
movq %rcx,TF_RCX(%rsp) | |||||
movq %r8,TF_R8(%rsp) | |||||
movq %r9,TF_R9(%rsp) | |||||
movq %rax,TF_RAX(%rsp) | |||||
movq %rbx,TF_RBX(%rsp) | |||||
movq %rbp,TF_RBP(%rsp) | |||||
movq %r10,TF_R10(%rsp) | |||||
movq %r11,TF_R11(%rsp) | |||||
movq %r12,TF_R12(%rsp) | |||||
movq %r13,TF_R13(%rsp) | |||||
movq %r14,TF_R14(%rsp) | |||||
movq %r15,TF_R15(%rsp) | |||||
SAVE_SEGS | |||||
movl $TF_HASSEGS,TF_FLAGS(%rsp) | |||||
cld | |||||
xorl %ebx,%ebx | |||||
testb $SEL_RPL_MASK,TF_CS(%rsp) | |||||
jnz mchk_fromuserspace | |||||
/* | |||||
* We've interrupted the kernel. Preserve GS.base in %r12 | |||||
* and %cr3 in %r13. | |||||
*/ | |||||
movl $MSR_GSBASE,%ecx | |||||
rdmsr | |||||
movq %rax,%r12 | |||||
shlq $32,%rdx | |||||
orq %rdx,%r12 | |||||
/* Retrieve and load the canonical value for GS.base. */ | |||||
movq TF_SIZE(%rsp),%rdx | |||||
movl %edx,%eax | |||||
shrq $32,%rdx | |||||
wrmsr | |||||
movq %cr3,%r13 | |||||
movq PCPU(KCR3),%rax | |||||
cmpq $~0,%rax | |||||
je mchk_calltrap | |||||
movq %rax,%cr3 | |||||
jmp mchk_calltrap | |||||
mchk_fromuserspace: | |||||
incl %ebx | |||||
swapgs | |||||
movq %cr3,%r13 | |||||
movq PCPU(KCR3),%rax | |||||
cmpq $~0,%rax | |||||
je 1f | |||||
movq %rax,%cr3 | |||||
1: | |||||
/* Note: this label is also used by ddb and gdb: */ | |||||
mchk_calltrap: | |||||
FAKE_MCOUNT(TF_RIP(%rsp)) | |||||
movq %rsp,%rdi | |||||
call mca_intr | |||||
MEXITCOUNT | |||||
testl %ebx,%ebx /* %ebx == 0 => return to userland */ | testl %ebx,%ebx /* %ebx == 0 => return to userland */ | ||||
jnz doreti_exit | jnz doreti_exit | ||||
/* | /* | ||||
* Put back the preserved MSR_GSBASE value. | * Put back the preserved MSR_GSBASE value. | ||||
*/ | */ | ||||
movl $MSR_GSBASE,%ecx | movl $MSR_GSBASE,%ecx | ||||
movq %r12,%rdx | movq %r12,%rdx | ||||
movl %edx,%eax | movl %edx,%eax | ||||
▲ Show 20 Lines • Show All 339 Lines • Show Last 20 Lines |