Skip to content

Commit 0cc2dc4

Browse files
rpptmcgrof
authored andcommitted
arch: make execmem setup available regardless of CONFIG_MODULES
execmem does not depend on modules, on the contrary modules use execmem. To make execmem available when CONFIG_MODULES=n, for instance for kprobes, split execmem_params initialization out from arch/*/kernel/module.c and compile it when CONFIG_EXECMEM=y Signed-off-by: Mike Rapoport (IBM) <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Luis Chamberlain <[email protected]>
1 parent 1b750c2 commit 0cc2dc4

File tree

23 files changed

+453
-435
lines changed

23 files changed

+453
-435
lines changed

arch/arm/kernel/module.c

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,57 +12,14 @@
1212
#include <linux/kernel.h>
1313
#include <linux/mm.h>
1414
#include <linux/elf.h>
15-
#include <linux/vmalloc.h>
1615
#include <linux/fs.h>
1716
#include <linux/string.h>
18-
#include <linux/gfp.h>
19-
#include <linux/execmem.h>
2017

2118
#include <asm/sections.h>
2219
#include <asm/smp_plat.h>
2320
#include <asm/unwind.h>
2421
#include <asm/opcodes.h>
2522

26-
#ifdef CONFIG_XIP_KERNEL
27-
/*
28-
* The XIP kernel text is mapped in the module area for modules and
29-
* some other stuff to work without any indirect relocations.
30-
* MODULES_VADDR is redefined here and not in asm/memory.h to avoid
31-
* recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
32-
*/
33-
#undef MODULES_VADDR
34-
#define MODULES_VADDR (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK)
35-
#endif
36-
37-
#ifdef CONFIG_MMU
38-
static struct execmem_info execmem_info __ro_after_init;
39-
40-
struct execmem_info __init *execmem_arch_setup(void)
41-
{
42-
unsigned long fallback_start = 0, fallback_end = 0;
43-
44-
if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS)) {
45-
fallback_start = VMALLOC_START;
46-
fallback_end = VMALLOC_END;
47-
}
48-
49-
execmem_info = (struct execmem_info){
50-
.ranges = {
51-
[EXECMEM_DEFAULT] = {
52-
.start = MODULES_VADDR,
53-
.end = MODULES_END,
54-
.pgprot = PAGE_KERNEL_EXEC,
55-
.alignment = 1,
56-
.fallback_start = fallback_start,
57-
.fallback_end = fallback_end,
58-
},
59-
},
60-
};
61-
62-
return &execmem_info;
63-
}
64-
#endif
65-
6623
bool module_init_section(const char *name)
6724
{
6825
return strstarts(name, ".init") ||

arch/arm/mm/init.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/sizes.h>
2323
#include <linux/stop_machine.h>
2424
#include <linux/swiotlb.h>
25+
#include <linux/execmem.h>
2526

2627
#include <asm/cp15.h>
2728
#include <asm/mach-types.h>
@@ -486,3 +487,47 @@ void free_initrd_mem(unsigned long start, unsigned long end)
486487
free_reserved_area((void *)start, (void *)end, -1, "initrd");
487488
}
488489
#endif
490+
491+
#ifdef CONFIG_EXECMEM
492+
493+
#ifdef CONFIG_XIP_KERNEL
494+
/*
495+
* The XIP kernel text is mapped in the module area for modules and
496+
* some other stuff to work without any indirect relocations.
497+
* MODULES_VADDR is redefined here and not in asm/memory.h to avoid
498+
* recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
499+
*/
500+
#undef MODULES_VADDR
501+
#define MODULES_VADDR (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK)
502+
#endif
503+
504+
#ifdef CONFIG_MMU
505+
static struct execmem_info execmem_info __ro_after_init;
506+
507+
struct execmem_info __init *execmem_arch_setup(void)
508+
{
509+
unsigned long fallback_start = 0, fallback_end = 0;
510+
511+
if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS)) {
512+
fallback_start = VMALLOC_START;
513+
fallback_end = VMALLOC_END;
514+
}
515+
516+
execmem_info = (struct execmem_info){
517+
.ranges = {
518+
[EXECMEM_DEFAULT] = {
519+
.start = MODULES_VADDR,
520+
.end = MODULES_END,
521+
.pgprot = PAGE_KERNEL_EXEC,
522+
.alignment = 1,
523+
.fallback_start = fallback_start,
524+
.fallback_end = fallback_end,
525+
},
526+
},
527+
};
528+
529+
return &execmem_info;
530+
}
531+
#endif /* CONFIG_MMU */
532+
533+
#endif /* CONFIG_EXECMEM */

arch/arm64/kernel/module.c

Lines changed: 0 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -12,158 +12,18 @@
1212
#include <linux/bitops.h>
1313
#include <linux/elf.h>
1414
#include <linux/ftrace.h>
15-
#include <linux/gfp.h>
1615
#include <linux/kasan.h>
1716
#include <linux/kernel.h>
1817
#include <linux/mm.h>
1918
#include <linux/moduleloader.h>
2019
#include <linux/random.h>
2120
#include <linux/scs.h>
22-
#include <linux/vmalloc.h>
23-
#include <linux/execmem.h>
2421

2522
#include <asm/alternative.h>
2623
#include <asm/insn.h>
2724
#include <asm/scs.h>
2825
#include <asm/sections.h>
2926

30-
static u64 module_direct_base __ro_after_init = 0;
31-
static u64 module_plt_base __ro_after_init = 0;
32-
33-
/*
34-
* Choose a random page-aligned base address for a window of 'size' bytes which
35-
* entirely contains the interval [start, end - 1].
36-
*/
37-
static u64 __init random_bounding_box(u64 size, u64 start, u64 end)
38-
{
39-
u64 max_pgoff, pgoff;
40-
41-
if ((end - start) >= size)
42-
return 0;
43-
44-
max_pgoff = (size - (end - start)) / PAGE_SIZE;
45-
pgoff = get_random_u32_inclusive(0, max_pgoff);
46-
47-
return start - pgoff * PAGE_SIZE;
48-
}
49-
50-
/*
51-
* Modules may directly reference data and text anywhere within the kernel
52-
* image and other modules. References using PREL32 relocations have a +/-2G
53-
* range, and so we need to ensure that the entire kernel image and all modules
54-
* fall within a 2G window such that these are always within range.
55-
*
56-
* Modules may directly branch to functions and code within the kernel text,
57-
* and to functions and code within other modules. These branches will use
58-
* CALL26/JUMP26 relocations with a +/-128M range. Without PLTs, we must ensure
59-
* that the entire kernel text and all module text falls within a 128M window
60-
* such that these are always within range. With PLTs, we can expand this to a
61-
* 2G window.
62-
*
63-
* We chose the 128M region to surround the entire kernel image (rather than
64-
* just the text) as using the same bounds for the 128M and 2G regions ensures
65-
* by construction that we never select a 128M region that is not a subset of
66-
* the 2G region. For very large and unusual kernel configurations this means
67-
* we may fall back to PLTs where they could have been avoided, but this keeps
68-
* the logic significantly simpler.
69-
*/
70-
static int __init module_init_limits(void)
71-
{
72-
u64 kernel_end = (u64)_end;
73-
u64 kernel_start = (u64)_text;
74-
u64 kernel_size = kernel_end - kernel_start;
75-
76-
/*
77-
* The default modules region is placed immediately below the kernel
78-
* image, and is large enough to use the full 2G relocation range.
79-
*/
80-
BUILD_BUG_ON(KIMAGE_VADDR != MODULES_END);
81-
BUILD_BUG_ON(MODULES_VSIZE < SZ_2G);
82-
83-
if (!kaslr_enabled()) {
84-
if (kernel_size < SZ_128M)
85-
module_direct_base = kernel_end - SZ_128M;
86-
if (kernel_size < SZ_2G)
87-
module_plt_base = kernel_end - SZ_2G;
88-
} else {
89-
u64 min = kernel_start;
90-
u64 max = kernel_end;
91-
92-
if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
93-
pr_info("2G module region forced by RANDOMIZE_MODULE_REGION_FULL\n");
94-
} else {
95-
module_direct_base = random_bounding_box(SZ_128M, min, max);
96-
if (module_direct_base) {
97-
min = module_direct_base;
98-
max = module_direct_base + SZ_128M;
99-
}
100-
}
101-
102-
module_plt_base = random_bounding_box(SZ_2G, min, max);
103-
}
104-
105-
pr_info("%llu pages in range for non-PLT usage",
106-
module_direct_base ? (SZ_128M - kernel_size) / PAGE_SIZE : 0);
107-
pr_info("%llu pages in range for PLT usage",
108-
module_plt_base ? (SZ_2G - kernel_size) / PAGE_SIZE : 0);
109-
110-
return 0;
111-
}
112-
113-
static struct execmem_info execmem_info __ro_after_init;
114-
115-
struct execmem_info __init *execmem_arch_setup(void)
116-
{
117-
unsigned long fallback_start = 0, fallback_end = 0;
118-
unsigned long start = 0, end = 0;
119-
120-
module_init_limits();
121-
122-
/*
123-
* Where possible, prefer to allocate within direct branch range of the
124-
* kernel such that no PLTs are necessary.
125-
*/
126-
if (module_direct_base) {
127-
start = module_direct_base;
128-
end = module_direct_base + SZ_128M;
129-
130-
if (module_plt_base) {
131-
fallback_start = module_plt_base;
132-
fallback_end = module_plt_base + SZ_2G;
133-
}
134-
} else if (module_plt_base) {
135-
start = module_plt_base;
136-
end = module_plt_base + SZ_2G;
137-
}
138-
139-
execmem_info = (struct execmem_info){
140-
.ranges = {
141-
[EXECMEM_DEFAULT] = {
142-
.start = start,
143-
.end = end,
144-
.pgprot = PAGE_KERNEL,
145-
.alignment = 1,
146-
.fallback_start = fallback_start,
147-
.fallback_end = fallback_end,
148-
},
149-
[EXECMEM_KPROBES] = {
150-
.start = VMALLOC_START,
151-
.end = VMALLOC_END,
152-
.pgprot = PAGE_KERNEL_ROX,
153-
.alignment = 1,
154-
},
155-
[EXECMEM_BPF] = {
156-
.start = VMALLOC_START,
157-
.end = VMALLOC_END,
158-
.pgprot = PAGE_KERNEL,
159-
.alignment = 1,
160-
},
161-
},
162-
};
163-
164-
return &execmem_info;
165-
}
166-
16727
enum aarch64_reloc_op {
16828
RELOC_OP_NONE,
16929
RELOC_OP_ABS,

0 commit comments

Comments
 (0)