ARM: 6226/1: fix kprobe bug in ldr instruction emulation
authorNicolas Pitre <nico@fluxnic.net>
Wed, 14 Jul 2010 04:21:22 +0000 (05:21 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 14 Jul 2010 22:28:06 +0000 (23:28 +0100)
From: Bin Yang <bin.yang@marvell.com>

Cc: stable@kernel.org
Signed-off-by: Bin Yang <bin.yang@marvell.com>
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/kernel/kprobes-decode.c

index da1f949..8bccbfa 100644 (file)
@@ -583,13 +583,14 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
 {
        insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
        kprobe_opcode_t insn = p->opcode;
+       long ppc = (long)p->addr + 8;
        union reg_pair fnr;
        int rd = (insn >> 12) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;
        long rdv;
-       long rnv  = regs->uregs[rn];
-       long rmv  = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
+       long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+       long rmv = (rm == 15) ? ppc : regs->uregs[rm];
        long cpsr = regs->ARM_cpsr;
 
        fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);