summaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/hw_breakpoint.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-12-28 17:53:47 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-12-28 17:53:47 +0900
commit34d0b5af50a063cded842716633501b38ff815fb (patch)
treec729b349fd43e40530a65d073a8476ff754b4b2d /arch/sh/kernel/hw_breakpoint.c
parent22648735405f73299b717bb5933767e9a9c335ca (diff)
sh: Convert ptrace to hw_breakpoint API.
This is the initial step for converting singlestep handling via ptrace over to hw_breakpoints. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/hw_breakpoint.c')
-rw-r--r--arch/sh/kernel/hw_breakpoint.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c
index 022d8ed66bd..c515a3ecf56 100644
--- a/arch/sh/kernel/hw_breakpoint.c
+++ b/arch/sh/kernel/hw_breakpoint.c
@@ -20,6 +20,7 @@
#include <linux/io.h>
#include <asm/hw_breakpoint.h>
#include <asm/mmu_context.h>
+#include <asm/ptrace.h>
struct ubc_context {
unsigned long pc;
@@ -372,7 +373,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
rcu_read_unlock();
}
- if (bp) {
+ if (bp && bp->overflow_handler != ptrace_triggered) {
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
__raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR0);
@@ -387,9 +388,19 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
BUILD_TRAP_HANDLER(breakpoint)
{
unsigned long ex = lookup_exception_vector();
+ siginfo_t info;
+ int err;
TRAP_HANDLER_DECL;
- notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP);
+ err = notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP);
+ if (err == NOTIFY_STOP)
+ return;
+
+ /* Deliver the signal to userspace */
+ info.si_signo = SIGTRAP;
+ info.si_errno = 0;
+ info.si_code = TRAP_HWBKPT;
+ force_sig_info(SIGTRAP, &info, current);
}
/*