diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/kernel/module.c b/kernel/module.c index 77764f22f021..fb404299082e 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/device.h> | 39 | #include <linux/device.h> |
40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
41 | #include <linux/sched.h> | 41 | #include <linux/sched.h> |
42 | #include <linux/mutex.h> | ||
42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
43 | #include <asm/semaphore.h> | 44 | #include <asm/semaphore.h> |
44 | #include <asm/cacheflush.h> | 45 | #include <asm/cacheflush.h> |
@@ -60,18 +61,18 @@ | |||
60 | static DEFINE_SPINLOCK(modlist_lock); | 61 | static DEFINE_SPINLOCK(modlist_lock); |
61 | 62 | ||
62 | /* List of modules, protected by module_mutex AND modlist_lock */ | 63 | /* List of modules, protected by module_mutex AND modlist_lock */ |
63 | static DECLARE_MUTEX(module_mutex); | 64 | static DEFINE_MUTEX(module_mutex); |
64 | static LIST_HEAD(modules); | 65 | static LIST_HEAD(modules); |
65 | 66 | ||
66 | static DECLARE_MUTEX(notify_mutex); | 67 | static DEFINE_MUTEX(notify_mutex); |
67 | static struct notifier_block * module_notify_list; | 68 | static struct notifier_block * module_notify_list; |
68 | 69 | ||
69 | int register_module_notifier(struct notifier_block * nb) | 70 | int register_module_notifier(struct notifier_block * nb) |
70 | { | 71 | { |
71 | int err; | 72 | int err; |
72 | down(¬ify_mutex); | 73 | mutex_lock(¬ify_mutex); |
73 | err = notifier_chain_register(&module_notify_list, nb); | 74 | err = notifier_chain_register(&module_notify_list, nb); |
74 | up(¬ify_mutex); | 75 | mutex_unlock(¬ify_mutex); |
75 | return err; | 76 | return err; |
76 | } | 77 | } |
77 | EXPORT_SYMBOL(register_module_notifier); | 78 | EXPORT_SYMBOL(register_module_notifier); |
@@ -79,9 +80,9 @@ EXPORT_SYMBOL(register_module_notifier); | |||
79 | int unregister_module_notifier(struct notifier_block * nb) | 80 | int unregister_module_notifier(struct notifier_block * nb) |
80 | { | 81 | { |
81 | int err; | 82 | int err; |
82 | down(¬ify_mutex); | 83 | mutex_lock(¬ify_mutex); |
83 | err = notifier_chain_unregister(&module_notify_list, nb); | 84 | err = notifier_chain_unregister(&module_notify_list, nb); |
84 | up(¬ify_mutex); | 85 | mutex_unlock(¬ify_mutex); |
85 | return err; | 86 | return err; |
86 | } | 87 | } |
87 | EXPORT_SYMBOL(unregister_module_notifier); | 88 | EXPORT_SYMBOL(unregister_module_notifier); |
@@ -601,7 +602,7 @@ static void free_module(struct module *mod); | |||
601 | static void wait_for_zero_refcount(struct module *mod) | 602 | static void wait_for_zero_refcount(struct module *mod) |
602 | { | 603 | { |
603 | /* Since we might sleep for some time, drop the semaphore first */ | 604 | /* Since we might sleep for some time, drop the semaphore first */ |
604 | up(&module_mutex); | 605 | mutex_unlock(&module_mutex); |
605 | for (;;) { | 606 | for (;;) { |
606 | DEBUGP("Looking at refcount...\n"); | 607 | DEBUGP("Looking at refcount...\n"); |
607 | set_current_state(TASK_UNINTERRUPTIBLE); | 608 | set_current_state(TASK_UNINTERRUPTIBLE); |
@@ -610,7 +611,7 @@ static void wait_for_zero_refcount(struct module *mod) | |||
610 | schedule(); | 611 | schedule(); |
611 | } | 612 | } |
612 | current->state = TASK_RUNNING; | 613 | current->state = TASK_RUNNING; |
613 | down(&module_mutex); | 614 | mutex_lock(&module_mutex); |
614 | } | 615 | } |
615 | 616 | ||
616 | asmlinkage long | 617 | asmlinkage long |
@@ -627,7 +628,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
627 | return -EFAULT; | 628 | return -EFAULT; |
628 | name[MODULE_NAME_LEN-1] = '\0'; | 629 | name[MODULE_NAME_LEN-1] = '\0'; |
629 | 630 | ||
630 | if (down_interruptible(&module_mutex) != 0) | 631 | if (mutex_lock_interruptible(&module_mutex) != 0) |
631 | return -EINTR; | 632 | return -EINTR; |
632 | 633 | ||
633 | mod = find_module(name); | 634 | mod = find_module(name); |
@@ -676,14 +677,14 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
676 | 677 | ||
677 | /* Final destruction now noone is using it. */ | 678 | /* Final destruction now noone is using it. */ |
678 | if (mod->exit != NULL) { | 679 | if (mod->exit != NULL) { |
679 | up(&module_mutex); | 680 | mutex_unlock(&module_mutex); |
680 | mod->exit(); | 681 | mod->exit(); |
681 | down(&module_mutex); | 682 | mutex_lock(&module_mutex); |
682 | } | 683 | } |
683 | free_module(mod); | 684 | free_module(mod); |
684 | 685 | ||
685 | out: | 686 | out: |
686 | up(&module_mutex); | 687 | mutex_unlock(&module_mutex); |
687 | return ret; | 688 | return ret; |
688 | } | 689 | } |
689 | 690 | ||
@@ -1972,13 +1973,13 @@ sys_init_module(void __user *umod, | |||
1972 | return -EPERM; | 1973 | return -EPERM; |
1973 | 1974 | ||
1974 | /* Only one module load at a time, please */ | 1975 | /* Only one module load at a time, please */ |
1975 | if (down_interruptible(&module_mutex) != 0) | 1976 | if (mutex_lock_interruptible(&module_mutex) != 0) |
1976 | return -EINTR; | 1977 | return -EINTR; |
1977 | 1978 | ||
1978 | /* Do all the hard work */ | 1979 | /* Do all the hard work */ |
1979 | mod = load_module(umod, len, uargs); | 1980 | mod = load_module(umod, len, uargs); |
1980 | if (IS_ERR(mod)) { | 1981 | if (IS_ERR(mod)) { |
1981 | up(&module_mutex); | 1982 | mutex_unlock(&module_mutex); |
1982 | return PTR_ERR(mod); | 1983 | return PTR_ERR(mod); |
1983 | } | 1984 | } |
1984 | 1985 | ||
@@ -1987,11 +1988,11 @@ sys_init_module(void __user *umod, | |||
1987 | stop_machine_run(__link_module, mod, NR_CPUS); | 1988 | stop_machine_run(__link_module, mod, NR_CPUS); |
1988 | 1989 | ||
1989 | /* Drop lock so they can recurse */ | 1990 | /* Drop lock so they can recurse */ |
1990 | up(&module_mutex); | 1991 | mutex_unlock(&module_mutex); |
1991 | 1992 | ||
1992 | down(¬ify_mutex); | 1993 | mutex_lock(¬ify_mutex); |
1993 | notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); | 1994 | notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); |
1994 | up(¬ify_mutex); | 1995 | mutex_unlock(¬ify_mutex); |
1995 | 1996 | ||
1996 | /* Start the module */ | 1997 | /* Start the module */ |
1997 | if (mod->init != NULL) | 1998 | if (mod->init != NULL) |
@@ -2006,15 +2007,15 @@ sys_init_module(void __user *umod, | |||
2006 | mod->name); | 2007 | mod->name); |
2007 | else { | 2008 | else { |
2008 | module_put(mod); | 2009 | module_put(mod); |
2009 | down(&module_mutex); | 2010 | mutex_lock(&module_mutex); |
2010 | free_module(mod); | 2011 | free_module(mod); |
2011 | up(&module_mutex); | 2012 | mutex_unlock(&module_mutex); |
2012 | } | 2013 | } |
2013 | return ret; | 2014 | return ret; |
2014 | } | 2015 | } |
2015 | 2016 | ||
2016 | /* Now it's a first class citizen! */ | 2017 | /* Now it's a first class citizen! */ |
2017 | down(&module_mutex); | 2018 | mutex_lock(&module_mutex); |
2018 | mod->state = MODULE_STATE_LIVE; | 2019 | mod->state = MODULE_STATE_LIVE; |
2019 | /* Drop initial reference. */ | 2020 | /* Drop initial reference. */ |
2020 | module_put(mod); | 2021 | module_put(mod); |
@@ -2022,7 +2023,7 @@ sys_init_module(void __user *umod, | |||
2022 | mod->module_init = NULL; | 2023 | mod->module_init = NULL; |
2023 | mod->init_size = 0; | 2024 | mod->init_size = 0; |
2024 | mod->init_text_size = 0; | 2025 | mod->init_text_size = 0; |
2025 | up(&module_mutex); | 2026 | mutex_unlock(&module_mutex); |
2026 | 2027 | ||
2027 | return 0; | 2028 | return 0; |
2028 | } | 2029 | } |
@@ -2112,7 +2113,7 @@ struct module *module_get_kallsym(unsigned int symnum, | |||
2112 | { | 2113 | { |
2113 | struct module *mod; | 2114 | struct module *mod; |
2114 | 2115 | ||
2115 | down(&module_mutex); | 2116 | mutex_lock(&module_mutex); |
2116 | list_for_each_entry(mod, &modules, list) { | 2117 | list_for_each_entry(mod, &modules, list) { |
2117 | if (symnum < mod->num_symtab) { | 2118 | if (symnum < mod->num_symtab) { |
2118 | *value = mod->symtab[symnum].st_value; | 2119 | *value = mod->symtab[symnum].st_value; |
@@ -2120,12 +2121,12 @@ struct module *module_get_kallsym(unsigned int symnum, | |||
2120 | strncpy(namebuf, | 2121 | strncpy(namebuf, |
2121 | mod->strtab + mod->symtab[symnum].st_name, | 2122 | mod->strtab + mod->symtab[symnum].st_name, |
2122 | 127); | 2123 | 127); |
2123 | up(&module_mutex); | 2124 | mutex_unlock(&module_mutex); |
2124 | return mod; | 2125 | return mod; |
2125 | } | 2126 | } |
2126 | symnum -= mod->num_symtab; | 2127 | symnum -= mod->num_symtab; |
2127 | } | 2128 | } |
2128 | up(&module_mutex); | 2129 | mutex_unlock(&module_mutex); |
2129 | return NULL; | 2130 | return NULL; |
2130 | } | 2131 | } |
2131 | 2132 | ||
@@ -2168,7 +2169,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) | |||
2168 | struct list_head *i; | 2169 | struct list_head *i; |
2169 | loff_t n = 0; | 2170 | loff_t n = 0; |
2170 | 2171 | ||
2171 | down(&module_mutex); | 2172 | mutex_lock(&module_mutex); |
2172 | list_for_each(i, &modules) { | 2173 | list_for_each(i, &modules) { |
2173 | if (n++ == *pos) | 2174 | if (n++ == *pos) |
2174 | break; | 2175 | break; |
@@ -2189,7 +2190,7 @@ static void *m_next(struct seq_file *m, void *p, loff_t *pos) | |||
2189 | 2190 | ||
2190 | static void m_stop(struct seq_file *m, void *p) | 2191 | static void m_stop(struct seq_file *m, void *p) |
2191 | { | 2192 | { |
2192 | up(&module_mutex); | 2193 | mutex_unlock(&module_mutex); |
2193 | } | 2194 | } |
2194 | 2195 | ||
2195 | static int m_show(struct seq_file *m, void *p) | 2196 | static int m_show(struct seq_file *m, void *p) |