aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2017-02-15 15:11:13 +0000
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2017-05-30 20:54:51 +0000
commit95209863a4df2eaeaad1f176b2f3bae6774b09b5 (patch)
tree8b0a4131f1455e511dc5537130bb97ec59e7c356
parent327ec1603ba23834b9394b659753df7947d7b5ec (diff)
downloadlinux-arm64-no-rwx.tar.gz
arm64: efi: use effective text offset when allocating Imagearm64-no-rwx
Update the image allocation logic in the EFI stub so that the effective text offset is always honoured on 4 KB pagesize kernels. This ensures that the __init segment can be mapped without resorting to early RWX mappings. Note that this sacrifices 5 bits of KASLR randomization on such kernels. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-rw-r--r--arch/arm64/kernel/efi-entry.S5
-rw-r--r--arch/arm64/kernel/image.h1
-rw-r--r--drivers/firmware/efi/libstub/Makefile1
-rw-r--r--drivers/firmware/efi/libstub/arm64-stub.c14
4 files changed, 15 insertions, 6 deletions
diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
index 4e6ad355bd058e..4e1cbec3c842ce 100644
--- a/arch/arm64/kernel/efi-entry.S
+++ b/arch/arm64/kernel/efi-entry.S
@@ -120,3 +120,8 @@ efi_load_fail:
entry_end:
ENDPROC(entry)
+
+ __INITRODATA
+ .align 2
+ENTRY(effective_text_offset)
+ .long __eff_text_offset
diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
index 98e191cd97b121..f137856f50bf33 100644
--- a/arch/arm64/kernel/image.h
+++ b/arch/arm64/kernel/image.h
@@ -132,6 +132,7 @@ __efistub__text = KALLSYMS_HIDE(_text);
__efistub__end = KALLSYMS_HIDE(_end);
__efistub__edata = KALLSYMS_HIDE(_edata);
__efistub_screen_info = KALLSYMS_HIDE(screen_info);
+__efistub___eff_text_offset = KALLSYMS_HIDE(__eff_text_offset);
#endif
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index f7425960f6a57d..1563d5e5972779 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -41,7 +41,6 @@ lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o random.o \
lib-$(CONFIG_ARM) += arm32-stub.o
lib-$(CONFIG_ARM64) += arm64-stub.o
-CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
#
# arm64 puts the stub in the kernel proper, which will unnecessarily retain all
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index b4c2589d7c9127..bc724fc0b77027 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -16,6 +16,8 @@
#include "efistub.h"
+extern const u32 effective_text_offset;
+
efi_status_t check_platform_features(efi_system_table_t *sys_table_arg)
{
u64 tg;
@@ -70,7 +72,8 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
* a 2 MB aligned base, which itself may be lower than dram_base, as
* long as the resulting offset equals or exceeds it.
*/
- preferred_offset = round_down(dram_base, MIN_KIMG_ALIGN) + TEXT_OFFSET;
+ preferred_offset = round_down(dram_base, MIN_KIMG_ALIGN) +
+ effective_text_offset;
if (preferred_offset < dram_base)
preferred_offset += MIN_KIMG_ALIGN;
@@ -84,8 +87,9 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
* is a multiple of the minimal segment alignment (SZ_64K)
*/
u32 mask = (MIN_KIMG_ALIGN - 1) & ~(SZ_64K - 1);
- u32 offset = !IS_ENABLED(CONFIG_DEBUG_ALIGN_RODATA) ?
- (phys_seed >> 32) & mask : TEXT_OFFSET;
+ u32 offset = (!IS_ENABLED(CONFIG_DEBUG_ALIGN_RODATA) &&
+ PAGE_SIZE > SZ_4K) ? (phys_seed >> 32) & mask :
+ effective_text_offset;
/*
* If KASLR is enabled, and we have some randomness available,
@@ -122,7 +126,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
}
if (status != EFI_SUCCESS) {
- *reserve_size = kernel_memsize + TEXT_OFFSET;
+ *reserve_size = kernel_memsize + effective_text_offset;
status = efi_low_alloc(sys_table_arg, *reserve_size,
MIN_KIMG_ALIGN, reserve_addr);
@@ -131,7 +135,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
*reserve_size = 0;
return status;
}
- *image_addr = *reserve_addr + TEXT_OFFSET;
+ *image_addr = *reserve_addr + effective_text_offset;
}
memcpy((void *)*image_addr, old_image_addr, kernel_size);