Commit 0e524e76 authored by Matt Evans's avatar Matt Evans Committed by Michael Ellerman

powerpc: Clear branch trap (MSR.BE) before delivering SIGTRAP

When using SIG_DBG_BRANCH_TRACING, MSR.BE is left enabled in the
user context when single_step_exception() prepares the SIGTRAP
delivery.  The resulting branch-trap-within-the-SIGTRAP-handler
isn't healthy.

Commit 2538c2d0 broke this, by
replacing an MSR mask operation of ~(MSR_SE | MSR_BE) with a call
to clear_single_step() which only clears MSR_SE.

This patch adds a new helper, clear_br_trace(), which clears the
debug trap before invoking the signal handler.  This helper is a
NOP for BookE as SIG_DBG_BRANCH_TRACING isn't supported on BookE.
Signed-off-by: default avatarMatt Evans <matt@ozlabs.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 4b7e5532
...@@ -471,7 +471,7 @@ static inline int check_io_access(struct pt_regs *regs) ...@@ -471,7 +471,7 @@ static inline int check_io_access(struct pt_regs *regs)
/* single-step stuff */ /* single-step stuff */
#define single_stepping(regs) (current->thread.debug.dbcr0 & DBCR0_IC) #define single_stepping(regs) (current->thread.debug.dbcr0 & DBCR0_IC)
#define clear_single_step(regs) (current->thread.debug.dbcr0 &= ~DBCR0_IC) #define clear_single_step(regs) (current->thread.debug.dbcr0 &= ~DBCR0_IC)
#define clear_br_trace(regs) do {} while(0)
#else #else
/* On non-4xx, the reason for the machine check or program /* On non-4xx, the reason for the machine check or program
exception is in the MSR. */ exception is in the MSR. */
...@@ -484,6 +484,7 @@ static inline int check_io_access(struct pt_regs *regs) ...@@ -484,6 +484,7 @@ static inline int check_io_access(struct pt_regs *regs)
#define single_stepping(regs) ((regs)->msr & MSR_SE) #define single_stepping(regs) ((regs)->msr & MSR_SE)
#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE)
#define clear_br_trace(regs) ((regs)->msr &= ~MSR_BE)
#endif #endif
#if defined(CONFIG_E500) #if defined(CONFIG_E500)
...@@ -999,6 +1000,7 @@ void single_step_exception(struct pt_regs *regs) ...@@ -999,6 +1000,7 @@ void single_step_exception(struct pt_regs *regs)
enum ctx_state prev_state = exception_enter(); enum ctx_state prev_state = exception_enter();
clear_single_step(regs); clear_single_step(regs);
clear_br_trace(regs);
if (kprobe_post_handler(regs)) if (kprobe_post_handler(regs))
return; return;
......
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