aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
authorDavid Daney <ddaney@avtrex.com>2008-09-23 03:08:45 -0400
committerRalf Baechle <ralf@linux-mips.org>2008-10-11 11:18:56 -0400
commitb67b2b703047bfaf62687ca64c9486599b609ef0 (patch)
treeae9eee050db78869d62c5ca85953d0c1b93639f3 /arch/mips/kernel/traps.c
parent654f57bfb467996fb730eae96dc30ea4de989fdc (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.c24
1 files changed, 19 insertions, 5 deletions
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
913asmlinkage void do_watch(struct pt_regs *regs) 914asmlinkage 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
924asmlinkage void do_mcheck(struct pt_regs *regs) 938asmlinkage void do_mcheck(struct pt_regs *regs)