Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/kprobes: Don't call the ->break_handler() in powerpc kprobes code

Don't call the ->break_handler() from the powerpc kprobes code,
because it was only used by jprobes which got removed.

This also removes skip_singlestep() and embeds it in the
caller, kprobe_ftrace_handler(), which simplifies regs->nip
operation around there.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: linux-arch@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Link: https://lore.kernel.org/lkml/152942477127.15209.8982613703787878618.stgit@devbox
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Masami Hiramatsu and committed by
Ingo Molnar
6e5fd3a2 c9abd554

+23 -64
-10
arch/powerpc/include/asm/kprobes.h
··· 102 102 extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); 103 103 extern int kprobe_handler(struct pt_regs *regs); 104 104 extern int kprobe_post_handler(struct pt_regs *regs); 105 - #ifdef CONFIG_KPROBES_ON_FTRACE 106 - extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs, 107 - struct kprobe_ctlblk *kcb); 108 - #else 109 - static inline int skip_singlestep(struct kprobe *p, struct pt_regs *regs, 110 - struct kprobe_ctlblk *kcb) 111 - { 112 - return 0; 113 - } 114 - #endif 115 105 #else 116 106 static inline int kprobe_handler(struct pt_regs *regs) { return 0; } 117 107 static inline int kprobe_post_handler(struct pt_regs *regs) { return 0; }
+12 -34
arch/powerpc/kernel/kprobes-ftrace.c
··· 25 25 #include <linux/preempt.h> 26 26 #include <linux/ftrace.h> 27 27 28 - static nokprobe_inline 29 - int __skip_singlestep(struct kprobe *p, struct pt_regs *regs, 30 - struct kprobe_ctlblk *kcb, unsigned long orig_nip) 31 - { 32 - /* 33 - * Emulate singlestep (and also recover regs->nip) 34 - * as if there is a nop 35 - */ 36 - regs->nip = (unsigned long)p->addr + MCOUNT_INSN_SIZE; 37 - if (unlikely(p->post_handler)) { 38 - kcb->kprobe_status = KPROBE_HIT_SSDONE; 39 - p->post_handler(p, regs, 0); 40 - } 41 - __this_cpu_write(current_kprobe, NULL); 42 - if (orig_nip) 43 - regs->nip = orig_nip; 44 - return 1; 45 - } 46 - 47 - int skip_singlestep(struct kprobe *p, struct pt_regs *regs, 48 - struct kprobe_ctlblk *kcb) 49 - { 50 - if (kprobe_ftrace(p)) 51 - return __skip_singlestep(p, regs, kcb, 0); 52 - else 53 - return 0; 54 - } 55 - NOKPROBE_SYMBOL(skip_singlestep); 56 - 57 28 /* Ftrace callback handler for kprobes */ 58 29 void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip, 59 30 struct ftrace_ops *ops, struct pt_regs *regs) ··· 42 71 if (kprobe_running()) { 43 72 kprobes_inc_nmissed_count(p); 44 73 } else { 45 - unsigned long orig_nip = regs->nip; 46 - 47 74 /* 48 75 * On powerpc, NIP is *before* this instruction for the 49 76 * pre handler ··· 50 81 51 82 __this_cpu_write(current_kprobe, p); 52 83 kcb->kprobe_status = KPROBE_HIT_ACTIVE; 53 - if (!p->pre_handler || !p->pre_handler(p, regs)) 54 - __skip_singlestep(p, regs, kcb, orig_nip); 55 - else { 84 + if (!p->pre_handler || !p->pre_handler(p, regs)) { 85 + /* 86 + * Emulate singlestep (and also recover regs->nip) 87 + * as if there is a nop 88 + */ 89 + regs->nip += MCOUNT_INSN_SIZE; 90 + if (unlikely(p->post_handler)) { 91 + kcb->kprobe_status = KPROBE_HIT_SSDONE; 92 + p->post_handler(p, regs, 0); 93 + } 94 + __this_cpu_write(current_kprobe, NULL); 95 + } else { 56 96 /* 57 97 * If pre_handler returns !0, it sets regs->nip and 58 98 * resets current kprobe. In this case, we should not
+11 -20
arch/powerpc/kernel/kprobes.c
··· 317 317 } 318 318 prepare_singlestep(p, regs); 319 319 return 1; 320 - } else { 321 - if (*addr != BREAKPOINT_INSTRUCTION) { 322 - /* If trap variant, then it belongs not to us */ 323 - kprobe_opcode_t cur_insn = *addr; 324 - if (is_trap(cur_insn)) 325 - goto no_kprobe; 326 - /* The breakpoint instruction was removed by 327 - * another cpu right after we hit, no further 328 - * handling of this interrupt is appropriate 329 - */ 330 - ret = 1; 320 + } else if (*addr != BREAKPOINT_INSTRUCTION) { 321 + /* If trap variant, then it belongs not to us */ 322 + kprobe_opcode_t cur_insn = *addr; 323 + 324 + if (is_trap(cur_insn)) 331 325 goto no_kprobe; 332 - } 333 - p = __this_cpu_read(current_kprobe); 334 - if (p->break_handler && p->break_handler(p, regs)) { 335 - if (!skip_singlestep(p, regs, kcb)) 336 - goto ss_probe; 337 - ret = 1; 338 - } 326 + /* The breakpoint instruction was removed by 327 + * another cpu right after we hit, no further 328 + * handling of this interrupt is appropriate 329 + */ 330 + ret = 1; 339 331 } 340 332 goto no_kprobe; 341 333 } ··· 342 350 */ 343 351 kprobe_opcode_t cur_insn = *addr; 344 352 if (is_trap(cur_insn)) 345 - goto no_kprobe; 353 + goto no_kprobe; 346 354 /* 347 355 * The breakpoint instruction was removed right 348 356 * after we hit it. Another cpu has removed ··· 362 370 /* handler has already set things up, so skip ss setup */ 363 371 return 1; 364 372 365 - ss_probe: 366 373 if (p->ainsn.boostable >= 0) { 367 374 ret = try_to_emulate(p, regs); 368 375