svn commit: r193491 - projects/mips/sys/mips/mips

Oleksandr Tymoshenko gonzo at FreeBSD.org
Fri Jun 5 09:21:04 UTC 2009


Author: gonzo
Date: Fri Jun  5 09:21:03 2009
New Revision: 193491
URL: http://svn.freebsd.org/changeset/base/193491

Log:
  - Status register should be set last in RESTORE_CPU in order
      to prevent race over k0, k1 registers.
  - Update interrupts mask in saved status register for
      MipsUserIntr and MipsUserGenException. It might be
      modified by intr filter or ithread.

Modified:
  projects/mips/sys/mips/mips/exception.S

Modified: projects/mips/sys/mips/mips/exception.S
==============================================================================
--- projects/mips/sys/mips/mips/exception.S	Fri Jun  5 09:16:52 2009	(r193490)
+++ projects/mips/sys/mips/mips/exception.S	Fri Jun  5 09:21:03 2009	(r193491)
@@ -326,10 +326,9 @@ SlowFault:
 
 #define	RESTORE_CPU \
 	mtc0	zero,COP_0_STATUS_REG	;\
-	RESTORE_REG(a0, SR, sp)		;\
+	RESTORE_REG(k0, SR, sp)		;\
 	RESTORE_REG(t0, MULLO, sp)	;\
 	RESTORE_REG(t1, MULHI, sp)	;\
-	mtc0	a0, COP_0_STATUS_REG	;\
 	mtlo	t0			;\
 	mthi	t1			;\
 	_MTC0	v0, COP_0_EXC_PC	;\
@@ -362,7 +361,8 @@ SlowFault:
 	RESTORE_REG(s8, S8, sp)	        ;\
 	RESTORE_REG(gp, GP, sp)		;\
 	RESTORE_REG(ra, RA, sp)		;\
-	addu	sp, sp, KERN_EXC_FRAME_SIZE
+	addu	sp, sp, KERN_EXC_FRAME_SIZE;\
+	mtc0	k0, COP_0_STATUS_REG
 
 
 /*
@@ -484,16 +484,19 @@ NNON_LEAF(MipsUserGenException, STAND_FR
 	la	k0, _C_LABEL(trap)
 	jalr	k0
 	nop
+
 /*
  * Restore user registers and return.
  * First disable interrupts and set exeption level.
  */
 	DO_AST
 
-	mtc0	zero, COP_0_STATUS_REG	# disable int
+	mfc0	t0, COP_0_STATUS_REG	# disable int
+	and	t0, t0, ~(MIPS_SR_INT_IE)
+	mtc0	t0, COP_0_STATUS_REG
 	ITLBNOPFIX
-	li	v0, SR_EXL
-	mtc0	v0, COP_0_STATUS_REG	# set exeption level
+	or	t0, t0, SR_EXL
+	mtc0	t0, COP_0_STATUS_REG	# set exeption level
 	ITLBNOPFIX
 
 /*
@@ -504,6 +507,18 @@ NNON_LEAF(MipsUserGenException, STAND_FR
 	GET_CPU_PCPU(k1)
 	lw	k1, PC_CURPCB(k1)
 
+	/*
+	 * Update interrupt mask in saved status register
+	 * Some of interrupts could be enabled by ithread
+	 * scheduled by ast()
+	 */
+	mfc0	a0, COP_0_STATUS_REG
+	and	a0, a0, SR_INT_MASK
+	RESTORE_U_PCB_REG(a1, SR, k1)
+	and	a1, a1, ~SR_INT_MASK
+	or	a1, a1, a0
+	SAVE_U_PCB_REG(a1, SR, k1)
+
 	RESTORE_U_PCB_REG(t0, MULLO, k1)
 	RESTORE_U_PCB_REG(t1, MULHI, k1)
 	mtlo	t0
@@ -714,14 +729,29 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE
 /*
  * Restore user registers and return. 
  */
-	mtc0	zero, COP_0_STATUS_REG	# re-disable interrupts
+	mfc0	t0, COP_0_STATUS_REG	# disable int
+	and	t0, t0, ~(MIPS_SR_INT_IE)
+	mtc0	t0, COP_0_STATUS_REG
 	ITLBNOPFIX
-	li	v0, SR_EXL
-	mtc0	v0, COP_0_STATUS_REG	# set exeption level bit.
+	or	t0, t0, SR_EXL
+	mtc0	t0, COP_0_STATUS_REG	# set exeption level
 	ITLBNOPFIX
 
 	GET_CPU_PCPU(k1)
 	lw	k1, PC_CURPCB(k1)
+
+	/*
+	 * Update interrupt mask in saved status register
+	 * Some of interrupts could be disabled by
+	 * intr filters
+	 */
+	mfc0	a0, COP_0_STATUS_REG
+	and	a0, a0, SR_INT_MASK
+	RESTORE_U_PCB_REG(a1, SR, k1)
+	and	a1, a1, ~SR_INT_MASK
+	or	a1, a1, a0
+	SAVE_U_PCB_REG(a1, SR, k1)
+
 	RESTORE_U_PCB_REG(s0, S0, k1)
 	RESTORE_U_PCB_REG(s1, S1, k1)
 	RESTORE_U_PCB_REG(s2, S2, k1)


More information about the svn-src-projects mailing list