At the time being we have something like

        if (something) {
                p = get();
                if (p) {
                        if (something_wrong)
                                goto out;
                        ...
                        return;
                } else if (a != b) {
                        if (some_error)
                                goto out;
                        ...
                }
                goto out;
        }
        p = get();
        if (!p) {
                if (a != b) {
                        if (some_error)
                                goto out;
                        ...
                }
                goto out;
        }

This is similar to

        p = get();
        if (!p) {
                if (a != b) {
                        if (some_error)
                                goto out;
                        ...
                }
                goto out;
        }
        if (something) {
                if (something_wrong)
                        goto out;
                ...
                return;
        }

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
v2: Reverse the logic by testing (!p) before kprobe_running() as suggested by 
Naveen.
---
 arch/powerpc/kernel/kprobes.c | 80 ++++++++++++++---------------------
 1 file changed, 32 insertions(+), 48 deletions(-)

diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 9b340af02c38..84567406b53d 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -274,54 +274,6 @@ int kprobe_handler(struct pt_regs *regs)
        preempt_disable();
        kcb = get_kprobe_ctlblk();
 
-       /* Check we're not actually recursing */
-       if (kprobe_running()) {
-               p = get_kprobe(addr);
-               if (p) {
-                       kprobe_opcode_t insn = *p->ainsn.insn;
-                       if (kcb->kprobe_status == KPROBE_HIT_SS &&
-                                       is_trap(insn)) {
-                               /* Turn off 'trace' bits */
-                               regs->msr &= ~MSR_SINGLESTEP;
-                               regs->msr |= kcb->kprobe_saved_msr;
-                               goto no_kprobe;
-                       }
-                       /* We have reentered the kprobe_handler(), since
-                        * another probe was hit while within the handler.
-                        * We here save the original kprobes variables and
-                        * just single step on the instruction of the new probe
-                        * without calling any user handlers.
-                        */
-                       save_previous_kprobe(kcb);
-                       set_current_kprobe(p, regs, kcb);
-                       kprobes_inc_nmissed_count(p);
-                       kcb->kprobe_status = KPROBE_REENTER;
-                       if (p->ainsn.boostable >= 0) {
-                               ret = try_to_emulate(p, regs);
-
-                               if (ret > 0) {
-                                       restore_previous_kprobe(kcb);
-                                       preempt_enable_no_resched();
-                                       return 1;
-                               }
-                       }
-                       prepare_singlestep(p, regs);
-                       return 1;
-               } else if (*addr != BREAKPOINT_INSTRUCTION) {
-                       /* If trap variant, then it belongs not to us */
-                       kprobe_opcode_t cur_insn = *addr;
-
-                       if (is_trap(cur_insn))
-                               goto no_kprobe;
-                       /* The breakpoint instruction was removed by
-                        * another cpu right after we hit, no further
-                        * handling of this interrupt is appropriate
-                        */
-                       ret = 1;
-               }
-               goto no_kprobe;
-       }
-
        p = get_kprobe(addr);
        if (!p) {
                if (*addr != BREAKPOINT_INSTRUCTION) {
@@ -346,6 +298,38 @@ int kprobe_handler(struct pt_regs *regs)
                goto no_kprobe;
        }
 
+       /* Check we're not actually recursing */
+       if (kprobe_running()) {
+               kprobe_opcode_t insn = *p->ainsn.insn;
+               if (kcb->kprobe_status == KPROBE_HIT_SS && is_trap(insn)) {
+                       /* Turn off 'trace' bits */
+                       regs->msr &= ~MSR_SINGLESTEP;
+                       regs->msr |= kcb->kprobe_saved_msr;
+                       goto no_kprobe;
+               }
+               /* We have reentered the kprobe_handler(), since
+                * another probe was hit while within the handler.
+                * We here save the original kprobes variables and
+                * just single step on the instruction of the new probe
+                * without calling any user handlers.
+                */
+               save_previous_kprobe(kcb);
+               set_current_kprobe(p, regs, kcb);
+               kprobes_inc_nmissed_count(p);
+               kcb->kprobe_status = KPROBE_REENTER;
+               if (p->ainsn.boostable >= 0) {
+                       ret = try_to_emulate(p, regs);
+
+                       if (ret > 0) {
+                               restore_previous_kprobe(kcb);
+                               preempt_enable_no_resched();
+                               return 1;
+                       }
+               }
+               prepare_singlestep(p, regs);
+               return 1;
+       }
+
        kcb->kprobe_status = KPROBE_HIT_ACTIVE;
        set_current_kprobe(p, regs, kcb);
        if (p->pre_handler && p->pre_handler(p, regs)) {
-- 
2.25.0

Reply via email to