powerpc/kprobes: Some minor fixes
authorKumar Gala <galak@kernel.crashing.org>
Thu, 26 Jun 2008 06:57:58 +0000 (01:57 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Thu, 26 Jun 2008 08:35:33 +0000 (03:35 -0500)
* Mark __flush_icache_range as a function that can't be probed since its
  used by the kprobe code.

* Fix an issue with single stepping and async exceptions.  We need to
  ensure that we dont get an async exception (external, decrementer, etc)
  while we are attempting to single step the probe point.

  Added a check to ensure we only handle a single step if its really
  intended for the instruction in question.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/misc_32.S

index 23545a2f51f34d40c02f44840eb607985c5ddc4c..74693d91731ff441de8c4db172608c1de65b635e 100644 (file)
@@ -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);
index 89aaaa6f3561549c896fcd9983a04e96cba72410..6321ae36f7292d03cce3eab12db6a43369464df7 100644 (file)
@@ -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)