summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2004-01-29 00:41:23 +0000
committermiod <miod@openbsd.org>2004-01-29 00:41:23 +0000
commit54e8f595dd19e543679891c874e3dd0e387c8425 (patch)
treec5664ae6c03e894b834fd9078425b07a0c103d00
parent187BUG, 188BUG and 197BUG agree that only SSR3 needs to be preserved across (diff)
downloadwireguard-openbsd-54e8f595dd19e543679891c874e3dd0e387c8425.tar.xz
wireguard-openbsd-54e8f595dd19e543679891c874e3dd0e387c8425.zip
Correctly handle 88110 exceptions occuring in a delay slot: control must
be restored with valid EXIP+D and ENIP values in this case, unless it is decided to skip instructions.
-rw-r--r--sys/arch/mvme88k/mvme88k/eh.S10
-rw-r--r--sys/arch/mvme88k/mvme88k/trap.c43
2 files changed, 34 insertions, 19 deletions
diff --git a/sys/arch/mvme88k/mvme88k/eh.S b/sys/arch/mvme88k/mvme88k/eh.S
index bc44b556ceb..05c3299bac8 100644
--- a/sys/arch/mvme88k/mvme88k/eh.S
+++ b/sys/arch/mvme88k/mvme88k/eh.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: eh.S,v 1.48 2004/01/19 17:21:25 miod Exp $ */
+/* $OpenBSD: eh.S,v 1.49 2004/01/29 00:41:23 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1991 Carnegie Mellon University
@@ -2471,16 +2471,12 @@ ASLOCAL(m88110_have_pcb)
ldcr TMP, EPSR
st TMP, r31, REG_OFF(EF_EPSR)
ldcr TMP2, EXIP
- st TMP2, r31, REG_OFF(EF_EXIP)
+ /* if the instruction was NOT in the delay slot, ignore ENIP */
bb0.n 0, TMP2, 1f
- /* The instruction was NOT in the delay slot, zero ENIP. */
- st r0, r31, REG_OFF(EF_ENIP)
- /* The instruction was in the delay slot, save ENIP. */
+ st TMP2, r31, REG_OFF(EF_EXIP)
ldcr TMP3, ENIP
st TMP3, r31, REG_OFF(EF_ENIP)
1:
- /* NO SFIP on mc88110, zero it */
- st r0, r31, REG_OFF(EF_SFIP)
/* get and store the cpu number */
extu TMP, FLAGS, FLAG_CPU_FIELD_WIDTH<0> /* TMP = cpu# */
diff --git a/sys/arch/mvme88k/mvme88k/trap.c b/sys/arch/mvme88k/mvme88k/trap.c
index 60c48c2541d..a594e51d19f 100644
--- a/sys/arch/mvme88k/mvme88k/trap.c
+++ b/sys/arch/mvme88k/mvme88k/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.70 2004/01/20 14:34:40 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.71 2004/01/29 00:41:23 miod Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -728,11 +728,12 @@ m88110_trap(unsigned type, struct trapframe *frame)
db_enable_interrupt();
ddb_entry_trap(T_KDB_ENTRY, (db_regs_t*)frame);
db_disable_interrupt();
- if (frame->tf_enip) {
+ /* skip one instruction */
+ if (frame->tf_exip & 1)
frame->tf_exip = frame->tf_enip;
- } else {
+ else
frame->tf_exip += 4;
- }
+ frame->tf_enip = 0;
splx(s);
return;
#if 0
@@ -819,6 +820,7 @@ m88110_trap(unsigned type, struct trapframe *frame)
(frame->tf_exip & XIP_ADDR) <=
(unsigned)&guarded_access_end) {
frame->tf_exip = (unsigned)&guarded_access_bad;
+ frame->tf_enip = 0;
return;
}
}
@@ -1006,6 +1008,7 @@ m88110_user_fault:
*/
if (result != 0 && p->p_addr->u_pcb.pcb_onfault != NULL) {
frame->tf_exip = p->p_addr->u_pcb.pcb_onfault;
+ frame->tf_enip = 0;
frame->tf_dsr = frame->tf_isr = 0;
/*
* Continue as if the fault had been resolved.
@@ -1469,8 +1472,12 @@ m88110_syscall(register_t code, struct trapframe *tf)
tf->tf_r[2] = rval[0];
tf->tf_r[3] = rval[1];
tf->tf_epsr &= ~PSR_C;
- tf->tf_exip += 4 + 4;
- tf->tf_exip &= XIP_ADDR;
+ /* skip two instructions */
+ if (tf->tf_exip & 1)
+ tf->tf_exip = tf->tf_enip + 4;
+ else
+ tf->tf_exip += 4 + 4;
+ tf->tf_enip = 0;
break;
case ERESTART:
/*
@@ -1482,16 +1489,24 @@ m88110_syscall(register_t code, struct trapframe *tf)
break;
case EJUSTRETURN:
tf->tf_epsr &= ~PSR_C;
- tf->tf_exip += 4;
- tf->tf_exip &= XIP_ADDR;
+ /* skip one instruction */
+ if (tf->tf_exip & 1)
+ tf->tf_exip = tf->tf_enip;
+ else
+ tf->tf_exip += 4;
+ tf->tf_enip = 0;
break;
default:
if (p->p_emul->e_errno)
error = p->p_emul->e_errno[error];
tf->tf_r[2] = error;
tf->tf_epsr |= PSR_C; /* fail */
- tf->tf_exip += 4;
- tf->tf_exip &= XIP_ADDR;
+ /* skip one instruction */
+ if (tf->tf_exip & 1)
+ tf->tf_exip = tf->tf_enip;
+ else
+ tf->tf_exip += 4;
+ tf->tf_enip = 0;
break;
}
@@ -1525,8 +1540,12 @@ child_return(arg)
tf->tf_snip = tf->tf_sfip & XIP_ADDR;
tf->tf_sfip = tf->tf_snip + 4;
} else {
- tf->tf_exip += 4 + 4;
- tf->tf_exip &= XIP_ADDR;
+ /* skip two instructions */
+ if (tf->tf_exip & 1)
+ tf->tf_exip = tf->tf_enip + 4;
+ else
+ tf->tf_exip += 4 + 4;
+ tf->tf_enip = 0;
}
userret(p, tf, p->p_sticks);