diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 349 |
1 files changed, 165 insertions, 184 deletions
diff --git a/kernel/module.c b/kernel/module.c index 38c7bd5583ff..8358f4697c0c 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -80,15 +80,6 @@ | |||
80 | # define debug_align(X) (X) | 80 | # define debug_align(X) (X) |
81 | #endif | 81 | #endif |
82 | 82 | ||
83 | /* | ||
84 | * Given BASE and SIZE this macro calculates the number of pages the | ||
85 | * memory regions occupies | ||
86 | */ | ||
87 | #define MOD_NUMBER_OF_PAGES(BASE, SIZE) (((SIZE) > 0) ? \ | ||
88 | (PFN_DOWN((unsigned long)(BASE) + (SIZE) - 1) - \ | ||
89 | PFN_DOWN((unsigned long)BASE) + 1) \ | ||
90 | : (0UL)) | ||
91 | |||
92 | /* If this is set, the section belongs in the init part of the module */ | 83 | /* If this is set, the section belongs in the init part of the module */ |
93 | #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) | 84 | #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) |
94 | 85 | ||
@@ -108,13 +99,6 @@ static LIST_HEAD(modules); | |||
108 | * Use a latched RB-tree for __module_address(); this allows us to use | 99 | * Use a latched RB-tree for __module_address(); this allows us to use |
109 | * RCU-sched lookups of the address from any context. | 100 | * RCU-sched lookups of the address from any context. |
110 | * | 101 | * |
111 | * Because modules have two address ranges: init and core, we need two | ||
112 | * latch_tree_nodes entries. Therefore we need the back-pointer from | ||
113 | * mod_tree_node. | ||
114 | * | ||
115 | * Because init ranges are short lived we mark them unlikely and have placed | ||
116 | * them outside the critical cacheline in struct module. | ||
117 | * | ||
118 | * This is conditional on PERF_EVENTS || TRACING because those can really hit | 102 | * This is conditional on PERF_EVENTS || TRACING because those can really hit |
119 | * __module_address() hard by doing a lot of stack unwinding; potentially from | 103 | * __module_address() hard by doing a lot of stack unwinding; potentially from |
120 | * NMI context. | 104 | * NMI context. |
@@ -122,24 +106,16 @@ static LIST_HEAD(modules); | |||
122 | 106 | ||
123 | static __always_inline unsigned long __mod_tree_val(struct latch_tree_node *n) | 107 | static __always_inline unsigned long __mod_tree_val(struct latch_tree_node *n) |
124 | { | 108 | { |
125 | struct mod_tree_node *mtn = container_of(n, struct mod_tree_node, node); | 109 | struct module_layout *layout = container_of(n, struct module_layout, mtn.node); |
126 | struct module *mod = mtn->mod; | ||
127 | 110 | ||
128 | if (unlikely(mtn == &mod->mtn_init)) | 111 | return (unsigned long)layout->base; |
129 | return (unsigned long)mod->module_init; | ||
130 | |||
131 | return (unsigned long)mod->module_core; | ||
132 | } | 112 | } |
133 | 113 | ||
134 | static __always_inline unsigned long __mod_tree_size(struct latch_tree_node *n) | 114 | static __always_inline unsigned long __mod_tree_size(struct latch_tree_node *n) |
135 | { | 115 | { |
136 | struct mod_tree_node *mtn = container_of(n, struct mod_tree_node, node); | 116 | struct module_layout *layout = container_of(n, struct module_layout, mtn.node); |
137 | struct module *mod = mtn->mod; | ||
138 | |||
139 | if (unlikely(mtn == &mod->mtn_init)) | ||
140 | return (unsigned long)mod->init_size; | ||
141 | 117 | ||
142 | return (unsigned long)mod->core_size; | 118 | return (unsigned long)layout->size; |
143 | } | 119 | } |
144 | 120 | ||
145 | static __always_inline bool | 121 | static __always_inline bool |
@@ -197,23 +173,23 @@ static void __mod_tree_remove(struct mod_tree_node *node) | |||
197 | */ | 173 | */ |
198 | static void mod_tree_insert(struct module *mod) | 174 | static void mod_tree_insert(struct module *mod) |
199 | { | 175 | { |
200 | mod->mtn_core.mod = mod; | 176 | mod->core_layout.mtn.mod = mod; |
201 | mod->mtn_init.mod = mod; | 177 | mod->init_layout.mtn.mod = mod; |
202 | 178 | ||
203 | __mod_tree_insert(&mod->mtn_core); | 179 | __mod_tree_insert(&mod->core_layout.mtn); |
204 | if (mod->init_size) | 180 | if (mod->init_layout.size) |
205 | __mod_tree_insert(&mod->mtn_init); | 181 | __mod_tree_insert(&mod->init_layout.mtn); |
206 | } | 182 | } |
207 | 183 | ||
208 | static void mod_tree_remove_init(struct module *mod) | 184 | static void mod_tree_remove_init(struct module *mod) |
209 | { | 185 | { |
210 | if (mod->init_size) | 186 | if (mod->init_layout.size) |
211 | __mod_tree_remove(&mod->mtn_init); | 187 | __mod_tree_remove(&mod->init_layout.mtn); |
212 | } | 188 | } |
213 | 189 | ||
214 | static void mod_tree_remove(struct module *mod) | 190 | static void mod_tree_remove(struct module *mod) |
215 | { | 191 | { |
216 | __mod_tree_remove(&mod->mtn_core); | 192 | __mod_tree_remove(&mod->core_layout.mtn); |
217 | mod_tree_remove_init(mod); | 193 | mod_tree_remove_init(mod); |
218 | } | 194 | } |
219 | 195 | ||
@@ -267,9 +243,9 @@ static void __mod_update_bounds(void *base, unsigned int size) | |||
267 | 243 | ||
268 | static void mod_update_bounds(struct module *mod) | 244 | static void mod_update_bounds(struct module *mod) |
269 | { | 245 | { |
270 | __mod_update_bounds(mod->module_core, mod->core_size); | 246 | __mod_update_bounds(mod->core_layout.base, mod->core_layout.size); |
271 | if (mod->init_size) | 247 | if (mod->init_layout.size) |
272 | __mod_update_bounds(mod->module_init, mod->init_size); | 248 | __mod_update_bounds(mod->init_layout.base, mod->init_layout.size); |
273 | } | 249 | } |
274 | 250 | ||
275 | #ifdef CONFIG_KGDB_KDB | 251 | #ifdef CONFIG_KGDB_KDB |
@@ -1214,7 +1190,7 @@ struct module_attribute module_uevent = | |||
1214 | static ssize_t show_coresize(struct module_attribute *mattr, | 1190 | static ssize_t show_coresize(struct module_attribute *mattr, |
1215 | struct module_kobject *mk, char *buffer) | 1191 | struct module_kobject *mk, char *buffer) |
1216 | { | 1192 | { |
1217 | return sprintf(buffer, "%u\n", mk->mod->core_size); | 1193 | return sprintf(buffer, "%u\n", mk->mod->core_layout.size); |
1218 | } | 1194 | } |
1219 | 1195 | ||
1220 | static struct module_attribute modinfo_coresize = | 1196 | static struct module_attribute modinfo_coresize = |
@@ -1223,7 +1199,7 @@ static struct module_attribute modinfo_coresize = | |||
1223 | static ssize_t show_initsize(struct module_attribute *mattr, | 1199 | static ssize_t show_initsize(struct module_attribute *mattr, |
1224 | struct module_kobject *mk, char *buffer) | 1200 | struct module_kobject *mk, char *buffer) |
1225 | { | 1201 | { |
1226 | return sprintf(buffer, "%u\n", mk->mod->init_size); | 1202 | return sprintf(buffer, "%u\n", mk->mod->init_layout.size); |
1227 | } | 1203 | } |
1228 | 1204 | ||
1229 | static struct module_attribute modinfo_initsize = | 1205 | static struct module_attribute modinfo_initsize = |
@@ -1873,64 +1849,75 @@ static void mod_sysfs_teardown(struct module *mod) | |||
1873 | /* | 1849 | /* |
1874 | * LKM RO/NX protection: protect module's text/ro-data | 1850 | * LKM RO/NX protection: protect module's text/ro-data |
1875 | * from modification and any data from execution. | 1851 | * from modification and any data from execution. |
1852 | * | ||
1853 | * General layout of module is: | ||
1854 | * [text] [read-only-data] [writable data] | ||
1855 | * text_size -----^ ^ ^ | ||
1856 | * ro_size ------------------------| | | ||
1857 | * size -------------------------------------------| | ||
1858 | * | ||
1859 | * These values are always page-aligned (as is base) | ||
1876 | */ | 1860 | */ |
1877 | void set_page_attributes(void *start, void *end, int (*set)(unsigned long start, int num_pages)) | 1861 | static void frob_text(const struct module_layout *layout, |
1862 | int (*set_memory)(unsigned long start, int num_pages)) | ||
1878 | { | 1863 | { |
1879 | unsigned long begin_pfn = PFN_DOWN((unsigned long)start); | 1864 | BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); |
1880 | unsigned long end_pfn = PFN_DOWN((unsigned long)end); | 1865 | BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); |
1866 | set_memory((unsigned long)layout->base, | ||
1867 | layout->text_size >> PAGE_SHIFT); | ||
1868 | } | ||
1881 | 1869 | ||
1882 | if (end_pfn > begin_pfn) | 1870 | static void frob_rodata(const struct module_layout *layout, |
1883 | set(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn); | 1871 | int (*set_memory)(unsigned long start, int num_pages)) |
1872 | { | ||
1873 | BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); | ||
1874 | BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); | ||
1875 | BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); | ||
1876 | set_memory((unsigned long)layout->base + layout->text_size, | ||
1877 | (layout->ro_size - layout->text_size) >> PAGE_SHIFT); | ||
1884 | } | 1878 | } |
1885 | 1879 | ||
1886 | static void set_section_ro_nx(void *base, | 1880 | static void frob_writable_data(const struct module_layout *layout, |
1887 | unsigned long text_size, | 1881 | int (*set_memory)(unsigned long start, int num_pages)) |
1888 | unsigned long ro_size, | ||
1889 | unsigned long total_size) | ||
1890 | { | 1882 | { |
1891 | /* begin and end PFNs of the current subsection */ | 1883 | BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); |
1892 | unsigned long begin_pfn; | 1884 | BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); |
1893 | unsigned long end_pfn; | 1885 | BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1)); |
1886 | set_memory((unsigned long)layout->base + layout->ro_size, | ||
1887 | (layout->size - layout->ro_size) >> PAGE_SHIFT); | ||
1888 | } | ||
1894 | 1889 | ||
1895 | /* | 1890 | /* livepatching wants to disable read-only so it can frob module. */ |
1896 | * Set RO for module text and RO-data: | 1891 | void module_disable_ro(const struct module *mod) |
1897 | * - Always protect first page. | 1892 | { |
1898 | * - Do not protect last partial page. | 1893 | frob_text(&mod->core_layout, set_memory_rw); |
1899 | */ | 1894 | frob_rodata(&mod->core_layout, set_memory_rw); |
1900 | if (ro_size > 0) | 1895 | frob_text(&mod->init_layout, set_memory_rw); |
1901 | set_page_attributes(base, base + ro_size, set_memory_ro); | 1896 | frob_rodata(&mod->init_layout, set_memory_rw); |
1897 | } | ||
1902 | 1898 | ||
1903 | /* | 1899 | void module_enable_ro(const struct module *mod) |
1904 | * Set NX permissions for module data: | 1900 | { |
1905 | * - Do not protect first partial page. | 1901 | frob_text(&mod->core_layout, set_memory_ro); |
1906 | * - Always protect last page. | 1902 | frob_rodata(&mod->core_layout, set_memory_ro); |
1907 | */ | 1903 | frob_text(&mod->init_layout, set_memory_ro); |
1908 | if (total_size > text_size) { | 1904 | frob_rodata(&mod->init_layout, set_memory_ro); |
1909 | begin_pfn = PFN_UP((unsigned long)base + text_size); | ||
1910 | end_pfn = PFN_UP((unsigned long)base + total_size); | ||
1911 | if (end_pfn > begin_pfn) | ||
1912 | set_memory_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn); | ||
1913 | } | ||
1914 | } | 1905 | } |
1915 | 1906 | ||
1916 | static void unset_module_core_ro_nx(struct module *mod) | 1907 | static void module_enable_nx(const struct module *mod) |
1917 | { | 1908 | { |
1918 | set_page_attributes(mod->module_core + mod->core_text_size, | 1909 | frob_rodata(&mod->core_layout, set_memory_nx); |
1919 | mod->module_core + mod->core_size, | 1910 | frob_writable_data(&mod->core_layout, set_memory_nx); |
1920 | set_memory_x); | 1911 | frob_rodata(&mod->init_layout, set_memory_nx); |
1921 | set_page_attributes(mod->module_core, | 1912 | frob_writable_data(&mod->init_layout, set_memory_nx); |
1922 | mod->module_core + mod->core_ro_size, | ||
1923 | set_memory_rw); | ||
1924 | } | 1913 | } |
1925 | 1914 | ||
1926 | static void unset_module_init_ro_nx(struct module *mod) | 1915 | static void module_disable_nx(const struct module *mod) |
1927 | { | 1916 | { |
1928 | set_page_attributes(mod->module_init + mod->init_text_size, | 1917 | frob_rodata(&mod->core_layout, set_memory_x); |
1929 | mod->module_init + mod->init_size, | 1918 | frob_writable_data(&mod->core_layout, set_memory_x); |
1930 | set_memory_x); | 1919 | frob_rodata(&mod->init_layout, set_memory_x); |
1931 | set_page_attributes(mod->module_init, | 1920 | frob_writable_data(&mod->init_layout, set_memory_x); |
1932 | mod->module_init + mod->init_ro_size, | ||
1933 | set_memory_rw); | ||
1934 | } | 1921 | } |
1935 | 1922 | ||
1936 | /* Iterate through all modules and set each module's text as RW */ | 1923 | /* Iterate through all modules and set each module's text as RW */ |
@@ -1942,16 +1929,9 @@ void set_all_modules_text_rw(void) | |||
1942 | list_for_each_entry_rcu(mod, &modules, list) { | 1929 | list_for_each_entry_rcu(mod, &modules, list) { |
1943 | if (mod->state == MODULE_STATE_UNFORMED) | 1930 | if (mod->state == MODULE_STATE_UNFORMED) |
1944 | continue; | 1931 | continue; |
1945 | if ((mod->module_core) && (mod->core_text_size)) { | 1932 | |
1946 | set_page_attributes(mod->module_core, | 1933 | frob_text(&mod->core_layout, set_memory_rw); |
1947 | mod->module_core + mod->core_text_size, | 1934 | frob_text(&mod->init_layout, set_memory_rw); |
1948 | set_memory_rw); | ||
1949 | } | ||
1950 | if ((mod->module_init) && (mod->init_text_size)) { | ||
1951 | set_page_attributes(mod->module_init, | ||
1952 | mod->module_init + mod->init_text_size, | ||
1953 | set_memory_rw); | ||
1954 | } | ||
1955 | } | 1935 | } |
1956 | mutex_unlock(&module_mutex); | 1936 | mutex_unlock(&module_mutex); |
1957 | } | 1937 | } |
@@ -1965,23 +1945,25 @@ void set_all_modules_text_ro(void) | |||
1965 | list_for_each_entry_rcu(mod, &modules, list) { | 1945 | list_for_each_entry_rcu(mod, &modules, list) { |
1966 | if (mod->state == MODULE_STATE_UNFORMED) | 1946 | if (mod->state == MODULE_STATE_UNFORMED) |
1967 | continue; | 1947 | continue; |
1968 | if ((mod->module_core) && (mod->core_text_size)) { | 1948 | |
1969 | set_page_attributes(mod->module_core, | 1949 | frob_text(&mod->core_layout, set_memory_ro); |
1970 | mod->module_core + mod->core_text_size, | 1950 | frob_text(&mod->init_layout, set_memory_ro); |
1971 | set_memory_ro); | ||
1972 | } | ||
1973 | if ((mod->module_init) && (mod->init_text_size)) { | ||
1974 | set_page_attributes(mod->module_init, | ||
1975 | mod->module_init + mod->init_text_size, | ||
1976 | set_memory_ro); | ||
1977 | } | ||
1978 | } | 1951 | } |
1979 | mutex_unlock(&module_mutex); | 1952 | mutex_unlock(&module_mutex); |
1980 | } | 1953 | } |
1954 | |||
1955 | static void disable_ro_nx(const struct module_layout *layout) | ||
1956 | { | ||
1957 | frob_text(layout, set_memory_rw); | ||
1958 | frob_rodata(layout, set_memory_rw); | ||
1959 | frob_rodata(layout, set_memory_x); | ||
1960 | frob_writable_data(layout, set_memory_x); | ||
1961 | } | ||
1962 | |||
1981 | #else | 1963 | #else |
1982 | static inline void set_section_ro_nx(void *base, unsigned long text_size, unsigned long ro_size, unsigned long total_size) { } | 1964 | static void disable_ro_nx(const struct module_layout *layout) { } |
1983 | static void unset_module_core_ro_nx(struct module *mod) { } | 1965 | static void module_enable_nx(const struct module *mod) { } |
1984 | static void unset_module_init_ro_nx(struct module *mod) { } | 1966 | static void module_disable_nx(const struct module *mod) { } |
1985 | #endif | 1967 | #endif |
1986 | 1968 | ||
1987 | void __weak module_memfree(void *module_region) | 1969 | void __weak module_memfree(void *module_region) |
@@ -2033,19 +2015,19 @@ static void free_module(struct module *mod) | |||
2033 | synchronize_sched(); | 2015 | synchronize_sched(); |
2034 | mutex_unlock(&module_mutex); | 2016 | mutex_unlock(&module_mutex); |
2035 | 2017 | ||
2036 | /* This may be NULL, but that's OK */ | 2018 | /* This may be empty, but that's OK */ |
2037 | unset_module_init_ro_nx(mod); | 2019 | disable_ro_nx(&mod->init_layout); |
2038 | module_arch_freeing_init(mod); | 2020 | module_arch_freeing_init(mod); |
2039 | module_memfree(mod->module_init); | 2021 | module_memfree(mod->init_layout.base); |
2040 | kfree(mod->args); | 2022 | kfree(mod->args); |
2041 | percpu_modfree(mod); | 2023 | percpu_modfree(mod); |
2042 | 2024 | ||
2043 | /* Free lock-classes; relies on the preceding sync_rcu(). */ | 2025 | /* Free lock-classes; relies on the preceding sync_rcu(). */ |
2044 | lockdep_free_key_range(mod->module_core, mod->core_size); | 2026 | lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); |
2045 | 2027 | ||
2046 | /* Finally, free the core (containing the module structure) */ | 2028 | /* Finally, free the core (containing the module structure) */ |
2047 | unset_module_core_ro_nx(mod); | 2029 | disable_ro_nx(&mod->core_layout); |
2048 | module_memfree(mod->module_core); | 2030 | module_memfree(mod->core_layout.base); |
2049 | 2031 | ||
2050 | #ifdef CONFIG_MPU | 2032 | #ifdef CONFIG_MPU |
2051 | update_protections(current->mm); | 2033 | update_protections(current->mm); |
@@ -2248,20 +2230,20 @@ static void layout_sections(struct module *mod, struct load_info *info) | |||
2248 | || s->sh_entsize != ~0UL | 2230 | || s->sh_entsize != ~0UL |
2249 | || strstarts(sname, ".init")) | 2231 | || strstarts(sname, ".init")) |
2250 | continue; | 2232 | continue; |
2251 | s->sh_entsize = get_offset(mod, &mod->core_size, s, i); | 2233 | s->sh_entsize = get_offset(mod, &mod->core_layout.size, s, i); |
2252 | pr_debug("\t%s\n", sname); | 2234 | pr_debug("\t%s\n", sname); |
2253 | } | 2235 | } |
2254 | switch (m) { | 2236 | switch (m) { |
2255 | case 0: /* executable */ | 2237 | case 0: /* executable */ |
2256 | mod->core_size = debug_align(mod->core_size); | 2238 | mod->core_layout.size = debug_align(mod->core_layout.size); |
2257 | mod->core_text_size = mod->core_size; | 2239 | mod->core_layout.text_size = mod->core_layout.size; |
2258 | break; | 2240 | break; |
2259 | case 1: /* RO: text and ro-data */ | 2241 | case 1: /* RO: text and ro-data */ |
2260 | mod->core_size = debug_align(mod->core_size); | 2242 | mod->core_layout.size = debug_align(mod->core_layout.size); |
2261 | mod->core_ro_size = mod->core_size; | 2243 | mod->core_layout.ro_size = mod->core_layout.size; |
2262 | break; | 2244 | break; |
2263 | case 3: /* whole core */ | 2245 | case 3: /* whole core */ |
2264 | mod->core_size = debug_align(mod->core_size); | 2246 | mod->core_layout.size = debug_align(mod->core_layout.size); |
2265 | break; | 2247 | break; |
2266 | } | 2248 | } |
2267 | } | 2249 | } |
@@ -2277,21 +2259,21 @@ static void layout_sections(struct module *mod, struct load_info *info) | |||
2277 | || s->sh_entsize != ~0UL | 2259 | || s->sh_entsize != ~0UL |
2278 | || !strstarts(sname, ".init")) | 2260 | || !strstarts(sname, ".init")) |
2279 | continue; | 2261 | continue; |
2280 | s->sh_entsize = (get_offset(mod, &mod->init_size, s, i) | 2262 | s->sh_entsize = (get_offset(mod, &mod->init_layout.size, s, i) |
2281 | | INIT_OFFSET_MASK); | 2263 | | INIT_OFFSET_MASK); |
2282 | pr_debug("\t%s\n", sname); | 2264 | pr_debug("\t%s\n", sname); |
2283 | } | 2265 | } |
2284 | switch (m) { | 2266 | switch (m) { |
2285 | case 0: /* executable */ | 2267 | case 0: /* executable */ |
2286 | mod->init_size = debug_align(mod->init_size); | 2268 | mod->init_layout.size = debug_align(mod->init_layout.size); |
2287 | mod->init_text_size = mod->init_size; | 2269 | mod->init_layout.text_size = mod->init_layout.size; |
2288 | break; | 2270 | break; |
2289 | case 1: /* RO: text and ro-data */ | 2271 | case 1: /* RO: text and ro-data */ |
2290 | mod->init_size = debug_align(mod->init_size); | 2272 | mod->init_layout.size = debug_align(mod->init_layout.size); |
2291 | mod->init_ro_size = mod->init_size; | 2273 | mod->init_layout.ro_size = mod->init_layout.size; |
2292 | break; | 2274 | break; |
2293 | case 3: /* whole init */ | 2275 | case 3: /* whole init */ |
2294 | mod->init_size = debug_align(mod->init_size); | 2276 | mod->init_layout.size = debug_align(mod->init_layout.size); |
2295 | break; | 2277 | break; |
2296 | } | 2278 | } |
2297 | } | 2279 | } |
@@ -2401,7 +2383,7 @@ static char elf_type(const Elf_Sym *sym, const struct load_info *info) | |||
2401 | } | 2383 | } |
2402 | if (sym->st_shndx == SHN_UNDEF) | 2384 | if (sym->st_shndx == SHN_UNDEF) |
2403 | return 'U'; | 2385 | return 'U'; |
2404 | if (sym->st_shndx == SHN_ABS) | 2386 | if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu) |
2405 | return 'a'; | 2387 | return 'a'; |
2406 | if (sym->st_shndx >= SHN_LORESERVE) | 2388 | if (sym->st_shndx >= SHN_LORESERVE) |
2407 | return '?'; | 2389 | return '?'; |
@@ -2430,7 +2412,7 @@ static char elf_type(const Elf_Sym *sym, const struct load_info *info) | |||
2430 | } | 2412 | } |
2431 | 2413 | ||
2432 | static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, | 2414 | static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, |
2433 | unsigned int shnum) | 2415 | unsigned int shnum, unsigned int pcpundx) |
2434 | { | 2416 | { |
2435 | const Elf_Shdr *sec; | 2417 | const Elf_Shdr *sec; |
2436 | 2418 | ||
@@ -2439,6 +2421,11 @@ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, | |||
2439 | || !src->st_name) | 2421 | || !src->st_name) |
2440 | return false; | 2422 | return false; |
2441 | 2423 | ||
2424 | #ifdef CONFIG_KALLSYMS_ALL | ||
2425 | if (src->st_shndx == pcpundx) | ||
2426 | return true; | ||
2427 | #endif | ||
2428 | |||
2442 | sec = sechdrs + src->st_shndx; | 2429 | sec = sechdrs + src->st_shndx; |
2443 | if (!(sec->sh_flags & SHF_ALLOC) | 2430 | if (!(sec->sh_flags & SHF_ALLOC) |
2444 | #ifndef CONFIG_KALLSYMS_ALL | 2431 | #ifndef CONFIG_KALLSYMS_ALL |
@@ -2466,7 +2453,7 @@ static void layout_symtab(struct module *mod, struct load_info *info) | |||
2466 | 2453 | ||
2467 | /* Put symbol section at end of init part of module. */ | 2454 | /* Put symbol section at end of init part of module. */ |
2468 | symsect->sh_flags |= SHF_ALLOC; | 2455 | symsect->sh_flags |= SHF_ALLOC; |
2469 | symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect, | 2456 | symsect->sh_entsize = get_offset(mod, &mod->init_layout.size, symsect, |
2470 | info->index.sym) | INIT_OFFSET_MASK; | 2457 | info->index.sym) | INIT_OFFSET_MASK; |
2471 | pr_debug("\t%s\n", info->secstrings + symsect->sh_name); | 2458 | pr_debug("\t%s\n", info->secstrings + symsect->sh_name); |
2472 | 2459 | ||
@@ -2476,23 +2463,24 @@ static void layout_symtab(struct module *mod, struct load_info *info) | |||
2476 | /* Compute total space required for the core symbols' strtab. */ | 2463 | /* Compute total space required for the core symbols' strtab. */ |
2477 | for (ndst = i = 0; i < nsrc; i++) { | 2464 | for (ndst = i = 0; i < nsrc; i++) { |
2478 | if (i == 0 || | 2465 | if (i == 0 || |
2479 | is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { | 2466 | is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, |
2467 | info->index.pcpu)) { | ||
2480 | strtab_size += strlen(&info->strtab[src[i].st_name])+1; | 2468 | strtab_size += strlen(&info->strtab[src[i].st_name])+1; |
2481 | ndst++; | 2469 | ndst++; |
2482 | } | 2470 | } |
2483 | } | 2471 | } |
2484 | 2472 | ||
2485 | /* Append room for core symbols at end of core part. */ | 2473 | /* Append room for core symbols at end of core part. */ |
2486 | info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); | 2474 | info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1); |
2487 | info->stroffs = mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym); | 2475 | info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym); |
2488 | mod->core_size += strtab_size; | 2476 | mod->core_layout.size += strtab_size; |
2489 | mod->core_size = debug_align(mod->core_size); | 2477 | mod->core_layout.size = debug_align(mod->core_layout.size); |
2490 | 2478 | ||
2491 | /* Put string table section at end of init part of module. */ | 2479 | /* Put string table section at end of init part of module. */ |
2492 | strsect->sh_flags |= SHF_ALLOC; | 2480 | strsect->sh_flags |= SHF_ALLOC; |
2493 | strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect, | 2481 | strsect->sh_entsize = get_offset(mod, &mod->init_layout.size, strsect, |
2494 | info->index.str) | INIT_OFFSET_MASK; | 2482 | info->index.str) | INIT_OFFSET_MASK; |
2495 | mod->init_size = debug_align(mod->init_size); | 2483 | mod->init_layout.size = debug_align(mod->init_layout.size); |
2496 | pr_debug("\t%s\n", info->secstrings + strsect->sh_name); | 2484 | pr_debug("\t%s\n", info->secstrings + strsect->sh_name); |
2497 | } | 2485 | } |
2498 | 2486 | ||
@@ -2513,12 +2501,13 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) | |||
2513 | for (i = 0; i < mod->num_symtab; i++) | 2501 | for (i = 0; i < mod->num_symtab; i++) |
2514 | mod->symtab[i].st_info = elf_type(&mod->symtab[i], info); | 2502 | mod->symtab[i].st_info = elf_type(&mod->symtab[i], info); |
2515 | 2503 | ||
2516 | mod->core_symtab = dst = mod->module_core + info->symoffs; | 2504 | mod->core_symtab = dst = mod->core_layout.base + info->symoffs; |
2517 | mod->core_strtab = s = mod->module_core + info->stroffs; | 2505 | mod->core_strtab = s = mod->core_layout.base + info->stroffs; |
2518 | src = mod->symtab; | 2506 | src = mod->symtab; |
2519 | for (ndst = i = 0; i < mod->num_symtab; i++) { | 2507 | for (ndst = i = 0; i < mod->num_symtab; i++) { |
2520 | if (i == 0 || | 2508 | if (i == 0 || |
2521 | is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { | 2509 | is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, |
2510 | info->index.pcpu)) { | ||
2522 | dst[ndst] = src[i]; | 2511 | dst[ndst] = src[i]; |
2523 | dst[ndst++].st_name = s - mod->core_strtab; | 2512 | dst[ndst++].st_name = s - mod->core_strtab; |
2524 | s += strlcpy(s, &mod->strtab[src[i].st_name], | 2513 | s += strlcpy(s, &mod->strtab[src[i].st_name], |
@@ -2964,7 +2953,7 @@ static int move_module(struct module *mod, struct load_info *info) | |||
2964 | void *ptr; | 2953 | void *ptr; |
2965 | 2954 | ||
2966 | /* Do the allocs. */ | 2955 | /* Do the allocs. */ |
2967 | ptr = module_alloc(mod->core_size); | 2956 | ptr = module_alloc(mod->core_layout.size); |
2968 | /* | 2957 | /* |
2969 | * The pointer to this block is stored in the module structure | 2958 | * The pointer to this block is stored in the module structure |
2970 | * which is inside the block. Just mark it as not being a | 2959 | * which is inside the block. Just mark it as not being a |
@@ -2974,11 +2963,11 @@ static int move_module(struct module *mod, struct load_info *info) | |||
2974 | if (!ptr) | 2963 | if (!ptr) |
2975 | return -ENOMEM; | 2964 | return -ENOMEM; |
2976 | 2965 | ||
2977 | memset(ptr, 0, mod->core_size); | 2966 | memset(ptr, 0, mod->core_layout.size); |
2978 | mod->module_core = ptr; | 2967 | mod->core_layout.base = ptr; |
2979 | 2968 | ||
2980 | if (mod->init_size) { | 2969 | if (mod->init_layout.size) { |
2981 | ptr = module_alloc(mod->init_size); | 2970 | ptr = module_alloc(mod->init_layout.size); |
2982 | /* | 2971 | /* |
2983 | * The pointer to this block is stored in the module structure | 2972 | * The pointer to this block is stored in the module structure |
2984 | * which is inside the block. This block doesn't need to be | 2973 | * which is inside the block. This block doesn't need to be |
@@ -2987,13 +2976,13 @@ static int move_module(struct module *mod, struct load_info *info) | |||
2987 | */ | 2976 | */ |
2988 | kmemleak_ignore(ptr); | 2977 | kmemleak_ignore(ptr); |
2989 | if (!ptr) { | 2978 | if (!ptr) { |
2990 | module_memfree(mod->module_core); | 2979 | module_memfree(mod->core_layout.base); |
2991 | return -ENOMEM; | 2980 | return -ENOMEM; |
2992 | } | 2981 | } |
2993 | memset(ptr, 0, mod->init_size); | 2982 | memset(ptr, 0, mod->init_layout.size); |
2994 | mod->module_init = ptr; | 2983 | mod->init_layout.base = ptr; |
2995 | } else | 2984 | } else |
2996 | mod->module_init = NULL; | 2985 | mod->init_layout.base = NULL; |
2997 | 2986 | ||
2998 | /* Transfer each section which specifies SHF_ALLOC */ | 2987 | /* Transfer each section which specifies SHF_ALLOC */ |
2999 | pr_debug("final section addresses:\n"); | 2988 | pr_debug("final section addresses:\n"); |
@@ -3005,10 +2994,10 @@ static int move_module(struct module *mod, struct load_info *info) | |||
3005 | continue; | 2994 | continue; |
3006 | 2995 | ||
3007 | if (shdr->sh_entsize & INIT_OFFSET_MASK) | 2996 | if (shdr->sh_entsize & INIT_OFFSET_MASK) |
3008 | dest = mod->module_init | 2997 | dest = mod->init_layout.base |
3009 | + (shdr->sh_entsize & ~INIT_OFFSET_MASK); | 2998 | + (shdr->sh_entsize & ~INIT_OFFSET_MASK); |
3010 | else | 2999 | else |
3011 | dest = mod->module_core + shdr->sh_entsize; | 3000 | dest = mod->core_layout.base + shdr->sh_entsize; |
3012 | 3001 | ||
3013 | if (shdr->sh_type != SHT_NOBITS) | 3002 | if (shdr->sh_type != SHT_NOBITS) |
3014 | memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size); | 3003 | memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size); |
@@ -3070,12 +3059,12 @@ static void flush_module_icache(const struct module *mod) | |||
3070 | * Do it before processing of module parameters, so the module | 3059 | * Do it before processing of module parameters, so the module |
3071 | * can provide parameter accessor functions of its own. | 3060 | * can provide parameter accessor functions of its own. |
3072 | */ | 3061 | */ |
3073 | if (mod->module_init) | 3062 | if (mod->init_layout.base) |
3074 | flush_icache_range((unsigned long)mod->module_init, | 3063 | flush_icache_range((unsigned long)mod->init_layout.base, |
3075 | (unsigned long)mod->module_init | 3064 | (unsigned long)mod->init_layout.base |
3076 | + mod->init_size); | 3065 | + mod->init_layout.size); |
3077 | flush_icache_range((unsigned long)mod->module_core, | 3066 | flush_icache_range((unsigned long)mod->core_layout.base, |
3078 | (unsigned long)mod->module_core + mod->core_size); | 3067 | (unsigned long)mod->core_layout.base + mod->core_layout.size); |
3079 | 3068 | ||
3080 | set_fs(old_fs); | 3069 | set_fs(old_fs); |
3081 | } | 3070 | } |
@@ -3133,8 +3122,8 @@ static void module_deallocate(struct module *mod, struct load_info *info) | |||
3133 | { | 3122 | { |
3134 | percpu_modfree(mod); | 3123 | percpu_modfree(mod); |
3135 | module_arch_freeing_init(mod); | 3124 | module_arch_freeing_init(mod); |
3136 | module_memfree(mod->module_init); | 3125 | module_memfree(mod->init_layout.base); |
3137 | module_memfree(mod->module_core); | 3126 | module_memfree(mod->core_layout.base); |
3138 | } | 3127 | } |
3139 | 3128 | ||
3140 | int __weak module_finalize(const Elf_Ehdr *hdr, | 3129 | int __weak module_finalize(const Elf_Ehdr *hdr, |
@@ -3221,7 +3210,7 @@ static noinline int do_init_module(struct module *mod) | |||
3221 | ret = -ENOMEM; | 3210 | ret = -ENOMEM; |
3222 | goto fail; | 3211 | goto fail; |
3223 | } | 3212 | } |
3224 | freeinit->module_init = mod->module_init; | 3213 | freeinit->module_init = mod->init_layout.base; |
3225 | 3214 | ||
3226 | /* | 3215 | /* |
3227 | * We want to find out whether @mod uses async during init. Clear | 3216 | * We want to find out whether @mod uses async during init. Clear |
@@ -3279,12 +3268,12 @@ static noinline int do_init_module(struct module *mod) | |||
3279 | mod->strtab = mod->core_strtab; | 3268 | mod->strtab = mod->core_strtab; |
3280 | #endif | 3269 | #endif |
3281 | mod_tree_remove_init(mod); | 3270 | mod_tree_remove_init(mod); |
3282 | unset_module_init_ro_nx(mod); | 3271 | disable_ro_nx(&mod->init_layout); |
3283 | module_arch_freeing_init(mod); | 3272 | module_arch_freeing_init(mod); |
3284 | mod->module_init = NULL; | 3273 | mod->init_layout.base = NULL; |
3285 | mod->init_size = 0; | 3274 | mod->init_layout.size = 0; |
3286 | mod->init_ro_size = 0; | 3275 | mod->init_layout.ro_size = 0; |
3287 | mod->init_text_size = 0; | 3276 | mod->init_layout.text_size = 0; |
3288 | /* | 3277 | /* |
3289 | * We want to free module_init, but be aware that kallsyms may be | 3278 | * We want to free module_init, but be aware that kallsyms may be |
3290 | * walking this with preempt disabled. In all the failure paths, we | 3279 | * walking this with preempt disabled. In all the failure paths, we |
@@ -3373,17 +3362,9 @@ static int complete_formation(struct module *mod, struct load_info *info) | |||
3373 | /* This relies on module_mutex for list integrity. */ | 3362 | /* This relies on module_mutex for list integrity. */ |
3374 | module_bug_finalize(info->hdr, info->sechdrs, mod); | 3363 | module_bug_finalize(info->hdr, info->sechdrs, mod); |
3375 | 3364 | ||
3376 | /* Set RO and NX regions for core */ | 3365 | /* Set RO and NX regions */ |
3377 | set_section_ro_nx(mod->module_core, | 3366 | module_enable_ro(mod); |
3378 | mod->core_text_size, | 3367 | module_enable_nx(mod); |
3379 | mod->core_ro_size, | ||
3380 | mod->core_size); | ||
3381 | |||
3382 | /* Set RO and NX regions for init */ | ||
3383 | set_section_ro_nx(mod->module_init, | ||
3384 | mod->init_text_size, | ||
3385 | mod->init_ro_size, | ||
3386 | mod->init_size); | ||
3387 | 3368 | ||
3388 | /* Mark state as coming so strong_try_module_get() ignores us, | 3369 | /* Mark state as coming so strong_try_module_get() ignores us, |
3389 | * but kallsyms etc. can see us. */ | 3370 | * but kallsyms etc. can see us. */ |
@@ -3548,8 +3529,8 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
3548 | MODULE_STATE_GOING, mod); | 3529 | MODULE_STATE_GOING, mod); |
3549 | 3530 | ||
3550 | /* we can't deallocate the module until we clear memory protection */ | 3531 | /* we can't deallocate the module until we clear memory protection */ |
3551 | unset_module_init_ro_nx(mod); | 3532 | module_disable_ro(mod); |
3552 | unset_module_core_ro_nx(mod); | 3533 | module_disable_nx(mod); |
3553 | 3534 | ||
3554 | ddebug_cleanup: | 3535 | ddebug_cleanup: |
3555 | dynamic_debug_remove(info->debug); | 3536 | dynamic_debug_remove(info->debug); |
@@ -3578,7 +3559,7 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
3578 | */ | 3559 | */ |
3579 | ftrace_release_mod(mod); | 3560 | ftrace_release_mod(mod); |
3580 | /* Free lock-classes; relies on the preceding sync_rcu() */ | 3561 | /* Free lock-classes; relies on the preceding sync_rcu() */ |
3581 | lockdep_free_key_range(mod->module_core, mod->core_size); | 3562 | lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); |
3582 | 3563 | ||
3583 | module_deallocate(mod, info); | 3564 | module_deallocate(mod, info); |
3584 | free_copy: | 3565 | free_copy: |
@@ -3656,9 +3637,9 @@ static const char *get_ksymbol(struct module *mod, | |||
3656 | 3637 | ||
3657 | /* At worse, next value is at end of module */ | 3638 | /* At worse, next value is at end of module */ |
3658 | if (within_module_init(addr, mod)) | 3639 | if (within_module_init(addr, mod)) |
3659 | nextval = (unsigned long)mod->module_init+mod->init_text_size; | 3640 | nextval = (unsigned long)mod->init_layout.base+mod->init_layout.text_size; |
3660 | else | 3641 | else |
3661 | nextval = (unsigned long)mod->module_core+mod->core_text_size; | 3642 | nextval = (unsigned long)mod->core_layout.base+mod->core_layout.text_size; |
3662 | 3643 | ||
3663 | /* Scan for closest preceding symbol, and next symbol. (ELF | 3644 | /* Scan for closest preceding symbol, and next symbol. (ELF |
3664 | starts real symbols at 1). */ | 3645 | starts real symbols at 1). */ |
@@ -3905,7 +3886,7 @@ static int m_show(struct seq_file *m, void *p) | |||
3905 | return 0; | 3886 | return 0; |
3906 | 3887 | ||
3907 | seq_printf(m, "%s %u", | 3888 | seq_printf(m, "%s %u", |
3908 | mod->name, mod->init_size + mod->core_size); | 3889 | mod->name, mod->init_layout.size + mod->core_layout.size); |
3909 | print_unload_info(m, mod); | 3890 | print_unload_info(m, mod); |
3910 | 3891 | ||
3911 | /* Informative for users. */ | 3892 | /* Informative for users. */ |
@@ -3914,7 +3895,7 @@ static int m_show(struct seq_file *m, void *p) | |||
3914 | mod->state == MODULE_STATE_COMING ? "Loading" : | 3895 | mod->state == MODULE_STATE_COMING ? "Loading" : |
3915 | "Live"); | 3896 | "Live"); |
3916 | /* Used by oprofile and other similar tools. */ | 3897 | /* Used by oprofile and other similar tools. */ |
3917 | seq_printf(m, " 0x%pK", mod->module_core); | 3898 | seq_printf(m, " 0x%pK", mod->core_layout.base); |
3918 | 3899 | ||
3919 | /* Taints info */ | 3900 | /* Taints info */ |
3920 | if (mod->taints) | 3901 | if (mod->taints) |
@@ -4057,8 +4038,8 @@ struct module *__module_text_address(unsigned long addr) | |||
4057 | struct module *mod = __module_address(addr); | 4038 | struct module *mod = __module_address(addr); |
4058 | if (mod) { | 4039 | if (mod) { |
4059 | /* Make sure it's within the text section. */ | 4040 | /* Make sure it's within the text section. */ |
4060 | if (!within(addr, mod->module_init, mod->init_text_size) | 4041 | if (!within(addr, mod->init_layout.base, mod->init_layout.text_size) |
4061 | && !within(addr, mod->module_core, mod->core_text_size)) | 4042 | && !within(addr, mod->core_layout.base, mod->core_layout.text_size)) |
4062 | mod = NULL; | 4043 | mod = NULL; |
4063 | } | 4044 | } |
4064 | return mod; | 4045 | return mod; |