diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2015-09-27 09:11:12 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2015-09-27 09:11:12 +0000 |
commit | 966e7350f8c07b33900038be562b3476b9ef901e (patch) | |
tree | 3f1f88bd4663c39a034839cbb36565dc063e9163 /sys | |
parent | d5ed9666bcc654146baaddb7c1d6fef143d8d4a2 (diff) |
On R8000, make trap() behave closer to interrupt() when servicing a real
interrupt by not invoking refreshcreds(), but closer to itsa() when servicing
a trap-reported-as-interrupt by invoking userret() in that case.
No change on !defined(CPU_R8000) kernels.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/mips64/mips64/trap.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/sys/arch/mips64/mips64/trap.c b/sys/arch/mips64/mips64/trap.c index 65bc612da84..f05a6e7c5ab 100644 --- a/sys/arch/mips64/mips64/trap.c +++ b/sys/arch/mips64/mips64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.109 2015/08/19 16:40:10 visa Exp $ */ +/* $OpenBSD: trap.c,v 1.110 2015/09/27 09:11:11 miod Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -206,9 +206,6 @@ trap(struct trap_frame *trapframe) break; } - if (type & T_USER) - refreshcreds(p); - #ifdef CPU_R8000 /* * Some exception causes on R8000 are actually detected by external @@ -218,34 +215,47 @@ trap(struct trap_frame *trapframe) * as if they were triggered as regular exceptions. */ if ((type & ~T_USER) == T_INT) { - /* - * Similar reality check as done in interrupt(), in case - * an interrupt occured between a write to COP_0_STATUS_REG - * and it taking effect. - */ - if (!ISSET(trapframe->sr, SR_INT_ENAB)) - return; - if (trapframe->cause & CR_VCE) { #ifndef DEBUG_INTERRUPT trapdebug_enter(ci, trapframe, -1); #endif panic("VCE or TLBX"); } + if (trapframe->cause & CR_FPE) { #ifndef DEBUG_INTERRUPT trapdebug_enter(ci, trapframe, -1); #endif + atomic_inc_int(&uvmexp.traps); + if (type & T_USER) + refreshcreds(p); itsa(trapframe, ci, p, T_FPE | (type & T_USER)); cp0_reset_cause(CR_FPE); } - if (trapframe->cause & CR_INT_MASK) - interrupt(trapframe); - return; /* no userret */ - } else + if (trapframe->cause & CR_INT_MASK) { + /* + * Similar reality check as done in interrupt(), in + * case an interrupt occured between a write to + * COP_0_STATUS_REG and it taking effect. + * (I have never seen this occuring on R8000 but + * this is cheap) + */ + if (ISSET(trapframe->sr, SR_INT_ENAB)) + interrupt(trapframe); + } + + if ((trapframe->cause & CR_FPE) && (type & T_USER)) + userret(p); + + return; + } #endif - itsa(trapframe, ci, p, type); + + if (type & T_USER) + refreshcreds(p); + + itsa(trapframe, ci, p, type); if (type & T_USER) userret(p); |