]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
ARM: kprobes: Use conditional breakpoints for ARM probes
authorJon Medhurst <tixy@yxit.co.uk>
Thu, 16 Jun 2011 16:22:37 +0000 (17:22 +0100)
committerTixy <tixy@medhuaa1.miniserver.com>
Wed, 13 Jul 2011 17:32:42 +0000 (17:32 +0000)
Now we no longer trigger probes on conditional instructions when the
condition is false, we can make use of conditional instructions as
breakpoints in ARM code to avoid taking unnecessary exceptions.

Note, we can't rely on not getting an exception when the condition check
fails, as that is Implementation Defined on newer ARM architectures. We
therefore still need to perform manual condition checks as well.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
arch/arm/kernel/kprobes.c
arch/arm/kernel/kprobes.h

index b6e9a1cc1c55a50da958bd99f472f4e93d92eb44..0003dfd3b854520bd3a1d8029a65944b5c349aea 100644 (file)
@@ -138,7 +138,13 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
 
 void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
-       *p->addr = KPROBE_ARM_BREAKPOINT_INSTRUCTION;
+       kprobe_opcode_t insn = p->opcode;
+       kprobe_opcode_t brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION;
+       if (insn >= 0xe0000000)
+               brkp |= 0xe0000000;  /* Unconditional instruction */
+       else
+               brkp |= insn & 0xf0000000;  /* Copy condition from insn */
+       *p->addr = brkp;
        flush_insns(p->addr, sizeof(p->addr[0]));
 }
 
@@ -625,7 +631,7 @@ static struct undef_hook kprobes_thumb32_break_hook = {
 #else  /* !CONFIG_THUMB2_KERNEL */
 
 static struct undef_hook kprobes_arm_break_hook = {
-       .instr_mask     = 0xffffffff,
+       .instr_mask     = 0x0fffffff,
        .instr_val      = KPROBE_ARM_BREAKPOINT_INSTRUCTION,
        .cpsr_mask      = MODE_MASK,
        .cpsr_val       = SVC_MODE,
index 5e2485c4cacd5e2c88b5d9874ee282805559d015..e3803c65c4bee5c9638d3341dc13a99233415c9b 100644 (file)
@@ -21,7 +21,7 @@
  * These undefined instructions must be unique and
  * reserved solely for kprobes' use.
  */
-#define KPROBE_ARM_BREAKPOINT_INSTRUCTION      0xe7f001f8
+#define KPROBE_ARM_BREAKPOINT_INSTRUCTION      0x07f001f8
 #define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION  0xde18
 #define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION  0xf7f0a018