arm: kprobes: Skip single-stepping in recursing path if possible
authorMasami Hiramatsu <mhiramat@kernel.org>
Mon, 13 Feb 2017 15:04:48 +0000 (00:04 +0900)
committerJon Medhurst <tixy@linaro.org>
Tue, 21 Mar 2017 16:24:18 +0000 (16:24 +0000)
Kprobes/arm skips single-stepping (moreover handling the event)
if the conditional instruction must not be executed. This
also apply the rule when we hit the recursing kprobe, so
that kprobe does not count nmissed up in that case.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Jon Medhurst <tixy@linaro.org>
arch/arm/probes/kprobes/core.c

index 35148b46c4f5ed79c786cf731242284e40b98e91..269f66e66ff5a4ab8647256af90f0d7028f6718d 100644 (file)
@@ -266,7 +266,15 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
 #endif
 
        if (p) {
-               if (cur) {
+               if (!p->ainsn.insn_check_cc(regs->ARM_cpsr)) {
+                       /*
+                        * Probe hit but conditional execution check failed,
+                        * so just skip the instruction and continue as if
+                        * nothing had happened.
+                        * In this case, we can skip recursing check too.
+                        */
+                       singlestep_skip(p, regs);
+               } else if (cur) {
                        /* Kprobe is pending, so we're recursing. */
                        switch (kcb->kprobe_status) {
                        case KPROBE_HIT_ACTIVE:
@@ -289,7 +297,7 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
                                /* impossible cases */
                                BUG();
                        }
-               } else if (p->ainsn.insn_check_cc(regs->ARM_cpsr)) {
+               } else {
                        /* Probe hit and conditional execution check ok. */
                        set_current_kprobe(p);
                        kcb->kprobe_status = KPROBE_HIT_ACTIVE;
@@ -310,13 +318,6 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
                                }
                                reset_current_kprobe();
                        }
-               } else {
-                       /*
-                        * Probe hit but conditional execution check failed,
-                        * so just skip the instruction and continue as if
-                        * nothing had happened.
-                        */
-                       singlestep_skip(p, regs);
                }
        } else if (cur) {
                /* We probably hit a jprobe.  Call its break handler. */