From 0150bbcab8b06988f5ca18cccb968da9ee7737e4 Mon Sep 17 00:00:00 2001 From: Jon Medhurst Date: Thu, 16 Jun 2011 15:54:00 +0100 Subject: [PATCH] --- yaml --- r: 258334 b: refs/heads/master c: 3cca6c243568d355c1ccecaaa71bf490f014d729 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/arm/kernel/kprobes.c | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index e5c15a3910d7..f7e6fccdb2aa 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6aaa8b5570c7b5b9eb8913ec80263a1012b1dd66 +refs/heads/master: 3cca6c243568d355c1ccecaaa71bf490f014d729 diff --git a/trunk/arch/arm/kernel/kprobes.c b/trunk/arch/arm/kernel/kprobes.c index a9050bad4434..b6e9a1cc1c55 100644 --- a/trunk/arch/arm/kernel/kprobes.c +++ b/trunk/arch/arm/kernel/kprobes.c @@ -207,6 +207,20 @@ static void __kprobes set_current_kprobe(struct kprobe *p) __get_cpu_var(current_kprobe) = p; } +static void __kprobes +singlestep_skip(struct kprobe *p, struct pt_regs *regs) +{ +#ifdef CONFIG_THUMB2_KERNEL + regs->ARM_cpsr = it_advance(regs->ARM_cpsr); + if (is_wide_instruction(p->opcode)) + regs->ARM_pc += 4; + else + regs->ARM_pc += 2; +#else + regs->ARM_pc += 4; +#endif +} + static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { @@ -262,7 +276,8 @@ void __kprobes kprobe_handler(struct pt_regs *regs) /* impossible cases */ BUG(); } - } else { + } else if (p->ainsn.insn_check_cc(regs->ARM_cpsr)) { + /* Probe hit and conditional execution check ok. */ set_current_kprobe(p); kcb->kprobe_status = KPROBE_HIT_ACTIVE; @@ -282,6 +297,13 @@ 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. */