Modify the ptrace code to use the hardware breakpoint interfaces for user-space.
Signed-off-by: K.Prasad <pra...@linux.vnet.ibm.com> --- arch/powerpc/kernel/ptrace.c | 48 +++++ Index: linux-2.6-tip.hbkpt/arch/powerpc/kernel/ptrace.c =================================================================== --- linux-2.6-tip.hbkpt.orig/arch/powerpc/kernel/ptrace.c +++ linux-2.6-tip.hbkpt/arch/powerpc/kernel/ptrace.c @@ -37,6 +37,9 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <asm/system.h> +#ifdef CONFIG_PPC64 +#include <asm/hw_breakpoint.h> +#endif /* * does not yet catch signals sent when the child dies. @@ -735,9 +738,22 @@ void user_disable_single_step(struct tas clear_tsk_thread_flag(task, TIF_SINGLESTEP); } +static void ptrace_triggered(struct hw_breakpoint *bp, struct pt_regs *regs) +{ + /* + * The SIGTRAP signal is generated automatically for us in do_dabr(). + * We don't have to do anything here + */ +} + int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data) { +#ifdef CONFIG_PPC64 + struct thread_struct *thread = &(task->thread); + struct hw_breakpoint *bp; + int ret; +#endif /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). * For embedded processors we support one DAC and no IAC's at the * moment. @@ -767,6 +783,38 @@ int ptrace_set_debugreg(struct task_stru if (data && !(data & DABR_TRANSLATION)) return -EIO; +#ifdef CONFIG_PPC64 + bp = thread->hbp[0]; + if ((data & ~HW_BREAKPOINT_ALIGN) == 0) { + if (bp) { + unregister_user_hw_breakpoint(task, bp); + kfree(bp); + thread->hbp[0] = NULL; + } + return 0; + } + + if (bp) { + bp->info.type = data & DABR_DATA_RW; + task->thread.dabr = bp->info.address = + (data & ~HW_BREAKPOINT_ALIGN); + return modify_user_hw_breakpoint(task, bp); + } + bp = kzalloc(sizeof(struct hw_breakpoint), GFP_KERNEL); + if (!bp) + return -ENOMEM; + + /* Store the type of breakpoint */ + bp->info.type = data & DABR_DATA_RW; + bp->triggered = ptrace_triggered; + task->thread.dabr = bp->info.address = (data & ~HW_BREAKPOINT_ALIGN); + + ret = register_user_hw_breakpoint(task, bp); + if (ret) + return ret; + set_tsk_thread_flag(task, TIF_DEBUG); +#endif /* CONFIG_PPC64 */ + /* Move contents to the DABR register */ task->thread.dabr = data; _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev