Changeset View
Changeset View
Standalone View
Standalone View
head/sys/mips/mips/trap.c
Show First 20 Lines • Show All 663 Lines • ▼ Show 20 Lines | #endif | ||||
case T_TLB_ST_MISS: | case T_TLB_ST_MISS: | ||||
ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ; | ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ; | ||||
/* check for kernel address */ | /* check for kernel address */ | ||||
if (KERNLAND(trapframe->badvaddr)) { | if (KERNLAND(trapframe->badvaddr)) { | ||||
vm_offset_t va; | vm_offset_t va; | ||||
int rv; | int rv; | ||||
kernel_fault: | kernel_fault: | ||||
va = trunc_page((vm_offset_t)trapframe->badvaddr); | va = (vm_offset_t)trapframe->badvaddr; | ||||
rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL); | rv = vm_fault_trap(kernel_map, va, ftype, | ||||
VM_FAULT_NORMAL, NULL, NULL); | |||||
if (rv == KERN_SUCCESS) | if (rv == KERN_SUCCESS) | ||||
return (trapframe->pc); | return (trapframe->pc); | ||||
if (td->td_pcb->pcb_onfault != NULL) { | if (td->td_pcb->pcb_onfault != NULL) { | ||||
pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; | pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; | ||||
td->td_pcb->pcb_onfault = NULL; | td->td_pcb->pcb_onfault = NULL; | ||||
return (pc); | return (pc); | ||||
} | } | ||||
goto err; | goto err; | ||||
Show All 18 Lines | dofault: | ||||
{ | { | ||||
vm_offset_t va; | vm_offset_t va; | ||||
struct vmspace *vm; | struct vmspace *vm; | ||||
vm_map_t map; | vm_map_t map; | ||||
int rv = 0; | int rv = 0; | ||||
vm = p->p_vmspace; | vm = p->p_vmspace; | ||||
map = &vm->vm_map; | map = &vm->vm_map; | ||||
va = trunc_page((vm_offset_t)trapframe->badvaddr); | va = (vm_offset_t)trapframe->badvaddr; | ||||
if (KERNLAND(trapframe->badvaddr)) { | if (KERNLAND(trapframe->badvaddr)) { | ||||
/* | /* | ||||
* Don't allow user-mode faults in kernel | * Don't allow user-mode faults in kernel | ||||
* address space. | * address space. | ||||
*/ | */ | ||||
goto nogo; | goto nogo; | ||||
} | } | ||||
rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); | rv = vm_fault_trap(map, va, ftype, VM_FAULT_NORMAL, | ||||
&i, &ucode); | |||||
/* | /* | ||||
* XXXDTRACE: add dtrace_doubletrap_func here? | * XXXDTRACE: add dtrace_doubletrap_func here? | ||||
*/ | */ | ||||
#ifdef VMFAULT_TRACE | #ifdef VMFAULT_TRACE | ||||
printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n", | printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n", | ||||
map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr, | map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr, | ||||
ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc); | ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc); | ||||
#endif | #endif | ||||
if (rv == KERN_SUCCESS) { | if (rv == KERN_SUCCESS) { | ||||
if (!usermode) { | if (!usermode) { | ||||
return (trapframe->pc); | return (trapframe->pc); | ||||
} | } | ||||
goto out; | goto out; | ||||
} | } | ||||
nogo: | nogo: | ||||
if (!usermode) { | if (!usermode) { | ||||
if (td->td_pcb->pcb_onfault != NULL) { | if (td->td_pcb->pcb_onfault != NULL) { | ||||
pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; | pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; | ||||
td->td_pcb->pcb_onfault = NULL; | td->td_pcb->pcb_onfault = NULL; | ||||
return (pc); | return (pc); | ||||
} | } | ||||
goto err; | goto err; | ||||
} | } | ||||
i = SIGSEGV; | |||||
if (rv == KERN_PROTECTION_FAILURE) | |||||
ucode = SEGV_ACCERR; | |||||
else | |||||
ucode = SEGV_MAPERR; | |||||
addr = trapframe->pc; | addr = trapframe->pc; | ||||
msg = "BAD_PAGE_FAULT"; | msg = "BAD_PAGE_FAULT"; | ||||
log_bad_page_fault(msg, trapframe, type); | log_bad_page_fault(msg, trapframe, type); | ||||
break; | break; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 956 Lines • Show Last 20 Lines |