diff options
-rw-r--r-- | arch/powerpc/kernel/kprobes.c | 9 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_32.S | 2 |
2 files changed, 10 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 23545a2f51f3..74693d91731f 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -95,6 +95,11 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) { + /* We turn off async exceptions to ensure that the single step will + * be for the instruction we have the kprobe on, if we dont its + * possible we'd get the single step reported for an exception handler + * like Decrementer or External Interrupt */ + regs->msr &= ~MSR_EE; regs->msr |= MSR_SE; /* @@ -376,6 +381,10 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) if (!cur) return 0; + /* make sure we got here for instruction we have a kprobe on */ + if (((unsigned long)cur->ainsn.insn + 4) != regs->nip) + return 0; + if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { kcb->kprobe_status = KPROBE_HIT_SSDONE; cur->post_handler(cur, regs, 0); diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 89aaaa6f3561..6321ae36f729 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -489,7 +489,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE) * * flush_icache_range(unsigned long start, unsigned long stop) */ -_GLOBAL(__flush_icache_range) +_KPROBE(__flush_icache_range) BEGIN_FTR_SECTION blr /* for 601, do nothing */ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) |