Merge branch 'fixes' of git://git.linaro.org/people/rmk/linux-arm
[linux-flexiantxendom0-3.2.10.git] / kernel / module.c
index efa290e..78ac6ec 100644 (file)
@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/moduleloader.h>
 #include <linux/ftrace_event.h>
 #include <linux/init.h>
 #include <linux/kmemleak.h>
 #include <linux/jump_label.h>
 #include <linux/pfn.h>
+#include <linux/bsearch.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/module.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(fmt , a...)
-#endif
-
 #ifndef ARCH_SHF_SMALL
 #define ARCH_SHF_SMALL 0
 #endif
@@ -110,6 +105,7 @@ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
 
 /* Block module loading/unloading? */
 int modules_disabled = 0;
+core_param(nomodule, modules_disabled, bint, 0);
 
 /* Waiting for a module to finish initializing? */
 static DECLARE_WAIT_QUEUE_HEAD(module_wq);
@@ -137,7 +133,6 @@ struct load_info {
        unsigned long len;
        Elf_Shdr *sechdrs;
        char *secstrings, *strtab;
-       unsigned long *strmap;
        unsigned long symoffs, stroffs;
        struct _ddebug *debug;
        unsigned int num_debug;
@@ -240,23 +235,24 @@ static bool each_symbol_in_section(const struct symsearch *arr,
                                   struct module *owner,
                                   bool (*fn)(const struct symsearch *syms,
                                              struct module *owner,
-                                             unsigned int symnum, void *data),
+                                             void *data),
                                   void *data)
 {
-       unsigned int i, j;
+       unsigned int j;
 
        for (j = 0; j < arrsize; j++) {
-               for (i = 0; i < arr[j].stop - arr[j].start; i++)
-                       if (fn(&arr[j], owner, i, data))
-                               return true;
+               if (fn(&arr[j], owner, data))
+                       return true;
        }
 
        return false;
 }
 
 /* Returns true as soon as fn returns true, otherwise false. */
-bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
-                           unsigned int symnum, void *data), void *data)
+bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
+                                   struct module *owner,
+                                   void *data),
+                        void *data)
 {
        struct module *mod;
        static const struct symsearch arr[] = {
@@ -309,7 +305,7 @@ bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
        }
        return false;
 }
-EXPORT_SYMBOL_GPL(each_symbol);
+EXPORT_SYMBOL_GPL(each_symbol_section);
 
 struct find_symbol_arg {
        /* Input */
@@ -323,15 +319,12 @@ struct find_symbol_arg {
        const struct kernel_symbol *sym;
 };
 
-static bool find_symbol_in_section(const struct symsearch *syms,
-                                  struct module *owner,
-                                  unsigned int symnum, void *data)
+static bool check_symbol(const struct symsearch *syms,
+                                struct module *owner,
+                                unsigned int symnum, void *data)
 {
        struct find_symbol_arg *fsa = data;
 
-       if (strcmp(syms->start[symnum].name, fsa->name) != 0)
-               return false;
-
        if (!fsa->gplok) {
                if (syms->licence == GPL_ONLY)
                        return false;
@@ -365,6 +358,30 @@ static bool find_symbol_in_section(const struct symsearch *syms,
        return true;
 }
 
+static int cmp_name(const void *va, const void *vb)
+{
+       const char *a;
+       const struct kernel_symbol *b;
+       a = va; b = vb;
+       return strcmp(a, b->name);
+}
+
+static bool find_symbol_in_section(const struct symsearch *syms,
+                                  struct module *owner,
+                                  void *data)
+{
+       struct find_symbol_arg *fsa = data;
+       struct kernel_symbol *sym;
+
+       sym = bsearch(fsa->name, syms->start, syms->stop - syms->start,
+                       sizeof(struct kernel_symbol), cmp_name);
+
+       if (sym != NULL && check_symbol(syms, owner, sym - syms->start, data))
+               return true;
+
+       return false;
+}
+
 /* Find a symbol and return it, along with, (optional) crc and
  * (optional) module which owns it.  Needs preempt disabled or module_mutex. */
 const struct kernel_symbol *find_symbol(const char *name,
@@ -379,7 +396,7 @@ const struct kernel_symbol *find_symbol(const char *name,
        fsa.gplok = gplok;
        fsa.warn = warn;
 
-       if (each_symbol(find_symbol_in_section, &fsa)) {
+       if (each_symbol_section(find_symbol_in_section, &fsa)) {
                if (owner)
                        *owner = fsa.owner;
                if (crc)
@@ -387,7 +404,7 @@ const struct kernel_symbol *find_symbol(const char *name,
                return fsa.sym;
        }
 
-       DEBUGP("Failed to find symbol %s\n", name);
+       pr_debug("Failed to find symbol %s\n", name);
        return NULL;
 }
 EXPORT_SYMBOL_GPL(find_symbol);
@@ -522,9 +539,9 @@ static void setup_modinfo_##field(struct module *mod, const char *s)  \
        mod->field = kstrdup(s, GFP_KERNEL);                          \
 }                                                                     \
 static ssize_t show_modinfo_##field(struct module_attribute *mattr,   \
-                       struct module *mod, char *buffer)             \
+                       struct module_kobject *mk, char *buffer)      \
 {                                                                     \
-       return sprintf(buffer, "%s\n", mod->field);                   \
+       return sprintf(buffer, "%s\n", mk->mod->field);               \
 }                                                                     \
 static int modinfo_##field##_exists(struct module *mod)               \
 {                                                                     \
@@ -577,11 +594,11 @@ static int already_uses(struct module *a, struct module *b)
 
        list_for_each_entry(use, &b->source_list, source_list) {
                if (use->source == a) {
-                       DEBUGP("%s uses %s!\n", a->name, b->name);
+                       pr_debug("%s uses %s!\n", a->name, b->name);
                        return 1;
                }
        }
-       DEBUGP("%s does not use %s!\n", a->name, b->name);
+       pr_debug("%s does not use %s!\n", a->name, b->name);
        return 0;
 }
 
@@ -596,7 +613,7 @@ static int add_module_usage(struct module *a, struct module *b)
 {
        struct module_use *use;
 
-       DEBUGP("Allocating new usage for %s.\n", a->name);
+       pr_debug("Allocating new usage for %s.\n", a->name);
        use = kmalloc(sizeof(*use), GFP_ATOMIC);
        if (!use) {
                printk(KERN_WARNING "%s: out of memory loading\n", a->name);
@@ -640,7 +657,7 @@ static void module_unload_free(struct module *mod)
        mutex_lock(&module_mutex);
        list_for_each_entry_safe(use, tmp, &mod->target_list, target_list) {
                struct module *i = use->target;
-               DEBUGP("%s unusing %s\n", mod->name, i->name);
+               pr_debug("%s unusing %s\n", mod->name, i->name);
                module_put(i);
                list_del(&use->source_list);
                list_del(&use->target_list);
@@ -703,9 +720,9 @@ static int try_stop_module(struct module *mod, int flags, int *forced)
        }
 }
 
-unsigned int module_refcount(struct module *mod)
+unsigned long module_refcount(struct module *mod)
 {
-       unsigned int incs = 0, decs = 0;
+       unsigned long incs = 0, decs = 0;
        int cpu;
 
        for_each_possible_cpu(cpu)
@@ -738,7 +755,7 @@ static void wait_for_zero_refcount(struct module *mod)
        /* Since we might sleep for some time, release the mutex first */
        mutex_unlock(&module_mutex);
        for (;;) {
-               DEBUGP("Looking at refcount...\n");
+               pr_debug("Looking at refcount...\n");
                set_current_state(TASK_UNINTERRUPTIBLE);
                if (module_refcount(mod) == 0)
                        break;
@@ -781,7 +798,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
        if (mod->state != MODULE_STATE_LIVE) {
                /* FIXME: if (force), slam module count and wake up
                    waiter --RR */
-               DEBUGP("%s already dying\n", mod->name);
+               pr_debug("%s already dying\n", mod->name);
                ret = -EBUSY;
                goto out;
        }
@@ -809,7 +826,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
                wait_for_zero_refcount(mod);
 
        mutex_unlock(&module_mutex);
-       /* Final destruction now noone is using it. */
+       /* Final destruction now no one is using it. */
        if (mod->exit != NULL)
                mod->exit();
        blocking_notifier_call_chain(&module_notify_list,
@@ -831,7 +848,7 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod)
        struct module_use *use;
        int printed_something = 0;
 
-       seq_printf(m, " %u ", module_refcount(mod));
+       seq_printf(m, " %lu ", module_refcount(mod));
 
        /* Always include a trailing , so userspace can differentiate
            between this and the old multi-field proc format. */
@@ -879,15 +896,43 @@ void symbol_put_addr(void *addr)
 EXPORT_SYMBOL_GPL(symbol_put_addr);
 
 static ssize_t show_refcnt(struct module_attribute *mattr,
-                          struct module *mod, char *buffer)
+                          struct module_kobject *mk, char *buffer)
 {
-       return sprintf(buffer, "%u\n", module_refcount(mod));
+       return sprintf(buffer, "%lu\n", module_refcount(mk->mod));
 }
 
-static struct module_attribute refcnt = {
-       .attr = { .name = "refcnt", .mode = 0444 },
-       .show = show_refcnt,
-};
+static struct module_attribute modinfo_refcnt =
+       __ATTR(refcnt, 0444, show_refcnt, NULL);
+
+void __module_get(struct module *module)
+{
+       if (module) {
+               preempt_disable();
+               __this_cpu_inc(module->refptr->incs);
+               trace_module_get(module, _RET_IP_);
+               preempt_enable();
+       }
+}
+EXPORT_SYMBOL(__module_get);
+
+bool try_module_get(struct module *module)
+{
+       bool ret = true;
+
+       if (module) {
+               preempt_disable();
+
+               if (likely(module_is_live(module))) {
+                       __this_cpu_inc(module->refptr->incs);
+                       trace_module_get(module, _RET_IP_);
+               } else
+                       ret = false;
+
+               preempt_enable();
+       }
+       return ret;
+}
+EXPORT_SYMBOL(try_module_get);
 
 void module_put(struct module *module)
 {
@@ -928,12 +973,32 @@ static inline int module_unload_init(struct module *mod)
 }
 #endif /* CONFIG_MODULE_UNLOAD */
 
+static size_t module_flags_taint(struct module *mod, char *buf)
+{
+       size_t l = 0;
+
+       if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
+               buf[l++] = 'P';
+       if (mod->taints & (1 << TAINT_OOT_MODULE))
+               buf[l++] = 'O';
+       if (mod->taints & (1 << TAINT_FORCED_MODULE))
+               buf[l++] = 'F';
+       if (mod->taints & (1 << TAINT_CRAP))
+               buf[l++] = 'C';
+       /*
+        * TAINT_FORCED_RMMOD: could be added.
+        * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
+        * apply to modules.
+        */
+       return l;
+}
+
 static ssize_t show_initstate(struct module_attribute *mattr,
-                          struct module *mod, char *buffer)
+                             struct module_kobject *mk, char *buffer)
 {
        const char *state = "unknown";
 
-       switch (mod->state) {
+       switch (mk->mod->state) {
        case MODULE_STATE_LIVE:
                state = "live";
                break;
@@ -947,17 +1012,64 @@ static ssize_t show_initstate(struct module_attribute *mattr,
        return sprintf(buffer, "%s\n", state);
 }
 
-static struct module_attribute initstate = {
-       .attr = { .name = "initstate", .mode = 0444 },
-       .show = show_initstate,
-};
+static struct module_attribute modinfo_initstate =
+       __ATTR(initstate, 0444, show_initstate, NULL);
+
+static ssize_t store_uevent(struct module_attribute *mattr,
+                           struct module_kobject *mk,
+                           const char *buffer, size_t count)
+{
+       enum kobject_action action;
+
+       if (kobject_action_type(buffer, count, &action) == 0)
+               kobject_uevent(&mk->kobj, action);
+       return count;
+}
+
+struct module_attribute module_uevent =
+       __ATTR(uevent, 0200, NULL, store_uevent);
+
+static ssize_t show_coresize(struct module_attribute *mattr,
+                            struct module_kobject *mk, char *buffer)
+{
+       return sprintf(buffer, "%u\n", mk->mod->core_size);
+}
+
+static struct module_attribute modinfo_coresize =
+       __ATTR(coresize, 0444, show_coresize, NULL);
+
+static ssize_t show_initsize(struct module_attribute *mattr,
+                            struct module_kobject *mk, char *buffer)
+{
+       return sprintf(buffer, "%u\n", mk->mod->init_size);
+}
+
+static struct module_attribute modinfo_initsize =
+       __ATTR(initsize, 0444, show_initsize, NULL);
+
+static ssize_t show_taint(struct module_attribute *mattr,
+                         struct module_kobject *mk, char *buffer)
+{
+       size_t l;
+
+       l = module_flags_taint(mk->mod, buffer);
+       buffer[l++] = '\n';
+       return l;
+}
+
+static struct module_attribute modinfo_taint =
+       __ATTR(taint, 0444, show_taint, NULL);
 
 static struct module_attribute *modinfo_attrs[] = {
+       &module_uevent,
        &modinfo_version,
        &modinfo_srcversion,
-       &initstate,
+       &modinfo_initstate,
+       &modinfo_coresize,
+       &modinfo_initsize,
+       &modinfo_taint,
 #ifdef CONFIG_MODULE_UNLOAD
-       &refcnt,
+       &modinfo_refcnt,
 #endif
        NULL,
 };
@@ -1017,7 +1129,7 @@ static int check_version(Elf_Shdr *sechdrs,
 
                if (versions[i].crc == maybe_relocated(*crc, crc_owner))
                        return 1;
-               DEBUGP("Found checksum %lX vs module %lX\n",
+               pr_debug("Found checksum %lX vs module %lX\n",
                       maybe_relocated(*crc, crc_owner), versions[i].crc);
                goto bad_version;
        }
@@ -1164,11 +1276,11 @@ struct module_sect_attrs
 };
 
 static ssize_t module_sect_show(struct module_attribute *mattr,
-                               struct module *mod, char *buf)
+                               struct module_kobject *mk, char *buf)
 {
        struct module_sect_attr *sattr =
                container_of(mattr, struct module_sect_attr, mattr);
-       return sprintf(buf, "0x%lx\n", sattr->address);
+       return sprintf(buf, "0x%pK\n", (void *)sattr->address);
 }
 
 static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
@@ -1607,27 +1719,28 @@ static void set_section_ro_nx(void *base,
        }
 }
 
-/* Setting memory back to RW+NX before releasing it */
-void unset_section_ro_nx(struct module *mod, void *module_region)
+static void unset_module_core_ro_nx(struct module *mod)
 {
-       unsigned long total_pages;
-
-       if (mod->module_core == module_region) {
-               /* Set core as NX+RW */
-               total_pages = MOD_NUMBER_OF_PAGES(mod->module_core, mod->core_size);
-               set_memory_nx((unsigned long)mod->module_core, total_pages);
-               set_memory_rw((unsigned long)mod->module_core, total_pages);
+       set_page_attributes(mod->module_core + mod->core_text_size,
+               mod->module_core + mod->core_size,
+               set_memory_x);
+       set_page_attributes(mod->module_core,
+               mod->module_core + mod->core_ro_size,
+               set_memory_rw);
+}
 
-       } else if (mod->module_init == module_region) {
-               /* Set init as NX+RW */
-               total_pages = MOD_NUMBER_OF_PAGES(mod->module_init, mod->init_size);
-               set_memory_nx((unsigned long)mod->module_init, total_pages);
-               set_memory_rw((unsigned long)mod->module_init, total_pages);
-       }
+static void unset_module_init_ro_nx(struct module *mod)
+{
+       set_page_attributes(mod->module_init + mod->init_text_size,
+               mod->module_init + mod->init_size,
+               set_memory_x);
+       set_page_attributes(mod->module_init,
+               mod->module_init + mod->init_ro_size,
+               set_memory_rw);
 }
 
 /* Iterate through all modules and set each module's text as RW */
-void set_all_modules_text_rw()
+void set_all_modules_text_rw(void)
 {
        struct module *mod;
 
@@ -1648,7 +1761,7 @@ void set_all_modules_text_rw()
 }
 
 /* Iterate through all modules and set each module's text as RO */
-void set_all_modules_text_ro()
+void set_all_modules_text_ro(void)
 {
        struct module *mod;
 
@@ -1669,9 +1782,19 @@ void set_all_modules_text_ro()
 }
 #else
 static inline void set_section_ro_nx(void *base, unsigned long text_size, unsigned long ro_size, unsigned long total_size) { }
-static inline void unset_section_ro_nx(struct module *mod, void *module_region) { }
+static void unset_module_core_ro_nx(struct module *mod) { }
+static void unset_module_init_ro_nx(struct module *mod) { }
 #endif
 
+void __weak module_free(struct module *mod, void *module_region)
+{
+       vfree(module_region);
+}
+
+void __weak module_arch_cleanup(struct module *mod)
+{
+}
+
 /* Free a module, remove from lists, etc. */
 static void free_module(struct module *mod)
 {
@@ -1696,7 +1819,7 @@ static void free_module(struct module *mod)
        destroy_params(mod->kp, mod->num_kp);
 
        /* This may be NULL, but that's OK */
-       unset_section_ro_nx(mod, mod->module_init);
+       unset_module_init_ro_nx(mod);
        module_free(mod, mod->module_init);
        kfree(mod->args);
        percpu_modfree(mod);
@@ -1705,7 +1828,7 @@ static void free_module(struct module *mod)
        lockdep_free_key_range(mod->module_core, mod->core_size);
 
        /* Finally, free the core (containing the module structure) */
-       unset_section_ro_nx(mod, mod->module_core);
+       unset_module_core_ro_nx(mod);
        module_free(mod, mod->module_core);
 
 #ifdef CONFIG_MPU
@@ -1783,7 +1906,7 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
                case SHN_COMMON:
                        /* We compiled with -fno-common.  These are not
                           supposed to happen.  */
-                       DEBUGP("Common symbol: %s\n", name);
+                       pr_debug("Common symbol: %s\n", name);
                        printk("%s: please compile with -fno-common\n",
                               mod->name);
                        ret = -ENOEXEC;
@@ -1791,7 +1914,7 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
 
                case SHN_ABS:
                        /* Don't need to do anything */
-                       DEBUGP("Absolute symbol: 0x%08lx\n",
+                       pr_debug("Absolute symbol: 0x%08lx\n",
                               (long)sym[i].st_value);
                        break;
 
@@ -1826,6 +1949,26 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
        return ret;
 }
 
+int __weak apply_relocate(Elf_Shdr *sechdrs,
+                         const char *strtab,
+                         unsigned int symindex,
+                         unsigned int relsec,
+                         struct module *me)
+{
+       pr_err("module %s: REL relocation unsupported\n", me->name);
+       return -ENOEXEC;
+}
+
+int __weak apply_relocate_add(Elf_Shdr *sechdrs,
+                             const char *strtab,
+                             unsigned int symindex,
+                             unsigned int relsec,
+                             struct module *me)
+{
+       pr_err("module %s: RELA relocation unsupported\n", me->name);
+       return -ENOEXEC;
+}
+
 static int apply_relocations(struct module *mod, const struct load_info *info)
 {
        unsigned int i;
@@ -1895,7 +2038,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
        for (i = 0; i < info->hdr->e_shnum; i++)
                info->sechdrs[i].sh_entsize = ~0UL;
 
-       DEBUGP("Core section allocation order:\n");
+       pr_debug("Core section allocation order:\n");
        for (m = 0; m < ARRAY_SIZE(masks); ++m) {
                for (i = 0; i < info->hdr->e_shnum; ++i) {
                        Elf_Shdr *s = &info->sechdrs[i];
@@ -1907,7 +2050,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
                            || strstarts(sname, ".init"))
                                continue;
                        s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
-                       DEBUGP("\t%s\n", name);
+                       pr_debug("\t%s\n", sname);
                }
                switch (m) {
                case 0: /* executable */
@@ -1924,7 +2067,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
                }
        }
 
-       DEBUGP("Init section allocation order:\n");
+       pr_debug("Init section allocation order:\n");
        for (m = 0; m < ARRAY_SIZE(masks); ++m) {
                for (i = 0; i < info->hdr->e_shnum; ++i) {
                        Elf_Shdr *s = &info->sechdrs[i];
@@ -1937,7 +2080,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
                                continue;
                        s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
                                         | INIT_OFFSET_MASK);
-                       DEBUGP("\t%s\n", sname);
+                       pr_debug("\t%s\n", sname);
                }
                switch (m) {
                case 0: /* executable */
@@ -2030,11 +2173,8 @@ static const struct kernel_symbol *lookup_symbol(const char *name,
        const struct kernel_symbol *start,
        const struct kernel_symbol *stop)
 {
-       const struct kernel_symbol *ks = start;
-       for (; ks < stop; ks++)
-               if (strcmp(ks->name, name) == 0)
-                       return ks;
-       return NULL;
+       return bsearch(name, start, stop - start,
+                       sizeof(struct kernel_symbol), cmp_name);
 }
 
 static int is_exported(const char *name, unsigned long value,
@@ -2110,45 +2250,46 @@ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
        return true;
 }
 
+/*
+ * We only allocate and copy the strings needed by the parts of symtab
+ * we keep.  This is simple, but has the effect of making multiple
+ * copies of duplicates.  We could be more sophisticated, see
+ * linux-kernel thread starting with
+ * <73defb5e4bca04a6431392cc341112b1@localhost>.
+ */
 static void layout_symtab(struct module *mod, struct load_info *info)
 {
        Elf_Shdr *symsect = info->sechdrs + info->index.sym;
        Elf_Shdr *strsect = info->sechdrs + info->index.str;
        const Elf_Sym *src;
-       unsigned int i, nsrc, ndst;
+       unsigned int i, nsrc, ndst, strtab_size;
 
        /* Put symbol section at end of init part of module. */
        symsect->sh_flags |= SHF_ALLOC;
        symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect,
                                         info->index.sym) | INIT_OFFSET_MASK;
-       DEBUGP("\t%s\n", info->secstrings + symsect->sh_name);
+       pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
 
        src = (void *)info->hdr + symsect->sh_offset;
        nsrc = symsect->sh_size / sizeof(*src);
-       for (ndst = i = 1; i < nsrc; ++i, ++src)
-               if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
-                       unsigned int j = src->st_name;
 
-                       while (!__test_and_set_bit(j, info->strmap)
-                              && info->strtab[j])
-                               ++j;
-                       ++ndst;
+       /* Compute total space required for the core symbols' strtab. */
+       for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src)
+               if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
+                       strtab_size += strlen(&info->strtab[src->st_name]) + 1;
+                       ndst++;
                }
 
        /* Append room for core symbols at end of core part. */
        info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
-       mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym);
+       info->stroffs = mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym);
+       mod->core_size += strtab_size;
 
        /* Put string table section at end of init part of module. */
        strsect->sh_flags |= SHF_ALLOC;
        strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
                                         info->index.str) | INIT_OFFSET_MASK;
-       DEBUGP("\t%s\n", info->secstrings + strsect->sh_name);
-
-       /* Append room for core symbols' strings at end of core part. */
-       info->stroffs = mod->core_size;
-       __set_bit(0, info->strmap);
-       mod->core_size += bitmap_weight(info->strmap, strsect->sh_size);
+       pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
 }
 
 static void add_kallsyms(struct module *mod, const struct load_info *info)
@@ -2169,22 +2310,19 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
                mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
 
        mod->core_symtab = dst = mod->module_core + info->symoffs;
+       mod->core_strtab = s = mod->module_core + info->stroffs;
        src = mod->symtab;
        *dst = *src;
+       *s++ = 0;
        for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
                if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum))
                        continue;
+
                dst[ndst] = *src;
-               dst[ndst].st_name = bitmap_weight(info->strmap,
-                                                 dst[ndst].st_name);
-               ++ndst;
+               dst[ndst++].st_name = s - mod->core_strtab;
+               s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1;
        }
        mod->core_num_syms = ndst;
-
-       mod->core_strtab = s = mod->module_core + info->stroffs;
-       for (*s = 0, i = 1; i < info->sechdrs[info->index.str].sh_size; ++i)
-               if (test_bit(i, info->strmap))
-                       *++s = mod->strtab[i];
 }
 #else
 static inline void layout_symtab(struct module *mod, struct load_info *info)
@@ -2213,6 +2351,11 @@ static void dynamic_debug_remove(struct _ddebug *debug)
                ddebug_remove_module(debug->modname);
 }
 
+void * __weak module_alloc(unsigned long size)
+{
+       return size == 0 ? NULL : vmalloc_exec(size);
+}
+
 static void *module_alloc_update_bounds(unsigned long size)
 {
        void *ret = module_alloc(size);
@@ -2268,8 +2411,7 @@ static int copy_and_check(struct load_info *info,
                return -ENOEXEC;
 
        /* Suck in entire file: we'll want most of it. */
-       /* vmalloc barfs on "unusual" numbers.  Check here */
-       if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
+       if ((hdr = vmalloc(len)) == NULL)
                return -ENOMEM;
 
        if (copy_from_user(hdr, umod, len) != 0) {
@@ -2414,6 +2556,9 @@ static int check_modinfo(struct module *mod, struct load_info *info)
                return -ENOEXEC;
        }
 
+       if (!get_modinfo(info, "intree"))
+               add_taint_module(mod, TAINT_OOT_MODULE);
+
        if (get_modinfo(info, "staging")) {
                add_taint_module(mod, TAINT_CRAP);
                printk(KERN_WARNING "%s: module is from the staging directory,"
@@ -2545,7 +2690,7 @@ static int move_module(struct module *mod, struct load_info *info)
        mod->module_init = ptr;
 
        /* Transfer each section which specifies SHF_ALLOC */
-       DEBUGP("final section addresses:\n");
+       pr_debug("final section addresses:\n");
        for (i = 0; i < info->hdr->e_shnum; i++) {
                void *dest;
                Elf_Shdr *shdr = &info->sechdrs[i];
@@ -2563,8 +2708,8 @@ static int move_module(struct module *mod, struct load_info *info)
                        memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
                /* Update sh_addr to point to copy in image. */
                shdr->sh_addr = (unsigned long)dest;
-               DEBUGP("\t0x%lx %s\n",
-                      shdr->sh_addr, info->secstrings + shdr->sh_name);
+               pr_debug("\t0x%lx %s\n",
+                        (long)shdr->sh_addr, info->secstrings + shdr->sh_name);
        }
 
        return 0;
@@ -2623,6 +2768,14 @@ static void flush_module_icache(const struct module *mod)
        set_fs(old_fs);
 }
 
+int __weak module_frob_arch_sections(Elf_Ehdr *hdr,
+                                    Elf_Shdr *sechdrs,
+                                    char *secstrings,
+                                    struct module *mod)
+{
+       return 0;
+}
+
 static struct module *layout_and_allocate(struct load_info *info)
 {
        /* Module within temporary copy. */
@@ -2658,27 +2811,18 @@ static struct module *layout_and_allocate(struct load_info *info)
           this is done generically; there doesn't appear to be any
           special cases for the architectures. */
        layout_sections(mod, info);
-
-       info->strmap = kzalloc(BITS_TO_LONGS(info->sechdrs[info->index.str].sh_size)
-                        * sizeof(long), GFP_KERNEL);
-       if (!info->strmap) {
-               err = -ENOMEM;
-               goto free_percpu;
-       }
        layout_symtab(mod, info);
 
        /* Allocate and move to the final place */
        err = move_module(mod, info);
        if (err)
-               goto free_strmap;
+               goto free_percpu;
 
        /* 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_strmap:
-       kfree(info->strmap);
 free_percpu:
        percpu_modfree(mod);
 out:
@@ -2688,12 +2832,18 @@ out:
 /* mod is no longer valid after this! */
 static void module_deallocate(struct module *mod, struct load_info *info)
 {
-       kfree(info->strmap);
        percpu_modfree(mod);
        module_free(mod, mod->module_init);
        module_free(mod, mod->module_core);
 }
 
+int __weak module_finalize(const Elf_Ehdr *hdr,
+                          const Elf_Shdr *sechdrs,
+                          struct module *me)
+{
+       return 0;
+}
+
 static int post_relocation(struct module *mod, const struct load_info *info)
 {
        /* Sort exception table now relocations are done. */
@@ -2720,7 +2870,7 @@ static struct module *load_module(void __user *umod,
        struct module *mod;
        long err;
 
-       DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
+       pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n",
               umod, len, uargs);
 
        /* Copy in the blobs from userspace, check they are vaguely sane. */
@@ -2777,7 +2927,7 @@ static struct module *load_module(void __user *umod,
        mod->state = MODULE_STATE_COMING;
 
        /* Now sew it into the lists so we can get lockdep and oops
-        * info during argument parsing.  Noone should access us, since
+        * info during argument parsing.  No one should access us, since
         * strong_try_module_get() will fail.
         * lockdep/oops can run asynchronous, so use the RCU list insertion
         * function to insert in a way safe to concurrent readers.
@@ -2790,8 +2940,7 @@ static struct module *load_module(void __user *umod,
        }
 
        /* This has to be done once we're sure module name is unique. */
-       if (!mod->taints)
-               dynamic_debug_setup(info.debug, info.num_debug);
+       dynamic_debug_setup(info.debug, info.num_debug);
 
        /* Find duplicate symbols */
        err = verify_export_symbols(mod);
@@ -2803,7 +2952,8 @@ static struct module *load_module(void __user *umod,
        mutex_unlock(&module_mutex);
 
        /* Module is ready to execute: parsing args may do that. */
-       err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
+       err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
+                        -32768, 32767, NULL);
        if (err < 0)
                goto unlink;
 
@@ -2812,8 +2962,7 @@ static struct module *load_module(void __user *umod,
        if (err < 0)
                goto unlink;
 
-       /* Get rid of temporary copy and strmap. */
-       kfree(info.strmap);
+       /* Get rid of temporary copy. */
        free_copy(&info);
 
        /* Done! */
@@ -2827,8 +2976,7 @@ static struct module *load_module(void __user *umod,
        module_bug_cleanup(mod);
 
  ddebug:
-       if (!mod->taints)
-               dynamic_debug_remove(info.debug);
+       dynamic_debug_remove(info.debug);
  unlock:
        mutex_unlock(&module_mutex);
        synchronize_sched();
@@ -2931,10 +3079,11 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
        mod->symtab = mod->core_symtab;
        mod->strtab = mod->core_strtab;
 #endif
-       unset_section_ro_nx(mod, mod->module_init);
+       unset_module_init_ro_nx(mod);
        module_free(mod, mod->module_init);
        mod->module_init = NULL;
        mod->init_size = 0;
+       mod->init_ro_size = 0;
        mod->init_text_size = 0;
        mutex_unlock(&module_mutex);
 
@@ -2971,7 +3120,7 @@ static const char *get_ksymbol(struct module *mod,
        else
                nextval = (unsigned long)mod->module_core+mod->core_text_size;
 
-       /* Scan for closest preceeding symbol, and next symbol. (ELF
+       /* Scan for closest preceding symbol, and next symbol. (ELF
           starts real symbols at 1). */
        for (i = 1; i < mod->num_symtab; i++) {
                if (mod->symtab[i].st_shndx == SHN_UNDEF)
@@ -3166,18 +3315,7 @@ static char *module_flags(struct module *mod, char *buf)
            mod->state == MODULE_STATE_GOING ||
            mod->state == MODULE_STATE_COMING) {
                buf[bx++] = '(';
-               if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
-                       buf[bx++] = 'P';
-               if (mod->taints & (1 << TAINT_FORCED_MODULE))
-                       buf[bx++] = 'F';
-               if (mod->taints & (1 << TAINT_CRAP))
-                       buf[bx++] = 'C';
-               /*
-                * TAINT_FORCED_RMMOD: could be added.
-                * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
-                * apply to modules.
-                */
-
+               bx += module_flags_taint(mod, buf + bx);
                /* Show a - for module-is-being-unloaded */
                if (mod->state == MODULE_STATE_GOING)
                        buf[bx++] = '-';
@@ -3224,7 +3362,7 @@ static int m_show(struct seq_file *m, void *p)
                   mod->state == MODULE_STATE_COMING ? "Loading":
                   "Live");
        /* Used by oprofile and other similar tools. */
-       seq_printf(m, " 0x%p", mod->module_core);
+       seq_printf(m, " 0x%pK", mod->module_core);
 
        /* Taints info */
        if (mod->taints)
@@ -3398,50 +3536,3 @@ void module_layout(struct module *mod,
 }
 EXPORT_SYMBOL(module_layout);
 #endif
-
-#ifdef CONFIG_TRACEPOINTS
-void module_update_tracepoints(void)
-{
-       struct module *mod;
-
-       mutex_lock(&module_mutex);
-       list_for_each_entry(mod, &modules, list)
-               if (!mod->taints)
-                       tracepoint_update_probe_range(mod->tracepoints_ptrs,
-                               mod->tracepoints_ptrs + mod->num_tracepoints);
-       mutex_unlock(&module_mutex);
-}
-
-/*
- * Returns 0 if current not found.
- * Returns 1 if current found.
- */
-int module_get_iter_tracepoints(struct tracepoint_iter *iter)
-{
-       struct module *iter_mod;
-       int found = 0;
-
-       mutex_lock(&module_mutex);
-       list_for_each_entry(iter_mod, &modules, list) {
-               if (!iter_mod->taints) {
-                       /*
-                        * Sorted module list
-                        */
-                       if (iter_mod < iter->module)
-                               continue;
-                       else if (iter_mod > iter->module)
-                               iter->tracepoint = NULL;
-                       found = tracepoint_get_iter_range(&iter->tracepoint,
-                               iter_mod->tracepoints_ptrs,
-                               iter_mod->tracepoints_ptrs
-                                       + iter_mod->num_tracepoints);
-                       if (found) {
-                               iter->module = iter_mod;
-                               break;
-                       }
-               }
-       }
-       mutex_unlock(&module_mutex);
-       return found;
-}
-#endif