]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/module.c
module: reduce module image and resident size
[linux-2.6-omap-h63xx.git] / kernel / module.c
index 901cd6ac2f11d9d4b54d3bff34e10495e86f01a2..031bf26af8ea43a80c38c7de7051841e457e3164 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/mutex.h>
 #include <linux/unwind.h>
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
 #include <asm/cacheflush.h>
 #include <linux/license.h>
 #include <asm/sections.h>
@@ -664,7 +663,7 @@ static void free_module(struct module *mod);
 
 static void wait_for_zero_refcount(struct module *mod)
 {
-       /* Since we might sleep for some time, drop the semaphore first */
+       /* Since we might sleep for some time, release the mutex first */
        mutex_unlock(&module_mutex);
        for (;;) {
                DEBUGP("Looking at refcount...\n");
@@ -992,6 +991,20 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
  * J. Corbet <corbet@lwn.net>
  */
 #if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS)
+struct module_sect_attr
+{
+       struct module_attribute mattr;
+       char *name;
+       unsigned long address;
+};
+
+struct module_sect_attrs
+{
+       struct attribute_group grp;
+       unsigned int nsections;
+       struct module_sect_attr attrs[0];
+};
+
 static ssize_t module_sect_show(struct module_attribute *mattr,
                                struct module *mod, char *buf)
 {
@@ -1002,7 +1015,7 @@ static ssize_t module_sect_show(struct module_attribute *mattr,
 
 static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
 {
-       int section;
+       unsigned int section;
 
        for (section = 0; section < sect_attrs->nsections; section++)
                kfree(sect_attrs->attrs[section].name);
@@ -1815,8 +1828,9 @@ static struct module *load_module(void __user *umod,
        unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME);
 #endif
 
-       /* Don't keep modinfo section */
+       /* Don't keep modinfo and version sections. */
        sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
+       sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
 #ifdef CONFIG_KALLSYMS
        /* Keep symbol and string tables for decoding later. */
        sechdrs[symindex].sh_flags |= SHF_ALLOC;
@@ -1933,8 +1947,15 @@ static struct module *load_module(void __user *umod,
        /* Set up license info based on the info section */
        set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
+       /*
+        * ndiswrapper is under GPL by itself, but loads proprietary modules.
+        * Don't use add_taint_module(), as it would prevent ndiswrapper from
+        * using GPL-only symbols it needs.
+        */
        if (strcmp(mod->name, "ndiswrapper") == 0)
-               add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+               add_taint(TAINT_PROPRIETARY_MODULE);
+
+       /* driverloader was caught wrongly pretending to be under GPL */
        if (strcmp(mod->name, "driverloader") == 0)
                add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
 
@@ -2171,10 +2192,20 @@ sys_init_module(void __user *umod,
                wake_up(&module_wq);
                return ret;
        }
+       if (ret > 0) {
+               printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, "
+                                   "it should follow 0/-E convention\n"
+                      KERN_WARNING "%s: loading module anyway...\n",
+                      __func__, mod->name, ret,
+                      __func__);
+               dump_stack();
+       }
 
-       /* Now it's a first class citizen! */
-       mutex_lock(&module_mutex);
+       /* Now it's a first class citizen!  Wake up anyone waiting for it. */
        mod->state = MODULE_STATE_LIVE;
+       wake_up(&module_wq);
+
+       mutex_lock(&module_mutex);
        /* Drop initial reference. */
        module_put(mod);
        unwind_remove_table(mod->unwind_info, 1);
@@ -2183,7 +2214,6 @@ sys_init_module(void __user *umod,
        mod->init_size = 0;
        mod->init_text_size = 0;
        mutex_unlock(&module_mutex);
-       wake_up(&module_wq);
 
        return 0;
 }