diff options
Diffstat (limited to 'arch/arm/kernel/kprobes-decode.c')
-rw-r--r-- | arch/arm/kernel/kprobes-decode.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c index da1f94906a4e..8bccbfa693ff 100644 --- a/arch/arm/kernel/kprobes-decode.c +++ b/arch/arm/kernel/kprobes-decode.c | |||
@@ -583,13 +583,14 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs) | |||
583 | { | 583 | { |
584 | insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0]; | 584 | insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0]; |
585 | kprobe_opcode_t insn = p->opcode; | 585 | kprobe_opcode_t insn = p->opcode; |
586 | long ppc = (long)p->addr + 8; | ||
586 | union reg_pair fnr; | 587 | union reg_pair fnr; |
587 | int rd = (insn >> 12) & 0xf; | 588 | int rd = (insn >> 12) & 0xf; |
588 | int rn = (insn >> 16) & 0xf; | 589 | int rn = (insn >> 16) & 0xf; |
589 | int rm = insn & 0xf; | 590 | int rm = insn & 0xf; |
590 | long rdv; | 591 | long rdv; |
591 | long rnv = regs->uregs[rn]; | 592 | long rnv = (rn == 15) ? ppc : regs->uregs[rn]; |
592 | long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ | 593 | long rmv = (rm == 15) ? ppc : regs->uregs[rm]; |
593 | long cpsr = regs->ARM_cpsr; | 594 | long cpsr = regs->ARM_cpsr; |
594 | 595 | ||
595 | fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn); | 596 | fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn); |