diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-03-08 11:48:51 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-03-08 11:48:51 -0400 |
| commit | dba58e39ced7af63f2748d12bbb2b4ac83c72391 (patch) | |
| tree | ee15a5e7667b51d0d0f7e8cb39064652f7c84c28 /kernel/kprobes.c | |
| parent | 9de36825b321fe9fe9cf73260554251af579f4ca (diff) | |
| parent | 78ff7fae04554b49d29226ed12536268c2500d1f (diff) | |
Merge branches 'tracing/doc', 'tracing/ftrace', 'tracing/printk' and 'tracing/textedit' into tracing/core
Diffstat (limited to 'kernel/kprobes.c')
| -rw-r--r-- | kernel/kprobes.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 7ba8cd9845cb..479d4d5672f9 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <linux/seq_file.h> | 43 | #include <linux/seq_file.h> |
| 44 | #include <linux/debugfs.h> | 44 | #include <linux/debugfs.h> |
| 45 | #include <linux/kdebug.h> | 45 | #include <linux/kdebug.h> |
| 46 | #include <linux/memory.h> | ||
| 46 | 47 | ||
| 47 | #include <asm-generic/sections.h> | 48 | #include <asm-generic/sections.h> |
| 48 | #include <asm/cacheflush.h> | 49 | #include <asm/cacheflush.h> |
| @@ -699,9 +700,10 @@ int __kprobes register_kprobe(struct kprobe *p) | |||
| 699 | goto out; | 700 | goto out; |
| 700 | } | 701 | } |
| 701 | 702 | ||
| 703 | mutex_lock(&text_mutex); | ||
| 702 | ret = arch_prepare_kprobe(p); | 704 | ret = arch_prepare_kprobe(p); |
| 703 | if (ret) | 705 | if (ret) |
| 704 | goto out; | 706 | goto out_unlock_text; |
| 705 | 707 | ||
| 706 | INIT_HLIST_NODE(&p->hlist); | 708 | INIT_HLIST_NODE(&p->hlist); |
| 707 | hlist_add_head_rcu(&p->hlist, | 709 | hlist_add_head_rcu(&p->hlist, |
| @@ -710,6 +712,8 @@ int __kprobes register_kprobe(struct kprobe *p) | |||
| 710 | if (kprobe_enabled) | 712 | if (kprobe_enabled) |
| 711 | arch_arm_kprobe(p); | 713 | arch_arm_kprobe(p); |
| 712 | 714 | ||
| 715 | out_unlock_text: | ||
| 716 | mutex_unlock(&text_mutex); | ||
| 713 | out: | 717 | out: |
| 714 | mutex_unlock(&kprobe_mutex); | 718 | mutex_unlock(&kprobe_mutex); |
| 715 | 719 | ||
| @@ -746,8 +750,11 @@ valid_p: | |||
| 746 | * enabled and not gone - otherwise, the breakpoint would | 750 | * enabled and not gone - otherwise, the breakpoint would |
| 747 | * already have been removed. We save on flushing icache. | 751 | * already have been removed. We save on flushing icache. |
| 748 | */ | 752 | */ |
| 749 | if (kprobe_enabled && !kprobe_gone(old_p)) | 753 | if (kprobe_enabled && !kprobe_gone(old_p)) { |
| 754 | mutex_lock(&text_mutex); | ||
| 750 | arch_disarm_kprobe(p); | 755 | arch_disarm_kprobe(p); |
| 756 | mutex_unlock(&text_mutex); | ||
| 757 | } | ||
| 751 | hlist_del_rcu(&old_p->hlist); | 758 | hlist_del_rcu(&old_p->hlist); |
| 752 | } else { | 759 | } else { |
| 753 | if (p->break_handler && !kprobe_gone(p)) | 760 | if (p->break_handler && !kprobe_gone(p)) |
| @@ -1280,12 +1287,14 @@ static void __kprobes enable_all_kprobes(void) | |||
| 1280 | if (kprobe_enabled) | 1287 | if (kprobe_enabled) |
| 1281 | goto already_enabled; | 1288 | goto already_enabled; |
| 1282 | 1289 | ||
| 1290 | mutex_lock(&text_mutex); | ||
| 1283 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { | 1291 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
| 1284 | head = &kprobe_table[i]; | 1292 | head = &kprobe_table[i]; |
| 1285 | hlist_for_each_entry_rcu(p, node, head, hlist) | 1293 | hlist_for_each_entry_rcu(p, node, head, hlist) |
| 1286 | if (!kprobe_gone(p)) | 1294 | if (!kprobe_gone(p)) |
| 1287 | arch_arm_kprobe(p); | 1295 | arch_arm_kprobe(p); |
| 1288 | } | 1296 | } |
| 1297 | mutex_unlock(&text_mutex); | ||
| 1289 | 1298 | ||
| 1290 | kprobe_enabled = true; | 1299 | kprobe_enabled = true; |
| 1291 | printk(KERN_INFO "Kprobes globally enabled\n"); | 1300 | printk(KERN_INFO "Kprobes globally enabled\n"); |
| @@ -1310,6 +1319,7 @@ static void __kprobes disable_all_kprobes(void) | |||
| 1310 | 1319 | ||
| 1311 | kprobe_enabled = false; | 1320 | kprobe_enabled = false; |
| 1312 | printk(KERN_INFO "Kprobes globally disabled\n"); | 1321 | printk(KERN_INFO "Kprobes globally disabled\n"); |
| 1322 | mutex_lock(&text_mutex); | ||
| 1313 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { | 1323 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
| 1314 | head = &kprobe_table[i]; | 1324 | head = &kprobe_table[i]; |
| 1315 | hlist_for_each_entry_rcu(p, node, head, hlist) { | 1325 | hlist_for_each_entry_rcu(p, node, head, hlist) { |
| @@ -1318,6 +1328,7 @@ static void __kprobes disable_all_kprobes(void) | |||
| 1318 | } | 1328 | } |
| 1319 | } | 1329 | } |
| 1320 | 1330 | ||
| 1331 | mutex_unlock(&text_mutex); | ||
| 1321 | mutex_unlock(&kprobe_mutex); | 1332 | mutex_unlock(&kprobe_mutex); |
| 1322 | /* Allow all currently running kprobes to complete */ | 1333 | /* Allow all currently running kprobes to complete */ |
| 1323 | synchronize_sched(); | 1334 | synchronize_sched(); |
