Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: align randomized TEXT_OFFSET on 4 kB boundary

When booting via UEFI, the kernel Image is loaded at a 4 kB boundary and
the embedded EFI stub is executed in place. The EFI stub relocates the
Image to reside TEXT_OFFSET bytes above a 2 MB boundary, and jumps into
the kernel proper.

In AArch64, PC relative symbol references are emitted using adrp/add or
adrp/ldr pairs, where the offset into a 4 kB page is resolved using a
separate :lo12: relocation. This implicitly assumes that the code will
always be executed at the same relative offset with respect to a 4 kB
boundary, or the references will point to the wrong address.

This means we should link the kernel at a 4 kB aligned base address in
order to remain compatible with the base address the UEFI loader uses
when doing the initial load of Image. So update the code that generates
TEXT_OFFSET to choose a multiple of 4 kB.

At the same time, update the code so it chooses from the interval [0..2MB)
as the author originally intended.

Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>

authored by

Ard Biesheuvel and committed by
Will Deacon
4190312b 503e6636

+5 -5
+1 -1
arch/arm64/Makefile
··· 39 39 40 40 # The byte offset of the kernel image in RAM from the start of RAM. 41 41 ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) 42 - TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%04x0\n", int(65535 * rand())}') 42 + TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}') 43 43 else 44 44 TEXT_OFFSET := 0x00080000 45 45 endif
+4 -4
arch/arm64/kernel/head.S
··· 38 38 39 39 #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) 40 40 41 - #if (TEXT_OFFSET & 0xf) != 0 42 - #error TEXT_OFFSET must be at least 16B aligned 43 - #elif (PAGE_OFFSET & 0xfffff) != 0 41 + #if (TEXT_OFFSET & 0xfff) != 0 42 + #error TEXT_OFFSET must be at least 4KB aligned 43 + #elif (PAGE_OFFSET & 0x1fffff) != 0 44 44 #error PAGE_OFFSET must be at least 2MB aligned 45 - #elif TEXT_OFFSET > 0xfffff 45 + #elif TEXT_OFFSET > 0x1fffff 46 46 #error TEXT_OFFSET must be less than 2MB 47 47 #endif 48 48