summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 b6e9a1cc1c5..0003dfd3b85 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 5e2485c4cac..e3803c65c4b 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