summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/powerpc64/powerpc64/trap.c89
1 files changed, 79 insertions, 10 deletions
diff --git a/sys/arch/powerpc64/powerpc64/trap.c b/sys/arch/powerpc64/powerpc64/trap.c
index 73b91ce747d..ca37568ca92 100644
--- a/sys/arch/powerpc64/powerpc64/trap.c
+++ b/sys/arch/powerpc64/powerpc64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.15 2020/06/27 15:04:49 kettenis Exp $ */
+/* $OpenBSD: trap.c,v 1.16 2020/06/27 20:44:49 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -18,6 +18,7 @@
#include <sys/param.h>
#include <sys/proc.h>
+#include <sys/signalvar.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <sys/syscall_mi.h>
@@ -42,12 +43,13 @@ trap(struct trapframe *frame)
struct cpu_info *ci = curcpu();
struct proc *p = curproc;
int type = frame->exc;
+ union sigval sv;
struct vm_map *map;
struct slb_desc *slbd;
pmap_t pm;
vaddr_t va;
int ftype;
- int error;
+ int error, sig, code;
/* Disable access to floating-point and vector registers. */
mtmsr(mfmsr() & ~(PSL_FP|PSL_VEC|PSL_VSX));
@@ -127,7 +129,6 @@ trap(struct trapframe *frame)
/* FALLTHROUGH */
case EXC_DSI|EXC_USER:
-// printf("proc %p type %x dar 0x%lx dsisr 0x%lx\n", p, type, frame->dar, frame->dsisr);
map = &p->p_vmspace->vm_map;
va = frame->dar;
if (frame->dsisr & DSISR_STORE)
@@ -140,8 +141,30 @@ trap(struct trapframe *frame)
if (error) {
printf("type %x dar 0x%lx dsisr 0x%lx\n",
type, frame->dar, frame->dsisr);
- printf("r29 0x%lx\n", frame->fixreg[29]);
- goto fatal;
+ for (int i = 0; i < 32; i++)
+ printf("r%d 0x%lx\n", i, frame->fixreg[i]);
+ printf("ctr 0x%lx\n", frame->ctr);
+ printf("xer 0x%lx\n", frame->xer);
+ printf("cr 0x%lx\n", frame->cr);
+ printf("lr 0x%lx\n", frame->lr);
+
+ if (error == ENOMEM) {
+ sig = SIGKILL;
+ code = 0;
+ } else if (error == EIO) {
+ sig = SIGBUS;
+ code = BUS_OBJERR;
+ } else if (error == EACCES) {
+ sig = SIGSEGV;
+ code = SEGV_ACCERR;
+ } else {
+ sig = SIGSEGV;
+ code = SEGV_MAPERR;
+ }
+ sv.sival_ptr = (void *)va;
+ KERNEL_LOCK();
+ trapsignal(p, sig, 0, code, sv);
+ KERNEL_UNLOCK();
}
break;
@@ -155,15 +178,39 @@ trap(struct trapframe *frame)
/* FALLTHROUGH */
case EXC_ISI|EXC_USER:
-// printf("proc %p type %x srr0 0x%lx\n", p, type, frame->srr0);
map = &p->p_vmspace->vm_map;
va = frame->srr0;
ftype = PROT_READ | PROT_EXEC;
KERNEL_LOCK();
error = uvm_fault(map, trunc_page(va), 0, ftype);
KERNEL_UNLOCK();
- if (error)
- goto fatal;
+ if (error) {
+ printf("type %x srr0 0x%lx\n", type, frame->srr0);
+ for (int i = 0; i < 32; i++)
+ printf("r%d 0x%lx\n", i, frame->fixreg[i]);
+ printf("ctr 0x%lx\n", frame->ctr);
+ printf("xer 0x%lx\n", frame->xer);
+ printf("cr 0x%lx\n", frame->cr);
+ printf("lr 0x%lx\n", frame->lr);
+
+ if (error == ENOMEM) {
+ sig = SIGKILL;
+ code = 0;
+ } else if (error == EIO) {
+ sig = SIGBUS;
+ code = BUS_OBJERR;
+ } else if (error == EACCES) {
+ sig = SIGSEGV;
+ code = SEGV_ACCERR;
+ } else {
+ sig = SIGSEGV;
+ code = SEGV_MAPERR;
+ }
+ sv.sival_ptr = (void *)va;
+ KERNEL_LOCK();
+ trapsignal(p, sig, 0, code, sv);
+ KERNEL_UNLOCK();
+ }
break;
case EXC_SC|EXC_USER:
@@ -176,6 +223,28 @@ trap(struct trapframe *frame)
mi_ast(p, ci->ci_want_resched);
break;
+ case EXC_ALI|EXC_USER:
+ sv.sival_ptr = (void *)frame->dar;
+ KERNEL_LOCK();
+ trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv);
+ KERNEL_UNLOCK();
+ break;
+
+ case EXC_PGM|EXC_USER:
+ printf("type %x srr0 0x%lx\n", type, frame->srr0);
+ for (int i = 0; i < 32; i++)
+ printf("r%d 0x%lx\n", i, frame->fixreg[i]);
+ printf("ctr 0x%lx\n", frame->ctr);
+ printf("xer 0x%lx\n", frame->xer);
+ printf("cr 0x%lx\n", frame->cr);
+ printf("lr 0x%lx\n", frame->lr);
+
+ sv.sival_ptr = (void *)frame->srr0;
+ KERNEL_LOCK();
+ trapsignal(p, SIGTRAP, 0, TRAP_BRKPT, sv);
+ KERNEL_UNLOCK();
+ break;
+
case EXC_FPU|EXC_USER:
restore_vsx(p);
curpcb->pcb_flags |= PCB_FP;
@@ -190,8 +259,8 @@ trap(struct trapframe *frame)
default:
fatal:
- panic("trap type %lx srr1 %lx at %lx lr %lx",
- frame->exc, frame->srr1, frame->srr0, frame->lr);
+ panic("trap type %x srr1 %lx at %lx lr %lx",
+ type, frame->srr1, frame->srr0, frame->lr);
}
userret(p);