diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2014-08-13 18:53:03 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-01-22 21:27:27 +0000 |
commit | c86df325d594f33eff078fe6b6014f1994f9bcb7 (patch) | |
tree | 3411bca2c05530291d278827acde67055368f26d | |
parent | 432d182423d53bc7f03d3a399cd57482c5ca47b0 (diff) |
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>
(cherry picked from commit 4190312beb2acfb7bfb1bb971e24a759aa96b0e8)
Signed-off-by: Mark Brown <broonie@kernel.org>
Conflicts:
arch/arm64/Makefile
arch/arm64/kernel/head.S
-rw-r--r-- | arch/arm64/Makefile | 4 | ||||
-rw-r--r-- | arch/arm64/kernel/head.S | 8 |
2 files changed, 10 insertions, 2 deletions
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 |