summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@kernel.org>2017-02-14 00:04:48 +0900
committerJon Medhurst <tixy@linaro.org>2017-03-21 16:24:18 +0000
commit91fc862c613ab7a0ef6b0b7755c33619127f4e5a (patch)
tree9b00473acb68d7e96b0dd5dd8093d26e1ba3ac69
parentf3fbd7ec62dec1528fb8044034e2885f2b257941 (diff)
arm: kprobes: Skip single-stepping in recursing path if possible
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>
-rw-r--r--arch/arm/probes/kprobes/core.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c
index 35148b46c4f5..269f66e66ff5 100644
--- a/arch/arm/probes/kprobes/core.c
+++ b/arch/arm/probes/kprobes/core.c
@@ -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. */