aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/kprobes.c
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-06-16 12:22:37 -0400
committerTixy <tixy@medhuaa1.miniserver.com>2011-07-13 13:32:42 -0400
commit3b26945597d5eff5d428a268c9d109338fce801e (patch)
tree846f3125796ecae7645a6ed2b96744f2a99eaba7 /arch/arm/kernel/kprobes.c
parent3cca6c243568d355c1ccecaaa71bf490f014d729 (diff)
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>
Diffstat (limited to 'arch/arm/kernel/kprobes.c')
-rw-r--r--arch/arm/kernel/kprobes.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index b6e9a1cc1c55..0003dfd3b854 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)
138 138
139void __kprobes arch_arm_kprobe(struct kprobe *p) 139void __kprobes arch_arm_kprobe(struct kprobe *p)
140{ 140{
141 *p->addr = KPROBE_ARM_BREAKPOINT_INSTRUCTION; 141 kprobe_opcode_t insn = p->opcode;
142 kprobe_opcode_t brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION;
143 if (insn >= 0xe0000000)
144 brkp |= 0xe0000000; /* Unconditional instruction */
145 else
146 brkp |= insn & 0xf0000000; /* Copy condition from insn */
147 *p->addr = brkp;
142 flush_insns(p->addr, sizeof(p->addr[0])); 148 flush_insns(p->addr, sizeof(p->addr[0]));
143} 149}
144 150
@@ -625,7 +631,7 @@ static struct undef_hook kprobes_thumb32_break_hook = {
625#else /* !CONFIG_THUMB2_KERNEL */ 631#else /* !CONFIG_THUMB2_KERNEL */
626 632
627static struct undef_hook kprobes_arm_break_hook = { 633static struct undef_hook kprobes_arm_break_hook = {
628 .instr_mask = 0xffffffff, 634 .instr_mask = 0x0fffffff,
629 .instr_val = KPROBE_ARM_BREAKPOINT_INSTRUCTION, 635 .instr_val = KPROBE_ARM_BREAKPOINT_INSTRUCTION,
630 .cpsr_mask = MODE_MASK, 636 .cpsr_mask = MODE_MASK,
631 .cpsr_val = SVC_MODE, 637 .cpsr_val = SVC_MODE,