diff options
author | David Daney <ddaney@avtrex.com> | 2008-09-23 03:08:45 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-10-11 11:18:56 -0400 |
commit | b67b2b703047bfaf62687ca64c9486599b609ef0 (patch) | |
tree | ae9eee050db78869d62c5ca85953d0c1b93639f3 /arch/mips/kernel | |
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')
-rw-r--r-- | arch/mips/kernel/genex.S | 4 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 24 |
2 files changed, 23 insertions, 5 deletions
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 01dcbe38fa01..757d48f0d80f 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -453,7 +453,11 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
453 | BUILD_HANDLER tr tr sti silent /* #13 */ | 453 | BUILD_HANDLER tr tr sti silent /* #13 */ |
454 | BUILD_HANDLER fpe fpe fpe silent /* #15 */ | 454 | BUILD_HANDLER fpe fpe fpe silent /* #15 */ |
455 | BUILD_HANDLER mdmx mdmx sti silent /* #22 */ | 455 | BUILD_HANDLER mdmx mdmx sti silent /* #22 */ |
456 | #ifdef CONFIG_HARDWARE_WATCHPOINTS | ||
457 | BUILD_HANDLER watch watch sti silent /* #23 */ | ||
458 | #else | ||
456 | BUILD_HANDLER watch watch sti verbose /* #23 */ | 459 | BUILD_HANDLER watch watch sti verbose /* #23 */ |
460 | #endif | ||
457 | BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ | 461 | BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ |
458 | BUILD_HANDLER mt mt sti silent /* #25 */ | 462 | BUILD_HANDLER mt mt sti silent /* #25 */ |
459 | BUILD_HANDLER dsp dsp sti silent /* #26 */ | 463 | BUILD_HANDLER dsp dsp sti silent /* #26 */ |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b602ac6eb47d..80b9e070c207 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/tlbdebug.h> | 42 | #include <asm/tlbdebug.h> |
43 | #include <asm/traps.h> | 43 | #include <asm/traps.h> |
44 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
45 | #include <asm/watch.h> | ||
45 | #include <asm/mmu_context.h> | 46 | #include <asm/mmu_context.h> |
46 | #include <asm/types.h> | 47 | #include <asm/types.h> |
47 | #include <asm/stacktrace.h> | 48 | #include <asm/stacktrace.h> |
@@ -912,13 +913,26 @@ asmlinkage void do_mdmx(struct pt_regs *regs) | |||
912 | 913 | ||
913 | asmlinkage void do_watch(struct pt_regs *regs) | 914 | asmlinkage void do_watch(struct pt_regs *regs) |
914 | { | 915 | { |
916 | u32 cause; | ||
917 | |||
915 | /* | 918 | /* |
916 | * We use the watch exception where available to detect stack | 919 | * Clear WP (bit 22) bit of cause register so we don't loop |
917 | * overflows. | 920 | * forever. |
918 | */ | 921 | */ |
919 | dump_tlb_all(); | 922 | cause = read_c0_cause(); |
920 | show_regs(regs); | 923 | cause &= ~(1 << 22); |
921 | panic("Caught WATCH exception - probably caused by stack overflow."); | 924 | write_c0_cause(cause); |
925 | |||
926 | /* | ||
927 | * If the current thread has the watch registers loaded, save | ||
928 | * their values and send SIGTRAP. Otherwise another thread | ||
929 | * left the registers set, clear them and continue. | ||
930 | */ | ||
931 | if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) { | ||
932 | mips_read_watch_registers(); | ||
933 | force_sig(SIGTRAP, current); | ||
934 | } else | ||
935 | mips_clear_watch_registers(); | ||
922 | } | 936 | } |
923 | 937 | ||
924 | asmlinkage void do_mcheck(struct pt_regs *regs) | 938 | asmlinkage void do_mcheck(struct pt_regs *regs) |