Skip to content

Commit ea3752b

Browse files
mrutland-armctmarinas
authored andcommitted
arm64: module: mandate MODULE_PLTS
Contemporary kernels and modules can be relatively large, especially when common debug options are enabled. Using GCC 12.1.0, a v6.3-rc7 defconfig kernel is ~38M, and with PROVE_LOCKING + KASAN_INLINE enabled this expands to ~117M. Shanker reports [1] that the NVIDIA GPU driver alone can consume 110M of module space in some configurations. Both KASLR and ARM64_ERRATUM_843419 select MODULE_PLTS, so anyone wanting a kernel to have KASLR or run on Cortex-A53 will have MODULE_PLTS selected. This is the case in defconfig and distribution kernels (e.g. Debian, Android, etc). Practically speaking, this means we're very likely to need MODULE_PLTS and while it's almost guaranteed that MODULE_PLTS will be selected, it is possible to disable support, and we have to maintain some awkward special cases for such unusual configurations. This patch removes the MODULE_PLTS config option, with the support code always enabled if MODULES is selected. This results in a slight simplification, and will allow for further improvement in subsequent patches. For any config which currently selects MODULE_PLTS, there will be no functional change as a result of this patch. [1] https://lore.kernel.org/linux-arm-kernel/[email protected]/ Signed-off-by: Mark Rutland <[email protected]> Reviewed-by: Ard Biesheuvel <[email protected]> Cc: Shanker Donthineni <[email protected]> Cc: Will Deacon <[email protected]> Tested-by: Shanker Donthineni <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent e46b710 commit ea3752b

File tree

6 files changed

+19
-49
lines changed

6 files changed

+19
-49
lines changed

arch/arm64/Kconfig

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ config ARM64
207207
select HAVE_IOREMAP_PROT
208208
select HAVE_IRQ_TIME_ACCOUNTING
209209
select HAVE_KVM
210+
select HAVE_MOD_ARCH_SPECIFIC
210211
select HAVE_NMI
211212
select HAVE_PERF_EVENTS
212213
select HAVE_PERF_REGS
@@ -577,7 +578,6 @@ config ARM64_ERRATUM_845719
577578
config ARM64_ERRATUM_843419
578579
bool "Cortex-A53: 843419: A load or store might access an incorrect address"
579580
default y
580-
select ARM64_MODULE_PLTS if MODULES
581581
help
582582
This option links the kernel with '--fix-cortex-a53-843419' and
583583
enables PLT support to replace certain ADRP instructions, which can
@@ -2107,26 +2107,6 @@ config ARM64_SME
21072107
register state capable of holding two dimensional matrix tiles to
21082108
enable various matrix operations.
21092109

2110-
config ARM64_MODULE_PLTS
2111-
bool "Use PLTs to allow module memory to spill over into vmalloc area"
2112-
depends on MODULES
2113-
select HAVE_MOD_ARCH_SPECIFIC
2114-
help
2115-
Allocate PLTs when loading modules so that jumps and calls whose
2116-
targets are too far away for their relative offsets to be encoded
2117-
in the instructions themselves can be bounced via veneers in the
2118-
module's PLT. This allows modules to be allocated in the generic
2119-
vmalloc area after the dedicated module memory area has been
2120-
exhausted.
2121-
2122-
When running with address space randomization (KASLR), the module
2123-
region itself may be too far away for ordinary relative jumps and
2124-
calls, and so in that case, module PLTs are required and cannot be
2125-
disabled.
2126-
2127-
Specific errata workaround(s) might also force module PLTs to be
2128-
enabled (ARM64_ERRATUM_843419).
2129-
21302110
config ARM64_PSEUDO_NMI
21312111
bool "Support for NMI-like interrupts"
21322112
select ARM_GIC_V3
@@ -2167,7 +2147,6 @@ config RELOCATABLE
21672147

21682148
config RANDOMIZE_BASE
21692149
bool "Randomize the address of the kernel image"
2170-
select ARM64_MODULE_PLTS if MODULES
21712150
select RELOCATABLE
21722151
help
21732152
Randomizes the virtual address at which the kernel image is
@@ -2198,9 +2177,8 @@ config RANDOMIZE_MODULE_REGION_FULL
21982177
When this option is not set, the module region will be randomized over
21992178
a limited range that contains the [_stext, _etext] interval of the
22002179
core kernel, so branch relocations are almost always in range unless
2201-
ARM64_MODULE_PLTS is enabled and the region is exhausted. In this
2202-
particular case of region exhaustion, modules might be able to fall
2203-
back to a larger 2GB area.
2180+
the region is exhausted. In this particular case of region
2181+
exhaustion, modules might be able to fall back to a larger 2GB area.
22042182

22052183
config CC_HAVE_STACKPROTECTOR_SYSREG
22062184
def_bool $(cc-option,-mstack-protector-guard=sysreg -mstack-protector-guard-reg=sp_el0 -mstack-protector-guard-offset=0)

arch/arm64/include/asm/module.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
#include <asm-generic/module.h>
99

10-
#ifdef CONFIG_ARM64_MODULE_PLTS
1110
struct mod_plt_sec {
1211
int plt_shndx;
1312
int plt_num_entries;
@@ -21,7 +20,6 @@ struct mod_arch_specific {
2120
/* for CONFIG_DYNAMIC_FTRACE */
2221
struct plt_entry *ftrace_trampolines;
2322
};
24-
#endif
2523

2624
u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs,
2725
void *loc, const Elf64_Rela *rela,

arch/arm64/include/asm/module.lds.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
SECTIONS {
2-
#ifdef CONFIG_ARM64_MODULE_PLTS
32
.plt 0 : { BYTE(0) }
43
.init.plt 0 : { BYTE(0) }
54
.text.ftrace_trampoline 0 : { BYTE(0) }
6-
#endif
75

86
#ifdef CONFIG_KASAN_SW_TAGS
97
/*

arch/arm64/kernel/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ obj-$(CONFIG_COMPAT) += sigreturn32.o
4242
obj-$(CONFIG_COMPAT_ALIGNMENT_FIXUPS) += compat_alignment.o
4343
obj-$(CONFIG_KUSER_HELPERS) += kuser32.o
4444
obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
45-
obj-$(CONFIG_MODULES) += module.o
46-
obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o
45+
obj-$(CONFIG_MODULES) += module.o module-plts.o
4746
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
4847
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
4948
obj-$(CONFIG_CPU_PM) += sleep.o suspend.o

arch/arm64/kernel/ftrace.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
197197

198198
static struct plt_entry *get_ftrace_plt(struct module *mod)
199199
{
200-
#ifdef CONFIG_ARM64_MODULE_PLTS
200+
#ifdef CONFIG_MODULES
201201
struct plt_entry *plt = mod->arch.ftrace_trampolines;
202202

203203
return &plt[FTRACE_PLT_IDX];
@@ -249,7 +249,7 @@ static bool ftrace_find_callable_addr(struct dyn_ftrace *rec,
249249
* must use a PLT to reach it. We can only place PLTs for modules, and
250250
* only when module PLT support is built-in.
251251
*/
252-
if (!IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
252+
if (!IS_ENABLED(CONFIG_MODULES))
253253
return false;
254254

255255
/*
@@ -431,10 +431,8 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
431431
*
432432
* Note: 'mod' is only set at module load time.
433433
*/
434-
if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_ARGS) &&
435-
IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) && mod) {
434+
if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_ARGS) && mod)
436435
return aarch64_insn_patch_text_nosync((void *)pc, new);
437-
}
438436

439437
if (!ftrace_find_callable_addr(rec, mod, &addr))
440438
return -EINVAL;

arch/arm64/kernel/module.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,25 +73,26 @@ subsys_initcall(kaslr_module_init)
7373
void *module_alloc(unsigned long size)
7474
{
7575
u64 module_alloc_end = module_alloc_base + MODULES_VSIZE;
76-
gfp_t gfp_mask = GFP_KERNEL;
7776
void *p;
7877

79-
/* Silence the initial allocation */
80-
if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
81-
gfp_mask |= __GFP_NOWARN;
82-
78+
/*
79+
* Where possible, prefer to allocate within direct branch range of the
80+
* kernel such that no PLTs are necessary. This may fail, so we pass
81+
* __GFP_NOWARN to silence the resulting warning.
82+
*/
8383
p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
84-
module_alloc_end, gfp_mask, PAGE_KERNEL, 0,
85-
NUMA_NO_NODE, __builtin_return_address(0));
84+
module_alloc_end, GFP_KERNEL | __GFP_NOWARN,
85+
PAGE_KERNEL, 0, NUMA_NO_NODE,
86+
__builtin_return_address(0));
8687

87-
if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS)) {
88+
if (!p) {
8889
p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
8990
module_alloc_base + SZ_2G, GFP_KERNEL,
9091
PAGE_KERNEL, 0, NUMA_NO_NODE,
9192
__builtin_return_address(0));
9293
}
9394

94-
if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
95+
if (p && (kasan_alloc_module_shadow(p, size, GFP_KERNEL) < 0)) {
9596
vfree(p);
9697
return NULL;
9798
}
@@ -479,9 +480,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
479480
case R_AARCH64_CALL26:
480481
ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 26,
481482
AARCH64_INSN_IMM_26);
482-
483-
if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
484-
ovf == -ERANGE) {
483+
if (ovf == -ERANGE) {
485484
val = module_emit_plt_entry(me, sechdrs, loc, &rel[i], sym);
486485
if (!val)
487486
return -ENOEXEC;
@@ -518,7 +517,7 @@ static int module_init_ftrace_plt(const Elf_Ehdr *hdr,
518517
const Elf_Shdr *sechdrs,
519518
struct module *mod)
520519
{
521-
#if defined(CONFIG_ARM64_MODULE_PLTS) && defined(CONFIG_DYNAMIC_FTRACE)
520+
#if defined(CONFIG_DYNAMIC_FTRACE)
522521
const Elf_Shdr *s;
523522
struct plt_entry *plts;
524523

0 commit comments

Comments
 (0)