Commit ea3752ba authored by Mark Rutland's avatar Mark Rutland Committed by Catalin Marinas
Browse files

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/159ceeab-09af-3174-5058-445bc8dcf85b@nvidia.com/



Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Reviewed-by: default avatarArd Biesheuvel <ardb@kernel.org>
Cc: Shanker Donthineni <sdonthineni@nvidia.com>
Cc: Will Deacon <will@kernel.org>
Tested-by: default avatarShanker Donthineni <sdonthineni@nvidia.com>
Link: https://lore.kernel.org/r/20230530110328.2213762-6-mark.rutland@arm.com


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent e46b7103
Loading
Loading
Loading
Loading
+3 −25
Original line number Diff line number Diff line
@@ -207,6 +207,7 @@ config ARM64
	select HAVE_IOREMAP_PROT
	select HAVE_IRQ_TIME_ACCOUNTING
	select HAVE_KVM
	select HAVE_MOD_ARCH_SPECIFIC
	select HAVE_NMI
	select HAVE_PERF_EVENTS
	select HAVE_PERF_REGS
@@ -577,7 +578,6 @@ config ARM64_ERRATUM_845719
config ARM64_ERRATUM_843419
	bool "Cortex-A53: 843419: A load or store might access an incorrect address"
	default y
	select ARM64_MODULE_PLTS if MODULES
	help
	  This option links the kernel with '--fix-cortex-a53-843419' and
	  enables PLT support to replace certain ADRP instructions, which can
@@ -2107,26 +2107,6 @@ config ARM64_SME
	  register state capable of holding two dimensional matrix tiles to
	  enable various matrix operations.

config ARM64_MODULE_PLTS
	bool "Use PLTs to allow module memory to spill over into vmalloc area"
	depends on MODULES
	select HAVE_MOD_ARCH_SPECIFIC
	help
	  Allocate PLTs when loading modules so that jumps and calls whose
	  targets are too far away for their relative offsets to be encoded
	  in the instructions themselves can be bounced via veneers in the
	  module's PLT. This allows modules to be allocated in the generic
	  vmalloc area after the dedicated module memory area has been
	  exhausted.

	  When running with address space randomization (KASLR), the module
	  region itself may be too far away for ordinary relative jumps and
	  calls, and so in that case, module PLTs are required and cannot be
	  disabled.

	  Specific errata workaround(s) might also force module PLTs to be
	  enabled (ARM64_ERRATUM_843419).

config ARM64_PSEUDO_NMI
	bool "Support for NMI-like interrupts"
	select ARM_GIC_V3
@@ -2167,7 +2147,6 @@ config RELOCATABLE

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

config CC_HAVE_STACKPROTECTOR_SYSREG
	def_bool $(cc-option,-mstack-protector-guard=sysreg -mstack-protector-guard-reg=sp_el0 -mstack-protector-guard-offset=0)
+0 −2
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@

#include <asm-generic/module.h>

#ifdef CONFIG_ARM64_MODULE_PLTS
struct mod_plt_sec {
	int			plt_shndx;
	int			plt_num_entries;
@@ -21,7 +20,6 @@ struct mod_arch_specific {
	/* for CONFIG_DYNAMIC_FTRACE */
	struct plt_entry	*ftrace_trampolines;
};
#endif

u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs,
			  void *loc, const Elf64_Rela *rela,
+0 −2
Original line number Diff line number Diff line
SECTIONS {
#ifdef CONFIG_ARM64_MODULE_PLTS
	.plt 0 : { BYTE(0) }
	.init.plt 0 : { BYTE(0) }
	.text.ftrace_trampoline 0 : { BYTE(0) }
#endif

#ifdef CONFIG_KASAN_SW_TAGS
	/*
+1 −2
Original line number Diff line number Diff line
@@ -42,8 +42,7 @@ obj-$(CONFIG_COMPAT) += sigreturn32.o
obj-$(CONFIG_COMPAT_ALIGNMENT_FIXUPS)	+= compat_alignment.o
obj-$(CONFIG_KUSER_HELPERS)		+= kuser32.o
obj-$(CONFIG_FUNCTION_TRACER)		+= ftrace.o entry-ftrace.o
obj-$(CONFIG_MODULES)			+= module.o
obj-$(CONFIG_ARM64_MODULE_PLTS)		+= module-plts.o
obj-$(CONFIG_MODULES)			+= module.o module-plts.o
obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
obj-$(CONFIG_CPU_PM)			+= sleep.o suspend.o
+3 −5
Original line number Diff line number Diff line
@@ -197,7 +197,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)

static struct plt_entry *get_ftrace_plt(struct module *mod)
{
#ifdef CONFIG_ARM64_MODULE_PLTS
#ifdef CONFIG_MODULES
	struct plt_entry *plt = mod->arch.ftrace_trampolines;

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

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

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