Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-module-and-param
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 5 Apr 2009 17:30:21 +0000 (10:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 5 Apr 2009 17:30:21 +0000 (10:30 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-module-and-param:
  module: use strstarts()
  strstarts: helper function for !strncmp(str, prefix, strlen(prefix))
  arm: allow usage of string functions in linux/string.h
  module: don't use stop_machine on module load
  module: create a request_module_nowait()
  module: include other structures in module version check
  module: remove the SHF_ALLOC flag on the __versions section.
  module: clarify the force-loading taint message.
  module: Export symbols needed for Ksplice
  Ksplice: Add functions for walking kallsyms symbols
  module: remove module_text_address()
  module: __module_address
  module: Make find_symbol return a struct kernel_symbol
  kernel/module.c: fix an unused goto label
  param: fix charp parameters set via sysfs

Fix trivial conflicts in kernel/extable.c manually.

13 files changed:
arch/arm/boot/compressed/misc.c
drivers/mtd/nand/nand_base.c
include/linux/kallsyms.h
include/linux/kmod.h
include/linux/module.h
include/linux/moduleparam.h
include/linux/string.h
kernel/extable.c
kernel/kallsyms.c
kernel/kmod.c
kernel/module.c
kernel/params.c
scripts/mod/modpost.c

index 393c816..9e6e512 100644 (file)
 
 unsigned int __machine_arch_type;
 
-#include <linux/string.h>
+#include <linux/compiler.h>    /* for inline */
+#include <linux/types.h>       /* for size_t */
+#include <linux/stddef.h>      /* for NULL */
+#include <asm/string.h>
 
 #ifdef STANDALONE_DEBUG
 #define putstr printf
index 0c3afcc..5f71371 100644 (file)
@@ -2720,14 +2720,14 @@ int nand_scan_tail(struct mtd_info *mtd)
        return chip->scan_bbt(mtd);
 }
 
-/* module_text_address() isn't exported, and it's mostly a pointless
+/* is_module_text_address() isn't exported, and it's mostly a pointless
    test if this is a module _anyway_ -- they'd have to try _really_ hard
    to call us from in-kernel code if the core NAND support is modular. */
 #ifdef MODULE
 #define caller_is_module() (1)
 #else
 #define caller_is_module() \
-       module_text_address((unsigned long)__builtin_return_address(0))
+       is_module_text_address((unsigned long)__builtin_return_address(0))
 #endif
 
 /**
index f3fe343..7922742 100644 (file)
 #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
                         2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
 
+struct module;
+
 #ifdef CONFIG_KALLSYMS
 /* Lookup the address for a symbol. Returns 0 if not found. */
 unsigned long kallsyms_lookup_name(const char *name);
 
+/* Call a function on each kallsyms symbol in the core kernel */
+int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
+                                     unsigned long),
+                           void *data);
+
 extern int kallsyms_lookup_size_offset(unsigned long addr,
                                  unsigned long *symbolsize,
                                  unsigned long *offset);
@@ -43,6 +50,14 @@ static inline unsigned long kallsyms_lookup_name(const char *name)
        return 0;
 }
 
+static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+                                                   struct module *,
+                                                   unsigned long),
+                                         void *data)
+{
+       return 0;
+}
+
 static inline int kallsyms_lookup_size_offset(unsigned long addr,
                                              unsigned long *symbolsize,
                                              unsigned long *offset)
index 92213a9..d5fa565 100644 (file)
 #ifdef CONFIG_MODULES
 /* modprobe exit status on success, -ve on error.  Return value
  * usually useless though. */
-extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
-#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
+extern int __request_module(bool wait, const char *name, ...) \
+       __attribute__((format(printf, 2, 3)));
+#define request_module(mod...) __request_module(true, mod)
+#define request_module_nowait(mod...) __request_module(false, mod)
+#define try_then_request_module(x, mod...) \
+       ((x) ?: (__request_module(false, mod), (x)))
 #else
-static inline int request_module(const char * name, ...) { return -ENOSYS; }
+static inline int request_module(const char *name, ...) { return -ENOSYS; }
+static inline int request_module_nowait(const char *name, ...) { return -ENOSYS; }
 #define try_then_request_module(x, mod...) (x)
 #endif
 
index 145a755..d246da0 100644 (file)
@@ -248,6 +248,10 @@ struct module
        const unsigned long *crcs;
        unsigned int num_syms;
 
+       /* Kernel parameters. */
+       struct kernel_param *kp;
+       unsigned int num_kp;
+
        /* GPL-only exported symbols. */
        unsigned int num_gpl_syms;
        const struct kernel_symbol *gpl_syms;
@@ -350,6 +354,8 @@ struct module
 #define MODULE_ARCH_INIT {}
 #endif
 
+extern struct mutex module_mutex;
+
 /* FIXME: It'd be nice to isolate modules during init, too, so they
    aren't used before they (may) fail.  But presently too much code
    (IDE & SCSI) require entry into the module during init.*/
@@ -358,10 +364,10 @@ static inline int module_is_live(struct module *mod)
        return mod->state != MODULE_STATE_GOING;
 }
 
-/* Is this address in a module? (second is with no locks, for oops) */
-struct module *module_text_address(unsigned long addr);
 struct module *__module_text_address(unsigned long addr);
-int is_module_address(unsigned long addr);
+struct module *__module_address(unsigned long addr);
+bool is_module_address(unsigned long addr);
+bool is_module_text_address(unsigned long addr);
 
 static inline int within_module_core(unsigned long addr, struct module *mod)
 {
@@ -375,6 +381,31 @@ static inline int within_module_init(unsigned long addr, struct module *mod)
               addr < (unsigned long)mod->module_init + mod->init_size;
 }
 
+/* Search for module by name: must hold module_mutex. */
+struct module *find_module(const char *name);
+
+struct symsearch {
+       const struct kernel_symbol *start, *stop;
+       const unsigned long *crcs;
+       enum {
+               NOT_GPL_ONLY,
+               GPL_ONLY,
+               WILL_BE_GPL_ONLY,
+       } licence;
+       bool unused;
+};
+
+/* Search for an exported symbol by name. */
+const struct kernel_symbol *find_symbol(const char *name,
+                                       struct module **owner,
+                                       const unsigned long **crc,
+                                       bool gplok,
+                                       bool warn);
+
+/* Walk the exported symbol table */
+bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
+                           unsigned int symnum, void *data), void *data);
+
 /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
    symnum out of range. */
 int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
@@ -383,6 +414,10 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
 /* Look for this name: can be of form module:name. */
 unsigned long module_kallsyms_lookup_name(const char *name);
 
+int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+                                            struct module *, unsigned long),
+                                  void *data);
+
 extern void __module_put_and_exit(struct module *mod, long code)
        __attribute__((noreturn));
 #define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
@@ -444,6 +479,7 @@ static inline void __module_get(struct module *module)
 #define symbol_put_addr(p) do { } while(0)
 
 #endif /* CONFIG_MODULE_UNLOAD */
+int use_module(struct module *a, struct module *b);
 
 /* This is a #define so the string doesn't get put in every .o file */
 #define module_name(mod)                       \
@@ -490,21 +526,24 @@ search_module_extables(unsigned long addr)
        return NULL;
 }
 
-/* Is this address in a module? */
-static inline struct module *module_text_address(unsigned long addr)
+static inline struct module *__module_address(unsigned long addr)
 {
        return NULL;
 }
 
-/* Is this address in a module? (don't take a lock, we're oopsing) */
 static inline struct module *__module_text_address(unsigned long addr)
 {
        return NULL;
 }
 
-static inline int is_module_address(unsigned long addr)
+static inline bool is_module_address(unsigned long addr)
 {
-       return 0;
+       return false;
+}
+
+static inline bool is_module_text_address(unsigned long addr)
+{
+       return false;
 }
 
 /* Get/put a kernel symbol (calls should be symmetric) */
@@ -559,6 +598,14 @@ static inline unsigned long module_kallsyms_lookup_name(const char *name)
        return 0;
 }
 
+static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+                                                          struct module *,
+                                                          unsigned long),
+                                                void *data)
+{
+       return 0;
+}
+
 static inline int register_module_notifier(struct notifier_block * nb)
 {
        /* no events will happen anyway, so this can always succeed */
index e4af339..a4f0b93 100644 (file)
@@ -138,6 +138,16 @@ extern int parse_args(const char *name,
                      unsigned num,
                      int (*unknown)(char *param, char *val));
 
+/* Called by module remove. */
+#ifdef CONFIG_SYSFS
+extern void destroy_params(const struct kernel_param *params, unsigned num);
+#else
+static inline void destroy_params(const struct kernel_param *params,
+                                 unsigned num)
+{
+}
+#endif /* !CONFIG_SYSFS */
+
 /* All the helper functions */
 /* The macros to do compile-time type checking stolen from Jakub
    Jelinek, who IIRC came up with this idea for the 2.4 module init code. */
index 3c877d6..489019e 100644 (file)
@@ -122,5 +122,14 @@ int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
 extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
                        const void *from, size_t available);
 
+/**
+ * strstarts - does @str start with @prefix?
+ * @str: string to examine
+ * @prefix: prefix to look for.
+ */
+static inline bool strstarts(const char *str, const char *prefix)
+{
+       return strncmp(str, prefix, strlen(prefix)) == 0;
+}
 #endif
 #endif /* _LINUX_STRING_H_ */
index c46da6a..81e99d1 100644 (file)
@@ -65,7 +65,7 @@ __notrace_funcgraph int __kernel_text_address(unsigned long addr)
 {
        if (core_kernel_text(addr))
                return 1;
-       if (__module_text_address(addr))
+       if (is_module_text_address(addr))
                return 1;
        /*
         * There might be init symbols in saved stacktraces.
@@ -84,7 +84,7 @@ int kernel_text_address(unsigned long addr)
 {
        if (core_kernel_text(addr))
                return 1;
-       return module_text_address(addr) != NULL;
+       return is_module_text_address(addr);
 }
 
 /*
@@ -100,5 +100,5 @@ int func_ptr_is_kernel_text(void *ptr)
        addr = (unsigned long) dereference_function_descriptor(ptr);
        if (core_kernel_text(addr))
                return 1;
-       return module_text_address(addr) != NULL;
+       return is_module_text_address(addr);
 }
index 7b8b0f2..374faf9 100644 (file)
@@ -161,6 +161,25 @@ unsigned long kallsyms_lookup_name(const char *name)
        return module_kallsyms_lookup_name(name);
 }
 
+int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
+                                     unsigned long),
+                           void *data)
+{
+       char namebuf[KSYM_NAME_LEN];
+       unsigned long i;
+       unsigned int off;
+       int ret;
+
+       for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
+               off = kallsyms_expand_symbol(off, namebuf);
+               ret = fn(data, namebuf, NULL, kallsyms_addresses[i]);
+               if (ret != 0)
+                       return ret;
+       }
+       return module_kallsyms_on_each_symbol(fn, data);
+}
+EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);
+
 static unsigned long get_symbol_pos(unsigned long addr,
                                    unsigned long *symbolsize,
                                    unsigned long *offset)
index f0c8f54..b750675 100644 (file)
@@ -50,7 +50,8 @@ static struct workqueue_struct *khelper_wq;
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
 
 /**
- * request_module - try to load a kernel module
+ * __request_module - try to load a kernel module
+ * @wait: wait (or not) for the operation to complete
  * @fmt: printf style format string for the name of the module
  * @...: arguments as specified in the format string
  *
@@ -63,7 +64,7 @@ char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
  * If module auto-loading support is disabled then this function
  * becomes a no-operation.
  */
-int request_module(const char *fmt, ...)
+int __request_module(bool wait, const char *fmt, ...)
 {
        va_list args;
        char module_name[MODULE_NAME_LEN];
@@ -108,11 +109,12 @@ int request_module(const char *fmt, ...)
                return -ENOMEM;
        }
 
-       ret = call_usermodehelper(modprobe_path, argv, envp, 1);
+       ret = call_usermodehelper(modprobe_path, argv, envp,
+                       wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
        atomic_dec(&kmod_concurrent);
        return ret;
 }
-EXPORT_SYMBOL(request_module);
+EXPORT_SYMBOL(__request_module);
 #endif /* CONFIG_MODULES */
 
 struct subprocess_info {
index f77ac32..f6e08b7 100644 (file)
@@ -68,7 +68,8 @@
 
 /* List of modules, protected by module_mutex or preempt_disable
  * (delete uses stop_machine/add uses RCU list operations). */
-static DEFINE_MUTEX(module_mutex);
+DEFINE_MUTEX(module_mutex);
+EXPORT_SYMBOL_GPL(module_mutex);
 static LIST_HEAD(modules);
 
 /* Waiting for a module to finish initializing? */
@@ -76,7 +77,7 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq);
 
 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
 
-/* Bounds of module allocation, for speeding __module_text_address */
+/* Bounds of module allocation, for speeding __module_address */
 static unsigned long module_addr_min = -1UL, module_addr_max = 0;
 
 int register_module_notifier(struct notifier_block * nb)
@@ -186,17 +187,6 @@ extern const unsigned long __start___kcrctab_unused_gpl[];
 #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
 #endif
 
-struct symsearch {
-       const struct kernel_symbol *start, *stop;
-       const unsigned long *crcs;
-       enum {
-               NOT_GPL_ONLY,
-               GPL_ONLY,
-               WILL_BE_GPL_ONLY,
-       } licence;
-       bool unused;
-};
-
 static bool each_symbol_in_section(const struct symsearch *arr,
                                   unsigned int arrsize,
                                   struct module *owner,
@@ -217,10 +207,8 @@ static bool each_symbol_in_section(const struct symsearch *arr,
 }
 
 /* Returns true as soon as fn returns true, otherwise false. */
-static bool each_symbol(bool (*fn)(const struct symsearch *arr,
-                                  struct module *owner,
-                                  unsigned int symnum, void *data),
-                       void *data)
+bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
+                           unsigned int symnum, void *data), void *data)
 {
        struct module *mod;
        const struct symsearch arr[] = {
@@ -273,6 +261,7 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr,
        }
        return false;
 }
+EXPORT_SYMBOL_GPL(each_symbol);
 
 struct find_symbol_arg {
        /* Input */
@@ -283,7 +272,7 @@ struct find_symbol_arg {
        /* Output */
        struct module *owner;
        const unsigned long *crc;
-       unsigned long value;
+       const struct kernel_symbol *sym;
 };
 
 static bool find_symbol_in_section(const struct symsearch *syms,
@@ -324,17 +313,17 @@ static bool find_symbol_in_section(const struct symsearch *syms,
 
        fsa->owner = owner;
        fsa->crc = symversion(syms->crcs, symnum);
-       fsa->value = syms->start[symnum].value;
+       fsa->sym = &syms->start[symnum];
        return true;
 }
 
-/* Find a symbol, return value, (optional) crc and (optional) module
- * which owns it */
-static unsigned long find_symbol(const char *name,
-                                struct module **owner,
-                                const unsigned long **crc,
-                                bool gplok,
-                                bool warn)
+/* Find a symbol and return it, along with, (optional) crc and
+ * (optional) module which owns it */
+const struct kernel_symbol *find_symbol(const char *name,
+                                       struct module **owner,
+                                       const unsigned long **crc,
+                                       bool gplok,
+                                       bool warn)
 {
        struct find_symbol_arg fsa;
 
@@ -347,15 +336,16 @@ static unsigned long find_symbol(const char *name,
                        *owner = fsa.owner;
                if (crc)
                        *crc = fsa.crc;
-               return fsa.value;
+               return fsa.sym;
        }
 
        DEBUGP("Failed to find symbol %s\n", name);
-       return -ENOENT;
+       return NULL;
 }
+EXPORT_SYMBOL_GPL(find_symbol);
 
 /* Search for module by name: must hold module_mutex. */
-static struct module *find_module(const char *name)
+struct module *find_module(const char *name)
 {
        struct module *mod;
 
@@ -365,6 +355,7 @@ static struct module *find_module(const char *name)
        }
        return NULL;
 }
+EXPORT_SYMBOL_GPL(find_module);
 
 #ifdef CONFIG_SMP
 
@@ -641,7 +632,7 @@ static int already_uses(struct module *a, struct module *b)
 }
 
 /* Module a uses b */
-static int use_module(struct module *a, struct module *b)
+int use_module(struct module *a, struct module *b)
 {
        struct module_use *use;
        int no_warn, err;
@@ -674,6 +665,7 @@ static int use_module(struct module *a, struct module *b)
        no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
        return 1;
 }
+EXPORT_SYMBOL_GPL(use_module);
 
 /* Clear the unload stuff of the module. */
 static void module_unload_free(struct module *mod)
@@ -894,7 +886,7 @@ void __symbol_put(const char *symbol)
        struct module *owner;
 
        preempt_disable();
-       if (IS_ERR_VALUE(find_symbol(symbol, &owner, NULL, true, false)))
+       if (!find_symbol(symbol, &owner, NULL, true, false))
                BUG();
        module_put(owner);
        preempt_enable();
@@ -908,8 +900,10 @@ void symbol_put_addr(void *addr)
        if (core_kernel_text((unsigned long)addr))
                return;
 
-       if (!(modaddr = module_text_address((unsigned long)addr)))
-               BUG();
+       /* module_text_address is safe here: we're supposed to have reference
+        * to module from symbol_get, so it can't go away. */
+       modaddr = __module_text_address((unsigned long)addr);
+       BUG_ON(!modaddr);
        module_put(modaddr);
 }
 EXPORT_SYMBOL_GPL(symbol_put_addr);
@@ -949,10 +943,11 @@ static inline void module_unload_free(struct module *mod)
 {
 }
 
-static inline int use_module(struct module *a, struct module *b)
+int use_module(struct module *a, struct module *b)
 {
        return strong_try_module_get(b) == 0;
 }
+EXPORT_SYMBOL_GPL(use_module);
 
 static inline void module_unload_init(struct module *mod)
 {
@@ -995,12 +990,12 @@ static struct module_attribute *modinfo_attrs[] = {
 
 static const char vermagic[] = VERMAGIC_STRING;
 
-static int try_to_force_load(struct module *mod, const char *symname)
+static int try_to_force_load(struct module *mod, const char *reason)
 {
 #ifdef CONFIG_MODULE_FORCE_LOAD
        if (!test_taint(TAINT_FORCED_MODULE))
-               printk("%s: no version for \"%s\" found: kernel tainted.\n",
-                      mod->name, symname);
+               printk(KERN_WARNING "%s: %s: kernel tainted.\n",
+                      mod->name, reason);
        add_taint_module(mod, TAINT_FORCED_MODULE);
        return 0;
 #else
@@ -1057,9 +1052,9 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
 {
        const unsigned long *crc;
 
-       if (IS_ERR_VALUE(find_symbol("struct_module", NULL, &crc, true, false)))
+       if (!find_symbol("module_layout", NULL, &crc, true, false))
                BUG();
-       return check_version(sechdrs, versindex, "struct_module", mod, crc);
+       return check_version(sechdrs, versindex, "module_layout", mod, crc);
 }
 
 /* First part is kernel version, which we ignore if module has crcs. */
@@ -1098,25 +1093,25 @@ static inline int same_magic(const char *amagic, const char *bmagic,
 
 /* Resolve a symbol for this module.  I.e. if we find one, record usage.
    Must be holding module_mutex. */
-static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
-                                   unsigned int versindex,
-                                   const char *name,
-                                   struct module *mod)
+static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
+                                                 unsigned int versindex,
+                                                 const char *name,
+                                                 struct module *mod)
 {
        struct module *owner;
-       unsigned long ret;
+       const struct kernel_symbol *sym;
        const unsigned long *crc;
 
-       ret = find_symbol(name, &owner, &crc,
+       sym = find_symbol(name, &owner, &crc,
                          !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
-       if (!IS_ERR_VALUE(ret)) {
-               /* use_module can fail due to OOM,
-                  or module initialization or unloading */
+       /* use_module can fail due to OOM,
+          or module initialization or unloading */
+       if (sym) {
                if (!check_version(sechdrs, versindex, name, mod, crc) ||
                    !use_module(mod, owner))
-                       ret = -EINVAL;
+                       sym = NULL;
        }
-       return ret;
+       return sym;
 }
 
 /*
@@ -1491,6 +1486,9 @@ static void free_module(struct module *mod)
        /* Module unload stuff */
        module_unload_free(mod);
 
+       /* Free any allocated parameters. */
+       destroy_params(mod->kp, mod->num_kp);
+
        /* release any pointers to mcount in this module */
        ftrace_release(mod->module_core, mod->core_size);
 
@@ -1513,17 +1511,15 @@ static void free_module(struct module *mod)
 void *__symbol_get(const char *symbol)
 {
        struct module *owner;
-       unsigned long value;
+       const struct kernel_symbol *sym;
 
        preempt_disable();
-       value = find_symbol(symbol, &owner, NULL, true, true);
-       if (IS_ERR_VALUE(value))
-               value = 0;
-       else if (strong_try_module_get(owner))
-               value = 0;
+       sym = find_symbol(symbol, &owner, NULL, true, true);
+       if (sym && strong_try_module_get(owner))
+               sym = NULL;
        preempt_enable();
 
-       return (void *)value;
+       return sym ? (void *)sym->value : NULL;
 }
 EXPORT_SYMBOL_GPL(__symbol_get);
 
@@ -1551,8 +1547,7 @@ static int verify_export_symbols(struct module *mod)
 
        for (i = 0; i < ARRAY_SIZE(arr); i++) {
                for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
-                       if (!IS_ERR_VALUE(find_symbol(s->name, &owner,
-                                                     NULL, true, false))) {
+                       if (find_symbol(s->name, &owner, NULL, true, false)) {
                                printk(KERN_ERR
                                       "%s: exports duplicate symbol %s"
                                       " (owned by %s)\n",
@@ -1576,6 +1571,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
        unsigned long secbase;
        unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
        int ret = 0;
+       const struct kernel_symbol *ksym;
 
        for (i = 1; i < n; i++) {
                switch (sym[i].st_shndx) {
@@ -1595,13 +1591,14 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
                        break;
 
                case SHN_UNDEF:
-                       sym[i].st_value
-                         = resolve_symbol(sechdrs, versindex,
-                                          strtab + sym[i].st_name, mod);
-
+                       ksym = resolve_symbol(sechdrs, versindex,
+                                             strtab + sym[i].st_name, mod);
                        /* Ok if resolved.  */
-                       if (!IS_ERR_VALUE(sym[i].st_value))
+                       if (ksym) {
+                               sym[i].st_value = ksym->value;
                                break;
+                       }
+
                        /* Ok if weak.  */
                        if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
                                break;
@@ -1676,8 +1673,7 @@ static void layout_sections(struct module *mod,
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || strncmp(secstrings + s->sh_name,
-                                      ".init", 5) == 0)
+                           || strstarts(secstrings + s->sh_name, ".init"))
                                continue;
                        s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
                        DEBUGP("\t%s\n", secstrings + s->sh_name);
@@ -1694,8 +1690,7 @@ static void layout_sections(struct module *mod,
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || strncmp(secstrings + s->sh_name,
-                                      ".init", 5) != 0)
+                           || !strstarts(secstrings + s->sh_name, ".init"))
                                continue;
                        s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
                                         | INIT_OFFSET_MASK);
@@ -1828,8 +1823,7 @@ static char elf_type(const Elf_Sym *sym,
                else
                        return 'b';
        }
-       if (strncmp(secstrings + sechdrs[sym->st_shndx].sh_name,
-                   ".debug", strlen(".debug")) == 0)
+       if (strstarts(secstrings + sechdrs[sym->st_shndx].sh_name, ".debug"))
                return 'n';
        return '?';
 }
@@ -1898,8 +1892,7 @@ static noinline struct module *load_module(void __user *umod,
        unsigned int symindex = 0;
        unsigned int strindex = 0;
        unsigned int modindex, versindex, infoindex, pcpuindex;
-       unsigned int num_kp, num_mcount;
-       struct kernel_param *kp;
+       unsigned int num_mcount;
        struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -1916,12 +1909,6 @@ static noinline struct module *load_module(void __user *umod,
        if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
                return ERR_PTR(-ENOMEM);
 
-       /* Create stop_machine threads since the error path relies on
-        * a non-failing stop_machine call. */
-       err = stop_machine_create();
-       if (err)
-               goto free_hdr;
-
        if (copy_from_user(hdr, umod, len) != 0) {
                err = -EFAULT;
                goto free_hdr;
@@ -1962,9 +1949,12 @@ static noinline struct module *load_module(void __user *umod,
                }
 #ifndef CONFIG_MODULE_UNLOAD
                /* Don't load .exit sections */
-               if (strncmp(secstrings+sechdrs[i].sh_name, ".exit", 5) == 0)
+               if (strstarts(secstrings+sechdrs[i].sh_name, ".exit"))
                        sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
 #endif
+               /* Don't keep __versions around; it's just for loading. */
+               if (strcmp(secstrings + sechdrs[i].sh_name, "__versions") == 0)
+                       sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
        }
 
        modindex = find_sec(hdr, sechdrs, secstrings,
@@ -2006,7 +1996,7 @@ static noinline struct module *load_module(void __user *umod,
        modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
        /* This is allowed: modprobe --force will invalidate it. */
        if (!modmagic) {
-               err = try_to_force_load(mod, "magic");
+               err = try_to_force_load(mod, "bad vermagic");
                if (err)
                        goto free_hdr;
        } else if (!same_magic(modmagic, vermagic, versindex)) {
@@ -2144,8 +2134,8 @@ static noinline struct module *load_module(void __user *umod,
 
        /* Now we've got everything in the final locations, we can
         * find optional sections. */
-       kp = section_objs(hdr, sechdrs, secstrings, "__param", sizeof(*kp),
-                         &num_kp);
+       mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
+                              sizeof(*mod->kp), &mod->num_kp);
        mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
                                 sizeof(*mod->syms), &mod->num_syms);
        mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
@@ -2195,8 +2185,8 @@ static noinline struct module *load_module(void __user *umod,
            || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
 #endif
                ) {
-               printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name);
-               err = try_to_force_load(mod, "nocrc");
+               err = try_to_force_load(mod,
+                                       "no versions for exported symbols");
                if (err)
                        goto cleanup;
        }
@@ -2291,11 +2281,11 @@ static noinline struct module *load_module(void __user *umod,
         */
        list_add_rcu(&mod->list, &modules);
 
-       err = parse_args(mod->name, mod->args, kp, num_kp, NULL);
+       err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
        if (err < 0)
                goto unlink;
 
-       err = mod_sysfs_setup(mod, kp, num_kp);
+       err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
        if (err < 0)
                goto unlink;
        add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
@@ -2304,12 +2294,13 @@ static noinline struct module *load_module(void __user *umod,
        /* Get rid of temporary copy */
        vfree(hdr);
 
-       stop_machine_destroy();
        /* Done! */
        return mod;
 
  unlink:
-       stop_machine(__unlink_module, mod, NULL);
+       /* Unlink carefully: kallsyms could be walking list. */
+       list_del_rcu(&mod->list);
+       synchronize_sched();
        module_arch_cleanup(mod);
  cleanup:
        kobject_del(&mod->mkobj.kobj);
@@ -2317,8 +2308,8 @@ static noinline struct module *load_module(void __user *umod,
        ftrace_release(mod->module_core, mod->core_size);
  free_unload:
        module_unload_free(mod);
- free_init:
 #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
+ free_init:
        percpu_modfree(mod->refptr);
 #endif
        module_free(mod, mod->module_init);
@@ -2332,7 +2323,6 @@ static noinline struct module *load_module(void __user *umod,
        kfree(args);
  free_hdr:
        vfree(hdr);
-       stop_machine_destroy();
        return ERR_PTR(err);
 
  truncated:
@@ -2609,6 +2599,25 @@ unsigned long module_kallsyms_lookup_name(const char *name)
        preempt_enable();
        return ret;
 }
+
+int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+                                            struct module *, unsigned long),
+                                  void *data)
+{
+       struct module *mod;
+       unsigned int i;
+       int ret;
+
+       list_for_each_entry(mod, &modules, list) {
+               for (i = 0; i < mod->num_symtab; i++) {
+                       ret = fn(data, mod->strtab + mod->symtab[i].st_name,
+                                mod, mod->symtab[i].st_value);
+                       if (ret != 0)
+                               return ret;
+               }
+       }
+       return 0;
+}
 #endif /* CONFIG_KALLSYMS */
 
 static char *module_flags(struct module *mod, char *buf)
@@ -2744,29 +2753,31 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
 }
 
 /*
- * Is this a valid module address?
+ * is_module_address - is this address inside a module?
+ * @addr: the address to check.
+ *
+ * See is_module_text_address() if you simply want to see if the address
+ * is code (not data).
  */
-int is_module_address(unsigned long addr)
+bool is_module_address(unsigned long addr)
 {
-       struct module *mod;
+       bool ret;
 
        preempt_disable();
-
-       list_for_each_entry_rcu(mod, &modules, list) {
-               if (within_module_core(addr, mod)) {
-                       preempt_enable();
-                       return 1;
-               }
-       }
-
+       ret = __module_address(addr) != NULL;
        preempt_enable();
 
-       return 0;
+       return ret;
 }
 
-
-/* Is this a valid kernel address? */
-__notrace_funcgraph struct module *__module_text_address(unsigned long addr)
+/*
+ * __module_address - get the module which contains an address.
+ * @addr: the address.
+ *
+ * Must be called with preempt disabled or module mutex held so that
+ * module doesn't get freed during this.
+ */
+__notrace_funcgraph struct module *__module_address(unsigned long addr)
 {
        struct module *mod;
 
@@ -2774,22 +2785,51 @@ __notrace_funcgraph struct module *__module_text_address(unsigned long addr)
                return NULL;
 
        list_for_each_entry_rcu(mod, &modules, list)
-               if (within(addr, mod->module_init, mod->init_text_size)
-                   || within(addr, mod->module_core, mod->core_text_size))
+               if (within_module_core(addr, mod)
+                   || within_module_init(addr, mod))
                        return mod;
        return NULL;
 }
+EXPORT_SYMBOL_GPL(__module_address);
 
-struct module *module_text_address(unsigned long addr)
+/*
+ * is_module_text_address - is this address inside module code?
+ * @addr: the address to check.
+ *
+ * See is_module_address() if you simply want to see if the address is
+ * anywhere in a module.  See kernel_text_address() for testing if an
+ * address corresponds to kernel or module code.
+ */
+bool is_module_text_address(unsigned long addr)
 {
-       struct module *mod;
+       bool ret;
 
        preempt_disable();
-       mod = __module_text_address(addr);
+       ret = __module_text_address(addr) != NULL;
        preempt_enable();
 
+       return ret;
+}
+
+/*
+ * __module_text_address - get the module whose code contains an address.
+ * @addr: the address.
+ *
+ * Must be called with preempt disabled or module mutex held so that
+ * module doesn't get freed during this.
+ */
+struct module *__module_text_address(unsigned long addr)
+{
+       struct module *mod = __module_address(addr);
+       if (mod) {
+               /* Make sure it's within the text section. */
+               if (!within(addr, mod->module_init, mod->init_text_size)
+                   && !within(addr, mod->module_core, mod->core_text_size))
+                       mod = NULL;
+       }
        return mod;
 }
+EXPORT_SYMBOL_GPL(__module_text_address);
 
 /* Don't grab lock, we're oopsing. */
 void print_modules(void)
@@ -2809,9 +2849,17 @@ void print_modules(void)
 }
 
 #ifdef CONFIG_MODVERSIONS
-/* Generate the signature for struct module here, too, for modversions. */
-void struct_module(struct module *mod) { return; }
-EXPORT_SYMBOL(struct_module);
+/* Generate the signature for all relevant module structures here.
+ * If these change, we don't want to try to parse the module. */
+void module_layout(struct module *mod,
+                  struct modversion_info *ver,
+                  struct kernel_param *kp,
+                  struct kernel_symbol *ks,
+                  struct marker *marker,
+                  struct tracepoint *tp)
+{
+}
+EXPORT_SYMBOL(module_layout);
 #endif
 
 #ifdef CONFIG_MARKERS
index a1e3025..de273ec 100644 (file)
@@ -24,6 +24,9 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 
+/* We abuse the high bits of "perm" to record whether we kmalloc'ed. */
+#define KPARAM_KMALLOCED       0x80000000
+
 #if 0
 #define DEBUGP printk
 #else
@@ -217,7 +220,19 @@ int param_set_charp(const char *val, struct kernel_param *kp)
                return -ENOSPC;
        }
 
-       *(char **)kp->arg = (char *)val;
+       if (kp->perm & KPARAM_KMALLOCED)
+               kfree(*(char **)kp->arg);
+
+       /* This is a hack.  We can't need to strdup in early boot, and we
+        * don't need to; this mangled commandline is preserved. */
+       if (slab_is_available()) {
+               kp->perm |= KPARAM_KMALLOCED;
+               *(char **)kp->arg = kstrdup(val, GFP_KERNEL);
+               if (!kp->arg)
+                       return -ENOMEM;
+       } else
+               *(const char **)kp->arg = val;
+
        return 0;
 }
 
@@ -571,6 +586,15 @@ void module_param_sysfs_remove(struct module *mod)
 }
 #endif
 
+void destroy_params(const struct kernel_param *params, unsigned num)
+{
+       unsigned int i;
+
+       for (i = 0; i < num; i++)
+               if (params[i].perm & KPARAM_KMALLOCED)
+                       kfree(*(char **)params[i].arg);
+}
+
 static void __init kernel_add_sysfs_param(const char *name,
                                          struct kernel_param *kparam,
                                          unsigned int name_skip)
index 7e62303..8cc7061 100644 (file)
@@ -1607,12 +1607,12 @@ static void read_symbols(char *modname)
 
        parse_elf_finish(&info);
 
-       /* Our trick to get versioning for struct_module - it's
+       /* Our trick to get versioning for module struct etc. - it's
         * never passed as an argument to an exported function, so
         * the automatic versioning doesn't pick it up, but it's really
         * important anyhow */
        if (modversions)
-               mod->unres = alloc_symbol("struct_module", 0, mod->unres);
+               mod->unres = alloc_symbol("module_layout", 0, mod->unres);
 }
 
 #define SZ 500