kprobes: fix to use text_mutex around arm/disarm kprobe
authorMasami Hiramatsu <mhiramat@redhat.com>
Thu, 7 May 2009 20:31:26 +0000 (16:31 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 May 2009 23:23:48 +0000 (16:23 -0700)
Fix kprobes to lock text_mutex around some arch_arm/disarm_kprobe() which
are newly added by commit de5bd88d5a5cce3cacea904d3503e5ebdb3852a2.

Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
kernel/kprobes.c

index a5e74dd..c0fa54b 100644 (file)
@@ -319,6 +319,22 @@ struct kprobe __kprobes *get_kprobe(void *addr)
        return NULL;
 }
 
        return NULL;
 }
 
+/* Arm a kprobe with text_mutex */
+static void __kprobes arm_kprobe(struct kprobe *kp)
+{
+       mutex_lock(&text_mutex);
+       arch_arm_kprobe(kp);
+       mutex_unlock(&text_mutex);
+}
+
+/* Disarm a kprobe with text_mutex */
+static void __kprobes disarm_kprobe(struct kprobe *kp)
+{
+       mutex_lock(&text_mutex);
+       arch_disarm_kprobe(kp);
+       mutex_unlock(&text_mutex);
+}
+
 /*
  * Aggregate handlers for multiple kprobes support - these handlers
  * take care of invoking the individual kprobe handlers on p->list
 /*
  * Aggregate handlers for multiple kprobes support - these handlers
  * take care of invoking the individual kprobe handlers on p->list
@@ -538,7 +554,7 @@ static int __kprobes add_new_kprobe(struct kprobe *ap, struct kprobe *p)
                ap->flags &= ~KPROBE_FLAG_DISABLED;
                if (!kprobes_all_disarmed)
                        /* Arm the breakpoint again. */
                ap->flags &= ~KPROBE_FLAG_DISABLED;
                if (!kprobes_all_disarmed)
                        /* Arm the breakpoint again. */
-                       arch_arm_kprobe(ap);
+                       arm_kprobe(ap);
        }
        return 0;
 }
        }
        return 0;
 }
@@ -789,11 +805,8 @@ static int __kprobes __unregister_kprobe_top(struct kprobe *p)
                 * enabled and not gone - otherwise, the breakpoint would
                 * already have been removed. We save on flushing icache.
                 */
                 * enabled and not gone - otherwise, the breakpoint would
                 * already have been removed. We save on flushing icache.
                 */
-               if (!kprobes_all_disarmed && !kprobe_disabled(old_p)) {
-                       mutex_lock(&text_mutex);
-                       arch_disarm_kprobe(p);
-                       mutex_unlock(&text_mutex);
-               }
+               if (!kprobes_all_disarmed && !kprobe_disabled(old_p))
+                       disarm_kprobe(p);
                hlist_del_rcu(&old_p->hlist);
        } else {
                if (p->break_handler && !kprobe_gone(p))
                hlist_del_rcu(&old_p->hlist);
        } else {
                if (p->break_handler && !kprobe_gone(p))
@@ -810,7 +823,7 @@ noclean:
                if (!kprobe_disabled(old_p)) {
                        try_to_disable_aggr_kprobe(old_p);
                        if (!kprobes_all_disarmed && kprobe_disabled(old_p))
                if (!kprobe_disabled(old_p)) {
                        try_to_disable_aggr_kprobe(old_p);
                        if (!kprobes_all_disarmed && kprobe_disabled(old_p))
-                               arch_disarm_kprobe(old_p);
+                               disarm_kprobe(old_p);
                }
        }
        return 0;
                }
        }
        return 0;
@@ -1364,7 +1377,7 @@ int __kprobes disable_kprobe(struct kprobe *kp)
                try_to_disable_aggr_kprobe(p);
 
        if (!kprobes_all_disarmed && kprobe_disabled(p))
                try_to_disable_aggr_kprobe(p);
 
        if (!kprobes_all_disarmed && kprobe_disabled(p))
-               arch_disarm_kprobe(p);
+               disarm_kprobe(p);
 out:
        mutex_unlock(&kprobe_mutex);
        return ret;
 out:
        mutex_unlock(&kprobe_mutex);
        return ret;
@@ -1393,7 +1406,7 @@ int __kprobes enable_kprobe(struct kprobe *kp)
        }
 
        if (!kprobes_all_disarmed && kprobe_disabled(p))
        }
 
        if (!kprobes_all_disarmed && kprobe_disabled(p))
-               arch_arm_kprobe(p);
+               arm_kprobe(p);
 
        p->flags &= ~KPROBE_FLAG_DISABLED;
        if (p != kp)
 
        p->flags &= ~KPROBE_FLAG_DISABLED;
        if (p != kp)