diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 343 |
1 files changed, 163 insertions, 180 deletions
diff --git a/kernel/module.c b/kernel/module.c index 0d8d21ee792c..1f4cc00e0c20 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -20,11 +20,13 @@ | |||
| 20 | #include <linux/moduleloader.h> | 20 | #include <linux/moduleloader.h> |
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/kallsyms.h> | 22 | #include <linux/kallsyms.h> |
| 23 | #include <linux/fs.h> | ||
| 23 | #include <linux/sysfs.h> | 24 | #include <linux/sysfs.h> |
| 24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
| 25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 26 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
| 27 | #include <linux/elf.h> | 28 | #include <linux/elf.h> |
| 29 | #include <linux/proc_fs.h> | ||
| 28 | #include <linux/seq_file.h> | 30 | #include <linux/seq_file.h> |
| 29 | #include <linux/syscalls.h> | 31 | #include <linux/syscalls.h> |
| 30 | #include <linux/fcntl.h> | 32 | #include <linux/fcntl.h> |
| @@ -42,6 +44,7 @@ | |||
| 42 | #include <linux/string.h> | 44 | #include <linux/string.h> |
| 43 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
| 44 | #include <linux/unwind.h> | 46 | #include <linux/unwind.h> |
| 47 | #include <linux/rculist.h> | ||
| 45 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
| 46 | #include <asm/cacheflush.h> | 49 | #include <asm/cacheflush.h> |
| 47 | #include <linux/license.h> | 50 | #include <linux/license.h> |
| @@ -63,7 +66,7 @@ | |||
| 63 | #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) | 66 | #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) |
| 64 | 67 | ||
| 65 | /* List of modules, protected by module_mutex or preempt_disable | 68 | /* List of modules, protected by module_mutex or preempt_disable |
| 66 | * (add/delete uses stop_machine). */ | 69 | * (delete uses stop_machine/add uses RCU list operations). */ |
| 67 | static DEFINE_MUTEX(module_mutex); | 70 | static DEFINE_MUTEX(module_mutex); |
| 68 | static LIST_HEAD(modules); | 71 | static LIST_HEAD(modules); |
| 69 | 72 | ||
| @@ -132,6 +135,29 @@ static unsigned int find_sec(Elf_Ehdr *hdr, | |||
| 132 | return 0; | 135 | return 0; |
| 133 | } | 136 | } |
| 134 | 137 | ||
| 138 | /* Find a module section, or NULL. */ | ||
| 139 | static void *section_addr(Elf_Ehdr *hdr, Elf_Shdr *shdrs, | ||
| 140 | const char *secstrings, const char *name) | ||
| 141 | { | ||
| 142 | /* Section 0 has sh_addr 0. */ | ||
| 143 | return (void *)shdrs[find_sec(hdr, shdrs, secstrings, name)].sh_addr; | ||
| 144 | } | ||
| 145 | |||
| 146 | /* Find a module section, or NULL. Fill in number of "objects" in section. */ | ||
| 147 | static void *section_objs(Elf_Ehdr *hdr, | ||
| 148 | Elf_Shdr *sechdrs, | ||
| 149 | const char *secstrings, | ||
| 150 | const char *name, | ||
| 151 | size_t object_size, | ||
| 152 | unsigned int *num) | ||
| 153 | { | ||
| 154 | unsigned int sec = find_sec(hdr, sechdrs, secstrings, name); | ||
| 155 | |||
| 156 | /* Section 0 has sh_addr 0 and sh_size 0. */ | ||
| 157 | *num = sechdrs[sec].sh_size / object_size; | ||
| 158 | return (void *)sechdrs[sec].sh_addr; | ||
| 159 | } | ||
| 160 | |||
| 135 | /* Provided by the linker */ | 161 | /* Provided by the linker */ |
| 136 | extern const struct kernel_symbol __start___ksymtab[]; | 162 | extern const struct kernel_symbol __start___ksymtab[]; |
| 137 | extern const struct kernel_symbol __stop___ksymtab[]; | 163 | extern const struct kernel_symbol __stop___ksymtab[]; |
| @@ -218,7 +244,7 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr, | |||
| 218 | if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data)) | 244 | if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data)) |
| 219 | return true; | 245 | return true; |
| 220 | 246 | ||
| 221 | list_for_each_entry(mod, &modules, list) { | 247 | list_for_each_entry_rcu(mod, &modules, list) { |
| 222 | struct symsearch arr[] = { | 248 | struct symsearch arr[] = { |
| 223 | { mod->syms, mod->syms + mod->num_syms, mod->crcs, | 249 | { mod->syms, mod->syms + mod->num_syms, mod->crcs, |
| 224 | NOT_GPL_ONLY, false }, | 250 | NOT_GPL_ONLY, false }, |
| @@ -1394,17 +1420,6 @@ static void mod_kobject_remove(struct module *mod) | |||
| 1394 | } | 1420 | } |
| 1395 | 1421 | ||
| 1396 | /* | 1422 | /* |
| 1397 | * link the module with the whole machine is stopped with interrupts off | ||
| 1398 | * - this defends against kallsyms not taking locks | ||
| 1399 | */ | ||
| 1400 | static int __link_module(void *_mod) | ||
| 1401 | { | ||
| 1402 | struct module *mod = _mod; | ||
| 1403 | list_add(&mod->list, &modules); | ||
| 1404 | return 0; | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | /* | ||
| 1408 | * unlink the module with the whole machine is stopped with interrupts off | 1423 | * unlink the module with the whole machine is stopped with interrupts off |
| 1409 | * - this defends against kallsyms not taking locks | 1424 | * - this defends against kallsyms not taking locks |
| 1410 | */ | 1425 | */ |
| @@ -1789,32 +1804,20 @@ static inline void add_kallsyms(struct module *mod, | |||
| 1789 | } | 1804 | } |
| 1790 | #endif /* CONFIG_KALLSYMS */ | 1805 | #endif /* CONFIG_KALLSYMS */ |
| 1791 | 1806 | ||
| 1792 | #ifdef CONFIG_DYNAMIC_PRINTK_DEBUG | 1807 | static void dynamic_printk_setup(struct mod_debug *debug, unsigned int num) |
| 1793 | static void dynamic_printk_setup(Elf_Shdr *sechdrs, unsigned int verboseindex) | ||
| 1794 | { | 1808 | { |
| 1795 | struct mod_debug *debug_info; | 1809 | #ifdef CONFIG_DYNAMIC_PRINTK_DEBUG |
| 1796 | unsigned long pos, end; | 1810 | unsigned int i; |
| 1797 | unsigned int num_verbose; | ||
| 1798 | |||
| 1799 | pos = sechdrs[verboseindex].sh_addr; | ||
| 1800 | num_verbose = sechdrs[verboseindex].sh_size / | ||
| 1801 | sizeof(struct mod_debug); | ||
| 1802 | end = pos + (num_verbose * sizeof(struct mod_debug)); | ||
| 1803 | 1811 | ||
| 1804 | for (; pos < end; pos += sizeof(struct mod_debug)) { | 1812 | for (i = 0; i < num; i++) { |
| 1805 | debug_info = (struct mod_debug *)pos; | 1813 | register_dynamic_debug_module(debug[i].modname, |
| 1806 | register_dynamic_debug_module(debug_info->modname, | 1814 | debug[i].type, |
| 1807 | debug_info->type, debug_info->logical_modname, | 1815 | debug[i].logical_modname, |
| 1808 | debug_info->flag_names, debug_info->hash, | 1816 | debug[i].flag_names, |
| 1809 | debug_info->hash2); | 1817 | debug[i].hash, debug[i].hash2); |
| 1810 | } | 1818 | } |
| 1811 | } | ||
| 1812 | #else | ||
| 1813 | static inline void dynamic_printk_setup(Elf_Shdr *sechdrs, | ||
| 1814 | unsigned int verboseindex) | ||
| 1815 | { | ||
| 1816 | } | ||
| 1817 | #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */ | 1819 | #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */ |
| 1820 | } | ||
| 1818 | 1821 | ||
| 1819 | static void *module_alloc_update_bounds(unsigned long size) | 1822 | static void *module_alloc_update_bounds(unsigned long size) |
| 1820 | { | 1823 | { |
| @@ -1843,37 +1846,14 @@ static noinline struct module *load_module(void __user *umod, | |||
| 1843 | unsigned int i; | 1846 | unsigned int i; |
| 1844 | unsigned int symindex = 0; | 1847 | unsigned int symindex = 0; |
| 1845 | unsigned int strindex = 0; | 1848 | unsigned int strindex = 0; |
| 1846 | unsigned int setupindex; | 1849 | unsigned int modindex, versindex, infoindex, pcpuindex; |
| 1847 | unsigned int exindex; | ||
| 1848 | unsigned int exportindex; | ||
| 1849 | unsigned int modindex; | ||
| 1850 | unsigned int obsparmindex; | ||
| 1851 | unsigned int infoindex; | ||
| 1852 | unsigned int gplindex; | ||
| 1853 | unsigned int crcindex; | ||
| 1854 | unsigned int gplcrcindex; | ||
| 1855 | unsigned int versindex; | ||
| 1856 | unsigned int pcpuindex; | ||
| 1857 | unsigned int gplfutureindex; | ||
| 1858 | unsigned int gplfuturecrcindex; | ||
| 1859 | unsigned int unwindex = 0; | 1850 | unsigned int unwindex = 0; |
| 1860 | #ifdef CONFIG_UNUSED_SYMBOLS | 1851 | unsigned int num_kp, num_mcount; |
| 1861 | unsigned int unusedindex; | 1852 | struct kernel_param *kp; |
| 1862 | unsigned int unusedcrcindex; | ||
| 1863 | unsigned int unusedgplindex; | ||
| 1864 | unsigned int unusedgplcrcindex; | ||
| 1865 | #endif | ||
| 1866 | unsigned int markersindex; | ||
| 1867 | unsigned int markersstringsindex; | ||
| 1868 | unsigned int verboseindex; | ||
| 1869 | unsigned int tracepointsindex; | ||
| 1870 | unsigned int tracepointsstringsindex; | ||
| 1871 | unsigned int mcountindex; | ||
| 1872 | struct module *mod; | 1853 | struct module *mod; |
| 1873 | long err = 0; | 1854 | long err = 0; |
| 1874 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1855 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
| 1875 | void *mseg; | 1856 | unsigned long *mseg; |
| 1876 | struct exception_table_entry *extable; | ||
| 1877 | mm_segment_t old_fs; | 1857 | mm_segment_t old_fs; |
| 1878 | 1858 | ||
| 1879 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", | 1859 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", |
| @@ -1937,6 +1917,7 @@ static noinline struct module *load_module(void __user *umod, | |||
| 1937 | err = -ENOEXEC; | 1917 | err = -ENOEXEC; |
| 1938 | goto free_hdr; | 1918 | goto free_hdr; |
| 1939 | } | 1919 | } |
| 1920 | /* This is temporary: point mod into copy of data. */ | ||
| 1940 | mod = (void *)sechdrs[modindex].sh_addr; | 1921 | mod = (void *)sechdrs[modindex].sh_addr; |
| 1941 | 1922 | ||
| 1942 | if (symindex == 0) { | 1923 | if (symindex == 0) { |
| @@ -1946,22 +1927,6 @@ static noinline struct module *load_module(void __user *umod, | |||
| 1946 | goto free_hdr; | 1927 | goto free_hdr; |
| 1947 | } | 1928 | } |
| 1948 | 1929 | ||
| 1949 | /* Optional sections */ | ||
| 1950 | exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); | ||
| 1951 | gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); | ||
| 1952 | gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future"); | ||
| 1953 | crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); | ||
| 1954 | gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); | ||
| 1955 | gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future"); | ||
| 1956 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
| 1957 | unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused"); | ||
| 1958 | unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl"); | ||
| 1959 | unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused"); | ||
| 1960 | unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl"); | ||
| 1961 | #endif | ||
| 1962 | setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); | ||
| 1963 | exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); | ||
| 1964 | obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); | ||
| 1965 | versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); | 1930 | versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); |
| 1966 | infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); | 1931 | infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); |
| 1967 | pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); | 1932 | pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); |
| @@ -2117,42 +2082,57 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2117 | if (err < 0) | 2082 | if (err < 0) |
| 2118 | goto cleanup; | 2083 | goto cleanup; |
| 2119 | 2084 | ||
| 2120 | /* Set up EXPORTed & EXPORT_GPLed symbols (section 0 is 0 length) */ | 2085 | /* Now we've got everything in the final locations, we can |
| 2121 | mod->num_syms = sechdrs[exportindex].sh_size / sizeof(*mod->syms); | 2086 | * find optional sections. */ |
| 2122 | mod->syms = (void *)sechdrs[exportindex].sh_addr; | 2087 | kp = section_objs(hdr, sechdrs, secstrings, "__param", sizeof(*kp), |
| 2123 | if (crcindex) | 2088 | &num_kp); |
| 2124 | mod->crcs = (void *)sechdrs[crcindex].sh_addr; | 2089 | mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab", |
| 2125 | mod->num_gpl_syms = sechdrs[gplindex].sh_size / sizeof(*mod->gpl_syms); | 2090 | sizeof(*mod->syms), &mod->num_syms); |
| 2126 | mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr; | 2091 | mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab"); |
| 2127 | if (gplcrcindex) | 2092 | mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl", |
| 2128 | mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; | 2093 | sizeof(*mod->gpl_syms), |
| 2129 | mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size / | 2094 | &mod->num_gpl_syms); |
| 2130 | sizeof(*mod->gpl_future_syms); | 2095 | mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl"); |
| 2131 | mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr; | 2096 | mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings, |
| 2132 | if (gplfuturecrcindex) | 2097 | "__ksymtab_gpl_future", |
| 2133 | mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; | 2098 | sizeof(*mod->gpl_future_syms), |
| 2099 | &mod->num_gpl_future_syms); | ||
| 2100 | mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings, | ||
| 2101 | "__kcrctab_gpl_future"); | ||
| 2134 | 2102 | ||
| 2135 | #ifdef CONFIG_UNUSED_SYMBOLS | 2103 | #ifdef CONFIG_UNUSED_SYMBOLS |
| 2136 | mod->num_unused_syms = sechdrs[unusedindex].sh_size / | 2104 | mod->unused_syms = section_objs(hdr, sechdrs, secstrings, |
| 2137 | sizeof(*mod->unused_syms); | 2105 | "__ksymtab_unused", |
| 2138 | mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size / | 2106 | sizeof(*mod->unused_syms), |
| 2139 | sizeof(*mod->unused_gpl_syms); | 2107 | &mod->num_unused_syms); |
| 2140 | mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr; | 2108 | mod->unused_crcs = section_addr(hdr, sechdrs, secstrings, |
| 2141 | if (unusedcrcindex) | 2109 | "__kcrctab_unused"); |
| 2142 | mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr; | 2110 | mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings, |
| 2143 | mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr; | 2111 | "__ksymtab_unused_gpl", |
| 2144 | if (unusedgplcrcindex) | 2112 | sizeof(*mod->unused_gpl_syms), |
| 2145 | mod->unused_gpl_crcs | 2113 | &mod->num_unused_gpl_syms); |
| 2146 | = (void *)sechdrs[unusedgplcrcindex].sh_addr; | 2114 | mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings, |
| 2115 | "__kcrctab_unused_gpl"); | ||
| 2116 | #endif | ||
| 2117 | |||
| 2118 | #ifdef CONFIG_MARKERS | ||
| 2119 | mod->markers = section_objs(hdr, sechdrs, secstrings, "__markers", | ||
| 2120 | sizeof(*mod->markers), &mod->num_markers); | ||
| 2121 | #endif | ||
| 2122 | #ifdef CONFIG_TRACEPOINTS | ||
| 2123 | mod->tracepoints = section_objs(hdr, sechdrs, secstrings, | ||
| 2124 | "__tracepoints", | ||
| 2125 | sizeof(*mod->tracepoints), | ||
| 2126 | &mod->num_tracepoints); | ||
| 2147 | #endif | 2127 | #endif |
| 2148 | 2128 | ||
| 2149 | #ifdef CONFIG_MODVERSIONS | 2129 | #ifdef CONFIG_MODVERSIONS |
| 2150 | if ((mod->num_syms && !crcindex) | 2130 | if ((mod->num_syms && !mod->crcs) |
| 2151 | || (mod->num_gpl_syms && !gplcrcindex) | 2131 | || (mod->num_gpl_syms && !mod->gpl_crcs) |
| 2152 | || (mod->num_gpl_future_syms && !gplfuturecrcindex) | 2132 | || (mod->num_gpl_future_syms && !mod->gpl_future_crcs) |
| 2153 | #ifdef CONFIG_UNUSED_SYMBOLS | 2133 | #ifdef CONFIG_UNUSED_SYMBOLS |
| 2154 | || (mod->num_unused_syms && !unusedcrcindex) | 2134 | || (mod->num_unused_syms && !mod->unused_crcs) |
| 2155 | || (mod->num_unused_gpl_syms && !unusedgplcrcindex) | 2135 | || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs) |
| 2156 | #endif | 2136 | #endif |
| 2157 | ) { | 2137 | ) { |
| 2158 | printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name); | 2138 | printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name); |
| @@ -2161,16 +2141,6 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2161 | goto cleanup; | 2141 | goto cleanup; |
| 2162 | } | 2142 | } |
| 2163 | #endif | 2143 | #endif |
| 2164 | markersindex = find_sec(hdr, sechdrs, secstrings, "__markers"); | ||
| 2165 | markersstringsindex = find_sec(hdr, sechdrs, secstrings, | ||
| 2166 | "__markers_strings"); | ||
| 2167 | verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose"); | ||
| 2168 | tracepointsindex = find_sec(hdr, sechdrs, secstrings, "__tracepoints"); | ||
| 2169 | tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings, | ||
| 2170 | "__tracepoints_strings"); | ||
| 2171 | |||
| 2172 | mcountindex = find_sec(hdr, sechdrs, secstrings, | ||
| 2173 | "__mcount_loc"); | ||
| 2174 | 2144 | ||
| 2175 | /* Now do relocations. */ | 2145 | /* Now do relocations. */ |
| 2176 | for (i = 1; i < hdr->e_shnum; i++) { | 2146 | for (i = 1; i < hdr->e_shnum; i++) { |
| @@ -2193,28 +2163,16 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2193 | if (err < 0) | 2163 | if (err < 0) |
| 2194 | goto cleanup; | 2164 | goto cleanup; |
| 2195 | } | 2165 | } |
| 2196 | #ifdef CONFIG_MARKERS | ||
| 2197 | mod->markers = (void *)sechdrs[markersindex].sh_addr; | ||
| 2198 | mod->num_markers = | ||
| 2199 | sechdrs[markersindex].sh_size / sizeof(*mod->markers); | ||
| 2200 | #endif | ||
| 2201 | #ifdef CONFIG_TRACEPOINTS | ||
| 2202 | mod->tracepoints = (void *)sechdrs[tracepointsindex].sh_addr; | ||
| 2203 | mod->num_tracepoints = | ||
| 2204 | sechdrs[tracepointsindex].sh_size / sizeof(*mod->tracepoints); | ||
| 2205 | #endif | ||
| 2206 | |||
| 2207 | 2166 | ||
| 2208 | /* Find duplicate symbols */ | 2167 | /* Find duplicate symbols */ |
| 2209 | err = verify_export_symbols(mod); | 2168 | err = verify_export_symbols(mod); |
| 2210 | |||
| 2211 | if (err < 0) | 2169 | if (err < 0) |
| 2212 | goto cleanup; | 2170 | goto cleanup; |
| 2213 | 2171 | ||
| 2214 | /* Set up and sort exception table */ | 2172 | /* Set up and sort exception table */ |
| 2215 | mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable); | 2173 | mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table", |
| 2216 | mod->extable = extable = (void *)sechdrs[exindex].sh_addr; | 2174 | sizeof(*mod->extable), &mod->num_exentries); |
| 2217 | sort_extable(extable, extable + mod->num_exentries); | 2175 | sort_extable(mod->extable, mod->extable + mod->num_exentries); |
| 2218 | 2176 | ||
| 2219 | /* Finally, copy percpu area over. */ | 2177 | /* Finally, copy percpu area over. */ |
| 2220 | percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr, | 2178 | percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr, |
| @@ -2223,11 +2181,17 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2223 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); | 2181 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); |
| 2224 | 2182 | ||
| 2225 | if (!mod->taints) { | 2183 | if (!mod->taints) { |
| 2184 | struct mod_debug *debug; | ||
| 2185 | unsigned int num_debug; | ||
| 2186 | |||
| 2226 | #ifdef CONFIG_MARKERS | 2187 | #ifdef CONFIG_MARKERS |
| 2227 | marker_update_probe_range(mod->markers, | 2188 | marker_update_probe_range(mod->markers, |
| 2228 | mod->markers + mod->num_markers); | 2189 | mod->markers + mod->num_markers); |
| 2229 | #endif | 2190 | #endif |
| 2230 | dynamic_printk_setup(sechdrs, verboseindex); | 2191 | debug = section_objs(hdr, sechdrs, secstrings, "__verbose", |
| 2192 | sizeof(*debug), &num_debug); | ||
| 2193 | dynamic_printk_setup(debug, num_debug); | ||
| 2194 | |||
| 2231 | #ifdef CONFIG_TRACEPOINTS | 2195 | #ifdef CONFIG_TRACEPOINTS |
| 2232 | tracepoint_update_probe_range(mod->tracepoints, | 2196 | tracepoint_update_probe_range(mod->tracepoints, |
| 2233 | mod->tracepoints + mod->num_tracepoints); | 2197 | mod->tracepoints + mod->num_tracepoints); |
| @@ -2235,8 +2199,9 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2235 | } | 2199 | } |
| 2236 | 2200 | ||
| 2237 | /* sechdrs[0].sh_size is always zero */ | 2201 | /* sechdrs[0].sh_size is always zero */ |
| 2238 | mseg = (void *)sechdrs[mcountindex].sh_addr; | 2202 | mseg = section_objs(hdr, sechdrs, secstrings, "__mcount_loc", |
| 2239 | ftrace_init_module(mseg, mseg + sechdrs[mcountindex].sh_size); | 2203 | sizeof(*mseg), &num_mcount); |
| 2204 | ftrace_init_module(mseg, mseg + num_mcount); | ||
| 2240 | 2205 | ||
| 2241 | err = module_finalize(hdr, sechdrs, mod); | 2206 | err = module_finalize(hdr, sechdrs, mod); |
| 2242 | if (err < 0) | 2207 | if (err < 0) |
| @@ -2261,30 +2226,24 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2261 | set_fs(old_fs); | 2226 | set_fs(old_fs); |
| 2262 | 2227 | ||
| 2263 | mod->args = args; | 2228 | mod->args = args; |
| 2264 | if (obsparmindex) | 2229 | if (section_addr(hdr, sechdrs, secstrings, "__obsparm")) |
| 2265 | printk(KERN_WARNING "%s: Ignoring obsolete parameters\n", | 2230 | printk(KERN_WARNING "%s: Ignoring obsolete parameters\n", |
| 2266 | mod->name); | 2231 | mod->name); |
| 2267 | 2232 | ||
| 2268 | /* Now sew it into the lists so we can get lockdep and oops | 2233 | /* Now sew it into the lists so we can get lockdep and oops |
| 2269 | * info during argument parsing. Noone should access us, since | 2234 | * info during argument parsing. Noone should access us, since |
| 2270 | * strong_try_module_get() will fail. */ | 2235 | * strong_try_module_get() will fail. |
| 2271 | stop_machine(__link_module, mod, NULL); | 2236 | * lockdep/oops can run asynchronous, so use the RCU list insertion |
| 2272 | 2237 | * function to insert in a way safe to concurrent readers. | |
| 2273 | /* Size of section 0 is 0, so this works well if no params */ | 2238 | * The mutex protects against concurrent writers. |
| 2274 | err = parse_args(mod->name, mod->args, | 2239 | */ |
| 2275 | (struct kernel_param *) | 2240 | list_add_rcu(&mod->list, &modules); |
| 2276 | sechdrs[setupindex].sh_addr, | 2241 | |
| 2277 | sechdrs[setupindex].sh_size | 2242 | err = parse_args(mod->name, mod->args, kp, num_kp, NULL); |
| 2278 | / sizeof(struct kernel_param), | ||
| 2279 | NULL); | ||
| 2280 | if (err < 0) | 2243 | if (err < 0) |
| 2281 | goto unlink; | 2244 | goto unlink; |
| 2282 | 2245 | ||
| 2283 | err = mod_sysfs_setup(mod, | 2246 | err = mod_sysfs_setup(mod, kp, num_kp); |
| 2284 | (struct kernel_param *) | ||
| 2285 | sechdrs[setupindex].sh_addr, | ||
| 2286 | sechdrs[setupindex].sh_size | ||
| 2287 | / sizeof(struct kernel_param)); | ||
| 2288 | if (err < 0) | 2247 | if (err < 0) |
| 2289 | goto unlink; | 2248 | goto unlink; |
| 2290 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | 2249 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); |
| @@ -2473,7 +2432,7 @@ const char *module_address_lookup(unsigned long addr, | |||
| 2473 | const char *ret = NULL; | 2432 | const char *ret = NULL; |
| 2474 | 2433 | ||
| 2475 | preempt_disable(); | 2434 | preempt_disable(); |
| 2476 | list_for_each_entry(mod, &modules, list) { | 2435 | list_for_each_entry_rcu(mod, &modules, list) { |
| 2477 | if (within(addr, mod->module_init, mod->init_size) | 2436 | if (within(addr, mod->module_init, mod->init_size) |
| 2478 | || within(addr, mod->module_core, mod->core_size)) { | 2437 | || within(addr, mod->module_core, mod->core_size)) { |
| 2479 | if (modname) | 2438 | if (modname) |
| @@ -2496,7 +2455,7 @@ int lookup_module_symbol_name(unsigned long addr, char *symname) | |||
| 2496 | struct module *mod; | 2455 | struct module *mod; |
| 2497 | 2456 | ||
| 2498 | preempt_disable(); | 2457 | preempt_disable(); |
| 2499 | list_for_each_entry(mod, &modules, list) { | 2458 | list_for_each_entry_rcu(mod, &modules, list) { |
| 2500 | if (within(addr, mod->module_init, mod->init_size) || | 2459 | if (within(addr, mod->module_init, mod->init_size) || |
| 2501 | within(addr, mod->module_core, mod->core_size)) { | 2460 | within(addr, mod->module_core, mod->core_size)) { |
| 2502 | const char *sym; | 2461 | const char *sym; |
| @@ -2520,7 +2479,7 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, | |||
| 2520 | struct module *mod; | 2479 | struct module *mod; |
| 2521 | 2480 | ||
| 2522 | preempt_disable(); | 2481 | preempt_disable(); |
| 2523 | list_for_each_entry(mod, &modules, list) { | 2482 | list_for_each_entry_rcu(mod, &modules, list) { |
| 2524 | if (within(addr, mod->module_init, mod->init_size) || | 2483 | if (within(addr, mod->module_init, mod->init_size) || |
| 2525 | within(addr, mod->module_core, mod->core_size)) { | 2484 | within(addr, mod->module_core, mod->core_size)) { |
| 2526 | const char *sym; | 2485 | const char *sym; |
| @@ -2547,7 +2506,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, | |||
| 2547 | struct module *mod; | 2506 | struct module *mod; |
| 2548 | 2507 | ||
| 2549 | preempt_disable(); | 2508 | preempt_disable(); |
| 2550 | list_for_each_entry(mod, &modules, list) { | 2509 | list_for_each_entry_rcu(mod, &modules, list) { |
| 2551 | if (symnum < mod->num_symtab) { | 2510 | if (symnum < mod->num_symtab) { |
| 2552 | *value = mod->symtab[symnum].st_value; | 2511 | *value = mod->symtab[symnum].st_value; |
| 2553 | *type = mod->symtab[symnum].st_info; | 2512 | *type = mod->symtab[symnum].st_info; |
| @@ -2590,7 +2549,7 @@ unsigned long module_kallsyms_lookup_name(const char *name) | |||
| 2590 | ret = mod_find_symname(mod, colon+1); | 2549 | ret = mod_find_symname(mod, colon+1); |
| 2591 | *colon = ':'; | 2550 | *colon = ':'; |
| 2592 | } else { | 2551 | } else { |
| 2593 | list_for_each_entry(mod, &modules, list) | 2552 | list_for_each_entry_rcu(mod, &modules, list) |
| 2594 | if ((ret = mod_find_symname(mod, name)) != 0) | 2553 | if ((ret = mod_find_symname(mod, name)) != 0) |
| 2595 | break; | 2554 | break; |
| 2596 | } | 2555 | } |
| @@ -2599,23 +2558,6 @@ unsigned long module_kallsyms_lookup_name(const char *name) | |||
| 2599 | } | 2558 | } |
| 2600 | #endif /* CONFIG_KALLSYMS */ | 2559 | #endif /* CONFIG_KALLSYMS */ |
| 2601 | 2560 | ||
| 2602 | /* Called by the /proc file system to return a list of modules. */ | ||
| 2603 | static void *m_start(struct seq_file *m, loff_t *pos) | ||
| 2604 | { | ||
| 2605 | mutex_lock(&module_mutex); | ||
| 2606 | return seq_list_start(&modules, *pos); | ||
| 2607 | } | ||
| 2608 | |||
| 2609 | static void *m_next(struct seq_file *m, void *p, loff_t *pos) | ||
| 2610 | { | ||
| 2611 | return seq_list_next(p, &modules, pos); | ||
| 2612 | } | ||
| 2613 | |||
| 2614 | static void m_stop(struct seq_file *m, void *p) | ||
| 2615 | { | ||
| 2616 | mutex_unlock(&module_mutex); | ||
| 2617 | } | ||
| 2618 | |||
| 2619 | static char *module_flags(struct module *mod, char *buf) | 2561 | static char *module_flags(struct module *mod, char *buf) |
| 2620 | { | 2562 | { |
| 2621 | int bx = 0; | 2563 | int bx = 0; |
| @@ -2649,6 +2591,24 @@ static char *module_flags(struct module *mod, char *buf) | |||
| 2649 | return buf; | 2591 | return buf; |
| 2650 | } | 2592 | } |
| 2651 | 2593 | ||
| 2594 | #ifdef CONFIG_PROC_FS | ||
| 2595 | /* Called by the /proc file system to return a list of modules. */ | ||
| 2596 | static void *m_start(struct seq_file *m, loff_t *pos) | ||
| 2597 | { | ||
| 2598 | mutex_lock(&module_mutex); | ||
| 2599 | return seq_list_start(&modules, *pos); | ||
| 2600 | } | ||
| 2601 | |||
| 2602 | static void *m_next(struct seq_file *m, void *p, loff_t *pos) | ||
| 2603 | { | ||
| 2604 | return seq_list_next(p, &modules, pos); | ||
| 2605 | } | ||
| 2606 | |||
| 2607 | static void m_stop(struct seq_file *m, void *p) | ||
| 2608 | { | ||
| 2609 | mutex_unlock(&module_mutex); | ||
| 2610 | } | ||
| 2611 | |||
| 2652 | static int m_show(struct seq_file *m, void *p) | 2612 | static int m_show(struct seq_file *m, void *p) |
| 2653 | { | 2613 | { |
| 2654 | struct module *mod = list_entry(p, struct module, list); | 2614 | struct module *mod = list_entry(p, struct module, list); |
| @@ -2679,13 +2639,33 @@ static int m_show(struct seq_file *m, void *p) | |||
| 2679 | Where refcount is a number or -, and deps is a comma-separated list | 2639 | Where refcount is a number or -, and deps is a comma-separated list |
| 2680 | of depends or -. | 2640 | of depends or -. |
| 2681 | */ | 2641 | */ |
| 2682 | const struct seq_operations modules_op = { | 2642 | static const struct seq_operations modules_op = { |
| 2683 | .start = m_start, | 2643 | .start = m_start, |
| 2684 | .next = m_next, | 2644 | .next = m_next, |
| 2685 | .stop = m_stop, | 2645 | .stop = m_stop, |
| 2686 | .show = m_show | 2646 | .show = m_show |
| 2687 | }; | 2647 | }; |
| 2688 | 2648 | ||
| 2649 | static int modules_open(struct inode *inode, struct file *file) | ||
| 2650 | { | ||
| 2651 | return seq_open(file, &modules_op); | ||
| 2652 | } | ||
| 2653 | |||
| 2654 | static const struct file_operations proc_modules_operations = { | ||
| 2655 | .open = modules_open, | ||
| 2656 | .read = seq_read, | ||
| 2657 | .llseek = seq_lseek, | ||
| 2658 | .release = seq_release, | ||
| 2659 | }; | ||
| 2660 | |||
| 2661 | static int __init proc_modules_init(void) | ||
| 2662 | { | ||
| 2663 | proc_create("modules", 0, NULL, &proc_modules_operations); | ||
| 2664 | return 0; | ||
| 2665 | } | ||
| 2666 | module_init(proc_modules_init); | ||
| 2667 | #endif | ||
| 2668 | |||
| 2689 | /* Given an address, look for it in the module exception tables. */ | 2669 | /* Given an address, look for it in the module exception tables. */ |
| 2690 | const struct exception_table_entry *search_module_extables(unsigned long addr) | 2670 | const struct exception_table_entry *search_module_extables(unsigned long addr) |
| 2691 | { | 2671 | { |
| @@ -2693,7 +2673,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) | |||
| 2693 | struct module *mod; | 2673 | struct module *mod; |
| 2694 | 2674 | ||
| 2695 | preempt_disable(); | 2675 | preempt_disable(); |
| 2696 | list_for_each_entry(mod, &modules, list) { | 2676 | list_for_each_entry_rcu(mod, &modules, list) { |
| 2697 | if (mod->num_exentries == 0) | 2677 | if (mod->num_exentries == 0) |
| 2698 | continue; | 2678 | continue; |
| 2699 | 2679 | ||
| @@ -2719,7 +2699,7 @@ int is_module_address(unsigned long addr) | |||
| 2719 | 2699 | ||
| 2720 | preempt_disable(); | 2700 | preempt_disable(); |
| 2721 | 2701 | ||
| 2722 | list_for_each_entry(mod, &modules, list) { | 2702 | list_for_each_entry_rcu(mod, &modules, list) { |
| 2723 | if (within(addr, mod->module_core, mod->core_size)) { | 2703 | if (within(addr, mod->module_core, mod->core_size)) { |
| 2724 | preempt_enable(); | 2704 | preempt_enable(); |
| 2725 | return 1; | 2705 | return 1; |
| @@ -2740,7 +2720,7 @@ struct module *__module_text_address(unsigned long addr) | |||
| 2740 | if (addr < module_addr_min || addr > module_addr_max) | 2720 | if (addr < module_addr_min || addr > module_addr_max) |
| 2741 | return NULL; | 2721 | return NULL; |
| 2742 | 2722 | ||
| 2743 | list_for_each_entry(mod, &modules, list) | 2723 | list_for_each_entry_rcu(mod, &modules, list) |
| 2744 | if (within(addr, mod->module_init, mod->init_text_size) | 2724 | if (within(addr, mod->module_init, mod->init_text_size) |
| 2745 | || within(addr, mod->module_core, mod->core_text_size)) | 2725 | || within(addr, mod->module_core, mod->core_text_size)) |
| 2746 | return mod; | 2726 | return mod; |
| @@ -2765,8 +2745,11 @@ void print_modules(void) | |||
| 2765 | char buf[8]; | 2745 | char buf[8]; |
| 2766 | 2746 | ||
| 2767 | printk("Modules linked in:"); | 2747 | printk("Modules linked in:"); |
| 2768 | list_for_each_entry(mod, &modules, list) | 2748 | /* Most callers should already have preempt disabled, but make sure */ |
| 2749 | preempt_disable(); | ||
| 2750 | list_for_each_entry_rcu(mod, &modules, list) | ||
| 2769 | printk(" %s%s", mod->name, module_flags(mod, buf)); | 2751 | printk(" %s%s", mod->name, module_flags(mod, buf)); |
| 2752 | preempt_enable(); | ||
| 2770 | if (last_unloaded_module[0]) | 2753 | if (last_unloaded_module[0]) |
| 2771 | printk(" [last unloaded: %s]", last_unloaded_module); | 2754 | printk(" [last unloaded: %s]", last_unloaded_module); |
| 2772 | printk("\n"); | 2755 | printk("\n"); |
