[PATCH] Kprobes/IA64: check jprobe break before handling
authorKeshavamurthy Anil S <anil.s.keshavamurthy@intel.com>
Thu, 23 Jun 2005 07:09:35 +0000 (00:09 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 23 Jun 2005 16:45:24 +0000 (09:45 -0700)
Once the jprobe instrumented function returns, it executes a jprobe_break
which is a break instruction with __IA64_JPROBE_BREAK value.  The current
patch checks for this break value, before assuming that jprobe instrumented
function just completed.

The previous code was not checking for this value and that was a bug.

Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/ia64/kernel/kprobes.c

index 027d656..41e80b4 100644 (file)
@@ -419,10 +419,11 @@ static void prepare_ss(struct kprobe *p, struct pt_regs *regs)
        ia64_psr(regs)->ss = 1;
 }
 
-static int pre_kprobes_handler(struct pt_regs *regs)
+static int pre_kprobes_handler(struct die_args *args)
 {
        struct kprobe *p;
        int ret = 0;
+       struct pt_regs *regs = args->regs;
        kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
 
        preempt_disable();
@@ -437,7 +438,7 @@ static int pre_kprobes_handler(struct pt_regs *regs)
                        }
                        arch_disarm_kprobe(p);
                        ret = 1;
-               } else {
+               } else if (args->err == __IA64_BREAK_JPROBE) {
                        /*
                         * jprobe instrumented function just completed
                         */
@@ -445,6 +446,9 @@ static int pre_kprobes_handler(struct pt_regs *regs)
                        if (p->break_handler && p->break_handler(p, regs)) {
                                goto ss_probe;
                        }
+               } else {
+                       /* Not our break */
+                       goto no_kprobe;
                }
        }
 
@@ -515,7 +519,7 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
        struct die_args *args = (struct die_args *)data;
        switch(val) {
        case DIE_BREAK:
-               if (pre_kprobes_handler(args->regs))
+               if (pre_kprobes_handler(args))
                        return NOTIFY_STOP;
                break;
        case DIE_SS: