Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/arm64/trap.c
Show First 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | svc_handler(struct thread *td, struct trapframe *frame) | ||||
} else { | } else { | ||||
call_trapsignal(td, SIGILL, ILL_ILLOPN, (void *)frame->tf_elr); | call_trapsignal(td, SIGILL, ILL_ILLOPN, (void *)frame->tf_elr); | ||||
userret(td, frame); | userret(td, frame); | ||||
} | } | ||||
} | } | ||||
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) | 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; | vm_offset_t va; | ||||
int error, sig, ucode; | int error, sig, ucode; | ||||
#ifdef KDB | #ifdef KDB | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | if (td->td_critnest != 0 || WITNESS_CHECK(WARN_SLEEPOK | | ||||
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); | va = trunc_page(far); | ||||
ftype = ((esr >> 6) & 1) ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_READ; | ftype = ((esr >> 6) & 1) ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_READ; | ||||
if (exec) | |||||
ftype |= VM_PROT_EXECUTE; | |||||
/* Fault in the page. */ | /* Fault in the page. */ | ||||
error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); | error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); | ||||
if (error != KERN_SUCCESS) { | if (error != KERN_SUCCESS) { | ||||
if (lower) { | if (lower) { | ||||
sig = SIGSEGV; | sig = SIGSEGV; | ||||
if (error == KERN_PROTECTION_FAILURE) | if (error == KERN_PROTECTION_FAILURE) | ||||
ucode = SEGV_ACCERR; | ucode = SEGV_ACCERR; | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | #endif | ||||
printf(" esr: %.8lx\n", esr); | printf(" esr: %.8lx\n", esr); | ||||
panic("VFP exception in the kernel"); | panic("VFP exception in the kernel"); | ||||
} | } | ||||
break; | break; | ||||
case EXCP_INSN_ABORT: | case EXCP_INSN_ABORT: | ||||
case EXCP_DATA_ABORT: | case EXCP_DATA_ABORT: | ||||
far = READ_SPECIALREG(far_el1); | far = READ_SPECIALREG(far_el1); | ||||
intr_enable(); | intr_enable(); | ||||
data_abort(td, frame, esr, far, 0); | data_abort(td, frame, esr, far, 0, | ||||
exception == EXCP_INSN_ABORT); | |||||
break; | break; | ||||
case EXCP_BRK: | case EXCP_BRK: | ||||
#ifdef KDTRACE_HOOKS | #ifdef KDTRACE_HOOKS | ||||
if ((esr & ESR_ELx_ISS_MASK) == 0x40d && \ | if ((esr & ESR_ELx_ISS_MASK) == 0x40d && \ | ||||
dtrace_invop_jump_addr != 0) { | dtrace_invop_jump_addr != 0) { | ||||
dtrace_invop_jump_addr(frame); | dtrace_invop_jump_addr(frame); | ||||
break; | break; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | #endif | ||||
break; | break; | ||||
case EXCP_SVC32: | case EXCP_SVC32: | ||||
case EXCP_SVC64: | case EXCP_SVC64: | ||||
svc_handler(td, frame); | svc_handler(td, frame); | ||||
break; | break; | ||||
case EXCP_INSN_ABORT_L: | case EXCP_INSN_ABORT_L: | ||||
case EXCP_DATA_ABORT_L: | case EXCP_DATA_ABORT_L: | ||||
case EXCP_DATA_ABORT: | case EXCP_DATA_ABORT: | ||||
data_abort(td, frame, esr, far, 1); | data_abort(td, frame, esr, far, 1, | ||||
exception == EXCP_INSN_ABORT_L); | |||||
break; | break; | ||||
case EXCP_UNKNOWN: | case EXCP_UNKNOWN: | ||||
if (!undef_insn(0, frame)) | if (!undef_insn(0, frame)) | ||||
call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far); | call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far); | ||||
userret(td, frame); | userret(td, frame); | ||||
break; | break; | ||||
case EXCP_SP_ALIGN: | case EXCP_SP_ALIGN: | ||||
call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_sp); | call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_sp); | ||||
▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines |