Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b67b2b70 authored by David Daney's avatar David Daney Committed by Ralf Baechle
Browse files

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: default avatarDavid Daney <ddaney@avtrex.com>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 654f57bf
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -453,7 +453,11 @@ NESTED(nmi_handler, PT_SIZE, sp)
	BUILD_HANDLER tr tr sti silent			/* #13 */
	BUILD_HANDLER fpe fpe fpe silent		/* #15 */
	BUILD_HANDLER mdmx mdmx sti silent		/* #22 */
#ifdef 	CONFIG_HARDWARE_WATCHPOINTS
	BUILD_HANDLER watch watch sti silent		/* #23 */
#else
	BUILD_HANDLER watch watch sti verbose		/* #23 */
#endif
	BUILD_HANDLER mcheck mcheck cli verbose		/* #24 */
	BUILD_HANDLER mt mt sti silent			/* #25 */
	BUILD_HANDLER dsp dsp sti silent		/* #26 */
+19 −5
Original line number Diff line number Diff line
@@ -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)