Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/arm64/trap.c
Show First 20 Lines • Show All 149 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
data_abort(struct thread *td, struct trapframe *frame, uint64_t esr, | data_abort(struct thread *td, struct trapframe *frame, uint64_t esr, | ||||
uint64_t far, int lower, int exec) | uint64_t far, int lower, int exec) | ||||
{ | { | ||||
struct vm_map *map; | struct vm_map *map; | ||||
struct proc *p; | struct proc *p; | ||||
struct pcb *pcb; | struct pcb *pcb; | ||||
vm_prot_t ftype; | vm_prot_t ftype; | ||||
vm_offset_t va; | |||||
int error, sig, ucode; | int error, sig, ucode; | ||||
#ifdef KDB | #ifdef KDB | ||||
bool handled; | bool handled; | ||||
#endif | #endif | ||||
/* | /* | ||||
* According to the ARMv8-A rev. A.g, B2.10.5 "Load-Exclusive | * According to the ARMv8-A rev. A.g, B2.10.5 "Load-Exclusive | ||||
* and Store-Exclusive instruction usage restrictions", state | * and Store-Exclusive instruction usage restrictions", state | ||||
Show All 39 Lines | #endif | ||||
if (td->td_critnest != 0 || WITNESS_CHECK(WARN_SLEEPOK | | if (td->td_critnest != 0 || WITNESS_CHECK(WARN_SLEEPOK | | ||||
WARN_GIANTOK, NULL, "Kernel page fault") != 0) { | WARN_GIANTOK, NULL, "Kernel page fault") != 0) { | ||||
print_registers(frame); | print_registers(frame); | ||||
printf(" far: %16lx\n", far); | printf(" far: %16lx\n", far); | ||||
printf(" esr: %.8lx\n", esr); | printf(" esr: %.8lx\n", esr); | ||||
panic("data abort in critical section or under mutex"); | panic("data abort in critical section or under mutex"); | ||||
} | } | ||||
va = trunc_page(far); | |||||
if (exec) | if (exec) | ||||
ftype = VM_PROT_EXECUTE; | ftype = VM_PROT_EXECUTE; | ||||
else | else | ||||
ftype = (esr & ISS_DATA_WnR) == 0 ? VM_PROT_READ : | ftype = (esr & ISS_DATA_WnR) == 0 ? VM_PROT_READ : | ||||
VM_PROT_READ | VM_PROT_WRITE; | VM_PROT_READ | VM_PROT_WRITE; | ||||
/* Fault in the page. */ | /* Fault in the page. */ | ||||
error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); | error = vm_fault_trap(map, far, ftype, VM_FAULT_NORMAL, &sig, &ucode); | ||||
if (error != KERN_SUCCESS) { | if (error != KERN_SUCCESS) { | ||||
if (lower) { | if (lower) { | ||||
sig = SIGSEGV; | |||||
if (error == KERN_PROTECTION_FAILURE) | |||||
ucode = SEGV_ACCERR; | |||||
else | |||||
ucode = SEGV_MAPERR; | |||||
call_trapsignal(td, sig, ucode, (void *)far); | call_trapsignal(td, sig, ucode, (void *)far); | ||||
} else { | } else { | ||||
if (td->td_intr_nesting_level == 0 && | if (td->td_intr_nesting_level == 0 && | ||||
pcb->pcb_onfault != 0) { | pcb->pcb_onfault != 0) { | ||||
frame->tf_x[0] = error; | frame->tf_x[0] = error; | ||||
frame->tf_elr = pcb->pcb_onfault; | frame->tf_elr = pcb->pcb_onfault; | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 263 Lines • Show Last 20 Lines |