diff options
author | 2004-01-29 00:41:23 +0000 | |
---|---|---|
committer | 2004-01-29 00:41:23 +0000 | |
commit | 54e8f595dd19e543679891c874e3dd0e387c8425 (patch) | |
tree | c5664ae6c03e894b834fd9078425b07a0c103d00 | |
parent | 187BUG, 188BUG and 197BUG agree that only SSR3 needs to be preserved across (diff) | |
download | wireguard-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.S | 10 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/trap.c | 43 |
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); |