diff options
author | David Daney <ddaney@caviumnetworks.com> | 2009-01-05 15:29:58 -0800 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-01-30 21:32:58 +0000 |
commit | 8bc6d05b481aa7dc79c81b8ffac0da755e149643 (patch) | |
tree | 0c6b7c62dbec9d598546c7e58cb13c0c78212a1e /arch/mips/kernel/traps.c | |
parent | 7adbedaf4469dcdcd6a1ab9bdeb8ad854d4f9827 (diff) | |
download | lwn-8bc6d05b481aa7dc79c81b8ffac0da755e149643.tar.gz lwn-8bc6d05b481aa7dc79c81b8ffac0da755e149643.zip |
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 <ddaney@caviumnetworks.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r-- | arch/mips/kernel/traps.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index fa06460cbf2c..b2d7041341b8 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) |