[PATCH] arm: apple: Fix mem layout

The current approach for setting the environment variables that describe the memory layout runs the risk of overlapping with reserved memory regions. Use the lmb code to derive the addresses for these variables instead.
Signed-off-by: Mark Kettenis kettenis@openbsd.org ---
Another candidate for 2022.04. Not a regression either, but the current code may end up randomly failing due to address space randomization. The efi_loader bootpath seems to be unaffected, but attempt to load a Linux kernel directly are more likely to fail. Also tested widely by people using the Asahi Linux installer.
arch/arm/mach-apple/board.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 54005f3adf..722dff1f64 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -6,6 +6,7 @@ #include <common.h> #include <dm.h> #include <efi_loader.h> +#include <lmb.h>
#include <asm/armv8/mmu.h> #include <asm/global_data.h> @@ -266,32 +267,27 @@ u64 get_page_table_size(void) return SZ_256K; }
+#define KERNEL_COMP_SIZE SZ_128M + int board_late_init(void) { - unsigned long base; - unsigned long top; + struct lmb lmb; u32 status = 0;
- /* Reserve 4M each for scriptaddr and pxefile_addr_r at the top of RAM - * at least 1M below the stack. - */ - top = gd->start_addr_sp - CONFIG_STACK_SIZE - SZ_8M - SZ_1M; - top = ALIGN_DOWN(top, SZ_8M); - - status |= env_set_hex("scriptaddr", top + SZ_4M); - status |= env_set_hex("pxefile_addr_r", top); + lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
/* somewhat based on the Linux Kernel boot requirements: * align by 2M and maximal FDT size 2M */ - base = ALIGN(gd->ram_base, SZ_2M); - - status |= env_set_hex("fdt_addr_r", base); - status |= env_set_hex("kernel_addr_r", base + SZ_2M); - status |= env_set_hex("ramdisk_addr_r", base + SZ_128M); - status |= env_set_hex("loadaddr", base + SZ_2G); - status |= env_set_hex("kernel_comp_addr_r", base + SZ_2G - SZ_128M); - status |= env_set_hex("kernel_comp_size", SZ_128M); + status |= env_set_hex("loadaddr", lmb_alloc(&lmb, SZ_1G, SZ_2M)); + status |= env_set_hex("fdt_addr_r", lmb_alloc(&lmb, SZ_2M, SZ_2M)); + status |= env_set_hex("kernel_addr_r", lmb_alloc(&lmb, SZ_128M, SZ_2M)); + status |= env_set_hex("ramdisk_addr_r", lmb_alloc(&lmb, SZ_1G, SZ_2M)); + status |= env_set_hex("kernel_comp_addr_r", + lmb_alloc(&lmb, KERNEL_COMP_SIZE, SZ_2M)); + status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE); + status |= env_set_hex("scriptaddr", lmb_alloc(&lmb, SZ_4M, SZ_2M)); + status |= env_set_hex("pxefile_addr_r", lmb_alloc(&lmb, SZ_4M, SZ_2M));
if (status) log_warning("late_init: Failed to set run time variables\n");

Hi Mark,
On Mon, 21 Mar 2022 at 15:41, Mark Kettenis kettenis@openbsd.org wrote:
The current approach for setting the environment variables that describe the memory layout runs the risk of overlapping with reserved memory regions. Use the lmb code to derive the addresses for these variables instead.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
Another candidate for 2022.04. Not a regression either, but the current code may end up randomly failing due to address space randomization. The efi_loader bootpath seems to be unaffected, but attempt to load a Linux kernel directly are more likely to fail. Also tested widely by people using the Asahi Linux installer.
Where is the randomisation happening?
arch/arm/mach-apple/board.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org Date: Wed, 23 Mar 2022 03:59:58 -0600
Hi Mark,
On Mon, 21 Mar 2022 at 15:41, Mark Kettenis kettenis@openbsd.org wrote:
The current approach for setting the environment variables that describe the memory layout runs the risk of overlapping with reserved memory regions. Use the lmb code to derive the addresses for these variables instead.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
Another candidate for 2022.04. Not a regression either, but the current code may end up randomly failing due to address space randomization. The efi_loader bootpath seems to be unaffected, but attempt to load a Linux kernel directly are more likely to fail. Also tested widely by people using the Asahi Linux installer.
Where is the randomisation happening?
There are a few factors here. The Apple bootloader loads m1n1 at a somewhat random address. And then there are variations in how U-Boot gets loaded (as a m1n1 payload, chainloaded, running under the m1n1 hypervisor, etc.) that affect which memory ranges end up being reserved in the DTB by m1n1. And the variation in firmware between machines makes the memory map somewhat unpredictable too.
arch/arm/mach-apple/board.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

Hi Mark,
On Wed, 23 Mar 2022 at 04:18, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Wed, 23 Mar 2022 03:59:58 -0600
Hi Mark,
On Mon, 21 Mar 2022 at 15:41, Mark Kettenis kettenis@openbsd.org wrote:
The current approach for setting the environment variables that describe the memory layout runs the risk of overlapping with reserved memory regions. Use the lmb code to derive the addresses for these variables instead.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
Another candidate for 2022.04. Not a regression either, but the current code may end up randomly failing due to address space randomization. The efi_loader bootpath seems to be unaffected, but attempt to load a Linux kernel directly are more likely to fail. Also tested widely by people using the Asahi Linux installer.
Where is the randomisation happening?
There are a few factors here. The Apple bootloader loads m1n1 at a somewhat random address. And then there are variations in how U-Boot gets loaded (as a m1n1 payload, chainloaded, running under the m1n1 hypervisor, etc.) that affect which memory ranges end up being reserved in the DTB by m1n1. And the variation in firmware between machines makes the memory map somewhat unpredictable too.
OK, thanks, sounds complicated!
arch/arm/mach-apple/board.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Mon, Mar 21, 2022 at 10:41:18PM +0100, Mark Kettenis wrote:
The current approach for setting the environment variables that describe the memory layout runs the risk of overlapping with reserved memory regions. Use the lmb code to derive the addresses for these variables instead.
Signed-off-by: Mark Kettenis kettenis@openbsd.org Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!
participants (4)
-
Mark Kettenis
-
Mark Kettenis
-
Simon Glass
-
Tom Rini