misc: nct1008: avoid reading bogus temperature
[linux-3.10.git] / kernel / module.c
index fd8d46c..2b741ae 100644 (file)
@@ -1,6 +1,6 @@
 /*
    Copyright (C) 2002 Richard Henderson
-   Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
+   Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     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/kallsyms.h>
+#include <linux/file.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
 #include <linux/kernel.h>
@@ -28,6 +29,7 @@
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
 #include <linux/proc_fs.h>
+#include <linux/security.h>
 #include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/fcntl.h>
 #include <linux/async.h>
 #include <linux/percpu.h>
 #include <linux/kmemleak.h>
+#include <linux/jump_label.h>
+#include <linux/pfn.h>
+#include <linux/bsearch.h>
+#include <linux/fips.h>
+#include <uapi/linux/module.h>
+#include "module-internal.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
 
+/*
+ * Modules' sections will be aligned on page boundaries
+ * to ensure complete separation of code and data, but
+ * only when CONFIG_DEBUG_SET_MODULE_RONX=y
+ */
+#ifdef CONFIG_DEBUG_SET_MODULE_RONX
+# define debug_align(X) ALIGN(X, PAGE_SIZE)
+#else
+# define debug_align(X) (X)
+#endif
+
+/*
+ * Given BASE and SIZE this macro calculates the number of pages the
+ * memory regions occupies
+ */
+#define MOD_NUMBER_OF_PAGES(BASE, SIZE) (((SIZE) > 0) ?                \
+               (PFN_DOWN((unsigned long)(BASE) + (SIZE) - 1) - \
+                        PFN_DOWN((unsigned long)BASE) + 1)     \
+               : (0UL))
+
 /* If this is set, the section belongs in the init part of the module */
 #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
 
@@ -85,9 +107,47 @@ static LIST_HEAD(modules);
 struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
 #endif /* CONFIG_KGDB_KDB */
 
+#ifdef CONFIG_MODULE_SIG
+#ifdef CONFIG_MODULE_SIG_FORCE
+static bool sig_enforce = true;
+#else
+static bool sig_enforce = false;
+
+static int param_set_bool_enable_only(const char *val,
+                                     const struct kernel_param *kp)
+{
+       int err;
+       bool test;
+       struct kernel_param dummy_kp = *kp;
+
+       dummy_kp.arg = &test;
+
+       err = param_set_bool(val, &dummy_kp);
+       if (err)
+               return err;
+
+       /* Don't let them unset it once it's set! */
+       if (!test && sig_enforce)
+               return -EROFS;
+
+       if (test)
+               sig_enforce = true;
+       return 0;
+}
+
+static const struct kernel_param_ops param_ops_bool_enable_only = {
+       .set = param_set_bool_enable_only,
+       .get = param_get_bool,
+};
+#define param_check_bool_enable_only param_check_bool
+
+module_param(sig_enforce, bool_enable_only, 0644);
+#endif /* !CONFIG_MODULE_SIG_FORCE */
+#endif /* CONFIG_MODULE_SIG */
 
 /* 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);
@@ -114,9 +174,11 @@ struct load_info {
        Elf_Ehdr *hdr;
        unsigned long len;
        Elf_Shdr *sechdrs;
-       char *secstrings, *args, *strtab;
-       unsigned long *strmap;
+       char *secstrings, *strtab;
        unsigned long symoffs, stroffs;
+       struct _ddebug *debug;
+       unsigned int num_debug;
+       bool sig_ok;
        struct {
                unsigned int sym, str, mod, vers, info, pcpu;
        } index;
@@ -126,6 +188,7 @@ struct load_info {
    ongoing or failed initialization etc. */
 static inline int strong_try_module_get(struct module *mod)
 {
+       BUG_ON(mod && mod->state == MODULE_STATE_UNFORMED);
        if (mod && mod->state == MODULE_STATE_COMING)
                return -EBUSY;
        if (try_module_get(mod))
@@ -134,9 +197,10 @@ static inline int strong_try_module_get(struct module *mod)
                return -ENOENT;
 }
 
-static inline void add_taint_module(struct module *mod, unsigned flag)
+static inline void add_taint_module(struct module *mod, unsigned flag,
+                                   enum lockdep_ok lockdep_ok)
 {
-       add_taint(flag);
+       add_taint(flag, lockdep_ok);
        mod->taints |= (1U << flag);
 }
 
@@ -152,42 +216,38 @@ void __module_put_and_exit(struct module *mod, long code)
 EXPORT_SYMBOL(__module_put_and_exit);
 
 /* Find a module section: 0 means not found. */
-static unsigned int find_sec(Elf_Ehdr *hdr,
-                            Elf_Shdr *sechdrs,
-                            const char *secstrings,
-                            const char *name)
+static unsigned int find_sec(const struct load_info *info, const char *name)
 {
        unsigned int i;
 
-       for (i = 1; i < hdr->e_shnum; i++)
+       for (i = 1; i < info->hdr->e_shnum; i++) {
+               Elf_Shdr *shdr = &info->sechdrs[i];
                /* Alloc bit cleared means "ignore it." */
-               if ((sechdrs[i].sh_flags & SHF_ALLOC)
-                   && strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
+               if ((shdr->sh_flags & SHF_ALLOC)
+                   && strcmp(info->secstrings + shdr->sh_name, name) == 0)
                        return i;
+       }
        return 0;
 }
 
 /* Find a module section, or NULL. */
-static void *section_addr(Elf_Ehdr *hdr, Elf_Shdr *shdrs,
-                         const char *secstrings, const char *name)
+static void *section_addr(const struct load_info *info, const char *name)
 {
        /* Section 0 has sh_addr 0. */
-       return (void *)shdrs[find_sec(hdr, shdrs, secstrings, name)].sh_addr;
+       return (void *)info->sechdrs[find_sec(info, name)].sh_addr;
 }
 
 /* Find a module section, or NULL.  Fill in number of "objects" in section. */
-static void *section_objs(Elf_Ehdr *hdr,
-                         Elf_Shdr *sechdrs,
-                         const char *secstrings,
+static void *section_objs(const struct load_info *info,
                          const char *name,
                          size_t object_size,
                          unsigned int *num)
 {
-       unsigned int sec = find_sec(hdr, sechdrs, secstrings, name);
+       unsigned int sec = find_sec(info, name);
 
        /* Section 0 has sh_addr 0 and sh_size 0. */
-       *num = sechdrs[sec].sh_size / object_size;
-       return (void *)sechdrs[sec].sh_addr;
+       *num = info->sechdrs[sec].sh_size / object_size;
+       return (void *)info->sechdrs[sec].sh_addr;
 }
 
 /* Provided by the linker */
@@ -220,23 +280,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[] = {
@@ -284,12 +345,15 @@ bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
 #endif
                };
 
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
+
                if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
                        return true;
        }
        return false;
 }
-EXPORT_SYMBOL_GPL(each_symbol);
+EXPORT_SYMBOL_GPL(each_symbol_section);
 
 struct find_symbol_arg {
        /* Input */
@@ -303,15 +367,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;
@@ -319,9 +380,6 @@ static bool find_symbol_in_section(const struct symsearch *syms,
                        printk(KERN_WARNING "Symbol %s is being used "
                               "by a non-GPL module, which will not "
                               "be allowed in the future\n", fsa->name);
-                       printk(KERN_WARNING "Please see the file "
-                              "Documentation/feature-removal-schedule.txt "
-                              "in the kernel source tree for more details.\n");
                }
        }
 
@@ -345,6 +403,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,
@@ -359,7 +441,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)
@@ -367,22 +449,30 @@ 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);
 
 /* Search for module by name: must hold module_mutex. */
-struct module *find_module(const char *name)
+static struct module *find_module_all(const char *name,
+                                     bool even_unformed)
 {
        struct module *mod;
 
        list_for_each_entry(mod, &modules, list) {
+               if (!even_unformed && mod->state == MODULE_STATE_UNFORMED)
+                       continue;
                if (strcmp(mod->name, name) == 0)
                        return mod;
        }
        return NULL;
 }
+
+struct module *find_module(const char *name)
+{
+       return find_module_all(name, false);
+}
 EXPORT_SYMBOL_GPL(find_module);
 
 #ifdef CONFIG_SMP
@@ -417,11 +507,9 @@ static void percpu_modfree(struct module *mod)
        free_percpu(mod->percpu);
 }
 
-static unsigned int find_pcpusec(Elf_Ehdr *hdr,
-                                Elf_Shdr *sechdrs,
-                                const char *secstrings)
+static unsigned int find_pcpusec(struct load_info *info)
 {
-       return find_sec(hdr, sechdrs, secstrings, ".data..percpu");
+       return find_sec(info, ".data..percpu");
 }
 
 static void percpu_modcopy(struct module *mod,
@@ -450,6 +538,8 @@ bool is_module_percpu_address(unsigned long addr)
        preempt_disable();
 
        list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
                if (!mod->percpu_size)
                        continue;
                for_each_possible_cpu(cpu) {
@@ -481,9 +571,7 @@ static inline int percpu_modalloc(struct module *mod,
 static inline void percpu_modfree(struct module *mod)
 {
 }
-static inline unsigned int find_pcpusec(Elf_Ehdr *hdr,
-                                       Elf_Shdr *sechdrs,
-                                       const char *secstrings)
+static unsigned int find_pcpusec(struct load_info *info)
 {
        return 0;
 }
@@ -506,9 +594,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)               \
 {                                                                     \
@@ -561,11 +649,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;
 }
 
@@ -580,7 +668,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);
@@ -624,7 +712,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);
@@ -640,7 +728,7 @@ static inline int try_force_unload(unsigned int flags)
 {
        int ret = (flags & O_TRUNC);
        if (ret)
-               add_taint(TAINT_FORCED_RMMOD);
+               add_taint(TAINT_FORCED_RMMOD, LOCKDEP_NOW_UNRELIABLE);
        return ret;
 }
 #else
@@ -687,9 +775,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)
@@ -722,7 +810,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;
@@ -765,7 +853,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;
        }
@@ -793,7 +881,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,
@@ -815,7 +903,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. */
@@ -863,15 +951,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)
 {
@@ -912,12 +1028,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;
@@ -927,21 +1063,70 @@ static ssize_t show_initstate(struct module_attribute *mattr,
        case MODULE_STATE_GOING:
                state = "going";
                break;
+       default:
+               BUG();
        }
        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,
 };
@@ -954,7 +1139,7 @@ static int try_to_force_load(struct module *mod, const char *reason)
        if (!test_taint(TAINT_FORCED_MODULE))
                printk(KERN_WARNING "%s: %s: kernel tainted.\n",
                       mod->name, reason);
-       add_taint_module(mod, TAINT_FORCED_MODULE);
+       add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_NOW_UNRELIABLE);
        return 0;
 #else
        return -ENOEXEC;
@@ -1001,7 +1186,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;
        }
@@ -1024,10 +1209,11 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
 
        /* Since this should be found in kernel (which can't be removed),
         * no locking is necessary. */
-       if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL,
+       if (!find_symbol(VMLINUX_SYMBOL_STR(module_layout), NULL,
                         &crc, true, false))
                BUG();
-       return check_version(sechdrs, versindex, "module_layout", mod, crc,
+       return check_version(sechdrs, versindex,
+                            VMLINUX_SYMBOL_STR(module_layout), mod, crc,
                             NULL);
 }
 
@@ -1067,10 +1253,9 @@ static inline int same_magic(const char *amagic, const char *bmagic,
 #endif /* CONFIG_MODVERSIONS */
 
 /* Resolve a symbol for this module.  I.e. if we find one, record usage. */
-static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
-                                                 unsigned int versindex,
+static const struct kernel_symbol *resolve_symbol(struct module *mod,
+                                                 const struct load_info *info,
                                                  const char *name,
-                                                 struct module *mod,
                                                  char ownername[])
 {
        struct module *owner;
@@ -1084,7 +1269,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
        if (!sym)
                goto unlock;
 
-       if (!check_version(sechdrs, versindex, name, mod, crc, owner)) {
+       if (!check_version(info->sechdrs, info->index.vers, name, mod, crc,
+                          owner)) {
                sym = ERR_PTR(-EINVAL);
                goto getname;
        }
@@ -1103,21 +1289,20 @@ unlock:
        return sym;
 }
 
-static const struct kernel_symbol *resolve_symbol_wait(Elf_Shdr *sechdrs,
-                                                      unsigned int versindex,
-                                                      const char *name,
-                                                      struct module *mod)
+static const struct kernel_symbol *
+resolve_symbol_wait(struct module *mod,
+                   const struct load_info *info,
+                   const char *name)
 {
        const struct kernel_symbol *ksym;
-       char ownername[MODULE_NAME_LEN];
+       char owner[MODULE_NAME_LEN];
 
        if (wait_event_interruptible_timeout(module_wq,
-                       !IS_ERR(ksym = resolve_symbol(sechdrs, versindex, name,
-                                                     mod, ownername)) ||
-                       PTR_ERR(ksym) != -EBUSY,
+                       !IS_ERR(ksym = resolve_symbol(mod, info, name, owner))
+                       || PTR_ERR(ksym) != -EBUSY,
                                             30 * HZ) <= 0) {
                printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n",
-                      mod->name, ownername);
+                      mod->name, owner);
        }
        return ksym;
 }
@@ -1149,11 +1334,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)
@@ -1504,11 +1689,6 @@ static void mod_sysfs_fini(struct module *mod)
 
 #else /* !CONFIG_SYSFS */
 
-static int mod_sysfs_init(struct module *mod)
-{
-       return 0;
-}
-
 static int mod_sysfs_setup(struct module *mod,
                           const struct load_info *info,
                           struct kernel_param *kparam,
@@ -1521,13 +1701,17 @@ static void mod_sysfs_fini(struct module *mod)
 {
 }
 
+static void module_remove_modinfo_attrs(struct module *mod)
+{
+}
+
 static void del_usage_links(struct module *mod)
 {
 }
 
 #endif /* CONFIG_SYSFS */
 
-static void mod_kobject_remove(struct module *mod)
+static void mod_sysfs_teardown(struct module *mod)
 {
        del_usage_links(mod);
        module_remove_modinfo_attrs(mod);
@@ -1545,19 +1729,144 @@ static int __unlink_module(void *_mod)
 {
        struct module *mod = _mod;
        list_del(&mod->list);
+       module_bug_cleanup(mod);
        return 0;
 }
 
+#ifdef CONFIG_DEBUG_SET_MODULE_RONX
+/*
+ * LKM RO/NX protection: protect module's text/ro-data
+ * from modification and any data from execution.
+ */
+void set_page_attributes(void *start, void *end, int (*set)(unsigned long start, int num_pages))
+{
+       unsigned long begin_pfn = PFN_DOWN((unsigned long)start);
+       unsigned long end_pfn = PFN_DOWN((unsigned long)end);
+
+       if (end_pfn > begin_pfn)
+               set(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn);
+}
+
+static void set_section_ro_nx(void *base,
+                       unsigned long text_size,
+                       unsigned long ro_size,
+                       unsigned long total_size)
+{
+       /* begin and end PFNs of the current subsection */
+       unsigned long begin_pfn;
+       unsigned long end_pfn;
+
+       /*
+        * Set RO for module text and RO-data:
+        * - Always protect first page.
+        * - Do not protect last partial page.
+        */
+       if (ro_size > 0)
+               set_page_attributes(base, base + ro_size, set_memory_ro);
+
+       /*
+        * Set NX permissions for module data:
+        * - Do not protect first partial page.
+        * - Always protect last page.
+        */
+       if (total_size > text_size) {
+               begin_pfn = PFN_UP((unsigned long)base + text_size);
+               end_pfn = PFN_UP((unsigned long)base + total_size);
+               if (end_pfn > begin_pfn)
+                       set_memory_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn);
+       }
+}
+
+static void unset_module_core_ro_nx(struct module *mod)
+{
+       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);
+}
+
+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)
+{
+       struct module *mod;
+
+       mutex_lock(&module_mutex);
+       list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
+               if ((mod->module_core) && (mod->core_text_size)) {
+                       set_page_attributes(mod->module_core,
+                                               mod->module_core + mod->core_text_size,
+                                               set_memory_rw);
+               }
+               if ((mod->module_init) && (mod->init_text_size)) {
+                       set_page_attributes(mod->module_init,
+                                               mod->module_init + mod->init_text_size,
+                                               set_memory_rw);
+               }
+       }
+       mutex_unlock(&module_mutex);
+}
+
+/* Iterate through all modules and set each module's text as RO */
+void set_all_modules_text_ro(void)
+{
+       struct module *mod;
+
+       mutex_lock(&module_mutex);
+       list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
+               if ((mod->module_core) && (mod->core_text_size)) {
+                       set_page_attributes(mod->module_core,
+                                               mod->module_core + mod->core_text_size,
+                                               set_memory_ro);
+               }
+               if ((mod->module_init) && (mod->init_text_size)) {
+                       set_page_attributes(mod->module_init,
+                                               mod->module_init + mod->init_text_size,
+                                               set_memory_ro);
+               }
+       }
+       mutex_unlock(&module_mutex);
+}
+#else
+static inline void set_section_ro_nx(void *base, unsigned long text_size, unsigned long ro_size, unsigned long total_size) { }
+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)
 {
        trace_module_free(mod);
 
-       /* Delete from various lists */
-       mutex_lock(&module_mutex);
-       stop_machine(__unlink_module, mod, NULL);
-       mutex_unlock(&module_mutex);
-       mod_kobject_remove(mod);
+       mod_sysfs_teardown(mod);
+
+       /* We leave it in list to prevent duplicate loads, but make sure
+        * that noone uses it while it's being deconstructed. */
+       mod->state = MODULE_STATE_UNFORMED;
 
        /* Remove dynamic debug info */
        ddebug_remove_module(mod->name);
@@ -1571,7 +1880,13 @@ static void free_module(struct module *mod)
        /* Free any allocated parameters. */
        destroy_params(mod->kp, mod->num_kp);
 
+       /* Now we can delete it from the lists */
+       mutex_lock(&module_mutex);
+       stop_machine(__unlink_module, mod, NULL);
+       mutex_unlock(&module_mutex);
+
        /* This may be NULL, but that's OK */
+       unset_module_init_ro_nx(mod);
        module_free(mod, mod->module_init);
        kfree(mod->args);
        percpu_modfree(mod);
@@ -1580,6 +1895,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_module_core_ro_nx(mod);
        module_free(mod, mod->module_core);
 
 #ifdef CONFIG_MPU
@@ -1641,25 +1957,23 @@ static int verify_export_symbols(struct module *mod)
 }
 
 /* Change all symbols so that st_value encodes the pointer directly. */
-static int simplify_symbols(Elf_Shdr *sechdrs,
-                           unsigned int symindex,
-                           const char *strtab,
-                           unsigned int versindex,
-                           unsigned int pcpuindex,
-                           struct module *mod)
-{
-       Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+static int simplify_symbols(struct module *mod, const struct load_info *info)
+{
+       Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
+       Elf_Sym *sym = (void *)symsec->sh_addr;
        unsigned long secbase;
-       unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+       unsigned int i;
        int ret = 0;
        const struct kernel_symbol *ksym;
 
-       for (i = 1; i < n; i++) {
+       for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) {
+               const char *name = info->strtab + sym[i].st_name;
+
                switch (sym[i].st_shndx) {
                case SHN_COMMON:
                        /* We compiled with -fno-common.  These are not
                           supposed to happen.  */
-                       DEBUGP("Common symbol: %s\n", strtab + sym[i].st_name);
+                       pr_debug("Common symbol: %s\n", name);
                        printk("%s: please compile with -fno-common\n",
                               mod->name);
                        ret = -ENOEXEC;
@@ -1667,14 +1981,12 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
 
                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;
 
                case SHN_UNDEF:
-                       ksym = resolve_symbol_wait(sechdrs, versindex,
-                                                  strtab + sym[i].st_name,
-                                                  mod);
+                       ksym = resolve_symbol_wait(mod, info, name);
                        /* Ok if resolved.  */
                        if (ksym && !IS_ERR(ksym)) {
                                sym[i].st_value = ksym->value;
@@ -1686,17 +1998,16 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
                                break;
 
                        printk(KERN_WARNING "%s: Unknown symbol %s (err %li)\n",
-                              mod->name, strtab + sym[i].st_name,
-                              PTR_ERR(ksym));
+                              mod->name, name, PTR_ERR(ksym));
                        ret = PTR_ERR(ksym) ?: -ENOENT;
                        break;
 
                default:
                        /* Divert to percpu allocation if a percpu var. */
-                       if (sym[i].st_shndx == pcpuindex)
+                       if (sym[i].st_shndx == info->index.pcpu)
                                secbase = (unsigned long)mod_percpu(mod);
                        else
-                               secbase = sechdrs[sym[i].st_shndx].sh_addr;
+                               secbase = info->sechdrs[sym[i].st_shndx].sh_addr;
                        sym[i].st_value += secbase;
                        break;
                }
@@ -1705,33 +2016,29 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
        return ret;
 }
 
-static int apply_relocations(struct module *mod,
-                            Elf_Ehdr *hdr,
-                            Elf_Shdr *sechdrs,
-                            unsigned int symindex,
-                            unsigned int strindex)
+static int apply_relocations(struct module *mod, const struct load_info *info)
 {
        unsigned int i;
        int err = 0;
 
        /* Now do relocations. */
-       for (i = 1; i < hdr->e_shnum; i++) {
-               const char *strtab = (char *)sechdrs[strindex].sh_addr;
-               unsigned int info = sechdrs[i].sh_info;
+       for (i = 1; i < info->hdr->e_shnum; i++) {
+               unsigned int infosec = info->sechdrs[i].sh_info;
 
                /* Not a valid relocation section? */
-               if (info >= hdr->e_shnum)
+               if (infosec >= info->hdr->e_shnum)
                        continue;
 
                /* Don't bother with non-allocated sections */
-               if (!(sechdrs[info].sh_flags & SHF_ALLOC))
+               if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC))
                        continue;
 
-               if (sechdrs[i].sh_type == SHT_REL)
-                       err = apply_relocate(sechdrs, strtab, symindex, i, mod);
-               else if (sechdrs[i].sh_type == SHT_RELA)
-                       err = apply_relocate_add(sechdrs, strtab, symindex, i,
-                                                mod);
+               if (info->sechdrs[i].sh_type == SHT_REL)
+                       err = apply_relocate(info->sechdrs, info->strtab,
+                                            info->index.sym, i, mod);
+               else if (info->sechdrs[i].sh_type == SHT_RELA)
+                       err = apply_relocate_add(info->sechdrs, info->strtab,
+                                                info->index.sym, i, mod);
                if (err < 0)
                        break;
        }
@@ -1762,10 +2069,7 @@ static long get_offset(struct module *mod, unsigned int *size,
    might -- code, read-only data, read-write data, small data.  Tally
    sizes, and place the offsets into sh_entsize fields: high bit means it
    belongs in init. */
-static void layout_sections(struct module *mod,
-                           const Elf_Ehdr *hdr,
-                           Elf_Shdr *sechdrs,
-                           const char *secstrings)
+static void layout_sections(struct module *mod, struct load_info *info)
 {
        static unsigned long const masks[][2] = {
                /* NOTE: all executable code must be the first section
@@ -1778,42 +2082,66 @@ static void layout_sections(struct module *mod,
        };
        unsigned int m, i;
 
-       for (i = 0; i < hdr->e_shnum; i++)
-               sechdrs[i].sh_entsize = ~0UL;
+       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 < hdr->e_shnum; ++i) {
-                       Elf_Shdr *s = &sechdrs[i];
+               for (i = 0; i < info->hdr->e_shnum; ++i) {
+                       Elf_Shdr *s = &info->sechdrs[i];
+                       const char *sname = info->secstrings + s->sh_name;
 
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || strstarts(secstrings + s->sh_name, ".init"))
+                           || strstarts(sname, ".init"))
                                continue;
                        s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
-                       DEBUGP("\t%s\n", secstrings + s->sh_name);
+                       pr_debug("\t%s\n", sname);
                }
-               if (m == 0)
+               switch (m) {
+               case 0: /* executable */
+                       mod->core_size = debug_align(mod->core_size);
                        mod->core_text_size = mod->core_size;
+                       break;
+               case 1: /* RO: text and ro-data */
+                       mod->core_size = debug_align(mod->core_size);
+                       mod->core_ro_size = mod->core_size;
+                       break;
+               case 3: /* whole core */
+                       mod->core_size = debug_align(mod->core_size);
+                       break;
+               }
        }
 
-       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 < hdr->e_shnum; ++i) {
-                       Elf_Shdr *s = &sechdrs[i];
+               for (i = 0; i < info->hdr->e_shnum; ++i) {
+                       Elf_Shdr *s = &info->sechdrs[i];
+                       const char *sname = info->secstrings + s->sh_name;
 
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || !strstarts(secstrings + s->sh_name, ".init"))
+                           || !strstarts(sname, ".init"))
                                continue;
                        s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
                                         | INIT_OFFSET_MASK);
-                       DEBUGP("\t%s\n", secstrings + s->sh_name);
+                       pr_debug("\t%s\n", sname);
                }
-               if (m == 0)
+               switch (m) {
+               case 0: /* executable */
+                       mod->init_size = debug_align(mod->init_size);
                        mod->init_text_size = mod->init_size;
+                       break;
+               case 1: /* RO: text and ro-data */
+                       mod->init_size = debug_align(mod->init_size);
+                       mod->init_ro_size = mod->init_size;
+                       break;
+               case 3: /* whole init */
+                       mod->init_size = debug_align(mod->init_size);
+                       break;
+               }
        }
 }
 
@@ -1826,7 +2154,8 @@ static void set_license(struct module *mod, const char *license)
                if (!test_taint(TAINT_PROPRIETARY_MODULE))
                        printk(KERN_WARNING "%s: module license '%s' taints "
                                "kernel.\n", mod->name, license);
-               add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+               add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
+                                LOCKDEP_NOW_UNRELIABLE);
        }
 }
 
@@ -1849,33 +2178,28 @@ static char *next_string(char *string, unsigned long *secsize)
        return string;
 }
 
-static char *get_modinfo(const Elf_Shdr *sechdrs,
-                        unsigned int info,
-                        const char *tag)
+static char *get_modinfo(struct load_info *info, const char *tag)
 {
        char *p;
        unsigned int taglen = strlen(tag);
-       unsigned long size = sechdrs[info].sh_size;
+       Elf_Shdr *infosec = &info->sechdrs[info->index.info];
+       unsigned long size = infosec->sh_size;
 
-       for (p = (char *)sechdrs[info].sh_addr; p; p = next_string(p, &size)) {
+       for (p = (char *)infosec->sh_addr; p; p = next_string(p, &size)) {
                if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
                        return p + taglen + 1;
        }
        return NULL;
 }
 
-static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
-                         unsigned int infoindex)
+static void setup_modinfo(struct module *mod, struct load_info *info)
 {
        struct module_attribute *attr;
        int i;
 
        for (i = 0; (attr = modinfo_attrs[i]); i++) {
                if (attr->setup)
-                       attr->setup(mod,
-                                   get_modinfo(sechdrs,
-                                               infoindex,
-                                               attr->attr.name));
+                       attr->setup(mod, get_modinfo(info, attr->attr.name));
        }
 }
 
@@ -1897,11 +2221,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,
@@ -1977,59 +2298,51 @@ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
        return true;
 }
 
-static unsigned long layout_symtab(struct module *mod,
-                                  Elf_Shdr *sechdrs,
-                                  unsigned int symindex,
-                                  unsigned int strindex,
-                                  const Elf_Ehdr *hdr,
-                                  const char *secstrings,
-                                  unsigned long *pstroffs,
-                                  unsigned long *strmap)
+/*
+ * 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)
 {
-       unsigned long symoffs;
-       Elf_Shdr *symsect = sechdrs + symindex;
-       Elf_Shdr *strsect = sechdrs + strindex;
+       Elf_Shdr *symsect = info->sechdrs + info->index.sym;
+       Elf_Shdr *strsect = info->sechdrs + info->index.str;
        const Elf_Sym *src;
-       const char *strtab;
-       unsigned int i, nsrc, ndst;
+       unsigned int i, nsrc, ndst, strtab_size = 0;
 
        /* 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,
-                                        symindex) | INIT_OFFSET_MASK;
-       DEBUGP("\t%s\n", secstrings + symsect->sh_name);
+                                        info->index.sym) | INIT_OFFSET_MASK;
+       pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
 
-       src = (void *)hdr + symsect->sh_offset;
+       src = (void *)info->hdr + symsect->sh_offset;
        nsrc = symsect->sh_size / sizeof(*src);
-       strtab = (void *)hdr + strsect->sh_offset;
-       for (ndst = i = 1; i < nsrc; ++i, ++src)
-               if (is_core_symbol(src, sechdrs, hdr->e_shnum)) {
-                       unsigned int j = src->st_name;
-
-                       while(!__test_and_set_bit(j, strmap) && strtab[j])
-                               ++j;
-                       ++ndst;
+
+       /* Compute total space required for the core symbols' strtab. */
+       for (ndst = i = 0; i < nsrc; i++) {
+               if (i == 0 ||
+                   is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
+                       strtab_size += strlen(&info->strtab[src[i].st_name])+1;
+                       ndst++;
                }
+       }
 
        /* Append room for core symbols at end of core part. */
-       symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
-       mod->core_size = symoffs + ndst * sizeof(Elf_Sym);
+       info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
+       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,
-                                        strindex) | INIT_OFFSET_MASK;
-       DEBUGP("\t%s\n", secstrings + strsect->sh_name);
-
-       /* Append room for core symbols' strings at end of core part. */
-       *pstroffs = mod->core_size;
-       __set_bit(0, strmap);
-       mod->core_size += bitmap_weight(strmap, strsect->sh_size);
-
-       return symoffs;
+                                        info->index.str) | INIT_OFFSET_MASK;
+       pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
 }
 
-static void add_kallsyms(struct module *mod, struct load_info *info)
+static void add_kallsyms(struct module *mod, const struct load_info *info)
 {
        unsigned int i, ndst;
        const Elf_Sym *src;
@@ -2047,43 +2360,33 @@ static void add_kallsyms(struct module *mod, 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;
-       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;
+       for (ndst = i = 0; i < mod->num_symtab; i++) {
+               if (i == 0 ||
+                   is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
+                       dst[ndst] = src[i];
+                       dst[ndst++].st_name = s - mod->core_strtab;
+                       s += strlcpy(s, &mod->strtab[src[i].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 unsigned long layout_symtab(struct module *mod,
-                                         Elf_Shdr *sechdrs,
-                                         unsigned int symindex,
-                                         unsigned int strindex,
-                                         const Elf_Ehdr *hdr,
-                                         const char *secstrings,
-                                         unsigned long *pstroffs,
-                                         unsigned long *strmap)
+static inline void layout_symtab(struct module *mod, struct load_info *info)
 {
-       return 0;
 }
 
-static void add_kallsyms(struct module *mod, struct load_info *info)
+static void add_kallsyms(struct module *mod, const struct load_info *info)
 {
 }
 #endif /* CONFIG_KALLSYMS */
 
 static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num)
 {
+       if (!debug)
+               return;
 #ifdef CONFIG_DYNAMIC_DEBUG
        if (ddebug_add_module(debug, num, debug->modname))
                printk(KERN_ERR "dynamic debug error adding module: %s\n",
@@ -2097,6 +2400,11 @@ static void dynamic_debug_remove(struct _ddebug *debug)
                ddebug_remove_module(debug->modname);
 }
 
+void * __weak module_alloc(unsigned long size)
+{
+       return vmalloc_exec(size);
+}
+
 static void *module_alloc_update_bounds(unsigned long size)
 {
        void *ret = module_alloc(size);
@@ -2114,93 +2422,178 @@ static void *module_alloc_update_bounds(unsigned long size)
 }
 
 #ifdef CONFIG_DEBUG_KMEMLEAK
-static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
-                                const Elf_Shdr *sechdrs,
-                                const char *secstrings)
+static void kmemleak_load_module(const struct module *mod,
+                                const struct load_info *info)
 {
        unsigned int i;
 
        /* only scan the sections containing data */
        kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL);
 
-       for (i = 1; i < hdr->e_shnum; i++) {
-               if (!(sechdrs[i].sh_flags & SHF_ALLOC))
-                       continue;
-               if (strncmp(secstrings + sechdrs[i].sh_name, ".data", 5) != 0
-                   && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0)
+       for (i = 1; i < info->hdr->e_shnum; i++) {
+               /* 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 *)sechdrs[i].sh_addr,
-                                  sechdrs[i].sh_size, GFP_KERNEL);
+               kmemleak_scan_area((void *)info->sechdrs[i].sh_addr,
+                                  info->sechdrs[i].sh_size, GFP_KERNEL);
        }
 }
 #else
-static inline void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
-                                       Elf_Shdr *sechdrs,
-                                       const char *secstrings)
+static inline void kmemleak_load_module(const struct module *mod,
+                                       const struct load_info *info)
 {
 }
 #endif
 
-/* Sets info->hdr, info->len and info->args. */
-static int copy_and_check(struct load_info *info,
-                         const void __user *umod, unsigned long len,
-                         const char __user *uargs)
+#ifdef CONFIG_MODULE_SIG
+static int module_sig_check(struct load_info *info)
+{
+       int err = -ENOKEY;
+       const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
+       const void *mod = info->hdr;
+
+       if (info->len > markerlen &&
+           memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
+               /* We truncate the module to discard the signature */
+               info->len -= markerlen;
+               err = mod_verify_sig(mod, &info->len);
+       }
+
+       if (!err) {
+               info->sig_ok = true;
+               return 0;
+       }
+
+       /* Not having a signature is only an error if we're strict. */
+       if (err < 0 && fips_enabled)
+               panic("Module verification failed with error %d in FIPS mode\n",
+                     err);
+       if (err == -ENOKEY && !sig_enforce)
+               err = 0;
+
+       return err;
+}
+#else /* !CONFIG_MODULE_SIG */
+static int module_sig_check(struct load_info *info)
+{
+       return 0;
+}
+#endif /* !CONFIG_MODULE_SIG */
+
+/* Sanity checks against invalid binaries, wrong arch, weird elf version. */
+static int elf_header_check(struct load_info *info)
+{
+       if (info->len < sizeof(*(info->hdr)))
+               return -ENOEXEC;
+
+       if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0
+           || info->hdr->e_type != ET_REL
+           || !elf_check_arch(info->hdr)
+           || info->hdr->e_shentsize != sizeof(Elf_Shdr))
+               return -ENOEXEC;
+
+       if (info->hdr->e_shoff >= info->len
+           || (info->hdr->e_shnum * sizeof(Elf_Shdr) >
+               info->len - info->hdr->e_shoff))
+               return -ENOEXEC;
+
+       return 0;
+}
+
+/* Sets info->hdr and info->len. */
+static int copy_module_from_user(const void __user *umod, unsigned long len,
+                                 struct load_info *info)
 {
        int err;
-       Elf_Ehdr *hdr;
 
-       if (len < sizeof(*hdr))
+       info->len = len;
+       if (info->len < sizeof(*(info->hdr)))
                return -ENOEXEC;
 
+       err = security_kernel_module_from_file(NULL);
+       if (err)
+               return err;
+
        /* 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)
+       info->hdr = vmalloc(info->len);
+       if (!info->hdr)
                return -ENOMEM;
 
-       if (copy_from_user(hdr, umod, len) != 0) {
-               err = -EFAULT;
-               goto free_hdr;
+       if (copy_from_user(info->hdr, umod, info->len) != 0) {
+               vfree(info->hdr);
+               return -EFAULT;
        }
 
-       /* Sanity checks against insmoding binaries or wrong arch,
-          weird elf version */
-       if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
-           || hdr->e_type != ET_REL
-           || !elf_check_arch(hdr)
-           || hdr->e_shentsize != sizeof(Elf_Shdr)) {
-               err = -ENOEXEC;
-               goto free_hdr;
+       return 0;
+}
+
+/* Sets info->hdr and info->len. */
+static int copy_module_from_fd(int fd, struct load_info *info)
+{
+       struct file *file;
+       int err;
+       struct kstat stat;
+       loff_t pos;
+       ssize_t bytes = 0;
+
+       file = fget(fd);
+       if (!file)
+               return -ENOEXEC;
+
+       err = security_kernel_module_from_file(file);
+       if (err)
+               goto out;
+
+       err = vfs_getattr(&file->f_path, &stat);
+       if (err)
+               goto out;
+
+       if (stat.size > INT_MAX) {
+               err = -EFBIG;
+               goto out;
        }
 
-       if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
-               err = -ENOEXEC;
-               goto free_hdr;
+       /* Don't hand 0 to vmalloc, it whines. */
+       if (stat.size == 0) {
+               err = -EINVAL;
+               goto out;
        }
 
-       /* Now copy in args */
-       info->args = strndup_user(uargs, ~0UL >> 1);
-       if (IS_ERR(info->args)) {
-               err = PTR_ERR(info->args);
-               goto free_hdr;
+       info->hdr = vmalloc(stat.size);
+       if (!info->hdr) {
+               err = -ENOMEM;
+               goto out;
        }
 
-       info->hdr = hdr;
-       info->len = len;
-       return 0;
+       pos = 0;
+       while (pos < stat.size) {
+               bytes = kernel_read(file, pos, (char *)(info->hdr) + pos,
+                                   stat.size - pos);
+               if (bytes < 0) {
+                       vfree(info->hdr);
+                       err = bytes;
+                       goto out;
+               }
+               if (bytes == 0)
+                       break;
+               pos += bytes;
+       }
+       info->len = pos;
 
-free_hdr:
-       vfree(hdr);
+out:
+       fput(file);
        return err;
 }
 
 static void free_copy(struct load_info *info)
 {
-       kfree(info->args);
        vfree(info->hdr);
 }
 
-static int rewrite_section_headers(struct load_info *info)
+static int rewrite_section_headers(struct load_info *info, int flags)
 {
        unsigned int i;
 
@@ -2228,8 +2621,11 @@ static int rewrite_section_headers(struct load_info *info)
        }
 
        /* Track but don't keep modinfo and version sections. */
-       info->index.vers = find_sec(info->hdr, info->sechdrs, info->secstrings, "__versions");
-       info->index.info = find_sec(info->hdr, info->sechdrs, info->secstrings, ".modinfo");
+       if (flags & MODULE_INIT_IGNORE_MODVERSIONS)
+               info->index.vers = 0; /* Pretend no __versions section! */
+       else
+               info->index.vers = find_sec(info, "__versions");
+       info->index.info = find_sec(info, ".modinfo");
        info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
        info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
        return 0;
@@ -2243,7 +2639,7 @@ static int rewrite_section_headers(struct load_info *info)
  * Return the temporary module pointer (we'll replace it with the final
  * one when we move the module sections around).
  */
-static struct module *setup_load_info(struct load_info *info)
+static struct module *setup_load_info(struct load_info *info, int flags)
 {
        unsigned int i;
        int err;
@@ -2254,7 +2650,7 @@ static struct module *setup_load_info(struct load_info *info)
        info->secstrings = (void *)info->hdr
                + info->sechdrs[info->hdr->e_shstrndx].sh_offset;
 
-       err = rewrite_section_headers(info);
+       err = rewrite_section_headers(info, flags);
        if (err)
                return ERR_PTR(err);
 
@@ -2269,8 +2665,7 @@ static struct module *setup_load_info(struct load_info *info)
                }
        }
 
-       info->index.mod = find_sec(info->hdr, info->sechdrs, info->secstrings,
-                           ".gnu.linkonce.this_module");
+       info->index.mod = find_sec(info, ".gnu.linkonce.this_module");
        if (!info->index.mod) {
                printk(KERN_WARNING "No module found in object\n");
                return ERR_PTR(-ENOEXEC);
@@ -2284,7 +2679,7 @@ static struct module *setup_load_info(struct load_info *info)
                return ERR_PTR(-ENOEXEC);
        }
 
-       info->index.pcpu = find_pcpusec(info->hdr, info->sechdrs, info->secstrings);
+       info->index.pcpu = find_pcpusec(info);
 
        /* Check module struct version now, before we try to use module. */
        if (!check_modstruct_version(info->sechdrs, info->index.vers, mod))
@@ -2293,109 +2688,112 @@ static struct module *setup_load_info(struct load_info *info)
        return mod;
 }
 
-static int check_modinfo(struct module *mod,
-                        const Elf_Shdr *sechdrs,
-                        unsigned int infoindex, unsigned int versindex)
+static int check_modinfo(struct module *mod, struct load_info *info, int flags)
 {
-       const char *modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
+       const char *modmagic = get_modinfo(info, "vermagic");
        int err;
 
+       if (flags & MODULE_INIT_IGNORE_VERMAGIC)
+               modmagic = NULL;
+
        /* This is allowed: modprobe --force will invalidate it. */
        if (!modmagic) {
                err = try_to_force_load(mod, "bad vermagic");
                if (err)
                        return err;
-       } else if (!same_magic(modmagic, vermagic, versindex)) {
+       } else if (!same_magic(modmagic, vermagic, info->index.vers)) {
                printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
                       mod->name, modmagic, vermagic);
-               return -ENOEXEC;
+               //return -ENOEXEC;
        }
 
-       if (get_modinfo(sechdrs, infoindex, "staging")) {
-               add_taint_module(mod, TAINT_CRAP);
+       if (!get_modinfo(info, "intree"))
+               add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
+
+       if (get_modinfo(info, "staging")) {
+               add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK);
                printk(KERN_WARNING "%s: module is from the staging directory,"
                       " the quality is unknown, you have been warned.\n",
                       mod->name);
        }
 
        /* Set up license info based on the info section */
-       set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
+       set_license(mod, get_modinfo(info, "license"));
 
        return 0;
 }
 
-static void find_module_sections(struct module *mod, Elf_Ehdr *hdr,
-                                Elf_Shdr *sechdrs, const char *secstrings)
+static void find_module_sections(struct module *mod, struct load_info *info)
 {
-       mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
+       mod->kp = section_objs(info, "__param",
                               sizeof(*mod->kp), &mod->num_kp);
-       mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
+       mod->syms = section_objs(info, "__ksymtab",
                                 sizeof(*mod->syms), &mod->num_syms);
-       mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
-       mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl",
+       mod->crcs = section_addr(info, "__kcrctab");
+       mod->gpl_syms = section_objs(info, "__ksymtab_gpl",
                                     sizeof(*mod->gpl_syms),
                                     &mod->num_gpl_syms);
-       mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl");
-       mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings,
+       mod->gpl_crcs = section_addr(info, "__kcrctab_gpl");
+       mod->gpl_future_syms = section_objs(info,
                                            "__ksymtab_gpl_future",
                                            sizeof(*mod->gpl_future_syms),
                                            &mod->num_gpl_future_syms);
-       mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings,
-                                           "__kcrctab_gpl_future");
+       mod->gpl_future_crcs = section_addr(info, "__kcrctab_gpl_future");
 
 #ifdef CONFIG_UNUSED_SYMBOLS
-       mod->unused_syms = section_objs(hdr, sechdrs, secstrings,
-                                       "__ksymtab_unused",
+       mod->unused_syms = section_objs(info, "__ksymtab_unused",
                                        sizeof(*mod->unused_syms),
                                        &mod->num_unused_syms);
-       mod->unused_crcs = section_addr(hdr, sechdrs, secstrings,
-                                       "__kcrctab_unused");
-       mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings,
-                                           "__ksymtab_unused_gpl",
+       mod->unused_crcs = section_addr(info, "__kcrctab_unused");
+       mod->unused_gpl_syms = section_objs(info, "__ksymtab_unused_gpl",
                                            sizeof(*mod->unused_gpl_syms),
                                            &mod->num_unused_gpl_syms);
-       mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings,
-                                           "__kcrctab_unused_gpl");
+       mod->unused_gpl_crcs = section_addr(info, "__kcrctab_unused_gpl");
 #endif
 #ifdef CONFIG_CONSTRUCTORS
-       mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors",
+       mod->ctors = section_objs(info, CONFIG_GCOV_CTORS,
                                  sizeof(*mod->ctors), &mod->num_ctors);
 #endif
 
 #ifdef CONFIG_TRACEPOINTS
-       mod->tracepoints = section_objs(hdr, sechdrs, secstrings,
-                                       "__tracepoints",
-                                       sizeof(*mod->tracepoints),
-                                       &mod->num_tracepoints);
+       mod->tracepoints_ptrs = section_objs(info, "__tracepoints_ptrs",
+                                            sizeof(*mod->tracepoints_ptrs),
+                                            &mod->num_tracepoints);
+#endif
+#ifdef HAVE_JUMP_LABEL
+       mod->jump_entries = section_objs(info, "__jump_table",
+                                       sizeof(*mod->jump_entries),
+                                       &mod->num_jump_entries);
 #endif
 #ifdef CONFIG_EVENT_TRACING
-       mod->trace_events = section_objs(hdr, sechdrs, secstrings,
-                                        "_ftrace_events",
+       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);
 #endif
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
        /* sechdrs[0].sh_size is always zero */
-       mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings,
-                                            "__mcount_loc",
+       mod->ftrace_callsites = section_objs(info, "__mcount_loc",
                                             sizeof(*mod->ftrace_callsites),
                                             &mod->num_ftrace_callsites);
 #endif
 
-       if (section_addr(hdr, sechdrs, secstrings, "__obsparm"))
+       mod->extable = section_objs(info, "__ex_table",
+                                   sizeof(*mod->extable), &mod->num_exentries);
+
+       if (section_addr(info, "__obsparm"))
                printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
                       mod->name);
+
+       info->debug = section_objs(info, "__verbose",
+                                  sizeof(*info->debug), &info->num_debug);
 }
 
-static int move_module(struct module *mod,
-                      Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
-                      const char *secstrings, unsigned modindex)
+static int move_module(struct module *mod, struct load_info *info)
 {
        int i;
        void *ptr;
@@ -2414,49 +2812,51 @@ static int move_module(struct module *mod,
        memset(ptr, 0, mod->core_size);
        mod->module_core = ptr;
 
-       ptr = module_alloc_update_bounds(mod->init_size);
-       /*
-        * The pointer to this block is stored in the module structure
-        * which is inside the block. This block doesn't need to be
-        * scanned as it contains data and code that will be freed
-        * after the module is initialized.
-        */
-       kmemleak_ignore(ptr);
-       if (!ptr && mod->init_size) {
-               module_free(mod, mod->module_core);
-               return -ENOMEM;
-       }
-       memset(ptr, 0, mod->init_size);
-       mod->module_init = ptr;
+       if (mod->init_size) {
+               ptr = module_alloc_update_bounds(mod->init_size);
+               /*
+                * The pointer to this block is stored in the module structure
+                * which is inside the block. This block doesn't need to be
+                * scanned as it contains data and code that will be freed
+                * after the module is initialized.
+                */
+               kmemleak_ignore(ptr);
+               if (!ptr) {
+                       module_free(mod, mod->module_core);
+                       return -ENOMEM;
+               }
+               memset(ptr, 0, mod->init_size);
+               mod->module_init = ptr;
+       } else
+               mod->module_init = NULL;
 
        /* Transfer each section which specifies SHF_ALLOC */
-       DEBUGP("final section addresses:\n");
-       for (i = 0; i < hdr->e_shnum; i++) {
+       pr_debug("final section addresses:\n");
+       for (i = 0; i < info->hdr->e_shnum; i++) {
                void *dest;
+               Elf_Shdr *shdr = &info->sechdrs[i];
 
-               if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+               if (!(shdr->sh_flags & SHF_ALLOC))
                        continue;
 
-               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
+               if (shdr->sh_entsize & INIT_OFFSET_MASK)
                        dest = mod->module_init
-                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
+                               + (shdr->sh_entsize & ~INIT_OFFSET_MASK);
                else
-                       dest = mod->module_core + sechdrs[i].sh_entsize;
+                       dest = mod->module_core + shdr->sh_entsize;
 
-               if (sechdrs[i].sh_type != SHT_NOBITS)
-                       memcpy(dest, (void *)sechdrs[i].sh_addr,
-                              sechdrs[i].sh_size);
+               if (shdr->sh_type != SHT_NOBITS)
+                       memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
                /* Update sh_addr to point to copy in image. */
-               sechdrs[i].sh_addr = (unsigned long)dest;
-               DEBUGP("\t0x%lx %s\n",
-                      sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
+               shdr->sh_addr = (unsigned long)dest;
+               pr_debug("\t0x%lx %s\n",
+                        (long)shdr->sh_addr, info->secstrings + shdr->sh_name);
        }
 
        return 0;
 }
 
-static int check_module_license_and_versions(struct module *mod,
-                                            Elf_Shdr *sechdrs)
+static int check_module_license_and_versions(struct module *mod)
 {
        /*
         * ndiswrapper is under GPL by itself, but loads proprietary modules.
@@ -2464,11 +2864,17 @@ static int check_module_license_and_versions(struct module *mod,
         * using GPL-only symbols it needs.
         */
        if (strcmp(mod->name, "ndiswrapper") == 0)
-               add_taint(TAINT_PROPRIETARY_MODULE);
+               add_taint(TAINT_PROPRIETARY_MODULE, LOCKDEP_NOW_UNRELIABLE);
 
        /* driverloader was caught wrongly pretending to be under GPL */
        if (strcmp(mod->name, "driverloader") == 0)
-               add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+               add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
+                                LOCKDEP_NOW_UNRELIABLE);
+
+       /* lve claims to be GPL but upstream won't provide source */
+       if (strcmp(mod->name, "lve") == 0)
+               add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
+                                LOCKDEP_NOW_UNRELIABLE);
 
 #ifdef CONFIG_MODVERSIONS
        if ((mod->num_syms && !mod->crcs)
@@ -2509,214 +2915,108 @@ static void flush_module_icache(const struct module *mod)
        set_fs(old_fs);
 }
 
-static struct module *layout_and_allocate(struct load_info *info)
+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, int flags)
 {
        /* Module within temporary copy. */
        struct module *mod;
        int err;
 
-       mod = setup_load_info(info);
+       mod = setup_load_info(info, flags);
        if (IS_ERR(mod))
                return mod;
 
-       err = check_modinfo(mod, info->sechdrs, info->index.info, info->index.vers);
+       err = check_modinfo(mod, info, flags);
        if (err)
                return ERR_PTR(err);
 
        /* Allow arches to frob section contents and sizes.  */
-       err = module_frob_arch_sections(info->hdr, info->sechdrs, info->secstrings, mod);
+       err = module_frob_arch_sections(info->hdr, info->sechdrs,
+                                       info->secstrings, mod);
        if (err < 0)
-               goto free_args;
+               return ERR_PTR(err);
 
-       if (info->index.pcpu) {
-               /* We have a special allocation for this section. */
-               err = percpu_modalloc(mod, info->sechdrs[info->index.pcpu].sh_size,
-                                     info->sechdrs[info->index.pcpu].sh_addralign);
-               if (err)
-                       goto free_args;
-               info->sechdrs[info->index.pcpu].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
           special cases for the architectures. */
-       layout_sections(mod, info->hdr, info->sechdrs, info->secstrings);
-
-       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;
-       }
-       info->symoffs = layout_symtab(mod, info->sechdrs, info->index.sym, info->index.str, info->hdr,
-                               info->secstrings, &info->stroffs, info->strmap);
+       layout_sections(mod, info);
+       layout_symtab(mod, info);
 
        /* Allocate and move to the final place */
-       err = move_module(mod, info->hdr, info->sechdrs, info->secstrings, info->index.mod);
+       err = move_module(mod, info);
        if (err)
-               goto free_strmap;
+               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->hdr, info->sechdrs, info->secstrings);
+       kmemleak_load_module(mod, info);
        return mod;
+}
 
-free_strmap:
-       kfree(info->strmap);
-free_percpu:
-       percpu_modfree(mod);
-free_args:
-       kfree(info->args);
-       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! */
 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);
 }
 
-/* Allocate and load the module: note that size of section 0 is always
-   zero, and we rely on this for optional sections. */
-static noinline struct module *load_module(void __user *umod,
-                                 unsigned long len,
-                                 const char __user *uargs)
+int __weak module_finalize(const Elf_Ehdr *hdr,
+                          const Elf_Shdr *sechdrs,
+                          struct module *me)
 {
-       struct load_info info = { NULL, };
-       struct module *mod;
-       long err;
-       struct _ddebug *debug = NULL;
-       unsigned int num_debug = 0;
-
-       DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
-              umod, len, uargs);
-
-       /* Copy in the blobs from userspace, check they are vaguely sane. */
-       err = copy_and_check(&info, umod, len, uargs);
-       if (err)
-               return ERR_PTR(err);
-
-       /* Figure out module layout, and allocate all the memory. */
-       mod = layout_and_allocate(&info);
-       if (IS_ERR(mod)) {
-               err = PTR_ERR(mod);
-               goto free_copy;
-       }
-
-       /* Now we've moved module, initialize linked lists, etc. */
-       err = module_unload_init(mod);
-       if (err)
-               goto free_module;
-
-       /* Now we've got everything in the final locations, we can
-        * find optional sections. */
-       find_module_sections(mod, info.hdr, info.sechdrs, info.secstrings);
-
-       err = check_module_license_and_versions(mod, info.sechdrs);
-       if (err)
-               goto free_unload;
-
-       /* Set up MODINFO_ATTR fields */
-       setup_modinfo(mod, info.sechdrs, info.index.info);
-
-       /* Fix up syms, so that st_value is a pointer to location. */
-       err = simplify_symbols(info.sechdrs, info.index.sym, info.strtab, info.index.vers, info.index.pcpu,
-                              mod);
-       if (err < 0)
-               goto free_modinfo;
-
-       err = apply_relocations(mod, info.hdr, info.sechdrs, info.index.sym, info.index.str);
-       if (err < 0)
-               goto free_modinfo;
+       return 0;
+}
 
-       /* Set up and sort exception table */
-       mod->extable = section_objs(info.hdr, info.sechdrs, info.secstrings, "__ex_table",
-                                   sizeof(*mod->extable), &mod->num_exentries);
+static int post_relocation(struct module *mod, const struct load_info *info)
+{
+       /* Sort exception table now relocations are done. */
        sort_extable(mod->extable, mod->extable + mod->num_exentries);
 
-       /* Finally, copy percpu area over. */
-       percpu_modcopy(mod, (void *)info.sechdrs[info.index.pcpu].sh_addr,
-                      info.sechdrs[info.index.pcpu].sh_size);
-
-       add_kallsyms(mod, &info);
-
-       if (!mod->taints)
-               debug = section_objs(info.hdr, info.sechdrs, info.secstrings, "__verbose",
-                                    sizeof(*debug), &num_debug);
+       /* Copy relocated percpu area over. */
+       percpu_modcopy(mod, (void *)info->sechdrs[info->index.pcpu].sh_addr,
+                      info->sechdrs[info->index.pcpu].sh_size);
 
-       err = module_finalize(info.hdr, info.sechdrs, mod);
-       if (err < 0)
-               goto free_modinfo;
+       /* Setup kallsyms-specific fields. */
+       add_kallsyms(mod, info);
 
-       flush_module_icache(mod);
-
-       mod->args = info.args;
+       /* Arch-specific module finalizing. */
+       return module_finalize(info->hdr, info->sechdrs, mod);
+}
 
-       mod->state = MODULE_STATE_COMING;
+/* Is this module of this name done loading?  No locks held. */
+static bool finished_loading(const char *name)
+{
+       struct module *mod;
+       bool ret;
 
-       /* Now sew it into the lists so we can get lockdep and oops
-        * info during argument parsing.  Noone 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.
-        * The mutex protects against concurrent writers.
-        */
        mutex_lock(&module_mutex);
-       if (find_module(mod->name)) {
-               err = -EEXIST;
-               goto unlock;
-       }
-
-       if (debug)
-               dynamic_debug_setup(debug, num_debug);
-
-       /* Find duplicate symbols */
-       err = verify_export_symbols(mod);
-       if (err < 0)
-               goto ddebug;
-
-       list_add_rcu(&mod->list, &modules);
+       mod = find_module_all(name, true);
+       ret = !mod || mod->state == MODULE_STATE_LIVE
+               || mod->state == MODULE_STATE_GOING;
        mutex_unlock(&module_mutex);
 
-       err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
-       if (err < 0)
-               goto unlink;
-
-       err = mod_sysfs_setup(mod, &info, mod->kp, mod->num_kp);
-       if (err < 0)
-               goto unlink;
-
-       /* Get rid of temporary copy and strmap. */
-       kfree(info.strmap);
-       free_copy(&info);
-
-       trace_module_load(mod);
-
-       /* Done! */
-       return mod;
-
- unlink:
-       mutex_lock(&module_mutex);
-       /* Unlink carefully: kallsyms could be walking list. */
-       list_del_rcu(&mod->list);
- ddebug:
-       dynamic_debug_remove(debug);
- unlock:
-       mutex_unlock(&module_mutex);
-       synchronize_sched();
-       module_arch_cleanup(mod);
- free_modinfo:
-       free_modinfo(mod);
- free_unload:
-       module_unload_free(mod);
- free_module:
-       module_deallocate(mod, &info);
- free_copy:
-       free_copy(&info);
-       return ERR_PTR(err);
+       return ret;
 }
 
 /* Call module constructors. */
@@ -2731,24 +3031,31 @@ static void do_mod_ctors(struct module *mod)
 }
 
 /* This is where the real work happens */
-SYSCALL_DEFINE3(init_module, void __user *, umod,
-               unsigned long, len, const char __user *, uargs)
+static int do_init_module(struct module *mod)
 {
-       struct module *mod;
        int ret = 0;
 
-       /* Must have permission */
-       if (!capable(CAP_SYS_MODULE) || modules_disabled)
-               return -EPERM;
-
-       /* Do all the hard work */
-       mod = load_module(umod, len, uargs);
-       if (IS_ERR(mod))
-               return PTR_ERR(mod);
+       /*
+        * We want to find out whether @mod uses async during init.  Clear
+        * PF_USED_ASYNC.  async_schedule*() will set it.
+        */
+       current->flags &= ~PF_USED_ASYNC;
 
        blocking_notifier_call_chain(&module_notify_list,
                        MODULE_STATE_COMING, mod);
 
+       /* Set RO and NX regions for core */
+       set_section_ro_nx(mod->module_core,
+                               mod->core_text_size,
+                               mod->core_ro_size,
+                               mod->core_size);
+
+       /* Set RO and NX regions for init */
+       set_section_ro_nx(mod->module_init,
+                               mod->init_text_size,
+                               mod->init_ro_size,
+                               mod->init_size);
+
        do_mod_ctors(mod);
        /* Start the module */
        if (mod->init != NULL)
@@ -2762,7 +3069,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
                blocking_notifier_call_chain(&module_notify_list,
                                             MODULE_STATE_GOING, mod);
                free_module(mod);
-               wake_up(&module_wq);
+               wake_up_all(&module_wq);
                return ret;
        }
        if (ret > 0) {
@@ -2774,14 +3081,30 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
                dump_stack();
        }
 
-       /* Now it's a first class citizen!  Wake up anyone waiting for it. */
+       /* Now it's a first class citizen! */
        mod->state = MODULE_STATE_LIVE;
-       wake_up(&module_wq);
        blocking_notifier_call_chain(&module_notify_list,
                                     MODULE_STATE_LIVE, mod);
 
-       /* We need to finish all async code before the module init sequence is done */
-       async_synchronize_full();
+       /*
+        * We need to finish all async code before the module init sequence
+        * is done.  This has potential to deadlock.  For example, a newly
+        * detected block device can trigger request_module() of the
+        * default iosched from async probing task.  Once userland helper
+        * reaches here, async_synchronize_full() will wait on the async
+        * task waiting on request_module() and deadlock.
+        *
+        * This deadlock is avoided by perfomring async_synchronize_full()
+        * iff module init queued any async jobs.  This isn't a full
+        * solution as it will deadlock the same if module loading from
+        * async jobs nests more than once; however, due to the various
+        * constraints, this hack seems to be the best option for now.
+        * Please refer to the following thread for details.
+        *
+        * http://thread.gmane.org/gmane.linux.kernel/1420814
+        */
+       if (current->flags & PF_USED_ASYNC)
+               async_synchronize_full();
 
        mutex_lock(&module_mutex);
        /* Drop initial reference. */
@@ -2792,15 +3115,264 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
        mod->symtab = mod->core_symtab;
        mod->strtab = mod->core_strtab;
 #endif
+       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);
+       wake_up_all(&module_wq);
+
+       return 0;
+}
+
+static int may_init_module(void)
+{
+       if (!capable(CAP_SYS_MODULE) || modules_disabled)
+               return -EPERM;
 
        return 0;
 }
 
+/*
+ * We try to place it in the list now to make sure it's unique before
+ * we dedicate too many resources.  In particular, temporary percpu
+ * memory exhaustion.
+ */
+static int add_unformed_module(struct module *mod)
+{
+       int err;
+       struct module *old;
+
+       mod->state = MODULE_STATE_UNFORMED;
+
+again:
+       mutex_lock(&module_mutex);
+       if ((old = find_module_all(mod->name, true)) != NULL) {
+               if (old->state == MODULE_STATE_COMING
+                   || old->state == MODULE_STATE_UNFORMED) {
+                       /* Wait in case it fails to load. */
+                       mutex_unlock(&module_mutex);
+                       err = wait_event_interruptible(module_wq,
+                                              finished_loading(mod->name));
+                       if (err)
+                               goto out_unlocked;
+                       goto again;
+               }
+               err = -EEXIST;
+               goto out;
+       }
+       list_add_rcu(&mod->list, &modules);
+       err = 0;
+
+out:
+       mutex_unlock(&module_mutex);
+out_unlocked:
+       return err;
+}
+
+static int complete_formation(struct module *mod, struct load_info *info)
+{
+       int err;
+
+       mutex_lock(&module_mutex);
+
+       /* Find duplicate symbols (must be called under lock). */
+       err = verify_export_symbols(mod);
+       if (err < 0)
+               goto out;
+
+       /* This relies on module_mutex for list integrity. */
+       module_bug_finalize(info->hdr, info->sechdrs, mod);
+
+       /* Mark state as coming so strong_try_module_get() ignores us,
+        * but kallsyms etc. can see us. */
+       mod->state = MODULE_STATE_COMING;
+
+out:
+       mutex_unlock(&module_mutex);
+       return err;
+}
+
+/* Allocate and load the module: note that size of section 0 is always
+   zero, and we rely on this for optional sections. */
+static int load_module(struct load_info *info, const char __user *uargs,
+                      int flags)
+{
+       struct module *mod;
+       long err;
+
+       err = module_sig_check(info);
+       if (err)
+               goto free_copy;
+
+       err = elf_header_check(info);
+       if (err)
+               goto free_copy;
+
+       /* Figure out module layout, and allocate all the memory. */
+       mod = layout_and_allocate(info, flags);
+       if (IS_ERR(mod)) {
+               err = PTR_ERR(mod);
+               goto free_copy;
+       }
+
+       /* Reserve our place in the list. */
+       err = add_unformed_module(mod);
+       if (err)
+               goto free_module;
+
+#ifdef CONFIG_MODULE_SIG
+       mod->sig_ok = info->sig_ok;
+       if (!mod->sig_ok) {
+               printk_once(KERN_NOTICE
+                           "%s: module verification failed: signature and/or"
+                           " required key missing - tainting kernel\n",
+                           mod->name);
+               add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_STILL_OK);
+       }
+#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)
+               goto unlink_mod;
+
+       /* Now we've got everything in the final locations, we can
+        * find optional sections. */
+       find_module_sections(mod, info);
+
+       err = check_module_license_and_versions(mod);
+       if (err)
+               goto free_unload;
+
+       /* Set up MODINFO_ATTR fields */
+       setup_modinfo(mod, info);
+
+       /* Fix up syms, so that st_value is a pointer to location. */
+       err = simplify_symbols(mod, info);
+       if (err < 0)
+               goto free_modinfo;
+
+       err = apply_relocations(mod, info);
+       if (err < 0)
+               goto free_modinfo;
+
+       err = post_relocation(mod, info);
+       if (err < 0)
+               goto free_modinfo;
+
+       flush_module_icache(mod);
+
+       /* Now copy in args */
+       mod->args = strndup_user(uargs, ~0UL >> 1);
+       if (IS_ERR(mod->args)) {
+               err = PTR_ERR(mod->args);
+               goto free_arch_cleanup;
+       }
+
+       dynamic_debug_setup(info->debug, info->num_debug);
+
+       /* Finally it's fully formed, ready to start executing. */
+       err = complete_formation(mod, info);
+       if (err)
+               goto ddebug_cleanup;
+
+       /* Module is ready to execute: parsing args may do that. */
+       err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
+                        -32768, 32767, &ddebug_dyndbg_module_param_cb);
+       if (err < 0)
+               goto bug_cleanup;
+
+       /* Link in to syfs. */
+       err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp);
+       if (err < 0)
+               goto bug_cleanup;
+
+       /* Get rid of temporary copy. */
+       free_copy(info);
+
+       /* Done! */
+       trace_module_load(mod);
+
+       return do_init_module(mod);
+
+ bug_cleanup:
+       /* module_bug_cleanup needs module_mutex protection */
+       mutex_lock(&module_mutex);
+       module_bug_cleanup(mod);
+       mutex_unlock(&module_mutex);
+ ddebug_cleanup:
+       dynamic_debug_remove(info->debug);
+       synchronize_sched();
+       kfree(mod->args);
+ free_arch_cleanup:
+       module_arch_cleanup(mod);
+ free_modinfo:
+       free_modinfo(mod);
+ free_unload:
+       module_unload_free(mod);
+ unlink_mod:
+       mutex_lock(&module_mutex);
+       /* Unlink carefully: kallsyms could be walking list. */
+       list_del_rcu(&mod->list);
+       wake_up_all(&module_wq);
+       mutex_unlock(&module_mutex);
+ free_module:
+       module_deallocate(mod, info);
+ free_copy:
+       free_copy(info);
+       return err;
+}
+
+SYSCALL_DEFINE3(init_module, void __user *, umod,
+               unsigned long, len, const char __user *, uargs)
+{
+       int err;
+       struct load_info info = { };
+
+       err = may_init_module();
+       if (err)
+               return err;
+
+       pr_debug("init_module: umod=%p, len=%lu, uargs=%p\n",
+              umod, len, uargs);
+
+       err = copy_module_from_user(umod, len, &info);
+       if (err)
+               return err;
+
+       return load_module(&info, uargs, 0);
+}
+
+SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
+{
+       int err;
+       struct load_info info = { };
+
+       err = may_init_module();
+       if (err)
+               return err;
+
+       pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags);
+
+       if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS
+                     |MODULE_INIT_IGNORE_VERMAGIC))
+               return -EINVAL;
+
+       err = copy_module_from_fd(fd, &info);
+       if (err)
+               return err;
+
+       return load_module(&info, uargs, flags);
+}
+
 static inline int within(unsigned long addr, void *start, unsigned long size)
 {
        return ((void *)addr >= start && (void *)addr < start + size);
@@ -2831,7 +3403,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)
@@ -2874,6 +3446,8 @@ const char *module_address_lookup(unsigned long addr,
 
        preempt_disable();
        list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
                if (within_module_init(addr, mod) ||
                    within_module_core(addr, mod)) {
                        if (modname)
@@ -2897,6 +3471,8 @@ int lookup_module_symbol_name(unsigned long addr, char *symname)
 
        preempt_disable();
        list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
                if (within_module_init(addr, mod) ||
                    within_module_core(addr, mod)) {
                        const char *sym;
@@ -2921,6 +3497,8 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
 
        preempt_disable();
        list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
                if (within_module_init(addr, mod) ||
                    within_module_core(addr, mod)) {
                        const char *sym;
@@ -2948,6 +3526,8 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
 
        preempt_disable();
        list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
                if (symnum < mod->num_symtab) {
                        *value = mod->symtab[symnum].st_value;
                        *type = mod->symtab[symnum].st_info;
@@ -2990,9 +3570,12 @@ unsigned long module_kallsyms_lookup_name(const char *name)
                        ret = mod_find_symname(mod, colon+1);
                *colon = ':';
        } else {
-               list_for_each_entry_rcu(mod, &modules, list)
+               list_for_each_entry_rcu(mod, &modules, list) {
+                       if (mod->state == MODULE_STATE_UNFORMED)
+                               continue;
                        if ((ret = mod_find_symname(mod, name)) != 0)
                                break;
+               }
        }
        preempt_enable();
        return ret;
@@ -3007,6 +3590,8 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
        int ret;
 
        list_for_each_entry(mod, &modules, list) {
+               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,
                                 mod, mod->symtab[i].st_value);
@@ -3022,22 +3607,12 @@ static char *module_flags(struct module *mod, char *buf)
 {
        int bx = 0;
 
+       BUG_ON(mod->state == MODULE_STATE_UNFORMED);
        if (mod->taints ||
            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++] = '-';
@@ -3074,6 +3649,10 @@ static int m_show(struct seq_file *m, void *p)
        struct module *mod = list_entry(p, struct module, list);
        char buf[8];
 
+       /* We always ignore unformed modules. */
+       if (mod->state == MODULE_STATE_UNFORMED)
+               return 0;
+
        seq_printf(m, "%s %u",
                   mod->name, mod->init_size + mod->core_size);
        print_unload_info(m, mod);
@@ -3084,7 +3663,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)
@@ -3134,6 +3713,8 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
 
        preempt_disable();
        list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
                if (mod->num_exentries == 0)
                        continue;
 
@@ -3182,10 +3763,13 @@ struct module *__module_address(unsigned long addr)
        if (addr < module_addr_min || addr > module_addr_max)
                return NULL;
 
-       list_for_each_entry_rcu(mod, &modules, list)
+       list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
                if (within_module_core(addr, mod)
                    || within_module_init(addr, mod))
                        return mod;
+       }
        return NULL;
 }
 EXPORT_SYMBOL_GPL(__module_address);
@@ -3238,8 +3822,11 @@ void print_modules(void)
        printk(KERN_DEFAULT "Modules linked in:");
        /* Most callers should already have preempt disabled, but make sure */
        preempt_disable();
-       list_for_each_entry_rcu(mod, &modules, list)
+       list_for_each_entry_rcu(mod, &modules, list) {
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
                printk(" %s%s", mod->name, module_flags(mod, buf));
+       }
        preempt_enable();
        if (last_unloaded_module[0])
                printk(" [last unloaded: %s]", last_unloaded_module);
@@ -3253,55 +3840,8 @@ void module_layout(struct module *mod,
                   struct modversion_info *ver,
                   struct kernel_param *kp,
                   struct kernel_symbol *ks,
-                  struct tracepoint *tp)
+                  struct tracepoint * const *tp)
 {
 }
 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,
-                               mod->tracepoints + 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,
-                               iter_mod->tracepoints
-                                       + iter_mod->num_tracepoints);
-                       if (found) {
-                               iter->module = iter_mod;
-                               break;
-                       }
-               }
-       }
-       mutex_unlock(&module_mutex);
-       return found;
-}
-#endif