On Mon, Oct 14, 2019 at 06:33:09PM +0200, Ard Biesheuvel wrote: > The EFI stubloader for ARM starts out by allocating a 32 MB window > at the base of RAM, in order to ensure that the decompressor (which > blindly copies the uncompressed kernel into that window) does not > overwrite other allocations that are made while running in the context > of the EFI firmware. > > In some cases, (e.g., U-Boot running on the Raspberry Pi 2), this is > causing boot failures because this initial allocation conflicts with > a page of reserved memory at the base of RAM that contains the SMP spin > tables and other pieces of firmware data and which was put there by > the bootloader under the assumption that the TEXT_OFFSET window right > below the kernel is only used partially during early boot, and will be > left alone once the memory reservations are processed and taken into > account. > > So let's permit reserved memory regions to exist in the region starting > at the base of RAM, and ending at TEXT_OFFSET - 5 * PAGE_SIZE, which is > the window below the kernel that is not touched by the early boot code. > > Cc: Guillaume Gardet <Guillaume.Gardet@xxxxxxx> > Cc: Chester Lin <clin@xxxxxxxx> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> > --- > drivers/firmware/efi/libstub/Makefile | 1 + > drivers/firmware/efi/libstub/arm32-stub.c | 16 +++++++++++++--- > 2 files changed, 14 insertions(+), 3 deletions(-) > > diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile > index 0460c7581220..ee0661ddb25b 100644 > --- a/drivers/firmware/efi/libstub/Makefile > +++ b/drivers/firmware/efi/libstub/Makefile > @@ -52,6 +52,7 @@ 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_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) > CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) > > # > diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c > index e8f7aefb6813..47aafeff3e01 100644 > --- a/drivers/firmware/efi/libstub/arm32-stub.c > +++ b/drivers/firmware/efi/libstub/arm32-stub.c > @@ -195,6 +195,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, > unsigned long dram_base, > efi_loaded_image_t *image) > { > + unsigned long kernel_base; > efi_status_t status; > > /* > @@ -204,9 +205,18 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, > * loaded. These assumptions are made by the decompressor, > * before any memory map is available. > */ > - dram_base = round_up(dram_base, SZ_128M); > + kernel_base = round_up(dram_base, SZ_128M); > > - status = reserve_kernel_base(sys_table, dram_base, reserve_addr, > + /* > + * Note that some platforms (notably, the Raspberry Pi 2) put > + * spin-tables and other pieces of firmware at the base of RAM, > + * abusing the fact that the window of TEXT_OFFSET bytes at the > + * base of the kernel image is only partially used at the moment. > + * (Up to 5 pages are used for the swapper page table) > + */ > + kernel_base += TEXT_OFFSET - 5 * PAGE_SIZE; > + > + status = reserve_kernel_base(sys_table, kernel_base, reserve_addr, > reserve_size); > if (status != EFI_SUCCESS) { > pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n"); > @@ -220,7 +230,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, > *image_size = image->image_size; > status = efi_relocate_kernel(sys_table, image_addr, *image_size, > *image_size, > - dram_base + MAX_UNCOMP_KERNEL_SIZE, 0); > + kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0); > if (status != EFI_SUCCESS) { > pr_efi_err(sys_table, "Failed to relocate kernel.\n"); > efi_free(sys_table, *reserve_size, *reserve_addr); Acked-by: Chester Lin <clin@xxxxxxxx>