Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/powerpc/trap.c
Show First 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
#define FAULTBUF_R14 3 | #define FAULTBUF_R14 3 | ||||
#define MOREARGS(sp) ((caddr_t)((uintptr_t)(sp) + \ | #define MOREARGS(sp) ((caddr_t)((uintptr_t)(sp) + \ | ||||
sizeof(struct callframe) - 3*sizeof(register_t))) /* more args go here */ | sizeof(struct callframe) - 3*sizeof(register_t))) /* more args go here */ | ||||
static void trap_fatal(struct trapframe *frame); | static void trap_fatal(struct trapframe *frame); | ||||
static void printtrap(u_int vector, struct trapframe *frame, int isfatal, | static void printtrap(u_int vector, struct trapframe *frame, int isfatal, | ||||
int user); | int user); | ||||
static int trap_pfault(struct trapframe *frame, int user); | static bool trap_pfault(struct trapframe *frame, int user, int *signo, | ||||
int *ucode); | |||||
static int fix_unaligned(struct thread *td, struct trapframe *frame); | static int fix_unaligned(struct thread *td, struct trapframe *frame); | ||||
alc: Consider changing "user" into a "bool". | |||||
static int handle_onfault(struct trapframe *frame); | static int handle_onfault(struct trapframe *frame); | ||||
static void syscall(struct trapframe *frame); | static void syscall(struct trapframe *frame); | ||||
#if defined(__powerpc64__) && defined(AIM) | #if defined(__powerpc64__) && defined(AIM) | ||||
static void normalize_inputs(void); | static void normalize_inputs(void); | ||||
#endif | #endif | ||||
extern vm_offset_t __startkernel; | extern vm_offset_t __startkernel; | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | case EXC_DSE: | ||||
(type == EXC_ISE) ? frame->srr0 : frame->dar) != 0){ | (type == EXC_ISE) ? frame->srr0 : frame->dar) != 0){ | ||||
sig = SIGSEGV; | sig = SIGSEGV; | ||||
ucode = SEGV_MAPERR; | ucode = SEGV_MAPERR; | ||||
} | } | ||||
break; | break; | ||||
#endif | #endif | ||||
case EXC_DSI: | case EXC_DSI: | ||||
case EXC_ISI: | case EXC_ISI: | ||||
sig = trap_pfault(frame, 1); | if (trap_pfault(frame, 1, &sig, &ucode)) | ||||
if (sig == SIGSEGV) | sig = 0; | ||||
ucode = SEGV_MAPERR; | |||||
break; | break; | ||||
case EXC_SC: | case EXC_SC: | ||||
syscall(frame); | syscall(frame); | ||||
break; | break; | ||||
case EXC_FPU: | case EXC_FPU: | ||||
KASSERT((td->td_pcb->pcb_flags & PCB_FPU) != PCB_FPU, | KASSERT((td->td_pcb->pcb_flags & PCB_FPU) != PCB_FPU, | ||||
▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | case EXC_DSE: | ||||
__asm __volatile ("slbmte %0, %1" :: | __asm __volatile ("slbmte %0, %1" :: | ||||
"r"(td->td_pcb->pcb_cpu.aim.usr_vsid), | "r"(td->td_pcb->pcb_cpu.aim.usr_vsid), | ||||
"r"(USER_SLB_SLBE)); | "r"(USER_SLB_SLBE)); | ||||
return; | return; | ||||
} | } | ||||
break; | break; | ||||
#endif | #endif | ||||
case EXC_DSI: | case EXC_DSI: | ||||
if (trap_pfault(frame, 0) == 0) | if (trap_pfault(frame, 0, &sig, &ucode)) | ||||
Done Inline ActionsWhy pass &sig and &ucode in this case? They don't appear to be used after the call. alc: Why pass &sig and &ucode in this case? They don't appear to be used after the call. | |||||
return; | return; | ||||
break; | break; | ||||
case EXC_MCHK: | case EXC_MCHK: | ||||
if (handle_onfault(frame)) | if (handle_onfault(frame)) | ||||
return; | return; | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Lines | __asm __volatile ("slbmte %0, %1; isync" :: | ||||
"r"(td->td_pcb->pcb_cpu.aim.usr_vsid), "r"(USER_SLB_SLBE)); | "r"(td->td_pcb->pcb_cpu.aim.usr_vsid), "r"(USER_SLB_SLBE)); | ||||
#endif | #endif | ||||
syscallenter(td); | syscallenter(td); | ||||
syscallret(td); | syscallret(td); | ||||
} | } | ||||
static int | static int | ||||
trap_pfault(struct trapframe *frame, int user) | trap_pfault(struct trapframe *frame, int user, int *signo, int *ucode) | ||||
{ | { | ||||
vm_offset_t eva, va; | vm_offset_t eva, va; | ||||
struct thread *td; | struct thread *td; | ||||
struct proc *p; | struct proc *p; | ||||
vm_map_t map; | vm_map_t map; | ||||
vm_prot_t ftype; | vm_prot_t ftype; | ||||
int rv, is_user; | int rv, is_user; | ||||
Show All 16 Lines | else | ||||
ftype = VM_PROT_READ; | ftype = VM_PROT_READ; | ||||
} | } | ||||
if (user) { | if (user) { | ||||
KASSERT(p->p_vmspace != NULL, ("trap_pfault: vmspace NULL")); | KASSERT(p->p_vmspace != NULL, ("trap_pfault: vmspace NULL")); | ||||
map = &p->p_vmspace->vm_map; | map = &p->p_vmspace->vm_map; | ||||
} else { | } else { | ||||
rv = pmap_decode_kernel_ptr(eva, &is_user, &eva); | rv = pmap_decode_kernel_ptr(eva, &is_user, &eva); | ||||
if (rv != 0) | if (rv != 0) { | ||||
return (SIGSEGV); | *signo = SIGSEGV; | ||||
*ucode = SEGV_ACCERR; | |||||
Done Inline ActionsI don't see why we need to do this. alc: I don't see why we need to do this. | |||||
return (false); | |||||
} | |||||
if (is_user) | if (is_user) | ||||
map = &p->p_vmspace->vm_map; | map = &p->p_vmspace->vm_map; | ||||
else | else | ||||
map = kernel_map; | map = kernel_map; | ||||
} | } | ||||
va = trunc_page(eva); | va = trunc_page(eva); | ||||
Done Inline ActionsAnother redundant trunc_page() alc: Another redundant trunc_page() | |||||
/* Fault in the page. */ | /* Fault in the page. */ | ||||
rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); | rv = vm_fault_trap(map, va, ftype, VM_FAULT_NORMAL, signo, ucode); | ||||
/* | /* | ||||
* XXXDTRACE: add dtrace_doubletrap_func here? | * XXXDTRACE: add dtrace_doubletrap_func here? | ||||
*/ | */ | ||||
if (rv == KERN_SUCCESS) | if (rv == KERN_SUCCESS) | ||||
return (0); | return (true); | ||||
if (!user && handle_onfault(frame)) | if (!user && handle_onfault(frame)) | ||||
return (0); | return (true); | ||||
return (SIGSEGV); | return (false); | ||||
} | } | ||||
/* | /* | ||||
* For now, this only deals with the particular unaligned access case | * For now, this only deals with the particular unaligned access case | ||||
* that gcc tends to generate. Eventually it should handle all of the | * that gcc tends to generate. Eventually it should handle all of the | ||||
* possibilities that can happen on a 32-bit PowerPC in big-endian mode. | * possibilities that can happen on a 32-bit PowerPC in big-endian mode. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 161 Lines • Show Last 20 Lines |
Consider changing "user" into a "bool".