aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c35
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 }