]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - kernel/kprobes.c
Merge tag 'cris-for-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/jesper...
[mirror_ubuntu-zesty-kernel.git] / kernel / kprobes.c
index ee619929cf9091059406e8f82df32c50d609c0d9..c90e417bb9636300e4f4fe87d2c995a6c2cdab12 100644 (file)
@@ -717,7 +717,7 @@ static void prepare_optimized_kprobe(struct kprobe *p)
        struct optimized_kprobe *op;
 
        op = container_of(p, struct optimized_kprobe, kp);
-       arch_prepare_optimized_kprobe(op);
+       arch_prepare_optimized_kprobe(op, p);
 }
 
 /* Allocate new optimized_kprobe and try to prepare optimized instructions */
@@ -731,7 +731,7 @@ static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
 
        INIT_LIST_HEAD(&op->list);
        op->kp.addr = p->addr;
-       arch_prepare_optimized_kprobe(op);
+       arch_prepare_optimized_kprobe(op, p);
 
        return &op->kp;
 }
@@ -869,7 +869,8 @@ static void __disarm_kprobe(struct kprobe *p, bool reopt)
 {
        struct kprobe *_p;
 
-       unoptimize_kprobe(p, false);    /* Try to unoptimize */
+       /* Try to unoptimize */
+       unoptimize_kprobe(p, kprobes_all_disarmed);
 
        if (!kprobe_queued(p)) {
                arch_disarm_kprobe(p);
@@ -1571,7 +1572,13 @@ static struct kprobe *__disable_kprobe(struct kprobe *p)
 
                /* Try to disarm and disable this/parent probe */
                if (p == orig_p || aggr_kprobe_disabled(orig_p)) {
-                       disarm_kprobe(orig_p, true);
+                       /*
+                        * If kprobes_all_disarmed is set, orig_p
+                        * should have already been disarmed, so
+                        * skip unneed disarming process.
+                        */
+                       if (!kprobes_all_disarmed)
+                               disarm_kprobe(orig_p, true);
                        orig_p->flags |= KPROBE_FLAG_DISABLED;
                }
        }
@@ -2320,6 +2327,12 @@ static void arm_all_kprobes(void)
        if (!kprobes_all_disarmed)
                goto already_enabled;
 
+       /*
+        * optimize_kprobe() called by arm_kprobe() checks
+        * kprobes_all_disarmed, so set kprobes_all_disarmed before
+        * arm_kprobe.
+        */
+       kprobes_all_disarmed = false;
        /* Arming kprobes doesn't optimize kprobe itself */
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
@@ -2328,7 +2341,6 @@ static void arm_all_kprobes(void)
                                arm_kprobe(p);
        }
 
-       kprobes_all_disarmed = false;
        printk(KERN_INFO "Kprobes globally enabled\n");
 
 already_enabled: