diff options
author | David Daney <ddaney@avtrex.com> | 2008-09-23 00:08:45 -0700 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-10-11 16:18:56 +0100 |
commit | b67b2b703047bfaf62687ca64c9486599b609ef0 (patch) | |
tree | ae9eee050db78869d62c5ca85953d0c1b93639f3 /arch/mips/kernel/traps.c | |
parent | 654f57bfb467996fb730eae96dc30ea4de989fdc (diff) |
MIPS: Watch exception handling for HARDWARE_WATCHPOINTS.
Here we hook up the watch exception handler so that it sends SIGTRAP when
the hardware watch registers are triggered.
Signed-off-by: David Daney <ddaney@avtrex.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 | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b602ac6eb47..80b9e070c20 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -42,6 +42,7 @@ #include <asm/tlbdebug.h> #include <asm/traps.h> #include <asm/uaccess.h> +#include <asm/watch.h> #include <asm/mmu_context.h> #include <asm/types.h> #include <asm/stacktrace.h> @@ -912,13 +913,26 @@ asmlinkage void do_mdmx(struct pt_regs *regs) asmlinkage void do_watch(struct pt_regs *regs) { + u32 cause; + /* - * We use the watch exception where available to detect stack - * overflows. + * Clear WP (bit 22) bit of cause register so we don't loop + * forever. */ - dump_tlb_all(); - show_regs(regs); - panic("Caught WATCH exception - probably caused by stack overflow."); + cause = read_c0_cause(); + cause &= ~(1 << 22); + write_c0_cause(cause); + + /* + * If the current thread has the watch registers loaded, save + * their values and send SIGTRAP. Otherwise another thread + * left the registers set, clear them and continue. + */ + if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) { + mips_read_watch_registers(); + force_sig(SIGTRAP, current); + } else + mips_clear_watch_registers(); } asmlinkage void do_mcheck(struct pt_regs *regs) |