From 123e73dbfdc364cd478086ee54a3d706e731e716 Mon Sep 17 00:00:00 2001 From: David Daney Date: Mon, 5 Jan 2009 15:29:58 -0800 Subject: [PATCH] MIPS: Read watch registers with interrupts disabled. If a context switch occurred between the watch exception and reading the watch registers, it would be possible for the new process to corrupt their state. Enabling interrupts only after the watch registers are read avoids this race. Signed-off-by: David Daney Signed-off-by: Ralf Baechle --- arch/mips/kernel/genex.S | 6 +++++- arch/mips/kernel/traps.c | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index fb6f73148df2f..8882e5766f27c 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -458,7 +458,11 @@ NESTED(nmi_handler, PT_SIZE, sp) BUILD_HANDLER fpe fpe fpe silent /* #15 */ BUILD_HANDLER mdmx mdmx sti silent /* #22 */ #ifdef CONFIG_HARDWARE_WATCHPOINTS - BUILD_HANDLER watch watch sti silent /* #23 */ + /* + * For watch, interrupts will be enabled after the watch + * registers are read. + */ + BUILD_HANDLER watch watch cli silent /* #23 */ #else BUILD_HANDLER watch watch sti verbose /* #23 */ #endif diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index fa06460cbf2c7..b2d7041341b8f 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -944,6 +944,9 @@ asmlinkage void do_mdmx(struct pt_regs *regs) force_sig(SIGILL, current); } +/* + * Called with interrupts disabled. + */ asmlinkage void do_watch(struct pt_regs *regs) { u32 cause; @@ -963,9 +966,12 @@ asmlinkage void do_watch(struct pt_regs *regs) */ if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) { mips_read_watch_registers(); + local_irq_enable(); force_sig(SIGTRAP, current); - } else + } else { mips_clear_watch_registers(); + local_irq_enable(); + } } asmlinkage void do_mcheck(struct pt_regs *regs) -- 2.39.5