Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/amd64/trap.c
Show First 20 Lines • Show All 588 Lines • ▼ Show 20 Lines | |||||
#ifdef KDTRACE_HOOKS | #ifdef KDTRACE_HOOKS | ||||
if (dtrace_trap_func != NULL && | if (dtrace_trap_func != NULL && | ||||
(*dtrace_trap_func)(frame, frame->tf_trapno) != 0) | (*dtrace_trap_func)(frame, frame->tf_trapno) != 0) | ||||
return; | return; | ||||
#endif | #endif | ||||
trap(frame); | trap(frame); | ||||
} | } | ||||
static bool | |||||
trap_is_smap(struct trapframe *frame) | |||||
{ | |||||
/* | |||||
* A page fault is classified as SMAP-induced if: | |||||
* - SMAP is supported; | |||||
* - kernel mode accessed present page; | |||||
* - rflags.AC was cleared. | |||||
*/ | |||||
return ((cpu_stdext_feature & CPUID_STDEXT_SMAP) != 0 && | |||||
(frame->tf_err & (PGEX_P | PGEX_U | PGEX_RSV)) == PGEX_P && | |||||
(frame->tf_rflags & PSL_AC) == 0); | |||||
} | |||||
static int | static int | ||||
trap_pfault(struct trapframe *frame, int usermode) | trap_pfault(struct trapframe *frame, int usermode) | ||||
{ | { | ||||
struct thread *td; | struct thread *td; | ||||
struct proc *p; | struct proc *p; | ||||
vm_map_t map; | vm_map_t map; | ||||
vm_offset_t va; | vm_offset_t va; | ||||
int rv; | int rv; | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | if (va >= VM_MIN_KERNEL_ADDRESS) { | ||||
map = &p->p_vmspace->vm_map; | map = &p->p_vmspace->vm_map; | ||||
/* | /* | ||||
* When accessing a usermode address, kernel must be | * When accessing a usermode address, kernel must be | ||||
* ready to accept the page fault, and provide a | * ready to accept the page fault, and provide a | ||||
* handling routine. Since accessing the address | * handling routine. Since accessing the address | ||||
* without the handler is a bug, do not try to handle | * without the handler is a bug, do not try to handle | ||||
* it normally, and panic immediately. | * it normally, and panic immediately. | ||||
* | |||||
* If SMAP is enabled, filter SMAP faults also, | |||||
* because illegal access might occur to the mapped | |||||
* user address, causing infinite loop. | |||||
*/ | */ | ||||
if (!usermode && (td->td_intr_nesting_level != 0 || | if (!usermode && (td->td_intr_nesting_level != 0 || | ||||
curpcb->pcb_onfault == NULL)) { | trap_is_smap(frame) || curpcb->pcb_onfault == NULL)) { | ||||
trap_fatal(frame, eva); | trap_fatal(frame, eva); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* If the trap was caused by errant bits in the PTE then panic. | * If the trap was caused by errant bits in the PTE then panic. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 263 Lines • Show Last 20 Lines |