Skip to content

Commit cba786a

Browse files
ardbiesheuvelbp3tk0v
authored andcommitted
x86/purgatory: Switch to the position-independent small code model
On x86, the ordinary, position dependent small and kernel code models only support placement of the executable in 32-bit addressable memory, due to the use of 32-bit signed immediates to generate references to global variables. For the kernel, this implies that all global variables must reside in the top 2 GiB of the kernel virtual address space, where the implicit address bits 63:32 are equal to sign bit 31. This means the kernel code model is not suitable for other bare metal executables such as the kexec purgatory, which can be placed arbitrarily in the physical address space, where its address may no longer be representable as a sign extended 32-bit quantity. For this reason, commit e16c298 ("x86/purgatory: Change compiler flags from -mcmodel=kernel to -mcmodel=large to fix kexec relocation errors") switched to the large code model, which uses 64-bit immediates for all symbol references, including function calls, in order to avoid relying on any assumptions regarding proximity of symbols in the final executable. The large code model is rarely used, clunky and the least likely to operate in a similar fashion when comparing GCC and Clang, so it is best avoided. This is especially true now that Clang 18 has started to emit executable code in two separate sections (.text and .ltext), which triggers an issue in the kexec loading code at runtime. The SUSE bugzilla fixes tag points to gcc 13 having issues with the large model too and that perhaps the large model should simply not be used at all. Instead, use the position independent small code model, which makes no assumptions about placement but only about proximity, where all referenced symbols must be within -/+ 2 GiB, i.e., in range for a RIP-relative reference. Use hidden visibility to suppress the use of a GOT, which carries absolute addresses that are not covered by static ELF relocations, and is therefore incompatible with the kexec loader's relocation logic. [ bp: Massage commit message. ] Fixes: e16c298 ("x86/purgatory: Change compiler flags from -mcmodel=kernel to -mcmodel=large to fix kexec relocation errors") Fixes: https://bugzilla.suse.com/show_bug.cgi?id=1211853 Closes: ClangBuiltLinux/linux#2016 Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Reviewed-by: Nathan Chancellor <[email protected]> Reviewed-by: Fangrui Song <[email protected]> Acked-by: Nick Desaulniers <[email protected]> Tested-by: Nathan Chancellor <[email protected]> Link: https://lore.kernel.org/all/[email protected]/
1 parent 29b0aab commit cba786a

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

arch/x86/purgatory/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ KCOV_INSTRUMENT := n
4242
# make up the standalone purgatory.ro
4343

4444
PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel
45-
PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss -g0
45+
PURGATORY_CFLAGS := -mcmodel=small -ffreestanding -fno-zero-initialized-in-bss -g0
46+
PURGATORY_CFLAGS += -fpic -fvisibility=hidden
4647
PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING
4748
PURGATORY_CFLAGS += -fno-stack-protector
4849

0 commit comments

Comments
 (0)