summaryrefslogtreecommitdiff
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2009-01-05 15:29:58 -0800
committerRalf Baechle <ralf@linux-mips.org>2009-01-30 21:32:58 +0000
commit8bc6d05b481aa7dc79c81b8ffac0da755e149643 (patch)
tree0c6b7c62dbec9d598546c7e58cb13c0c78212a1e /arch/mips/kernel/traps.c
parent7adbedaf4469dcdcd6a1ab9bdeb8ad854d4f9827 (diff)
downloadlwn-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.c8
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)