[PATCH 00/16] Make EFI memory allocations synchronous with LMB

This is part two of the series to have the EFI and LMB modules have a coherent view of memory. Part one of this goal was to change the LMB module to have a global and persistent memory map. Those patches have now been applied to the next branch.
These patches are changing the EFI memory allocation API's such that they rely on the LMB module to allocate RAM memory. This fixes the current scenario where the EFI memory module has no visibility of the allocations/reservations made by the LMB module. One thing to note here is that this is limited to the RAM memory region, i.e. the EFI_CONVENTIONAL_MEMORY type. Any other memory type that is to be added to the EFI memory map, still gets handled by the EFI memory module.
Note: To be applied on top of the next branch.
Sughosh Ganu (16): lmb: add versions of the lmb API with flags lmb: add a flag to allow suppressing memory map change notification efi: memory: use the lmb API's for allocating and freeing memory event: add event to notify lmb memory map changes lib: Kconfig: add a config symbol for getting lmb memory map updates add a function to check if an address is in RAM memory lmb: notify of any changes to the LMB memory map efi_memory: add an event handler to update memory map ti: k3: remove efi_add_known_memory() function definition stm32mp: remove efi_add_known_memory() function definition lmb: allow for boards to specify memory map layerscape: use the lmb API's to add RAM memory x86: e820: use the lmb API for adding RAM memory efi_memory: do not add RAM memory to the memory map lmb: remove call to efi_lmb_reserve() test: event: update the expected event dump output
arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 8 +- arch/arm/mach-k3/common.c | 11 -- arch/arm/mach-stm32mp/dram_init.c | 11 -- arch/x86/lib/e820.c | 47 ++++-- common/board_r.c | 5 + common/event.c | 2 + include/efi_loader.h | 12 +- include/event.h | 14 ++ include/lmb.h | 11 ++ lib/Kconfig | 30 ++++ lib/efi_loader/Kconfig | 3 + lib/efi_loader/efi_memory.c | 184 ++++++++---------------- lib/lmb.c | 146 +++++++++++++------ test/py/tests/test_event_dump.py | 1 + 14 files changed, 276 insertions(+), 209 deletions(-)

The LMB module is to be used as a backend for allocating and freeing up memory requested from other modules like EFI. These memory requests are different from the typical LMB reservations in that memory required by the EFI module cannot be overwritten, or re-requested. Add versions of the LMB API functions with flags for allocating and freeing up memory. The caller can then use these API's for specifying the type of memory that is required. For now, these functions will be used by the EFI memory module.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- include/lmb.h | 6 ++++++ lib/lmb.c | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/include/lmb.h b/include/lmb.h index fc2daaa7bf..45a06c3b99 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -86,8 +86,13 @@ long lmb_reserve(phys_addr_t base, phys_size_t size); long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags); phys_addr_t lmb_alloc(phys_size_t size, ulong align); +phys_addr_t lmb_alloc_flags(phys_size_t size, ulong align, uint flags); phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr); +phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, + phys_addr_t max_addr, uint flags); phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size); +phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size, + uint flags); phys_size_t lmb_get_free_size(phys_addr_t addr);
/** @@ -103,6 +108,7 @@ phys_size_t lmb_get_free_size(phys_addr_t addr); int lmb_is_reserved_flags(phys_addr_t addr, int flags);
long lmb_free(phys_addr_t base, phys_size_t size); +long lmb_free_flags(phys_addr_t base, phys_size_t size, uint flags);
void lmb_dump_all(void); void lmb_dump_all_force(void); diff --git a/lib/lmb.c b/lib/lmb.c index 3ed570fb29..da6a1595cc 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -479,7 +479,7 @@ long lmb_add(phys_addr_t base, phys_size_t size) return lmb_add_region(lmb_rgn_lst, base, size); }
-long lmb_free(phys_addr_t base, phys_size_t size) +static long __lmb_free(phys_addr_t base, phys_size_t size) { struct lmb_region *rgn; struct alist *lmb_rgn_lst = &lmb.used_mem; @@ -530,6 +530,17 @@ long lmb_free(phys_addr_t base, phys_size_t size) rgn[i].flags); }
+long lmb_free(phys_addr_t base, phys_size_t size) +{ + return __lmb_free(base, size); +} + +long lmb_free_flags(phys_addr_t base, phys_size_t size, + __always_unused uint flags) +{ + return __lmb_free(base, size); +} + long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags) { struct alist *lmb_rgn_lst = &lmb.used_mem; @@ -613,6 +624,12 @@ phys_addr_t lmb_alloc(phys_size_t size, ulong align) return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE); }
+phys_addr_t lmb_alloc_flags(phys_size_t size, ulong align, uint flags) +{ + return __lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE, + flags); +} + phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) { phys_addr_t alloc; @@ -626,6 +643,20 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) return alloc; }
+phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, + phys_addr_t max_addr, uint flags) +{ + phys_addr_t alloc; + + alloc = __lmb_alloc_base(size, align, max_addr, flags); + + if (alloc == 0) + printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", + (ulong)size, (ulong)max_addr); + + return alloc; +} + static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, enum lmb_flags flags) { @@ -660,6 +691,12 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) return __lmb_alloc_addr(base, size, LMB_NONE); }
+phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size, + uint flags) +{ + return __lmb_alloc_addr(base, size, flags); +} + /* Return number of bytes from a given address that are free */ phys_size_t lmb_get_free_size(phys_addr_t addr) {

On 9/5/24 10:27, Sughosh Ganu wrote:
The LMB module is to be used as a backend for allocating and freeing up memory requested from other modules like EFI. These memory requests are different from the typical LMB reservations in that memory required by the EFI module cannot be overwritten, or re-requested. Add versions of the LMB API functions with flags for allocating and freeing up memory. The caller can then use these API's for specifying the type of memory that is required. For now, these functions will be used by the EFI memory module.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
include/lmb.h | 6 ++++++ lib/lmb.c | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/include/lmb.h b/include/lmb.h index fc2daaa7bf..45a06c3b99 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -86,8 +86,13 @@ long lmb_reserve(phys_addr_t base, phys_size_t size); long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags); phys_addr_t lmb_alloc(phys_size_t size, ulong align); +phys_addr_t lmb_alloc_flags(phys_size_t size, ulong align, uint flags);
Please, provide Sphinx style function descriptions for the functions that you are adding or changing.
Cf. https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html#function-do...
Best regards
Heinrich
phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr); +phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align,
phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size);phys_addr_t max_addr, uint flags);
+phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size,
uint flags);
phys_size_t lmb_get_free_size(phys_addr_t addr);
/**
@@ -103,6 +108,7 @@ phys_size_t lmb_get_free_size(phys_addr_t addr); int lmb_is_reserved_flags(phys_addr_t addr, int flags);
long lmb_free(phys_addr_t base, phys_size_t size); +long lmb_free_flags(phys_addr_t base, phys_size_t size, uint flags);
void lmb_dump_all(void); void lmb_dump_all_force(void); diff --git a/lib/lmb.c b/lib/lmb.c index 3ed570fb29..da6a1595cc 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -479,7 +479,7 @@ long lmb_add(phys_addr_t base, phys_size_t size) return lmb_add_region(lmb_rgn_lst, base, size); }
-long lmb_free(phys_addr_t base, phys_size_t size) +static long __lmb_free(phys_addr_t base, phys_size_t size) { struct lmb_region *rgn; struct alist *lmb_rgn_lst = &lmb.used_mem; @@ -530,6 +530,17 @@ long lmb_free(phys_addr_t base, phys_size_t size) rgn[i].flags); }
+long lmb_free(phys_addr_t base, phys_size_t size) +{
- return __lmb_free(base, size);
+}
+long lmb_free_flags(phys_addr_t base, phys_size_t size,
__always_unused uint flags)
+{
- return __lmb_free(base, size);
+}
- long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags) { struct alist *lmb_rgn_lst = &lmb.used_mem;
@@ -613,6 +624,12 @@ phys_addr_t lmb_alloc(phys_size_t size, ulong align) return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE); }
+phys_addr_t lmb_alloc_flags(phys_size_t size, ulong align, uint flags) +{
- return __lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE,
flags);
+}
- phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) { phys_addr_t alloc;
@@ -626,6 +643,20 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) return alloc; }
+phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align,
phys_addr_t max_addr, uint flags)
+{
- phys_addr_t alloc;
- alloc = __lmb_alloc_base(size, align, max_addr, flags);
- if (alloc == 0)
printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
(ulong)size, (ulong)max_addr);
- return alloc;
+}
- static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, enum lmb_flags flags) {
@@ -660,6 +691,12 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) return __lmb_alloc_addr(base, size, LMB_NONE); }
+phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size,
uint flags)
+{
- return __lmb_alloc_addr(base, size, flags);
+}
- /* Return number of bytes from a given address that are free */ phys_size_t lmb_get_free_size(phys_addr_t addr) {

On Sat, 14 Sept 2024 at 20:01, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
The LMB module is to be used as a backend for allocating and freeing up memory requested from other modules like EFI. These memory requests are different from the typical LMB reservations in that memory required by the EFI module cannot be overwritten, or re-requested. Add versions of the LMB API functions with flags for allocating and freeing up memory. The caller can then use these API's for specifying the type of memory that is required. For now, these functions will be used by the EFI memory module.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
include/lmb.h | 6 ++++++ lib/lmb.c | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/include/lmb.h b/include/lmb.h index fc2daaa7bf..45a06c3b99 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -86,8 +86,13 @@ long lmb_reserve(phys_addr_t base, phys_size_t size); long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags); phys_addr_t lmb_alloc(phys_size_t size, ulong align); +phys_addr_t lmb_alloc_flags(phys_size_t size, ulong align, uint flags);
Please, provide Sphinx style function descriptions for the functions that you are adding or changing.
Will do. Thanks.
-sughosh
Cf. https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html#function-do...
Best regards
Heinrich
phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr); +phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align,
phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size);phys_addr_t max_addr, uint flags);
+phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size,
uint flags);
phys_size_t lmb_get_free_size(phys_addr_t addr);
/**
@@ -103,6 +108,7 @@ phys_size_t lmb_get_free_size(phys_addr_t addr); int lmb_is_reserved_flags(phys_addr_t addr, int flags);
long lmb_free(phys_addr_t base, phys_size_t size); +long lmb_free_flags(phys_addr_t base, phys_size_t size, uint flags);
void lmb_dump_all(void); void lmb_dump_all_force(void); diff --git a/lib/lmb.c b/lib/lmb.c index 3ed570fb29..da6a1595cc 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -479,7 +479,7 @@ long lmb_add(phys_addr_t base, phys_size_t size) return lmb_add_region(lmb_rgn_lst, base, size); }
-long lmb_free(phys_addr_t base, phys_size_t size) +static long __lmb_free(phys_addr_t base, phys_size_t size) { struct lmb_region *rgn; struct alist *lmb_rgn_lst = &lmb.used_mem; @@ -530,6 +530,17 @@ long lmb_free(phys_addr_t base, phys_size_t size) rgn[i].flags); }
+long lmb_free(phys_addr_t base, phys_size_t size) +{
return __lmb_free(base, size);
+}
+long lmb_free_flags(phys_addr_t base, phys_size_t size,
__always_unused uint flags)
+{
return __lmb_free(base, size);
+}
- long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags) { struct alist *lmb_rgn_lst = &lmb.used_mem;
@@ -613,6 +624,12 @@ phys_addr_t lmb_alloc(phys_size_t size, ulong align) return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE); }
+phys_addr_t lmb_alloc_flags(phys_size_t size, ulong align, uint flags) +{
return __lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE,
flags);
+}
- phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) { phys_addr_t alloc;
@@ -626,6 +643,20 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) return alloc; }
+phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align,
phys_addr_t max_addr, uint flags)
+{
phys_addr_t alloc;
alloc = __lmb_alloc_base(size, align, max_addr, flags);
if (alloc == 0)
printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
(ulong)size, (ulong)max_addr);
return alloc;
+}
- static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, enum lmb_flags flags) {
@@ -660,6 +691,12 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) return __lmb_alloc_addr(base, size, LMB_NONE); }
+phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size,
uint flags)
+{
return __lmb_alloc_addr(base, size, flags);
+}
- /* Return number of bytes from a given address that are free */ phys_size_t lmb_get_free_size(phys_addr_t addr) {

Add a flag LMB_NONOTIFY that can be passed to the LMB API's for reserving memory. This will then result in no notification being sent from the LMB module for the changes to the LMB's memory map.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- include/lmb.h | 1 + lib/lmb.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/lmb.h b/include/lmb.h index 45a06c3b99..ffba7e2889 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -23,6 +23,7 @@ enum lmb_flags { LMB_NONE = 0, LMB_NOMAP = BIT(1), LMB_NOOVERWRITE = BIT(2), + LMB_NONOTIFY = BIT(3), };
/** diff --git a/lib/lmb.c b/lib/lmb.c index da6a1595cc..419b31a651 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -30,7 +30,7 @@ static struct lmb lmb; static void lmb_print_region_flags(enum lmb_flags flags) { u64 bitpos; - const char *flag_str[] = { "none", "no-map", "no-overwrite" }; + const char *flag_str[] = { "none", "no-map", "no-overwrite", "no-notify" };
do { bitpos = flags ? fls(flags) - 1 : 0;

On 9/5/24 10:27, Sughosh Ganu wrote:
Add a flag LMB_NONOTIFY that can be passed to the LMB API's for reserving memory. This will then result in no notification being sent from the LMB module for the changes to the LMB's memory map.
You seem to be using this in patch 3 and 7.
Please, describe in this patch why you want to be able to suppress notification.
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
include/lmb.h | 1 + lib/lmb.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/lmb.h b/include/lmb.h index 45a06c3b99..ffba7e2889 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -23,6 +23,7 @@ enum lmb_flags { LMB_NONE = 0, LMB_NOMAP = BIT(1), LMB_NOOVERWRITE = BIT(2),
LMB_NONOTIFY = BIT(3), };
/**
diff --git a/lib/lmb.c b/lib/lmb.c index da6a1595cc..419b31a651 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -30,7 +30,7 @@ static struct lmb lmb; static void lmb_print_region_flags(enum lmb_flags flags) { u64 bitpos;
- const char *flag_str[] = { "none", "no-map", "no-overwrite" };
const char *flag_str[] = { "none", "no-map", "no-overwrite", "no-notify" };
do { bitpos = flags ? fls(flags) - 1 : 0;

On Sat, 14 Sept 2024 at 20:14, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add a flag LMB_NONOTIFY that can be passed to the LMB API's for reserving memory. This will then result in no notification being sent from the LMB module for the changes to the LMB's memory map.
You seem to be using this in patch 3 and 7.
Please, describe in this patch why you want to be able to suppress notification.
Will add the reasoning behind this flag in the commit message.
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
So, do you want me to use the EFI event signaling mechanism for this purpose ? Is my understanding correct ? If so, this will mean that we have an event notification specifically for EFI, and there might be one needed for any other consumers of this event. Currently there aren't any other consumers of the LMB memory map change event other than EFI, but using the U-Boot's event notification mechanism means that the same notification mechanism can be used if there were any additional consumers of this event in the future. In that case, we would have two separate event notifications, one for EFI, and one for non-EFI consumers.
-sughosh
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
include/lmb.h | 1 + lib/lmb.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/lmb.h b/include/lmb.h index 45a06c3b99..ffba7e2889 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -23,6 +23,7 @@ enum lmb_flags { LMB_NONE = 0, LMB_NOMAP = BIT(1), LMB_NOOVERWRITE = BIT(2),
LMB_NONOTIFY = BIT(3),
};
/**
diff --git a/lib/lmb.c b/lib/lmb.c index da6a1595cc..419b31a651 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -30,7 +30,7 @@ static struct lmb lmb; static void lmb_print_region_flags(enum lmb_flags flags) { u64 bitpos;
const char *flag_str[] = { "none", "no-map", "no-overwrite" };
const char *flag_str[] = { "none", "no-map", "no-overwrite", "no-notify" }; do { bitpos = flags ? fls(flags) - 1 : 0;

Hi,
On Tue, 17 Sept 2024 at 13:55, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:14, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add a flag LMB_NONOTIFY that can be passed to the LMB API's for reserving memory. This will then result in no notification being sent from the LMB module for the changes to the LMB's memory map.
You seem to be using this in patch 3 and 7.
Please, describe in this patch why you want to be able to suppress notification.
Will add the reasoning behind this flag in the commit message.
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
So, do you want me to use the EFI event signaling mechanism for this purpose ? Is my understanding correct ? If so, this will mean that we have an event notification specifically for EFI, and there might be one needed for any other consumers of this event. Currently there aren't any other consumers of the LMB memory map change event other than EFI, but using the U-Boot's event notification mechanism means that the same notification mechanism can be used if there were any additional consumers of this event in the future. In that case, we would have two separate event notifications, one for EFI, and one for non-EFI consumers.
As I have previously said, none of this is necessary.
Essentially all of the EFI setup that is done in U-Boot can be delayed until we are actually starting an EFI app. The current approach of keeping parallel EFI tables everywhere is causing much confusion.
For EFI, it should be enough to read the lmb tables at the end and add whatever parallel tables are needed to boot the app. We should not need to keep things in sync through the life of U-Boot, since:
1. EFI pool-allocations should use malloc() until the app starts 2. EFI page allocations should not be allowed until the app starts
This whole area needs a healthy dose of 'keep it simple'.
Regards, Simon

On Thu, 19 Sept 2024 at 19:42, Simon Glass sjg@chromium.org wrote:
Hi,
On Tue, 17 Sept 2024 at 13:55, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:14, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add a flag LMB_NONOTIFY that can be passed to the LMB API's for reserving memory. This will then result in no notification being sent from the LMB module for the changes to the LMB's memory map.
You seem to be using this in patch 3 and 7.
Please, describe in this patch why you want to be able to suppress notification.
Will add the reasoning behind this flag in the commit message.
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
So, do you want me to use the EFI event signaling mechanism for this purpose ? Is my understanding correct ? If so, this will mean that we have an event notification specifically for EFI, and there might be one needed for any other consumers of this event. Currently there aren't any other consumers of the LMB memory map change event other than EFI, but using the U-Boot's event notification mechanism means that the same notification mechanism can be used if there were any additional consumers of this event in the future. In that case, we would have two separate event notifications, one for EFI, and one for non-EFI consumers.
As I have previously said, none of this is necessary.
Essentially all of the EFI setup that is done in U-Boot can be delayed until we are actually starting an EFI app. The current approach of keeping parallel EFI tables everywhere is causing much confusion.
For EFI, it should be enough to read the lmb tables at the end and add whatever parallel tables are needed to boot the app. We should not need to keep things in sync through the life of U-Boot, since:
- EFI pool-allocations should use malloc() until the app starts
- EFI page allocations should not be allowed until the app starts
This whole area needs a healthy dose of 'keep it simple'.
Except, the current implementation proposed by the patch *is* actually much more simpler than syncing the maps when the app starts. Because there is another scenario when the map needs to be synced, when the user issues a 'efidebug memmap' command, which dumps the efi memory map.
Syncing the map from lmb means that the efi memory map first has to be generated afresh. And that is much more complicated than the method incorporated in the patch series. Apart from the ram/conventional memory type, we also need to include other memory types that might have been added to the memory map. So, this would mean, create a new memory map, add entries for conventional memory as have been obtained from lmb followed by other entries, and then discard the old memory map. And this has to be carried out every time a need for a memory map update is needed.
-sughosh
Regards, Simon

Hi Sughosh,
On Fri, 20 Sept 2024 at 06:33, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Thu, 19 Sept 2024 at 19:42, Simon Glass sjg@chromium.org wrote:
Hi,
On Tue, 17 Sept 2024 at 13:55, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:14, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add a flag LMB_NONOTIFY that can be passed to the LMB API's for reserving memory. This will then result in no notification being sent from the LMB module for the changes to the LMB's memory map.
You seem to be using this in patch 3 and 7.
Please, describe in this patch why you want to be able to suppress notification.
Will add the reasoning behind this flag in the commit message.
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
So, do you want me to use the EFI event signaling mechanism for this purpose ? Is my understanding correct ? If so, this will mean that we have an event notification specifically for EFI, and there might be one needed for any other consumers of this event. Currently there aren't any other consumers of the LMB memory map change event other than EFI, but using the U-Boot's event notification mechanism means that the same notification mechanism can be used if there were any additional consumers of this event in the future. In that case, we would have two separate event notifications, one for EFI, and one for non-EFI consumers.
As I have previously said, none of this is necessary.
Essentially all of the EFI setup that is done in U-Boot can be delayed until we are actually starting an EFI app. The current approach of keeping parallel EFI tables everywhere is causing much confusion.
For EFI, it should be enough to read the lmb tables at the end and add whatever parallel tables are needed to boot the app. We should not need to keep things in sync through the life of U-Boot, since:
- EFI pool-allocations should use malloc() until the app starts
- EFI page allocations should not be allowed until the app starts
This whole area needs a healthy dose of 'keep it simple'.
Except, the current implementation proposed by the patch *is* actually much more simpler than syncing the maps when the app starts. Because there is another scenario when the map needs to be synced, when the user issues a 'efidebug memmap' command, which dumps the efi memory map.
Syncing the map from lmb means that the efi memory map first has to be generated afresh. And that is much more complicated than the method incorporated in the patch series. Apart from the ram/conventional memory type, we also need to include other memory types that might have been added to the memory map. So, this would mean, create a new memory map, add entries for conventional memory as have been obtained from lmb followed by other entries, and then discard the old memory map. And this has to be carried out every time a need for a memory map update is needed.
We are just not on the same page here. But I've replied to this point on your other email. Also please understand that my objective is actually to not do EFI allocations until just before the EFI app actually starts (when we set up the EFI memory map). Until then, I believe malloc() suffices.
Regards, Simon

Hi Simon,
On Thu, 19 Sept 2024 at 17:12, Simon Glass sjg@chromium.org wrote:
Hi,
On Tue, 17 Sept 2024 at 13:55, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:14, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add a flag LMB_NONOTIFY that can be passed to the LMB API's for reserving memory. This will then result in no notification being sent from the LMB module for the changes to the LMB's memory map.
You seem to be using this in patch 3 and 7.
Please, describe in this patch why you want to be able to suppress notification.
Will add the reasoning behind this flag in the commit message.
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
So, do you want me to use the EFI event signaling mechanism for this purpose ? Is my understanding correct ? If so, this will mean that we have an event notification specifically for EFI, and there might be one needed for any other consumers of this event. Currently there aren't any other consumers of the LMB memory map change event other than EFI, but using the U-Boot's event notification mechanism means that the same notification mechanism can be used if there were any additional consumers of this event in the future. In that case, we would have two separate event notifications, one for EFI, and one for non-EFI consumers.
As I have previously said, none of this is necessary.
Essentially all of the EFI setup that is done in U-Boot can be delayed until we are actually starting an EFI app.
Can you explain how you plan to deal with EFI variables, the TPM eventlog, measuring events when tables are added, capsules updates etc etc, which expect certain EFI services to be up and running?
The current approach of keeping parallel EFI tables everywhere is causing much confusion.
Apart from all of the above the EFI app can return. Which makes all of the above just a burden
For EFI, it should be enough to read the lmb tables at the end and add whatever parallel tables are needed to boot the app.
Yes apart from the fact that LMB has no idea about memory types or permissions.
We should not need to keep things in sync through the life of U-Boot, since:
- EFI pool-allocations should use malloc() until the app starts
- EFI page allocations should not be allowed until the app starts
This whole area needs a healthy dose of 'keep it simple'.
Regards, Simon
Thanks /Ilias

Hi Ilias,
On Fri, 27 Sept 2024 at 05:08, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Simon,
On Thu, 19 Sept 2024 at 17:12, Simon Glass sjg@chromium.org wrote:
Hi,
On Tue, 17 Sept 2024 at 13:55, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:14, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add a flag LMB_NONOTIFY that can be passed to the LMB API's for reserving memory. This will then result in no notification being sent from the LMB module for the changes to the LMB's memory map.
You seem to be using this in patch 3 and 7.
Please, describe in this patch why you want to be able to suppress notification.
Will add the reasoning behind this flag in the commit message.
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
So, do you want me to use the EFI event signaling mechanism for this purpose ? Is my understanding correct ? If so, this will mean that we have an event notification specifically for EFI, and there might be one needed for any other consumers of this event. Currently there aren't any other consumers of the LMB memory map change event other than EFI, but using the U-Boot's event notification mechanism means that the same notification mechanism can be used if there were any additional consumers of this event in the future. In that case, we would have two separate event notifications, one for EFI, and one for non-EFI consumers.
As I have previously said, none of this is necessary.
Essentially all of the EFI setup that is done in U-Boot can be delayed until we are actually starting an EFI app.
Can you explain how you plan to deal with EFI variables, the TPM eventlog, measuring events when tables are added, capsules updates etc etc, which expect certain EFI services to be up and running?
Yes, sure. Accessing EFI variables is going to require EFI to be inited, I assume. For capsule updates, I believe that is triggered on boot, so again it would need EFI services. It's fine to use EFI when it is needed. But this memory-map thing has really got out of hand. BTW we need TPM eventlog and measuring for any type of boot so it needs to work without EFI.
The current approach of keeping parallel EFI tables everywhere is causing much confusion.
Apart from all of the above the EFI app can return. Which makes all of the above just a burden
It's fine if it returns, isn't it? What is the burden?
For EFI, it should be enough to read the lmb tables at the end and add whatever parallel tables are needed to boot the app.
Yes apart from the fact that LMB has no idea about memory types or permissions.
Neither should it. It is for laying out images in memory. We need to maintain some separation of concerns here, or we'll end up with a complex mess. Memory types are really an EFI construct which should be easy enough to add statically - e.g. U-Boot code is EFI_BOOT_SERVICES_CODE. Memory permissions are known based on the memory areas, so I don't think lmb needs to know about that.
We should not need to keep things in sync through the life of U-Boot, since:
- EFI pool-allocations should use malloc() until the app starts
- EFI page allocations should not be allowed until the app starts
This whole area needs a healthy dose of 'keep it simple'.
Regards, Simon

Use the LMB API's for allocating and freeing up memory. With this, the LMB module becomes the common backend for managing non U-Boot image memory that might be requested by other modules.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- lib/efi_loader/Kconfig | 1 + lib/efi_loader/efi_memory.c | 74 ++++++++++--------------------------- 2 files changed, 21 insertions(+), 54 deletions(-)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6ffefa9103..911d4c6bbe 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -18,6 +18,7 @@ config EFI_LOADER select DM_EVENT select EVENT_DYNAMIC select LIB_UUID + select LMB imply PARTITION_UUIDS select REGEX imply FAT diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index c6f1dd0945..90e07ed6a2 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -9,6 +9,7 @@
#include <efi_loader.h> #include <init.h> +#include <lmb.h> #include <log.h> #include <malloc.h> #include <mapmem.h> @@ -432,53 +433,6 @@ static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated) return EFI_NOT_FOUND; }
-/** - * efi_find_free_memory() - find free memory pages - * - * @len: size of memory area needed - * @max_addr: highest address to allocate - * Return: pointer to free memory area or 0 - */ -static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) -{ - struct efi_mem_list *lmem; - - /* - * Prealign input max address, so we simplify our matching - * logic below and can just reuse it as return pointer. - */ - max_addr &= ~EFI_PAGE_MASK; - - list_for_each_entry(lmem, &efi_mem, link) { - struct efi_mem_desc *desc = &lmem->desc; - uint64_t desc_len = desc->num_pages << EFI_PAGE_SHIFT; - uint64_t desc_end = desc->physical_start + desc_len; - uint64_t curmax = min(max_addr, desc_end); - uint64_t ret = curmax - len; - - /* We only take memory from free RAM */ - if (desc->type != EFI_CONVENTIONAL_MEMORY) - continue; - - /* Out of bounds for max_addr */ - if ((ret + len) > max_addr) - continue; - - /* Out of bounds for upper map limit */ - if ((ret + len) > desc_end) - continue; - - /* Out of bounds for lower map limit */ - if (ret < desc->physical_start) - continue; - - /* Return the highest address in this map within bounds */ - return ret; - } - - return 0; -} - /** * efi_allocate_pages - allocate memory pages * @@ -493,6 +447,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, efi_uintn_t pages, uint64_t *memory) { u64 len; + uint flags; efi_status_t ret; uint64_t addr;
@@ -508,33 +463,35 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, (len >> EFI_PAGE_SHIFT) != (u64)pages) return EFI_OUT_OF_RESOURCES;
+ flags = LMB_NOOVERWRITE | LMB_NONOTIFY; switch (type) { case EFI_ALLOCATE_ANY_PAGES: /* Any page */ - addr = efi_find_free_memory(len, -1ULL); + addr = (u64)lmb_alloc_flags(len, EFI_PAGE_SIZE, flags); if (!addr) return EFI_OUT_OF_RESOURCES; break; case EFI_ALLOCATE_MAX_ADDRESS: /* Max address */ - addr = efi_find_free_memory(len, *memory); + addr = (u64)lmb_alloc_base_flags(len, EFI_PAGE_SIZE, *memory, + flags); if (!addr) return EFI_OUT_OF_RESOURCES; break; case EFI_ALLOCATE_ADDRESS: if (*memory & EFI_PAGE_MASK) return EFI_NOT_FOUND; - /* Exact address, reserve it. The addr is already in *memory. */ - ret = efi_check_allocated(*memory, false); - if (ret != EFI_SUCCESS) - return EFI_NOT_FOUND; - addr = *memory; + + addr = (u64)lmb_alloc_addr_flags(*memory, len, flags); + if (!addr) + return EFI_OUT_OF_RESOURCES; break; default: /* UEFI doesn't specify other allocation types */ return EFI_INVALID_PARAMETER; }
+ addr = (u64)(uintptr_t)map_sysmem(addr, 0); /* Reserve that map in our memory maps */ ret = efi_add_memory_map_pg(addr, pages, memory_type, true); if (ret != EFI_SUCCESS) @@ -555,6 +512,9 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, */ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) { + u64 len; + uint flags; + long status; efi_status_t ret;
ret = efi_check_allocated(memory, true); @@ -568,6 +528,12 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) return EFI_INVALID_PARAMETER; }
+ flags = LMB_NOOVERWRITE | LMB_NONOTIFY; + len = (u64)pages << EFI_PAGE_SHIFT; + status = lmb_free_flags(memory, len, flags); + if (status) + return EFI_NOT_FOUND; + ret = efi_add_memory_map_pg(memory, pages, EFI_CONVENTIONAL_MEMORY, false); if (ret != EFI_SUCCESS)

On 9/5/24 10:27, Sughosh Ganu wrote:
Use the LMB API's for allocating and freeing up memory. With this, the LMB module becomes the common backend for managing non U-Boot image memory that might be requested by other modules.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
lib/efi_loader/Kconfig | 1 + lib/efi_loader/efi_memory.c | 74 ++++++++++--------------------------- 2 files changed, 21 insertions(+), 54 deletions(-)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6ffefa9103..911d4c6bbe 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -18,6 +18,7 @@ config EFI_LOADER select DM_EVENT select EVENT_DYNAMIC select LIB_UUID
- select LMB imply PARTITION_UUIDS select REGEX imply FAT
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index c6f1dd0945..90e07ed6a2 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -9,6 +9,7 @@
#include <efi_loader.h> #include <init.h> +#include <lmb.h> #include <log.h> #include <malloc.h> #include <mapmem.h> @@ -432,53 +433,6 @@ static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated) return EFI_NOT_FOUND; }
-/**
- efi_find_free_memory() - find free memory pages
- @len: size of memory area needed
- @max_addr: highest address to allocate
- Return: pointer to free memory area or 0
- */
-static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) -{
- struct efi_mem_list *lmem;
- /*
* Prealign input max address, so we simplify our matching
* logic below and can just reuse it as return pointer.
*/
- max_addr &= ~EFI_PAGE_MASK;
- list_for_each_entry(lmem, &efi_mem, link) {
struct efi_mem_desc *desc = &lmem->desc;
uint64_t desc_len = desc->num_pages << EFI_PAGE_SHIFT;
uint64_t desc_end = desc->physical_start + desc_len;
uint64_t curmax = min(max_addr, desc_end);
uint64_t ret = curmax - len;
/* We only take memory from free RAM */
if (desc->type != EFI_CONVENTIONAL_MEMORY)
continue;
/* Out of bounds for max_addr */
if ((ret + len) > max_addr)
continue;
/* Out of bounds for upper map limit */
if ((ret + len) > desc_end)
continue;
/* Out of bounds for lower map limit */
if (ret < desc->physical_start)
continue;
/* Return the highest address in this map within bounds */
return ret;
- }
- return 0;
-}
- /**
- efi_allocate_pages - allocate memory pages
@@ -493,6 +447,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, efi_uintn_t pages, uint64_t *memory) { u64 len;
- uint flags; efi_status_t ret; uint64_t addr;
@@ -508,33 +463,35 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, (len >> EFI_PAGE_SHIFT) != (u64)pages) return EFI_OUT_OF_RESOURCES;
- flags = LMB_NOOVERWRITE | LMB_NONOTIFY;
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event and update the memory map.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
switch (type) { case EFI_ALLOCATE_ANY_PAGES: /* Any page */
addr = efi_find_free_memory(len, -1ULL);
addr = (u64)lmb_alloc_flags(len, EFI_PAGE_SIZE, flags);
On ARM64 we must ensure that "all 4KiB pages in the 64KiB page ... use identical ARM Memory Page Attributes". I cannot see how LMB implements this.
See chapter 2.3.6 AArch64 Platforms in the UEFI specification.
If you pass the EFI memory type to LMB and store it there, we can avoid duplication of the memory map and we can implement the 64 KiB pages logic in LMB.
Best regards
Heinrich
if (!addr) return EFI_OUT_OF_RESOURCES; break;
case EFI_ALLOCATE_MAX_ADDRESS: /* Max address */
addr = efi_find_free_memory(len, *memory);
addr = (u64)lmb_alloc_base_flags(len, EFI_PAGE_SIZE, *memory,
if (!addr) return EFI_OUT_OF_RESOURCES; break; case EFI_ALLOCATE_ADDRESS: if (*memory & EFI_PAGE_MASK) return EFI_NOT_FOUND;flags);
/* Exact address, reserve it. The addr is already in *memory. */
ret = efi_check_allocated(*memory, false);
if (ret != EFI_SUCCESS)
return EFI_NOT_FOUND;
addr = *memory;
addr = (u64)lmb_alloc_addr_flags(*memory, len, flags);
if (!addr)
return EFI_OUT_OF_RESOURCES;
break; default: /* UEFI doesn't specify other allocation types */ return EFI_INVALID_PARAMETER; }
addr = (u64)(uintptr_t)map_sysmem(addr, 0); /* Reserve that map in our memory maps */ ret = efi_add_memory_map_pg(addr, pages, memory_type, true); if (ret != EFI_SUCCESS)
@@ -555,6 +512,9 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, */ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) {
u64 len;
uint flags;
long status; efi_status_t ret;
ret = efi_check_allocated(memory, true);
@@ -568,6 +528,12 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) return EFI_INVALID_PARAMETER; }
- flags = LMB_NOOVERWRITE | LMB_NONOTIFY;
- len = (u64)pages << EFI_PAGE_SHIFT;
- status = lmb_free_flags(memory, len, flags);
- if (status)
return EFI_NOT_FOUND;
- ret = efi_add_memory_map_pg(memory, pages, EFI_CONVENTIONAL_MEMORY, false); if (ret != EFI_SUCCESS)

On Sat, 14 Sept 2024 at 20:35, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Use the LMB API's for allocating and freeing up memory. With this, the LMB module becomes the common backend for managing non U-Boot image memory that might be requested by other modules.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
lib/efi_loader/Kconfig | 1 + lib/efi_loader/efi_memory.c | 74 ++++++++++--------------------------- 2 files changed, 21 insertions(+), 54 deletions(-)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6ffefa9103..911d4c6bbe 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -18,6 +18,7 @@ config EFI_LOADER select DM_EVENT select EVENT_DYNAMIC select LIB_UUID
select LMB imply PARTITION_UUIDS select REGEX imply FAT
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index c6f1dd0945..90e07ed6a2 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -9,6 +9,7 @@
#include <efi_loader.h> #include <init.h> +#include <lmb.h> #include <log.h> #include <malloc.h> #include <mapmem.h> @@ -432,53 +433,6 @@ static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated) return EFI_NOT_FOUND; }
-/**
- efi_find_free_memory() - find free memory pages
- @len: size of memory area needed
- @max_addr: highest address to allocate
- Return: pointer to free memory area or 0
- */
-static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) -{
struct efi_mem_list *lmem;
/*
* Prealign input max address, so we simplify our matching
* logic below and can just reuse it as return pointer.
*/
max_addr &= ~EFI_PAGE_MASK;
list_for_each_entry(lmem, &efi_mem, link) {
struct efi_mem_desc *desc = &lmem->desc;
uint64_t desc_len = desc->num_pages << EFI_PAGE_SHIFT;
uint64_t desc_end = desc->physical_start + desc_len;
uint64_t curmax = min(max_addr, desc_end);
uint64_t ret = curmax - len;
/* We only take memory from free RAM */
if (desc->type != EFI_CONVENTIONAL_MEMORY)
continue;
/* Out of bounds for max_addr */
if ((ret + len) > max_addr)
continue;
/* Out of bounds for upper map limit */
if ((ret + len) > desc_end)
continue;
/* Out of bounds for lower map limit */
if (ret < desc->physical_start)
continue;
/* Return the highest address in this map within bounds */
return ret;
}
return 0;
-}
- /**
- efi_allocate_pages - allocate memory pages
@@ -493,6 +447,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, efi_uintn_t pages, uint64_t *memory) { u64 len;
uint flags; efi_status_t ret; uint64_t addr;
@@ -508,33 +463,35 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, (len >> EFI_PAGE_SHIFT) != (u64)pages) return EFI_OUT_OF_RESOURCES;
flags = LMB_NOOVERWRITE | LMB_NONOTIFY;
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event and update the memory map.
Not sure if I am understanding your comment right, but what is happening here is that the EFI subsystem is requesting LMB for memory. And the reason why we have a flag LMB_NONOTIFY, is to prevent a circular chain of LMB then notifying EFI of a change to it's memory map.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
switch (type) { case EFI_ALLOCATE_ANY_PAGES: /* Any page */
addr = efi_find_free_memory(len, -1ULL);
addr = (u64)lmb_alloc_flags(len, EFI_PAGE_SIZE, flags);
On ARM64 we must ensure that "all 4KiB pages in the 64KiB page ... use identical ARM Memory Page Attributes". I cannot see how LMB implements this.
If you are referring to arm memory attributes, this is not being handled by the current EFI memory code as well. If this is to be handled, that needs to be taken up as a separate task -- I am not sure if U-Boot even has support in the form of any API's where memory regions can be configured for different memory attributes.
See chapter 2.3.6 AArch64 Platforms in the UEFI specification.
If you pass the EFI memory type to LMB and store it there, we can avoid duplication of the memory map and we can implement the 64 KiB pages logic in LMB.
Okay, that would mean mixing up EFI code in the LMB module. Again, not sure if this comes under the purview of the goal of this series, which is to ensure that EFI memory does not trample over that allocated by LMB. Also, thinking a bit more on this, if we are to address aspects like memory attributes etc, I feel that the earlier design that I had posted of notification between LMB and EFI to have a synchronous view of each other's memory would be a better approach. That way, the EFI memory module can then implement things that it needs to, from the EFI spec point of view, and the LMB module can then just update the EFI module of the memory that it is using.
-sughosh
Best regards
Heinrich
if (!addr) return EFI_OUT_OF_RESOURCES; break; case EFI_ALLOCATE_MAX_ADDRESS: /* Max address */
addr = efi_find_free_memory(len, *memory);
addr = (u64)lmb_alloc_base_flags(len, EFI_PAGE_SIZE, *memory,
flags); if (!addr) return EFI_OUT_OF_RESOURCES; break; case EFI_ALLOCATE_ADDRESS: if (*memory & EFI_PAGE_MASK) return EFI_NOT_FOUND;
/* Exact address, reserve it. The addr is already in *memory. */
ret = efi_check_allocated(*memory, false);
if (ret != EFI_SUCCESS)
return EFI_NOT_FOUND;
addr = *memory;
addr = (u64)lmb_alloc_addr_flags(*memory, len, flags);
if (!addr)
return EFI_OUT_OF_RESOURCES; break; default: /* UEFI doesn't specify other allocation types */ return EFI_INVALID_PARAMETER; }
addr = (u64)(uintptr_t)map_sysmem(addr, 0); /* Reserve that map in our memory maps */ ret = efi_add_memory_map_pg(addr, pages, memory_type, true); if (ret != EFI_SUCCESS)
@@ -555,6 +512,9 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, */ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) {
u64 len;
uint flags;
long status; efi_status_t ret; ret = efi_check_allocated(memory, true);
@@ -568,6 +528,12 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) return EFI_INVALID_PARAMETER; }
flags = LMB_NOOVERWRITE | LMB_NONOTIFY;
len = (u64)pages << EFI_PAGE_SHIFT;
status = lmb_free_flags(memory, len, flags);
if (status)
return EFI_NOT_FOUND;
ret = efi_add_memory_map_pg(memory, pages, EFI_CONVENTIONAL_MEMORY, false); if (ret != EFI_SUCCESS)

Hi Sughosh,
On Tue, 17 Sept 2024 at 15:09, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:35, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Use the LMB API's for allocating and freeing up memory. With this, the LMB module becomes the common backend for managing non U-Boot image memory that might be requested by other modules.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
lib/efi_loader/Kconfig | 1 + lib/efi_loader/efi_memory.c | 74 ++++++++++--------------------------- 2 files changed, 21 insertions(+), 54 deletions(-)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6ffefa9103..911d4c6bbe 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -18,6 +18,7 @@ config EFI_LOADER select DM_EVENT select EVENT_DYNAMIC select LIB_UUID
select LMB imply PARTITION_UUIDS select REGEX imply FAT
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index c6f1dd0945..90e07ed6a2 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -9,6 +9,7 @@
#include <efi_loader.h> #include <init.h> +#include <lmb.h> #include <log.h> #include <malloc.h> #include <mapmem.h> @@ -432,53 +433,6 @@ static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated) return EFI_NOT_FOUND; }
-/**
- efi_find_free_memory() - find free memory pages
- @len: size of memory area needed
- @max_addr: highest address to allocate
- Return: pointer to free memory area or 0
- */
-static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) -{
struct efi_mem_list *lmem;
/*
* Prealign input max address, so we simplify our matching
* logic below and can just reuse it as return pointer.
*/
max_addr &= ~EFI_PAGE_MASK;
list_for_each_entry(lmem, &efi_mem, link) {
struct efi_mem_desc *desc = &lmem->desc;
uint64_t desc_len = desc->num_pages << EFI_PAGE_SHIFT;
uint64_t desc_end = desc->physical_start + desc_len;
uint64_t curmax = min(max_addr, desc_end);
uint64_t ret = curmax - len;
/* We only take memory from free RAM */
if (desc->type != EFI_CONVENTIONAL_MEMORY)
continue;
/* Out of bounds for max_addr */
if ((ret + len) > max_addr)
continue;
/* Out of bounds for upper map limit */
if ((ret + len) > desc_end)
continue;
/* Out of bounds for lower map limit */
if (ret < desc->physical_start)
continue;
/* Return the highest address in this map within bounds */
return ret;
}
return 0;
-}
- /**
- efi_allocate_pages - allocate memory pages
@@ -493,6 +447,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, efi_uintn_t pages, uint64_t *memory) { u64 len;
uint flags; efi_status_t ret; uint64_t addr;
@@ -508,33 +463,35 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, (len >> EFI_PAGE_SHIFT) != (u64)pages) return EFI_OUT_OF_RESOURCES;
flags = LMB_NOOVERWRITE | LMB_NONOTIFY;
In the EFI context we should use LMB notification to notify the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event and update the memory map.
Not sure if I am understanding your comment right, but what is happening here is that the EFI subsystem is requesting LMB for memory. And the reason why we have a flag LMB_NONOTIFY, is to prevent a circular chain of LMB then notifying EFI of a change to it's memory map.
See chapter 7.1.2 EFI_BOOT_SERVICES.CreateEventEx() in the UEFI specification.
switch (type) { case EFI_ALLOCATE_ANY_PAGES: /* Any page */
addr = efi_find_free_memory(len, -1ULL);
addr = (u64)lmb_alloc_flags(len, EFI_PAGE_SIZE, flags);
On ARM64 we must ensure that "all 4KiB pages in the 64KiB page ... use identical ARM Memory Page Attributes". I cannot see how LMB implements this.
If you are referring to arm memory attributes, this is not being handled by the current EFI memory code as well. If this is to be handled, that needs to be taken up as a separate task -- I am not sure if U-Boot even has support in the form of any API's where memory regions can be configured for different memory attributes.
So, we *do* handle some EFI memory attributes currently, in efi_add_memory_map_pg(), but we don't translate those to Arm memory attributes. The latter should indeed be a task, but I think what Henrich is saying here is orthogonal. Regardless of what happens to the mmu in the future the spec says "a 64KiB physical page contains any 4KiB page with any of the following types listed below, then all 4KiB pages in the 64KiB page must use identical ARM Memory Page Attribute". So for runtime services/code, EfiACPIMemoryNVS and reserved memory we should group similar attributes in 64k boundaries. I think this is something worth planning ahead, instead of plugging holes afterwards
Cheers /Ilias
See chapter 2.3.6 AArch64 Platforms in the UEFI specification.
If you pass the EFI memory type to LMB and store it there, we can avoid duplication of the memory map and we can implement the 64 KiB pages logic in LMB.
Okay, that would mean mixing up EFI code in the LMB module. Again, not sure if this comes under the purview of the goal of this series, which is to ensure that EFI memory does not trample over that allocated by LMB. Also, thinking a bit more on this, if we are to address aspects like memory attributes etc, I feel that the earlier design that I had posted of notification between LMB and EFI to have a synchronous view of each other's memory would be a better approach. That way, the EFI memory module can then implement things that it needs to, from the EFI spec point of view, and the LMB module can then just update the EFI module of the memory that it is using.
-sughosh
Best regards
Heinrich
if (!addr) return EFI_OUT_OF_RESOURCES; break; case EFI_ALLOCATE_MAX_ADDRESS: /* Max address */
addr = efi_find_free_memory(len, *memory);
addr = (u64)lmb_alloc_base_flags(len, EFI_PAGE_SIZE, *memory,
flags); if (!addr) return EFI_OUT_OF_RESOURCES; break; case EFI_ALLOCATE_ADDRESS: if (*memory & EFI_PAGE_MASK) return EFI_NOT_FOUND;
/* Exact address, reserve it. The addr is already in *memory. */
ret = efi_check_allocated(*memory, false);
if (ret != EFI_SUCCESS)
return EFI_NOT_FOUND;
addr = *memory;
addr = (u64)lmb_alloc_addr_flags(*memory, len, flags);
if (!addr)
return EFI_OUT_OF_RESOURCES; break; default: /* UEFI doesn't specify other allocation types */ return EFI_INVALID_PARAMETER; }
addr = (u64)(uintptr_t)map_sysmem(addr, 0); /* Reserve that map in our memory maps */ ret = efi_add_memory_map_pg(addr, pages, memory_type, true); if (ret != EFI_SUCCESS)
@@ -555,6 +512,9 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, */ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) {
u64 len;
uint flags;
long status; efi_status_t ret; ret = efi_check_allocated(memory, true);
@@ -568,6 +528,12 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) return EFI_INVALID_PARAMETER; }
flags = LMB_NOOVERWRITE | LMB_NONOTIFY;
len = (u64)pages << EFI_PAGE_SHIFT;
status = lmb_free_flags(memory, len, flags);
if (status)
return EFI_NOT_FOUND;
ret = efi_add_memory_map_pg(memory, pages, EFI_CONVENTIONAL_MEMORY, false); if (ret != EFI_SUCCESS)

Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop", + + "lmb_map_update", };
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size"); diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
+ /** + * @EVT_LMB_MAP_UPDATE: + * This event is triggered on an update to the LMB reserved memory + * region. This can be used to notify about any LMB memory allocation + * or freeing of memory having occurred. + */ + EVT_LMB_MAP_UPDATE, + /** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when @@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup; + + struct event_lmb_map_update { + u64 base; + u64 size; + u8 op; + } lmb_map; };
/**

On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update", };
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
- /**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
- EVT_LMB_MAP_UPDATE,
- /**
- @EVT_COUNT:
- This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map; };
/**

On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
The LMB module only concerns itself with RAM memory. If I understand correctly, you are proposing maintaining the EFI memory map within the LMB module ? That would mean handling memory types other than conventional memory in LMB.
-sughosh
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update",
};
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
/**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
EVT_LMB_MAP_UPDATE,
/** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map;
};
/**

Hi Sughosh,
On Tue, 17 Sept 2024 at 15:33, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
The LMB module only concerns itself with RAM memory. If I understand correctly, you are proposing maintaining the EFI memory map within the LMB module ? That would mean handling memory types other than conventional memory in LMB.
I am pretty sure I've asked this before, but do these *always* need to be in sync?
The efi allocators will call LMB now. So when we allocate something gtom EFI, even if any potential changes from LMB haven't been published to EFI, we won't have any memory corruptions. Can't we just opportunistically update the memory map once someone requests it?
Thanks /Ilias
-sughosh
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update",
};
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
/**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
EVT_LMB_MAP_UPDATE,
/** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map;
};
/**

On Fri, 20 Sept 2024 at 14:51, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Sughosh,
On Tue, 17 Sept 2024 at 15:33, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
The LMB module only concerns itself with RAM memory. If I understand correctly, you are proposing maintaining the EFI memory map within the LMB module ? That would mean handling memory types other than conventional memory in LMB.
I am pretty sure I've asked this before, but do these *always* need to be in sync?
The efi allocators will call LMB now. So when we allocate something gtom EFI, even if any potential changes from LMB haven't been published to EFI, we won't have any memory corruptions. Can't we just opportunistically update the memory map once someone requests it?
I have given this a thought. Because what you mention, Simon has a similar comment. But to achieve this, it would require generating a new efi memory map afresh every time such a requirement comes up. This would mean, create a new memory map, put in the conventional memory, and add other memory types that were part of the existing memory map. And then remove the older memory map. This would need to be done every time a memory map is needed to be generated. And that would also include instances when a user enters a command to get the current memory map. I think notifying any changes to the lmb memory map to the efi memory module is easier, and less error prone.
-sughosh
Thanks /Ilias
-sughosh
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update",
};
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
/**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
EVT_LMB_MAP_UPDATE,
/** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map;
};
/**

Hi Sughosh,
On Fri, 20 Sept 2024 at 13:38, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Fri, 20 Sept 2024 at 14:51, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Sughosh,
On Tue, 17 Sept 2024 at 15:33, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
The LMB module only concerns itself with RAM memory. If I understand correctly, you are proposing maintaining the EFI memory map within the LMB module ? That would mean handling memory types other than conventional memory in LMB.
I am pretty sure I've asked this before, but do these *always* need to be in sync?
The efi allocators will call LMB now. So when we allocate something gtom EFI, even if any potential changes from LMB haven't been published to EFI, we won't have any memory corruptions. Can't we just opportunistically update the memory map once someone requests it?
I have given this a thought. Because what you mention, Simon has a similar comment. But to achieve this, it would require generating a new efi memory map afresh every time such a requirement comes up. This would mean, create a new memory map, put in the conventional memory, and add other memory types that were part of the existing memory map. And then remove the older memory map. This would need to be done every time a memory map is needed to be generated. And that would also include instances when a user enters a command to get the current memory map. I think notifying any changes to the lmb memory map to the efi memory module is easier, and less error prone.
We need to get some agreement on my memory-allocation patches first. I don't believe we are on the same page on those, despite some weeks of discussion. We need to resolve that issue first. I did try right from the start to first agree on the problem to be solved. We skipped that, so now we are having to do it now...
Regards, Simon
-sughosh
Thanks /Ilias
-sughosh
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update",
};
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
/**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
EVT_LMB_MAP_UPDATE,
/** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map;
};
/**

On Wed, 25 Sept 2024 at 18:23, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Fri, 20 Sept 2024 at 13:38, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Fri, 20 Sept 2024 at 14:51, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Sughosh,
On Tue, 17 Sept 2024 at 15:33, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
The LMB module only concerns itself with RAM memory. If I understand correctly, you are proposing maintaining the EFI memory map within the LMB module ? That would mean handling memory types other than conventional memory in LMB.
I am pretty sure I've asked this before, but do these *always* need to be in sync?
The efi allocators will call LMB now. So when we allocate something gtom EFI, even if any potential changes from LMB haven't been published to EFI, we won't have any memory corruptions. Can't we just opportunistically update the memory map once someone requests it?
I have given this a thought. Because what you mention, Simon has a similar comment. But to achieve this, it would require generating a new efi memory map afresh every time such a requirement comes up. This would mean, create a new memory map, put in the conventional memory, and add other memory types that were part of the existing memory map. And then remove the older memory map. This would need to be done every time a memory map is needed to be generated. And that would also include instances when a user enters a command to get the current memory map. I think notifying any changes to the lmb memory map to the efi memory module is easier, and less error prone.
We need to get some agreement on my memory-allocation patches first. I don't believe we are on the same page on those, despite some weeks of discussion. We need to resolve that issue first. I did try right from the start to first agree on the problem to be solved. We skipped that, so now we are having to do it now...
These patches are currently under review. But fwiw, I think you are aware that these patches are not related to what your patch series is attempting. Your patches are related to the efi_allocate_pool() function, whereas this series is trying to use LMB as the backend for allocating pages, as requested from efi_allocate_pages(). So these are not related. But like I said, you are aware of these details :)
-sughosh
Regards, Simon
-sughosh
Thanks /Ilias
-sughosh
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update",
};
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
/**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
EVT_LMB_MAP_UPDATE,
/** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map;
};
/**

Hi Sughosh,
On Thu, 26 Sept 2024 at 09:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Wed, 25 Sept 2024 at 18:23, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Fri, 20 Sept 2024 at 13:38, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Fri, 20 Sept 2024 at 14:51, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Sughosh,
On Tue, 17 Sept 2024 at 15:33, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote: > Add an event which would be used for notifying changes in the > LMB modules' memory map. This is to be used for having a > synchronous view of the memory that is currently in use, and that is > available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
The LMB module only concerns itself with RAM memory. If I understand correctly, you are proposing maintaining the EFI memory map within the LMB module ? That would mean handling memory types other than conventional memory in LMB.
I am pretty sure I've asked this before, but do these *always* need to be in sync?
The efi allocators will call LMB now. So when we allocate something gtom EFI, even if any potential changes from LMB haven't been published to EFI, we won't have any memory corruptions. Can't we just opportunistically update the memory map once someone requests it?
I have given this a thought. Because what you mention, Simon has a similar comment. But to achieve this, it would require generating a new efi memory map afresh every time such a requirement comes up. This would mean, create a new memory map, put in the conventional memory, and add other memory types that were part of the existing memory map. And then remove the older memory map. This would need to be done every time a memory map is needed to be generated. And that would also include instances when a user enters a command to get the current memory map. I think notifying any changes to the lmb memory map to the efi memory module is easier, and less error prone.
We need to get some agreement on my memory-allocation patches first. I don't believe we are on the same page on those, despite some weeks of discussion. We need to resolve that issue first. I did try right from the start to first agree on the problem to be solved. We skipped that, so now we are having to do it now...
These patches are currently under review. But fwiw, I think you are aware that these patches are not related to what your patch series is attempting. Your patches are related to the efi_allocate_pool() function, whereas this series is trying to use LMB as the backend for allocating pages, as requested from efi_allocate_pages(). So these are not related. But like I said, you are aware of these details :)
The thing is, if we actually tidy up the EFI allocations then there will be no use of allocate-pages before the app starts. So we won't need to 'sync' the two different sets of memory tables. There will just be one.
If I were confident that we could apply your series and then clean it up later, I would be fine with it. But given that my two series have sat here for a considerable period of time and are still not really making progress, I lack confidence.
Regards, Simon [..]

On Thu, 26 Sept 2024 at 16:38, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Thu, 26 Sept 2024 at 09:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Wed, 25 Sept 2024 at 18:23, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Fri, 20 Sept 2024 at 13:38, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Fri, 20 Sept 2024 at 14:51, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Sughosh,
On Tue, 17 Sept 2024 at 15:33, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote: > > On 9/5/24 10:27, Sughosh Ganu wrote: > > Add an event which would be used for notifying changes in the > > LMB modules' memory map. This is to be used for having a > > synchronous view of the memory that is currently in use, and that is > > available for allocations. > > The synchronous view problem only exists because we are duplicating > data. Store the EFI memory type in LMB and the problem vanishes.
The LMB module only concerns itself with RAM memory. If I understand correctly, you are proposing maintaining the EFI memory map within the LMB module ? That would mean handling memory types other than conventional memory in LMB.
I am pretty sure I've asked this before, but do these *always* need to be in sync?
The efi allocators will call LMB now. So when we allocate something gtom EFI, even if any potential changes from LMB haven't been published to EFI, we won't have any memory corruptions. Can't we just opportunistically update the memory map once someone requests it?
I have given this a thought. Because what you mention, Simon has a similar comment. But to achieve this, it would require generating a new efi memory map afresh every time such a requirement comes up. This would mean, create a new memory map, put in the conventional memory, and add other memory types that were part of the existing memory map. And then remove the older memory map. This would need to be done every time a memory map is needed to be generated. And that would also include instances when a user enters a command to get the current memory map. I think notifying any changes to the lmb memory map to the efi memory module is easier, and less error prone.
We need to get some agreement on my memory-allocation patches first. I don't believe we are on the same page on those, despite some weeks of discussion. We need to resolve that issue first. I did try right from the start to first agree on the problem to be solved. We skipped that, so now we are having to do it now...
These patches are currently under review. But fwiw, I think you are aware that these patches are not related to what your patch series is attempting. Your patches are related to the efi_allocate_pool() function, whereas this series is trying to use LMB as the backend for allocating pages, as requested from efi_allocate_pages(). So these are not related. But like I said, you are aware of these details :)
The thing is, if we actually tidy up the EFI allocations then there will be no use of allocate-pages before the app starts. So we won't need to 'sync' the two different sets of memory tables. There will just be one.
How do we get rid of using efi_allocate_pages() in U-Boot ? This function is used, among other things, to allocate memory used for loading images to memory. This can be a significant amount of memory. Are you proposing using malloc() even for loading EFI images ?
Moreover, the syncing of the memory maps is currently needed primarily as we support printing the EFI memory map through a command. And I mentioned in one of my earlier replies that not syncing the changes in the LMB memory map with the EFI module would mean that the EFI memory map would have to be generated afresh whenever there is a need for the EFI memory map -- this would be either when requested from an EFI app, or when a user asks through a command. Re-generating the EFI memory map is not a trivial task, and syncing the changes in the LMB map as and when they happen is much easier.
-sughosh
If I were confident that we could apply your series and then clean it up later, I would be fine with it. But given that my two series have sat here for a considerable period of time and are still not really making progress, I lack confidence.
Regards, Simon [..]

Hi Sughosh,
On Thu, 26 Sept 2024 at 14:29, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Thu, 26 Sept 2024 at 16:38, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Thu, 26 Sept 2024 at 09:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Wed, 25 Sept 2024 at 18:23, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Fri, 20 Sept 2024 at 13:38, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Fri, 20 Sept 2024 at 14:51, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Sughosh,
On Tue, 17 Sept 2024 at 15:33, Sughosh Ganu sughosh.ganu@linaro.org wrote: > > On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote: > > > > On 9/5/24 10:27, Sughosh Ganu wrote: > > > Add an event which would be used for notifying changes in the > > > LMB modules' memory map. This is to be used for having a > > > synchronous view of the memory that is currently in use, and that is > > > available for allocations. > > > > The synchronous view problem only exists because we are duplicating > > data. Store the EFI memory type in LMB and the problem vanishes. > > The LMB module only concerns itself with RAM memory. If I understand > correctly, you are proposing maintaining the EFI memory map within the > LMB module ? That would mean handling memory types other than > conventional memory in LMB.
I am pretty sure I've asked this before, but do these *always* need to be in sync?
The efi allocators will call LMB now. So when we allocate something gtom EFI, even if any potential changes from LMB haven't been published to EFI, we won't have any memory corruptions. Can't we just opportunistically update the memory map once someone requests it?
I have given this a thought. Because what you mention, Simon has a similar comment. But to achieve this, it would require generating a new efi memory map afresh every time such a requirement comes up. This would mean, create a new memory map, put in the conventional memory, and add other memory types that were part of the existing memory map. And then remove the older memory map. This would need to be done every time a memory map is needed to be generated. And that would also include instances when a user enters a command to get the current memory map. I think notifying any changes to the lmb memory map to the efi memory module is easier, and less error prone.
We need to get some agreement on my memory-allocation patches first. I don't believe we are on the same page on those, despite some weeks of discussion. We need to resolve that issue first. I did try right from the start to first agree on the problem to be solved. We skipped that, so now we are having to do it now...
These patches are currently under review. But fwiw, I think you are aware that these patches are not related to what your patch series is attempting. Your patches are related to the efi_allocate_pool() function, whereas this series is trying to use LMB as the backend for allocating pages, as requested from efi_allocate_pages(). So these are not related. But like I said, you are aware of these details :)
The thing is, if we actually tidy up the EFI allocations then there will be no use of allocate-pages before the app starts. So we won't need to 'sync' the two different sets of memory tables. There will just be one.
The issue is, again, that we never actually identified the problem to be solved at the beginning. So we are suffering somewhat now from a lack of clarity. But in any case, let me try to respond to the points you raise.
How do we get rid of using efi_allocate_pages() in U-Boot ? This function is used, among other things, to allocate memory used for loading images to memory. This can be a significant amount of memory. Are you proposing using malloc() even for loading EFI images ?
We actually don't use efi_allocate_pages() to load things into memory, or at least I hope we don't. We should be using lmb. No, we cannot use malloc() for loading images as the region is quite small on many boards. Heinrich mentioned it can be as small as 1-2MB on some. Also, it isn't really what malloc() is designed for.
Moreover, the syncing of the memory maps is currently needed primarily as we support printing the EFI memory map through a command. And I mentioned in one of my earlier replies that not syncing the changes in the LMB memory map with the EFI module would mean that the EFI memory map would have to be generated afresh whenever there is a need for the EFI memory map -- this would be either when requested from an EFI app, or when a user asks through a command. Re-generating the EFI memory map is not a trivial task, and syncing the changes in the LMB map as and when they happen is much easier.
Yes I have seen you make this point and I am sorry I didn't reply directly. The thing is, we don't care about the EFI memory until we boot the app. After all, it is only the app that actually needs it.
I see that 'efi_init_obj_list()' is called by the efidebug command, so yes, it should show the memory map.
But in my view of the world the memory map (before an app boots and does what it likes in terms of allocations, etc.) consists solely of:
1. U-Boot's memory (malloc() space, code, bloblist, stack, arch-specific stuff, etc.) 2. Images that were loaded (which are in lmb)
Since we need to handle (1) by manually adding records to the EFI map, it isn't a big stretch to handle (2) with a for-loop through the lmb records.
If I were confident that we could apply your series and then clean it up later, I would be fine with it. But given that my two series have sat here for a considerable period of time and are still not really making progress, I lack confidence.
Regards, Simon

On Fri, 27 Sept 2024 at 16:12, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Thu, 26 Sept 2024 at 14:29, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Thu, 26 Sept 2024 at 16:38, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Thu, 26 Sept 2024 at 09:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Wed, 25 Sept 2024 at 18:23, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Fri, 20 Sept 2024 at 13:38, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Fri, 20 Sept 2024 at 14:51, Ilias Apalodimas ilias.apalodimas@linaro.org wrote: > > Hi Sughosh, > > On Tue, 17 Sept 2024 at 15:33, Sughosh Ganu sughosh.ganu@linaro.org wrote: > > > > On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote: > > > > > > On 9/5/24 10:27, Sughosh Ganu wrote: > > > > Add an event which would be used for notifying changes in the > > > > LMB modules' memory map. This is to be used for having a > > > > synchronous view of the memory that is currently in use, and that is > > > > available for allocations. > > > > > > The synchronous view problem only exists because we are duplicating > > > data. Store the EFI memory type in LMB and the problem vanishes. > > > > The LMB module only concerns itself with RAM memory. If I understand > > correctly, you are proposing maintaining the EFI memory map within the > > LMB module ? That would mean handling memory types other than > > conventional memory in LMB. > > I am pretty sure I've asked this before, but do these *always* need to > be in sync? > > The efi allocators will call LMB now. So when we allocate something > gtom EFI, even if any potential changes from LMB haven't been > published to EFI, we won't have any memory corruptions. Can't we just > opportunistically update the memory map once someone requests it?
I have given this a thought. Because what you mention, Simon has a similar comment. But to achieve this, it would require generating a new efi memory map afresh every time such a requirement comes up. This would mean, create a new memory map, put in the conventional memory, and add other memory types that were part of the existing memory map. And then remove the older memory map. This would need to be done every time a memory map is needed to be generated. And that would also include instances when a user enters a command to get the current memory map. I think notifying any changes to the lmb memory map to the efi memory module is easier, and less error prone.
We need to get some agreement on my memory-allocation patches first. I don't believe we are on the same page on those, despite some weeks of discussion. We need to resolve that issue first. I did try right from the start to first agree on the problem to be solved. We skipped that, so now we are having to do it now...
These patches are currently under review. But fwiw, I think you are aware that these patches are not related to what your patch series is attempting. Your patches are related to the efi_allocate_pool() function, whereas this series is trying to use LMB as the backend for allocating pages, as requested from efi_allocate_pages(). So these are not related. But like I said, you are aware of these details :)
The thing is, if we actually tidy up the EFI allocations then there will be no use of allocate-pages before the app starts. So we won't need to 'sync' the two different sets of memory tables. There will just be one.
The issue is, again, that we never actually identified the problem to be solved at the beginning. So we are suffering somewhat now from a lack of clarity. But in any case, let me try to respond to the points you raise.
How do we get rid of using efi_allocate_pages() in U-Boot ? This function is used, among other things, to allocate memory used for loading images to memory. This can be a significant amount of memory. Are you proposing using malloc() even for loading EFI images ?
We actually don't use efi_allocate_pages() to load things into memory, or at least I hope we don't. We should be using lmb. No, we cannot use malloc() for loading images as the region is quite small on many boards. Heinrich mentioned it can be as small as 1-2MB on some. Also, it isn't really what malloc() is designed for.
So you are proposing using lmb for loading images. And that is precisely what this series is doing -- changing the efi_allocate_pages() function so that it calls the lmb API's to get the memory. So then I wonder why are we not on the same page ? Yes, I understand that you have a differing view when it comes to efi_allocate_pool(), but the changes to the efi_allocate_pages() done in this series are exactly what you refer to above.
Moreover, the syncing of the memory maps is currently needed primarily as we support printing the EFI memory map through a command. And I mentioned in one of my earlier replies that not syncing the changes in the LMB memory map with the EFI module would mean that the EFI memory map would have to be generated afresh whenever there is a need for the EFI memory map -- this would be either when requested from an EFI app, or when a user asks through a command. Re-generating the EFI memory map is not a trivial task, and syncing the changes in the LMB map as and when they happen is much easier.
Yes I have seen you make this point and I am sorry I didn't reply directly. The thing is, we don't care about the EFI memory until we boot the app. After all, it is only the app that actually needs it.
I see that 'efi_init_obj_list()' is called by the efidebug command, so yes, it should show the memory map.
But in my view of the world the memory map (before an app boots and does what it likes in terms of allocations, etc.) consists solely of:
- U-Boot's memory (malloc() space, code, bloblist, stack,
arch-specific stuff, etc.) 2. Images that were loaded (which are in lmb)
Since we need to handle (1) by manually adding records to the EFI map, it isn't a big stretch to handle (2) with a for-loop through the lmb records.
If I were confident that we could apply your series and then clean it up later, I would be fine with it. But given that my two series have sat here for a considerable period of time and are still not really making progress, I lack confidence.
So the difference here is, unlike the way the LMB memory map gets stored and shown, i.e. a separate entry for the total available memory, and then a separate list of currently allocated entries, the EFI memory map storage is designed in a different way. The conventional memory, which is the DRAM memory gets added first, and that is then followed by carving out the different memory regions which are being used, e.g. the U-Boot's memory, and other memory regions that have been requested. So if you try out the 'efidebug memmap' command, you will see a single list of memory regions, which includes the conventional memory, and other reserved memory regions. Although I did not come up with this design, I suspect that it is the way it is because the EFI memory map is not dealing only with DRAM/conventional memory, but other possible memory regions as well.
What this means is that syncing the EFI memory map in the manner that you propose would mean that the entire EFI memory map would have to be re-generated, as the carve-out's (reserved memory regions) might have changed. Please also note that, apart from the added complexity, we are also going to be worse off from the size impact point-of-view. Especially if we consider Ilias's review comment of doing away with the event framework, and directly calling the efi_add_memory_map_pg() directly.
-sughosh
Regards, Simon

Hi Sughosh,
On Fri, 27 Sept 2024 at 05:01, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Fri, 27 Sept 2024 at 16:12, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Thu, 26 Sept 2024 at 14:29, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Thu, 26 Sept 2024 at 16:38, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Thu, 26 Sept 2024 at 09:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
On Wed, 25 Sept 2024 at 18:23, Simon Glass sjg@chromium.org wrote:
Hi Sughosh,
On Fri, 20 Sept 2024 at 13:38, Sughosh Ganu sughosh.ganu@linaro.org wrote: > > On Fri, 20 Sept 2024 at 14:51, Ilias Apalodimas > ilias.apalodimas@linaro.org wrote: > > > > Hi Sughosh, > > > > On Tue, 17 Sept 2024 at 15:33, Sughosh Ganu sughosh.ganu@linaro.org wrote: > > > > > > On Sat, 14 Sept 2024 at 20:38, Heinrich Schuchardt xypron.glpk@gmx.de wrote: > > > > > > > > On 9/5/24 10:27, Sughosh Ganu wrote: > > > > > Add an event which would be used for notifying changes in the > > > > > LMB modules' memory map. This is to be used for having a > > > > > synchronous view of the memory that is currently in use, and that is > > > > > available for allocations. > > > > > > > > The synchronous view problem only exists because we are duplicating > > > > data. Store the EFI memory type in LMB and the problem vanishes. > > > > > > The LMB module only concerns itself with RAM memory. If I understand > > > correctly, you are proposing maintaining the EFI memory map within the > > > LMB module ? That would mean handling memory types other than > > > conventional memory in LMB. > > > > I am pretty sure I've asked this before, but do these *always* need to > > be in sync? > > > > The efi allocators will call LMB now. So when we allocate something > > gtom EFI, even if any potential changes from LMB haven't been > > published to EFI, we won't have any memory corruptions. Can't we just > > opportunistically update the memory map once someone requests it? > > I have given this a thought. Because what you mention, Simon has a > similar comment. But to achieve this, it would require generating a > new efi memory map afresh every time such a requirement comes up. This > would mean, create a new memory map, put in the conventional memory, > and add other memory types that were part of the existing memory map. > And then remove the older memory map. This would need to be done every > time a memory map is needed to be generated. And that would also > include instances when a user enters a command to get the current > memory map. I think notifying any changes to the lmb memory map to the > efi memory module is easier, and less error prone.
We need to get some agreement on my memory-allocation patches first. I don't believe we are on the same page on those, despite some weeks of discussion. We need to resolve that issue first. I did try right from the start to first agree on the problem to be solved. We skipped that, so now we are having to do it now...
These patches are currently under review. But fwiw, I think you are aware that these patches are not related to what your patch series is attempting. Your patches are related to the efi_allocate_pool() function, whereas this series is trying to use LMB as the backend for allocating pages, as requested from efi_allocate_pages(). So these are not related. But like I said, you are aware of these details :)
The thing is, if we actually tidy up the EFI allocations then there will be no use of allocate-pages before the app starts. So we won't need to 'sync' the two different sets of memory tables. There will just be one.
The issue is, again, that we never actually identified the problem to be solved at the beginning. So we are suffering somewhat now from a lack of clarity. But in any case, let me try to respond to the points you raise.
How do we get rid of using efi_allocate_pages() in U-Boot ? This function is used, among other things, to allocate memory used for loading images to memory. This can be a significant amount of memory. Are you proposing using malloc() even for loading EFI images ?
We actually don't use efi_allocate_pages() to load things into memory, or at least I hope we don't. We should be using lmb. No, we cannot use malloc() for loading images as the region is quite small on many boards. Heinrich mentioned it can be as small as 1-2MB on some. Also, it isn't really what malloc() is designed for.
So you are proposing using lmb for loading images. And that is precisely what this series is doing -- changing the efi_allocate_pages() function so that it calls the lmb API's to get the memory. So then I wonder why are we not on the same page ? Yes, I understand that you have a differing view when it comes to efi_allocate_pool(), but the changes to the efi_allocate_pages() done in this series are exactly what you refer to above.
Moreover, the syncing of the memory maps is currently needed primarily as we support printing the EFI memory map through a command. And I mentioned in one of my earlier replies that not syncing the changes in the LMB memory map with the EFI module would mean that the EFI memory map would have to be generated afresh whenever there is a need for the EFI memory map -- this would be either when requested from an EFI app, or when a user asks through a command. Re-generating the EFI memory map is not a trivial task, and syncing the changes in the LMB map as and when they happen is much easier.
Yes I have seen you make this point and I am sorry I didn't reply directly. The thing is, we don't care about the EFI memory until we boot the app. After all, it is only the app that actually needs it.
I see that 'efi_init_obj_list()' is called by the efidebug command, so yes, it should show the memory map.
But in my view of the world the memory map (before an app boots and does what it likes in terms of allocations, etc.) consists solely of:
- U-Boot's memory (malloc() space, code, bloblist, stack,
arch-specific stuff, etc.) 2. Images that were loaded (which are in lmb)
Since we need to handle (1) by manually adding records to the EFI map, it isn't a big stretch to handle (2) with a for-loop through the lmb records.
If I were confident that we could apply your series and then clean it up later, I would be fine with it. But given that my two series have sat here for a considerable period of time and are still not really making progress, I lack confidence.
So the difference here is, unlike the way the LMB memory map gets stored and shown, i.e. a separate entry for the total available memory, and then a separate list of currently allocated entries, the EFI memory map storage is designed in a different way. The conventional memory, which is the DRAM memory gets added first, and that is then followed by carving out the different memory regions which are being used, e.g. the U-Boot's memory, and other memory regions that have been requested. So if you try out the 'efidebug memmap' command, you will see a single list of memory regions, which includes the conventional memory, and other reserved memory regions. Although I did not come up with this design, I suspect that it is the way it is because the EFI memory map is not dealing only with DRAM/conventional memory, but other possible memory regions as well.
What this means is that syncing the EFI memory map in the manner that you propose would mean that the entire EFI memory map would have to be re-generated, as the carve-out's (reserved memory regions) might have changed. Please also note that, apart from the added complexity, we are also going to be worse off from the size impact point-of-view. Especially if we consider Ilias's review comment of doing away with the event framework, and directly calling the efi_add_memory_map_pg() directly.
Look, I certainly understand your frustration and I share it.
I would like to see progress on the series i sent, which moves pool allocations to use malloc(). I would also like to see the EFI test applied, which has been held up for a long time (perhaps the latest version will be OK) I did discuss this with Tom and was OK with your first series on the basis that we can figure out the next step after that. But I never believed that the problem to be solved was that lmb and EFI were not deeply integrated and I was expecting to have made some progress on the malloc() issue by now.
I should also point out that no one else dug into this to understand what was really going on (that EFI was allocating stuff where it shouldn't, i.e. in space that is supposed to be used by lmb). I had an inkling of it but had never spent the time to really understand it.
My current view on EFI memory is that, just before launching the app (or firmware update, or whatever), we should be able to call efi_memory_init(), which adds the known memory, the U-Boot regions and the images it knows about. Only the last piece is missing today. As to that, we need to clean up the EFI hack and maintain a list of images and which device they came from, so that the EFI loader can find that out. It isn't just about lmb.
So I hope you can understand that, coming from that point of view, all this stuff about keeping things in sync doesn't seem right.
Regards, Simon

Hi Heinrich,
On Sat, 14 Sept 2024 at 18:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
We could, but I wonder if that would be enough. Apart from the EFI memory types, we plan on fixing the EFI memory attributes. I'll go read the spec again and take look at EDK2 but IIRC, you can't correlate memory types to memory attributes (at least not for all of them).
If that's true we'll also need the attributes in LMB + perhaps logic for 64kb page size OSes and 4KB page firmware, which might be a bit too much. In that case, I think the sync is fine, but I really don't see the point of making an event out of it. Perhaps we could just update the efi memory map directly from LMB.
Thanks /Ilias
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update",
};
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
/**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
EVT_LMB_MAP_UPDATE,
/** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map;
};
/**

On 26.09.24 14:58, Ilias Apalodimas wrote:
Hi Heinrich,
On Sat, 14 Sept 2024 at 18:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
We could, but I wonder if that would be enough. Apart from the EFI memory types, we plan on fixing the EFI memory attributes. I'll go read the spec again and take look at EDK2 but IIRC, you can't correlate memory types to memory attributes (at least not for all of them).
If that's true we'll also need the attributes in LMB + perhaps logic for 64kb page size OSes and 4KB page firmware, which might be a bit too much. In that case, I think the sync is fine, but I really don't see the point of making an event out of it. Perhaps we could just update the efi memory map directly from LMB.
Yes, memory attributes should be stored in LMB too if UEFI is enabled.
I would suggest:
* GetMemoryMap() calls into LMB to generate the map on the fly. * The EFI_MEMORY_ATTRIBUTES_TABLE is generated from LMB information. * The EFI_MEMORY_ATTRIBUTE_PROTOCOL calls into LMB.
Best regards
Heinrich
Thanks /Ilias
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update",
};
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
/**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
EVT_LMB_MAP_UPDATE,
/** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map;
};
/**

Hi Heinrich,
On Thu, 26 Sept 2024 at 16:19, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 26.09.24 14:58, Ilias Apalodimas wrote:
Hi Heinrich,
On Sat, 14 Sept 2024 at 18:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
We could, but I wonder if that would be enough. Apart from the EFI memory types, we plan on fixing the EFI memory attributes. I'll go read the spec again and take look at EDK2 but IIRC, you can't correlate memory types to memory attributes (at least not for all of them).
If that's true we'll also need the attributes in LMB + perhaps logic for 64kb page size OSes and 4KB page firmware, which might be a bit too much. In that case, I think the sync is fine, but I really don't see the point of making an event out of it. Perhaps we could just update the efi memory map directly from LMB.
Yes, memory attributes should be stored in LMB too if UEFI is enabled.
I would suggest:
- GetMemoryMap() calls into LMB to generate the map on the fly.
- The EFI_MEMORY_ATTRIBUTES_TABLE is generated from LMB information.
- The EFI_MEMORY_ATTRIBUTE_PROTOCOL calls into LMB.
Best regards
Heinrich
That would work. TBH I do have a few doubts on how clean this is going to be. It seems a bit cleaner to me atm to keep the efi memory map as is. Especially if we get rid of the event. Would it make sense to clean this up from the event and merge it close to its current form? Then we could prototype what you suggest and send an RFC to decide it it looks cleaner or not.
Thanks /Ilias
Thanks /Ilias
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update",
};
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
/**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
EVT_LMB_MAP_UPDATE,
/** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map;
};
/**

On 26.09.24 15:54, Ilias Apalodimas wrote:
Hi Heinrich,
On Thu, 26 Sept 2024 at 16:19, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 26.09.24 14:58, Ilias Apalodimas wrote:
Hi Heinrich,
On Sat, 14 Sept 2024 at 18:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:27, Sughosh Ganu wrote:
Add an event which would be used for notifying changes in the LMB modules' memory map. This is to be used for having a synchronous view of the memory that is currently in use, and that is available for allocations.
The synchronous view problem only exists because we are duplicating data. Store the EFI memory type in LMB and the problem vanishes.
We could, but I wonder if that would be enough. Apart from the EFI memory types, we plan on fixing the EFI memory attributes. I'll go read the spec again and take look at EDK2 but IIRC, you can't correlate memory types to memory attributes (at least not for all of them).
If that's true we'll also need the attributes in LMB + perhaps logic for 64kb page size OSes and 4KB page firmware, which might be a bit too much. In that case, I think the sync is fine, but I really don't see the point of making an event out of it. Perhaps we could just update the efi memory map directly from LMB.
Yes, memory attributes should be stored in LMB too if UEFI is enabled.
I would suggest:
- GetMemoryMap() calls into LMB to generate the map on the fly.
- The EFI_MEMORY_ATTRIBUTES_TABLE is generated from LMB information.
- The EFI_MEMORY_ATTRIBUTE_PROTOCOL calls into LMB.
Best regards
Heinrich
That would work. TBH I do have a few doubts on how clean this is going to be. It seems a bit cleaner to me atm to keep the efi memory map as is. Especially if we get rid of the event. Would it make sense to clean this up from the event and merge it close to its current form? Then we could prototype what you suggest and send an RFC to decide it it looks cleaner or not.
Sure, we can split the work into two series.
Best regards
Heinrich
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
common/event.c | 2 ++ include/event.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/common/event.c b/common/event.c index dda569d447..fc8002603c 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,8 @@ const char *const type_name[] = {
/* main loop events */ "main_loop",
"lmb_map_update",
};
_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size");
diff --git a/include/event.h b/include/event.h index fb353ad623..fce7e96170 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,14 @@ enum event_t { */ EVT_MAIN_LOOP,
/**
* @EVT_LMB_MAP_UPDATE:
* This event is triggered on an update to the LMB reserved memory
* region. This can be used to notify about any LMB memory allocation
* or freeing of memory having occurred.
*/
EVT_LMB_MAP_UPDATE,
/** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when
@@ -203,6 +211,12 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup;
struct event_lmb_map_update {
u64 base;
u64 size;
u8 op;
} lmb_map;
};
/**

Add a Kconfig symbol to enable getting updates on any memory map changes that might be done by the LMB module. This notification mechanism can then be used to have a synchronous view of allocated and free memory.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- lib/Kconfig | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/lib/Kconfig b/lib/Kconfig index 5f282ecb54..2e73cda580 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -74,6 +74,17 @@ config HAVE_PRIVATE_LIBGCC config LIB_UUID bool
+config MEM_MAP_UPDATE_NOTIFY + bool "Get notified of any changes to the LMB memory map" + depends on LMB && EFI_LOADER + select EVENT + default y + help + Enable this option to get notification on any changes to the + memory that is allocated or freed by the LMB module. This will + allow different modules that allocate memory or maintain a memory + map to have a synchronous view of available and allocated memory. + config RANDOM_UUID bool "GPT Random UUID generation" select LIB_UUID

On 9/5/24 10:28, Sughosh Ganu wrote:
Add a Kconfig symbol to enable getting updates on any memory map changes that might be done by the LMB module. This notification mechanism can then be used to have a synchronous view of allocated and free memory.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
lib/Kconfig | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/lib/Kconfig b/lib/Kconfig index 5f282ecb54..2e73cda580 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -74,6 +74,17 @@ config HAVE_PRIVATE_LIBGCC config LIB_UUID bool
+config MEM_MAP_UPDATE_NOTIFY
- bool "Get notified of any changes to the LMB memory map"
- depends on LMB && EFI_LOADER
- select EVENT
- default y
- help
Enable this option to get notification on any changes to the
memory that is allocated or freed by the LMB module. This will
allow different modules that allocate memory or maintain a memory
map to have a synchronous view of available and allocated memory.
We should have only one store for all LMB allocations. They should not be duplicated in the EFI sub-system.
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
- config RANDOM_UUID bool "GPT Random UUID generation" select LIB_UUID

On Sat, 14 Sept 2024 at 20:41, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 9/5/24 10:28, Sughosh Ganu wrote:
Add a Kconfig symbol to enable getting updates on any memory map changes that might be done by the LMB module. This notification mechanism can then be used to have a synchronous view of allocated and free memory.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
lib/Kconfig | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/lib/Kconfig b/lib/Kconfig index 5f282ecb54..2e73cda580 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -74,6 +74,17 @@ config HAVE_PRIVATE_LIBGCC config LIB_UUID bool
+config MEM_MAP_UPDATE_NOTIFY
bool "Get notified of any changes to the LMB memory map"
depends on LMB && EFI_LOADER
select EVENT
default y
help
Enable this option to get notification on any changes to the
memory that is allocated or freed by the LMB module. This will
allow different modules that allocate memory or maintain a memory
map to have a synchronous view of available and allocated memory.
We should have only one store for all LMB allocations. They should not be duplicated in the EFI sub-system.
We do have a single allocator for handling the conventional memory, which is LMB. The notifications are needed so that the EFI memory map also has visibility of which memory regions are currently being used, and which are free. So, for e.g. if a user wants to view the EFI memory map with the 'efidebug memmap' command, the EFI memory map should be up-to-date when it comes to conventional memory. And this also includes memory which is being consumed by other non-EFI modules.
-sughosh
The event is only needed to notify EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
- config RANDOM_UUID bool "GPT Random UUID generation" select LIB_UUID

Add a function to check if a given address falls within the RAM address used by U-Boot. This will be used to notify other modules if the address gets allocated, so as to not get re-allocated by some other module.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- common/board_r.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/common/board_r.c b/common/board_r.c index 4faaa20242..877ea3afd0 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -72,6 +72,11 @@ DECLARE_GLOBAL_DATA_PTR;
ulong monitor_flash_len;
+__weak bool __maybe_unused is_addr_in_ram(uintptr_t addr) +{ + return addr >= gd->ram_base && addr <= gd->ram_top; +} + __weak int board_flash_wp_on(void) { /*

In U-Boot, LMB and EFI are two primary modules who provide memory allocation and reservation API's. Both these modules operate with the same regions of memory for allocations. Use the LMB memory map update event to notify other interested listeners about a change in it's memory map. This can then be used by the other module to keep track of available and used memory.
There is no need to send these notifications when the LMB module is being unit-tested. Add a flag to the lmb structure to indicate if the memory map is being used for tests, and suppress sending any notifications when running these unit tests.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- include/lmb.h | 2 ++ lib/lmb.c | 74 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/include/lmb.h b/include/lmb.h index ffba7e2889..f711b8fac8 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -44,10 +44,12 @@ struct lmb_region { * * @free_mem: List of free memory regions * @used_mem: List of used/reserved memory regions + * @test: Is structure being used for LMB tests */ struct lmb { struct alist free_mem; struct alist used_mem; + bool test; };
/** diff --git a/lib/lmb.c b/lib/lmb.c index 419b31a651..aff2830cb9 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -8,6 +8,7 @@
#include <alist.h> #include <efi_loader.h> +#include <event.h> #include <image.h> #include <mapmem.h> #include <lmb.h> @@ -22,10 +23,33 @@
DECLARE_GLOBAL_DATA_PTR;
+#define MAP_OP_RESERVE (u8)0x1 +#define MAP_OP_FREE (u8)0x2 +#define MAP_OP_ADD (u8)0x3 + #define LMB_ALLOC_ANYWHERE 0 #define LMB_ALIST_INITIAL_SIZE 4
static struct lmb lmb; +extern bool is_addr_in_ram(uintptr_t addr); + +static bool lmb_notify(enum lmb_flags flags) +{ + return !lmb.test && !(flags & LMB_NONOTIFY); +} + +static void lmb_map_update_notify(phys_addr_t addr, phys_size_t size, + u8 op) +{ + struct event_lmb_map_update lmb_map = {0}; + + lmb_map.base = addr; + lmb_map.size = size; + lmb_map.op = op; + + if (is_addr_in_ram((uintptr_t)addr)) + event_notify(EVT_LMB_MAP_UPDATE, &lmb_map, sizeof(lmb_map)); +}
static void lmb_print_region_flags(enum lmb_flags flags) { @@ -474,9 +498,17 @@ static long lmb_add_region(struct alist *lmb_rgn_lst, phys_addr_t base, /* This routine may be called with relocation disabled. */ long lmb_add(phys_addr_t base, phys_size_t size) { + long ret; struct alist *lmb_rgn_lst = &lmb.free_mem;
- return lmb_add_region(lmb_rgn_lst, base, size); + ret = lmb_add_region(lmb_rgn_lst, base, size); + if (ret) + return ret; + + if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) + lmb_map_update_notify(base, size, MAP_OP_ADD); + + return 0; }
static long __lmb_free(phys_addr_t base, phys_size_t size) @@ -530,22 +562,39 @@ static long __lmb_free(phys_addr_t base, phys_size_t size) rgn[i].flags); }
-long lmb_free(phys_addr_t base, phys_size_t size) +long lmb_free_flags(phys_addr_t base, phys_size_t size, + uint flags) { - return __lmb_free(base, size); + long ret; + + ret = __lmb_free(base, size); + if (ret < 0) + return ret; + + if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) && lmb_notify(flags)) + lmb_map_update_notify(base, size, MAP_OP_FREE); + + return ret; }
-long lmb_free_flags(phys_addr_t base, phys_size_t size, - __always_unused uint flags) +long lmb_free(phys_addr_t base, phys_size_t size) { return __lmb_free(base, size); }
long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags) { + long ret = 0; struct alist *lmb_rgn_lst = &lmb.used_mem;
- return lmb_add_region_flags(lmb_rgn_lst, base, size, flags); + ret = lmb_add_region_flags(lmb_rgn_lst, base, size, flags); + if (ret < 0) + return -1; + + if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) && lmb_notify(flags)) + lmb_map_update_notify(base, size, MAP_OP_RESERVE); + + return ret; }
long lmb_reserve(phys_addr_t base, phys_size_t size) @@ -607,6 +656,11 @@ static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, if (lmb_add_region_flags(&lmb.used_mem, base, size, flags) < 0) return 0; + + if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) && + lmb_notify(flags)) + lmb_map_update_notify(base, size, + MAP_OP_RESERVE); return base; }
@@ -740,7 +794,7 @@ int lmb_is_reserved_flags(phys_addr_t addr, int flags) return 0; }
-static int lmb_setup(void) +static int lmb_setup(bool test) { bool ret;
@@ -758,6 +812,8 @@ static int lmb_setup(void) return -ENOMEM; }
+ lmb.test = test; + return 0; }
@@ -777,7 +833,7 @@ int lmb_init(void) { int ret;
- ret = lmb_setup(); + ret = lmb_setup(false); if (ret) { log_info("Unable to init LMB\n"); return ret; @@ -805,7 +861,7 @@ int lmb_push(struct lmb *store) int ret;
*store = lmb; - ret = lmb_setup(); + ret = lmb_setup(true); if (ret) return ret;

There are events that would be used to notify other interested modules of any changes in available and occupied memory. This would happen when a module allocates or reserves memory, or frees up memory. These changes in memory map should be notified to other interested modules so that the allocated memory does not get overwritten. Add an event handler in the EFI memory module to update the EFI memory map accordingly when such changes happen. As a consequence, any subsequent memory request would honour the updated memory map and only available memory would be allocated from.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- lib/efi_loader/Kconfig | 2 ++ lib/efi_loader/efi_memory.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 911d4c6bbe..41d51987c3 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -16,9 +16,11 @@ config EFI_LOADER select CHARSET # We need to send DM events, dynamically, in the EFI block driver select DM_EVENT + select EVENT select EVENT_DYNAMIC select LIB_UUID select LMB + select MEM_MAP_UPDATE_NOTIFY imply PARTITION_UUIDS select REGEX imply FAT diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 90e07ed6a2..900d3c12f1 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -44,6 +44,10 @@ static LIST_HEAD(efi_mem); void *efi_bounce_buffer; #endif
+#define MAP_OP_RESERVE (u8)0x1 +#define MAP_OP_FREE (u8)0x2 +#define MAP_OP_ADD (u8)0x3 + /** * struct efi_pool_allocation - memory block allocated from pool * @@ -919,3 +923,34 @@ int efi_memory_init(void)
return 0; } + +#if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) +static int lmb_mem_map_update_sync(void *ctx, struct event *event) +{ + u8 op; + u64 addr; + u64 pages; + efi_status_t status; + struct event_lmb_map_update *lmb_map = &event->data.lmb_map; + + addr = (uintptr_t)map_sysmem(lmb_map->base, 0); + pages = efi_size_in_pages(lmb_map->size + (addr & EFI_PAGE_MASK)); + op = lmb_map->op; + addr &= ~EFI_PAGE_MASK; + + if (op != MAP_OP_RESERVE && op != MAP_OP_FREE && op != MAP_OP_ADD) { + log_debug("Invalid map update op received (%d)\n", op); + return -1; + } + + status = efi_add_memory_map_pg(addr, pages, + op == MAP_OP_RESERVE ? + EFI_BOOT_SERVICES_DATA : + EFI_CONVENTIONAL_MEMORY, + op == MAP_OP_RESERVE ? true : false); + + return status == EFI_SUCCESS ? 0 : -1; +} + +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); +#endif /* MEM_MAP_UPDATE_NOTIFY */

The efi_add_known_memory() function for the TI K3 platforms is adding the EFI_CONVENTIONAL_MEMORY type. This memory is now being handled through the LMB module -- the lmb_add_memory() adds this memory to the memory map. Remove the definition of the now superfluous efi_add_known_memory() function.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- arch/arm/mach-k3/common.c | 11 ----------- 1 file changed, 11 deletions(-)
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index df48ec8d47..f2086cbdf5 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -310,14 +310,3 @@ void setup_qos(void) writel(qos_data[i].val, (uintptr_t)qos_data[i].reg); } #endif - -void efi_add_known_memory(void) -{ - if (IS_ENABLED(CONFIG_EFI_LOADER)) - /* - * Memory over ram_top can be used by various firmware - * Declare to EFI only memory area below ram_top - */ - efi_add_memory_map(gd->ram_base, gd->ram_top - gd->ram_base, - EFI_CONVENTIONAL_MEMORY); -}

The efi_add_known_memory() function for the stm32mp platforms is adding the EFI_CONVENTIONAL_MEMORY type. This memory is now being handled through the LMB module -- the lmb_add_memory() adds this memory to the memory map. Remove the definition of the now superfluous efi_add_known_memory() function.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- arch/arm/mach-stm32mp/dram_init.c | 11 ----------- 1 file changed, 11 deletions(-)
diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c index 198785353f..3698fc49bf 100644 --- a/arch/arm/mach-stm32mp/dram_init.c +++ b/arch/arm/mach-stm32mp/dram_init.c @@ -86,14 +86,3 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
return reg + size; } - -void efi_add_known_memory(void) -{ - if (IS_ENABLED(CONFIG_EFI_LOADER)) - /* - * Memory over ram_top is reserved to OPTEE. - * Declare to EFI only memory area below ram_top - */ - efi_add_memory_map(gd->ram_base, gd->ram_top - gd->ram_base, - EFI_CONVENTIONAL_MEMORY); -}

Some architectures have special or unique aspects which need consideration when adding memory ranges to the list of available memory map. Enable this config in such scenarios which allow architectures and boards to define their own memory map.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- include/lmb.h | 2 ++ lib/Kconfig | 18 ++++++++++++++++++ lib/lmb.c | 3 +++ 3 files changed, 23 insertions(+)
diff --git a/include/lmb.h b/include/lmb.h index f711b8fac8..6ef03f9b63 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -116,6 +116,8 @@ long lmb_free_flags(phys_addr_t base, phys_size_t size, uint flags); void lmb_dump_all(void); void lmb_dump_all_force(void);
+void lmb_arch_add_memory(void); + struct lmb *lmb_get(void); int lmb_push(struct lmb *store); void lmb_pop(struct lmb *store); diff --git a/lib/Kconfig b/lib/Kconfig index 2e73cda580..f2fb90c12d 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -1127,6 +1127,24 @@ config SPL_LMB SPL. This will require a malloc() implementation for defining the data structures needed for maintaining the LMB memory map.
+config LMB_ARCH_MEM_MAP + bool "Add an architecture specific memory map" + depends on LMB + help + Some architectures have special or unique aspects which need + consideration when adding memory ranges to the list of available + memory map. Enable this config in such scenarios which allow + architectures and boards to define their own memory map. + +config SPL_LMB_ARCH_MEM_MAP + bool "Add an architecture specific memory map" + depends on SPL_LMB + help + Some architectures have special or unique scenarios which need + consideration when adding memory ranges to the list of available + memory map. Enable this config in such scenarios which allow + architectures and boards to define their own memory map. + config PHANDLE_CHECK_SEQ bool "Enable phandle check while getting sequence number" help diff --git a/lib/lmb.c b/lib/lmb.c index aff2830cb9..ec5078527e 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -309,6 +309,9 @@ void lmb_add_memory(void) u64 ram_top = gd->ram_top; struct bd_info *bd = gd->bd;
+ if (CONFIG_IS_ENABLED(LMB_ARCH_MEM_MAP)) + return lmb_arch_add_memory(); + /* Assume a 4GB ram_top if not defined */ if (!ram_top) ram_top = 0x100000000ULL;

The EFI memory allocations are now being done through the LMB module, and hence the memory map is maintained by the LMB module. Use the lmb_arch_add_memory() API function to add the usable RAM memory to the LMB's memory map.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 8 ++++---- lib/Kconfig | 1 + 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index d2dbfdd08a..e7fb91a821 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -10,6 +10,7 @@ #include <env.h> #include <init.h> #include <hang.h> +#include <lmb.h> #include <log.h> #include <net.h> #include <vsprintf.h> @@ -1525,8 +1526,8 @@ int dram_init_banksize(void) return 0; }
-#if CONFIG_IS_ENABLED(EFI_LOADER) -void efi_add_known_memory(void) +#if CONFIG_IS_ENABLED(LMB_ARCH_MEM_MAP) +void lmb_arch_add_memory(void) { int i; phys_addr_t ram_start; @@ -1548,8 +1549,7 @@ void efi_add_known_memory(void) gd->arch.resv_ram < ram_start + ram_size) ram_size = gd->arch.resv_ram - ram_start; #endif - efi_add_memory_map(ram_start, ram_size, - EFI_CONVENTIONAL_MEMORY); + lmb_add(ram_start, ram_size); } } #endif diff --git a/lib/Kconfig b/lib/Kconfig index f2fb90c12d..ee0b4d65f2 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -1130,6 +1130,7 @@ config SPL_LMB config LMB_ARCH_MEM_MAP bool "Add an architecture specific memory map" depends on LMB + default y if FSL_LAYERSCAPE help Some architectures have special or unique aspects which need consideration when adding memory ranges to the list of available

The EFI_CONVENTIONAL_MEMORY type is now being managed through the LMB module. Add a separate function, lmb_arch_add_memory() to add the RAM memory to the LMB memory map. The efi_add_known_memory() function is now used for adding any other memory type to the EFI memory map.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- arch/x86/lib/e820.c | 47 ++++++++++++++++++++++++++++++++++----------- lib/Kconfig | 2 +- 2 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/arch/x86/lib/e820.c b/arch/x86/lib/e820.c index 122b4f7ca0..d478b7486e 100644 --- a/arch/x86/lib/e820.c +++ b/arch/x86/lib/e820.c @@ -4,6 +4,7 @@ */
#include <efi_loader.h> +#include <lmb.h> #include <asm/e820.h> #include <asm/global_data.h>
@@ -41,15 +42,11 @@ void efi_add_known_memory(void) { struct e820_entry e820[E820MAX]; unsigned int i, num; - u64 start, ram_top; + u64 start; int type;
num = install_e820_map(ARRAY_SIZE(e820), e820);
- ram_top = (u64)gd->ram_top & ~EFI_PAGE_MASK; - if (!ram_top) - ram_top = 0x100000000ULL; - for (i = 0; i < num; ++i) { start = e820[i].addr;
@@ -72,13 +69,41 @@ void efi_add_known_memory(void) break; }
- if (type == EFI_CONVENTIONAL_MEMORY) { - efi_add_conventional_memory_map(start, - start + e820[i].size, - ram_top); - } else { + if (type != EFI_CONVENTIONAL_MEMORY) efi_add_memory_map(start, e820[i].size, type); - } } } #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */ + +#if CONFIG_IS_ENABLED(LMB_ARCH_MEM_MAP) +void lmb_arch_add_memory(void) +{ + struct e820_entry e820[E820MAX]; + unsigned int i, num; + u64 ram_top; + + num = install_e820_map(ARRAY_SIZE(e820), e820); + + ram_top = (u64)gd->ram_top & ~EFI_PAGE_MASK; + if (!ram_top) + ram_top = 0x100000000ULL; + + for (i = 0; i < num; ++i) { + if (e820[i].type == E820_RAM) { + u64 start, size, rgn_top; + + start = e820[i].addr; + size = e820[i].size; + rgn_top = start + size; + + if (start > ram_top) + continue; + + if (rgn_top > ram_top) + size -= rgn_top - ram_top; + + lmb_add(start, size); + } + } +} +#endif /* CONFIG_IS_ENABLED(LMB_ARCH_MEM_MAP) */ diff --git a/lib/Kconfig b/lib/Kconfig index ee0b4d65f2..75447dfa27 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -1130,7 +1130,7 @@ config SPL_LMB config LMB_ARCH_MEM_MAP bool "Add an architecture specific memory map" depends on LMB - default y if FSL_LAYERSCAPE + default y if FSL_LAYERSCAPE || X86 help Some architectures have special or unique aspects which need consideration when adding memory ranges to the list of available

The EFI_CONVENTIONAL_MEMORY type, which is the usable RAM memory is now being managed by the LMB module. Remove the addition of this memory type to the EFI memory map. This memory now gets added to the EFI memory map as part of the LMB memory map update event handler.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- include/efi_loader.h | 12 +++--- lib/efi_loader/efi_memory.c | 75 +++---------------------------------- 2 files changed, 12 insertions(+), 75 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h index f84852e384..d68709f611 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -784,9 +784,6 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, uint32_t *descriptor_version); /* Adds a range into the EFI memory map */ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); -/* Adds a conventional range into the EFI memory map */ -efi_status_t efi_add_conventional_memory_map(u64 ram_start, u64 ram_end, - u64 ram_top);
/* Called by board init to initialize the EFI drivers */ efi_status_t efi_driver_init(void); @@ -1172,9 +1169,14 @@ efi_status_t efi_console_get_u16_string efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int size);
/** - * efi_add_known_memory() - add memory banks to EFI memory map + * efi_add_known_memory() - add memory types to the EFI memory map * - * This weak function may be overridden for specific architectures. + * This function is to be used to adding different memory types other + * than EFI_CONVENTIONAL_MEMORY to the EFI memory map. The conventional + * memory is handled by the LMB module, and gets added to the memory + * map through the LMB module. + * + * This function may be overridden for specific architectures. */ void efi_add_known_memory(void);
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 900d3c12f1..02f1682b54 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -784,82 +784,17 @@ efi_status_t efi_get_memory_map_alloc(efi_uintn_t *map_size, }
/** - * efi_add_conventional_memory_map() - add a RAM memory area to the map + * efi_add_known_memory() - add memory types to the EFI memory map * - * @ram_start: start address of a RAM memory area - * @ram_end: end address of a RAM memory area - * @ram_top: max address to be used as conventional memory - * Return: status code - */ -efi_status_t efi_add_conventional_memory_map(u64 ram_start, u64 ram_end, - u64 ram_top) -{ - u64 pages; - - /* Remove partial pages */ - ram_end &= ~EFI_PAGE_MASK; - ram_start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK; - - if (ram_end <= ram_start) { - /* Invalid mapping */ - return EFI_INVALID_PARAMETER; - } - - pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT; - - efi_add_memory_map_pg(ram_start, pages, - EFI_CONVENTIONAL_MEMORY, false); - - /* - * Boards may indicate to the U-Boot memory core that they - * can not support memory above ram_top. Let's honor this - * in the efi_loader subsystem too by declaring any memory - * above ram_top as "already occupied by firmware". - */ - if (ram_top < ram_start) { - /* ram_top is before this region, reserve all */ - efi_add_memory_map_pg(ram_start, pages, - EFI_BOOT_SERVICES_DATA, true); - } else if (ram_top < ram_end) { - /* ram_top is inside this region, reserve parts */ - pages = (ram_end - ram_top) >> EFI_PAGE_SHIFT; - - efi_add_memory_map_pg(ram_top, pages, - EFI_BOOT_SERVICES_DATA, true); - } - - return EFI_SUCCESS; -} - -/** - * efi_add_known_memory() - add memory banks to map + * This function is to be used to adding different memory types other + * than EFI_CONVENTIONAL_MEMORY to the EFI memory map. The conventional + * memory is handled by the LMB module, and gets added to the memory + * map through the LMB module. * * This function may be overridden for specific architectures. */ __weak void efi_add_known_memory(void) { - u64 ram_top = gd->ram_top & ~EFI_PAGE_MASK; - int i; - - /* - * ram_top is just outside mapped memory. So use an offset of one for - * mapping the sandbox address. - */ - ram_top = (uintptr_t)map_sysmem(ram_top - 1, 0) + 1; - - /* Fix for 32bit targets with ram_top at 4G */ - if (!ram_top) - ram_top = 0x100000000ULL; - - /* Add RAM */ - for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { - u64 ram_end, ram_start; - - ram_start = (uintptr_t)map_sysmem(gd->bd->bi_dram[i].start, 0); - ram_end = ram_start + gd->bd->bi_dram[i].size; - - efi_add_conventional_memory_map(ram_start, ram_end, ram_top); - } }
/**

The EFI memory allocations are now being done through the LMB module. With this change, there is no need to get the EFI memory map and set aside EFI allocated memory.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- lib/lmb.c | 36 ------------------------------------ 1 file changed, 36 deletions(-)
diff --git a/lib/lmb.c b/lib/lmb.c index ec5078527e..7074217417 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -7,7 +7,6 @@ */
#include <alist.h> -#include <efi_loader.h> #include <event.h> #include <image.h> #include <mapmem.h> @@ -186,38 +185,6 @@ static void lmb_fix_over_lap_regions(struct alist *lmb_rgn_lst, lmb_remove_region(lmb_rgn_lst, r2); }
-/** - * efi_lmb_reserve() - add reservations for EFI memory - * - * Add reservations for all EFI memory areas that are not - * EFI_CONVENTIONAL_MEMORY. - * - * Return: 0 on success, 1 on failure - */ -static __maybe_unused int efi_lmb_reserve(void) -{ - struct efi_mem_desc *memmap = NULL, *map; - efi_uintn_t i, map_size = 0; - efi_status_t ret; - - ret = efi_get_memory_map_alloc(&map_size, &memmap); - if (ret != EFI_SUCCESS) - return 1; - - for (i = 0, map = memmap; i < map_size / sizeof(*map); ++map, ++i) { - if (map->type != EFI_CONVENTIONAL_MEMORY) { - lmb_reserve_flags(map_to_sysmem((void *)(uintptr_t) - map->physical_start), - map->num_pages * EFI_PAGE_SIZE, - map->type == EFI_RESERVED_MEMORY_TYPE - ? LMB_NOMAP : LMB_NONE); - } - } - efi_free_pool(memmap); - - return 0; -} - static void lmb_reserve_uboot_region(void) { int bank; @@ -264,9 +231,6 @@ static void lmb_reserve_common(void *fdt_blob)
if (CONFIG_IS_ENABLED(OF_LIBFDT) && fdt_blob) boot_fdt_add_mem_rsv_regions(fdt_blob); - - if (CONFIG_IS_ENABLED(EFI_LOADER)) - efi_lmb_reserve(); }
static __maybe_unused void lmb_reserve_common_spl(void)

With the addition of two events for notification of any changes to memory that is occupied and is free, the output of the event_dump.py script has changed. Update the expected event log to incorporate this change.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- test/py/tests/test_event_dump.py | 1 + 1 file changed, 1 insertion(+)
diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py index e282c67335..3537f0383c 100644 --- a/test/py/tests/test_event_dump.py +++ b/test/py/tests/test_event_dump.py @@ -19,6 +19,7 @@ def test_event_dump(u_boot_console): EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*boot/vbe_request.c:.* EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple_os.c:.* EVT_LAST_STAGE_INIT install_smbios_table .*lib/efi_loader/efi_smbios.c:.* +EVT_LMB_MAP_UPDATE lmb_mem_map_update_sync .*lib/efi_loader/efi_memory.c:.* EVT_MISC_INIT_F sandbox_early_getopt_check .*arch/sandbox/cpu/start.c:.* EVT_TEST h_adder_simple .*test/common/event.c:''' assert re.match(expect, out, re.MULTILINE) is not None

On 9/5/24 10:27, Sughosh Ganu wrote:
This is part two of the series to have the EFI and LMB modules have a coherent view of memory. Part one of this goal was to change the LMB module to have a global and persistent memory map. Those patches have now been applied to the next branch.
We should have only one memory map. This will ensure synchronicity.
Implementing the ARM64 requirement that 4 KiB pages with conflicting memory attributes cannot be located in the same 64 KiB cannot be reasonably implemented with the concept presented in this patch series.
Events should only be used to signal EFI_EVENT_GROUP_MEMORY_MAP_CHANGE.
Best regards
Heinrich
These patches are changing the EFI memory allocation API's such that they rely on the LMB module to allocate RAM memory. This fixes the current scenario where the EFI memory module has no visibility of the allocations/reservations made by the LMB module. One thing to note here is that this is limited to the RAM memory region, i.e. the EFI_CONVENTIONAL_MEMORY type. Any other memory type that is to be added to the EFI memory map, still gets handled by the EFI memory module.
Note: To be applied on top of the next branch.
Sughosh Ganu (16): lmb: add versions of the lmb API with flags lmb: add a flag to allow suppressing memory map change notification efi: memory: use the lmb API's for allocating and freeing memory event: add event to notify lmb memory map changes lib: Kconfig: add a config symbol for getting lmb memory map updates add a function to check if an address is in RAM memory lmb: notify of any changes to the LMB memory map efi_memory: add an event handler to update memory map ti: k3: remove efi_add_known_memory() function definition stm32mp: remove efi_add_known_memory() function definition lmb: allow for boards to specify memory map layerscape: use the lmb API's to add RAM memory x86: e820: use the lmb API for adding RAM memory efi_memory: do not add RAM memory to the memory map lmb: remove call to efi_lmb_reserve() test: event: update the expected event dump output
arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 8 +- arch/arm/mach-k3/common.c | 11 -- arch/arm/mach-stm32mp/dram_init.c | 11 -- arch/x86/lib/e820.c | 47 ++++-- common/board_r.c | 5 + common/event.c | 2 + include/efi_loader.h | 12 +- include/event.h | 14 ++ include/lmb.h | 11 ++ lib/Kconfig | 30 ++++ lib/efi_loader/Kconfig | 3 + lib/efi_loader/efi_memory.c | 184 ++++++++---------------- lib/lmb.c | 146 +++++++++++++------ test/py/tests/test_event_dump.py | 1 + 14 files changed, 276 insertions(+), 209 deletions(-)
participants (4)
-
Heinrich Schuchardt
-
Ilias Apalodimas
-
Simon Glass
-
Sughosh Ganu