]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - kernel/module.c
Merge tag 'regulator-v3.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-imx.git] / kernel / module.c
index d1a161be7b0476ecd93de1de3dd83c4d485ca151..206915830d2993bc54124b0fecf09abadac08a0f 100644 (file)
@@ -482,23 +482,28 @@ static inline void __percpu *mod_percpu(struct module *mod)
        return mod->percpu;
 }
 
-static int percpu_modalloc(struct module *mod,
-                          unsigned long size, unsigned long align)
+static int percpu_modalloc(struct module *mod, struct load_info *info)
 {
+       Elf_Shdr *pcpusec = &info->sechdrs[info->index.pcpu];
+       unsigned long align = pcpusec->sh_addralign;
+
+       if (!pcpusec->sh_size)
+               return 0;
+
        if (align > PAGE_SIZE) {
                printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
                       mod->name, align, PAGE_SIZE);
                align = PAGE_SIZE;
        }
 
-       mod->percpu = __alloc_reserved_percpu(size, align);
+       mod->percpu = __alloc_reserved_percpu(pcpusec->sh_size, align);
        if (!mod->percpu) {
                printk(KERN_WARNING
                       "%s: Could not allocate %lu bytes percpu data\n",
-                      mod->name, size);
+                      mod->name, (unsigned long)pcpusec->sh_size);
                return -ENOMEM;
        }
-       mod->percpu_size = size;
+       mod->percpu_size = pcpusec->sh_size;
        return 0;
 }
 
@@ -563,10 +568,12 @@ static inline void __percpu *mod_percpu(struct module *mod)
 {
        return NULL;
 }
-static inline int percpu_modalloc(struct module *mod,
-                                 unsigned long size, unsigned long align)
+static int percpu_modalloc(struct module *mod, struct load_info *info)
 {
-       return -ENOMEM;
+       /* UP modules shouldn't have this section: ENOMEM isn't quite right */
+       if (info->sechdrs[info->index.pcpu].sh_size != 0)
+               return -ENOMEM;
+       return 0;
 }
 static inline void percpu_modfree(struct module *mod)
 {
@@ -2431,10 +2438,10 @@ static void kmemleak_load_module(const struct module *mod,
        kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL);
 
        for (i = 1; i < info->hdr->e_shnum; i++) {
-               const char *name = info->secstrings + info->sechdrs[i].sh_name;
-               if (!(info->sechdrs[i].sh_flags & SHF_ALLOC))
-                       continue;
-               if (!strstarts(name, ".data") && !strstarts(name, ".bss"))
+               /* Scan all writable sections that's not executable */
+               if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) ||
+                   !(info->sechdrs[i].sh_flags & SHF_WRITE) ||
+                   (info->sechdrs[i].sh_flags & SHF_EXECINSTR))
                        continue;
 
                kmemleak_scan_area((void *)info->sechdrs[i].sh_addr,
@@ -2769,24 +2776,11 @@ static void find_module_sections(struct module *mod, struct load_info *info)
        mod->trace_events = section_objs(info, "_ftrace_events",
                                         sizeof(*mod->trace_events),
                                         &mod->num_trace_events);
-       /*
-        * This section contains pointers to allocated objects in the trace
-        * code and not scanning it leads to false positives.
-        */
-       kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) *
-                          mod->num_trace_events, GFP_KERNEL);
 #endif
 #ifdef CONFIG_TRACING
        mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt",
                                         sizeof(*mod->trace_bprintk_fmt_start),
                                         &mod->num_trace_bprintk_fmt);
-       /*
-        * This section contains pointers to allocated objects in the trace
-        * code and not scanning it leads to false positives.
-        */
-       kmemleak_scan_area(mod->trace_bprintk_fmt_start,
-                          sizeof(*mod->trace_bprintk_fmt_start) *
-                          mod->num_trace_bprintk_fmt, GFP_KERNEL);
 #endif
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
        /* sechdrs[0].sh_size is always zero */
@@ -2976,16 +2970,6 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
        return mod;
 }
 
-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! */
 static void module_deallocate(struct module *mod, struct load_info *info)
 {
@@ -3260,7 +3244,7 @@ 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);
+       err = percpu_modalloc(mod, info);
        if (err)
                goto unlink_mod;