Skip to content

Commit a494682

Browse files
committed
Merge tag 'modules-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux
Pull modules updates from Luis Chamberlain: "Finally something fun. Mike Rapoport does some cleanup to allow us to take out module_alloc() out of modules into a new paint shedded execmem_alloc() and execmem_free() so to make emphasis these helpers are actually used outside of modules. It starts with a non-functional changes API rename / placeholders to then allow architectures to define their requirements into a new shiny struct execmem_info with ranges, and requirements for those ranges. Archs now can intitialize this execmem_info as the last part of mm_core_init() if they have to diverge from the norm. Each range is a known type clearly articulated and spelled out in enum execmem_type. Although a lot of this is major cleanup and prep work for future enhancements an immediate clear gain is we get to enable KPROBES without MODULES now. That is ultimately what motiviated to pick this work up again, now with smaller goal as concrete stepping stone" * tag 'modules-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux: bpf: remove CONFIG_BPF_JIT dependency on CONFIG_MODULES of kprobes: remove dependency on CONFIG_MODULES powerpc: use CONFIG_EXECMEM instead of CONFIG_MODULES where appropriate x86/ftrace: enable dynamic ftrace without CONFIG_MODULES arch: make execmem setup available regardless of CONFIG_MODULES powerpc: extend execmem_params for kprobes allocations arm64: extend execmem_info for generated code allocations riscv: extend execmem_params for generated code allocations mm/execmem, arch: convert remaining overrides of module_alloc to execmem mm/execmem, arch: convert simple overrides of module_alloc to execmem mm: introduce execmem_alloc() and execmem_free() module: make module_memory_{alloc,free} more self-contained sparc: simplify module_alloc() nios2: define virtual address space for modules mips: module: rename MODULE_START to MODULES_VADDR arm64: module: remove unneeded call to kasan_alloc_module_shadow() kallsyms: replace deprecated strncpy with strscpy module: allow UNUSED_KSYMS_WHITELIST to be relative against objtree.
2 parents 8c06da6 + 2c9e5d4 commit a494682

File tree

62 files changed

+906
-584
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+906
-584
lines changed

arch/Kconfig

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ config GENERIC_ENTRY
6060

6161
config KPROBES
6262
bool "Kprobes"
63-
depends on MODULES
6463
depends on HAVE_KPROBES
6564
select KALLSYMS
65+
select EXECMEM
6666
select NEED_TASKS_RCU
6767
help
6868
Kprobes allows you to trap at almost any kernel address and
@@ -977,6 +977,14 @@ config ARCH_WANTS_MODULES_DATA_IN_VMALLOC
977977
For architectures like powerpc/32 which have constraints on module
978978
allocation and need to allocate module data outside of module area.
979979

980+
config ARCH_WANTS_EXECMEM_LATE
981+
bool
982+
help
983+
For architectures that do not allocate executable memory early on
984+
boot, but rather require its initialization late when there is
985+
enough entropy for module space randomization, for instance
986+
arm64.
987+
980988
config HAVE_IRQ_EXIT_ON_IRQ_STACK
981989
bool
982990
help

arch/arm/kernel/module.c

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,48 +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>
1917

2018
#include <asm/sections.h>
2119
#include <asm/smp_plat.h>
2220
#include <asm/unwind.h>
2321
#include <asm/opcodes.h>
2422

25-
#ifdef CONFIG_XIP_KERNEL
26-
/*
27-
* The XIP kernel text is mapped in the module area for modules and
28-
* some other stuff to work without any indirect relocations.
29-
* MODULES_VADDR is redefined here and not in asm/memory.h to avoid
30-
* recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
31-
*/
32-
#undef MODULES_VADDR
33-
#define MODULES_VADDR (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK)
34-
#endif
35-
36-
#ifdef CONFIG_MMU
37-
void *module_alloc(unsigned long size)
38-
{
39-
gfp_t gfp_mask = GFP_KERNEL;
40-
void *p;
41-
42-
/* Silence the initial allocation */
43-
if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS))
44-
gfp_mask |= __GFP_NOWARN;
45-
46-
p = __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
47-
gfp_mask, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
48-
__builtin_return_address(0));
49-
if (!IS_ENABLED(CONFIG_ARM_MODULE_PLTS) || p)
50-
return p;
51-
return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
52-
GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
53-
__builtin_return_address(0));
54-
}
55-
#endif
56-
5723
bool module_init_section(const char *name)
5824
{
5925
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/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ config ARM64
105105
select ARCH_WANT_FRAME_POINTERS
106106
select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
107107
select ARCH_WANT_LD_ORPHAN_WARN
108+
select ARCH_WANTS_EXECMEM_LATE if EXECMEM
108109
select ARCH_WANTS_NO_INSTR
109110
select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
110111
select ARCH_HAS_UBSAN

arch/arm64/kernel/module.c

Lines changed: 0 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -12,144 +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>
2321

2422
#include <asm/alternative.h>
2523
#include <asm/insn.h>
2624
#include <asm/scs.h>
2725
#include <asm/sections.h>
2826

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

arch/arm64/kernel/probes/kprobes.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,6 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
129129
return 0;
130130
}
131131

132-
void *alloc_insn_page(void)
133-
{
134-
return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
135-
GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
136-
NUMA_NO_NODE, __builtin_return_address(0));
137-
}
138-
139132
/* arm kprobe: install breakpoint in text */
140133
void __kprobes arch_arm_kprobe(struct kprobe *p)
141134
{

0 commit comments

Comments
 (0)