All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] efi: libstub/arm: account for firmware reserved memory at the base of RAM
@ 2019-10-14 16:33 ` Ard Biesheuvel
  0 siblings, 0 replies; 6+ messages in thread
From: Ard Biesheuvel @ 2019-10-14 16:33 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: linux-efi, Ard Biesheuvel, Guillaume Gardet, Chester Lin

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@arm.com>
Cc: Chester Lin <clin@suse.com> 
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 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);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH] efi: libstub/arm: account for firmware reserved memory at the base of RAM
@ 2019-10-14 16:33 ` Ard Biesheuvel
  0 siblings, 0 replies; 6+ messages in thread
From: Ard Biesheuvel @ 2019-10-14 16:33 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Chester Lin, Guillaume Gardet, linux-efi, Ard Biesheuvel

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@arm.com>
Cc: Chester Lin <clin@suse.com> 
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 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);
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] efi: libstub/arm: account for firmware reserved memory at the base of RAM
  2019-10-14 16:33 ` Ard Biesheuvel
@ 2019-10-15  2:26   ` Chester Lin
  -1 siblings, 0 replies; 6+ messages in thread
From: Chester Lin @ 2019-10-15  2:26 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: linux-arm-kernel, Guillaume Gardet, Chester Lin, linux-efi

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@arm.com>
> Cc: Chester Lin <clin@suse.com> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  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@suse.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] efi: libstub/arm: account for firmware reserved memory at the base of RAM
@ 2019-10-15  2:26   ` Chester Lin
  0 siblings, 0 replies; 6+ messages in thread
From: Chester Lin @ 2019-10-15  2:26 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: Chester Lin, linux-efi, linux-arm-kernel, Guillaume Gardet

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@arm.com>
> Cc: Chester Lin <clin@suse.com> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  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@suse.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH] efi: libstub/arm: account for firmware reserved memory at the base of RAM
  2019-10-14 16:33 ` Ard Biesheuvel
@ 2019-10-15  6:14   ` Guillaume Gardet
  -1 siblings, 0 replies; 6+ messages in thread
From: Guillaume Gardet @ 2019-10-15  6:14 UTC (permalink / raw)
  To: Ard Biesheuvel, linux-arm-kernel; +Cc: linux-efi, Chester Lin



> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Sent: 14 October 2019 18:33
> To: linux-arm-kernel@lists.infradead.org
> Cc: linux-efi@vger.kernel.org; Ard Biesheuvel <ard.biesheuvel@linaro.org>;
> Guillaume Gardet <Guillaume.Gardet@arm.com>; Chester Lin <clin@suse.com>
> Subject: [PATCH] efi: libstub/arm: account for firmware reserved memory at the
> base of RAM
>
> 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@arm.com>
> Cc: Chester Lin <clin@suse.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Tested-by: Guillaume Gardet <Guillaume.Gardet@arm.com>

> ---
>  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);
> --
> 2.20.1

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH] efi: libstub/arm: account for firmware reserved memory at the base of RAM
@ 2019-10-15  6:14   ` Guillaume Gardet
  0 siblings, 0 replies; 6+ messages in thread
From: Guillaume Gardet @ 2019-10-15  6:14 UTC (permalink / raw)
  To: Ard Biesheuvel, linux-arm-kernel; +Cc: Chester Lin, linux-efi



> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Sent: 14 October 2019 18:33
> To: linux-arm-kernel@lists.infradead.org
> Cc: linux-efi@vger.kernel.org; Ard Biesheuvel <ard.biesheuvel@linaro.org>;
> Guillaume Gardet <Guillaume.Gardet@arm.com>; Chester Lin <clin@suse.com>
> Subject: [PATCH] efi: libstub/arm: account for firmware reserved memory at the
> base of RAM
>
> 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@arm.com>
> Cc: Chester Lin <clin@suse.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Tested-by: Guillaume Gardet <Guillaume.Gardet@arm.com>

> ---
>  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);
> --
> 2.20.1

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-10-15  6:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-14 16:33 [PATCH] efi: libstub/arm: account for firmware reserved memory at the base of RAM Ard Biesheuvel
2019-10-14 16:33 ` Ard Biesheuvel
2019-10-15  2:26 ` Chester Lin
2019-10-15  2:26   ` Chester Lin
2019-10-15  6:14 ` Guillaume Gardet
2019-10-15  6:14   ` Guillaume Gardet

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.