summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/mips64/mips64/trap.c44
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);