diff options
-rw-r--r-- | arch/arm/kernel/kprobes.c | 10 | ||||
-rw-r--r-- | arch/arm/kernel/kprobes.h | 2 |
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 |