Commit 658d029d authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman

powerpc/hw_breakpoint: move instruction stepping out of hw_breakpoint_handler()

On 8xx, breakpoints stop after executing the instruction, so
stepping/emulation is not needed. Move it into a sub-function and
remove the #ifdefs.
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: default avatarRavi Bangoria <ravi.bangoria@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/f8cdc3f1c66ad3c43ebc568abcc6c39ed4676284.1561737231.git.christophe.leroy@c-s.fr
parent 65e701b2
...@@ -198,15 +198,43 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) ...@@ -198,15 +198,43 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
/* /*
* Handle debug exception notifications. * Handle debug exception notifications.
*/ */
static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp,
unsigned long addr)
{
int stepped;
unsigned int instr;
/* Do not emulate user-space instructions, instead single-step them */
if (user_mode(regs)) {
current->thread.last_hit_ubp = bp;
regs->msr |= MSR_SE;
return false;
}
stepped = 0;
instr = 0;
if (!__get_user_inatomic(instr, (unsigned int *)regs->nip))
stepped = emulate_step(regs, instr);
/*
* emulate_step() could not execute it. We've failed in reliably
* handling the hw-breakpoint. Unregister it and throw a warning
* message to let the user know about it.
*/
if (!stepped) {
WARN(1, "Unable to handle hardware breakpoint. Breakpoint at "
"0x%lx will be disabled.", addr);
perf_event_disable_inatomic(bp);
return false;
}
return true;
}
int hw_breakpoint_handler(struct die_args *args) int hw_breakpoint_handler(struct die_args *args)
{ {
int rc = NOTIFY_STOP; int rc = NOTIFY_STOP;
struct perf_event *bp; struct perf_event *bp;
struct pt_regs *regs = args->regs; struct pt_regs *regs = args->regs;
#ifndef CONFIG_PPC_8xx
int stepped = 1;
unsigned int instr;
#endif
struct arch_hw_breakpoint *info; struct arch_hw_breakpoint *info;
unsigned long dar = regs->dar; unsigned long dar = regs->dar;
...@@ -251,31 +279,9 @@ int hw_breakpoint_handler(struct die_args *args) ...@@ -251,31 +279,9 @@ int hw_breakpoint_handler(struct die_args *args)
(dar - bp->attr.bp_addr < bp->attr.bp_len))) (dar - bp->attr.bp_addr < bp->attr.bp_len)))
info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
#ifndef CONFIG_PPC_8xx if (!IS_ENABLED(CONFIG_PPC_8xx) && !stepping_handler(regs, bp, info->address))
/* Do not emulate user-space instructions, instead single-step them */
if (user_mode(regs)) {
current->thread.last_hit_ubp = bp;
regs->msr |= MSR_SE;
goto out; goto out;
}
stepped = 0;
instr = 0;
if (!__get_user_inatomic(instr, (unsigned int *) regs->nip))
stepped = emulate_step(regs, instr);
/*
* emulate_step() could not execute it. We've failed in reliably
* handling the hw-breakpoint. Unregister it and throw a warning
* message to let the user know about it.
*/
if (!stepped) {
WARN(1, "Unable to handle hardware breakpoint. Breakpoint at "
"0x%lx will be disabled.", info->address);
perf_event_disable_inatomic(bp);
goto out;
}
#endif
/* /*
* As a policy, the callback is invoked in a 'trigger-after-execute' * As a policy, the callback is invoked in a 'trigger-after-execute'
* fashion * fashion
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment