|
10 | 10 | #include <linux/vmalloc.h>
|
11 | 11 | #include <linux/mm.h>
|
12 | 12 | #include <linux/bug.h>
|
| 13 | +#include <linux/execmem.h> |
13 | 14 | #include <asm/module.h>
|
14 | 15 | #include <linux/uaccess.h>
|
15 | 16 | #include <asm/firmware.h>
|
@@ -89,39 +90,56 @@ int module_finalize(const Elf_Ehdr *hdr,
|
89 | 90 | return 0;
|
90 | 91 | }
|
91 | 92 |
|
92 |
| -static __always_inline void * |
93 |
| -__module_alloc(unsigned long size, unsigned long start, unsigned long end, bool nowarn) |
| 93 | +static struct execmem_info execmem_info __ro_after_init; |
| 94 | + |
| 95 | +struct execmem_info __init *execmem_arch_setup(void) |
94 | 96 | {
|
95 | 97 | pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : PAGE_KERNEL_EXEC;
|
96 |
| - gfp_t gfp = GFP_KERNEL | (nowarn ? __GFP_NOWARN : 0); |
| 98 | + unsigned long fallback_start = 0, fallback_end = 0; |
| 99 | + unsigned long start, end; |
97 | 100 |
|
98 | 101 | /*
|
99 |
| - * Don't do huge page allocations for modules yet until more testing |
100 |
| - * is done. STRICT_MODULE_RWX may require extra work to support this |
101 |
| - * too. |
| 102 | + * BOOK3S_32 and 8xx define MODULES_VADDR for text allocations and |
| 103 | + * allow allocating data in the entire vmalloc space |
102 | 104 | */
|
103 |
| - return __vmalloc_node_range(size, 1, start, end, gfp, prot, |
104 |
| - VM_FLUSH_RESET_PERMS, |
105 |
| - NUMA_NO_NODE, __builtin_return_address(0)); |
106 |
| -} |
107 |
| - |
108 |
| -void *module_alloc(unsigned long size) |
109 |
| -{ |
110 | 105 | #ifdef MODULES_VADDR
|
111 | 106 | unsigned long limit = (unsigned long)_etext - SZ_32M;
|
112 |
| - void *ptr = NULL; |
113 | 107 |
|
114 | 108 | BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
|
115 | 109 |
|
116 | 110 | /* First try within 32M limit from _etext to avoid branch trampolines */
|
117 |
| - if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit) |
118 |
| - ptr = __module_alloc(size, limit, MODULES_END, true); |
119 |
| - |
120 |
| - if (!ptr) |
121 |
| - ptr = __module_alloc(size, MODULES_VADDR, MODULES_END, false); |
| 111 | + if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit) { |
| 112 | + start = limit; |
| 113 | + fallback_start = MODULES_VADDR; |
| 114 | + fallback_end = MODULES_END; |
| 115 | + } else { |
| 116 | + start = MODULES_VADDR; |
| 117 | + } |
122 | 118 |
|
123 |
| - return ptr; |
| 119 | + end = MODULES_END; |
124 | 120 | #else
|
125 |
| - return __module_alloc(size, VMALLOC_START, VMALLOC_END, false); |
| 121 | + start = VMALLOC_START; |
| 122 | + end = VMALLOC_END; |
126 | 123 | #endif
|
| 124 | + |
| 125 | + execmem_info = (struct execmem_info){ |
| 126 | + .ranges = { |
| 127 | + [EXECMEM_DEFAULT] = { |
| 128 | + .start = start, |
| 129 | + .end = end, |
| 130 | + .pgprot = prot, |
| 131 | + .alignment = 1, |
| 132 | + .fallback_start = fallback_start, |
| 133 | + .fallback_end = fallback_end, |
| 134 | + }, |
| 135 | + [EXECMEM_MODULE_DATA] = { |
| 136 | + .start = VMALLOC_START, |
| 137 | + .end = VMALLOC_END, |
| 138 | + .pgprot = PAGE_KERNEL, |
| 139 | + .alignment = 1, |
| 140 | + }, |
| 141 | + }, |
| 142 | + }; |
| 143 | + |
| 144 | + return &execmem_info; |
127 | 145 | }
|
0 commit comments