[PATCH 15/51] ARM: kprobes: Don't trigger probes on conditional instructions when condition is false
Nicolas Pitre
nico at fluxnic.net
Mon Jul 11 15:04:53 EDT 2011
On Sat, 9 Jul 2011, Tixy wrote:
> From: Jon Medhurst <tixy at yxit.co.uk>
>
> This patch changes the behavior of kprobes on ARM so that:
>
> Kprobes on conditional instructions don't trigger when the
> condition is false. For conditional branches, this means that
> they don't trigger in the branch not taken case.
>
> Rationale:
>
> When probes are placed onto conditionally executed instructions in a
> Thumb IT block, they may not fire if the condition is not met. This
> is because we use invalid instructions for breakpoints and "it is
> IMPLEMENTATION DEFINED whether the instruction executes as a NOP or
> causes an Undefined Instruction exception". Therefore, for consistency,
> we will ignore all probes on any conditional instructions when the
> condition is false. Alternative solutions seem to be too complex to
> implement or inconsistent.
>
> This issue was discussed on linux.arm.kernel in the thread titled
> "[RFC] kprobes with thumb2 conditional code" See
> http://comments.gmane.org/gmane.linux.linaro.devel/2985
>
> Signed-off-by: Jon Medhurst <tixy at yxit.co.uk>
Acked-by: Nicolas Pitre <nicolas.pitre at linaro.org>
> ---
> arch/arm/kernel/kprobes.c | 24 +++++++++++++++++++++++-
> 1 files changed, 23 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
> index b8f5b3b..7a9be60 100644
> --- a/arch/arm/kernel/kprobes.c
> +++ b/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. */
> --
> 1.7.2.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
More information about the linux-arm-kernel
mailing list