Merge tag 'v3.10.99' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / kernel / module.c
index cab4bce49c23dbe3779d02db8259dda28b7b4258..57085deed9937087f35a4346e4d8dcad010e9e87 100644 (file)
@@ -942,11 +942,15 @@ void symbol_put_addr(void *addr)
        if (core_kernel_text(a))
                return;
 
-       /* module_text_address is safe here: we're supposed to have reference
-        * to module from symbol_get, so it can't go away. */
+       /*
+        * Even though we hold a reference on the module; we still need to
+        * disable preemption in order to safely traverse the data structure.
+        */
+       preempt_disable();
        modaddr = __module_text_address(a);
        BUG_ON(!modaddr);
        module_put(modaddr);
+       preempt_enable();
 }
 EXPORT_SYMBOL_GPL(symbol_put_addr);
 
@@ -1866,7 +1870,9 @@ static void free_module(struct module *mod)
 
        /* We leave it in list to prevent duplicate loads, but make sure
         * that noone uses it while it's being deconstructed. */
+       mutex_lock(&module_mutex);
        mod->state = MODULE_STATE_UNFORMED;
+       mutex_unlock(&module_mutex);
 
        /* Remove dynamic debug info */
        ddebug_remove_module(mod->name);
@@ -2927,7 +2933,6 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
 {
        /* Module within temporary copy. */
        struct module *mod;
-       Elf_Shdr *pcpusec;
        int err;
 
        mod = setup_load_info(info, flags);
@@ -2942,17 +2947,10 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
        err = module_frob_arch_sections(info->hdr, info->sechdrs,
                                        info->secstrings, mod);
        if (err < 0)
-               goto out;
+               return ERR_PTR(err);
 
-       pcpusec = &info->sechdrs[info->index.pcpu];
-       if (pcpusec->sh_size) {
-               /* We have a special allocation for this section. */
-               err = percpu_modalloc(mod,
-                                     pcpusec->sh_size, pcpusec->sh_addralign);
-               if (err)
-                       goto out;
-               pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC;
-       }
+       /* We will do a special allocation for per-cpu sections later. */
+       info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC;
 
        /* Determine total sizes, and put offsets in sh_entsize.  For now
           this is done generically; there doesn't appear to be any
@@ -2963,17 +2961,22 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
        /* Allocate and move to the final place */
        err = move_module(mod, info);
        if (err)
-               goto free_percpu;
+               return ERR_PTR(err);
 
        /* Module has been copied to its final place now: return it. */
        mod = (void *)info->sechdrs[info->index.mod].sh_addr;
        kmemleak_load_module(mod, info);
        return mod;
+}
 
-free_percpu:
-       percpu_modfree(mod);
-out:
-       return ERR_PTR(err);
+static int alloc_module_percpu(struct module *mod, struct load_info *info)
+{
+       Elf_Shdr *pcpusec = &info->sechdrs[info->index.pcpu];
+       if (!pcpusec->sh_size)
+               return 0;
+
+       /* We have a special allocation for this section. */
+       return percpu_modalloc(mod, pcpusec->sh_size, pcpusec->sh_addralign);
 }
 
 /* mod is no longer valid after this! */
@@ -3237,6 +3240,11 @@ static int load_module(struct load_info *info, const char __user *uargs,
        }
 #endif
 
+       /* To avoid stressing percpu allocator, do this once we're unique. */
+       err = alloc_module_percpu(mod, info);
+       if (err)
+               goto unlink_mod;
+
        /* Now module is in final location, initialize linked lists, etc. */
        err = module_unload_init(mod);
        if (err)
@@ -3277,6 +3285,9 @@ static int load_module(struct load_info *info, const char __user *uargs,
 
        dynamic_debug_setup(info->debug, info->num_debug);
 
+       /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */
+       ftrace_module_init(mod);
+
        /* Finally it's fully formed, ready to start executing. */
        err = complete_formation(mod, info);
        if (err)
@@ -3387,6 +3398,11 @@ static inline int is_arm_mapping_symbol(const char *str)
               && (str[2] == '\0' || str[2] == '.');
 }
 
+static const char *symname(struct module *mod, unsigned int symnum)
+{
+       return mod->strtab + mod->symtab[symnum].st_name;
+}
+
 static const char *get_ksymbol(struct module *mod,
                               unsigned long addr,
                               unsigned long *size,
@@ -3409,15 +3425,15 @@ static const char *get_ksymbol(struct module *mod,
 
                /* We ignore unnamed symbols: they're uninformative
                 * and inserted at a whim. */
+               if (*symname(mod, i) == '\0'
+                   || is_arm_mapping_symbol(symname(mod, i)))
+                       continue;
+
                if (mod->symtab[i].st_value <= addr
-                   && mod->symtab[i].st_value > mod->symtab[best].st_value
-                   && *(mod->strtab + mod->symtab[i].st_name) != '\0'
-                   && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name))
+                   && mod->symtab[i].st_value > mod->symtab[best].st_value)
                        best = i;
                if (mod->symtab[i].st_value > addr
-                   && mod->symtab[i].st_value < nextval
-                   && *(mod->strtab + mod->symtab[i].st_name) != '\0'
-                   && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name))
+                   && mod->symtab[i].st_value < nextval)
                        nextval = mod->symtab[i].st_value;
        }
 
@@ -3428,7 +3444,7 @@ static const char *get_ksymbol(struct module *mod,
                *size = nextval - mod->symtab[best].st_value;
        if (offset)
                *offset = addr - mod->symtab[best].st_value;
-       return mod->strtab + mod->symtab[best].st_name;
+       return symname(mod, best);
 }
 
 /* For kallsyms to ask for address resolution.  NULL means not found.  Careful
@@ -3529,8 +3545,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
                if (symnum < mod->num_symtab) {
                        *value = mod->symtab[symnum].st_value;
                        *type = mod->symtab[symnum].st_info;
-                       strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
-                               KSYM_NAME_LEN);
+                       strlcpy(name, symname(mod, symnum), KSYM_NAME_LEN);
                        strlcpy(module_name, mod->name, MODULE_NAME_LEN);
                        *exported = is_exported(name, *value, mod);
                        preempt_enable();
@@ -3547,7 +3562,7 @@ static unsigned long mod_find_symname(struct module *mod, const char *name)
        unsigned int i;
 
        for (i = 0; i < mod->num_symtab; i++)
-               if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0 &&
+               if (strcmp(name, symname(mod, i)) == 0 &&
                    mod->symtab[i].st_info != 'U')
                        return mod->symtab[i].st_value;
        return 0;
@@ -3591,7 +3606,7 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
                if (mod->state == MODULE_STATE_UNFORMED)
                        continue;
                for (i = 0; i < mod->num_symtab; i++) {
-                       ret = fn(data, mod->strtab + mod->symtab[i].st_name,
+                       ret = fn(data, symname(mod, i),
                                 mod, mod->symtab[i].st_value);
                        if (ret != 0)
                                return ret;
@@ -3823,7 +3838,7 @@ void print_modules(void)
        list_for_each_entry_rcu(mod, &modules, list) {
                if (mod->state == MODULE_STATE_UNFORMED)
                        continue;
-               printk(" %s%s", mod->name, module_flags(mod, buf));
+               printk(" %s %p %s", mod->name, mod->module_core,  module_flags(mod, buf));
        }
        preempt_enable();
        if (last_unloaded_module[0])