diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-04-05 19:41:22 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-04-05 19:41:22 -0400 |
| commit | 9efe21cb82b5dbe3b0b2ae4de4eccc64ecb94e95 (patch) | |
| tree | 7ff8833745d2f268f897f6fa4a27263b4a572245 /kernel/kprobes.c | |
| parent | de18836e447c2dc30120c0919b8db8ddc0401cc4 (diff) | |
| parent | 0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff) | |
Merge branch 'linus' into irq/threaded
Conflicts:
include/linux/irq.h
kernel/irq/handle.c
Diffstat (limited to 'kernel/kprobes.c')
| -rw-r--r-- | kernel/kprobes.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 7ba8cd9845cb..5016bfb682b9 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)) |
| @@ -912,10 +919,8 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p, | |||
| 912 | ri->rp = rp; | 919 | ri->rp = rp; |
| 913 | ri->task = current; | 920 | ri->task = current; |
| 914 | 921 | ||
| 915 | if (rp->entry_handler && rp->entry_handler(ri, regs)) { | 922 | if (rp->entry_handler && rp->entry_handler(ri, regs)) |
| 916 | spin_unlock_irqrestore(&rp->lock, flags); | ||
| 917 | return 0; | 923 | return 0; |
| 918 | } | ||
| 919 | 924 | ||
| 920 | arch_prepare_kretprobe(ri, regs); | 925 | arch_prepare_kretprobe(ri, regs); |
| 921 | 926 | ||
| @@ -1280,12 +1285,14 @@ static void __kprobes enable_all_kprobes(void) | |||
| 1280 | if (kprobe_enabled) | 1285 | if (kprobe_enabled) |
| 1281 | goto already_enabled; | 1286 | goto already_enabled; |
| 1282 | 1287 | ||
| 1288 | mutex_lock(&text_mutex); | ||
| 1283 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { | 1289 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
| 1284 | head = &kprobe_table[i]; | 1290 | head = &kprobe_table[i]; |
| 1285 | hlist_for_each_entry_rcu(p, node, head, hlist) | 1291 | hlist_for_each_entry_rcu(p, node, head, hlist) |
| 1286 | if (!kprobe_gone(p)) | 1292 | if (!kprobe_gone(p)) |
| 1287 | arch_arm_kprobe(p); | 1293 | arch_arm_kprobe(p); |
| 1288 | } | 1294 | } |
| 1295 | mutex_unlock(&text_mutex); | ||
| 1289 | 1296 | ||
| 1290 | kprobe_enabled = true; | 1297 | kprobe_enabled = true; |
| 1291 | printk(KERN_INFO "Kprobes globally enabled\n"); | 1298 | printk(KERN_INFO "Kprobes globally enabled\n"); |
| @@ -1310,6 +1317,7 @@ static void __kprobes disable_all_kprobes(void) | |||
| 1310 | 1317 | ||
| 1311 | kprobe_enabled = false; | 1318 | kprobe_enabled = false; |
| 1312 | printk(KERN_INFO "Kprobes globally disabled\n"); | 1319 | printk(KERN_INFO "Kprobes globally disabled\n"); |
| 1320 | mutex_lock(&text_mutex); | ||
| 1313 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { | 1321 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
| 1314 | head = &kprobe_table[i]; | 1322 | head = &kprobe_table[i]; |
| 1315 | hlist_for_each_entry_rcu(p, node, head, hlist) { | 1323 | hlist_for_each_entry_rcu(p, node, head, hlist) { |
| @@ -1318,6 +1326,7 @@ static void __kprobes disable_all_kprobes(void) | |||
| 1318 | } | 1326 | } |
| 1319 | } | 1327 | } |
| 1320 | 1328 | ||
| 1329 | mutex_unlock(&text_mutex); | ||
| 1321 | mutex_unlock(&kprobe_mutex); | 1330 | mutex_unlock(&kprobe_mutex); |
| 1322 | /* Allow all currently running kprobes to complete */ | 1331 | /* Allow all currently running kprobes to complete */ |
| 1323 | synchronize_sched(); | 1332 | synchronize_sched(); |
