aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-04-18 03:53:57 -0400
committerNicolas Pitre <nicolas.pitre@linaro.org>2011-04-28 23:40:59 -0400
commit41713d1396312a027ec02abc4767041627c178ef (patch)
tree778fedcc66cf4e15ca1e0eeb8502715bd84d021d
parentf0aeb8bff0fe9de50e1e4093ef86ff8f17a9b1b0 (diff)
ARM: kprobes: Fix emulation of PLD instructions
The PLD instructions wasn't being decoded correctly and the emulation code wasn't adjusting PC correctly. As the PLD instruction is only a performance hint we emulate it as a simple nop, and we can broaden the instruction decoding to take into account newer PLI and PLDW instructions. Signed-off-by: Jon Medhurst <tixy@yxit.co.uk> Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
-rw-r--r--arch/arm/kernel/kprobes-decode.c21
1 files changed, 8 insertions, 13 deletions
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index b81fbfb33151..bddf8d0f3dc1 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -657,14 +657,8 @@ static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
657 insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); 657 insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
658} 658}
659 659
660static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs) 660static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs)
661{ 661{
662 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
663 kprobe_opcode_t insn = p->opcode;
664 int rn = (insn >> 16) & 0xf;
665 long rnv = regs->uregs[rn];
666
667 insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
668} 662}
669 663
670static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs) 664static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
@@ -941,12 +935,13 @@ space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
941 (insn & 0xfe5f0f00) == 0xf84d0500) 935 (insn & 0xfe5f0f00) == 0xf84d0500)
942 return INSN_REJECTED; 936 return INSN_REJECTED;
943 937
944 /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */ 938 /* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */
945 if ((insn & 0xfd700000) == 0xf4500000) { 939 /* PLDI : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */
946 insn &= 0xfff0ffff; /* Rn = r0 */ 940 /* PLDW : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */
947 asi->insn[0] = insn; 941 /* PLD : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */
948 asi->insn_handler = emulate_rn16; 942 if ((insn & 0xfe300000) == 0xf4100000) {
949 return INSN_GOOD; 943 asi->insn_handler = emulate_nop;
944 return INSN_GOOD_NO_SLOT;
950 } 945 }
951 946
952 /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */ 947 /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */