Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm
[pandora-kernel.git] / kernel / module.c
index 8c25b1a..1eb8ca5 100644 (file)
@@ -45,6 +45,8 @@
 #include <asm/cacheflush.h>
 #include <linux/license.h>
 
+extern int module_sysfs_initialized;
+
 #if 0
 #define DEBUGP printk
 #else
@@ -346,10 +348,10 @@ static void *percpu_modalloc(unsigned long size, unsigned long align,
        unsigned int i;
        void *ptr;
 
-       if (align > SMP_CACHE_BYTES) {
-               printk(KERN_WARNING "%s: per-cpu alignment %li > %i\n",
-                      name, align, SMP_CACHE_BYTES);
-               align = SMP_CACHE_BYTES;
+       if (align > PAGE_SIZE) {
+               printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
+                      name, align, PAGE_SIZE);
+               align = PAGE_SIZE;
        }
 
        ptr = __per_cpu_start;
@@ -430,7 +432,7 @@ static int percpu_modinit(void)
        pcpu_size = kmalloc(sizeof(pcpu_size[0]) * pcpu_num_allocated,
                            GFP_KERNEL);
        /* Static in-kernel percpu data (used). */
-       pcpu_size[0] = -ALIGN(__per_cpu_end-__per_cpu_start, SMP_CACHE_BYTES);
+       pcpu_size[0] = -(__per_cpu_end-__per_cpu_start);
        /* Free room. */
        pcpu_size[1] = PERCPU_ENOUGH_ROOM + pcpu_size[0];
        if (pcpu_size[1] < 0) {
@@ -653,11 +655,20 @@ static void wait_for_zero_refcount(struct module *mod)
        mutex_lock(&module_mutex);
 }
 
-int delete_module(const char *name, unsigned int flags)
+asmlinkage long
+sys_delete_module(const char __user *name_user, unsigned int flags)
 {
        struct module *mod;
+       char name[MODULE_NAME_LEN];
        int ret, forced = 0;
 
+       if (!capable(CAP_SYS_MODULE))
+               return -EPERM;
+
+       if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
+               return -EFAULT;
+       name[MODULE_NAME_LEN-1] = '\0';
+
        if (mutex_lock_interruptible(&module_mutex) != 0)
                return -EINTR;
 
@@ -718,21 +729,6 @@ int delete_module(const char *name, unsigned int flags)
        return ret;
 }
 
-asmlinkage long
-sys_delete_module(const char __user *name_user, unsigned int flags)
-{
-       char name[MODULE_NAME_LEN];
-
-       if (!capable(CAP_SYS_MODULE))
-               return -EPERM;
-
-       if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
-               return -EFAULT;
-       name[MODULE_NAME_LEN-1] = '\0';
-
-       return delete_module(name, flags);
-}
-
 static void print_unload_info(struct seq_file *m, struct module *mod)
 {
        struct module_use *use;
@@ -1123,8 +1119,8 @@ int mod_sysfs_init(struct module *mod)
 {
        int err;
 
-       if (!module_subsys.kset.subsys) {
-               printk(KERN_ERR "%s: module_subsys not initialized\n",
+       if (!module_sysfs_initialized) {
+               printk(KERN_ERR "%s: module sysfs not initialized\n",
                       mod->name);
                err = -EINVAL;
                goto out;
@@ -1154,8 +1150,10 @@ int mod_sysfs_setup(struct module *mod,
                goto out;
 
        mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders");
-       if (!mod->holders_dir)
+       if (!mod->holders_dir) {
+               err = -ENOMEM;
                goto out_unreg;
+       }
 
        err = module_param_sysfs_setup(mod, kparam, num_params);
        if (err)
@@ -2389,9 +2387,14 @@ void module_add_driver(struct module *mod, struct device_driver *drv)
                struct kobject *mkobj;
 
                /* Lookup built-in module entry in /sys/modules */
-               mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name);
-               if (mkobj)
+               mkobj = kset_find_obj(&module_subsys, drv->mod_name);
+               if (mkobj) {
                        mk = container_of(mkobj, struct module_kobject, kobj);
+                       /* remember our module structure */
+                       drv->mkobj = mk;
+                       /* kset_find_obj took a reference */
+                       kobject_put(mkobj);
+               }
        }
 
        if (!mk)
@@ -2411,17 +2414,22 @@ EXPORT_SYMBOL(module_add_driver);
 
 void module_remove_driver(struct device_driver *drv)
 {
+       struct module_kobject *mk = NULL;
        char *driver_name;
 
        if (!drv)
                return;
 
        sysfs_remove_link(&drv->kobj, "module");
-       if (drv->owner && drv->owner->mkobj.drivers_dir) {
+
+       if (drv->owner)
+               mk = &drv->owner->mkobj;
+       else if (drv->mkobj)
+               mk = drv->mkobj;
+       if (mk && mk->drivers_dir) {
                driver_name = make_driver_name(drv);
                if (driver_name) {
-                       sysfs_remove_link(drv->owner->mkobj.drivers_dir,
-                                         driver_name);
+                       sysfs_remove_link(mk->drivers_dir, driver_name);
                        kfree(driver_name);
                }
        }