diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 35 |
1 files changed, 12 insertions, 23 deletions
diff --git a/kernel/module.c b/kernel/module.c index f47cce910f25..c9332c90d5a0 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/device.h> | 43 | #include <linux/device.h> |
44 | #include <linux/string.h> | 44 | #include <linux/string.h> |
45 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
46 | #include <linux/unwind.h> | ||
47 | #include <linux/rculist.h> | 46 | #include <linux/rculist.h> |
48 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
49 | #include <asm/cacheflush.h> | 48 | #include <asm/cacheflush.h> |
@@ -51,6 +50,7 @@ | |||
51 | #include <asm/sections.h> | 50 | #include <asm/sections.h> |
52 | #include <linux/tracepoint.h> | 51 | #include <linux/tracepoint.h> |
53 | #include <linux/ftrace.h> | 52 | #include <linux/ftrace.h> |
53 | #include <linux/async.h> | ||
54 | 54 | ||
55 | #if 0 | 55 | #if 0 |
56 | #define DEBUGP printk | 56 | #define DEBUGP printk |
@@ -817,6 +817,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
817 | mod->exit(); | 817 | mod->exit(); |
818 | blocking_notifier_call_chain(&module_notify_list, | 818 | blocking_notifier_call_chain(&module_notify_list, |
819 | MODULE_STATE_GOING, mod); | 819 | MODULE_STATE_GOING, mod); |
820 | async_synchronize_full(); | ||
820 | mutex_lock(&module_mutex); | 821 | mutex_lock(&module_mutex); |
821 | /* Store the name of the last unloaded module for diagnostic purposes */ | 822 | /* Store the name of the last unloaded module for diagnostic purposes */ |
822 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); | 823 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); |
@@ -1449,8 +1450,6 @@ static void free_module(struct module *mod) | |||
1449 | remove_sect_attrs(mod); | 1450 | remove_sect_attrs(mod); |
1450 | mod_kobject_remove(mod); | 1451 | mod_kobject_remove(mod); |
1451 | 1452 | ||
1452 | unwind_remove_table(mod->unwind_info, 0); | ||
1453 | |||
1454 | /* Arch-specific cleanup. */ | 1453 | /* Arch-specific cleanup. */ |
1455 | module_arch_cleanup(mod); | 1454 | module_arch_cleanup(mod); |
1456 | 1455 | ||
@@ -1867,7 +1866,6 @@ static noinline struct module *load_module(void __user *umod, | |||
1867 | unsigned int symindex = 0; | 1866 | unsigned int symindex = 0; |
1868 | unsigned int strindex = 0; | 1867 | unsigned int strindex = 0; |
1869 | unsigned int modindex, versindex, infoindex, pcpuindex; | 1868 | unsigned int modindex, versindex, infoindex, pcpuindex; |
1870 | unsigned int unwindex = 0; | ||
1871 | unsigned int num_kp, num_mcount; | 1869 | unsigned int num_kp, num_mcount; |
1872 | struct kernel_param *kp; | 1870 | struct kernel_param *kp; |
1873 | struct module *mod; | 1871 | struct module *mod; |
@@ -1957,9 +1955,6 @@ static noinline struct module *load_module(void __user *umod, | |||
1957 | versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); | 1955 | versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); |
1958 | infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); | 1956 | infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); |
1959 | pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); | 1957 | pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); |
1960 | #ifdef ARCH_UNWIND_SECTION_NAME | ||
1961 | unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME); | ||
1962 | #endif | ||
1963 | 1958 | ||
1964 | /* Don't keep modinfo and version sections. */ | 1959 | /* Don't keep modinfo and version sections. */ |
1965 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 1960 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
@@ -1969,8 +1964,6 @@ static noinline struct module *load_module(void __user *umod, | |||
1969 | sechdrs[symindex].sh_flags |= SHF_ALLOC; | 1964 | sechdrs[symindex].sh_flags |= SHF_ALLOC; |
1970 | sechdrs[strindex].sh_flags |= SHF_ALLOC; | 1965 | sechdrs[strindex].sh_flags |= SHF_ALLOC; |
1971 | #endif | 1966 | #endif |
1972 | if (unwindex) | ||
1973 | sechdrs[unwindex].sh_flags |= SHF_ALLOC; | ||
1974 | 1967 | ||
1975 | /* Check module struct version now, before we try to use module. */ | 1968 | /* Check module struct version now, before we try to use module. */ |
1976 | if (!check_modstruct_version(sechdrs, versindex, mod)) { | 1969 | if (!check_modstruct_version(sechdrs, versindex, mod)) { |
@@ -2267,11 +2260,6 @@ static noinline struct module *load_module(void __user *umod, | |||
2267 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | 2260 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); |
2268 | add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | 2261 | add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); |
2269 | 2262 | ||
2270 | /* Size of section 0 is 0, so this works well if no unwind info. */ | ||
2271 | mod->unwind_info = unwind_add_table(mod, | ||
2272 | (void *)sechdrs[unwindex].sh_addr, | ||
2273 | sechdrs[unwindex].sh_size); | ||
2274 | |||
2275 | /* Get rid of temporary copy */ | 2263 | /* Get rid of temporary copy */ |
2276 | vfree(hdr); | 2264 | vfree(hdr); |
2277 | 2265 | ||
@@ -2366,11 +2354,12 @@ sys_init_module(void __user *umod, | |||
2366 | /* Now it's a first class citizen! Wake up anyone waiting for it. */ | 2354 | /* Now it's a first class citizen! Wake up anyone waiting for it. */ |
2367 | mod->state = MODULE_STATE_LIVE; | 2355 | mod->state = MODULE_STATE_LIVE; |
2368 | wake_up(&module_wq); | 2356 | wake_up(&module_wq); |
2357 | blocking_notifier_call_chain(&module_notify_list, | ||
2358 | MODULE_STATE_LIVE, mod); | ||
2369 | 2359 | ||
2370 | mutex_lock(&module_mutex); | 2360 | mutex_lock(&module_mutex); |
2371 | /* Drop initial reference. */ | 2361 | /* Drop initial reference. */ |
2372 | module_put(mod); | 2362 | module_put(mod); |
2373 | unwind_remove_table(mod->unwind_info, 1); | ||
2374 | module_free(mod, mod->module_init); | 2363 | module_free(mod, mod->module_init); |
2375 | mod->module_init = NULL; | 2364 | mod->module_init = NULL; |
2376 | mod->init_size = 0; | 2365 | mod->init_size = 0; |
@@ -2405,7 +2394,7 @@ static const char *get_ksymbol(struct module *mod, | |||
2405 | unsigned long nextval; | 2394 | unsigned long nextval; |
2406 | 2395 | ||
2407 | /* At worse, next value is at end of module */ | 2396 | /* At worse, next value is at end of module */ |
2408 | if (within(addr, mod->module_init, mod->init_size)) | 2397 | if (within_module_init(addr, mod)) |
2409 | nextval = (unsigned long)mod->module_init+mod->init_text_size; | 2398 | nextval = (unsigned long)mod->module_init+mod->init_text_size; |
2410 | else | 2399 | else |
2411 | nextval = (unsigned long)mod->module_core+mod->core_text_size; | 2400 | nextval = (unsigned long)mod->module_core+mod->core_text_size; |
@@ -2453,8 +2442,8 @@ const char *module_address_lookup(unsigned long addr, | |||
2453 | 2442 | ||
2454 | preempt_disable(); | 2443 | preempt_disable(); |
2455 | list_for_each_entry_rcu(mod, &modules, list) { | 2444 | list_for_each_entry_rcu(mod, &modules, list) { |
2456 | if (within(addr, mod->module_init, mod->init_size) | 2445 | if (within_module_init(addr, mod) || |
2457 | || within(addr, mod->module_core, mod->core_size)) { | 2446 | within_module_core(addr, mod)) { |
2458 | if (modname) | 2447 | if (modname) |
2459 | *modname = mod->name; | 2448 | *modname = mod->name; |
2460 | ret = get_ksymbol(mod, addr, size, offset); | 2449 | ret = get_ksymbol(mod, addr, size, offset); |
@@ -2476,8 +2465,8 @@ int lookup_module_symbol_name(unsigned long addr, char *symname) | |||
2476 | 2465 | ||
2477 | preempt_disable(); | 2466 | preempt_disable(); |
2478 | list_for_each_entry_rcu(mod, &modules, list) { | 2467 | list_for_each_entry_rcu(mod, &modules, list) { |
2479 | if (within(addr, mod->module_init, mod->init_size) || | 2468 | if (within_module_init(addr, mod) || |
2480 | within(addr, mod->module_core, mod->core_size)) { | 2469 | within_module_core(addr, mod)) { |
2481 | const char *sym; | 2470 | const char *sym; |
2482 | 2471 | ||
2483 | sym = get_ksymbol(mod, addr, NULL, NULL); | 2472 | sym = get_ksymbol(mod, addr, NULL, NULL); |
@@ -2500,8 +2489,8 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, | |||
2500 | 2489 | ||
2501 | preempt_disable(); | 2490 | preempt_disable(); |
2502 | list_for_each_entry_rcu(mod, &modules, list) { | 2491 | list_for_each_entry_rcu(mod, &modules, list) { |
2503 | if (within(addr, mod->module_init, mod->init_size) || | 2492 | if (within_module_init(addr, mod) || |
2504 | within(addr, mod->module_core, mod->core_size)) { | 2493 | within_module_core(addr, mod)) { |
2505 | const char *sym; | 2494 | const char *sym; |
2506 | 2495 | ||
2507 | sym = get_ksymbol(mod, addr, size, offset); | 2496 | sym = get_ksymbol(mod, addr, size, offset); |
@@ -2720,7 +2709,7 @@ int is_module_address(unsigned long addr) | |||
2720 | preempt_disable(); | 2709 | preempt_disable(); |
2721 | 2710 | ||
2722 | list_for_each_entry_rcu(mod, &modules, list) { | 2711 | list_for_each_entry_rcu(mod, &modules, list) { |
2723 | if (within(addr, mod->module_core, mod->core_size)) { | 2712 | if (within_module_core(addr, mod)) { |
2724 | preempt_enable(); | 2713 | preempt_enable(); |
2725 | return 1; | 2714 | return 1; |
2726 | } | 2715 | } |