diff options
author | Anton Blanchard <anton@samba.org> | 2005-09-10 16:01:11 +1000 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-09-12 17:19:12 +1000 |
commit | fd9648dff6f9797ecc509bcd181706a274dc074d (patch) | |
tree | 845b99905dc4f54171d554c14e45b55f1cfe48e2 /arch/ppc64/mm | |
parent | a94d308513bdb2b926b45c11d7ce7fac6d6ca865 (diff) | |
download | blackbird-op-linux-fd9648dff6f9797ecc509bcd181706a274dc074d.tar.gz blackbird-op-linux-fd9648dff6f9797ecc509bcd181706a274dc074d.zip |
[PATCH] ppc64: Add ptrace data breakpoint support
Add hardware data breakpoint support.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/ppc64/mm')
-rw-r--r-- | arch/ppc64/mm/fault.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c index 772f0714a5b7..7fbc68bbb739 100644 --- a/arch/ppc64/mm/fault.c +++ b/arch/ppc64/mm/fault.c @@ -77,6 +77,28 @@ static int store_updates_sp(struct pt_regs *regs) return 0; } +static void do_dabr(struct pt_regs *regs, unsigned long error_code) +{ + siginfo_t info; + + if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, + 11, SIGSEGV) == NOTIFY_STOP) + return; + + if (debugger_dabr_match(regs)) + return; + + /* Clear the DABR */ + set_dabr(0); + + /* Deliver the signal to userspace */ + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_HWBKPT; + info.si_addr = (void __user *)regs->nip; + force_sig_info(SIGTRAP, &info, current); +} + /* * The error_code parameter is * - DSISR for a non-SLB data access fault, @@ -111,12 +133,9 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, if (!user_mode(regs) && (address >= TASK_SIZE)) return SIGSEGV; - if (error_code & DSISR_DABRMATCH) { - if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, - 11, SIGSEGV) == NOTIFY_STOP) - return 0; - if (debugger_dabr_match(regs)) - return 0; + if (error_code & DSISR_DABRMATCH) { + do_dabr(regs, error_code); + return 0; } if (in_atomic() || mm == NULL) { |