diff options
| author | Masami Hiramatsu <mhiramat@redhat.com> | 2009-05-07 16:31:26 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-05-08 19:23:48 -0400 |
| commit | 201517a7f3ec497fff545a7659c6c876f89f9054 (patch) | |
| tree | 47721de5b13043eb9e7e10aaf7fe544c794a3c7d /kernel | |
| parent | d7a5926978cb109b2db5985c65086483caf9e226 (diff) | |
kprobes: fix to use text_mutex around arm/disarm kprobe
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>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kprobes.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index a5e74ddee0e2..c0fa54b276d9 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -319,6 +319,22 @@ struct kprobe __kprobes *get_kprobe(void *addr) | |||
| 319 | return NULL; | 319 | return NULL; |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | /* Arm a kprobe with text_mutex */ | ||
| 323 | static void __kprobes arm_kprobe(struct kprobe *kp) | ||
| 324 | { | ||
| 325 | mutex_lock(&text_mutex); | ||
| 326 | arch_arm_kprobe(kp); | ||
| 327 | mutex_unlock(&text_mutex); | ||
| 328 | } | ||
| 329 | |||
| 330 | /* Disarm a kprobe with text_mutex */ | ||
| 331 | static void __kprobes disarm_kprobe(struct kprobe *kp) | ||
| 332 | { | ||
| 333 | mutex_lock(&text_mutex); | ||
| 334 | arch_disarm_kprobe(kp); | ||
| 335 | mutex_unlock(&text_mutex); | ||
| 336 | } | ||
| 337 | |||
| 322 | /* | 338 | /* |
| 323 | * Aggregate handlers for multiple kprobes support - these handlers | 339 | * Aggregate handlers for multiple kprobes support - these handlers |
| 324 | * take care of invoking the individual kprobe handlers on p->list | 340 | * 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) | |||
| 538 | ap->flags &= ~KPROBE_FLAG_DISABLED; | 554 | ap->flags &= ~KPROBE_FLAG_DISABLED; |
| 539 | if (!kprobes_all_disarmed) | 555 | if (!kprobes_all_disarmed) |
| 540 | /* Arm the breakpoint again. */ | 556 | /* Arm the breakpoint again. */ |
| 541 | arch_arm_kprobe(ap); | 557 | arm_kprobe(ap); |
| 542 | } | 558 | } |
| 543 | return 0; | 559 | return 0; |
| 544 | } | 560 | } |
| @@ -789,11 +805,8 @@ static int __kprobes __unregister_kprobe_top(struct kprobe *p) | |||
| 789 | * enabled and not gone - otherwise, the breakpoint would | 805 | * enabled and not gone - otherwise, the breakpoint would |
| 790 | * already have been removed. We save on flushing icache. | 806 | * already have been removed. We save on flushing icache. |
| 791 | */ | 807 | */ |
| 792 | if (!kprobes_all_disarmed && !kprobe_disabled(old_p)) { | 808 | if (!kprobes_all_disarmed && !kprobe_disabled(old_p)) |
| 793 | mutex_lock(&text_mutex); | 809 | disarm_kprobe(p); |
| 794 | arch_disarm_kprobe(p); | ||
| 795 | mutex_unlock(&text_mutex); | ||
| 796 | } | ||
| 797 | hlist_del_rcu(&old_p->hlist); | 810 | hlist_del_rcu(&old_p->hlist); |
| 798 | } else { | 811 | } else { |
| 799 | if (p->break_handler && !kprobe_gone(p)) | 812 | if (p->break_handler && !kprobe_gone(p)) |
| @@ -810,7 +823,7 @@ noclean: | |||
| 810 | if (!kprobe_disabled(old_p)) { | 823 | if (!kprobe_disabled(old_p)) { |
| 811 | try_to_disable_aggr_kprobe(old_p); | 824 | try_to_disable_aggr_kprobe(old_p); |
| 812 | if (!kprobes_all_disarmed && kprobe_disabled(old_p)) | 825 | if (!kprobes_all_disarmed && kprobe_disabled(old_p)) |
| 813 | arch_disarm_kprobe(old_p); | 826 | disarm_kprobe(old_p); |
| 814 | } | 827 | } |
| 815 | } | 828 | } |
| 816 | return 0; | 829 | return 0; |
| @@ -1364,7 +1377,7 @@ int __kprobes disable_kprobe(struct kprobe *kp) | |||
| 1364 | try_to_disable_aggr_kprobe(p); | 1377 | try_to_disable_aggr_kprobe(p); |
| 1365 | 1378 | ||
| 1366 | if (!kprobes_all_disarmed && kprobe_disabled(p)) | 1379 | if (!kprobes_all_disarmed && kprobe_disabled(p)) |
| 1367 | arch_disarm_kprobe(p); | 1380 | disarm_kprobe(p); |
| 1368 | out: | 1381 | out: |
| 1369 | mutex_unlock(&kprobe_mutex); | 1382 | mutex_unlock(&kprobe_mutex); |
| 1370 | return ret; | 1383 | return ret; |
| @@ -1393,7 +1406,7 @@ int __kprobes enable_kprobe(struct kprobe *kp) | |||
| 1393 | } | 1406 | } |
| 1394 | 1407 | ||
| 1395 | if (!kprobes_all_disarmed && kprobe_disabled(p)) | 1408 | if (!kprobes_all_disarmed && kprobe_disabled(p)) |
| 1396 | arch_arm_kprobe(p); | 1409 | arm_kprobe(p); |
| 1397 | 1410 | ||
| 1398 | p->flags &= ~KPROBE_FLAG_DISABLED; | 1411 | p->flags &= ~KPROBE_FLAG_DISABLED; |
| 1399 | if (p != kp) | 1412 | if (p != kp) |
