[PATCH] Not preempt in CP1 exception handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



do_ade may be invoked with preempt enabled. do_cpu will be invoked with
preempt enabled. When it's preempted(in do_ade/do_cpu), TIF_USEDFPU will be
cleared, when it returns to do_ade/do_cpu, the fpu is actually disabled.

e.g.
In do_ade()
  emulate_load_store_insn():
    BUG_ON(!is_fpu_owner()); <-- This assertion may be breaked.

In do_cpu()
  enable_restore_fp_context():
    was_fpu_owner = is_fpu_owner();

This patch simply disables interrupts in related handlers, and
disable preempt/enable interrupts in do_ade/do_cpu.
---
 arch/mips/kernel/genex.S | 4 ++--
 arch/mips/kernel/traps.c | 4 ++++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index ac35e12..a5c6931 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -370,7 +370,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
 	.macro	__build_clear_ade
 	MFC0	t0, CP0_BADVADDR
 	PTR_S	t0, PT_BVADDR(sp)
-	KMODE
+	CLI
 	.endm
 
 	.macro	__BUILD_silent exception
@@ -422,7 +422,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
 	BUILD_HANDLER dbe be cli silent			/* #7  */
 	BUILD_HANDLER bp bp sti silent			/* #9  */
 	BUILD_HANDLER ri ri sti silent			/* #10 */
-	BUILD_HANDLER cpu cpu sti silent		/* #11 */
+	BUILD_HANDLER cpu cpu cli silent		/* #11 */
 	BUILD_HANDLER ov ov sti silent			/* #12 */
 	BUILD_HANDLER tr tr sti silent			/* #13 */
 	BUILD_HANDLER msa_fpe msa_fpe sti silent	/* #14 */
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 51706d6..0e0f7de 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1166,6 +1166,9 @@ asmlinkage void do_cpu(struct pt_regs *regs)
 	int status, err;
 	unsigned long __maybe_unused flags;
 
+	preempt_disable();
+	local_irq_enable();
+
 	prev_state = exception_enter();
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
 
@@ -1258,6 +1261,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
 
 out:
 	exception_exit(prev_state);
+	preempt_enable();
 }
 
 asmlinkage void do_msa_fpe(struct pt_regs *regs)
-- 
1.9.0



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux