diff options
-rw-r--r-- | sys/arch/mips64/mips64/db_machdep.c | 8 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/fp_emulate.c | 15 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/trap.c | 74 |
3 files changed, 73 insertions, 24 deletions
diff --git a/sys/arch/mips64/mips64/db_machdep.c b/sys/arch/mips64/mips64/db_machdep.c index 41299aa5740..1c620160023 100644 --- a/sys/arch/mips64/mips64/db_machdep.c +++ b/sys/arch/mips64/mips64/db_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_machdep.c,v 1.47 2016/09/19 17:59:19 jasper Exp $ */ +/* $OpenBSD: db_machdep.c,v 1.48 2017/08/26 15:21:48 visa Exp $ */ /* * Copyright (c) 1998-2003 Opsycon AB (www.opsycon.se) @@ -358,9 +358,11 @@ db_addr_t next_instr_address(db_addr_t pc, boolean_t bd) { db_addr_t next; + uint32_t instr; - next = MipsEmulateBranch(&ddb_regs, (vaddr_t)pc, 0, 0); - return(next); + instr = kdbpeek(pc); + next = MipsEmulateBranch(&ddb_regs, (vaddr_t)pc, 0, instr); + return (next); } /* diff --git a/sys/arch/mips64/mips64/fp_emulate.c b/sys/arch/mips64/mips64/fp_emulate.c index 50251be956f..f6bee8e04c6 100644 --- a/sys/arch/mips64/mips64/fp_emulate.c +++ b/sys/arch/mips64/mips64/fp_emulate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fp_emulate.c,v 1.15 2017/01/21 05:42:03 guenther Exp $ */ +/* $OpenBSD: fp_emulate.c,v 1.16 2017/08/26 15:21:48 visa Exp $ */ /* * Copyright (c) 2010 Miodrag Vallat. @@ -134,6 +134,7 @@ MipsFPTrap(struct trapframe *tf) union sigval sv; vaddr_t pc; uint32_t fsr, excbits; + uint32_t branch = 0; uint32_t insn; InstFmt inst; int sig = 0; @@ -194,6 +195,15 @@ MipsFPTrap(struct trapframe *tf) } inst = *(InstFmt *)&insn; + if (tf->cause & CR_BR_DELAY) { + if (copyin32((const void *)tf->pc, &branch) != 0) { + sig = SIGBUS; + fault_type = BUS_OBJERR; + sv.sival_ptr = (void *)tf->pc; + goto deliver; + } + } + /* * Emulate the instruction. */ @@ -366,7 +376,8 @@ deliver: * only used to decide whether to branch or not * if the faulting instruction was BC1[FT]. */ - tf->pc = MipsEmulateBranch(tf, tf->pc, fsr, 0); + tf->pc = MipsEmulateBranch(tf, tf->pc, fsr, + branch); } else tf->pc += 4; } diff --git a/sys/arch/mips64/mips64/trap.c b/sys/arch/mips64/mips64/trap.c index f01bff0c8a7..9e2980dd18b 100644 --- a/sys/arch/mips64/mips64/trap.c +++ b/sys/arch/mips64/mips64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.127 2017/07/22 18:33:51 visa Exp $ */ +/* $OpenBSD: trap.c,v 1.128 2017/08/26 15:21:48 visa Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -465,6 +465,7 @@ fault_common_no_miss: struct sysent *callp; unsigned int code; register_t tpc; + uint32_t branch = 0; int error, numarg, numsys; struct args { register_t i[8]; @@ -475,10 +476,17 @@ fault_common_no_miss: /* compute next PC after syscall instruction */ tpc = trapframe->pc; /* Remember if restart */ - if (trapframe->cause & CR_BR_DELAY) + if (trapframe->cause & CR_BR_DELAY) { + /* Get the branch instruction. */ + if (copyin32((const void *)locr0->pc, &branch) != 0) { + signal = SIGBUS; + sicode = BUS_OBJERR; + break; + } + locr0->pc = MipsEmulateBranch(locr0, - trapframe->pc, 0, 0); - else + trapframe->pc, 0, branch); + } else locr0->pc += 4; callp = p->p_p->ps_emul->e_sysent; numsys = p->p_p->ps_emul->e_nsysent; @@ -578,15 +586,25 @@ fault_common_no_miss: case T_BREAK+T_USER: { - caddr_t va; - u_int32_t instr; struct trapframe *locr0 = p->p_md.md_regs; + caddr_t va; + uint32_t branch = 0; + uint32_t instr; /* compute address of break instruction */ va = (caddr_t)trapframe->pc; - if (trapframe->cause & CR_BR_DELAY) + if (trapframe->cause & CR_BR_DELAY) { va += 4; + /* Read branch instruction. */ + if (copyin32((const void *)trapframe->pc, + &branch) != 0) { + signal = SIGBUS; + sicode = BUS_OBJERR; + break; + } + } + /* read break instruction */ copyin(va, &instr, sizeof(int32_t)); @@ -597,7 +615,7 @@ fault_common_no_miss: /* skip instruction */ if (trapframe->cause & CR_BR_DELAY) locr0->pc = MipsEmulateBranch(locr0, - trapframe->pc, 0, 0); + trapframe->pc, 0, branch); else locr0->pc += 4; break; @@ -607,7 +625,7 @@ fault_common_no_miss: /* skip instruction */ if (trapframe->cause & CR_BR_DELAY) locr0->pc = MipsEmulateBranch(locr0, - trapframe->pc, 0, 0); + trapframe->pc, 0, branch); else locr0->pc += 4; break; @@ -685,20 +703,31 @@ fault_common_no_miss: case T_TRAP+T_USER: { - caddr_t va; - u_int32_t instr; struct trapframe *locr0 = p->p_md.md_regs; + caddr_t va; + uint32_t branch = 0; + uint32_t instr; /* compute address of trap instruction */ va = (caddr_t)trapframe->pc; - if (trapframe->cause & CR_BR_DELAY) + if (trapframe->cause & CR_BR_DELAY) { va += 4; + + /* Read branch instruction. */ + if (copyin32((const void *)trapframe->pc, + &branch) != 0) { + signal = SIGBUS; + sicode = BUS_OBJERR; + break; + } + } + /* read break instruction */ copyin(va, &instr, sizeof(int32_t)); if (trapframe->cause & CR_BR_DELAY) locr0->pc = MipsEmulateBranch(locr0, - trapframe->pc, 0, 0); + trapframe->pc, 0, branch); else locr0->pc += 4; /* @@ -721,13 +750,23 @@ fault_common_no_miss: { register_t *regs = (register_t *)trapframe; caddr_t va; + uint32_t branch = 0; InstFmt inst; /* Compute the instruction's address. */ va = (caddr_t)trapframe->pc; - if (trapframe->cause & CR_BR_DELAY) + if (trapframe->cause & CR_BR_DELAY) { va += 4; + /* Get the branch instruction. */ + if (copyin32((const void *)trapframe->pc, + &branch) != 0) { + signal = SIGBUS; + sicode = BUS_OBJERR; + break; + } + } + /* Get the faulting instruction. */ if (copyin32((void *)va, &inst.word) != 0) { signal = SIGBUS; @@ -746,7 +785,7 @@ fault_common_no_miss: /* Figure out where to continue. */ if (trapframe->cause & CR_BR_DELAY) trapframe->pc = MipsEmulateBranch(trapframe, - trapframe->pc, 0, 0); + trapframe->pc, 0, branch); else trapframe->pc += 4; return; @@ -951,10 +990,7 @@ MipsEmulateBranch(struct trapframe *tf, vaddr_t instPC, uint32_t fsr, #define GetBranchDest(InstPtr, inst) \ (InstPtr + 4 + ((short)inst.IType.imm << 2)) - if (curinst != 0) - inst = *(InstFmt *)&curinst; - else - inst = *(InstFmt *)instPC; + inst.word = curinst; regsPtr[ZERO] = 0; /* Make sure zero is 0x0 */ |