aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kprobes.c')
-rw-r--r--kernel/kprobes.c19
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
715out_unlock_text:
716 mutex_unlock(&text_mutex);
713out: 717out:
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();