Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73effccb authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Will Deacon
Browse files

arm64/efi: do not assume DRAM base is aligned to 2 MB



The current arm64 Image relocation code in the UEFI stub assumes that
the dram_base argument it receives is always a multiple of 2 MB. In
reality, it is simply the lowest start address of all RAM entries in
the UEFI memory map, which means it could be any multiple of 4 KB.

Since the arm64 kernel Image needs to reside TEXT_OFFSET bytes beyond
a 2 MB aligned base, or it will fail to boot, make sure we round dram_base
to 2 MB before using it to calculate the relocation address.

Fixes: e38457c3 ("arm64: efi: prefer AllocatePages() over efi_low_alloc() for vmlinux")
Reported-by: default avatarTimur Tabi <timur@codeaurora.org>
Tested-by: default avatarTimur Tabi <timur@codeaurora.org>
Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 9702970c
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -25,10 +25,20 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
	unsigned long kernel_size, kernel_memsize = 0;
	unsigned long nr_pages;
	void *old_image_addr = (void *)*image_addr;
	unsigned long preferred_offset;

	/*
	 * The preferred offset of the kernel Image is TEXT_OFFSET bytes beyond
	 * 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, SZ_2M) + TEXT_OFFSET;
	if (preferred_offset < dram_base)
		preferred_offset += SZ_2M;

	/* Relocate the image, if required. */
	kernel_size = _edata - _text;
	if (*image_addr != (dram_base + TEXT_OFFSET)) {
	if (*image_addr != preferred_offset) {
		kernel_memsize = kernel_size + (_end - _edata);

		/*
@@ -42,7 +52,7 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
		 * Mustang), we can still place the kernel at the address
		 * 'dram_base + TEXT_OFFSET'.
		 */
		*image_addr = *reserve_addr = dram_base + TEXT_OFFSET;
		*image_addr = *reserve_addr = preferred_offset;
		nr_pages = round_up(kernel_memsize, EFI_ALLOC_ALIGN) /
			   EFI_PAGE_SIZE;
		status = efi_call_early(allocate_pages, EFI_ALLOCATE_ADDRESS,