From: Ard Biesheuvel Date: Wed, 13 Aug 2014 17:53:03 +0000 (+0100) Subject: arm64: align randomized TEXT_OFFSET on 4 kB boundary X-Git-Tag: firefly_0821_release~3680^2~30^2^2~18 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c86df325d594f33eff078fe6b6014f1994f9bcb7;p=firefly-linux-kernel-4.4.55.git 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 Signed-off-by: Ard Biesheuvel Signed-off-by: Will Deacon (cherry picked from commit 4190312beb2acfb7bfb1bb971e24a759aa96b0e8) Signed-off-by: Mark Brown Conflicts: arch/arm64/Makefile arch/arm64/kernel/head.S --- diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 7ab6b358cc35..a5004a5b7aa4 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -32,7 +32,11 @@ CHECKFLAGS += -D__aarch64__ head-y := arch/arm64/kernel/head.o # The byte offset of the kernel image in RAM from the start of RAM. +ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) +TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}') +else TEXT_OFFSET := 0x00080000 +endif export TEXT_OFFSET GZFLAGS diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 7218fefc6ac9..9129a917203e 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -37,8 +37,12 @@ #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) -#if (KERNEL_RAM_VADDR & 0xfffff) != 0x80000 -#error KERNEL_RAM_VADDR must start at 0xXXX80000 +#if (TEXT_OFFSET & 0xfff) != 0 +#error TEXT_OFFSET must be at least 4KB aligned +#elif (PAGE_OFFSET & 0x1fffff) != 0 +#error PAGE_OFFSET must be at least 2MB aligned +#elif TEXT_OFFSET > 0x1fffff +#error TEXT_OFFSET must be less than 2MB #endif .macro pgtbl, ttb0, ttb1, virt_to_phys