diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 152 |
1 files changed, 87 insertions, 65 deletions
diff --git a/kernel/module.c b/kernel/module.c index 1f4cc00e0c20..ba22484a987e 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 |
@@ -573,13 +573,13 @@ static char last_unloaded_module[MODULE_NAME_LEN+1]; | |||
573 | /* Init the unload section of the module. */ | 573 | /* Init the unload section of the module. */ |
574 | static void module_unload_init(struct module *mod) | 574 | static void module_unload_init(struct module *mod) |
575 | { | 575 | { |
576 | unsigned int i; | 576 | int cpu; |
577 | 577 | ||
578 | INIT_LIST_HEAD(&mod->modules_which_use_me); | 578 | INIT_LIST_HEAD(&mod->modules_which_use_me); |
579 | for (i = 0; i < NR_CPUS; i++) | 579 | for_each_possible_cpu(cpu) |
580 | local_set(&mod->ref[i].count, 0); | 580 | local_set(__module_ref_addr(mod, cpu), 0); |
581 | /* Hold reference count during initialization. */ | 581 | /* Hold reference count during initialization. */ |
582 | local_set(&mod->ref[raw_smp_processor_id()].count, 1); | 582 | local_set(__module_ref_addr(mod, raw_smp_processor_id()), 1); |
583 | /* Backwards compatibility macros put refcount during init. */ | 583 | /* Backwards compatibility macros put refcount during init. */ |
584 | mod->waiter = current; | 584 | mod->waiter = current; |
585 | } | 585 | } |
@@ -717,10 +717,11 @@ static int try_stop_module(struct module *mod, int flags, int *forced) | |||
717 | 717 | ||
718 | unsigned int module_refcount(struct module *mod) | 718 | unsigned int module_refcount(struct module *mod) |
719 | { | 719 | { |
720 | unsigned int i, total = 0; | 720 | unsigned int total = 0; |
721 | int cpu; | ||
721 | 722 | ||
722 | for (i = 0; i < NR_CPUS; i++) | 723 | for_each_possible_cpu(cpu) |
723 | total += local_read(&mod->ref[i].count); | 724 | total += local_read(__module_ref_addr(mod, cpu)); |
724 | return total; | 725 | return total; |
725 | } | 726 | } |
726 | EXPORT_SYMBOL(module_refcount); | 727 | EXPORT_SYMBOL(module_refcount); |
@@ -743,8 +744,8 @@ static void wait_for_zero_refcount(struct module *mod) | |||
743 | mutex_lock(&module_mutex); | 744 | mutex_lock(&module_mutex); |
744 | } | 745 | } |
745 | 746 | ||
746 | asmlinkage long | 747 | SYSCALL_DEFINE2(delete_module, const char __user *, name_user, |
747 | sys_delete_module(const char __user *name_user, unsigned int flags) | 748 | unsigned int, flags) |
748 | { | 749 | { |
749 | struct module *mod; | 750 | struct module *mod; |
750 | char name[MODULE_NAME_LEN]; | 751 | char name[MODULE_NAME_LEN]; |
@@ -757,8 +758,16 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
757 | return -EFAULT; | 758 | return -EFAULT; |
758 | name[MODULE_NAME_LEN-1] = '\0'; | 759 | name[MODULE_NAME_LEN-1] = '\0'; |
759 | 760 | ||
760 | if (mutex_lock_interruptible(&module_mutex) != 0) | 761 | /* Create stop_machine threads since free_module relies on |
761 | return -EINTR; | 762 | * a non-failing stop_machine call. */ |
763 | ret = stop_machine_create(); | ||
764 | if (ret) | ||
765 | return ret; | ||
766 | |||
767 | if (mutex_lock_interruptible(&module_mutex) != 0) { | ||
768 | ret = -EINTR; | ||
769 | goto out_stop; | ||
770 | } | ||
762 | 771 | ||
763 | mod = find_module(name); | 772 | mod = find_module(name); |
764 | if (!mod) { | 773 | if (!mod) { |
@@ -809,6 +818,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
809 | mod->exit(); | 818 | mod->exit(); |
810 | blocking_notifier_call_chain(&module_notify_list, | 819 | blocking_notifier_call_chain(&module_notify_list, |
811 | MODULE_STATE_GOING, mod); | 820 | MODULE_STATE_GOING, mod); |
821 | async_synchronize_full(); | ||
812 | mutex_lock(&module_mutex); | 822 | mutex_lock(&module_mutex); |
813 | /* Store the name of the last unloaded module for diagnostic purposes */ | 823 | /* Store the name of the last unloaded module for diagnostic purposes */ |
814 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); | 824 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); |
@@ -817,10 +827,12 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
817 | 827 | ||
818 | out: | 828 | out: |
819 | mutex_unlock(&module_mutex); | 829 | mutex_unlock(&module_mutex); |
830 | out_stop: | ||
831 | stop_machine_destroy(); | ||
820 | return ret; | 832 | return ret; |
821 | } | 833 | } |
822 | 834 | ||
823 | static void print_unload_info(struct seq_file *m, struct module *mod) | 835 | static inline void print_unload_info(struct seq_file *m, struct module *mod) |
824 | { | 836 | { |
825 | struct module_use *use; | 837 | struct module_use *use; |
826 | int printed_something = 0; | 838 | int printed_something = 0; |
@@ -883,7 +895,7 @@ void module_put(struct module *module) | |||
883 | { | 895 | { |
884 | if (module) { | 896 | if (module) { |
885 | unsigned int cpu = get_cpu(); | 897 | unsigned int cpu = get_cpu(); |
886 | local_dec(&module->ref[cpu].count); | 898 | local_dec(__module_ref_addr(module, cpu)); |
887 | /* Maybe they're waiting for us to drop reference? */ | 899 | /* Maybe they're waiting for us to drop reference? */ |
888 | if (unlikely(!module_is_live(module))) | 900 | if (unlikely(!module_is_live(module))) |
889 | wake_up_process(module->waiter); | 901 | wake_up_process(module->waiter); |
@@ -893,7 +905,7 @@ void module_put(struct module *module) | |||
893 | EXPORT_SYMBOL(module_put); | 905 | EXPORT_SYMBOL(module_put); |
894 | 906 | ||
895 | #else /* !CONFIG_MODULE_UNLOAD */ | 907 | #else /* !CONFIG_MODULE_UNLOAD */ |
896 | static void print_unload_info(struct seq_file *m, struct module *mod) | 908 | static inline void print_unload_info(struct seq_file *m, struct module *mod) |
897 | { | 909 | { |
898 | /* We don't know the usage count, or what modules are using. */ | 910 | /* We don't know the usage count, or what modules are using. */ |
899 | seq_printf(m, " - -"); | 911 | seq_printf(m, " - -"); |
@@ -1439,8 +1451,6 @@ static void free_module(struct module *mod) | |||
1439 | remove_sect_attrs(mod); | 1451 | remove_sect_attrs(mod); |
1440 | mod_kobject_remove(mod); | 1452 | mod_kobject_remove(mod); |
1441 | 1453 | ||
1442 | unwind_remove_table(mod->unwind_info, 0); | ||
1443 | |||
1444 | /* Arch-specific cleanup. */ | 1454 | /* Arch-specific cleanup. */ |
1445 | module_arch_cleanup(mod); | 1455 | module_arch_cleanup(mod); |
1446 | 1456 | ||
@@ -1455,7 +1465,10 @@ static void free_module(struct module *mod) | |||
1455 | kfree(mod->args); | 1465 | kfree(mod->args); |
1456 | if (mod->percpu) | 1466 | if (mod->percpu) |
1457 | percpu_modfree(mod->percpu); | 1467 | percpu_modfree(mod->percpu); |
1458 | 1468 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | |
1469 | if (mod->refptr) | ||
1470 | percpu_modfree(mod->refptr); | ||
1471 | #endif | ||
1459 | /* Free lock-classes: */ | 1472 | /* Free lock-classes: */ |
1460 | lockdep_free_key_range(mod->module_core, mod->core_size); | 1473 | lockdep_free_key_range(mod->module_core, mod->core_size); |
1461 | 1474 | ||
@@ -1578,11 +1591,21 @@ static int simplify_symbols(Elf_Shdr *sechdrs, | |||
1578 | return ret; | 1591 | return ret; |
1579 | } | 1592 | } |
1580 | 1593 | ||
1594 | /* Additional bytes needed by arch in front of individual sections */ | ||
1595 | unsigned int __weak arch_mod_section_prepend(struct module *mod, | ||
1596 | unsigned int section) | ||
1597 | { | ||
1598 | /* default implementation just returns zero */ | ||
1599 | return 0; | ||
1600 | } | ||
1601 | |||
1581 | /* Update size with this section: return offset. */ | 1602 | /* Update size with this section: return offset. */ |
1582 | static long get_offset(unsigned int *size, Elf_Shdr *sechdr) | 1603 | static long get_offset(struct module *mod, unsigned int *size, |
1604 | Elf_Shdr *sechdr, unsigned int section) | ||
1583 | { | 1605 | { |
1584 | long ret; | 1606 | long ret; |
1585 | 1607 | ||
1608 | *size += arch_mod_section_prepend(mod, section); | ||
1586 | ret = ALIGN(*size, sechdr->sh_addralign ?: 1); | 1609 | ret = ALIGN(*size, sechdr->sh_addralign ?: 1); |
1587 | *size = ret + sechdr->sh_size; | 1610 | *size = ret + sechdr->sh_size; |
1588 | return ret; | 1611 | return ret; |
@@ -1622,7 +1645,7 @@ static void layout_sections(struct module *mod, | |||
1622 | || strncmp(secstrings + s->sh_name, | 1645 | || strncmp(secstrings + s->sh_name, |
1623 | ".init", 5) == 0) | 1646 | ".init", 5) == 0) |
1624 | continue; | 1647 | continue; |
1625 | s->sh_entsize = get_offset(&mod->core_size, s); | 1648 | s->sh_entsize = get_offset(mod, &mod->core_size, s, i); |
1626 | DEBUGP("\t%s\n", secstrings + s->sh_name); | 1649 | DEBUGP("\t%s\n", secstrings + s->sh_name); |
1627 | } | 1650 | } |
1628 | if (m == 0) | 1651 | if (m == 0) |
@@ -1640,7 +1663,7 @@ static void layout_sections(struct module *mod, | |||
1640 | || strncmp(secstrings + s->sh_name, | 1663 | || strncmp(secstrings + s->sh_name, |
1641 | ".init", 5) != 0) | 1664 | ".init", 5) != 0) |
1642 | continue; | 1665 | continue; |
1643 | s->sh_entsize = (get_offset(&mod->init_size, s) | 1666 | s->sh_entsize = (get_offset(mod, &mod->init_size, s, i) |
1644 | | INIT_OFFSET_MASK); | 1667 | | INIT_OFFSET_MASK); |
1645 | DEBUGP("\t%s\n", secstrings + s->sh_name); | 1668 | DEBUGP("\t%s\n", secstrings + s->sh_name); |
1646 | } | 1669 | } |
@@ -1725,15 +1748,15 @@ static const struct kernel_symbol *lookup_symbol(const char *name, | |||
1725 | return NULL; | 1748 | return NULL; |
1726 | } | 1749 | } |
1727 | 1750 | ||
1728 | static int is_exported(const char *name, const struct module *mod) | 1751 | static int is_exported(const char *name, unsigned long value, |
1752 | const struct module *mod) | ||
1729 | { | 1753 | { |
1730 | if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab)) | 1754 | const struct kernel_symbol *ks; |
1731 | return 1; | 1755 | if (!mod) |
1756 | ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab); | ||
1732 | else | 1757 | else |
1733 | if (mod && lookup_symbol(name, mod->syms, mod->syms + mod->num_syms)) | 1758 | ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms); |
1734 | return 1; | 1759 | return ks != NULL && ks->value == value; |
1735 | else | ||
1736 | return 0; | ||
1737 | } | 1760 | } |
1738 | 1761 | ||
1739 | /* As per nm */ | 1762 | /* As per nm */ |
@@ -1847,7 +1870,6 @@ static noinline struct module *load_module(void __user *umod, | |||
1847 | unsigned int symindex = 0; | 1870 | unsigned int symindex = 0; |
1848 | unsigned int strindex = 0; | 1871 | unsigned int strindex = 0; |
1849 | unsigned int modindex, versindex, infoindex, pcpuindex; | 1872 | unsigned int modindex, versindex, infoindex, pcpuindex; |
1850 | unsigned int unwindex = 0; | ||
1851 | unsigned int num_kp, num_mcount; | 1873 | unsigned int num_kp, num_mcount; |
1852 | struct kernel_param *kp; | 1874 | struct kernel_param *kp; |
1853 | struct module *mod; | 1875 | struct module *mod; |
@@ -1865,6 +1887,13 @@ static noinline struct module *load_module(void __user *umod, | |||
1865 | /* vmalloc barfs on "unusual" numbers. Check here */ | 1887 | /* vmalloc barfs on "unusual" numbers. Check here */ |
1866 | if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL) | 1888 | if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL) |
1867 | return ERR_PTR(-ENOMEM); | 1889 | return ERR_PTR(-ENOMEM); |
1890 | |||
1891 | /* Create stop_machine threads since the error path relies on | ||
1892 | * a non-failing stop_machine call. */ | ||
1893 | err = stop_machine_create(); | ||
1894 | if (err) | ||
1895 | goto free_hdr; | ||
1896 | |||
1868 | if (copy_from_user(hdr, umod, len) != 0) { | 1897 | if (copy_from_user(hdr, umod, len) != 0) { |
1869 | err = -EFAULT; | 1898 | err = -EFAULT; |
1870 | goto free_hdr; | 1899 | goto free_hdr; |
@@ -1930,9 +1959,6 @@ static noinline struct module *load_module(void __user *umod, | |||
1930 | versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); | 1959 | versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); |
1931 | infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); | 1960 | infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); |
1932 | pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); | 1961 | pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); |
1933 | #ifdef ARCH_UNWIND_SECTION_NAME | ||
1934 | unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME); | ||
1935 | #endif | ||
1936 | 1962 | ||
1937 | /* Don't keep modinfo and version sections. */ | 1963 | /* Don't keep modinfo and version sections. */ |
1938 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 1964 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
@@ -1942,8 +1968,6 @@ static noinline struct module *load_module(void __user *umod, | |||
1942 | sechdrs[symindex].sh_flags |= SHF_ALLOC; | 1968 | sechdrs[symindex].sh_flags |= SHF_ALLOC; |
1943 | sechdrs[strindex].sh_flags |= SHF_ALLOC; | 1969 | sechdrs[strindex].sh_flags |= SHF_ALLOC; |
1944 | #endif | 1970 | #endif |
1945 | if (unwindex) | ||
1946 | sechdrs[unwindex].sh_flags |= SHF_ALLOC; | ||
1947 | 1971 | ||
1948 | /* Check module struct version now, before we try to use module. */ | 1972 | /* Check module struct version now, before we try to use module. */ |
1949 | if (!check_modstruct_version(sechdrs, versindex, mod)) { | 1973 | if (!check_modstruct_version(sechdrs, versindex, mod)) { |
@@ -1991,6 +2015,14 @@ static noinline struct module *load_module(void __user *umod, | |||
1991 | if (err < 0) | 2015 | if (err < 0) |
1992 | goto free_mod; | 2016 | goto free_mod; |
1993 | 2017 | ||
2018 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2019 | mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), | ||
2020 | mod->name); | ||
2021 | if (!mod->refptr) { | ||
2022 | err = -ENOMEM; | ||
2023 | goto free_mod; | ||
2024 | } | ||
2025 | #endif | ||
1994 | if (pcpuindex) { | 2026 | if (pcpuindex) { |
1995 | /* We have a special allocation for this section. */ | 2027 | /* We have a special allocation for this section. */ |
1996 | percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, | 2028 | percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, |
@@ -1998,7 +2030,7 @@ static noinline struct module *load_module(void __user *umod, | |||
1998 | mod->name); | 2030 | mod->name); |
1999 | if (!percpu) { | 2031 | if (!percpu) { |
2000 | err = -ENOMEM; | 2032 | err = -ENOMEM; |
2001 | goto free_mod; | 2033 | goto free_percpu; |
2002 | } | 2034 | } |
2003 | sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2035 | sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
2004 | mod->percpu = percpu; | 2036 | mod->percpu = percpu; |
@@ -2184,24 +2216,15 @@ static noinline struct module *load_module(void __user *umod, | |||
2184 | struct mod_debug *debug; | 2216 | struct mod_debug *debug; |
2185 | unsigned int num_debug; | 2217 | unsigned int num_debug; |
2186 | 2218 | ||
2187 | #ifdef CONFIG_MARKERS | ||
2188 | marker_update_probe_range(mod->markers, | ||
2189 | mod->markers + mod->num_markers); | ||
2190 | #endif | ||
2191 | debug = section_objs(hdr, sechdrs, secstrings, "__verbose", | 2219 | debug = section_objs(hdr, sechdrs, secstrings, "__verbose", |
2192 | sizeof(*debug), &num_debug); | 2220 | sizeof(*debug), &num_debug); |
2193 | dynamic_printk_setup(debug, num_debug); | 2221 | dynamic_printk_setup(debug, num_debug); |
2194 | |||
2195 | #ifdef CONFIG_TRACEPOINTS | ||
2196 | tracepoint_update_probe_range(mod->tracepoints, | ||
2197 | mod->tracepoints + mod->num_tracepoints); | ||
2198 | #endif | ||
2199 | } | 2222 | } |
2200 | 2223 | ||
2201 | /* sechdrs[0].sh_size is always zero */ | 2224 | /* sechdrs[0].sh_size is always zero */ |
2202 | mseg = section_objs(hdr, sechdrs, secstrings, "__mcount_loc", | 2225 | mseg = section_objs(hdr, sechdrs, secstrings, "__mcount_loc", |
2203 | sizeof(*mseg), &num_mcount); | 2226 | sizeof(*mseg), &num_mcount); |
2204 | ftrace_init_module(mseg, mseg + num_mcount); | 2227 | ftrace_init_module(mod, mseg, mseg + num_mcount); |
2205 | 2228 | ||
2206 | err = module_finalize(hdr, sechdrs, mod); | 2229 | err = module_finalize(hdr, sechdrs, mod); |
2207 | if (err < 0) | 2230 | if (err < 0) |
@@ -2249,14 +2272,10 @@ static noinline struct module *load_module(void __user *umod, | |||
2249 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | 2272 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); |
2250 | add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | 2273 | add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); |
2251 | 2274 | ||
2252 | /* Size of section 0 is 0, so this works well if no unwind info. */ | ||
2253 | mod->unwind_info = unwind_add_table(mod, | ||
2254 | (void *)sechdrs[unwindex].sh_addr, | ||
2255 | sechdrs[unwindex].sh_size); | ||
2256 | |||
2257 | /* Get rid of temporary copy */ | 2275 | /* Get rid of temporary copy */ |
2258 | vfree(hdr); | 2276 | vfree(hdr); |
2259 | 2277 | ||
2278 | stop_machine_destroy(); | ||
2260 | /* Done! */ | 2279 | /* Done! */ |
2261 | return mod; | 2280 | return mod; |
2262 | 2281 | ||
@@ -2275,10 +2294,14 @@ static noinline struct module *load_module(void __user *umod, | |||
2275 | free_percpu: | 2294 | free_percpu: |
2276 | if (percpu) | 2295 | if (percpu) |
2277 | percpu_modfree(percpu); | 2296 | percpu_modfree(percpu); |
2297 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2298 | percpu_modfree(mod->refptr); | ||
2299 | #endif | ||
2278 | free_mod: | 2300 | free_mod: |
2279 | kfree(args); | 2301 | kfree(args); |
2280 | free_hdr: | 2302 | free_hdr: |
2281 | vfree(hdr); | 2303 | vfree(hdr); |
2304 | stop_machine_destroy(); | ||
2282 | return ERR_PTR(err); | 2305 | return ERR_PTR(err); |
2283 | 2306 | ||
2284 | truncated: | 2307 | truncated: |
@@ -2288,10 +2311,8 @@ static noinline struct module *load_module(void __user *umod, | |||
2288 | } | 2311 | } |
2289 | 2312 | ||
2290 | /* This is where the real work happens */ | 2313 | /* This is where the real work happens */ |
2291 | asmlinkage long | 2314 | SYSCALL_DEFINE3(init_module, void __user *, umod, |
2292 | sys_init_module(void __user *umod, | 2315 | unsigned long, len, const char __user *, uargs) |
2293 | unsigned long len, | ||
2294 | const char __user *uargs) | ||
2295 | { | 2316 | { |
2296 | struct module *mod; | 2317 | struct module *mod; |
2297 | int ret = 0; | 2318 | int ret = 0; |
@@ -2346,11 +2367,12 @@ sys_init_module(void __user *umod, | |||
2346 | /* Now it's a first class citizen! Wake up anyone waiting for it. */ | 2367 | /* Now it's a first class citizen! Wake up anyone waiting for it. */ |
2347 | mod->state = MODULE_STATE_LIVE; | 2368 | mod->state = MODULE_STATE_LIVE; |
2348 | wake_up(&module_wq); | 2369 | wake_up(&module_wq); |
2370 | blocking_notifier_call_chain(&module_notify_list, | ||
2371 | MODULE_STATE_LIVE, mod); | ||
2349 | 2372 | ||
2350 | mutex_lock(&module_mutex); | 2373 | mutex_lock(&module_mutex); |
2351 | /* Drop initial reference. */ | 2374 | /* Drop initial reference. */ |
2352 | module_put(mod); | 2375 | module_put(mod); |
2353 | unwind_remove_table(mod->unwind_info, 1); | ||
2354 | module_free(mod, mod->module_init); | 2376 | module_free(mod, mod->module_init); |
2355 | mod->module_init = NULL; | 2377 | mod->module_init = NULL; |
2356 | mod->init_size = 0; | 2378 | mod->init_size = 0; |
@@ -2385,7 +2407,7 @@ static const char *get_ksymbol(struct module *mod, | |||
2385 | unsigned long nextval; | 2407 | unsigned long nextval; |
2386 | 2408 | ||
2387 | /* At worse, next value is at end of module */ | 2409 | /* At worse, next value is at end of module */ |
2388 | if (within(addr, mod->module_init, mod->init_size)) | 2410 | if (within_module_init(addr, mod)) |
2389 | nextval = (unsigned long)mod->module_init+mod->init_text_size; | 2411 | nextval = (unsigned long)mod->module_init+mod->init_text_size; |
2390 | else | 2412 | else |
2391 | nextval = (unsigned long)mod->module_core+mod->core_text_size; | 2413 | nextval = (unsigned long)mod->module_core+mod->core_text_size; |
@@ -2433,8 +2455,8 @@ const char *module_address_lookup(unsigned long addr, | |||
2433 | 2455 | ||
2434 | preempt_disable(); | 2456 | preempt_disable(); |
2435 | list_for_each_entry_rcu(mod, &modules, list) { | 2457 | list_for_each_entry_rcu(mod, &modules, list) { |
2436 | if (within(addr, mod->module_init, mod->init_size) | 2458 | if (within_module_init(addr, mod) || |
2437 | || within(addr, mod->module_core, mod->core_size)) { | 2459 | within_module_core(addr, mod)) { |
2438 | if (modname) | 2460 | if (modname) |
2439 | *modname = mod->name; | 2461 | *modname = mod->name; |
2440 | ret = get_ksymbol(mod, addr, size, offset); | 2462 | ret = get_ksymbol(mod, addr, size, offset); |
@@ -2456,8 +2478,8 @@ int lookup_module_symbol_name(unsigned long addr, char *symname) | |||
2456 | 2478 | ||
2457 | preempt_disable(); | 2479 | preempt_disable(); |
2458 | list_for_each_entry_rcu(mod, &modules, list) { | 2480 | list_for_each_entry_rcu(mod, &modules, list) { |
2459 | if (within(addr, mod->module_init, mod->init_size) || | 2481 | if (within_module_init(addr, mod) || |
2460 | within(addr, mod->module_core, mod->core_size)) { | 2482 | within_module_core(addr, mod)) { |
2461 | const char *sym; | 2483 | const char *sym; |
2462 | 2484 | ||
2463 | sym = get_ksymbol(mod, addr, NULL, NULL); | 2485 | sym = get_ksymbol(mod, addr, NULL, NULL); |
@@ -2480,8 +2502,8 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, | |||
2480 | 2502 | ||
2481 | preempt_disable(); | 2503 | preempt_disable(); |
2482 | list_for_each_entry_rcu(mod, &modules, list) { | 2504 | list_for_each_entry_rcu(mod, &modules, list) { |
2483 | if (within(addr, mod->module_init, mod->init_size) || | 2505 | if (within_module_init(addr, mod) || |
2484 | within(addr, mod->module_core, mod->core_size)) { | 2506 | within_module_core(addr, mod)) { |
2485 | const char *sym; | 2507 | const char *sym; |
2486 | 2508 | ||
2487 | sym = get_ksymbol(mod, addr, size, offset); | 2509 | sym = get_ksymbol(mod, addr, size, offset); |
@@ -2513,7 +2535,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, | |||
2513 | strlcpy(name, mod->strtab + mod->symtab[symnum].st_name, | 2535 | strlcpy(name, mod->strtab + mod->symtab[symnum].st_name, |
2514 | KSYM_NAME_LEN); | 2536 | KSYM_NAME_LEN); |
2515 | strlcpy(module_name, mod->name, MODULE_NAME_LEN); | 2537 | strlcpy(module_name, mod->name, MODULE_NAME_LEN); |
2516 | *exported = is_exported(name, mod); | 2538 | *exported = is_exported(name, *value, mod); |
2517 | preempt_enable(); | 2539 | preempt_enable(); |
2518 | return 0; | 2540 | return 0; |
2519 | } | 2541 | } |
@@ -2700,7 +2722,7 @@ int is_module_address(unsigned long addr) | |||
2700 | preempt_disable(); | 2722 | preempt_disable(); |
2701 | 2723 | ||
2702 | list_for_each_entry_rcu(mod, &modules, list) { | 2724 | list_for_each_entry_rcu(mod, &modules, list) { |
2703 | if (within(addr, mod->module_core, mod->core_size)) { | 2725 | if (within_module_core(addr, mod)) { |
2704 | preempt_enable(); | 2726 | preempt_enable(); |
2705 | return 1; | 2727 | return 1; |
2706 | } | 2728 | } |
@@ -2713,7 +2735,7 @@ int is_module_address(unsigned long addr) | |||
2713 | 2735 | ||
2714 | 2736 | ||
2715 | /* Is this a valid kernel address? */ | 2737 | /* Is this a valid kernel address? */ |
2716 | struct module *__module_text_address(unsigned long addr) | 2738 | __notrace_funcgraph struct module *__module_text_address(unsigned long addr) |
2717 | { | 2739 | { |
2718 | struct module *mod; | 2740 | struct module *mod; |
2719 | 2741 | ||