Merge patch series "sandbox: align LMB memory"
Heinrich Schuchardt <heinrich.schuchardt@canonical.com> says:
To implement the EFI_SYSTEM_TABLE_POINTER we need 4 MiB aligned
memory.
On the sandbox LMB uses addresses relative to the start of a page aligned
RAM buffer allocated with mmap(). This leads to a mismatch of alignment
between EFI which uses pointers and LMB which uses phys_addr_t.
Ensure that the RAM buffer used for LMB is 4 MiB aligned.
Provide a unit test for efi_alloc_aligned_pages() verifying this alignment.
Do not overwrite RAM size in dram_init().
Link: https://lore.kernel.org/r/20250608075428.32631-1-heinrich.schuchardt@canonical.com
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 49236db..6a15c8b 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -480,7 +480,9 @@
state = &main_state;
state->ram_size = CFG_SYS_SDRAM_SIZE;
- state->ram_buf = os_malloc(state->ram_size);
+ state->mmap_addr = os_malloc(state->ram_size + SB_SDRAM_ALIGN);
+ state->ram_buf = (uint8_t *)ALIGN((uintptr_t)state->mmap_addr,
+ SB_SDRAM_ALIGN);
if (!state->ram_buf) {
printf("Out of memory\n");
os_exit(1);
@@ -533,7 +535,7 @@
trace_set_enabled(0);
os_free(state->state_fdt);
- os_free(state->ram_buf);
+ os_free(state->mmap_addr);
memset(state, '\0', sizeof(*state));
return 0;
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index dc21a62..9dea098 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -75,6 +75,7 @@
char **argv; /* Command line arguments */
const char *jumped_fname; /* Jumped from previous U-Boot */
const char *prog_fname; /* U-Boot executable filename */
+ uint8_t *mmap_addr; /* Memory allocated via mmap */
uint8_t *ram_buf; /* Emulated RAM buffer */
unsigned long ram_size; /* Size of RAM buffer */
const char *ram_buf_fname; /* Filename to use for RAM buffer */
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index d97945e..43f4edc 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -101,7 +101,6 @@
int dram_init(void)
{
- gd->ram_size = CFG_SYS_SDRAM_SIZE;
return 0;
}
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index db2ac7f..44d4960 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -14,6 +14,8 @@
#define CFG_SYS_SDRAM_BASE 0
#define CFG_SYS_SDRAM_SIZE \
(SB_TO_UL(CONFIG_SANDBOX_RAM_SIZE_MB) << 20)
+/** define SB_SDRAM_ALIGN - Alignment of emulated RAM */
+#define SB_SDRAM_ALIGN 0x400000
#define CFG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
diff --git a/test/lib/Makefile b/test/lib/Makefile
index ff4ff63..35b40b5 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -8,7 +8,7 @@
ifeq ($(CONFIG_XPL_BUILD),)
obj-y += abuf.o
obj-y += alist.o
-obj-$(CONFIG_EFI_LOADER) += efi_device_path.o
+obj-$(CONFIG_EFI_LOADER) += efi_device_path.o efi_memory.o
obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
obj-y += hexdump.o
obj-$(CONFIG_SANDBOX) += kconfig.o
diff --git a/test/lib/efi_memory.c b/test/lib/efi_memory.c
new file mode 100644
index 0000000..d2e1ab6
--- /dev/null
+++ b/test/lib/efi_memory.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Test memory functions
+ *
+ * Copyright (c) 2025 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <efi_loader.h>
+#include <test/lib.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static int lib_test_efi_alloc_aligned_pages(struct unit_test_state *uts)
+{
+ efi_status_t ret;
+
+ void *addr;
+ unsigned long align = 0x400000;
+
+ addr = efi_alloc_aligned_pages(4096, EFI_PERSISTENT_MEMORY_TYPE,
+ EFI_PAGE_SIZE);
+ ut_asserteq_ptr(NULL, addr);
+
+ addr = efi_alloc_aligned_pages(4096, 0x6FFFFFFF, EFI_PAGE_SIZE);
+ ut_asserteq_ptr(NULL, addr);
+
+ align = 0x200;
+ addr = efi_alloc_aligned_pages(4096, EFI_ACPI_RECLAIM_MEMORY, align);
+ ut_assertnonnull(addr);
+ ut_asserteq_64(0, (uintptr_t)addr & (align - 1));
+
+ ret = efi_free_pages((uintptr_t) addr, 1);
+ ut_asserteq_64(ret, EFI_SUCCESS);
+
+ align = 0x400000;
+ addr = efi_alloc_aligned_pages(4096, EFI_ACPI_RECLAIM_MEMORY, align);
+ ut_assertnonnull(addr);
+ ut_asserteq_64(0, (uintptr_t)addr & (align - 1));
+
+ ret = efi_free_pages((uintptr_t) addr, 1);
+ ut_asserteq_64(ret, EFI_SUCCESS);
+
+ return 0;
+}
+LIB_TEST(lib_test_efi_alloc_aligned_pages, 0);
+
+static int lib_test_efi_allocate_pages(struct unit_test_state *uts)
+{
+ efi_status_t ret;
+ u64 memory;
+
+ ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+ EFI_ACPI_RECLAIM_MEMORY,
+ 1, &memory);
+ ut_asserteq_64(ret, EFI_SUCCESS);
+ ut_asserteq_64(0, memory & EFI_PAGE_MASK);
+
+ ret = efi_free_pages(memory, 1);
+ ut_asserteq_64(ret, EFI_SUCCESS);
+
+ return 0;
+}
+LIB_TEST(lib_test_efi_allocate_pages, 0);