aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c62
1 files changed, 20 insertions, 42 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 9bd93de01f4a..539fed9ac83c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -61,10 +61,8 @@ extern int module_sysfs_initialized;
61/* If this is set, the section belongs in the init part of the module */ 61/* If this is set, the section belongs in the init part of the module */
62#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) 62#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
63 63
64/* Protects module list */ 64/* List of modules, protected by module_mutex or preempt_disable
65static DEFINE_SPINLOCK(modlist_lock); 65 * (add/delete uses stop_machine). */
66
67/* List of modules, protected by module_mutex AND modlist_lock */
68static DEFINE_MUTEX(module_mutex); 66static DEFINE_MUTEX(module_mutex);
69static LIST_HEAD(modules); 67static LIST_HEAD(modules);
70 68
@@ -488,8 +486,7 @@ static void free_modinfo_##field(struct module *mod) \
488 mod->field = NULL; \ 486 mod->field = NULL; \
489} \ 487} \
490static struct module_attribute modinfo_##field = { \ 488static struct module_attribute modinfo_##field = { \
491 .attr = { .name = __stringify(field), .mode = 0444, \ 489 .attr = { .name = __stringify(field), .mode = 0444 }, \
492 .owner = THIS_MODULE }, \
493 .show = show_modinfo_##field, \ 490 .show = show_modinfo_##field, \
494 .setup = setup_modinfo_##field, \ 491 .setup = setup_modinfo_##field, \
495 .test = modinfo_##field##_exists, \ 492 .test = modinfo_##field##_exists, \
@@ -761,14 +758,13 @@ static void print_unload_info(struct seq_file *m, struct module *mod)
761void __symbol_put(const char *symbol) 758void __symbol_put(const char *symbol)
762{ 759{
763 struct module *owner; 760 struct module *owner;
764 unsigned long flags;
765 const unsigned long *crc; 761 const unsigned long *crc;
766 762
767 spin_lock_irqsave(&modlist_lock, flags); 763 preempt_disable();
768 if (!__find_symbol(symbol, &owner, &crc, 1)) 764 if (!__find_symbol(symbol, &owner, &crc, 1))
769 BUG(); 765 BUG();
770 module_put(owner); 766 module_put(owner);
771 spin_unlock_irqrestore(&modlist_lock, flags); 767 preempt_enable();
772} 768}
773EXPORT_SYMBOL(__symbol_put); 769EXPORT_SYMBOL(__symbol_put);
774 770
@@ -793,7 +789,7 @@ static ssize_t show_refcnt(struct module_attribute *mattr,
793} 789}
794 790
795static struct module_attribute refcnt = { 791static struct module_attribute refcnt = {
796 .attr = { .name = "refcnt", .mode = 0444, .owner = THIS_MODULE }, 792 .attr = { .name = "refcnt", .mode = 0444 },
797 .show = show_refcnt, 793 .show = show_refcnt,
798}; 794};
799 795
@@ -851,7 +847,7 @@ static ssize_t show_initstate(struct module_attribute *mattr,
851} 847}
852 848
853static struct module_attribute initstate = { 849static struct module_attribute initstate = {
854 .attr = { .name = "initstate", .mode = 0444, .owner = THIS_MODULE }, 850 .attr = { .name = "initstate", .mode = 0444 },
855 .show = show_initstate, 851 .show = show_initstate,
856}; 852};
857 853
@@ -1032,7 +1028,6 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
1032 sattr->mattr.show = module_sect_show; 1028 sattr->mattr.show = module_sect_show;
1033 sattr->mattr.store = NULL; 1029 sattr->mattr.store = NULL;
1034 sattr->mattr.attr.name = sattr->name; 1030 sattr->mattr.attr.name = sattr->name;
1035 sattr->mattr.attr.owner = mod;
1036 sattr->mattr.attr.mode = S_IRUGO; 1031 sattr->mattr.attr.mode = S_IRUGO;
1037 *(gattr++) = &(sattr++)->mattr.attr; 1032 *(gattr++) = &(sattr++)->mattr.attr;
1038 } 1033 }
@@ -1090,7 +1085,6 @@ int module_add_modinfo_attrs(struct module *mod)
1090 if (!attr->test || 1085 if (!attr->test ||
1091 (attr->test && attr->test(mod))) { 1086 (attr->test && attr->test(mod))) {
1092 memcpy(temp_attr, attr, sizeof(*temp_attr)); 1087 memcpy(temp_attr, attr, sizeof(*temp_attr));
1093 temp_attr->attr.owner = mod;
1094 error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr); 1088 error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr);
1095 ++temp_attr; 1089 ++temp_attr;
1096 } 1090 }
@@ -1231,14 +1225,14 @@ static void free_module(struct module *mod)
1231void *__symbol_get(const char *symbol) 1225void *__symbol_get(const char *symbol)
1232{ 1226{
1233 struct module *owner; 1227 struct module *owner;
1234 unsigned long value, flags; 1228 unsigned long value;
1235 const unsigned long *crc; 1229 const unsigned long *crc;
1236 1230
1237 spin_lock_irqsave(&modlist_lock, flags); 1231 preempt_disable();
1238 value = __find_symbol(symbol, &owner, &crc, 1); 1232 value = __find_symbol(symbol, &owner, &crc, 1);
1239 if (value && !strong_try_module_get(owner)) 1233 if (value && !strong_try_module_get(owner))
1240 value = 0; 1234 value = 0;
1241 spin_unlock_irqrestore(&modlist_lock, flags); 1235 preempt_enable();
1242 1236
1243 return (void *)value; 1237 return (void *)value;
1244} 1238}
@@ -2235,26 +2229,13 @@ unsigned long module_kallsyms_lookup_name(const char *name)
2235/* Called by the /proc file system to return a list of modules. */ 2229/* Called by the /proc file system to return a list of modules. */
2236static void *m_start(struct seq_file *m, loff_t *pos) 2230static void *m_start(struct seq_file *m, loff_t *pos)
2237{ 2231{
2238 struct list_head *i;
2239 loff_t n = 0;
2240
2241 mutex_lock(&module_mutex); 2232 mutex_lock(&module_mutex);
2242 list_for_each(i, &modules) { 2233 return seq_list_start(&modules, *pos);
2243 if (n++ == *pos)
2244 break;
2245 }
2246 if (i == &modules)
2247 return NULL;
2248 return i;
2249} 2234}
2250 2235
2251static void *m_next(struct seq_file *m, void *p, loff_t *pos) 2236static void *m_next(struct seq_file *m, void *p, loff_t *pos)
2252{ 2237{
2253 struct list_head *i = p; 2238 return seq_list_next(p, &modules, pos);
2254 (*pos)++;
2255 if (i->next == &modules)
2256 return NULL;
2257 return i->next;
2258} 2239}
2259 2240
2260static void m_stop(struct seq_file *m, void *p) 2241static void m_stop(struct seq_file *m, void *p)
@@ -2324,11 +2305,10 @@ const struct seq_operations modules_op = {
2324/* Given an address, look for it in the module exception tables. */ 2305/* Given an address, look for it in the module exception tables. */
2325const struct exception_table_entry *search_module_extables(unsigned long addr) 2306const struct exception_table_entry *search_module_extables(unsigned long addr)
2326{ 2307{
2327 unsigned long flags;
2328 const struct exception_table_entry *e = NULL; 2308 const struct exception_table_entry *e = NULL;
2329 struct module *mod; 2309 struct module *mod;
2330 2310
2331 spin_lock_irqsave(&modlist_lock, flags); 2311 preempt_disable();
2332 list_for_each_entry(mod, &modules, list) { 2312 list_for_each_entry(mod, &modules, list) {
2333 if (mod->num_exentries == 0) 2313 if (mod->num_exentries == 0)
2334 continue; 2314 continue;
@@ -2339,7 +2319,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
2339 if (e) 2319 if (e)
2340 break; 2320 break;
2341 } 2321 }
2342 spin_unlock_irqrestore(&modlist_lock, flags); 2322 preempt_enable();
2343 2323
2344 /* Now, if we found one, we are running inside it now, hence 2324 /* Now, if we found one, we are running inside it now, hence
2345 we cannot unload the module, hence no refcnt needed. */ 2325 we cannot unload the module, hence no refcnt needed. */
@@ -2351,25 +2331,24 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
2351 */ 2331 */
2352int is_module_address(unsigned long addr) 2332int is_module_address(unsigned long addr)
2353{ 2333{
2354 unsigned long flags;
2355 struct module *mod; 2334 struct module *mod;
2356 2335
2357 spin_lock_irqsave(&modlist_lock, flags); 2336 preempt_disable();
2358 2337
2359 list_for_each_entry(mod, &modules, list) { 2338 list_for_each_entry(mod, &modules, list) {
2360 if (within(addr, mod->module_core, mod->core_size)) { 2339 if (within(addr, mod->module_core, mod->core_size)) {
2361 spin_unlock_irqrestore(&modlist_lock, flags); 2340 preempt_enable();
2362 return 1; 2341 return 1;
2363 } 2342 }
2364 } 2343 }
2365 2344
2366 spin_unlock_irqrestore(&modlist_lock, flags); 2345 preempt_enable();
2367 2346
2368 return 0; 2347 return 0;
2369} 2348}
2370 2349
2371 2350
2372/* Is this a valid kernel address? We don't grab the lock: we are oopsing. */ 2351/* Is this a valid kernel address? */
2373struct module *__module_text_address(unsigned long addr) 2352struct module *__module_text_address(unsigned long addr)
2374{ 2353{
2375 struct module *mod; 2354 struct module *mod;
@@ -2384,11 +2363,10 @@ struct module *__module_text_address(unsigned long addr)
2384struct module *module_text_address(unsigned long addr) 2363struct module *module_text_address(unsigned long addr)
2385{ 2364{
2386 struct module *mod; 2365 struct module *mod;
2387 unsigned long flags;
2388 2366
2389 spin_lock_irqsave(&modlist_lock, flags); 2367 preempt_disable();
2390 mod = __module_text_address(addr); 2368 mod = __module_text_address(addr);
2391 spin_unlock_irqrestore(&modlist_lock, flags); 2369 preempt_enable();
2392 2370
2393 return mod; 2371 return mod;
2394} 2372}