diff options
-rw-r--r-- | arch/powerpc/kernel/hw_breakpoint.c | 23 |
1 files changed, 7 insertions, 16 deletions
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index ed39805a3b84..241e09712314 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c | |||
@@ -197,7 +197,6 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) | |||
197 | */ | 197 | */ |
198 | int __kprobes hw_breakpoint_handler(struct die_args *args) | 198 | int __kprobes hw_breakpoint_handler(struct die_args *args) |
199 | { | 199 | { |
200 | bool is_ptrace_bp = false; | ||
201 | int rc = NOTIFY_STOP; | 200 | int rc = NOTIFY_STOP; |
202 | struct perf_event *bp; | 201 | struct perf_event *bp; |
203 | struct pt_regs *regs = args->regs; | 202 | struct pt_regs *regs = args->regs; |
@@ -208,6 +207,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
208 | 207 | ||
209 | /* Disable breakpoints during exception handling */ | 208 | /* Disable breakpoints during exception handling */ |
210 | set_dabr(0); | 209 | set_dabr(0); |
210 | |||
211 | /* | 211 | /* |
212 | * The counter may be concurrently released but that can only | 212 | * The counter may be concurrently released but that can only |
213 | * occur from a call_rcu() path. We can then safely fetch | 213 | * occur from a call_rcu() path. We can then safely fetch |
@@ -220,8 +220,6 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
220 | if (!bp) | 220 | if (!bp) |
221 | goto out; | 221 | goto out; |
222 | info = counter_arch_bp(bp); | 222 | info = counter_arch_bp(bp); |
223 | is_ptrace_bp = (bp->overflow_handler == ptrace_triggered) ? | ||
224 | true : false; | ||
225 | 223 | ||
226 | /* | 224 | /* |
227 | * Return early after invoking user-callback function without restoring | 225 | * Return early after invoking user-callback function without restoring |
@@ -229,7 +227,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
229 | * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal | 227 | * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal |
230 | * generated in do_dabr(). | 228 | * generated in do_dabr(). |
231 | */ | 229 | */ |
232 | if (is_ptrace_bp) { | 230 | if (bp->overflow_handler == ptrace_triggered) { |
233 | perf_bp_event(bp, regs); | 231 | perf_bp_event(bp, regs); |
234 | rc = NOTIFY_DONE; | 232 | rc = NOTIFY_DONE; |
235 | goto out; | 233 | goto out; |
@@ -237,19 +235,12 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
237 | 235 | ||
238 | /* | 236 | /* |
239 | * Verify if dar lies within the address range occupied by the symbol | 237 | * Verify if dar lies within the address range occupied by the symbol |
240 | * being watched to filter extraneous exceptions. | 238 | * being watched to filter extraneous exceptions. If it doesn't, |
239 | * we still need to single-step the instruction, but we don't | ||
240 | * generate an event. | ||
241 | */ | 241 | */ |
242 | if (!((bp->attr.bp_addr <= dar) && | 242 | info->extraneous_interrupt = !((bp->attr.bp_addr <= dar) && |
243 | (dar <= (bp->attr.bp_addr + bp->attr.bp_len)))) { | 243 | (dar - bp->attr.bp_addr < bp->attr.bp_len)); |
244 | /* | ||
245 | * This exception is triggered not because of a memory access | ||
246 | * on the monitored variable but in the double-word address | ||
247 | * range in which it is contained. We will consume this | ||
248 | * exception, considering it as 'noise'. | ||
249 | */ | ||
250 | info->extraneous_interrupt = true; | ||
251 | } else | ||
252 | info->extraneous_interrupt = false; | ||
253 | 244 | ||
254 | /* Do not emulate user-space instructions, instead single-step them */ | 245 | /* Do not emulate user-space instructions, instead single-step them */ |
255 | if (user_mode(regs)) { | 246 | if (user_mode(regs)) { |