Merge commit '8700c95adb03' into timers/nohz
[firefly-linux-kernel-4.4.55.git] / kernel / kprobes.c
index 550294d58a02ef67c76b17440cdaee3675690047..3fed7f0cbcdfe3d2149dd903e6912628ba58da95 100644 (file)
@@ -334,11 +334,10 @@ static inline void reset_kprobe_instance(void)
 struct kprobe __kprobes *get_kprobe(void *addr)
 {
        struct hlist_head *head;
-       struct hlist_node *node;
        struct kprobe *p;
 
        head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)];
-       hlist_for_each_entry_rcu(p, node, head, hlist) {
+       hlist_for_each_entry_rcu(p, head, hlist) {
                if (p->addr == addr)
                        return p;
        }
@@ -795,53 +794,58 @@ out:
 }
 
 #ifdef CONFIG_SYSCTL
-/* This should be called with kprobe_mutex locked */
 static void __kprobes optimize_all_kprobes(void)
 {
        struct hlist_head *head;
-       struct hlist_node *node;
        struct kprobe *p;
        unsigned int i;
 
+       mutex_lock(&kprobe_mutex);
        /* If optimization is already allowed, just return */
        if (kprobes_allow_optimization)
-               return;
+               goto out;
 
        kprobes_allow_optimization = true;
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_rcu(p, node, head, hlist)
+               hlist_for_each_entry_rcu(p, head, hlist)
                        if (!kprobe_disabled(p))
                                optimize_kprobe(p);
        }
        printk(KERN_INFO "Kprobes globally optimized\n");
+out:
+       mutex_unlock(&kprobe_mutex);
 }
 
-/* This should be called with kprobe_mutex locked */
 static void __kprobes unoptimize_all_kprobes(void)
 {
        struct hlist_head *head;
-       struct hlist_node *node;
        struct kprobe *p;
        unsigned int i;
 
+       mutex_lock(&kprobe_mutex);
        /* If optimization is already prohibited, just return */
-       if (!kprobes_allow_optimization)
+       if (!kprobes_allow_optimization) {
+               mutex_unlock(&kprobe_mutex);
                return;
+       }
 
        kprobes_allow_optimization = false;
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_rcu(p, node, head, hlist) {
+               hlist_for_each_entry_rcu(p, head, hlist) {
                        if (!kprobe_disabled(p))
                                unoptimize_kprobe(p, false);
                }
        }
+       mutex_unlock(&kprobe_mutex);
+
        /* Wait for unoptimizing completion */
        wait_for_kprobe_optimizer();
        printk(KERN_INFO "Kprobes globally unoptimized\n");
 }
 
+static DEFINE_MUTEX(kprobe_sysctl_mutex);
 int sysctl_kprobes_optimization;
 int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
                                      void __user *buffer, size_t *length,
@@ -849,7 +853,7 @@ int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
 {
        int ret;
 
-       mutex_lock(&kprobe_mutex);
+       mutex_lock(&kprobe_sysctl_mutex);
        sysctl_kprobes_optimization = kprobes_allow_optimization ? 1 : 0;
        ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
 
@@ -857,7 +861,7 @@ int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
                optimize_all_kprobes();
        else
                unoptimize_all_kprobes();
-       mutex_unlock(&kprobe_mutex);
+       mutex_unlock(&kprobe_sysctl_mutex);
 
        return ret;
 }
@@ -1148,7 +1152,7 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
 {
        struct kretprobe_instance *ri;
        struct hlist_head *head, empty_rp;
-       struct hlist_node *node, *tmp;
+       struct hlist_node *tmp;
        unsigned long hash, flags = 0;
 
        if (unlikely(!kprobes_initialized))
@@ -1159,12 +1163,12 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
        hash = hash_ptr(tk, KPROBE_HASH_BITS);
        head = &kretprobe_inst_table[hash];
        kretprobe_table_lock(hash, &flags);
-       hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+       hlist_for_each_entry_safe(ri, tmp, head, hlist) {
                if (ri->task == tk)
                        recycle_rp_inst(ri, &empty_rp);
        }
        kretprobe_table_unlock(hash, &flags);
-       hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+       hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
                hlist_del(&ri->hlist);
                kfree(ri);
        }
@@ -1173,9 +1177,9 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
 static inline void free_rp_inst(struct kretprobe *rp)
 {
        struct kretprobe_instance *ri;
-       struct hlist_node *pos, *next;
+       struct hlist_node *next;
 
-       hlist_for_each_entry_safe(ri, pos, next, &rp->free_instances, hlist) {
+       hlist_for_each_entry_safe(ri, next, &rp->free_instances, hlist) {
                hlist_del(&ri->hlist);
                kfree(ri);
        }
@@ -1185,14 +1189,14 @@ static void __kprobes cleanup_rp_inst(struct kretprobe *rp)
 {
        unsigned long flags, hash;
        struct kretprobe_instance *ri;
-       struct hlist_node *pos, *next;
+       struct hlist_node *next;
        struct hlist_head *head;
 
        /* No race here */
        for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) {
                kretprobe_table_lock(hash, &flags);
                head = &kretprobe_inst_table[hash];
-               hlist_for_each_entry_safe(ri, pos, next, head, hlist) {
+               hlist_for_each_entry_safe(ri, next, head, hlist) {
                        if (ri->rp == rp)
                                ri->rp = NULL;
                }
@@ -2028,7 +2032,6 @@ static int __kprobes kprobes_module_callback(struct notifier_block *nb,
 {
        struct module *mod = data;
        struct hlist_head *head;
-       struct hlist_node *node;
        struct kprobe *p;
        unsigned int i;
        int checkcore = (val == MODULE_STATE_GOING);
@@ -2045,7 +2048,7 @@ static int __kprobes kprobes_module_callback(struct notifier_block *nb,
        mutex_lock(&kprobe_mutex);
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_rcu(p, node, head, hlist)
+               hlist_for_each_entry_rcu(p, head, hlist)
                        if (within_module_init((unsigned long)p->addr, mod) ||
                            (checkcore &&
                             within_module_core((unsigned long)p->addr, mod))) {
@@ -2192,7 +2195,6 @@ static void __kprobes kprobe_seq_stop(struct seq_file *f, void *v)
 static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
 {
        struct hlist_head *head;
-       struct hlist_node *node;
        struct kprobe *p, *kp;
        const char *sym = NULL;
        unsigned int i = *(loff_t *) v;
@@ -2201,7 +2203,7 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
 
        head = &kprobe_table[i];
        preempt_disable();
-       hlist_for_each_entry_rcu(p, node, head, hlist) {
+       hlist_for_each_entry_rcu(p, head, hlist) {
                sym = kallsyms_lookup((unsigned long)p->addr, NULL,
                                        &offset, &modname, namebuf);
                if (kprobe_aggrprobe(p)) {
@@ -2236,7 +2238,6 @@ static const struct file_operations debugfs_kprobes_operations = {
 static void __kprobes arm_all_kprobes(void)
 {
        struct hlist_head *head;
-       struct hlist_node *node;
        struct kprobe *p;
        unsigned int i;
 
@@ -2249,7 +2250,7 @@ static void __kprobes arm_all_kprobes(void)
        /* Arming kprobes doesn't optimize kprobe itself */
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_rcu(p, node, head, hlist)
+               hlist_for_each_entry_rcu(p, head, hlist)
                        if (!kprobe_disabled(p))
                                arm_kprobe(p);
        }
@@ -2265,7 +2266,6 @@ already_enabled:
 static void __kprobes disarm_all_kprobes(void)
 {
        struct hlist_head *head;
-       struct hlist_node *node;
        struct kprobe *p;
        unsigned int i;
 
@@ -2282,7 +2282,7 @@ static void __kprobes disarm_all_kprobes(void)
 
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_rcu(p, node, head, hlist) {
+               hlist_for_each_entry_rcu(p, head, hlist) {
                        if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p))
                                disarm_kprobe(p, false);
                }