summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-06-16 17:22:37 +0100
committerTixy <tixy@medhuaa1.miniserver.com>2011-07-13 17:32:42 +0000
commit3b26945597d5eff5d428a268c9d109338fce801e (patch)
tree846f3125796ecae7645a6ed2b96744f2a99eaba7
parent3cca6c243568d355c1ccecaaa71bf490f014d729 (diff)
downloadop-kernel-dev-3b26945597d5eff5d428a268c9d109338fce801e.zip
op-kernel-dev-3b26945597d5eff5d428a268c9d109338fce801e.tar.gz
ARM: kprobes: Use conditional breakpoints for ARM probes
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>
-rw-r--r--arch/arm/kernel/kprobes.c10
-rw-r--r--arch/arm/kernel/kprobes.h2
2 files changed, 9 insertions, 3 deletions
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index b6e9a1c..0003dfd 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -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,
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h
index 5e2485c..e3803c6 100644
--- a/arch/arm/kernel/kprobes.h
+++ b/arch/arm/kernel/kprobes.h
@@ -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
OpenPOWER on IntegriCloud