diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 62 |
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 |
| 65 | static DEFINE_SPINLOCK(modlist_lock); | 65 | * (add/delete uses stop_machine). */ |
| 66 | |||
| 67 | /* List of modules, protected by module_mutex AND modlist_lock */ | ||
| 68 | static DEFINE_MUTEX(module_mutex); | 66 | static DEFINE_MUTEX(module_mutex); |
| 69 | static LIST_HEAD(modules); | 67 | static 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 | } \ |
| 490 | static struct module_attribute modinfo_##field = { \ | 488 | static 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) | |||
| 761 | void __symbol_put(const char *symbol) | 758 | void __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 | } |
| 773 | EXPORT_SYMBOL(__symbol_put); | 769 | EXPORT_SYMBOL(__symbol_put); |
| 774 | 770 | ||
| @@ -793,7 +789,7 @@ static ssize_t show_refcnt(struct module_attribute *mattr, | |||
| 793 | } | 789 | } |
| 794 | 790 | ||
| 795 | static struct module_attribute refcnt = { | 791 | static 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 | ||
| 853 | static struct module_attribute initstate = { | 849 | static 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) | |||
| 1231 | void *__symbol_get(const char *symbol) | 1225 | void *__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. */ |
| 2236 | static void *m_start(struct seq_file *m, loff_t *pos) | 2230 | static 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 | ||
| 2251 | static void *m_next(struct seq_file *m, void *p, loff_t *pos) | 2236 | static 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 | ||
| 2260 | static void m_stop(struct seq_file *m, void *p) | 2241 | static 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. */ |
| 2325 | const struct exception_table_entry *search_module_extables(unsigned long addr) | 2306 | const 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 | */ |
| 2352 | int is_module_address(unsigned long addr) | 2332 | int 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? */ |
| 2373 | struct module *__module_text_address(unsigned long addr) | 2352 | struct 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) | |||
| 2384 | struct module *module_text_address(unsigned long addr) | 2363 | struct 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 | } |
