diff options
| author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2014-08-13 13:53:03 -0400 |
|---|---|---|
| committer | Will Deacon <will.deacon@arm.com> | 2014-08-19 14:26:09 -0400 |
| commit | 4190312beb2acfb7bfb1bb971e24a759aa96b0e8 (patch) | |
| tree | 8de244a8483bf476270dfea7b49585fd86494cdd | |
| parent | 503e6636b6f96056210062be703356f4253b6db9 (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>
| -rw-r--r-- | arch/arm64/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm64/kernel/head.S | 8 |
2 files changed, 5 insertions, 5 deletions
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 57833546bf00..2df5e5daeebe 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile | |||
| @@ -39,7 +39,7 @@ head-y := arch/arm64/kernel/head.o | |||
| 39 | 39 | ||
| 40 | # The byte offset of the kernel image in RAM from the start of RAM. | 40 | # The byte offset of the kernel image in RAM from the start of RAM. |
| 41 | ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) | 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 | else | 43 | else |
| 44 | TEXT_OFFSET := 0x00080000 | 44 | TEXT_OFFSET := 0x00080000 |
| 45 | endif | 45 | endif |
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 144f10567f82..bed028364a93 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
| @@ -38,11 +38,11 @@ | |||
| 38 | 38 | ||
| 39 | #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) | 39 | #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) |
| 40 | 40 | ||
| 41 | #if (TEXT_OFFSET & 0xf) != 0 | 41 | #if (TEXT_OFFSET & 0xfff) != 0 |
| 42 | #error TEXT_OFFSET must be at least 16B aligned | 42 | #error TEXT_OFFSET must be at least 4KB aligned |
| 43 | #elif (PAGE_OFFSET & 0xfffff) != 0 | 43 | #elif (PAGE_OFFSET & 0x1fffff) != 0 |
| 44 | #error PAGE_OFFSET must be at least 2MB aligned | 44 | #error PAGE_OFFSET must be at least 2MB aligned |
| 45 | #elif TEXT_OFFSET > 0xfffff | 45 | #elif TEXT_OFFSET > 0x1fffff |
| 46 | #error TEXT_OFFSET must be less than 2MB | 46 | #error TEXT_OFFSET must be less than 2MB |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
