* [RFC PATCH 00/31] Make U-Boot memory reservations coherent
@ 2024-06-07 18:52 Sughosh Ganu
2024-06-07 18:52 ` [RFC PATCH 01/31] lmb: remove the unused lmb_is_reserved() function Sughosh Ganu
` (32 more replies)
0 siblings, 33 replies; 127+ messages in thread
From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass,
Marek Vasut, Mark Kettenis, Fabio Estevam
The aim of this patch series is to fix the current state of
incoherence between modules when it comes to memory usage. The primary
issue that this series is trying to fix is that the EFI memory module
which is responsible for allocating and freeing memory, does not have
any visibility of the memory that is being used by the LMB
module. This is further complicated by the fact that the LMB
allocations are caller specific -- the LMB memory map is not global
nor persistent. This means that the memory "allocated" by the LMB
module might be relevant only for a given function. Hence one of the
requirements for making the memory usage visible across modules is to
make LMB allocations persistent and global, and then have means to
communicate the use of memory across modules.
The first set of patches in this series work on making the LMB memory
map persistent and global. This is being done keeping in mind the
usage of LMB memory by platforms where the same memory region can be
used to load multiple different images. What is not allowed is to
overwrite memory that has been allocated by the other module,
currently the EFI memory module. This is being achieved by introducing
a new flag, LMB_NOOVERWRITE, which represents memory which cannot be
re-requested once allocated.
The second set of patches are then introducing a notification
mechanism to indicate any changes to a respective module's memory
map. This way, any memory allocation/reservation by a module gets
notified to any interested listners, who then update their memory map
accordingly, thus keeping memory usage coherent.
Todo's
------
I have run these patches through CI, but the LMB unit tests need an
overhaul. I have currently marked these tests for manual run, as
running these would obviously tamper the LMB memory map, thus
affecting subsequent tests. The current set of LMB tests are written
with the assumption of local LMB memory maps. This needs to be
reworked.
Secondly, there needs to be a test written for testing the various
scenarios of memory being allocated and freed by different modules,
namely LMB and EFI. I have written a couple of commands for testing
the changes that I have made -- I have also included these temporary
commands to assist anyone who might want to test these changes. But I
will be working on adding a more comprehensive test.
Lastly, as the series touches common code, there is obviously an
increase in the size of the image, moreover since the LMB memory is
now persistent, and the variables do not reside on the stack. I want
to check if there can be ways of decreasing the size impact of the
changes.
Sughosh Ganu (31):
lmb: remove the unused lmb_is_reserved() function
lmb: staticize __lmb_alloc_base()
lmb: make the lmb reservations persistent
lmb: remove local instances of the lmb structure variable
lmb: pass a flag to image_setup_libfdt() for lmb reservations
lmb: reserve and add common memory regions post relocation
lmb: remove lmb_init_and_reserve_range() function
lmb: replcace the lmb_init_and_reserve() function
lmb: allow for resizing lmb regions
event: add events to notify memory map changes
lib: Kconfig: add a config symbol for getting memory map updates
add a function to check if an address is in RAM memory
efi_memory: notify of any changes to the EFI memory map
lmb: notify of any changes to the LMB memory map
efi_memory: add an event handler to update memory map
lmb: add an event handler to update memory map
lmb: remove call to efi_lmb_reserve()
sandbox: iommu: remove lmb allocation in the driver
zynq: lmb: do not add to lmb map before relocation
test: cedit: use allocated address for reading file
test: event: update the expected event dump output
test: lmb: run the LMB tests only on sandbox
test: lmb: initialise the lmb structure before tests
test: lmb: add a test case for checking overlapping region add
test: lmb: adjust the test case to handle overlapping regions
test: lmb: run lmb tests only manually
test: bdinfo: dump the global LMB memory map
cmd: bdinfo: only dump the current LMB memory
temp: mx6sabresd: bump up the size limit of the board
temp: cmd: efi_mem: add a command to test efi alloc/free
temp: cmd: efi: add a command to dump EFI memory map
arch/arc/lib/cache.c | 4 +-
arch/arm/lib/stack.c | 4 +-
arch/arm/mach-apple/board.c | 17 +-
arch/arm/mach-snapdragon/board.c | 17 +-
arch/arm/mach-stm32mp/dram_init.c | 8 +-
arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +-
arch/m68k/lib/bootm.c | 7 +-
arch/microblaze/lib/bootm.c | 4 +-
arch/mips/lib/bootm.c | 11 +-
arch/nios2/lib/bootm.c | 4 +-
arch/powerpc/cpu/mpc85xx/mp.c | 4 +-
arch/powerpc/include/asm/mp.h | 4 +-
arch/powerpc/lib/bootm.c | 14 +-
arch/riscv/lib/bootm.c | 4 +-
arch/sandbox/cpu/cpu.c | 5 +
arch/sh/lib/bootm.c | 4 +-
arch/x86/lib/bootm.c | 4 +-
arch/xtensa/lib/bootm.c | 4 +-
board/xilinx/common/board.c | 33 --
boot/bootm.c | 26 +-
boot/bootm_os.c | 5 +-
boot/image-board.c | 34 +--
boot/image-fdt.c | 36 +--
cmd/Makefile | 2 +
cmd/bdinfo.c | 5 +-
cmd/booti.c | 2 +-
cmd/bootz.c | 2 +-
cmd/efi_map_dump.c | 28 ++
cmd/efi_memory.c | 155 ++++++++++
cmd/elf.c | 2 +-
cmd/load.c | 7 +-
common/board_r.c | 20 ++
common/event.c | 4 +
configs/mx6sabresd_defconfig | 2 +-
drivers/iommu/apple_dart.c | 8 +-
drivers/iommu/sandbox_iommu.c | 17 +-
fs/fs.c | 7 +-
include/efi_loader.h | 2 +
include/event.h | 28 ++
include/image.h | 27 +-
include/lmb.h | 96 +++---
lib/Kconfig | 10 +
lib/efi_loader/efi_dt_fixup.c | 2 +-
lib/efi_loader/efi_helper.c | 2 +-
lib/efi_loader/efi_memory.c | 127 +++++++-
lib/lmb.c | 442 ++++++++++++++++++---------
net/tftp.c | 5 +-
net/wget.c | 5 +-
test/boot/cedit.c | 5 +-
test/cmd/bdinfo.c | 22 +-
test/lib/Makefile | 2 +-
test/lib/lmb.c | 274 +++++++++--------
test/py/tests/test_event_dump.py | 2 +
53 files changed, 1001 insertions(+), 570 deletions(-)
create mode 100644 cmd/efi_map_dump.c
create mode 100644 cmd/efi_memory.c
--
2.34.1
^ permalink raw reply [flat|nested] 127+ messages in thread* [RFC PATCH 01/31] lmb: remove the unused lmb_is_reserved() function 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 9:33 ` Ilias Apalodimas 2024-06-07 18:52 ` [RFC PATCH 02/31] lmb: staticize __lmb_alloc_base() Sughosh Ganu ` (31 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The lmb_is_reserved() API is not used. There is another API, lmb_is_reserved_flags() which can be used to check if a particular memory region is reserved. Remove the unused API. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- include/lmb.h | 11 ----------- lib/lmb.c | 5 ----- 2 files changed, 16 deletions(-) diff --git a/include/lmb.h b/include/lmb.h index 231b68b27d..6c50d93e83 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -117,17 +117,6 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size); phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr); -/** - * lmb_is_reserved() - test if address is in reserved region - * - * The function checks if a reserved region comprising @addr exists. - * - * @lmb: the logical memory block struct - * @addr: address to be tested - * Return: 1 if reservation exists, 0 otherwise - */ -int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr); - /** * lmb_is_reserved_flags() - test if address is in reserved region with flag bits set * diff --git a/lib/lmb.c b/lib/lmb.c index 44f9820531..adc3abd5b4 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -565,11 +565,6 @@ int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags) return 0; } -int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) -{ - return lmb_is_reserved_flags(lmb, addr, LMB_NONE); -} - __weak void board_lmb_reserve(struct lmb *lmb) { /* please define platform specific board_lmb_reserve() */ -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 01/31] lmb: remove the unused lmb_is_reserved() function 2024-06-07 18:52 ` [RFC PATCH 01/31] lmb: remove the unused lmb_is_reserved() function Sughosh Ganu @ 2024-06-10 9:33 ` Ilias Apalodimas 0 siblings, 0 replies; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 9:33 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Fri, 7 Jun 2024 at 21:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > The lmb_is_reserved() API is not used. There is another API, > lmb_is_reserved_flags() which can be used to check if a particular > memory region is reserved. Remove the unused API. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > include/lmb.h | 11 ----------- > lib/lmb.c | 5 ----- > 2 files changed, 16 deletions(-) > > diff --git a/include/lmb.h b/include/lmb.h > index 231b68b27d..6c50d93e83 100644 > --- a/include/lmb.h > +++ b/include/lmb.h > @@ -117,17 +117,6 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, > phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size); > phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr); > > -/** > - * lmb_is_reserved() - test if address is in reserved region > - * > - * The function checks if a reserved region comprising @addr exists. > - * > - * @lmb: the logical memory block struct > - * @addr: address to be tested > - * Return: 1 if reservation exists, 0 otherwise > - */ > -int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr); > - > /** > * lmb_is_reserved_flags() - test if address is in reserved region with flag bits set > * > diff --git a/lib/lmb.c b/lib/lmb.c > index 44f9820531..adc3abd5b4 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -565,11 +565,6 @@ int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags) > return 0; > } > > -int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) > -{ > - return lmb_is_reserved_flags(lmb, addr, LMB_NONE); > -} > - > __weak void board_lmb_reserve(struct lmb *lmb) > { > /* please define platform specific board_lmb_reserve() */ > -- > 2.34.1 > Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 02/31] lmb: staticize __lmb_alloc_base() 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 01/31] lmb: remove the unused lmb_is_reserved() function Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 9:37 ` Ilias Apalodimas 2024-06-07 18:52 ` [RFC PATCH 03/31] lmb: make the lmb reservations persistent Sughosh Ganu ` (30 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The __lmb_alloc_base() function is only called from within the lmb module. Moreover, the lmb_alloc() and lmb_alloc_base() API's are good enough for the allocation API calls. Make the __lmb_alloc_base() function static. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- include/lmb.h | 2 -- lib/lmb.c | 39 ++++++++++++++++++++------------------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/include/lmb.h b/include/lmb.h index 6c50d93e83..7b87181b9e 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -112,8 +112,6 @@ long lmb_reserve_flags(struct lmb *lmb, phys_addr_t base, phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align); phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr); -phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, - phys_addr_t max_addr); phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size); phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr); diff --git a/lib/lmb.c b/lib/lmb.c index adc3abd5b4..4d39c0d1f9 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -435,30 +435,13 @@ static long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base, return (i < rgn->cnt) ? i : -1; } -phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align) -{ - return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE); -} - -phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) -{ - phys_addr_t alloc; - - alloc = __lmb_alloc_base(lmb, size, align, max_addr); - - 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_align_down(phys_addr_t addr, phys_size_t size) { return addr & ~(size - 1); } -phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) +static phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, + ulong align, phys_addr_t max_addr) { long i, rgn; phys_addr_t base = 0; @@ -499,6 +482,24 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy return 0; } +phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align) +{ + return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE); +} + +phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) +{ + phys_addr_t alloc; + + alloc = __lmb_alloc_base(lmb, size, align, max_addr); + + if (alloc == 0) + printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", + (ulong)size, (ulong)max_addr); + + return alloc; +} + /* * Try to allocate a specific address range: must be in defined memory but not * reserved -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 02/31] lmb: staticize __lmb_alloc_base() 2024-06-07 18:52 ` [RFC PATCH 02/31] lmb: staticize __lmb_alloc_base() Sughosh Ganu @ 2024-06-10 9:37 ` Ilias Apalodimas 0 siblings, 0 replies; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 9:37 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Fri, 7 Jun 2024 at 21:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > The __lmb_alloc_base() function is only called from within the lmb > module. Moreover, the lmb_alloc() and lmb_alloc_base() API's are good > enough for the allocation API calls. Make the __lmb_alloc_base() > function static. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > include/lmb.h | 2 -- > lib/lmb.c | 39 ++++++++++++++++++++------------------- > 2 files changed, 20 insertions(+), 21 deletions(-) > > diff --git a/include/lmb.h b/include/lmb.h > index 6c50d93e83..7b87181b9e 100644 > --- a/include/lmb.h > +++ b/include/lmb.h > @@ -112,8 +112,6 @@ long lmb_reserve_flags(struct lmb *lmb, phys_addr_t base, > phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align); > phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, > phys_addr_t max_addr); > -phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, > - phys_addr_t max_addr); > phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size); > phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr); > > diff --git a/lib/lmb.c b/lib/lmb.c > index adc3abd5b4..4d39c0d1f9 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -435,30 +435,13 @@ static long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base, > return (i < rgn->cnt) ? i : -1; > } > > -phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align) > -{ > - return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE); > -} > - > -phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) > -{ > - phys_addr_t alloc; > - > - alloc = __lmb_alloc_base(lmb, size, align, max_addr); > - > - 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_align_down(phys_addr_t addr, phys_size_t size) > { > return addr & ~(size - 1); > } > > -phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) > +static phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, > + ulong align, phys_addr_t max_addr) > { > long i, rgn; > phys_addr_t base = 0; > @@ -499,6 +482,24 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy > return 0; > } > > +phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align) > +{ > + return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE); > +} > + > +phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) > +{ > + phys_addr_t alloc; > + > + alloc = __lmb_alloc_base(lmb, size, align, max_addr); > + > + if (alloc == 0) > + printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > + (ulong)size, (ulong)max_addr); > + > + return alloc; > +} > + > /* > * Try to allocate a specific address range: must be in defined memory but not > * reserved > -- > 2.34.1 > Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 03/31] lmb: make the lmb reservations persistent 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 01/31] lmb: remove the unused lmb_is_reserved() function Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 02/31] lmb: staticize __lmb_alloc_base() Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 21:17 ` Ilias Apalodimas 2024-06-11 18:52 ` Simon Glass 2024-06-07 18:52 ` [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable Sughosh Ganu ` (29 subsequent siblings) 32 siblings, 2 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The current LMB API's for allocating and reserving memory use a per-caller based memory view. Memory allocated by a caller can then be overwritten by another caller. Make these allocations and reservations persistent. With this, memory allocated or reserved will not be overwritten. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- Note: @Mark Kettenis, please review the changes made in the apple dart driver. I have removed the driver-local LMB instance, but I am not sure if the current logic makes sense. I would think that it would be possible to simply use memory region allocated by the LMB module(maybe using the max address argument), instead of adding specific memory region with lmb_add(). arch/arm/mach-stm32mp/dram_init.c | 1 - board/xilinx/common/board.c | 1 - drivers/iommu/apple_dart.c | 1 - drivers/iommu/sandbox_iommu.c | 1 - include/lmb.h | 17 ++---- lib/lmb.c | 91 ++++++++++++++++--------------- test/lib/lmb.c | 18 ------ 7 files changed, 50 insertions(+), 80 deletions(-) diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c index fb1208fc5d..86d6577b35 100644 --- a/arch/arm/mach-stm32mp/dram_init.c +++ b/arch/arm/mach-stm32mp/dram_init.c @@ -59,7 +59,6 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) gd->ram_top = clamp_val(gd->ram_top, 0, SZ_4G - 1); /* found enough not-reserved memory to relocated U-Boot */ - lmb_init(&lmb); lmb_add(&lmb, gd->ram_base, gd->ram_top - gd->ram_base); boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); /* add 8M for reserved memory for display, fdt, gd,... */ diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index b47d2d23f9..ebe57da7f8 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -685,7 +685,6 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob); /* found enough not-reserved memory to relocated U-Boot */ - lmb_init(&lmb); lmb_add(&lmb, gd->ram_base, gd->ram_size); boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); diff --git a/drivers/iommu/apple_dart.c b/drivers/iommu/apple_dart.c index 6ecd84303b..ef385d9c9f 100644 --- a/drivers/iommu/apple_dart.c +++ b/drivers/iommu/apple_dart.c @@ -214,7 +214,6 @@ static int apple_dart_probe(struct udevice *dev) priv->dvabase = DART_PAGE_SIZE; priv->dvaend = SZ_4G - DART_PAGE_SIZE; - lmb_init(&priv->lmb); lmb_add(&priv->lmb, priv->dvabase, priv->dvaend - priv->dvabase); /* Disable translations. */ diff --git a/drivers/iommu/sandbox_iommu.c b/drivers/iommu/sandbox_iommu.c index 6ceb7fd5ec..31ce91345c 100644 --- a/drivers/iommu/sandbox_iommu.c +++ b/drivers/iommu/sandbox_iommu.c @@ -55,7 +55,6 @@ static int sandbox_iommu_probe(struct udevice *dev) { struct sandbox_iommu_priv *priv = dev_get_priv(dev); - lmb_init(&priv->lmb); lmb_add(&priv->lmb, 0x89abc000, SZ_16K); return 0; diff --git a/include/lmb.h b/include/lmb.h index 7b87181b9e..bbe1c5299c 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -49,8 +49,7 @@ struct lmb_property { * => CONFIG_LMB_MEMORY_REGIONS: struct lmb.memory_regions * => CONFIG_LMB_RESERVED_REGIONS: struct lmb.reserved_regions * lmb_region.region is only a pointer to the correct buffer, - * initialized in lmb_init(). This configuration is useful to manage - * more reserved memory regions with CONFIG_LMB_RESERVED_REGIONS. + * initialized with these values. */ /** @@ -73,26 +72,18 @@ struct lmb_region { /** * struct lmb - Logical memory block handle. * - * Clients provide storage for Logical memory block (lmb) handles. - * The content of the structure is managed by the lmb library. - * A lmb struct is initialized by lmb_init() functions. - * The lmb struct is passed to all other lmb APIs. + * The Logical Memory Block structure which is used to keep track + * of available memory which can be used for stuff like loading + * images(kernel, initrd, fdt). * * @memory: Description of memory regions. * @reserved: Description of reserved regions. - * @memory_regions: Array of the memory regions (statically allocated) - * @reserved_regions: Array of the reserved regions (statically allocated) */ struct lmb { struct lmb_region memory; struct lmb_region reserved; -#if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) - struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS]; - struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS]; -#endif }; -void lmb_init(struct lmb *lmb); void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob); void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, phys_size_t size, void *fdt_blob); diff --git a/lib/lmb.c b/lib/lmb.c index 4d39c0d1f9..7f34d4a8b0 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -20,6 +20,25 @@ DECLARE_GLOBAL_DATA_PTR; #define LMB_ALLOC_ANYWHERE 0 +#if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) +struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS]; +struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS]; +#endif + +struct lmb lmb = { +#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) + .memory.max = CONFIG_LMB_MAX_REGIONS, + .reserved.max = CONFIG_LMB_MAX_REGIONS, +#else + .memory.max = CONFIG_LMB_MEMORY_REGIONS, + .reserved.max = CONFIG_LMB_RESERVED_REGIONS, + .memory.region = memory_regions, + .reserved.region = reserved_regions, +#endif + .memory.cnt = 0, + .reserved.cnt = 0, +}; + static void lmb_dump_region(struct lmb_region *rgn, char *name) { unsigned long long base, size, end; @@ -42,8 +61,8 @@ static void lmb_dump_region(struct lmb_region *rgn, char *name) void lmb_dump_all_force(struct lmb *lmb) { printf("lmb_dump_all:\n"); - lmb_dump_region(&lmb->memory, "memory"); - lmb_dump_region(&lmb->reserved, "reserved"); + lmb_dump_region(&lmb.memory, "memory"); + lmb_dump_region(&lmb.reserved, "reserved"); } void lmb_dump_all(struct lmb *lmb) @@ -130,21 +149,6 @@ static void lmb_fix_over_lap_regions(struct lmb_region *rgn, unsigned long r1, lmb_remove_region(rgn, r2); } -void lmb_init(struct lmb *lmb) -{ -#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) - lmb->memory.max = CONFIG_LMB_MAX_REGIONS; - lmb->reserved.max = CONFIG_LMB_MAX_REGIONS; -#else - lmb->memory.max = CONFIG_LMB_MEMORY_REGIONS; - lmb->reserved.max = CONFIG_LMB_RESERVED_REGIONS; - lmb->memory.region = lmb->memory_regions; - lmb->reserved.region = lmb->reserved_regions; -#endif - lmb->memory.cnt = 0; - lmb->reserved.cnt = 0; -} - void arch_lmb_reserve_generic(struct lmb *lmb, ulong sp, ulong end, ulong align) { ulong bank_end; @@ -231,8 +235,6 @@ void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob) { int i; - lmb_init(lmb); - for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { if (bd->bi_dram[i].size) { lmb_add(lmb, bd->bi_dram[i].start, @@ -247,7 +249,6 @@ void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob) void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, phys_size_t size, void *fdt_blob) { - lmb_init(lmb); lmb_add(lmb, base, size); lmb_reserve_common(lmb, fdt_blob); } @@ -352,14 +353,14 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, /* This routine may be called with relocation disabled. */ long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size) { - struct lmb_region *_rgn = &(lmb->memory); + struct lmb_region *_rgn = &lmb.memory; return lmb_add_region(_rgn, base, size); } long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) { - struct lmb_region *rgn = &(lmb->reserved); + struct lmb_region *rgn = &lmb.reserved; phys_addr_t rgnbegin, rgnend; phys_addr_t end = base + size - 1; int i; @@ -410,7 +411,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) long lmb_reserve_flags(struct lmb *lmb, phys_addr_t base, phys_size_t size, enum lmb_flags flags) { - struct lmb_region *_rgn = &(lmb->reserved); + struct lmb_region *_rgn = &lmb.reserved; return lmb_add_region_flags(_rgn, base, size, flags); } @@ -447,9 +448,9 @@ static phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, phys_addr_t base = 0; phys_addr_t res_base; - for (i = lmb->memory.cnt - 1; i >= 0; i--) { - phys_addr_t lmbbase = lmb->memory.region[i].base; - phys_size_t lmbsize = lmb->memory.region[i].size; + for (i = lmb.memory.cnt - 1; i >= 0; i--) { + phys_addr_t lmbbase = lmb.memory.region[i].base; + phys_size_t lmbsize = lmb.memory.region[i].size; if (lmbsize < size) continue; @@ -465,15 +466,15 @@ static phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, continue; while (base && lmbbase <= base) { - rgn = lmb_overlaps_region(&lmb->reserved, base, size); + rgn = lmb_overlaps_region(&lmb.reserved, base, size); if (rgn < 0) { /* This area isn't reserved, take it */ - if (lmb_add_region(&lmb->reserved, base, + if (lmb_add_region(&lmb.reserved, base, size) < 0) return 0; return base; } - res_base = lmb->reserved.region[rgn].base; + res_base = lmb.reserved.region[rgn].base; if (res_base < size) break; base = lmb_align_down(res_base - size, align); @@ -509,14 +510,14 @@ phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size) long rgn; /* Check if the requested address is in one of the memory regions */ - rgn = lmb_overlaps_region(&lmb->memory, base, size); + rgn = lmb_overlaps_region(&lmb.memory, base, size); if (rgn >= 0) { /* * Check if the requested end address is in the same memory * region we found. */ - if (lmb_addrs_overlap(lmb->memory.region[rgn].base, - lmb->memory.region[rgn].size, + if (lmb_addrs_overlap(lmb.memory.region[rgn].base, + lmb.memory.region[rgn].size, base + size - 1, 1)) { /* ok, reserve the memory */ if (lmb_reserve(lmb, base, size) >= 0) @@ -533,22 +534,22 @@ phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr) long rgn; /* check if the requested address is in the memory regions */ - rgn = lmb_overlaps_region(&lmb->memory, addr, 1); + rgn = lmb_overlaps_region(&lmb.memory, addr, 1); if (rgn >= 0) { - for (i = 0; i < lmb->reserved.cnt; i++) { - if (addr < lmb->reserved.region[i].base) { + for (i = 0; i < lmb.reserved.cnt; i++) { + if (addr < lmb.reserved.region[i].base) { /* first reserved range > requested address */ - return lmb->reserved.region[i].base - addr; + return lmb.reserved.region[i].base - addr; } - if (lmb->reserved.region[i].base + - lmb->reserved.region[i].size > addr) { + if (lmb.reserved.region[i].base + + lmb.reserved.region[i].size > addr) { /* requested addr is in this reserved range */ return 0; } } /* if we come here: no reserved ranges above requested addr */ - return lmb->memory.region[lmb->memory.cnt - 1].base + - lmb->memory.region[lmb->memory.cnt - 1].size - addr; + return lmb.memory.region[lmb.memory.cnt - 1].base + + lmb.memory.region[lmb.memory.cnt - 1].size - addr; } return 0; } @@ -557,11 +558,11 @@ int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags) { int i; - for (i = 0; i < lmb->reserved.cnt; i++) { - phys_addr_t upper = lmb->reserved.region[i].base + - lmb->reserved.region[i].size - 1; - if ((addr >= lmb->reserved.region[i].base) && (addr <= upper)) - return (lmb->reserved.region[i].flags & flags) == flags; + for (i = 0; i < lmb.reserved.cnt; i++) { + phys_addr_t upper = lmb.reserved.region[i].base + + lmb.reserved.region[i].size - 1; + if ((addr >= lmb.reserved.region[i].base) && (addr <= upper)) + return (lmb.reserved.region[i].flags & flags) == flags; } return 0; } diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 7e4368de22..42551b7c6d 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -76,8 +76,6 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, ut_assert(alloc_64k_addr >= ram + 8); ut_assert(alloc_64k_end <= ram_end - 8); - lmb_init(&lmb); - if (ram0_size) { ret = lmb_add(&lmb, ram0, ram0_size); ut_asserteq(ret, 0); @@ -237,8 +235,6 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); - lmb_init(&lmb); - ret = lmb_add(&lmb, ram, ram_size); ut_asserteq(ret, 0); @@ -304,8 +300,6 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); - lmb_init(&lmb); - ret = lmb_add(&lmb, ram, ram_size); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); @@ -390,8 +384,6 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) long ret; phys_addr_t a, b; - lmb_init(&lmb); - ret = lmb_add(&lmb, ram, ram_size); ut_asserteq(ret, 0); @@ -429,8 +421,6 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) struct lmb lmb; long ret; - lmb_init(&lmb); - ret = lmb_add(&lmb, ram, ram_size); ut_asserteq(ret, 0); @@ -487,8 +477,6 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); - lmb_init(&lmb); - ret = lmb_add(&lmb, ram, ram_size); ut_asserteq(ret, 0); @@ -614,8 +602,6 @@ static int test_get_unreserved_size(struct unit_test_state *uts, /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); - lmb_init(&lmb); - ret = lmb_add(&lmb, ram, ram_size); ut_asserteq(ret, 0); @@ -684,8 +670,6 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) struct lmb lmb; int ret, i; - lmb_init(&lmb); - ut_asserteq(lmb.memory.cnt, 0); ut_asserteq(lmb.memory.max, CONFIG_LMB_MAX_REGIONS); ut_asserteq(lmb.reserved.cnt, 0); @@ -745,8 +729,6 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) struct lmb lmb; long ret; - lmb_init(&lmb); - ret = lmb_add(&lmb, ram, ram_size); ut_asserteq(ret, 0); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 03/31] lmb: make the lmb reservations persistent 2024-06-07 18:52 ` [RFC PATCH 03/31] lmb: make the lmb reservations persistent Sughosh Ganu @ 2024-06-10 21:17 ` Ilias Apalodimas 2024-06-10 11:23 ` Heinrich Schuchardt 2024-06-11 18:52 ` Simon Glass 1 sibling, 1 reply; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 21:17 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Sughosh [...] > #define LMB_ALLOC_ANYWHERE 0 > > +#if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) > +struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS]; > +struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS]; > +#endif > + > +struct lmb lmb = { > +#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) > + .memory.max = CONFIG_LMB_MAX_REGIONS, > + .reserved.max = CONFIG_LMB_MAX_REGIONS, > +#else > + .memory.max = CONFIG_LMB_MEMORY_REGIONS, > + .reserved.max = CONFIG_LMB_RESERVED_REGIONS, > + .memory.region = memory_regions, > + .reserved.region = reserved_regions, This is probably a good opportunity to look into why CONFIG_LMB_MEMORY_REGIONS was introduced. Since we are moving towards static allocations, do we still need it? Or allocating the size dynamically covers all our cases. > +#endif > + .memory.cnt = 0, > + .reserved.cnt = 0, > +}; > + > static void lmb_dump_region(struct lmb_region *rgn, char *name) > { > unsigned long long base, size, end; > @@ -42,8 +61,8 @@ static void lmb_dump_region(struct lmb_region *rgn, char *name) > void lmb_dump_all_force(struct lmb *lmb) > { > printf("lmb_dump_all:\n"); > - lmb_dump_region(&lmb->memory, "memory"); > - lmb_dump_region(&lmb->reserved, "reserved"); > + lmb_dump_region(&lmb.memory, "memory"); > + lmb_dump_region(&lmb.reserved, "reserved"); > } > [...] Thanks /Ilias ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 03/31] lmb: make the lmb reservations persistent 2024-06-10 21:17 ` Ilias Apalodimas @ 2024-06-10 11:23 ` Heinrich Schuchardt 2024-06-10 16:55 ` Tom Rini 0 siblings, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-10 11:23 UTC (permalink / raw) To: Ilias Apalodimas, Sughosh Ganu Cc: u-boot, Tom Rini, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On 1/1/70 01:00, Ilias Apalodimas wrote: > Hi Sughosh > > [...] > >> #define LMB_ALLOC_ANYWHERE 0 >> >> +#if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) >> +struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS]; >> +struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS]; >> +#endif >> + >> +struct lmb lmb = { >> +#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) >> + .memory.max = CONFIG_LMB_MAX_REGIONS, >> + .reserved.max = CONFIG_LMB_MAX_REGIONS, >> +#else >> + .memory.max = CONFIG_LMB_MEMORY_REGIONS, >> + .reserved.max = CONFIG_LMB_RESERVED_REGIONS, >> + .memory.region = memory_regions, >> + .reserved.region = reserved_regions, > > This is probably a good opportunity to look into why > CONFIG_LMB_MEMORY_REGIONS was introduced. Since we are moving towards > static allocations, do we still need it? Or allocating the size dynamically > covers all our cases. Up to now we used static arrays for saving memory allocations in LMB: include/lmb.h:67: struct lmb_property region[CONFIG_LMB_MAX_REGIONS]; As the EFI sub-system can produce any number of non-coalescable memory regions we should use a linked list instead. The fields memory.max and reserved.max seem to be unused except for test/lib/lmb.c. lib/lmb.c:136: lmb->memory.max = CONFIG_LMB_MAX_REGIONS; lib/lmb.c:139: lmb->memory.max = CONFIG_LMB_MEMORY_REGIONS; test/lib/lmb.c:689: ut_asserteq(lmb.memory.max, CONFIG_LMB_MAX_REGIONS); lib/lmb.c:137: lmb->reserved.max = CONFIG_LMB_MAX_REGIONS; lib/lmb.c:140: lmb->reserved.max = CONFIG_LMB_RESERVED_REGIONS; test/lib/lmb.c:691: ut_asserteq(lmb.reserved.max, CONFIG_LMB_MAX_REGIONS); Best regards Heinrich > > >> +#endif >> + .memory.cnt = 0, >> + .reserved.cnt = 0, >> +}; >> + >> static void lmb_dump_region(struct lmb_region *rgn, char *name) >> { >> unsigned long long base, size, end; >> @@ -42,8 +61,8 @@ static void lmb_dump_region(struct lmb_region *rgn, char *name) >> void lmb_dump_all_force(struct lmb *lmb) >> { >> printf("lmb_dump_all:\n"); >> - lmb_dump_region(&lmb->memory, "memory"); >> - lmb_dump_region(&lmb->reserved, "reserved"); >> + lmb_dump_region(&lmb.memory, "memory"); >> + lmb_dump_region(&lmb.reserved, "reserved"); >> } >> > > [...] > > > Thanks > /Ilias > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 03/31] lmb: make the lmb reservations persistent 2024-06-10 11:23 ` Heinrich Schuchardt @ 2024-06-10 16:55 ` Tom Rini 0 siblings, 0 replies; 127+ messages in thread From: Tom Rini @ 2024-06-10 16:55 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Ilias Apalodimas, Sughosh Ganu, u-boot, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 1606 bytes --] On Mon, Jun 10, 2024 at 01:23:49PM +0200, Heinrich Schuchardt wrote: > On 1/1/70 01:00, Ilias Apalodimas wrote: > > Hi Sughosh > > > > [...] > > > > > #define LMB_ALLOC_ANYWHERE 0 > > > > > > +#if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) > > > +struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS]; > > > +struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS]; > > > +#endif > > > + > > > +struct lmb lmb = { > > > +#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) > > > + .memory.max = CONFIG_LMB_MAX_REGIONS, > > > + .reserved.max = CONFIG_LMB_MAX_REGIONS, > > > +#else > > > + .memory.max = CONFIG_LMB_MEMORY_REGIONS, > > > + .reserved.max = CONFIG_LMB_RESERVED_REGIONS, > > > + .memory.region = memory_regions, > > > + .reserved.region = reserved_regions, > > > > This is probably a good opportunity to look into why > > CONFIG_LMB_MEMORY_REGIONS was introduced. Since we are moving towards > > static allocations, do we still need it? Or allocating the size dynamically > > covers all our cases. > > Up to now we used static arrays for saving memory allocations in LMB: > > include/lmb.h:67: > struct lmb_property region[CONFIG_LMB_MAX_REGIONS]; > > As the EFI sub-system can produce any number of non-coalescable memory > regions we should use a linked list instead. I think it's some historic flexibility that's I believe no longer really relevant to how we use LMB today, let alone once this patch series is complete. We should probably (I'm doing my size check thing now..) move to just following Heinrich's suggestion. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 03/31] lmb: make the lmb reservations persistent 2024-06-07 18:52 ` [RFC PATCH 03/31] lmb: make the lmb reservations persistent Sughosh Ganu 2024-06-10 21:17 ` Ilias Apalodimas @ 2024-06-11 18:52 ` Simon Glass 1 sibling, 0 replies; 127+ messages in thread From: Simon Glass @ 2024-06-11 18:52 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam HI Sughosh, On Fri, 7 Jun 2024 at 12:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > The current LMB API's for allocating and reserving memory use a > per-caller based memory view. Memory allocated by a caller can then be > overwritten by another caller. Make these allocations and reservations > persistent. With this, memory allocated or reserved will not be > overwritten. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > > Note: @Mark Kettenis, please review the changes made in the apple dart > driver. I have removed the driver-local LMB instance, but I am not > sure if the current logic makes sense. I would think that it would be > possible to simply use memory region allocated by the LMB module(maybe > using the max address argument), instead of adding specific memory > region with lmb_add(). > > arch/arm/mach-stm32mp/dram_init.c | 1 - > board/xilinx/common/board.c | 1 - > drivers/iommu/apple_dart.c | 1 - > drivers/iommu/sandbox_iommu.c | 1 - > include/lmb.h | 17 ++---- > lib/lmb.c | 91 ++++++++++++++++--------------- > test/lib/lmb.c | 18 ------ > 7 files changed, 50 insertions(+), 80 deletions(-) > > diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c > index fb1208fc5d..86d6577b35 100644 > --- a/arch/arm/mach-stm32mp/dram_init.c > +++ b/arch/arm/mach-stm32mp/dram_init.c > @@ -59,7 +59,6 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) > gd->ram_top = clamp_val(gd->ram_top, 0, SZ_4G - 1); > > /* found enough not-reserved memory to relocated U-Boot */ > - lmb_init(&lmb); > lmb_add(&lmb, gd->ram_base, gd->ram_top - gd->ram_base); > boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); > /* add 8M for reserved memory for display, fdt, gd,... */ > diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c > index b47d2d23f9..ebe57da7f8 100644 > --- a/board/xilinx/common/board.c > +++ b/board/xilinx/common/board.c > @@ -685,7 +685,6 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) > panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob); > > /* found enough not-reserved memory to relocated U-Boot */ > - lmb_init(&lmb); > lmb_add(&lmb, gd->ram_base, gd->ram_size); > boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); > size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); > diff --git a/drivers/iommu/apple_dart.c b/drivers/iommu/apple_dart.c > index 6ecd84303b..ef385d9c9f 100644 > --- a/drivers/iommu/apple_dart.c > +++ b/drivers/iommu/apple_dart.c > @@ -214,7 +214,6 @@ static int apple_dart_probe(struct udevice *dev) > priv->dvabase = DART_PAGE_SIZE; > priv->dvaend = SZ_4G - DART_PAGE_SIZE; > > - lmb_init(&priv->lmb); > lmb_add(&priv->lmb, priv->dvabase, priv->dvaend - priv->dvabase); > > /* Disable translations. */ > diff --git a/drivers/iommu/sandbox_iommu.c b/drivers/iommu/sandbox_iommu.c > index 6ceb7fd5ec..31ce91345c 100644 > --- a/drivers/iommu/sandbox_iommu.c > +++ b/drivers/iommu/sandbox_iommu.c > @@ -55,7 +55,6 @@ static int sandbox_iommu_probe(struct udevice *dev) > { > struct sandbox_iommu_priv *priv = dev_get_priv(dev); > > - lmb_init(&priv->lmb); > lmb_add(&priv->lmb, 0x89abc000, SZ_16K); > > return 0; > diff --git a/include/lmb.h b/include/lmb.h > index 7b87181b9e..bbe1c5299c 100644 > --- a/include/lmb.h > +++ b/include/lmb.h > @@ -49,8 +49,7 @@ struct lmb_property { > * => CONFIG_LMB_MEMORY_REGIONS: struct lmb.memory_regions > * => CONFIG_LMB_RESERVED_REGIONS: struct lmb.reserved_regions > * lmb_region.region is only a pointer to the correct buffer, > - * initialized in lmb_init(). This configuration is useful to manage > - * more reserved memory regions with CONFIG_LMB_RESERVED_REGIONS. > + * initialized with these values. > */ > > /** > @@ -73,26 +72,18 @@ struct lmb_region { > /** > * struct lmb - Logical memory block handle. > * > - * Clients provide storage for Logical memory block (lmb) handles. > - * The content of the structure is managed by the lmb library. > - * A lmb struct is initialized by lmb_init() functions. > - * The lmb struct is passed to all other lmb APIs. > + * The Logical Memory Block structure which is used to keep track > + * of available memory which can be used for stuff like loading > + * images(kernel, initrd, fdt). > * > * @memory: Description of memory regions. > * @reserved: Description of reserved regions. > - * @memory_regions: Array of the memory regions (statically allocated) > - * @reserved_regions: Array of the reserved regions (statically allocated) > */ > struct lmb { > struct lmb_region memory; > struct lmb_region reserved; > -#if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) > - struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS]; > - struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS]; > -#endif > }; > > -void lmb_init(struct lmb *lmb); > void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob); > void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, > phys_size_t size, void *fdt_blob); > diff --git a/lib/lmb.c b/lib/lmb.c > index 4d39c0d1f9..7f34d4a8b0 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -20,6 +20,25 @@ DECLARE_GLOBAL_DATA_PTR; > > #define LMB_ALLOC_ANYWHERE 0 > > +#if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) > +struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS]; > +struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS]; > +#endif > + > +struct lmb lmb = { > +#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) > + .memory.max = CONFIG_LMB_MAX_REGIONS, > + .reserved.max = CONFIG_LMB_MAX_REGIONS, > +#else > + .memory.max = CONFIG_LMB_MEMORY_REGIONS, > + .reserved.max = CONFIG_LMB_RESERVED_REGIONS, > + .memory.region = memory_regions, > + .reserved.region = reserved_regions, > +#endif > + .memory.cnt = 0, > + .reserved.cnt = 0, > +}; Please use a pointer in global_data, so we can handle tests. Also for bootstd we likely want to create a new one and 'own everything'. I haven't thought it through fully, though. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (2 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 03/31] lmb: make the lmb reservations persistent Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-11 18:52 ` Simon Glass 2024-06-07 18:52 ` [RFC PATCH 05/31] lmb: pass a flag to image_setup_libfdt() for lmb reservations Sughosh Ganu ` (28 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu With the move of the LMB structure to a persistent state, there is no need to declare the variable locally, and pass it as part of the LMB API's. Remove all local variable instances and change the API's correspondingly. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- arch/arc/lib/cache.c | 4 +- arch/arm/lib/stack.c | 4 +- arch/arm/mach-apple/board.c | 17 ++- arch/arm/mach-snapdragon/board.c | 17 ++- arch/arm/mach-stm32mp/dram_init.c | 7 +- arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +- arch/m68k/lib/bootm.c | 7 +- arch/microblaze/lib/bootm.c | 4 +- arch/mips/lib/bootm.c | 9 +- arch/nios2/lib/bootm.c | 4 +- arch/powerpc/cpu/mpc85xx/mp.c | 4 +- arch/powerpc/include/asm/mp.h | 4 +- arch/powerpc/lib/bootm.c | 14 +- arch/riscv/lib/bootm.c | 4 +- arch/sh/lib/bootm.c | 4 +- arch/x86/lib/bootm.c | 4 +- arch/xtensa/lib/bootm.c | 4 +- board/xilinx/common/board.c | 7 +- boot/bootm.c | 26 ++-- boot/bootm_os.c | 5 +- boot/image-board.c | 32 ++--- boot/image-fdt.c | 29 ++--- cmd/bdinfo.c | 6 +- cmd/booti.c | 2 +- cmd/bootz.c | 2 +- cmd/load.c | 7 +- drivers/iommu/apple_dart.c | 7 +- drivers/iommu/sandbox_iommu.c | 15 +-- fs/fs.c | 7 +- include/image.h | 22 +--- include/lmb.h | 39 +++--- lib/lmb.c | 81 ++++++------ net/tftp.c | 5 +- net/wget.c | 5 +- test/cmd/bdinfo.c | 2 +- test/lib/lmb.c | 187 +++++++++++++-------------- 36 files changed, 270 insertions(+), 333 deletions(-) diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index 22e748868a..5151af917a 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -829,7 +829,7 @@ static ulong get_sp(void) return ret; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096); } diff --git a/arch/arm/lib/stack.c b/arch/arm/lib/stack.c index 656084c7e5..9e41c5d91e 100644 --- a/arch/arm/lib/stack.c +++ b/arch/arm/lib/stack.c @@ -43,7 +43,7 @@ static ulong get_sp(void) return ret; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 16384); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 16384); } diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 7a6151a972..c877c7b94c 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -774,23 +774,22 @@ u64 get_page_table_size(void) int board_late_init(void) { - struct lmb lmb; u32 status = 0; - lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); + lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); /* somewhat based on the Linux Kernel boot requirements: * align by 2M and maximal FDT size 2M */ - status |= env_set_hex("loadaddr", lmb_alloc(&lmb, SZ_1G, SZ_2M)); - status |= env_set_hex("fdt_addr_r", lmb_alloc(&lmb, SZ_2M, SZ_2M)); - status |= env_set_hex("kernel_addr_r", lmb_alloc(&lmb, SZ_128M, SZ_2M)); - status |= env_set_hex("ramdisk_addr_r", lmb_alloc(&lmb, SZ_1G, SZ_2M)); + status |= env_set_hex("loadaddr", lmb_alloc(SZ_1G, SZ_2M)); + status |= env_set_hex("fdt_addr_r", lmb_alloc(SZ_2M, SZ_2M)); + status |= env_set_hex("kernel_addr_r", lmb_alloc(SZ_128M, SZ_2M)); + status |= env_set_hex("ramdisk_addr_r", lmb_alloc(SZ_1G, SZ_2M)); status |= env_set_hex("kernel_comp_addr_r", - lmb_alloc(&lmb, KERNEL_COMP_SIZE, SZ_2M)); + lmb_alloc(KERNEL_COMP_SIZE, SZ_2M)); status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE); - status |= env_set_hex("scriptaddr", lmb_alloc(&lmb, SZ_4M, SZ_2M)); - status |= env_set_hex("pxefile_addr_r", lmb_alloc(&lmb, SZ_4M, SZ_2M)); + status |= env_set_hex("scriptaddr", lmb_alloc(SZ_4M, SZ_2M)); + status |= env_set_hex("pxefile_addr_r", lmb_alloc(SZ_4M, SZ_2M)); if (status) log_warning("late_init: Failed to set run time variables\n"); diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c index b439a19ec7..a63c8bec45 100644 --- a/arch/arm/mach-snapdragon/board.c +++ b/arch/arm/mach-snapdragon/board.c @@ -275,24 +275,23 @@ void __weak qcom_late_init(void) #define KERNEL_COMP_SIZE SZ_64M -#define addr_alloc(lmb, size) lmb_alloc(lmb, size, SZ_2M) +#define addr_alloc(size) lmb_alloc(size, SZ_2M) /* Stolen from arch/arm/mach-apple/board.c */ int board_late_init(void) { - struct lmb lmb; u32 status = 0; - lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); + lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); /* We need to be fairly conservative here as we support boards with just 1G of TOTAL RAM */ - status |= env_set_hex("kernel_addr_r", addr_alloc(&lmb, SZ_128M)); - status |= env_set_hex("ramdisk_addr_r", addr_alloc(&lmb, SZ_128M)); - status |= env_set_hex("kernel_comp_addr_r", addr_alloc(&lmb, KERNEL_COMP_SIZE)); + status |= env_set_hex("kernel_addr_r", addr_alloc(SZ_128M)); + status |= env_set_hex("ramdisk_addr_r", addr_alloc(SZ_128M)); + status |= env_set_hex("kernel_comp_addr_r", addr_alloc(KERNEL_COMP_SIZE)); status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE); - status |= env_set_hex("scriptaddr", addr_alloc(&lmb, SZ_4M)); - status |= env_set_hex("pxefile_addr_r", addr_alloc(&lmb, SZ_4M)); - status |= env_set_hex("fdt_addr_r", addr_alloc(&lmb, SZ_2M)); + status |= env_set_hex("scriptaddr", addr_alloc(SZ_4M)); + status |= env_set_hex("pxefile_addr_r", addr_alloc(SZ_4M)); + status |= env_set_hex("fdt_addr_r", addr_alloc(SZ_2M)); if (status) log_warning("%s: Failed to set run time variables\n", __func__); diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c index 86d6577b35..33bca6f3c0 100644 --- a/arch/arm/mach-stm32mp/dram_init.c +++ b/arch/arm/mach-stm32mp/dram_init.c @@ -47,7 +47,6 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) { phys_size_t size; phys_addr_t reg; - struct lmb lmb; if (!total_size) return gd->ram_top; @@ -59,11 +58,11 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) gd->ram_top = clamp_val(gd->ram_top, 0, SZ_4G - 1); /* found enough not-reserved memory to relocated U-Boot */ - lmb_add(&lmb, gd->ram_base, gd->ram_top - gd->ram_base); - boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); + lmb_add(gd->ram_base, gd->ram_top - gd->ram_base); + boot_fdt_add_mem_rsv_regions((void *)gd->fdt_blob); /* add 8M for reserved memory for display, fdt, gd,... */ size = ALIGN(SZ_8M + CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE), - reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); + reg = lmb_alloc(size, MMU_SECTION_SIZE); if (!reg) reg = gd->ram_top - size; diff --git a/arch/arm/mach-stm32mp/stm32mp1/cpu.c b/arch/arm/mach-stm32mp/stm32mp1/cpu.c index 524778f00c..a223297034 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/cpu.c +++ b/arch/arm/mach-stm32mp/stm32mp1/cpu.c @@ -31,8 +31,6 @@ */ u8 early_tlb[PGTABLE_SIZE] __section(".data") __aligned(0x4000); -struct lmb lmb; - u32 get_bootmode(void) { /* read bootmode from TAMP backup register */ @@ -81,7 +79,7 @@ void dram_bank_mmu_setup(int bank) i < (start >> MMU_SECTION_SHIFT) + (size >> MMU_SECTION_SHIFT); i++) { option = DCACHE_DEFAULT_OPTION; - if (use_lmb && lmb_is_reserved_flags(&lmb, i << MMU_SECTION_SHIFT, LMB_NOMAP)) + if (use_lmb && lmb_is_reserved_flags(i << MMU_SECTION_SHIFT, LMB_NOMAP)) option = 0; /* INVALID ENTRY in TLB */ set_section_dcache(i, option); } @@ -145,7 +143,7 @@ int mach_cpu_init(void) void enable_caches(void) { /* parse device tree when data cache is still activated */ - lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); + lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); /* I-cache is already enabled in start.S: icache_enable() not needed */ diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c index f2d02e4376..eb220d178d 100644 --- a/arch/m68k/lib/bootm.c +++ b/arch/m68k/lib/bootm.c @@ -30,9 +30,9 @@ DECLARE_GLOBAL_DATA_PTR; static ulong get_sp (void); static void set_clocks_in_mhz (struct bd_info *kbd); -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 1024); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 1024); } int do_bootm_linux(int flag, struct bootm_info *bmi) @@ -41,7 +41,6 @@ int do_bootm_linux(int flag, struct bootm_info *bmi) int ret; struct bd_info *kbd; void (*kernel) (struct bd_info *, ulong, ulong, ulong, ulong); - struct lmb *lmb = &images->lmb; /* * allow the PREP bootm subcommand, it is required for bootm to work @@ -53,7 +52,7 @@ int do_bootm_linux(int flag, struct bootm_info *bmi) return 1; /* allocate space for kernel copy of board info */ - ret = boot_get_kbd (lmb, &kbd); + ret = boot_get_kbd (&kbd); if (ret) { puts("ERROR with allocation of kernel bd\n"); goto error; diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index cbe9d85aa9..ce96bca28f 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -32,9 +32,9 @@ static ulong get_sp(void) return ret; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096); } static void boot_jump_linux(struct bootm_headers *images, int flag) diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index adb6b6cc22..54d89e9cca 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -37,9 +37,9 @@ static ulong arch_get_sp(void) return ret; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, arch_get_sp(), gd->ram_top, 4096); + arch_lmb_reserve_generic(arch_get_sp(), gd->ram_top, 4096); } static void linux_cmdline_init(void) @@ -225,9 +225,8 @@ static int boot_reloc_fdt(struct bootm_headers *images) } #if CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && CONFIG_IS_ENABLED(OF_LIBFDT) - boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); - return boot_relocate_fdt(&images->lmb, &images->ft_addr, - &images->ft_len); + boot_fdt_add_mem_rsv_regions(images->ft_addr); + return boot_relocate_fdt(&images->ft_addr, &images->ft_len); #else return 0; #endif diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index 657a17c720..91ba537f7c 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -74,7 +74,7 @@ static ulong get_sp(void) return ret; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096); } diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 7c47e415f0..5411bcad35 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -409,11 +409,11 @@ static void plat_mp_up(unsigned long bootpg, unsigned int pagesize) } #endif -void cpu_mp_lmb_reserve(struct lmb *lmb) +void cpu_mp_lmb_reserve(void) { u32 bootpg = determine_mp_bootpg(NULL); - lmb_reserve(lmb, bootpg, 4096); + lmb_reserve(bootpg, 4096); } void setup_mp(void) diff --git a/arch/powerpc/include/asm/mp.h b/arch/powerpc/include/asm/mp.h index 8dacd2781d..b3f59be840 100644 --- a/arch/powerpc/include/asm/mp.h +++ b/arch/powerpc/include/asm/mp.h @@ -6,10 +6,8 @@ #ifndef _ASM_MP_H_ #define _ASM_MP_H_ -#include <lmb.h> - void setup_mp(void); -void cpu_mp_lmb_reserve(struct lmb *lmb); +void cpu_mp_lmb_reserve(void); u32 determine_mp_bootpg(unsigned int *pagesize); int is_core_disabled(int nr); diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index 75c6bfd2bf..3f26d07a2d 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -117,7 +117,7 @@ static void boot_jump_linux(struct bootm_headers *images) return; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { phys_size_t bootm_size; ulong size, bootmap_base; @@ -140,13 +140,13 @@ void arch_lmb_reserve(struct lmb *lmb) ulong base = bootmap_base + size; printf("WARNING: adjusting available memory from 0x%lx to 0x%llx\n", size, (unsigned long long)bootm_size); - lmb_reserve(lmb, base, bootm_size - size); + lmb_reserve(base, bootm_size - size); } - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096); #ifdef CONFIG_MP - cpu_mp_lmb_reserve(lmb); + cpu_mp_lmb_reserve(); #endif return; @@ -167,7 +167,6 @@ static void boot_prep_linux(struct bootm_headers *images) static int boot_cmdline_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; - struct lmb *lmb = &images->lmb; ulong *cmd_start = &images->cmdline_start; ulong *cmd_end = &images->cmdline_end; @@ -175,7 +174,7 @@ static int boot_cmdline_linux(struct bootm_headers *images) if (!of_size) { /* allocate space and init command line */ - ret = boot_get_cmdline (lmb, cmd_start, cmd_end); + ret = boot_get_cmdline (cmd_start, cmd_end); if (ret) { puts("ERROR with allocation of cmdline\n"); return ret; @@ -188,14 +187,13 @@ static int boot_cmdline_linux(struct bootm_headers *images) static int boot_bd_t_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; - struct lmb *lmb = &images->lmb; struct bd_info **kbd = &images->kbd; int ret = 0; if (!of_size) { /* allocate space for kernel copy of board info */ - ret = boot_get_kbd (lmb, kbd); + ret = boot_get_kbd (kbd); if (ret) { puts("ERROR with allocation of kernel bd\n"); return ret; diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 13cbaaba68..bbf62f9e05 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -142,7 +142,7 @@ static ulong get_sp(void) return ret; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096); } diff --git a/arch/sh/lib/bootm.c b/arch/sh/lib/bootm.c index 05d586b1b6..345f1267a7 100644 --- a/arch/sh/lib/bootm.c +++ b/arch/sh/lib/bootm.c @@ -110,7 +110,7 @@ static ulong get_sp(void) return ret; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096); } diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 050c420e86..0f4436d26a 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -268,7 +268,7 @@ static ulong get_sp(void) return ret; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096); } diff --git a/arch/xtensa/lib/bootm.c b/arch/xtensa/lib/bootm.c index 9780d46e9b..5a950da232 100644 --- a/arch/xtensa/lib/bootm.c +++ b/arch/xtensa/lib/bootm.c @@ -207,7 +207,7 @@ static ulong get_sp(void) return ret; } -void arch_lmb_reserve(struct lmb *lmb) +void arch_lmb_reserve(void) { - arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); + arch_lmb_reserve_generic(get_sp(), gd->ram_top, 4096); } diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index ebe57da7f8..7be1b6e511 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -676,7 +676,6 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) { phys_size_t size; phys_addr_t reg; - struct lmb lmb; if (!total_size) return gd->ram_top; @@ -685,10 +684,10 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob); /* found enough not-reserved memory to relocated U-Boot */ - lmb_add(&lmb, gd->ram_base, gd->ram_size); - boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); + lmb_add(gd->ram_base, gd->ram_size); + boot_fdt_add_mem_rsv_regions((void *)gd->fdt_blob); size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); - reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); + reg = lmb_alloc(size, MMU_SECTION_SIZE); if (!reg) reg = gd->ram_top - size; diff --git a/boot/bootm.c b/boot/bootm.c index 032f5a4a16..cd1003120c 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -240,7 +240,7 @@ static int boot_get_kernel(const char *addr_fit, struct bootm_headers *images, } #ifdef CONFIG_LMB -static void boot_start_lmb(struct bootm_headers *images) +static void boot_start_lmb(void) { phys_addr_t mem_start; phys_size_t mem_size; @@ -248,12 +248,11 @@ static void boot_start_lmb(struct bootm_headers *images) mem_start = env_get_bootm_low(); mem_size = env_get_bootm_size(); - lmb_init_and_reserve_range(&images->lmb, mem_start, - mem_size, NULL); + lmb_init_and_reserve_range(mem_start, mem_size, NULL); } #else -#define lmb_reserve(lmb, base, size) -static inline void boot_start_lmb(struct bootm_headers *images) { } +#define lmb_reserve(base, size) +static inline void boot_start_lmb(void) { } #endif static int bootm_start(void) @@ -261,7 +260,7 @@ static int bootm_start(void) memset((void *)&images, 0, sizeof(images)); images.verify = env_get_yesno("verify"); - boot_start_lmb(&images); + boot_start_lmb(); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start"); images.state = BOOTM_STATE_START; @@ -640,7 +639,7 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE) { ulong req_size = ALIGN(image_len * 4, SZ_1M); - load = lmb_alloc(&images->lmb, req_size, SZ_2M); + load = lmb_alloc(req_size, SZ_2M); if (!load) return 1; os.load = load; @@ -714,8 +713,7 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) images->os.end = relocated_addr + image_size; } - lmb_reserve(&images->lmb, images->os.load, (load_end - - images->os.load)); + lmb_reserve(images->os.load, (load_end - images->os.load)); return 0; } @@ -1041,8 +1039,9 @@ int bootm_run_states(struct bootm_info *bmi, int states) if (!ret && (states & BOOTM_STATE_RAMDISK)) { ulong rd_len = images->rd_end - images->rd_start; - ret = boot_ramdisk_high(&images->lmb, images->rd_start, - rd_len, &images->initrd_start, &images->initrd_end); + ret = boot_ramdisk_high(images->rd_start, rd_len, + &images->initrd_start, + &images->initrd_end); if (!ret) { env_set_hex("initrd_start", images->initrd_start); env_set_hex("initrd_end", images->initrd_end); @@ -1051,9 +1050,8 @@ int bootm_run_states(struct bootm_info *bmi, int states) #endif #if CONFIG_IS_ENABLED(OF_LIBFDT) && defined(CONFIG_LMB) if (!ret && (states & BOOTM_STATE_FDT)) { - boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); - ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, - &images->ft_len); + boot_fdt_add_mem_rsv_regions(images->ft_addr); + ret = boot_relocate_fdt(&images->ft_addr, &images->ft_len); } #endif diff --git a/boot/bootm_os.c b/boot/bootm_os.c index ccde72d22c..d0ffcdc2a2 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -260,12 +260,11 @@ static void do_bootvx_fdt(struct bootm_headers *images) char *bootline; ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; - struct lmb *lmb = &images->lmb; if (*of_flat_tree) { - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + boot_fdt_add_mem_rsv_regions(*of_flat_tree); - ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + ret = boot_relocate_fdt(of_flat_tree, &of_size); if (ret) return; diff --git a/boot/image-board.c b/boot/image-board.c index 09b6e4e0bd..89ccf80066 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -508,7 +508,6 @@ int boot_get_ramdisk(char const *select, struct bootm_headers *images, /** * boot_ramdisk_high - relocate init ramdisk - * @lmb: pointer to lmb handle, will be used for memory mgmt * @rd_data: ramdisk data start address * @rd_len: ramdisk data length * @initrd_start: pointer to a ulong variable, will hold final init ramdisk @@ -527,8 +526,8 @@ int boot_get_ramdisk(char const *select, struct bootm_headers *images, * 0 - success * -1 - failure */ -int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, - ulong *initrd_start, ulong *initrd_end) +int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start, + ulong *initrd_end) { char *s; phys_addr_t initrd_high; @@ -554,13 +553,14 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, debug(" in-place initrd\n"); *initrd_start = rd_data; *initrd_end = rd_data + rd_len; - lmb_reserve(lmb, rd_data, rd_len); + lmb_reserve(rd_data, rd_len); } else { if (initrd_high) - *initrd_start = (ulong)lmb_alloc_base(lmb, - rd_len, 0x1000, initrd_high); + *initrd_start = (ulong)lmb_alloc_base(rd_len, + 0x1000, + initrd_high); else - *initrd_start = (ulong)lmb_alloc(lmb, rd_len, + *initrd_start = (ulong)lmb_alloc(rd_len, 0x1000); if (*initrd_start == 0) { @@ -793,7 +793,6 @@ int boot_get_loadable(struct bootm_headers *images) /** * boot_get_cmdline - allocate and initialize kernel cmdline - * @lmb: pointer to lmb handle, will be used for memory mgmt * @cmd_start: pointer to a ulong variable, will hold cmdline start * @cmd_end: pointer to a ulong variable, will hold cmdline end * @@ -806,7 +805,7 @@ int boot_get_loadable(struct bootm_headers *images) * 0 - success * -1 - failure */ -int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) +int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end) { int barg; char *cmdline; @@ -820,7 +819,7 @@ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) return 0; barg = IF_ENABLED_INT(CONFIG_SYS_BOOT_GET_CMDLINE, CONFIG_SYS_BARGSIZE); - cmdline = (char *)(ulong)lmb_alloc_base(lmb, barg, 0xf, + cmdline = (char *)(ulong)lmb_alloc_base(barg, 0xf, env_get_bootm_mapsize() + env_get_bootm_low()); if (!cmdline) return -1; @@ -841,7 +840,6 @@ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) /** * boot_get_kbd - allocate and initialize kernel copy of board info - * @lmb: pointer to lmb handle, will be used for memory mgmt * @kbd: double pointer to board info data * * boot_get_kbd() allocates space for kernel copy of board info data below @@ -852,10 +850,9 @@ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) * 0 - success * -1 - failure */ -int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd) +int boot_get_kbd(struct bd_info **kbd) { - *kbd = (struct bd_info *)(ulong)lmb_alloc_base(lmb, - sizeof(struct bd_info), + *kbd = (struct bd_info *)(ulong)lmb_alloc_base(sizeof(struct bd_info), 0xf, env_get_bootm_mapsize() + env_get_bootm_low()); @@ -876,17 +873,16 @@ int image_setup_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; - struct lmb *lmb = images_lmb(images); int ret; /* This function cannot be called without lmb support */ if (!IS_ENABLED(CONFIG_LMB)) return -EFAULT; if (CONFIG_IS_ENABLED(OF_LIBFDT)) - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + boot_fdt_add_mem_rsv_regions(*of_flat_tree); if (IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) { - ret = boot_get_cmdline(lmb, &images->cmdline_start, + ret = boot_get_cmdline(&images->cmdline_start, &images->cmdline_end); if (ret) { puts("ERROR with allocation of cmdline\n"); @@ -895,7 +891,7 @@ int image_setup_linux(struct bootm_headers *images) } if (CONFIG_IS_ENABLED(OF_LIBFDT)) { - ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + ret = boot_relocate_fdt(of_flat_tree, &of_size); if (ret) return ret; } diff --git a/boot/image-fdt.c b/boot/image-fdt.c index f09716cba3..08afde203c 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -69,12 +69,12 @@ static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr) } #endif -static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr, - uint64_t size, enum lmb_flags flags) +static void boot_fdt_reserve_region(uint64_t addr, uint64_t size, + enum lmb_flags flags) { long ret; - ret = lmb_reserve_flags(lmb, addr, size, flags); + ret = lmb_reserve_flags(addr, size, flags); if (ret >= 0) { debug(" reserving fdt memory region: addr=%llx size=%llx flags=%x\n", (unsigned long long)addr, @@ -90,14 +90,13 @@ static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr, /** * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory * sections as unusable - * @lmb: pointer to lmb handle, will be used for memory mgmt * @fdt_blob: pointer to fdt blob base address * * Adds the and reserved-memorymemreserve regions in the dtb to the lmb block. * Adding the memreserve regions prevents u-boot from using them to store the * initrd or the fdt blob. */ -void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) +void boot_fdt_add_mem_rsv_regions(void *fdt_blob) { uint64_t addr, size; int i, total, ret; @@ -113,7 +112,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) for (i = 0; i < total; i++) { if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) continue; - boot_fdt_reserve_region(lmb, addr, size, LMB_NONE); + boot_fdt_reserve_region(addr, size, LMB_NONE); } /* process reserved-memory */ @@ -131,7 +130,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) flags = LMB_NOMAP; addr = res.start; size = res.end - res.start + 1; - boot_fdt_reserve_region(lmb, addr, size, flags); + boot_fdt_reserve_region(addr, size, flags); } subnode = fdt_next_subnode(fdt_blob, subnode); @@ -141,7 +140,6 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) /** * boot_relocate_fdt - relocate flat device tree - * @lmb: pointer to lmb handle, will be used for memory mgmt * @of_flat_tree: pointer to a char* variable, will hold fdt start address * @of_size: pointer to a ulong variable, will hold fdt length * @@ -156,7 +154,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) * 0 - success * 1 - failure */ -int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) +int boot_relocate_fdt(char **of_flat_tree, ulong *of_size) { u64 start, size, usable, addr, low, mapsize; void *fdt_blob = *of_flat_tree; @@ -188,18 +186,17 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) if (desired_addr == ~0UL) { /* All ones means use fdt in place */ of_start = fdt_blob; - lmb_reserve(lmb, map_to_sysmem(of_start), of_len); + lmb_reserve(map_to_sysmem(of_start), of_len); disable_relocation = 1; } else if (desired_addr) { - addr = lmb_alloc_base(lmb, of_len, 0x1000, - desired_addr); + addr = lmb_alloc_base(of_len, 0x1000, desired_addr); of_start = map_sysmem(addr, of_len); if (of_start == NULL) { puts("Failed using fdt_high value for Device Tree"); goto error; } } else { - addr = lmb_alloc(lmb, of_len, 0x1000); + addr = lmb_alloc(of_len, 0x1000); of_start = map_sysmem(addr, of_len); } } else { @@ -221,7 +218,7 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) * for LMB allocation. */ usable = min(start + size, low + mapsize); - addr = lmb_alloc_base(lmb, of_len, 0x1000, usable); + addr = lmb_alloc_base(of_len, 0x1000, usable); of_start = map_sysmem(addr, of_len); /* Allocation succeeded, use this block. */ if (of_start != NULL) @@ -672,7 +669,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, /* Delete the old LMB reservation */ if (lmb) - lmb_free(lmb, map_to_sysmem(blob), fdt_totalsize(blob)); + lmb_free(map_to_sysmem(blob), fdt_totalsize(blob)); ret = fdt_shrink_to_minimum(blob, 0); if (ret < 0) @@ -681,7 +678,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, /* Create a new LMB reservation */ if (lmb) - lmb_reserve(lmb, map_to_sysmem(blob), of_size); + lmb_reserve(map_to_sysmem(blob), of_size); #if defined(CONFIG_ARCH_KEYSTONE) if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 79106caeec..e08d3e2cf3 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -163,10 +163,8 @@ static int bdinfo_print_all(struct bd_info *bd) bdinfo_print_num_l("multi_dtb_fit", (ulong)gd->multi_dtb_fit); #endif if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { - struct lmb lmb; - - lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); - lmb_dump_all_force(&lmb); + lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_dump_all_force(); if (IS_ENABLED(CONFIG_OF_REAL)) printf("devicetree = %s\n", fdtdec_get_srcname()); } diff --git a/cmd/booti.c b/cmd/booti.c index b9637b3ec3..01f9f2c4a5 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -88,7 +88,7 @@ static int booti_start(struct bootm_info *bmi) images->os.start = relocated_addr; images->os.end = relocated_addr + image_size; - lmb_reserve(&images->lmb, images->ep, le32_to_cpu(image_size)); + lmb_reserve(images->ep, le32_to_cpu(image_size)); /* * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not diff --git a/cmd/bootz.c b/cmd/bootz.c index b6bb4aae72..5b5341dad6 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -57,7 +57,7 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, if (ret != 0) return 1; - lmb_reserve(&images->lmb, images->ep, zi_end - zi_start); + lmb_reserve(images->ep, zi_end - zi_start); /* * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not diff --git a/cmd/load.c b/cmd/load.c index 540361b43f..f019111991 100644 --- a/cmd/load.c +++ b/cmd/load.c @@ -142,7 +142,6 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, static ulong load_serial(long offset) { - struct lmb lmb; char record[SREC_MAXRECLEN + 1]; /* buffer for one S-Record */ char binbuf[SREC_MAXBINLEN]; /* buffer for binary data */ int binlen; /* no. of data bytes in S-Rec. */ @@ -155,7 +154,7 @@ static ulong load_serial(long offset) int line_count = 0; long ret; - lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); + lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); while (read_record(record, SREC_MAXRECLEN + 1) >= 0) { type = srec_decode(record, &binlen, &addr, binbuf); @@ -183,7 +182,7 @@ static ulong load_serial(long offset) { void *dst; - ret = lmb_reserve(&lmb, store_addr, binlen); + ret = lmb_reserve(store_addr, binlen); if (ret) { printf("\nCannot overwrite reserved area (%08lx..%08lx)\n", store_addr, store_addr + binlen); @@ -192,7 +191,7 @@ static ulong load_serial(long offset) dst = map_sysmem(store_addr, binlen); memcpy(dst, binbuf, binlen); unmap_sysmem(dst); - lmb_free(&lmb, store_addr, binlen); + lmb_free(store_addr, binlen); } if ((store_addr) < start_addr) start_addr = store_addr; diff --git a/drivers/iommu/apple_dart.c b/drivers/iommu/apple_dart.c index ef385d9c9f..5e3c16a8bc 100644 --- a/drivers/iommu/apple_dart.c +++ b/drivers/iommu/apple_dart.c @@ -71,7 +71,6 @@ struct apple_dart_priv { void *base; - struct lmb lmb; u64 *l1, *l2; int bypass, shift; @@ -125,7 +124,7 @@ static dma_addr_t apple_dart_map(struct udevice *dev, void *addr, size_t size) off = (phys_addr_t)addr - paddr; psize = ALIGN(size + off, DART_PAGE_SIZE); - dva = lmb_alloc(&priv->lmb, psize, DART_PAGE_SIZE); + dva = lmb_alloc(psize, DART_PAGE_SIZE); idx = dva / DART_PAGE_SIZE; for (i = 0; i < psize / DART_PAGE_SIZE; i++) { @@ -161,7 +160,7 @@ static void apple_dart_unmap(struct udevice *dev, dma_addr_t addr, size_t size) (unsigned long)&priv->l2[idx + i]); priv->flush_tlb(priv); - lmb_free(&priv->lmb, dva, psize); + lmb_free(dva, psize); } static struct iommu_ops apple_dart_ops = { @@ -214,7 +213,7 @@ static int apple_dart_probe(struct udevice *dev) priv->dvabase = DART_PAGE_SIZE; priv->dvaend = SZ_4G - DART_PAGE_SIZE; - lmb_add(&priv->lmb, priv->dvabase, priv->dvaend - priv->dvabase); + lmb_add(priv->dvabase, priv->dvaend - priv->dvabase); /* Disable translations. */ for (sid = 0; sid < priv->nsid; sid++) diff --git a/drivers/iommu/sandbox_iommu.c b/drivers/iommu/sandbox_iommu.c index 31ce91345c..c5bb88d299 100644 --- a/drivers/iommu/sandbox_iommu.c +++ b/drivers/iommu/sandbox_iommu.c @@ -12,14 +12,9 @@ #define IOMMU_PAGE_SIZE SZ_4K -struct sandbox_iommu_priv { - struct lmb lmb; -}; - static dma_addr_t sandbox_iommu_map(struct udevice *dev, void *addr, size_t size) { - struct sandbox_iommu_priv *priv = dev_get_priv(dev); phys_addr_t paddr, dva; phys_size_t psize, off; @@ -27,7 +22,7 @@ static dma_addr_t sandbox_iommu_map(struct udevice *dev, void *addr, off = virt_to_phys(addr) - paddr; psize = ALIGN(size + off, IOMMU_PAGE_SIZE); - dva = lmb_alloc(&priv->lmb, psize, IOMMU_PAGE_SIZE); + dva = lmb_alloc(psize, IOMMU_PAGE_SIZE); return dva + off; } @@ -35,7 +30,6 @@ static dma_addr_t sandbox_iommu_map(struct udevice *dev, void *addr, static void sandbox_iommu_unmap(struct udevice *dev, dma_addr_t addr, size_t size) { - struct sandbox_iommu_priv *priv = dev_get_priv(dev); phys_addr_t dva; phys_size_t psize; @@ -43,7 +37,7 @@ static void sandbox_iommu_unmap(struct udevice *dev, dma_addr_t addr, psize = size + (addr - dva); psize = ALIGN(psize, IOMMU_PAGE_SIZE); - lmb_free(&priv->lmb, dva, psize); + lmb_free(dva, psize); } static struct iommu_ops sandbox_iommu_ops = { @@ -53,9 +47,7 @@ static struct iommu_ops sandbox_iommu_ops = { static int sandbox_iommu_probe(struct udevice *dev) { - struct sandbox_iommu_priv *priv = dev_get_priv(dev); - - lmb_add(&priv->lmb, 0x89abc000, SZ_16K); + lmb_add(0x89abc000, SZ_16K); return 0; } @@ -69,7 +61,6 @@ U_BOOT_DRIVER(sandbox_iommu) = { .name = "sandbox_iommu", .id = UCLASS_IOMMU, .of_match = sandbox_iommu_ids, - .priv_auto = sizeof(struct sandbox_iommu_priv), .ops = &sandbox_iommu_ops, .probe = sandbox_iommu_probe, }; diff --git a/fs/fs.c b/fs/fs.c index acf465bdd8..3c54eaa366 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -531,7 +531,6 @@ int fs_size(const char *filename, loff_t *size) static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, loff_t len, struct fstype_info *info) { - struct lmb lmb; int ret; loff_t size; loff_t read_len; @@ -550,10 +549,10 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, if (len && len < read_len) read_len = len; - lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); - lmb_dump_all(&lmb); + lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_dump_all(); - if (lmb_alloc_addr(&lmb, addr, read_len) == addr) + if (lmb_alloc_addr(addr, read_len) == addr) return 0; log_err("** Reading file would overwrite reserved memory **\n"); diff --git a/include/image.h b/include/image.h index acffd17e0d..8c619030ee 100644 --- a/include/image.h +++ b/include/image.h @@ -411,18 +411,8 @@ struct bootm_headers { #define BOOTM_STATE_PRE_LOAD 0x00000800 #define BOOTM_STATE_MEASURE 0x00001000 int state; - -#if defined(CONFIG_LMB) && !defined(USE_HOSTCC) - struct lmb lmb; /* for memory mgmt */ -#endif }; -#ifdef CONFIG_LMB -#define images_lmb(_images) (&(_images)->lmb) -#else -#define images_lmb(_images) NULL -#endif - extern struct bootm_headers images; /* @@ -834,13 +824,13 @@ int boot_get_fdt(void *buf, const char *select, uint arch, struct bootm_headers *images, char **of_flat_tree, ulong *of_size); -void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob); -int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size); +void boot_fdt_add_mem_rsv_regions(void *fdt_blob); +int boot_relocate_fdt(char **of_flat_tree, ulong *of_size); -int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, - ulong *initrd_start, ulong *initrd_end); -int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end); -int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd); +int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start, + ulong *initrd_end); +int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end); +int boot_get_kbd(struct bd_info **kbd); /*******************************************************************/ /* Legacy format specific code (prefixed with image_) */ diff --git a/include/lmb.h b/include/lmb.h index bbe1c5299c..8f8a32c2ca 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -84,27 +84,25 @@ struct lmb { struct lmb_region reserved; }; -void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob); -void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, - phys_size_t size, void *fdt_blob); -long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size); -long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size); +void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob); +void lmb_init_and_reserve_range(phys_addr_t base, phys_size_t size, + void *fdt_blob); +long lmb_add(phys_addr_t base, phys_size_t size); +long lmb_reserve(phys_addr_t base, phys_size_t size); /** * lmb_reserve_flags - Reserve one region with a specific flags bitfield. * - * @lmb: the logical memory block struct * @base: base address of the memory region * @size: size of the memory region * @flags: flags for the memory region * Return: 0 if OK, > 0 for coalesced region or a negative error code. */ -long lmb_reserve_flags(struct lmb *lmb, phys_addr_t base, - phys_size_t size, enum lmb_flags flags); -phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align); -phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, - phys_addr_t max_addr); -phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size); -phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr); +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_base(phys_size_t size, ulong align, phys_addr_t max_addr); +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size); +phys_size_t lmb_get_free_size(phys_addr_t addr); /** * lmb_is_reserved_flags() - test if address is in reserved region with flag bits set @@ -112,21 +110,20 @@ phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr); * The function checks if a reserved region comprising @addr exists which has * all flag bits set which are set in @flags. * - * @lmb: the logical memory block struct * @addr: address to be tested * @flags: bitmap with bits to be tested * Return: 1 if matching reservation exists, 0 otherwise */ -int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags); +int lmb_is_reserved_flags(phys_addr_t addr, int flags); -long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size); +long lmb_free(phys_addr_t base, phys_size_t size); -void lmb_dump_all(struct lmb *lmb); -void lmb_dump_all_force(struct lmb *lmb); +void lmb_dump_all(void); +void lmb_dump_all_force(void); -void board_lmb_reserve(struct lmb *lmb); -void arch_lmb_reserve(struct lmb *lmb); -void arch_lmb_reserve_generic(struct lmb *lmb, ulong sp, ulong end, ulong align); +void board_lmb_reserve(void); +void arch_lmb_reserve(void); +void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align); #endif /* __KERNEL__ */ diff --git a/lib/lmb.c b/lib/lmb.c index 7f34d4a8b0..b0c9e2ef30 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -58,17 +58,17 @@ static void lmb_dump_region(struct lmb_region *rgn, char *name) } } -void lmb_dump_all_force(struct lmb *lmb) +void lmb_dump_all_force(void) { printf("lmb_dump_all:\n"); lmb_dump_region(&lmb.memory, "memory"); lmb_dump_region(&lmb.reserved, "reserved"); } -void lmb_dump_all(struct lmb *lmb) +void lmb_dump_all(void) { #ifdef DEBUG - lmb_dump_all_force(lmb); + lmb_dump_all_force(); #endif } @@ -149,7 +149,7 @@ static void lmb_fix_over_lap_regions(struct lmb_region *rgn, unsigned long r1, lmb_remove_region(rgn, r2); } -void arch_lmb_reserve_generic(struct lmb *lmb, ulong sp, ulong end, ulong align) +void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align) { ulong bank_end; int bank; @@ -175,10 +175,10 @@ void arch_lmb_reserve_generic(struct lmb *lmb, ulong sp, ulong end, ulong align) if (bank_end > end) bank_end = end - 1; - lmb_reserve(lmb, sp, bank_end - sp + 1); + lmb_reserve(sp, bank_end - sp + 1); if (gd->flags & GD_FLG_SKIP_RELOC) - lmb_reserve(lmb, (phys_addr_t)(uintptr_t)_start, gd->mon_len); + lmb_reserve((phys_addr_t)(uintptr_t)_start, gd->mon_len); break; } @@ -190,10 +190,9 @@ void arch_lmb_reserve_generic(struct lmb *lmb, ulong sp, ulong end, ulong align) * Add reservations for all EFI memory areas that are not * EFI_CONVENTIONAL_MEMORY. * - * @lmb: lmb environment * Return: 0 on success, 1 on failure */ -static __maybe_unused int efi_lmb_reserve(struct lmb *lmb) +static __maybe_unused int efi_lmb_reserve(void) { struct efi_mem_desc *memmap = NULL, *map; efi_uintn_t i, map_size = 0; @@ -205,8 +204,7 @@ static __maybe_unused int efi_lmb_reserve(struct lmb *lmb) for (i = 0, map = memmap; i < map_size / sizeof(*map); ++map, ++i) { if (map->type != EFI_CONVENTIONAL_MEMORY) { - lmb_reserve_flags(lmb, - map_to_sysmem((void *)(uintptr_t) + lmb_reserve_flags(map_to_sysmem((void *)(uintptr_t) map->physical_start), map->num_pages * EFI_PAGE_SIZE, map->type == EFI_RESERVED_MEMORY_TYPE @@ -218,39 +216,37 @@ static __maybe_unused int efi_lmb_reserve(struct lmb *lmb) return 0; } -static void lmb_reserve_common(struct lmb *lmb, void *fdt_blob) +static void lmb_reserve_common(void *fdt_blob) { - arch_lmb_reserve(lmb); - board_lmb_reserve(lmb); + arch_lmb_reserve(); + board_lmb_reserve(); if (CONFIG_IS_ENABLED(OF_LIBFDT) && fdt_blob) - boot_fdt_add_mem_rsv_regions(lmb, fdt_blob); + boot_fdt_add_mem_rsv_regions(fdt_blob); if (CONFIG_IS_ENABLED(EFI_LOADER)) - efi_lmb_reserve(lmb); + efi_lmb_reserve(); } /* Initialize the struct, add memory and call arch/board reserve functions */ -void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob) +void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob) { int i; for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { - if (bd->bi_dram[i].size) { - lmb_add(lmb, bd->bi_dram[i].start, - bd->bi_dram[i].size); - } + if (bd->bi_dram[i].size) + lmb_add(bd->bi_dram[i].start, bd->bi_dram[i].size); } - lmb_reserve_common(lmb, fdt_blob); + lmb_reserve_common(fdt_blob); } /* Initialize the struct, add memory and call arch/board reserve functions */ -void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, - phys_size_t size, void *fdt_blob) +void lmb_init_and_reserve_range(phys_addr_t base, phys_size_t size, + void *fdt_blob) { - lmb_add(lmb, base, size); - lmb_reserve_common(lmb, fdt_blob); + lmb_add(base, size); + lmb_reserve_common(fdt_blob); } /* This routine called with relocation disabled. */ @@ -351,14 +347,14 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, } /* This routine may be called with relocation disabled. */ -long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size) +long lmb_add(phys_addr_t base, phys_size_t size) { struct lmb_region *_rgn = &lmb.memory; return lmb_add_region(_rgn, base, size); } -long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) +long lmb_free(phys_addr_t base, phys_size_t size) { struct lmb_region *rgn = &lmb.reserved; phys_addr_t rgnbegin, rgnend; @@ -408,17 +404,16 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) rgn->region[i].flags); } -long lmb_reserve_flags(struct lmb *lmb, phys_addr_t base, phys_size_t size, - enum lmb_flags flags) +long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags) { struct lmb_region *_rgn = &lmb.reserved; return lmb_add_region_flags(_rgn, base, size, flags); } -long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size) +long lmb_reserve(phys_addr_t base, phys_size_t size) { - return lmb_reserve_flags(lmb, base, size, LMB_NONE); + return lmb_reserve_flags(base, size, LMB_NONE); } static long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base, @@ -441,8 +436,8 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) return addr & ~(size - 1); } -static phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, - ulong align, phys_addr_t max_addr) +static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, + phys_addr_t max_addr) { long i, rgn; phys_addr_t base = 0; @@ -483,16 +478,16 @@ static phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, return 0; } -phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align) +phys_addr_t lmb_alloc(phys_size_t size, ulong align) { - return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE); + return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE); } -phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) +phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) { phys_addr_t alloc; - alloc = __lmb_alloc_base(lmb, size, align, max_addr); + alloc = __lmb_alloc_base(size, align, max_addr); if (alloc == 0) printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", @@ -505,7 +500,7 @@ phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_ * Try to allocate a specific address range: must be in defined memory but not * reserved */ -phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size) +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) { long rgn; @@ -520,7 +515,7 @@ phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size) lmb.memory.region[rgn].size, base + size - 1, 1)) { /* ok, reserve the memory */ - if (lmb_reserve(lmb, base, size) >= 0) + if (lmb_reserve(base, size) >= 0) return base; } } @@ -528,7 +523,7 @@ phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size) } /* Return number of bytes from a given address that are free */ -phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr) +phys_size_t lmb_get_free_size(phys_addr_t addr) { int i; long rgn; @@ -554,7 +549,7 @@ phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr) return 0; } -int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags) +int lmb_is_reserved_flags(phys_addr_t addr, int flags) { int i; @@ -567,12 +562,12 @@ int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags) return 0; } -__weak void board_lmb_reserve(struct lmb *lmb) +__weak void board_lmb_reserve(void) { /* please define platform specific board_lmb_reserve() */ } -__weak void arch_lmb_reserve(struct lmb *lmb) +__weak void arch_lmb_reserve(void) { /* please define platform specific arch_lmb_reserve() */ } diff --git a/net/tftp.c b/net/tftp.c index 2e33541349..02a5ca0f9f 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -712,12 +712,11 @@ static void tftp_timeout_handler(void) static int tftp_init_load_addr(void) { #ifdef CONFIG_LMB - struct lmb lmb; phys_size_t max_size; - lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); + lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); - max_size = lmb_get_free_size(&lmb, image_load_addr); + max_size = lmb_get_free_size(image_load_addr); if (!max_size) return -1; diff --git a/net/wget.c b/net/wget.c index abab371e58..dbdc519946 100644 --- a/net/wget.c +++ b/net/wget.c @@ -74,12 +74,11 @@ static ulong wget_load_size; */ static int wget_init_load_size(void) { - struct lmb lmb; phys_size_t max_size; - lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); + lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); - max_size = lmb_get_free_size(&lmb, image_load_addr); + max_size = lmb_get_free_size(image_load_addr); if (!max_size) return -1; diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c index 4977d01f62..31d5e28105 100644 --- a/test/cmd/bdinfo.c +++ b/test/cmd/bdinfo.c @@ -201,7 +201,7 @@ static int bdinfo_test_all(struct unit_test_state *uts) if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { struct lmb lmb; - lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); + lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); ut_assertok(lmb_test_dump_all(uts, &lmb)); if (IS_ENABLED(CONFIG_OF_REAL)) ut_assert_nextline("devicetree = %s", fdtdec_get_srcname()); diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 42551b7c6d..ace1ddf4e4 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -13,6 +13,8 @@ #include <test/test.h> #include <test/ut.h> +extern struct lmb lmb; + static inline bool lmb_is_nomap(struct lmb_property *m) { return m->flags & LMB_NOMAP; @@ -65,7 +67,6 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, const phys_addr_t ram_end = ram + ram_size; const phys_addr_t alloc_64k_end = alloc_64k_addr + 0x10000; - struct lmb lmb; long ret; phys_addr_t a, a2, b, b2, c, d; @@ -77,11 +78,11 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, ut_assert(alloc_64k_end <= ram_end - 8); if (ram0_size) { - ret = lmb_add(&lmb, ram0, ram0_size); + ret = lmb_add(ram0, ram0_size); ut_asserteq(ret, 0); } - ret = lmb_add(&lmb, ram, ram_size); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); if (ram0_size) { @@ -97,67 +98,67 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, } /* reserve 64KiB somewhere */ - ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000); + ret = lmb_reserve(alloc_64k_addr, 0x10000); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, 0, 0, 1, alloc_64k_addr, 0x10000, 0, 0, 0, 0); /* allocate somewhere, should be at the end of RAM */ - a = lmb_alloc(&lmb, 4, 1); + a = lmb_alloc(4, 1); ut_asserteq(a, ram_end - 4); ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr, 0x10000, ram_end - 4, 4, 0, 0); /* alloc below end of reserved region -> below reserved region */ - b = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end); + b = lmb_alloc_base(4, 1, alloc_64k_end); ut_asserteq(b, alloc_64k_addr - 4); ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr - 4, 0x10000 + 4, ram_end - 4, 4, 0, 0); /* 2nd time */ - c = lmb_alloc(&lmb, 4, 1); + c = lmb_alloc(4, 1); ut_asserteq(c, ram_end - 8); ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr - 4, 0x10000 + 4, ram_end - 8, 8, 0, 0); - d = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end); + d = lmb_alloc_base(4, 1, alloc_64k_end); ut_asserteq(d, alloc_64k_addr - 8); ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0); - ret = lmb_free(&lmb, a, 4); + ret = lmb_free(a, 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); /* allocate again to ensure we get the same address */ - a2 = lmb_alloc(&lmb, 4, 1); + a2 = lmb_alloc(4, 1); ut_asserteq(a, a2); ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0); - ret = lmb_free(&lmb, a2, 4); + ret = lmb_free(a2, 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); - ret = lmb_free(&lmb, b, 4); + ret = lmb_free(b, 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, 0, 0, 3, alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, ram_end - 8, 4); /* allocate again to ensure we get the same address */ - b2 = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end); + b2 = lmb_alloc_base(4, 1, alloc_64k_end); ut_asserteq(b, b2); ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); - ret = lmb_free(&lmb, b2, 4); + ret = lmb_free(b2, 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, 0, 0, 3, alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, ram_end - 8, 4); - ret = lmb_free(&lmb, c, 4); + ret = lmb_free(c, 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0); - ret = lmb_free(&lmb, d, 4); + ret = lmb_free(d, 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, 0, 0, 1, alloc_64k_addr, 0x10000, 0, 0, 0, 0); @@ -228,42 +229,41 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) const phys_size_t big_block_size = 0x10000000; const phys_addr_t ram_end = ram + ram_size; const phys_addr_t alloc_64k_addr = ram + 0x10000000; - struct lmb lmb; long ret; phys_addr_t a, b; /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); - ret = lmb_add(&lmb, ram, ram_size); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); /* reserve 64KiB in the middle of RAM */ - ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000); + ret = lmb_reserve(alloc_64k_addr, 0x10000); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, 0, 0, 0, 0); /* allocate a big block, should be below reserved */ - a = lmb_alloc(&lmb, big_block_size, 1); + a = lmb_alloc(big_block_size, 1); ut_asserteq(a, ram); ASSERT_LMB(&lmb, ram, ram_size, 1, a, big_block_size + 0x10000, 0, 0, 0, 0); /* allocate 2nd big block */ /* This should fail, printing an error */ - b = lmb_alloc(&lmb, big_block_size, 1); + b = lmb_alloc(big_block_size, 1); ut_asserteq(b, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, a, big_block_size + 0x10000, 0, 0, 0, 0); - ret = lmb_free(&lmb, a, big_block_size); + ret = lmb_free(a, big_block_size); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, 0, 0, 0, 0); /* allocate too big block */ /* This should fail, printing an error */ - a = lmb_alloc(&lmb, ram_size, 1); + a = lmb_alloc(ram_size, 1); ut_asserteq(a, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000, 0, 0, 0, 0); @@ -291,7 +291,6 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, { const phys_size_t ram_size = 0x20000000; const phys_addr_t ram_end = ram + ram_size; - struct lmb lmb; long ret; phys_addr_t a, b; const phys_addr_t alloc_size_aligned = (alloc_size + align - 1) & @@ -300,17 +299,17 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); - ret = lmb_add(&lmb, ram, ram_size); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); /* allocate a block */ - a = lmb_alloc(&lmb, alloc_size, align); + a = lmb_alloc(alloc_size, align); ut_assert(a != 0); ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, alloc_size, 0, 0, 0, 0); /* allocate another block */ - b = lmb_alloc(&lmb, alloc_size, align); + b = lmb_alloc(alloc_size, align); ut_assert(b != 0); if (alloc_size == alloc_size_aligned) { ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - @@ -322,21 +321,21 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, - alloc_size_aligned, alloc_size, 0, 0); } /* and free them */ - ret = lmb_free(&lmb, b, alloc_size); + ret = lmb_free(b, alloc_size); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, alloc_size, 0, 0, 0, 0); - ret = lmb_free(&lmb, a, alloc_size); + ret = lmb_free(a, alloc_size); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); /* allocate a block with base*/ - b = lmb_alloc_base(&lmb, alloc_size, align, ram_end); + b = lmb_alloc_base(alloc_size, align, ram_end); ut_assert(a == b); ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, alloc_size, 0, 0, 0, 0); /* and free it */ - ret = lmb_free(&lmb, b, alloc_size); + ret = lmb_free(b, alloc_size); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); @@ -380,32 +379,31 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) { const phys_addr_t ram = 0; const phys_size_t ram_size = 0x20000000; - struct lmb lmb; long ret; phys_addr_t a, b; - ret = lmb_add(&lmb, ram, ram_size); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); /* allocate nearly everything */ - a = lmb_alloc(&lmb, ram_size - 4, 1); + a = lmb_alloc(ram_size - 4, 1); ut_asserteq(a, ram + 4); ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4, 0, 0, 0, 0); /* allocate the rest */ /* This should fail as the allocated address would be 0 */ - b = lmb_alloc(&lmb, 4, 1); + b = lmb_alloc(4, 1); ut_asserteq(b, 0); /* check that this was an error by checking lmb */ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4, 0, 0, 0, 0); /* check that this was an error by freeing b */ - ret = lmb_free(&lmb, b, 4); + ret = lmb_free(b, 4); ut_asserteq(ret, -1); ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4, 0, 0, 0, 0); - ret = lmb_free(&lmb, a, ram_size - 4); + ret = lmb_free(a, ram_size - 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); @@ -418,40 +416,39 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) { const phys_addr_t ram = 0x40000000; const phys_size_t ram_size = 0x20000000; - struct lmb lmb; long ret; - ret = lmb_add(&lmb, ram, ram_size); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); - ret = lmb_reserve(&lmb, 0x40010000, 0x10000); + ret = lmb_reserve(0x40010000, 0x10000); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); /* allocate overlapping region should fail */ - ret = lmb_reserve(&lmb, 0x40011000, 0x10000); + ret = lmb_reserve(0x40011000, 0x10000); ut_asserteq(ret, -1); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); /* allocate 3nd region */ - ret = lmb_reserve(&lmb, 0x40030000, 0x10000); + ret = lmb_reserve(0x40030000, 0x10000); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x10000, 0x40030000, 0x10000, 0, 0); /* allocate 2nd region , This should coalesced all region into one */ - ret = lmb_reserve(&lmb, 0x40020000, 0x10000); + ret = lmb_reserve(0x40020000, 0x10000); ut_assert(ret >= 0); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x30000, 0, 0, 0, 0); /* allocate 2nd region, which should be added as first region */ - ret = lmb_reserve(&lmb, 0x40000000, 0x8000); + ret = lmb_reserve(0x40000000, 0x8000); ut_assert(ret >= 0); ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40000000, 0x8000, 0x40010000, 0x30000, 0, 0); /* allocate 3rd region, coalesce with first and overlap with second */ - ret = lmb_reserve(&lmb, 0x40008000, 0x10000); + ret = lmb_reserve(0x40008000, 0x10000); ut_assert(ret >= 0); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40000000, 0x40000, 0, 0, 0, 0); @@ -470,102 +467,101 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) const phys_size_t alloc_addr_a = ram + 0x8000000; const phys_size_t alloc_addr_b = ram + 0x8000000 * 2; const phys_size_t alloc_addr_c = ram + 0x8000000 * 3; - struct lmb lmb; long ret; phys_addr_t a, b, c, d, e; /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); - ret = lmb_add(&lmb, ram, ram_size); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); /* reserve 3 blocks */ - ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000); + ret = lmb_reserve(alloc_addr_a, 0x10000); ut_asserteq(ret, 0); - ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000); + ret = lmb_reserve(alloc_addr_b, 0x10000); ut_asserteq(ret, 0); - ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000); + ret = lmb_reserve(alloc_addr_c, 0x10000); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000, alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); /* allocate blocks */ - a = lmb_alloc_addr(&lmb, ram, alloc_addr_a - ram); + a = lmb_alloc_addr(ram, alloc_addr_a - ram); ut_asserteq(a, ram); ASSERT_LMB(&lmb, ram, ram_size, 3, ram, 0x8010000, alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); - b = lmb_alloc_addr(&lmb, alloc_addr_a + 0x10000, + b = lmb_alloc_addr(alloc_addr_a + 0x10000, alloc_addr_b - alloc_addr_a - 0x10000); ut_asserteq(b, alloc_addr_a + 0x10000); ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x10010000, alloc_addr_c, 0x10000, 0, 0); - c = lmb_alloc_addr(&lmb, alloc_addr_b + 0x10000, + c = lmb_alloc_addr(alloc_addr_b + 0x10000, alloc_addr_c - alloc_addr_b - 0x10000); ut_asserteq(c, alloc_addr_b + 0x10000); ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); - d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, + d = lmb_alloc_addr(alloc_addr_c + 0x10000, ram_end - alloc_addr_c - 0x10000); ut_asserteq(d, alloc_addr_c + 0x10000); ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size, 0, 0, 0, 0); /* allocating anything else should fail */ - e = lmb_alloc(&lmb, 1, 1); + e = lmb_alloc(1, 1); ut_asserteq(e, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size, 0, 0, 0, 0); - ret = lmb_free(&lmb, d, ram_end - alloc_addr_c - 0x10000); + ret = lmb_free(d, ram_end - alloc_addr_c - 0x10000); ut_asserteq(ret, 0); /* allocate at 3 points in free range */ - d = lmb_alloc_addr(&lmb, ram_end - 4, 4); + d = lmb_alloc_addr(ram_end - 4, 4); ut_asserteq(d, ram_end - 4); ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000, d, 4, 0, 0); - ret = lmb_free(&lmb, d, 4); + ret = lmb_free(d, 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); - d = lmb_alloc_addr(&lmb, ram_end - 128, 4); + d = lmb_alloc_addr(ram_end - 128, 4); ut_asserteq(d, ram_end - 128); ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000, d, 4, 0, 0); - ret = lmb_free(&lmb, d, 4); + ret = lmb_free(d, 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); - d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, 4); + d = lmb_alloc_addr(alloc_addr_c + 0x10000, 4); ut_asserteq(d, alloc_addr_c + 0x10000); ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010004, 0, 0, 0, 0); - ret = lmb_free(&lmb, d, 4); + ret = lmb_free(d, 4); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); /* allocate at the bottom */ - ret = lmb_free(&lmb, a, alloc_addr_a - ram); + ret = lmb_free(a, alloc_addr_a - ram); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, ram + 0x8000000, 0x10010000, 0, 0, 0, 0); - d = lmb_alloc_addr(&lmb, ram, 4); + d = lmb_alloc_addr(ram, 4); ut_asserteq(d, ram); ASSERT_LMB(&lmb, ram, ram_size, 2, d, 4, ram + 0x8000000, 0x10010000, 0, 0); /* check that allocating outside memory fails */ if (ram_end != 0) { - ret = lmb_alloc_addr(&lmb, ram_end, 1); + ret = lmb_alloc_addr(ram_end, 1); ut_asserteq(ret, 0); } if (ram != 0) { - ret = lmb_alloc_addr(&lmb, ram - 1, 1); + ret = lmb_alloc_addr(ram - 1, 1); ut_asserteq(ret, 0); } @@ -595,46 +591,45 @@ static int test_get_unreserved_size(struct unit_test_state *uts, const phys_size_t alloc_addr_a = ram + 0x8000000; const phys_size_t alloc_addr_b = ram + 0x8000000 * 2; const phys_size_t alloc_addr_c = ram + 0x8000000 * 3; - struct lmb lmb; long ret; phys_size_t s; /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); - ret = lmb_add(&lmb, ram, ram_size); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); /* reserve 3 blocks */ - ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000); + ret = lmb_reserve(alloc_addr_a, 0x10000); ut_asserteq(ret, 0); - ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000); + ret = lmb_reserve(alloc_addr_b, 0x10000); ut_asserteq(ret, 0); - ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000); + ret = lmb_reserve(alloc_addr_c, 0x10000); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000, alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); /* check addresses in between blocks */ - s = lmb_get_free_size(&lmb, ram); + s = lmb_get_free_size(ram); ut_asserteq(s, alloc_addr_a - ram); - s = lmb_get_free_size(&lmb, ram + 0x10000); + s = lmb_get_free_size(ram + 0x10000); ut_asserteq(s, alloc_addr_a - ram - 0x10000); - s = lmb_get_free_size(&lmb, alloc_addr_a - 4); + s = lmb_get_free_size(alloc_addr_a - 4); ut_asserteq(s, 4); - s = lmb_get_free_size(&lmb, alloc_addr_a + 0x10000); + s = lmb_get_free_size(alloc_addr_a + 0x10000); ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x10000); - s = lmb_get_free_size(&lmb, alloc_addr_a + 0x20000); + s = lmb_get_free_size(alloc_addr_a + 0x20000); ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x20000); - s = lmb_get_free_size(&lmb, alloc_addr_b - 4); + s = lmb_get_free_size(alloc_addr_b - 4); ut_asserteq(s, 4); - s = lmb_get_free_size(&lmb, alloc_addr_c + 0x10000); + s = lmb_get_free_size(alloc_addr_c + 0x10000); ut_asserteq(s, ram_end - alloc_addr_c - 0x10000); - s = lmb_get_free_size(&lmb, alloc_addr_c + 0x20000); + s = lmb_get_free_size(alloc_addr_c + 0x20000); ut_asserteq(s, ram_end - alloc_addr_c - 0x20000); - s = lmb_get_free_size(&lmb, ram_end - 4); + s = lmb_get_free_size(ram_end - 4); ut_asserteq(s, 4); return 0; @@ -667,7 +662,6 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) + 1) * CONFIG_LMB_MAX_REGIONS; const phys_size_t blk_size = 0x10000; phys_addr_t offset; - struct lmb lmb; int ret, i; ut_asserteq(lmb.memory.cnt, 0); @@ -678,7 +672,7 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) /* Add CONFIG_LMB_MAX_REGIONS memory regions */ for (i = 0; i < CONFIG_LMB_MAX_REGIONS; i++) { offset = ram + 2 * i * ram_size; - ret = lmb_add(&lmb, offset, ram_size); + ret = lmb_add(offset, ram_size); ut_asserteq(ret, 0); } ut_asserteq(lmb.memory.cnt, CONFIG_LMB_MAX_REGIONS); @@ -686,7 +680,7 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) /* error for the (CONFIG_LMB_MAX_REGIONS + 1) memory regions */ offset = ram + 2 * (CONFIG_LMB_MAX_REGIONS + 1) * ram_size; - ret = lmb_add(&lmb, offset, ram_size); + ret = lmb_add(offset, ram_size); ut_asserteq(ret, -1); ut_asserteq(lmb.memory.cnt, CONFIG_LMB_MAX_REGIONS); @@ -695,7 +689,7 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) /* reserve CONFIG_LMB_MAX_REGIONS regions */ for (i = 0; i < CONFIG_LMB_MAX_REGIONS; i++) { offset = ram + 2 * i * blk_size; - ret = lmb_reserve(&lmb, offset, blk_size); + ret = lmb_reserve(offset, blk_size); ut_asserteq(ret, 0); } @@ -704,7 +698,7 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) /* error for the 9th reserved blocks */ offset = ram + 2 * (CONFIG_LMB_MAX_REGIONS + 1) * blk_size; - ret = lmb_reserve(&lmb, offset, blk_size); + ret = lmb_reserve(offset, blk_size); ut_asserteq(ret, -1); ut_asserteq(lmb.memory.cnt, CONFIG_LMB_MAX_REGIONS); @@ -726,26 +720,25 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) { const phys_addr_t ram = 0x40000000; const phys_size_t ram_size = 0x20000000; - struct lmb lmb; long ret; - ret = lmb_add(&lmb, ram, ram_size); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); /* reserve, same flag */ - ret = lmb_reserve_flags(&lmb, 0x40010000, 0x10000, LMB_NOMAP); + ret = lmb_reserve_flags(0x40010000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); /* reserve again, same flag */ - ret = lmb_reserve_flags(&lmb, 0x40010000, 0x10000, LMB_NOMAP); + ret = lmb_reserve_flags(0x40010000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); /* reserve again, new flag */ - ret = lmb_reserve_flags(&lmb, 0x40010000, 0x10000, LMB_NONE); + ret = lmb_reserve_flags(0x40010000, 0x10000, LMB_NONE); ut_asserteq(ret, -1); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); @@ -753,20 +746,20 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1); /* merge after */ - ret = lmb_reserve_flags(&lmb, 0x40020000, 0x10000, LMB_NOMAP); + ret = lmb_reserve_flags(0x40020000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 1); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x20000, 0, 0, 0, 0); /* merge before */ - ret = lmb_reserve_flags(&lmb, 0x40000000, 0x10000, LMB_NOMAP); + ret = lmb_reserve_flags(0x40000000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 1); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40000000, 0x30000, 0, 0, 0, 0); ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1); - ret = lmb_reserve_flags(&lmb, 0x40030000, 0x10000, LMB_NONE); + ret = lmb_reserve_flags(0x40030000, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40000000, 0x30000, 0x40030000, 0x10000, 0, 0); @@ -775,7 +768,7 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) ut_asserteq(lmb_is_nomap(&lmb.reserved.region[1]), 0); /* test that old API use LMB_NONE */ - ret = lmb_reserve(&lmb, 0x40040000, 0x10000); + ret = lmb_reserve(0x40040000, 0x10000); ut_asserteq(ret, 1); ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40000000, 0x30000, 0x40030000, 0x20000, 0, 0); @@ -783,18 +776,18 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1); ut_asserteq(lmb_is_nomap(&lmb.reserved.region[1]), 0); - ret = lmb_reserve_flags(&lmb, 0x40070000, 0x10000, LMB_NOMAP); + ret = lmb_reserve_flags(0x40070000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 3, 0x40000000, 0x30000, 0x40030000, 0x20000, 0x40070000, 0x10000); - ret = lmb_reserve_flags(&lmb, 0x40050000, 0x10000, LMB_NOMAP); + ret = lmb_reserve_flags(0x40050000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 4, 0x40000000, 0x30000, 0x40030000, 0x20000, 0x40050000, 0x10000); /* merge with 2 adjacent regions */ - ret = lmb_reserve_flags(&lmb, 0x40060000, 0x10000, LMB_NOMAP); + ret = lmb_reserve_flags(0x40060000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 2); ASSERT_LMB(&lmb, ram, ram_size, 3, 0x40000000, 0x30000, 0x40030000, 0x20000, 0x40050000, 0x30000); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-07 18:52 ` [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable Sughosh Ganu @ 2024-06-11 18:52 ` Simon Glass 2024-06-11 21:01 ` Tom Rini 0 siblings, 1 reply; 127+ messages in thread From: Simon Glass @ 2024-06-11 18:52 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Sughosh, On Fri, 7 Jun 2024 at 12:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > With the move of the LMB structure to a persistent state, there is no > need to declare the variable locally, and pass it as part of the LMB > API's. Remove all local variable instances and change the API's > correspondingly. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > arch/arc/lib/cache.c | 4 +- > arch/arm/lib/stack.c | 4 +- > arch/arm/mach-apple/board.c | 17 ++- > arch/arm/mach-snapdragon/board.c | 17 ++- > arch/arm/mach-stm32mp/dram_init.c | 7 +- > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +- > arch/m68k/lib/bootm.c | 7 +- > arch/microblaze/lib/bootm.c | 4 +- > arch/mips/lib/bootm.c | 9 +- > arch/nios2/lib/bootm.c | 4 +- > arch/powerpc/cpu/mpc85xx/mp.c | 4 +- > arch/powerpc/include/asm/mp.h | 4 +- > arch/powerpc/lib/bootm.c | 14 +- > arch/riscv/lib/bootm.c | 4 +- > arch/sh/lib/bootm.c | 4 +- > arch/x86/lib/bootm.c | 4 +- > arch/xtensa/lib/bootm.c | 4 +- > board/xilinx/common/board.c | 7 +- > boot/bootm.c | 26 ++-- > boot/bootm_os.c | 5 +- > boot/image-board.c | 32 ++--- > boot/image-fdt.c | 29 ++--- > cmd/bdinfo.c | 6 +- > cmd/booti.c | 2 +- > cmd/bootz.c | 2 +- > cmd/load.c | 7 +- > drivers/iommu/apple_dart.c | 7 +- > drivers/iommu/sandbox_iommu.c | 15 +-- > fs/fs.c | 7 +- > include/image.h | 22 +--- > include/lmb.h | 39 +++--- > lib/lmb.c | 81 ++++++------ > net/tftp.c | 5 +- > net/wget.c | 5 +- > test/cmd/bdinfo.c | 2 +- > test/lib/lmb.c | 187 +++++++++++++-------------- > 36 files changed, 270 insertions(+), 333 deletions(-) This isn't necessary...and it will make things harder. You can have a global 'lmb' while still allowing passing a different pointer when needed. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-11 18:52 ` Simon Glass @ 2024-06-11 21:01 ` Tom Rini 2024-06-11 22:08 ` Simon Glass 0 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-11 21:01 UTC (permalink / raw) To: Simon Glass Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 2726 bytes --] On Tue, Jun 11, 2024 at 12:52:22PM -0600, Simon Glass wrote: > Hi Sughosh, > > On Fri, 7 Jun 2024 at 12:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > With the move of the LMB structure to a persistent state, there is no > > need to declare the variable locally, and pass it as part of the LMB > > API's. Remove all local variable instances and change the API's > > correspondingly. > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > --- > > arch/arc/lib/cache.c | 4 +- > > arch/arm/lib/stack.c | 4 +- > > arch/arm/mach-apple/board.c | 17 ++- > > arch/arm/mach-snapdragon/board.c | 17 ++- > > arch/arm/mach-stm32mp/dram_init.c | 7 +- > > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +- > > arch/m68k/lib/bootm.c | 7 +- > > arch/microblaze/lib/bootm.c | 4 +- > > arch/mips/lib/bootm.c | 9 +- > > arch/nios2/lib/bootm.c | 4 +- > > arch/powerpc/cpu/mpc85xx/mp.c | 4 +- > > arch/powerpc/include/asm/mp.h | 4 +- > > arch/powerpc/lib/bootm.c | 14 +- > > arch/riscv/lib/bootm.c | 4 +- > > arch/sh/lib/bootm.c | 4 +- > > arch/x86/lib/bootm.c | 4 +- > > arch/xtensa/lib/bootm.c | 4 +- > > board/xilinx/common/board.c | 7 +- > > boot/bootm.c | 26 ++-- > > boot/bootm_os.c | 5 +- > > boot/image-board.c | 32 ++--- > > boot/image-fdt.c | 29 ++--- > > cmd/bdinfo.c | 6 +- > > cmd/booti.c | 2 +- > > cmd/bootz.c | 2 +- > > cmd/load.c | 7 +- > > drivers/iommu/apple_dart.c | 7 +- > > drivers/iommu/sandbox_iommu.c | 15 +-- > > fs/fs.c | 7 +- > > include/image.h | 22 +--- > > include/lmb.h | 39 +++--- > > lib/lmb.c | 81 ++++++------ > > net/tftp.c | 5 +- > > net/wget.c | 5 +- > > test/cmd/bdinfo.c | 2 +- > > test/lib/lmb.c | 187 +++++++++++++-------------- > > 36 files changed, 270 insertions(+), 333 deletions(-) > > This isn't necessary...and it will make things harder. You can have a > global 'lmb' while still allowing passing a different pointer when > needed. There's only one reservation checking system and list of known reservations, keep in mind. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-11 21:01 ` Tom Rini @ 2024-06-11 22:08 ` Simon Glass 2024-06-11 22:55 ` Tom Rini 0 siblings, 1 reply; 127+ messages in thread From: Simon Glass @ 2024-06-11 22:08 UTC (permalink / raw) To: Tom Rini Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Tom, On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: > > On Tue, Jun 11, 2024 at 12:52:22PM -0600, Simon Glass wrote: > > Hi Sughosh, > > > > On Fri, 7 Jun 2024 at 12:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > With the move of the LMB structure to a persistent state, there is no > > > need to declare the variable locally, and pass it as part of the LMB > > > API's. Remove all local variable instances and change the API's > > > correspondingly. > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > --- > > > arch/arc/lib/cache.c | 4 +- > > > arch/arm/lib/stack.c | 4 +- > > > arch/arm/mach-apple/board.c | 17 ++- > > > arch/arm/mach-snapdragon/board.c | 17 ++- > > > arch/arm/mach-stm32mp/dram_init.c | 7 +- > > > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +- > > > arch/m68k/lib/bootm.c | 7 +- > > > arch/microblaze/lib/bootm.c | 4 +- > > > arch/mips/lib/bootm.c | 9 +- > > > arch/nios2/lib/bootm.c | 4 +- > > > arch/powerpc/cpu/mpc85xx/mp.c | 4 +- > > > arch/powerpc/include/asm/mp.h | 4 +- > > > arch/powerpc/lib/bootm.c | 14 +- > > > arch/riscv/lib/bootm.c | 4 +- > > > arch/sh/lib/bootm.c | 4 +- > > > arch/x86/lib/bootm.c | 4 +- > > > arch/xtensa/lib/bootm.c | 4 +- > > > board/xilinx/common/board.c | 7 +- > > > boot/bootm.c | 26 ++-- > > > boot/bootm_os.c | 5 +- > > > boot/image-board.c | 32 ++--- > > > boot/image-fdt.c | 29 ++--- > > > cmd/bdinfo.c | 6 +- > > > cmd/booti.c | 2 +- > > > cmd/bootz.c | 2 +- > > > cmd/load.c | 7 +- > > > drivers/iommu/apple_dart.c | 7 +- > > > drivers/iommu/sandbox_iommu.c | 15 +-- > > > fs/fs.c | 7 +- > > > include/image.h | 22 +--- > > > include/lmb.h | 39 +++--- > > > lib/lmb.c | 81 ++++++------ > > > net/tftp.c | 5 +- > > > net/wget.c | 5 +- > > > test/cmd/bdinfo.c | 2 +- > > > test/lib/lmb.c | 187 +++++++++++++-------------- > > > 36 files changed, 270 insertions(+), 333 deletions(-) > > > > This isn't necessary...and it will make things harder. You can have a > > global 'lmb' while still allowing passing a different pointer when > > needed. > > There's only one reservation checking system and list of known > reservations, keep in mind. There is only one driver model, too, but we use a pointer. It makes tests much easier. In fact I see elsewhere in this series that it causes problems with tests. Best to use a pointer so it is easy to update. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-11 22:08 ` Simon Glass @ 2024-06-11 22:55 ` Tom Rini 2024-06-12 2:41 ` Simon Glass 0 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-11 22:55 UTC (permalink / raw) To: Simon Glass Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 3477 bytes --] On Tue, Jun 11, 2024 at 04:08:56PM -0600, Simon Glass wrote: > Hi Tom, > > On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: > > > > On Tue, Jun 11, 2024 at 12:52:22PM -0600, Simon Glass wrote: > > > Hi Sughosh, > > > > > > On Fri, 7 Jun 2024 at 12:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > > > With the move of the LMB structure to a persistent state, there is no > > > > need to declare the variable locally, and pass it as part of the LMB > > > > API's. Remove all local variable instances and change the API's > > > > correspondingly. > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > --- > > > > arch/arc/lib/cache.c | 4 +- > > > > arch/arm/lib/stack.c | 4 +- > > > > arch/arm/mach-apple/board.c | 17 ++- > > > > arch/arm/mach-snapdragon/board.c | 17 ++- > > > > arch/arm/mach-stm32mp/dram_init.c | 7 +- > > > > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +- > > > > arch/m68k/lib/bootm.c | 7 +- > > > > arch/microblaze/lib/bootm.c | 4 +- > > > > arch/mips/lib/bootm.c | 9 +- > > > > arch/nios2/lib/bootm.c | 4 +- > > > > arch/powerpc/cpu/mpc85xx/mp.c | 4 +- > > > > arch/powerpc/include/asm/mp.h | 4 +- > > > > arch/powerpc/lib/bootm.c | 14 +- > > > > arch/riscv/lib/bootm.c | 4 +- > > > > arch/sh/lib/bootm.c | 4 +- > > > > arch/x86/lib/bootm.c | 4 +- > > > > arch/xtensa/lib/bootm.c | 4 +- > > > > board/xilinx/common/board.c | 7 +- > > > > boot/bootm.c | 26 ++-- > > > > boot/bootm_os.c | 5 +- > > > > boot/image-board.c | 32 ++--- > > > > boot/image-fdt.c | 29 ++--- > > > > cmd/bdinfo.c | 6 +- > > > > cmd/booti.c | 2 +- > > > > cmd/bootz.c | 2 +- > > > > cmd/load.c | 7 +- > > > > drivers/iommu/apple_dart.c | 7 +- > > > > drivers/iommu/sandbox_iommu.c | 15 +-- > > > > fs/fs.c | 7 +- > > > > include/image.h | 22 +--- > > > > include/lmb.h | 39 +++--- > > > > lib/lmb.c | 81 ++++++------ > > > > net/tftp.c | 5 +- > > > > net/wget.c | 5 +- > > > > test/cmd/bdinfo.c | 2 +- > > > > test/lib/lmb.c | 187 +++++++++++++-------------- > > > > 36 files changed, 270 insertions(+), 333 deletions(-) > > > > > > This isn't necessary...and it will make things harder. You can have a > > > global 'lmb' while still allowing passing a different pointer when > > > needed. > > > > There's only one reservation checking system and list of known > > reservations, keep in mind. > > There is only one driver model, too, but we use a pointer. It makes > tests much easier. > > In fact I see elsewhere in this series that it causes problems with > tests. Best to use a pointer so it is easy to update. Maybe? I worry that will lead to thinking that we still, like today, have many LMB lists, rather than a single LMB list that everyone must use. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-11 22:55 ` Tom Rini @ 2024-06-12 2:41 ` Simon Glass 2024-06-12 5:41 ` Ilias Apalodimas ` (2 more replies) 0 siblings, 3 replies; 127+ messages in thread From: Simon Glass @ 2024-06-12 2:41 UTC (permalink / raw) To: Tom Rini Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Tom, On Tue, 11 Jun 2024 at 16:55, Tom Rini <trini@konsulko.com> wrote: > > On Tue, Jun 11, 2024 at 04:08:56PM -0600, Simon Glass wrote: > > Hi Tom, > > > > On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: > > > > > > On Tue, Jun 11, 2024 at 12:52:22PM -0600, Simon Glass wrote: > > > > Hi Sughosh, > > > > > > > > On Fri, 7 Jun 2024 at 12:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > > > > > With the move of the LMB structure to a persistent state, there is no > > > > > need to declare the variable locally, and pass it as part of the LMB > > > > > API's. Remove all local variable instances and change the API's > > > > > correspondingly. > > > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > > --- > > > > > arch/arc/lib/cache.c | 4 +- > > > > > arch/arm/lib/stack.c | 4 +- > > > > > arch/arm/mach-apple/board.c | 17 ++- > > > > > arch/arm/mach-snapdragon/board.c | 17 ++- > > > > > arch/arm/mach-stm32mp/dram_init.c | 7 +- > > > > > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +- > > > > > arch/m68k/lib/bootm.c | 7 +- > > > > > arch/microblaze/lib/bootm.c | 4 +- > > > > > arch/mips/lib/bootm.c | 9 +- > > > > > arch/nios2/lib/bootm.c | 4 +- > > > > > arch/powerpc/cpu/mpc85xx/mp.c | 4 +- > > > > > arch/powerpc/include/asm/mp.h | 4 +- > > > > > arch/powerpc/lib/bootm.c | 14 +- > > > > > arch/riscv/lib/bootm.c | 4 +- > > > > > arch/sh/lib/bootm.c | 4 +- > > > > > arch/x86/lib/bootm.c | 4 +- > > > > > arch/xtensa/lib/bootm.c | 4 +- > > > > > board/xilinx/common/board.c | 7 +- > > > > > boot/bootm.c | 26 ++-- > > > > > boot/bootm_os.c | 5 +- > > > > > boot/image-board.c | 32 ++--- > > > > > boot/image-fdt.c | 29 ++--- > > > > > cmd/bdinfo.c | 6 +- > > > > > cmd/booti.c | 2 +- > > > > > cmd/bootz.c | 2 +- > > > > > cmd/load.c | 7 +- > > > > > drivers/iommu/apple_dart.c | 7 +- > > > > > drivers/iommu/sandbox_iommu.c | 15 +-- > > > > > fs/fs.c | 7 +- > > > > > include/image.h | 22 +--- > > > > > include/lmb.h | 39 +++--- > > > > > lib/lmb.c | 81 ++++++------ > > > > > net/tftp.c | 5 +- > > > > > net/wget.c | 5 +- > > > > > test/cmd/bdinfo.c | 2 +- > > > > > test/lib/lmb.c | 187 +++++++++++++-------------- > > > > > 36 files changed, 270 insertions(+), 333 deletions(-) > > > > > > > > This isn't necessary...and it will make things harder. You can have a > > > > global 'lmb' while still allowing passing a different pointer when > > > > needed. > > > > > > There's only one reservation checking system and list of known > > > reservations, keep in mind. > > > > There is only one driver model, too, but we use a pointer. It makes > > tests much easier. > > > > In fact I see elsewhere in this series that it causes problems with > > tests. Best to use a pointer so it is easy to update. > > Maybe? I worry that will lead to thinking that we still, like today, > have many LMB lists, rather than a single LMB list that everyone must > use. Do people worry about that with driver model? Also IMO there is only really one LMB list today. We create it at the start of bootm and then it is done when we boot. The file-loading stuff is what makes all this confusing...and with bootstd that is under control as well. At lot of this effort seems to be about dealing with random scripts which load things. We want to make sure we complain if something overlaps. But we should be making the bootstd case work nicely and doing things within that framework. Also EFI sort-of has its own thing, which it is very-much in control of. Overall I think this is a bit more subtle that just combining allocators. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-12 2:41 ` Simon Glass @ 2024-06-12 5:41 ` Ilias Apalodimas 2024-06-12 6:13 ` Heinrich Schuchardt 2024-06-12 17:22 ` Tom Rini 2 siblings, 0 replies; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-12 5:41 UTC (permalink / raw) To: Simon Glass, Tom Rini Cc: Sughosh Ganu, u-boot, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam On Wed, 12 Jun 2024 at 05:41, Simon Glass <sjg@chromium.org> wrote: > > Hi Tom, > > On Tue, 11 Jun 2024 at 16:55, Tom Rini <trini@konsulko.com> wrote: > > > > On Tue, Jun 11, 2024 at 04:08:56PM -0600, Simon Glass wrote: > > > Hi Tom, > > > > > > On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: > > > > > > > > On Tue, Jun 11, 2024 at 12:52:22PM -0600, Simon Glass wrote: > > > > > Hi Sughosh, > > > > > > > > > > On Fri, 7 Jun 2024 at 12:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > > > > > > > With the move of the LMB structure to a persistent state, there is no > > > > > > need to declare the variable locally, and pass it as part of the LMB > > > > > > API's. Remove all local variable instances and change the API's > > > > > > correspondingly. > > > > > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > > > --- > > > > > > arch/arc/lib/cache.c | 4 +- > > > > > > arch/arm/lib/stack.c | 4 +- > > > > > > arch/arm/mach-apple/board.c | 17 ++- > > > > > > arch/arm/mach-snapdragon/board.c | 17 ++- > > > > > > arch/arm/mach-stm32mp/dram_init.c | 7 +- > > > > > > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +- > > > > > > arch/m68k/lib/bootm.c | 7 +- > > > > > > arch/microblaze/lib/bootm.c | 4 +- > > > > > > arch/mips/lib/bootm.c | 9 +- > > > > > > arch/nios2/lib/bootm.c | 4 +- > > > > > > arch/powerpc/cpu/mpc85xx/mp.c | 4 +- > > > > > > arch/powerpc/include/asm/mp.h | 4 +- > > > > > > arch/powerpc/lib/bootm.c | 14 +- > > > > > > arch/riscv/lib/bootm.c | 4 +- > > > > > > arch/sh/lib/bootm.c | 4 +- > > > > > > arch/x86/lib/bootm.c | 4 +- > > > > > > arch/xtensa/lib/bootm.c | 4 +- > > > > > > board/xilinx/common/board.c | 7 +- > > > > > > boot/bootm.c | 26 ++-- > > > > > > boot/bootm_os.c | 5 +- > > > > > > boot/image-board.c | 32 ++--- > > > > > > boot/image-fdt.c | 29 ++--- > > > > > > cmd/bdinfo.c | 6 +- > > > > > > cmd/booti.c | 2 +- > > > > > > cmd/bootz.c | 2 +- > > > > > > cmd/load.c | 7 +- > > > > > > drivers/iommu/apple_dart.c | 7 +- > > > > > > drivers/iommu/sandbox_iommu.c | 15 +-- > > > > > > fs/fs.c | 7 +- > > > > > > include/image.h | 22 +--- > > > > > > include/lmb.h | 39 +++--- > > > > > > lib/lmb.c | 81 ++++++------ > > > > > > net/tftp.c | 5 +- > > > > > > net/wget.c | 5 +- > > > > > > test/cmd/bdinfo.c | 2 +- > > > > > > test/lib/lmb.c | 187 +++++++++++++-------------- > > > > > > 36 files changed, 270 insertions(+), 333 deletions(-) > > > > > > > > > > This isn't necessary...and it will make things harder. You can have a > > > > > global 'lmb' while still allowing passing a different pointer when > > > > > needed. > > > > > > > > There's only one reservation checking system and list of known > > > > reservations, keep in mind. > > > > > > There is only one driver model, too, but we use a pointer. It makes > > > tests much easier. > > > > > > In fact I see elsewhere in this series that it causes problems with > > > tests. Best to use a pointer so it is easy to update. I don't mind keeping it, but OTOH we are fundamentally changing how lmb works, do we need to expose a ptr to make tests easier? We should be aiming for code that is more readable and easier to maintain. Isn't it better to just rewrite the tests replicating the existing cases & add new potential ones? > > > > Maybe? I worry that will lead to thinking that we still, like today, > > have many LMB lists, rather than a single LMB list that everyone must > > use. > > Do people worry about that with driver model? > > Also IMO there is only really one LMB list today. We create it at the > start of bootm and then it is done when we boot. The file-loading > stuff is what makes all this confusing...and with bootstd that is > under control as well. > > At lot of this effort seems to be about dealing with random scripts > which load things. We want to make sure we complain if something > overlaps. But we should be making the bootstd case work nicely and > doing things within that framework. Also EFI sort-of has its own > thing, which it is very-much in control of. > I agree that things should be nicely integrated in bootstd, but does keeping a ptr as an argument help with that ? > Overall I think this is a bit more subtle that just combining allocators. Regards /Ilias > > Regards, > Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-12 2:41 ` Simon Glass 2024-06-12 5:41 ` Ilias Apalodimas @ 2024-06-12 6:13 ` Heinrich Schuchardt 2024-06-12 17:22 ` Tom Rini 2 siblings, 0 replies; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-12 6:13 UTC (permalink / raw) To: Simon Glass, Tom Rini Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam Am 12. Juni 2024 04:41:39 MESZ schrieb Simon Glass <sjg@chromium.org>: >Hi Tom, > >On Tue, 11 Jun 2024 at 16:55, Tom Rini <trini@konsulko.com> wrote: >> >> On Tue, Jun 11, 2024 at 04:08:56PM -0600, Simon Glass wrote: >> > Hi Tom, >> > >> > On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: >> > > >> > > On Tue, Jun 11, 2024 at 12:52:22PM -0600, Simon Glass wrote: >> > > > Hi Sughosh, >> > > > >> > > > On Fri, 7 Jun 2024 at 12:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: >> > > > > >> > > > > With the move of the LMB structure to a persistent state, there is no >> > > > > need to declare the variable locally, and pass it as part of the LMB >> > > > > API's. Remove all local variable instances and change the API's >> > > > > correspondingly. >> > > > > >> > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> >> > > > > --- >> > > > > arch/arc/lib/cache.c | 4 +- >> > > > > arch/arm/lib/stack.c | 4 +- >> > > > > arch/arm/mach-apple/board.c | 17 ++- >> > > > > arch/arm/mach-snapdragon/board.c | 17 ++- >> > > > > arch/arm/mach-stm32mp/dram_init.c | 7 +- >> > > > > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +- >> > > > > arch/m68k/lib/bootm.c | 7 +- >> > > > > arch/microblaze/lib/bootm.c | 4 +- >> > > > > arch/mips/lib/bootm.c | 9 +- >> > > > > arch/nios2/lib/bootm.c | 4 +- >> > > > > arch/powerpc/cpu/mpc85xx/mp.c | 4 +- >> > > > > arch/powerpc/include/asm/mp.h | 4 +- >> > > > > arch/powerpc/lib/bootm.c | 14 +- >> > > > > arch/riscv/lib/bootm.c | 4 +- >> > > > > arch/sh/lib/bootm.c | 4 +- >> > > > > arch/x86/lib/bootm.c | 4 +- >> > > > > arch/xtensa/lib/bootm.c | 4 +- >> > > > > board/xilinx/common/board.c | 7 +- >> > > > > boot/bootm.c | 26 ++-- >> > > > > boot/bootm_os.c | 5 +- >> > > > > boot/image-board.c | 32 ++--- >> > > > > boot/image-fdt.c | 29 ++--- >> > > > > cmd/bdinfo.c | 6 +- >> > > > > cmd/booti.c | 2 +- >> > > > > cmd/bootz.c | 2 +- >> > > > > cmd/load.c | 7 +- >> > > > > drivers/iommu/apple_dart.c | 7 +- >> > > > > drivers/iommu/sandbox_iommu.c | 15 +-- >> > > > > fs/fs.c | 7 +- >> > > > > include/image.h | 22 +--- >> > > > > include/lmb.h | 39 +++--- >> > > > > lib/lmb.c | 81 ++++++------ >> > > > > net/tftp.c | 5 +- >> > > > > net/wget.c | 5 +- >> > > > > test/cmd/bdinfo.c | 2 +- >> > > > > test/lib/lmb.c | 187 +++++++++++++-------------- >> > > > > 36 files changed, 270 insertions(+), 333 deletions(-) >> > > > >> > > > This isn't necessary...and it will make things harder. You can have a >> > > > global 'lmb' while still allowing passing a different pointer when >> > > > needed. >> > > >> > > There's only one reservation checking system and list of known >> > > reservations, keep in mind. >> > >> > There is only one driver model, too, but we use a pointer. It makes >> > tests much easier. >> > >> > In fact I see elsewhere in this series that it causes problems with >> > tests. Best to use a pointer so it is easy to update. >> >> Maybe? I worry that will lead to thinking that we still, like today, >> have many LMB lists, rather than a single LMB list that everyone must >> use. > >Do people worry about that with driver model? > >Also IMO there is only really one LMB list today. We create it at the >start of bootm and then it is done when we boot. The file-loading >stuff is what makes all this confusing...and with bootstd that is >under control as well. As we have a command line interface bootstd is not the only case to consider. We should not start making assumptions about the sequence of commands entered manually. Best regards Heinrich > >At lot of this effort seems to be about dealing with random scripts >which load things. We want to make sure we complain if something >overlaps. But we should be making the bootstd case work nicely and >doing things within that framework. Also EFI sort-of has its own >thing, which it is very-much in control of. > >Overall I think this is a bit more subtle that just combining allocators. > >Regards, >Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-12 2:41 ` Simon Glass 2024-06-12 5:41 ` Ilias Apalodimas 2024-06-12 6:13 ` Heinrich Schuchardt @ 2024-06-12 17:22 ` Tom Rini 2024-06-12 20:24 ` Simon Glass 2 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-12 17:22 UTC (permalink / raw) To: Simon Glass Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 1121 bytes --] On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: [snip] > Also IMO there is only really one LMB list today. We create it at the > start of bootm and then it is done when we boot. The file-loading > stuff is what makes all this confusing...and with bootstd that is > under control as well. > > At lot of this effort seems to be about dealing with random scripts > which load things. We want to make sure we complain if something > overlaps. But we should be making the bootstd case work nicely and > doing things within that framework. Also EFI sort-of has its own > thing, which it is very-much in control of. > > Overall I think this is a bit more subtle that just combining allocators. I think this gets to the main misunderstanding. The problem isn't handling bootstd, or EFI boot, or even assorted scripts. Those are all cases where things are otherwise (sufficiently) well-defined. The problem is "security" and that a "carefully crafted payload" could do something malicious. That's why we have to do all of this stuff sooner rather than later in our boot process. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-12 17:22 ` Tom Rini @ 2024-06-12 20:24 ` Simon Glass 2024-06-12 21:40 ` Tom Rini 0 siblings, 1 reply; 127+ messages in thread From: Simon Glass @ 2024-06-12 20:24 UTC (permalink / raw) To: Tom Rini Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Tom, On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > > On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > > [snip] > > Also IMO there is only really one LMB list today. We create it at the > > start of bootm and then it is done when we boot. The file-loading > > stuff is what makes all this confusing...and with bootstd that is > > under control as well. > > > > At lot of this effort seems to be about dealing with random scripts > > which load things. We want to make sure we complain if something > > overlaps. But we should be making the bootstd case work nicely and > > doing things within that framework. Also EFI sort-of has its own > > thing, which it is very-much in control of. > > > > Overall I think this is a bit more subtle that just combining allocators. > > I think this gets to the main misunderstanding. The problem isn't > handling bootstd, or EFI boot, or even assorted scripts. Those are all > cases where things are otherwise (sufficiently) well-defined. The > problem is "security" and that a "carefully crafted payload" could do > something malicious. That's why we have to do all of this stuff sooner > rather than later in our boot process. That's the first I have heard of this, actually, but a bit more detail would help. How does the payload get loaded? I'm just not sure about the overall goals. It seems that everyone else is already familiar - can someone please take the time to point me to the details? Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-12 20:24 ` Simon Glass @ 2024-06-12 21:40 ` Tom Rini 2024-06-13 15:22 ` Simon Glass 0 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-12 21:40 UTC (permalink / raw) To: Simon Glass Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 1841 bytes --] On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > Hi Tom, > > On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > > > > On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > > > > [snip] > > > Also IMO there is only really one LMB list today. We create it at the > > > start of bootm and then it is done when we boot. The file-loading > > > stuff is what makes all this confusing...and with bootstd that is > > > under control as well. > > > > > > At lot of this effort seems to be about dealing with random scripts > > > which load things. We want to make sure we complain if something > > > overlaps. But we should be making the bootstd case work nicely and > > > doing things within that framework. Also EFI sort-of has its own > > > thing, which it is very-much in control of. > > > > > > Overall I think this is a bit more subtle that just combining allocators. > > > > I think this gets to the main misunderstanding. The problem isn't > > handling bootstd, or EFI boot, or even assorted scripts. Those are all > > cases where things are otherwise (sufficiently) well-defined. The > > problem is "security" and that a "carefully crafted payload" could do > > something malicious. That's why we have to do all of this stuff sooner > > rather than later in our boot process. > > That's the first I have heard of this, actually, but a bit more detail > would help. How does the payload get loaded? I'm just not sure about > the overall goals. It seems that everyone else is already familiar - > can someone please take the time to point me to the details? Well, the short version I believe of the first CVE we got (and so started abusing LMB) was along the lines of "load an image near where the U-Boot stack is, smash things for fun and exploits". -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-12 21:40 ` Tom Rini @ 2024-06-13 15:22 ` Simon Glass 2024-06-13 15:42 ` Tom Rini 0 siblings, 1 reply; 127+ messages in thread From: Simon Glass @ 2024-06-13 15:22 UTC (permalink / raw) To: Tom Rini Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Tom, On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > > On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > > Hi Tom, > > > > On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > > > > > > On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > > > > > > [snip] > > > > Also IMO there is only really one LMB list today. We create it at the > > > > start of bootm and then it is done when we boot. The file-loading > > > > stuff is what makes all this confusing...and with bootstd that is > > > > under control as well. > > > > > > > > At lot of this effort seems to be about dealing with random scripts > > > > which load things. We want to make sure we complain if something > > > > overlaps. But we should be making the bootstd case work nicely and > > > > doing things within that framework. Also EFI sort-of has its own > > > > thing, which it is very-much in control of. > > > > > > > > Overall I think this is a bit more subtle that just combining allocators. > > > > > > I think this gets to the main misunderstanding. The problem isn't > > > handling bootstd, or EFI boot, or even assorted scripts. Those are all > > > cases where things are otherwise (sufficiently) well-defined. The > > > problem is "security" and that a "carefully crafted payload" could do > > > something malicious. That's why we have to do all of this stuff sooner > > > rather than later in our boot process. > > > > That's the first I have heard of this, actually, but a bit more detail > > would help. How does the payload get loaded? I'm just not sure about > > the overall goals. It seems that everyone else is already familiar - > > can someone please take the time to point me to the details? > > Well, the short version I believe of the first CVE we got (and so > started abusing LMB) was along the lines of "load an image near where > the U-Boot stack is, smash things for fun and exploits". OK. I am surprised that LMB does not catch that. It is supposed to add the stack and various other things right at the start before loading any file. So even if it clears the LMB each time, it should not be able to do that. Having said this, the code may be buggy as I don't think we have tests for U-Boot's overall functional behaviour in these situations. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 15:22 ` Simon Glass @ 2024-06-13 15:42 ` Tom Rini 2024-06-13 16:59 ` Simon Glass 0 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-13 15:42 UTC (permalink / raw) To: Simon Glass Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 3590 bytes --] On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: > Hi Tom, > > On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > > > > On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > > > Hi Tom, > > > > > > On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > > > > > > > > On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > > > > > > > > [snip] > > > > > Also IMO there is only really one LMB list today. We create it at the > > > > > start of bootm and then it is done when we boot. The file-loading > > > > > stuff is what makes all this confusing...and with bootstd that is > > > > > under control as well. > > > > > > > > > > At lot of this effort seems to be about dealing with random scripts > > > > > which load things. We want to make sure we complain if something > > > > > overlaps. But we should be making the bootstd case work nicely and > > > > > doing things within that framework. Also EFI sort-of has its own > > > > > thing, which it is very-much in control of. > > > > > > > > > > Overall I think this is a bit more subtle that just combining allocators. > > > > > > > > I think this gets to the main misunderstanding. The problem isn't > > > > handling bootstd, or EFI boot, or even assorted scripts. Those are all > > > > cases where things are otherwise (sufficiently) well-defined. The > > > > problem is "security" and that a "carefully crafted payload" could do > > > > something malicious. That's why we have to do all of this stuff sooner > > > > rather than later in our boot process. > > > > > > That's the first I have heard of this, actually, but a bit more detail > > > would help. How does the payload get loaded? I'm just not sure about > > > the overall goals. It seems that everyone else is already familiar - > > > can someone please take the time to point me to the details? > > > > Well, the short version I believe of the first CVE we got (and so > > started abusing LMB) was along the lines of "load an image near where > > the U-Boot stack is, smash things for fun and exploits". > > OK. I am surprised that LMB does not catch that. It is supposed to add > the stack and various other things right at the start before loading > any file. So even if it clears the LMB each time, it should not be > able to do that. Having said this, the code may be buggy as I don't > think we have tests for U-Boot's overall functional behaviour in these > situations. Right, LMB does catch the example I gave (because we made all of the load from storage/network functions init an lmb and we always make sure a new lmb gets U-Boot stack/etc). The next thing we didn't catch was "what if EFI does the loading?" and we've kludged around that, and in turn had some of the thorny questions. Some of that is what I think you're asking about in this part of the thread, to which the answer is "EFI spec says you need to place X in memory", so we just need to reserve it when it's asked for, so that something else can't come along and smash it maliciously. But that also raised the more general problem, and why we need a persistent reservation list, of allowing boards/SoCs to say they want to reserve a block of memory for whatever, and have that obeyed, for real. For example, the mach-apple logic of "just pick some memory locations to use for kernel/dtb/initrd" isn't really as safe as it should be since those reservations aren't really seen anywhere once the function returns, it's just setting some environment variables. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 15:42 ` Tom Rini @ 2024-06-13 16:59 ` Simon Glass 2024-06-13 17:27 ` Heinrich Schuchardt 2024-06-13 20:06 ` Tom Rini 0 siblings, 2 replies; 127+ messages in thread From: Simon Glass @ 2024-06-13 16:59 UTC (permalink / raw) To: Tom Rini Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Tom, On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: > > On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: > > Hi Tom, > > > > On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > > > > > > On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > > > > Hi Tom, > > > > > > > > On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > > > > > > > > > > On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > > > > > > > > > > [snip] > > > > > > Also IMO there is only really one LMB list today. We create it at the > > > > > > start of bootm and then it is done when we boot. The file-loading > > > > > > stuff is what makes all this confusing...and with bootstd that is > > > > > > under control as well. > > > > > > > > > > > > At lot of this effort seems to be about dealing with random scripts > > > > > > which load things. We want to make sure we complain if something > > > > > > overlaps. But we should be making the bootstd case work nicely and > > > > > > doing things within that framework. Also EFI sort-of has its own > > > > > > thing, which it is very-much in control of. > > > > > > > > > > > > Overall I think this is a bit more subtle that just combining allocators. > > > > > > > > > > I think this gets to the main misunderstanding. The problem isn't > > > > > handling bootstd, or EFI boot, or even assorted scripts. Those are all > > > > > cases where things are otherwise (sufficiently) well-defined. The > > > > > problem is "security" and that a "carefully crafted payload" could do > > > > > something malicious. That's why we have to do all of this stuff sooner > > > > > rather than later in our boot process. > > > > > > > > That's the first I have heard of this, actually, but a bit more detail > > > > would help. How does the payload get loaded? I'm just not sure about > > > > the overall goals. It seems that everyone else is already familiar - > > > > can someone please take the time to point me to the details? > > > > > > Well, the short version I believe of the first CVE we got (and so > > > started abusing LMB) was along the lines of "load an image near where > > > the U-Boot stack is, smash things for fun and exploits". > > > > OK. I am surprised that LMB does not catch that. It is supposed to add > > the stack and various other things right at the start before loading > > any file. So even if it clears the LMB each time, it should not be > > able to do that. Having said this, the code may be buggy as I don't > > think we have tests for U-Boot's overall functional behaviour in these > > situations. > > Right, LMB does catch the example I gave (because we made all of the > load from storage/network functions init an lmb and we always make sure > a new lmb gets U-Boot stack/etc). The next thing we didn't catch was > "what if EFI does the loading?" and we've kludged around that, and in > turn had some of the thorny questions. Some of that is what I think > you're asking about in this part of the thread, to which the answer is > "EFI spec says you need to place X in memory", so we just need to > reserve it when it's asked for, so that something else can't come along > and smash it maliciously. OK I see. Of course it isn't just EFI that has this issue. I believe the answer (for small blocks) is to use malloc(), which I think we do with a few exceptions which Ilias pointed out. For things like the TPM log and ACPI tables we should probably use a bloblist, as we do on x86. For large things (like loading a kernel) we should use LMB. I've been thinking about how best to tie this to boot, as opposed to random allocations in U-Boot itself, which would lead to fragmentation and strange behaviour. I think bootstd is a great place to have a persistent LMB. It can be attached to bootstd_priv. My hope is that EFI is just another boot method, where already-allocating things are presented to the OS. Apart from the Ilias exceptions, I believe this is how it works today. Where I think this heads in the wrong direction is using EFI-allocation functions before we are booting an EFI image. EFI has no concept of what is 'in empty space' so it leads to the lmb conflict, the subject of this discussion. This is all quite subtle and probably worthy of a VC discussion. > > But that also raised the more general problem, and why we need a > persistent reservation list, of allowing boards/SoCs to say they want to > reserve a block of memory for whatever, and have that obeyed, for real. > For example, the mach-apple logic of "just pick some memory locations to > use for kernel/dtb/initrd" isn't really as safe as it should be since > those reservations aren't really seen anywhere once the function > returns, it's just setting some environment variables. Yes, that part of it I understand. Somehow I either didn't see or forgot that board_late_init() code. With the script-based boot it makes some sort of sense, but with bootstd we should have allocation of addresses dealt with there. I have held off on retiring kernel_addr_r etc. as the scripts are still in use. But perhaps it would be a good time to convert bootstd to use lmb instead? Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 16:59 ` Simon Glass @ 2024-06-13 17:27 ` Heinrich Schuchardt 2024-06-13 18:17 ` Sughosh Ganu 2024-06-13 19:05 ` Simon Glass 2024-06-13 20:06 ` Tom Rini 1 sibling, 2 replies; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-13 17:27 UTC (permalink / raw) To: Simon Glass Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini On 13.06.24 18:59, Simon Glass wrote: > Hi Tom, > > On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: >> >> On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: >>> Hi Tom, >>> >>> On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: >>>> >>>> On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: >>>>> Hi Tom, >>>>> >>>>> On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: >>>>>> >>>>>> On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: >>>>>> >>>>>> [snip] >>>>>>> Also IMO there is only really one LMB list today. We create it at the >>>>>>> start of bootm and then it is done when we boot. The file-loading >>>>>>> stuff is what makes all this confusing...and with bootstd that is >>>>>>> under control as well. >>>>>>> >>>>>>> At lot of this effort seems to be about dealing with random scripts >>>>>>> which load things. We want to make sure we complain if something >>>>>>> overlaps. But we should be making the bootstd case work nicely and >>>>>>> doing things within that framework. Also EFI sort-of has its own >>>>>>> thing, which it is very-much in control of. >>>>>>> >>>>>>> Overall I think this is a bit more subtle that just combining allocators. >>>>>> >>>>>> I think this gets to the main misunderstanding. The problem isn't >>>>>> handling bootstd, or EFI boot, or even assorted scripts. Those are all >>>>>> cases where things are otherwise (sufficiently) well-defined. The >>>>>> problem is "security" and that a "carefully crafted payload" could do >>>>>> something malicious. That's why we have to do all of this stuff sooner >>>>>> rather than later in our boot process. >>>>> >>>>> That's the first I have heard of this, actually, but a bit more detail >>>>> would help. How does the payload get loaded? I'm just not sure about >>>>> the overall goals. It seems that everyone else is already familiar - >>>>> can someone please take the time to point me to the details? >>>> >>>> Well, the short version I believe of the first CVE we got (and so >>>> started abusing LMB) was along the lines of "load an image near where >>>> the U-Boot stack is, smash things for fun and exploits". >>> >>> OK. I am surprised that LMB does not catch that. It is supposed to add >>> the stack and various other things right at the start before loading >>> any file. So even if it clears the LMB each time, it should not be >>> able to do that. Having said this, the code may be buggy as I don't >>> think we have tests for U-Boot's overall functional behaviour in these >>> situations. >> >> Right, LMB does catch the example I gave (because we made all of the >> load from storage/network functions init an lmb and we always make sure >> a new lmb gets U-Boot stack/etc). The next thing we didn't catch was >> "what if EFI does the loading?" and we've kludged around that, and in >> turn had some of the thorny questions. Some of that is what I think >> you're asking about in this part of the thread, to which the answer is >> "EFI spec says you need to place X in memory", so we just need to >> reserve it when it's asked for, so that something else can't come along >> and smash it maliciously. > > OK I see. Of course it isn't just EFI that has this issue. I believe > the answer (for small blocks) is to use malloc(), which I think we do > with a few exceptions which Ilias pointed out. For things like the TPM > log and ACPI tables we should probably use a bloblist, as we do on > x86. For large things (like loading a kernel) we should use LMB. I've > been thinking about how best to tie this to boot, as opposed to random > allocations in U-Boot itself, which would lead to fragmentation and > strange behaviour. I think bootstd is a great place to have a > persistent LMB. It can be attached to bootstd_priv. > > My hope is that EFI is just another boot method, where > already-allocating things are presented to the OS. Apart from the > Ilias exceptions, I believe this is how it works today. > > Where I think this heads in the wrong direction is using > EFI-allocation functions before we are booting an EFI image. EFI has > no concept of what is 'in empty space' so it leads to the lmb > conflict, the subject of this discussion. EFI binaries can return to the command line interface. EFI binaries may be drivers that stay resident and run in the background after returning to the command line interface. They might for instance provide block devices. Device-paths must be created from EFI pool memory as they may be freed via FreePool() according to the EFI specification. And these we create whenever a block-device is probed. We should not make any assumptions that conflict with the UEFI specification. In our initial discussion with Ilias one idea was to merge LMB and EFI memory management. This merged system would have to consider the requirements of the UEFI specifications like a finer grained memory type system and page boundaries. Best regards Heinrich > > This is all quite subtle and probably worthy of a VC discussion. > >> >> But that also raised the more general problem, and why we need a >> persistent reservation list, of allowing boards/SoCs to say they want to >> reserve a block of memory for whatever, and have that obeyed, for real. >> For example, the mach-apple logic of "just pick some memory locations to >> use for kernel/dtb/initrd" isn't really as safe as it should be since >> those reservations aren't really seen anywhere once the function >> returns, it's just setting some environment variables. > > Yes, that part of it I understand. Somehow I either didn't see or > forgot that board_late_init() code. With the script-based boot it > makes some sort of sense, but with bootstd we should have allocation > of addresses dealt with there. I have held off on retiring > kernel_addr_r etc. as the scripts are still in use. But perhaps it > would be a good time to convert bootstd to use lmb instead? > > Regards, > Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 17:27 ` Heinrich Schuchardt @ 2024-06-13 18:17 ` Sughosh Ganu 2024-06-13 19:06 ` Simon Glass 2024-06-13 19:05 ` Simon Glass 1 sibling, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-13 18:17 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Simon Glass, u-boot, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini On Thu, 13 Jun 2024 at 22:57, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 13.06.24 18:59, Simon Glass wrote: > > Hi Tom, > > > > On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: > >> > >> On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: > >>> Hi Tom, > >>> > >>> On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > >>>> > >>>> On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > >>>>> Hi Tom, > >>>>> > >>>>> On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > >>>>>> > >>>>>> On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > >>>>>> > >>>>>> [snip] > >>>>>>> Also IMO there is only really one LMB list today. We create it at the > >>>>>>> start of bootm and then it is done when we boot. The file-loading > >>>>>>> stuff is what makes all this confusing...and with bootstd that is > >>>>>>> under control as well. > >>>>>>> > >>>>>>> At lot of this effort seems to be about dealing with random scripts > >>>>>>> which load things. We want to make sure we complain if something > >>>>>>> overlaps. But we should be making the bootstd case work nicely and > >>>>>>> doing things within that framework. Also EFI sort-of has its own > >>>>>>> thing, which it is very-much in control of. > >>>>>>> > >>>>>>> Overall I think this is a bit more subtle that just combining allocators. > >>>>>> > >>>>>> I think this gets to the main misunderstanding. The problem isn't > >>>>>> handling bootstd, or EFI boot, or even assorted scripts. Those are all > >>>>>> cases where things are otherwise (sufficiently) well-defined. The > >>>>>> problem is "security" and that a "carefully crafted payload" could do > >>>>>> something malicious. That's why we have to do all of this stuff sooner > >>>>>> rather than later in our boot process. > >>>>> > >>>>> That's the first I have heard of this, actually, but a bit more detail > >>>>> would help. How does the payload get loaded? I'm just not sure about > >>>>> the overall goals. It seems that everyone else is already familiar - > >>>>> can someone please take the time to point me to the details? > >>>> > >>>> Well, the short version I believe of the first CVE we got (and so > >>>> started abusing LMB) was along the lines of "load an image near where > >>>> the U-Boot stack is, smash things for fun and exploits". > >>> > >>> OK. I am surprised that LMB does not catch that. It is supposed to add > >>> the stack and various other things right at the start before loading > >>> any file. So even if it clears the LMB each time, it should not be > >>> able to do that. Having said this, the code may be buggy as I don't > >>> think we have tests for U-Boot's overall functional behaviour in these > >>> situations. > >> > >> Right, LMB does catch the example I gave (because we made all of the > >> load from storage/network functions init an lmb and we always make sure > >> a new lmb gets U-Boot stack/etc). The next thing we didn't catch was > >> "what if EFI does the loading?" and we've kludged around that, and in > >> turn had some of the thorny questions. Some of that is what I think > >> you're asking about in this part of the thread, to which the answer is > >> "EFI spec says you need to place X in memory", so we just need to > >> reserve it when it's asked for, so that something else can't come along > >> and smash it maliciously. > > > > OK I see. Of course it isn't just EFI that has this issue. I believe > > the answer (for small blocks) is to use malloc(), which I think we do > > with a few exceptions which Ilias pointed out. For things like the TPM > > log and ACPI tables we should probably use a bloblist, as we do on > > x86. For large things (like loading a kernel) we should use LMB. I've > > been thinking about how best to tie this to boot, as opposed to random > > allocations in U-Boot itself, which would lead to fragmentation and > > strange behaviour. I think bootstd is a great place to have a > > persistent LMB. It can be attached to bootstd_priv. > > > > My hope is that EFI is just another boot method, where > > already-allocating things are presented to the OS. Apart from the > > Ilias exceptions, I believe this is how it works today. > > > > Where I think this heads in the wrong direction is using > > EFI-allocation functions before we are booting an EFI image. EFI has > > no concept of what is 'in empty space' so it leads to the lmb > > conflict, the subject of this discussion. > > EFI binaries can return to the command line interface. > EFI binaries may be drivers that stay resident and run in the background > after returning to the command line interface. They might for instance > provide block devices. > > Device-paths must be created from EFI pool memory as they may be freed > via FreePool() according to the EFI specification. And these we create > whenever a block-device is probed. > > We should not make any assumptions that conflict with the UEFI > specification. > > In our initial discussion with Ilias one idea was to merge LMB and EFI > memory management. This merged system would have to consider the > requirements of the UEFI specifications like a finer grained memory type > system and page boundaries. Not sure about merging LMB and EFI memory management, but I am looking at using the LMB API's for EFI allocations for the next version. The LMB API's as they stand today, align pretty neatly with the requirements of the efi_allocate_pages() function, which really is the EFI memory allocation function. I think it should be possible to use the LMB API's(with a different flag passed to differentiate between LMB and EFI reservations) from the EFI memory module. I think things like maintaining the EFI memory map should still reside in the EFI memory module. -sughosh > > Best regards > > Heinrich > > > > > This is all quite subtle and probably worthy of a VC discussion. > > > >> > >> But that also raised the more general problem, and why we need a > >> persistent reservation list, of allowing boards/SoCs to say they want to > >> reserve a block of memory for whatever, and have that obeyed, for real. > >> For example, the mach-apple logic of "just pick some memory locations to > >> use for kernel/dtb/initrd" isn't really as safe as it should be since > >> those reservations aren't really seen anywhere once the function > >> returns, it's just setting some environment variables. > > > > Yes, that part of it I understand. Somehow I either didn't see or > > forgot that board_late_init() code. With the script-based boot it > > makes some sort of sense, but with bootstd we should have allocation > > of addresses dealt with there. I have held off on retiring > > kernel_addr_r etc. as the scripts are still in use. But perhaps it > > would be a good time to convert bootstd to use lmb instead? > > > > Regards, > > Simon > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 18:17 ` Sughosh Ganu @ 2024-06-13 19:06 ` Simon Glass 0 siblings, 0 replies; 127+ messages in thread From: Simon Glass @ 2024-06-13 19:06 UTC (permalink / raw) To: Sughosh Ganu Cc: Heinrich Schuchardt, u-boot, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini Hi Sughosh, On Thu, 13 Jun 2024 at 12:17, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > On Thu, 13 Jun 2024 at 22:57, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > On 13.06.24 18:59, Simon Glass wrote: > > > Hi Tom, > > > > > > On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: > > >> > > >> On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: > > >>> Hi Tom, > > >>> > > >>> On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > > >>>> > > >>>> On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > > >>>>> Hi Tom, > > >>>>> > > >>>>> On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > > >>>>>> > > >>>>>> On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > > >>>>>> > > >>>>>> [snip] > > >>>>>>> Also IMO there is only really one LMB list today. We create it at the > > >>>>>>> start of bootm and then it is done when we boot. The file-loading > > >>>>>>> stuff is what makes all this confusing...and with bootstd that is > > >>>>>>> under control as well. > > >>>>>>> > > >>>>>>> At lot of this effort seems to be about dealing with random scripts > > >>>>>>> which load things. We want to make sure we complain if something > > >>>>>>> overlaps. But we should be making the bootstd case work nicely and > > >>>>>>> doing things within that framework. Also EFI sort-of has its own > > >>>>>>> thing, which it is very-much in control of. > > >>>>>>> > > >>>>>>> Overall I think this is a bit more subtle that just combining allocators. > > >>>>>> > > >>>>>> I think this gets to the main misunderstanding. The problem isn't > > >>>>>> handling bootstd, or EFI boot, or even assorted scripts. Those are all > > >>>>>> cases where things are otherwise (sufficiently) well-defined. The > > >>>>>> problem is "security" and that a "carefully crafted payload" could do > > >>>>>> something malicious. That's why we have to do all of this stuff sooner > > >>>>>> rather than later in our boot process. > > >>>>> > > >>>>> That's the first I have heard of this, actually, but a bit more detail > > >>>>> would help. How does the payload get loaded? I'm just not sure about > > >>>>> the overall goals. It seems that everyone else is already familiar - > > >>>>> can someone please take the time to point me to the details? > > >>>> > > >>>> Well, the short version I believe of the first CVE we got (and so > > >>>> started abusing LMB) was along the lines of "load an image near where > > >>>> the U-Boot stack is, smash things for fun and exploits". > > >>> > > >>> OK. I am surprised that LMB does not catch that. It is supposed to add > > >>> the stack and various other things right at the start before loading > > >>> any file. So even if it clears the LMB each time, it should not be > > >>> able to do that. Having said this, the code may be buggy as I don't > > >>> think we have tests for U-Boot's overall functional behaviour in these > > >>> situations. > > >> > > >> Right, LMB does catch the example I gave (because we made all of the > > >> load from storage/network functions init an lmb and we always make sure > > >> a new lmb gets U-Boot stack/etc). The next thing we didn't catch was > > >> "what if EFI does the loading?" and we've kludged around that, and in > > >> turn had some of the thorny questions. Some of that is what I think > > >> you're asking about in this part of the thread, to which the answer is > > >> "EFI spec says you need to place X in memory", so we just need to > > >> reserve it when it's asked for, so that something else can't come along > > >> and smash it maliciously. > > > > > > OK I see. Of course it isn't just EFI that has this issue. I believe > > > the answer (for small blocks) is to use malloc(), which I think we do > > > with a few exceptions which Ilias pointed out. For things like the TPM > > > log and ACPI tables we should probably use a bloblist, as we do on > > > x86. For large things (like loading a kernel) we should use LMB. I've > > > been thinking about how best to tie this to boot, as opposed to random > > > allocations in U-Boot itself, which would lead to fragmentation and > > > strange behaviour. I think bootstd is a great place to have a > > > persistent LMB. It can be attached to bootstd_priv. > > > > > > My hope is that EFI is just another boot method, where > > > already-allocating things are presented to the OS. Apart from the > > > Ilias exceptions, I believe this is how it works today. > > > > > > Where I think this heads in the wrong direction is using > > > EFI-allocation functions before we are booting an EFI image. EFI has > > > no concept of what is 'in empty space' so it leads to the lmb > > > conflict, the subject of this discussion. > > > > EFI binaries can return to the command line interface. > > EFI binaries may be drivers that stay resident and run in the background > > after returning to the command line interface. They might for instance > > provide block devices. > > > > Device-paths must be created from EFI pool memory as they may be freed > > via FreePool() according to the EFI specification. And these we create > > whenever a block-device is probed. > > > > We should not make any assumptions that conflict with the UEFI > > specification. > > > > In our initial discussion with Ilias one idea was to merge LMB and EFI > > memory management. This merged system would have to consider the > > requirements of the UEFI specifications like a finer grained memory type > > system and page boundaries. > > Not sure about merging LMB and EFI memory management, but I am looking > at using the LMB API's for EFI allocations for the next version. The > LMB API's as they stand today, align pretty neatly with the > requirements of the efi_allocate_pages() function, which really is the > EFI memory allocation function. I think it should be possible to use > the LMB API's(with a different flag passed to differentiate between > LMB and EFI reservations) from the EFI memory module. I think things > like maintaining the EFI memory map should still reside in the EFI > memory module. Yes, that makes a lot of sense to me. Regards, Simon > > -sughosh > > > > > Best regards > > > > Heinrich > > > > > > > > This is all quite subtle and probably worthy of a VC discussion. > > > > > >> > > >> But that also raised the more general problem, and why we need a > > >> persistent reservation list, of allowing boards/SoCs to say they want to > > >> reserve a block of memory for whatever, and have that obeyed, for real. > > >> For example, the mach-apple logic of "just pick some memory locations to > > >> use for kernel/dtb/initrd" isn't really as safe as it should be since > > >> those reservations aren't really seen anywhere once the function > > >> returns, it's just setting some environment variables. > > > > > > Yes, that part of it I understand. Somehow I either didn't see or > > > forgot that board_late_init() code. With the script-based boot it > > > makes some sort of sense, but with bootstd we should have allocation > > > of addresses dealt with there. I have held off on retiring > > > kernel_addr_r etc. as the scripts are still in use. But perhaps it > > > would be a good time to convert bootstd to use lmb instead? > > > > > > Regards, > > > Simon > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 17:27 ` Heinrich Schuchardt 2024-06-13 18:17 ` Sughosh Ganu @ 2024-06-13 19:05 ` Simon Glass 2024-06-13 20:11 ` Heinrich Schuchardt 1 sibling, 1 reply; 127+ messages in thread From: Simon Glass @ 2024-06-13 19:05 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini Hi Heinrich, On Thu, 13 Jun 2024 at 11:32, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 13.06.24 18:59, Simon Glass wrote: > > Hi Tom, > > > > On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: > >> > >> On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: > >>> Hi Tom, > >>> > >>> On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > >>>> > >>>> On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > >>>>> Hi Tom, > >>>>> > >>>>> On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > >>>>>> > >>>>>> On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > >>>>>> > >>>>>> [snip] > >>>>>>> Also IMO there is only really one LMB list today. We create it at the > >>>>>>> start of bootm and then it is done when we boot. The file-loading > >>>>>>> stuff is what makes all this confusing...and with bootstd that is > >>>>>>> under control as well. > >>>>>>> > >>>>>>> At lot of this effort seems to be about dealing with random scripts > >>>>>>> which load things. We want to make sure we complain if something > >>>>>>> overlaps. But we should be making the bootstd case work nicely and > >>>>>>> doing things within that framework. Also EFI sort-of has its own > >>>>>>> thing, which it is very-much in control of. > >>>>>>> > >>>>>>> Overall I think this is a bit more subtle that just combining allocators. > >>>>>> > >>>>>> I think this gets to the main misunderstanding. The problem isn't > >>>>>> handling bootstd, or EFI boot, or even assorted scripts. Those are all > >>>>>> cases where things are otherwise (sufficiently) well-defined. The > >>>>>> problem is "security" and that a "carefully crafted payload" could do > >>>>>> something malicious. That's why we have to do all of this stuff sooner > >>>>>> rather than later in our boot process. > >>>>> > >>>>> That's the first I have heard of this, actually, but a bit more detail > >>>>> would help. How does the payload get loaded? I'm just not sure about > >>>>> the overall goals. It seems that everyone else is already familiar - > >>>>> can someone please take the time to point me to the details? > >>>> > >>>> Well, the short version I believe of the first CVE we got (and so > >>>> started abusing LMB) was along the lines of "load an image near where > >>>> the U-Boot stack is, smash things for fun and exploits". > >>> > >>> OK. I am surprised that LMB does not catch that. It is supposed to add > >>> the stack and various other things right at the start before loading > >>> any file. So even if it clears the LMB each time, it should not be > >>> able to do that. Having said this, the code may be buggy as I don't > >>> think we have tests for U-Boot's overall functional behaviour in these > >>> situations. > >> > >> Right, LMB does catch the example I gave (because we made all of the > >> load from storage/network functions init an lmb and we always make sure > >> a new lmb gets U-Boot stack/etc). The next thing we didn't catch was > >> "what if EFI does the loading?" and we've kludged around that, and in > >> turn had some of the thorny questions. Some of that is what I think > >> you're asking about in this part of the thread, to which the answer is > >> "EFI spec says you need to place X in memory", so we just need to > >> reserve it when it's asked for, so that something else can't come along > >> and smash it maliciously. > > > > OK I see. Of course it isn't just EFI that has this issue. I believe > > the answer (for small blocks) is to use malloc(), which I think we do > > with a few exceptions which Ilias pointed out. For things like the TPM > > log and ACPI tables we should probably use a bloblist, as we do on > > x86. For large things (like loading a kernel) we should use LMB. I've > > been thinking about how best to tie this to boot, as opposed to random > > allocations in U-Boot itself, which would lead to fragmentation and > > strange behaviour. I think bootstd is a great place to have a > > persistent LMB. It can be attached to bootstd_priv. > > > > My hope is that EFI is just another boot method, where > > already-allocating things are presented to the OS. Apart from the > > Ilias exceptions, I believe this is how it works today. > > > > Where I think this heads in the wrong direction is using > > EFI-allocation functions before we are booting an EFI image. EFI has > > no concept of what is 'in empty space' so it leads to the lmb > > conflict, the subject of this discussion. > > EFI binaries can return to the command line interface. > EFI binaries may be drivers that stay resident and run in the background > after returning to the command line interface. They might for instance > provide block devices. Hmm you mentioned that before but I'm still not quite understanding. Do you mean that the EFI app returns back to U-Boot, leaving the driver active? If so, how does U-Boot use the driver? I'm just not familiar with how such a construct could work in a single-threaded U-Boot. > > Device-paths must be created from EFI pool memory as they may be freed > via FreePool() according to the EFI specification. And these we create > whenever a block-device is probed. The implementation of pool memory rounds up to pages and uses that. It might be more efficient to use malloc()/free() instead, given that we mark the malloc() space as reserved when we call the EFI app. > > We should not make any assumptions that conflict with the UEFI > specification. Indeed. > > In our initial discussion with Ilias one idea was to merge LMB and EFI > memory management. This merged system would have to consider the > requirements of the UEFI specifications like a finer grained memory type > system and page boundaries. > > Best regards > > Heinrich > > > > > This is all quite subtle and probably worthy of a VC discussion. > > > >> > >> But that also raised the more general problem, and why we need a > >> persistent reservation list, of allowing boards/SoCs to say they want to > >> reserve a block of memory for whatever, and have that obeyed, for real. > >> For example, the mach-apple logic of "just pick some memory locations to > >> use for kernel/dtb/initrd" isn't really as safe as it should be since > >> those reservations aren't really seen anywhere once the function > >> returns, it's just setting some environment variables. > > > > Yes, that part of it I understand. Somehow I either didn't see or > > forgot that board_late_init() code. With the script-based boot it > > makes some sort of sense, but with bootstd we should have allocation > > of addresses dealt with there. I have held off on retiring > > kernel_addr_r etc. as the scripts are still in use. But perhaps it > > would be a good time to convert bootstd to use lmb instead? > > > > Regards, > > Simon > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 19:05 ` Simon Glass @ 2024-06-13 20:11 ` Heinrich Schuchardt 2024-06-14 5:58 ` Ilias Apalodimas 2024-06-19 3:03 ` Simon Glass 0 siblings, 2 replies; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-13 20:11 UTC (permalink / raw) To: Simon Glass Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini Am 13. Juni 2024 21:05:58 MESZ schrieb Simon Glass <sjg@chromium.org>: >Hi Heinrich, > >On Thu, 13 Jun 2024 at 11:32, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: >> >> On 13.06.24 18:59, Simon Glass wrote: >> > Hi Tom, >> > >> > On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: >> >> >> >> On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: >> >>> Hi Tom, >> >>> >> >>> On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: >> >>>> >> >>>> On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: >> >>>>> Hi Tom, >> >>>>> >> >>>>> On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: >> >>>>>> >> >>>>>> On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: >> >>>>>> >> >>>>>> [snip] >> >>>>>>> Also IMO there is only really one LMB list today. We create it at the >> >>>>>>> start of bootm and then it is done when we boot. The file-loading >> >>>>>>> stuff is what makes all this confusing...and with bootstd that is >> >>>>>>> under control as well. >> >>>>>>> >> >>>>>>> At lot of this effort seems to be about dealing with random scripts >> >>>>>>> which load things. We want to make sure we complain if something >> >>>>>>> overlaps. But we should be making the bootstd case work nicely and >> >>>>>>> doing things within that framework. Also EFI sort-of has its own >> >>>>>>> thing, which it is very-much in control of. >> >>>>>>> >> >>>>>>> Overall I think this is a bit more subtle that just combining allocators. >> >>>>>> >> >>>>>> I think this gets to the main misunderstanding. The problem isn't >> >>>>>> handling bootstd, or EFI boot, or even assorted scripts. Those are all >> >>>>>> cases where things are otherwise (sufficiently) well-defined. The >> >>>>>> problem is "security" and that a "carefully crafted payload" could do >> >>>>>> something malicious. That's why we have to do all of this stuff sooner >> >>>>>> rather than later in our boot process. >> >>>>> >> >>>>> That's the first I have heard of this, actually, but a bit more detail >> >>>>> would help. How does the payload get loaded? I'm just not sure about >> >>>>> the overall goals. It seems that everyone else is already familiar - >> >>>>> can someone please take the time to point me to the details? >> >>>> >> >>>> Well, the short version I believe of the first CVE we got (and so >> >>>> started abusing LMB) was along the lines of "load an image near where >> >>>> the U-Boot stack is, smash things for fun and exploits". >> >>> >> >>> OK. I am surprised that LMB does not catch that. It is supposed to add >> >>> the stack and various other things right at the start before loading >> >>> any file. So even if it clears the LMB each time, it should not be >> >>> able to do that. Having said this, the code may be buggy as I don't >> >>> think we have tests for U-Boot's overall functional behaviour in these >> >>> situations. >> >> >> >> Right, LMB does catch the example I gave (because we made all of the >> >> load from storage/network functions init an lmb and we always make sure >> >> a new lmb gets U-Boot stack/etc). The next thing we didn't catch was >> >> "what if EFI does the loading?" and we've kludged around that, and in >> >> turn had some of the thorny questions. Some of that is what I think >> >> you're asking about in this part of the thread, to which the answer is >> >> "EFI spec says you need to place X in memory", so we just need to >> >> reserve it when it's asked for, so that something else can't come along >> >> and smash it maliciously. >> > >> > OK I see. Of course it isn't just EFI that has this issue. I believe >> > the answer (for small blocks) is to use malloc(), which I think we do >> > with a few exceptions which Ilias pointed out. For things like the TPM >> > log and ACPI tables we should probably use a bloblist, as we do on >> > x86. For large things (like loading a kernel) we should use LMB. I've >> > been thinking about how best to tie this to boot, as opposed to random >> > allocations in U-Boot itself, which would lead to fragmentation and >> > strange behaviour. I think bootstd is a great place to have a >> > persistent LMB. It can be attached to bootstd_priv. >> > >> > My hope is that EFI is just another boot method, where >> > already-allocating things are presented to the OS. Apart from the >> > Ilias exceptions, I believe this is how it works today. >> > >> > Where I think this heads in the wrong direction is using >> > EFI-allocation functions before we are booting an EFI image. EFI has >> > no concept of what is 'in empty space' so it leads to the lmb >> > conflict, the subject of this discussion. >> >> EFI binaries can return to the command line interface. >> EFI binaries may be drivers that stay resident and run in the background >> after returning to the command line interface. They might for instance >> provide block devices. > >Hmm you mentioned that before but I'm still not quite understanding. >Do you mean that the EFI app returns back to U-Boot, leaving the There are 3 types of of EFI binaries: * apps * boot time drivers * run time drivers >driver active? If so, how does U-Boot use the driver? I'm just not >familiar with how such a construct could work in a single-threaded >U-Boot. We already have code for EFI block devices. See lib/efi_driver/ When U-Boot reads from such a block device it may end up in an EFI driver that for instance uses U-Boots network drivers exposed as EFI simple network protocol to read from an NVMEoF or iSCSI server. > >> >> Device-paths must be created from EFI pool memory as they may be freed >> via FreePool() according to the EFI specification. And these we create >> whenever a block-device is probed. > >The implementation of pool memory rounds up to pages and uses that. It >might be more efficient to use malloc()/free() instead, given that we >mark the malloc() space as reserved when we call the EFI app. We have requirements on which EFI allocations may reside in the same page. See the ARM chapter in the UEFI specification. Best regards Heinrich > >> >> We should not make any assumptions that conflict with the UEFI >> specification. > >Indeed. > >> >> In our initial discussion with Ilias one idea was to merge LMB and EFI >> memory management. This merged system would have to consider the >> requirements of the UEFI specifications like a finer grained memory type >> system and page boundaries. >> >> Best regards >> >> Heinrich >> >> > >> > This is all quite subtle and probably worthy of a VC discussion. >> > >> >> >> >> But that also raised the more general problem, and why we need a >> >> persistent reservation list, of allowing boards/SoCs to say they want to >> >> reserve a block of memory for whatever, and have that obeyed, for real. >> >> For example, the mach-apple logic of "just pick some memory locations to >> >> use for kernel/dtb/initrd" isn't really as safe as it should be since >> >> those reservations aren't really seen anywhere once the function >> >> returns, it's just setting some environment variables. >> > >> > Yes, that part of it I understand. Somehow I either didn't see or >> > forgot that board_late_init() code. With the script-based boot it >> > makes some sort of sense, but with bootstd we should have allocation >> > of addresses dealt with there. I have held off on retiring >> > kernel_addr_r etc. as the scripts are still in use. But perhaps it >> > would be a good time to convert bootstd to use lmb instead? >> > >> > Regards, >> > Simon >> ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 20:11 ` Heinrich Schuchardt @ 2024-06-14 5:58 ` Ilias Apalodimas 2024-06-19 3:01 ` Simon Glass 2024-06-19 3:03 ` Simon Glass 1 sibling, 1 reply; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-14 5:58 UTC (permalink / raw) To: Heinrich Schuchardt, Simon Glass Cc: Sughosh Ganu, u-boot, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini On Thu, 13 Jun 2024 at 23:11, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > Am 13. Juni 2024 21:05:58 MESZ schrieb Simon Glass <sjg@chromium.org>: > >Hi Heinrich, > > > >On Thu, 13 Jun 2024 at 11:32, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > >> > >> On 13.06.24 18:59, Simon Glass wrote: > >> > Hi Tom, > >> > > >> > On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: > >> >> > >> >> On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: > >> >>> Hi Tom, > >> >>> > >> >>> On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > >> >>>> > >> >>>> On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > >> >>>>> Hi Tom, > >> >>>>> > >> >>>>> On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > >> >>>>>> > >> >>>>>> On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > >> >>>>>> > >> >>>>>> [snip] > >> >>>>>>> Also IMO there is only really one LMB list today. We create it at the > >> >>>>>>> start of bootm and then it is done when we boot. The file-loading > >> >>>>>>> stuff is what makes all this confusing...and with bootstd that is > >> >>>>>>> under control as well. > >> >>>>>>> > >> >>>>>>> At lot of this effort seems to be about dealing with random scripts > >> >>>>>>> which load things. We want to make sure we complain if something > >> >>>>>>> overlaps. But we should be making the bootstd case work nicely and > >> >>>>>>> doing things within that framework. Also EFI sort-of has its own > >> >>>>>>> thing, which it is very-much in control of. > >> >>>>>>> > >> >>>>>>> Overall I think this is a bit more subtle that just combining allocators. > >> >>>>>> > >> >>>>>> I think this gets to the main misunderstanding. The problem isn't > >> >>>>>> handling bootstd, or EFI boot, or even assorted scripts. Those are all > >> >>>>>> cases where things are otherwise (sufficiently) well-defined. The > >> >>>>>> problem is "security" and that a "carefully crafted payload" could do > >> >>>>>> something malicious. That's why we have to do all of this stuff sooner > >> >>>>>> rather than later in our boot process. > >> >>>>> > >> >>>>> That's the first I have heard of this, actually, but a bit more detail > >> >>>>> would help. How does the payload get loaded? I'm just not sure about > >> >>>>> the overall goals. It seems that everyone else is already familiar - > >> >>>>> can someone please take the time to point me to the details? > >> >>>> > >> >>>> Well, the short version I believe of the first CVE we got (and so > >> >>>> started abusing LMB) was along the lines of "load an image near where > >> >>>> the U-Boot stack is, smash things for fun and exploits". > >> >>> > >> >>> OK. I am surprised that LMB does not catch that. It is supposed to add > >> >>> the stack and various other things right at the start before loading > >> >>> any file. So even if it clears the LMB each time, it should not be > >> >>> able to do that. Having said this, the code may be buggy as I don't > >> >>> think we have tests for U-Boot's overall functional behaviour in these > >> >>> situations. > >> >> > >> >> Right, LMB does catch the example I gave (because we made all of the > >> >> load from storage/network functions init an lmb and we always make sure > >> >> a new lmb gets U-Boot stack/etc). The next thing we didn't catch was > >> >> "what if EFI does the loading?" and we've kludged around that, and in > >> >> turn had some of the thorny questions. Some of that is what I think > >> >> you're asking about in this part of the thread, to which the answer is > >> >> "EFI spec says you need to place X in memory", so we just need to > >> >> reserve it when it's asked for, so that something else can't come along > >> >> and smash it maliciously. > >> > > >> > OK I see. Of course it isn't just EFI that has this issue. I believe > >> > the answer (for small blocks) is to use malloc(), which I think we do > >> > with a few exceptions which Ilias pointed out. For things like the TPM > >> > log and ACPI tables we should probably use a bloblist, as we do on > >> > x86. For large things (like loading a kernel) we should use LMB. I've > >> > been thinking about how best to tie this to boot, as opposed to random > >> > allocations in U-Boot itself, which would lead to fragmentation and > >> > strange behaviour. I think bootstd is a great place to have a > >> > persistent LMB. It can be attached to bootstd_priv. > >> > > >> > My hope is that EFI is just another boot method, where > >> > already-allocating things are presented to the OS. Apart from the > >> > Ilias exceptions, I believe this is how it works today. > >> > > >> > Where I think this heads in the wrong direction is using > >> > EFI-allocation functions before we are booting an EFI image. EFI has > >> > no concept of what is 'in empty space' so it leads to the lmb > >> > conflict, the subject of this discussion. > >> > >> EFI binaries can return to the command line interface. > >> EFI binaries may be drivers that stay resident and run in the background > >> after returning to the command line interface. They might for instance > >> provide block devices. > > > >Hmm you mentioned that before but I'm still not quite understanding. > >Do you mean that the EFI app returns back to U-Boot, leaving the > > There are 3 types of of EFI binaries: > > * apps > * boot time drivers > * run time drivers > > > >driver active? If so, how does U-Boot use the driver? I'm just not > >familiar with how such a construct could work in a single-threaded > >U-Boot. > > We already have code for EFI block devices. See lib/efi_driver/ > > When U-Boot reads from such a block device it may end up in an EFI driver that for instance uses U-Boots network drivers exposed as EFI simple network protocol to read from an NVMEoF or iSCSI server. > > > > >> > >> Device-paths must be created from EFI pool memory as they may be freed > >> via FreePool() according to the EFI specification. And these we create > >> whenever a block-device is probed. > > > >The implementation of pool memory rounds up to pages and uses that. It > >might be more efficient to use malloc()/free() instead, given that we > >mark the malloc() space as reserved when we call the EFI app. > > We have requirements on which EFI allocations may reside in the same page. See the ARM chapter in the UEFI specification. And apart from all Heinrich mentioned, EFI memory has to be marked and preserved at runtime for runtime services and data. Using malloc for the variables, the eventlog etc, would just complicate the EFI code, as we'd have to copy those just before ExitBootServices is called. Thanks /Ilias > > Best regards > > Heinrich > > > > >> > >> We should not make any assumptions that conflict with the UEFI > >> specification. > > > >Indeed. > > > >> > >> In our initial discussion with Ilias one idea was to merge LMB and EFI > >> memory management. This merged system would have to consider the > >> requirements of the UEFI specifications like a finer grained memory type > >> system and page boundaries. > >> > >> Best regards > >> > >> Heinrich > >> > >> > > >> > This is all quite subtle and probably worthy of a VC discussion. > >> > > >> >> > >> >> But that also raised the more general problem, and why we need a > >> >> persistent reservation list, of allowing boards/SoCs to say they want to > >> >> reserve a block of memory for whatever, and have that obeyed, for real. > >> >> For example, the mach-apple logic of "just pick some memory locations to > >> >> use for kernel/dtb/initrd" isn't really as safe as it should be since > >> >> those reservations aren't really seen anywhere once the function > >> >> returns, it's just setting some environment variables. > >> > > >> > Yes, that part of it I understand. Somehow I either didn't see or > >> > forgot that board_late_init() code. With the script-based boot it > >> > makes some sort of sense, but with bootstd we should have allocation > >> > of addresses dealt with there. I have held off on retiring > >> > kernel_addr_r etc. as the scripts are still in use. But perhaps it > >> > would be a good time to convert bootstd to use lmb instead? > >> > > >> > Regards, > >> > Simon > >> ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-14 5:58 ` Ilias Apalodimas @ 2024-06-19 3:01 ` Simon Glass 0 siblings, 0 replies; 127+ messages in thread From: Simon Glass @ 2024-06-19 3:01 UTC (permalink / raw) To: Ilias Apalodimas Cc: Heinrich Schuchardt, Sughosh Ganu, u-boot, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini Hi Ilias, On Thu, 13 Jun 2024 at 23:58, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > On Thu, 13 Jun 2024 at 23:11, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > > > > > Am 13. Juni 2024 21:05:58 MESZ schrieb Simon Glass <sjg@chromium.org>: > > >Hi Heinrich, > > > > > >On Thu, 13 Jun 2024 at 11:32, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > >> > > >> On 13.06.24 18:59, Simon Glass wrote: > > >> > Hi Tom, > > >> > > > >> > On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: > > >> >> > > >> >> On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: > > >> >>> Hi Tom, > > >> >>> > > >> >>> On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > > >> >>>> > > >> >>>> On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > > >> >>>>> Hi Tom, > > >> >>>>> > > >> >>>>> On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > > >> >>>>>> > > >> >>>>>> On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > > >> >>>>>> > > >> >>>>>> [snip] > > >> >>>>>>> Also IMO there is only really one LMB list today. We create it at the > > >> >>>>>>> start of bootm and then it is done when we boot. The file-loading > > >> >>>>>>> stuff is what makes all this confusing...and with bootstd that is > > >> >>>>>>> under control as well. > > >> >>>>>>> > > >> >>>>>>> At lot of this effort seems to be about dealing with random scripts > > >> >>>>>>> which load things. We want to make sure we complain if something > > >> >>>>>>> overlaps. But we should be making the bootstd case work nicely and > > >> >>>>>>> doing things within that framework. Also EFI sort-of has its own > > >> >>>>>>> thing, which it is very-much in control of. > > >> >>>>>>> > > >> >>>>>>> Overall I think this is a bit more subtle that just combining allocators. > > >> >>>>>> > > >> >>>>>> I think this gets to the main misunderstanding. The problem isn't > > >> >>>>>> handling bootstd, or EFI boot, or even assorted scripts. Those are all > > >> >>>>>> cases where things are otherwise (sufficiently) well-defined. The > > >> >>>>>> problem is "security" and that a "carefully crafted payload" could do > > >> >>>>>> something malicious. That's why we have to do all of this stuff sooner > > >> >>>>>> rather than later in our boot process. > > >> >>>>> > > >> >>>>> That's the first I have heard of this, actually, but a bit more detail > > >> >>>>> would help. How does the payload get loaded? I'm just not sure about > > >> >>>>> the overall goals. It seems that everyone else is already familiar - > > >> >>>>> can someone please take the time to point me to the details? > > >> >>>> > > >> >>>> Well, the short version I believe of the first CVE we got (and so > > >> >>>> started abusing LMB) was along the lines of "load an image near where > > >> >>>> the U-Boot stack is, smash things for fun and exploits". > > >> >>> > > >> >>> OK. I am surprised that LMB does not catch that. It is supposed to add > > >> >>> the stack and various other things right at the start before loading > > >> >>> any file. So even if it clears the LMB each time, it should not be > > >> >>> able to do that. Having said this, the code may be buggy as I don't > > >> >>> think we have tests for U-Boot's overall functional behaviour in these > > >> >>> situations. > > >> >> > > >> >> Right, LMB does catch the example I gave (because we made all of the > > >> >> load from storage/network functions init an lmb and we always make sure > > >> >> a new lmb gets U-Boot stack/etc). The next thing we didn't catch was > > >> >> "what if EFI does the loading?" and we've kludged around that, and in > > >> >> turn had some of the thorny questions. Some of that is what I think > > >> >> you're asking about in this part of the thread, to which the answer is > > >> >> "EFI spec says you need to place X in memory", so we just need to > > >> >> reserve it when it's asked for, so that something else can't come along > > >> >> and smash it maliciously. > > >> > > > >> > OK I see. Of course it isn't just EFI that has this issue. I believe > > >> > the answer (for small blocks) is to use malloc(), which I think we do > > >> > with a few exceptions which Ilias pointed out. For things like the TPM > > >> > log and ACPI tables we should probably use a bloblist, as we do on > > >> > x86. For large things (like loading a kernel) we should use LMB. I've > > >> > been thinking about how best to tie this to boot, as opposed to random > > >> > allocations in U-Boot itself, which would lead to fragmentation and > > >> > strange behaviour. I think bootstd is a great place to have a > > >> > persistent LMB. It can be attached to bootstd_priv. > > >> > > > >> > My hope is that EFI is just another boot method, where > > >> > already-allocating things are presented to the OS. Apart from the > > >> > Ilias exceptions, I believe this is how it works today. > > >> > > > >> > Where I think this heads in the wrong direction is using > > >> > EFI-allocation functions before we are booting an EFI image. EFI has > > >> > no concept of what is 'in empty space' so it leads to the lmb > > >> > conflict, the subject of this discussion. > > >> > > >> EFI binaries can return to the command line interface. > > >> EFI binaries may be drivers that stay resident and run in the background > > >> after returning to the command line interface. They might for instance > > >> provide block devices. > > > > > >Hmm you mentioned that before but I'm still not quite understanding. > > >Do you mean that the EFI app returns back to U-Boot, leaving the > > > > There are 3 types of of EFI binaries: > > > > * apps > > * boot time drivers > > * run time drivers > > > > > > >driver active? If so, how does U-Boot use the driver? I'm just not > > >familiar with how such a construct could work in a single-threaded > > >U-Boot. > > > > We already have code for EFI block devices. See lib/efi_driver/ > > > > When U-Boot reads from such a block device it may end up in an EFI driver that for instance uses U-Boots network drivers exposed as EFI simple network protocol to read from an NVMEoF or iSCSI server. > > > > > > > >> > > >> Device-paths must be created from EFI pool memory as they may be freed > > >> via FreePool() according to the EFI specification. And these we create > > >> whenever a block-device is probed. > > > > > >The implementation of pool memory rounds up to pages and uses that. It > > >might be more efficient to use malloc()/free() instead, given that we > > >mark the malloc() space as reserved when we call the EFI app. > > > > We have requirements on which EFI allocations may reside in the same page. See the ARM chapter in the UEFI specification. > > And apart from all Heinrich mentioned, EFI memory has to be marked and > preserved at runtime for runtime services and data. > Using malloc for the variables, the eventlog etc, would just > complicate the EFI code, as we'd have to copy those just before > ExitBootServices is called. Since malloc() is marked as boot-time memory, you can just leave them where they are. Lots of things are in the malloc() region anyway. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 20:11 ` Heinrich Schuchardt 2024-06-14 5:58 ` Ilias Apalodimas @ 2024-06-19 3:03 ` Simon Glass 1 sibling, 0 replies; 127+ messages in thread From: Simon Glass @ 2024-06-19 3:03 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini Hi Heinrich, On Thu, 13 Jun 2024 at 14:16, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > Am 13. Juni 2024 21:05:58 MESZ schrieb Simon Glass <sjg@chromium.org>: > >Hi Heinrich, > > > >On Thu, 13 Jun 2024 at 11:32, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > >> > >> On 13.06.24 18:59, Simon Glass wrote: > >> > Hi Tom, > >> > > >> > On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: > >> >> > >> >> On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: > >> >>> Hi Tom, > >> >>> > >> >>> On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > >> >>>> > >> >>>> On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > >> >>>>> Hi Tom, > >> >>>>> > >> >>>>> On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > >> >>>>>> > >> >>>>>> On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > >> >>>>>> > >> >>>>>> [snip] > >> >>>>>>> Also IMO there is only really one LMB list today. We create it at the > >> >>>>>>> start of bootm and then it is done when we boot. The file-loading > >> >>>>>>> stuff is what makes all this confusing...and with bootstd that is > >> >>>>>>> under control as well. > >> >>>>>>> > >> >>>>>>> At lot of this effort seems to be about dealing with random scripts > >> >>>>>>> which load things. We want to make sure we complain if something > >> >>>>>>> overlaps. But we should be making the bootstd case work nicely and > >> >>>>>>> doing things within that framework. Also EFI sort-of has its own > >> >>>>>>> thing, which it is very-much in control of. > >> >>>>>>> > >> >>>>>>> Overall I think this is a bit more subtle that just combining allocators. > >> >>>>>> > >> >>>>>> I think this gets to the main misunderstanding. The problem isn't > >> >>>>>> handling bootstd, or EFI boot, or even assorted scripts. Those are all > >> >>>>>> cases where things are otherwise (sufficiently) well-defined. The > >> >>>>>> problem is "security" and that a "carefully crafted payload" could do > >> >>>>>> something malicious. That's why we have to do all of this stuff sooner > >> >>>>>> rather than later in our boot process. > >> >>>>> > >> >>>>> That's the first I have heard of this, actually, but a bit more detail > >> >>>>> would help. How does the payload get loaded? I'm just not sure about > >> >>>>> the overall goals. It seems that everyone else is already familiar - > >> >>>>> can someone please take the time to point me to the details? > >> >>>> > >> >>>> Well, the short version I believe of the first CVE we got (and so > >> >>>> started abusing LMB) was along the lines of "load an image near where > >> >>>> the U-Boot stack is, smash things for fun and exploits". > >> >>> > >> >>> OK. I am surprised that LMB does not catch that. It is supposed to add > >> >>> the stack and various other things right at the start before loading > >> >>> any file. So even if it clears the LMB each time, it should not be > >> >>> able to do that. Having said this, the code may be buggy as I don't > >> >>> think we have tests for U-Boot's overall functional behaviour in these > >> >>> situations. > >> >> > >> >> Right, LMB does catch the example I gave (because we made all of the > >> >> load from storage/network functions init an lmb and we always make sure > >> >> a new lmb gets U-Boot stack/etc). The next thing we didn't catch was > >> >> "what if EFI does the loading?" and we've kludged around that, and in > >> >> turn had some of the thorny questions. Some of that is what I think > >> >> you're asking about in this part of the thread, to which the answer is > >> >> "EFI spec says you need to place X in memory", so we just need to > >> >> reserve it when it's asked for, so that something else can't come along > >> >> and smash it maliciously. > >> > > >> > OK I see. Of course it isn't just EFI that has this issue. I believe > >> > the answer (for small blocks) is to use malloc(), which I think we do > >> > with a few exceptions which Ilias pointed out. For things like the TPM > >> > log and ACPI tables we should probably use a bloblist, as we do on > >> > x86. For large things (like loading a kernel) we should use LMB. I've > >> > been thinking about how best to tie this to boot, as opposed to random > >> > allocations in U-Boot itself, which would lead to fragmentation and > >> > strange behaviour. I think bootstd is a great place to have a > >> > persistent LMB. It can be attached to bootstd_priv. > >> > > >> > My hope is that EFI is just another boot method, where > >> > already-allocating things are presented to the OS. Apart from the > >> > Ilias exceptions, I believe this is how it works today. > >> > > >> > Where I think this heads in the wrong direction is using > >> > EFI-allocation functions before we are booting an EFI image. EFI has > >> > no concept of what is 'in empty space' so it leads to the lmb > >> > conflict, the subject of this discussion. > >> > >> EFI binaries can return to the command line interface. > >> EFI binaries may be drivers that stay resident and run in the background > >> after returning to the command line interface. They might for instance > >> provide block devices. > > > >Hmm you mentioned that before but I'm still not quite understanding. > >Do you mean that the EFI app returns back to U-Boot, leaving the > > There are 3 types of of EFI binaries: > > * apps > * boot time drivers > * run time drivers > > > >driver active? If so, how does U-Boot use the driver? I'm just not > >familiar with how such a construct could work in a single-threaded > >U-Boot. > > We already have code for EFI block devices. See lib/efi_driver/ > > When U-Boot reads from such a block device it may end up in an EFI driver that for instance uses U-Boots network drivers exposed as EFI simple network protocol to read from an NVMEoF or iSCSI server. Sure, but this is running on the same CPU / thread, right? There isn't anything actually complicated about that. > > > > >> > >> Device-paths must be created from EFI pool memory as they may be freed > >> via FreePool() according to the EFI specification. And these we create > >> whenever a block-device is probed. > > > >The implementation of pool memory rounds up to pages and uses that. It > >might be more efficient to use malloc()/free() instead, given that we > >mark the malloc() space as reserved when we call the EFI app. > > We have requirements on which EFI allocations may reside in the same page. See the ARM chapter in the UEFI specification. I don't believe the pool allocator allows that, though...not that I am an expert on this. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable 2024-06-13 16:59 ` Simon Glass 2024-06-13 17:27 ` Heinrich Schuchardt @ 2024-06-13 20:06 ` Tom Rini 1 sibling, 0 replies; 127+ messages in thread From: Tom Rini @ 2024-06-13 20:06 UTC (permalink / raw) To: Simon Glass Cc: Sughosh Ganu, u-boot, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 6775 bytes --] On Thu, Jun 13, 2024 at 10:59:48AM -0600, Simon Glass wrote: > Hi Tom, > > On Thu, 13 Jun 2024 at 09:42, Tom Rini <trini@konsulko.com> wrote: > > > > On Thu, Jun 13, 2024 at 09:22:15AM -0600, Simon Glass wrote: > > > Hi Tom, > > > > > > On Wed, 12 Jun 2024 at 15:40, Tom Rini <trini@konsulko.com> wrote: > > > > > > > > On Wed, Jun 12, 2024 at 02:24:25PM -0600, Simon Glass wrote: > > > > > Hi Tom, > > > > > > > > > > On Wed, 12 Jun 2024 at 11:22, Tom Rini <trini@konsulko.com> wrote: > > > > > > > > > > > > On Tue, Jun 11, 2024 at 08:41:39PM -0600, Simon Glass wrote: > > > > > > > > > > > > [snip] > > > > > > > Also IMO there is only really one LMB list today. We create it at the > > > > > > > start of bootm and then it is done when we boot. The file-loading > > > > > > > stuff is what makes all this confusing...and with bootstd that is > > > > > > > under control as well. > > > > > > > > > > > > > > At lot of this effort seems to be about dealing with random scripts > > > > > > > which load things. We want to make sure we complain if something > > > > > > > overlaps. But we should be making the bootstd case work nicely and > > > > > > > doing things within that framework. Also EFI sort-of has its own > > > > > > > thing, which it is very-much in control of. > > > > > > > > > > > > > > Overall I think this is a bit more subtle that just combining allocators. > > > > > > > > > > > > I think this gets to the main misunderstanding. The problem isn't > > > > > > handling bootstd, or EFI boot, or even assorted scripts. Those are all > > > > > > cases where things are otherwise (sufficiently) well-defined. The > > > > > > problem is "security" and that a "carefully crafted payload" could do > > > > > > something malicious. That's why we have to do all of this stuff sooner > > > > > > rather than later in our boot process. > > > > > > > > > > That's the first I have heard of this, actually, but a bit more detail > > > > > would help. How does the payload get loaded? I'm just not sure about > > > > > the overall goals. It seems that everyone else is already familiar - > > > > > can someone please take the time to point me to the details? > > > > > > > > Well, the short version I believe of the first CVE we got (and so > > > > started abusing LMB) was along the lines of "load an image near where > > > > the U-Boot stack is, smash things for fun and exploits". > > > > > > OK. I am surprised that LMB does not catch that. It is supposed to add > > > the stack and various other things right at the start before loading > > > any file. So even if it clears the LMB each time, it should not be > > > able to do that. Having said this, the code may be buggy as I don't > > > think we have tests for U-Boot's overall functional behaviour in these > > > situations. > > > > Right, LMB does catch the example I gave (because we made all of the > > load from storage/network functions init an lmb and we always make sure > > a new lmb gets U-Boot stack/etc). The next thing we didn't catch was > > "what if EFI does the loading?" and we've kludged around that, and in > > turn had some of the thorny questions. Some of that is what I think > > you're asking about in this part of the thread, to which the answer is > > "EFI spec says you need to place X in memory", so we just need to > > reserve it when it's asked for, so that something else can't come along > > and smash it maliciously. > > OK I see. Of course it isn't just EFI that has this issue. I believe > the answer (for small blocks) is to use malloc(), which I think we do > with a few exceptions which Ilias pointed out. For things like the TPM > log and ACPI tables we should probably use a bloblist, as we do on > x86. For large things (like loading a kernel) we should use LMB. I've > been thinking about how best to tie this to boot, as opposed to random > allocations in U-Boot itself, which would lead to fragmentation and > strange behaviour. I think bootstd is a great place to have a > persistent LMB. It can be attached to bootstd_priv. > > My hope is that EFI is just another boot method, where > already-allocating things are presented to the OS. Apart from the > Ilias exceptions, I believe this is how it works today. > > Where I think this heads in the wrong direction is using > EFI-allocation functions before we are booting an EFI image. EFI has > no concept of what is 'in empty space' so it leads to the lmb > conflict, the subject of this discussion. > > This is all quite subtle and probably worthy of a VC discussion. But it's not tied to "boot". Again, the problems are with potential malicious actions. So if we're in some function that says "I need to claim $THIS range", it needs check in with the reservation system so that it can be told "Sorry, already reserved" if needed. It's not a good idea for $subsystem to say it needs $THIS range, but then we don't make the reservation until later because someone could have acted in there in the interim. I see there's been further discussion between you/Heinrich/Sughosh and I'll otherwise leave it until the next iteration, but I want to be clear that I see it as important that when something says it needs $THIS range, we put it in the reservation system. > > But that also raised the more general problem, and why we need a > > persistent reservation list, of allowing boards/SoCs to say they want to > > reserve a block of memory for whatever, and have that obeyed, for real. > > For example, the mach-apple logic of "just pick some memory locations to > > use for kernel/dtb/initrd" isn't really as safe as it should be since > > those reservations aren't really seen anywhere once the function > > returns, it's just setting some environment variables. > > Yes, that part of it I understand. Somehow I either didn't see or > forgot that board_late_init() code. With the script-based boot it > makes some sort of sense, but with bootstd we should have allocation > of addresses dealt with there. I have held off on retiring > kernel_addr_r etc. as the scripts are still in use. But perhaps it > would be a good time to convert bootstd to use lmb instead? I'm not sure I follow you. It's already using lmb since that's been part of the normal OS boot flow since forever? If you mean make it easier to let the system just pick where to load stuff in to memory for you, yes, that mach-apple functionality would be a handy fallback/default. Especially if done in concert with double checking on what needs to be done to minimize copying data around and around and around in boot before we start the OS, since that's where much of the hard part of deciding addresses is. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 05/31] lmb: pass a flag to image_setup_libfdt() for lmb reservations 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (3 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 17:12 ` Tom Rini 2024-06-07 18:52 ` [RFC PATCH 06/31] lmb: reserve and add common memory regions post relocation Sughosh Ganu ` (27 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The image_setup_libfdt() function optionally calls the LMB API to reserve the region of memory occupied by the FDT blob. This was earlier determined through the presence of the pointer to the lmb structure, which is no longer present. Pass a flag to the image_setup_libfdt() function to indicate if the region occupied by the FDT blob is to be marked as reserved by the LMB module. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- arch/mips/lib/bootm.c | 2 +- boot/image-board.c | 2 +- boot/image-fdt.c | 7 +++---- cmd/elf.c | 2 +- include/image.h | 5 ++--- lib/efi_loader/efi_dt_fixup.c | 2 +- lib/efi_loader/efi_helper.c | 2 +- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 54d89e9cca..e4fc2e589d 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -247,7 +247,7 @@ static int boot_setup_fdt(struct bootm_headers *images) images->initrd_start = virt_to_phys((void *)images->initrd_start); images->initrd_end = virt_to_phys((void *)images->initrd_end); - return image_setup_libfdt(images, images->ft_addr, &images->lmb); + return image_setup_libfdt(images, images->ft_addr, 0); } static void boot_prep_linux(struct bootm_headers *images) diff --git a/boot/image-board.c b/boot/image-board.c index 89ccf80066..481b333b4c 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -897,7 +897,7 @@ int image_setup_linux(struct bootm_headers *images) } if (CONFIG_IS_ENABLED(OF_LIBFDT) && of_size) { - ret = image_setup_libfdt(images, *of_flat_tree, lmb); + ret = image_setup_libfdt(images, *of_flat_tree, 1); if (ret) return ret; } diff --git a/boot/image-fdt.c b/boot/image-fdt.c index 08afde203c..4daced9e99 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -567,8 +567,7 @@ __weak int arch_fixup_fdt(void *blob) return 0; } -int image_setup_libfdt(struct bootm_headers *images, void *blob, - struct lmb *lmb) +int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb) { ulong *initrd_start = &images->initrd_start; ulong *initrd_end = &images->initrd_end; @@ -668,7 +667,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, } /* Delete the old LMB reservation */ - if (lmb) + if (CONFIG_IS_ENABLED(LMB) && lmb) lmb_free(map_to_sysmem(blob), fdt_totalsize(blob)); ret = fdt_shrink_to_minimum(blob, 0); @@ -677,7 +676,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, of_size = ret; /* Create a new LMB reservation */ - if (lmb) + if (CONFIG_IS_ENABLED(LMB) && lmb) lmb_reserve(map_to_sysmem(blob), of_size); #if defined(CONFIG_ARCH_KEYSTONE) diff --git a/cmd/elf.c b/cmd/elf.c index df4354d374..00879de22b 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -89,7 +89,7 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) printf("## Setting up FDT at 0x%08lx ...\n", fdt_addr); flush(); - if (image_setup_libfdt(&img, (void *)fdt_addr, NULL)) + if (image_setup_libfdt(&img, (void *)fdt_addr, 0)) return 1; } #endif diff --git a/include/image.h b/include/image.h index 8c619030ee..92ebe25548 100644 --- a/include/image.h +++ b/include/image.h @@ -1018,11 +1018,10 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, * * @images: Images information * @blob: FDT to update - * @lmb: Points to logical memory block structure + * @lmb: Flag indicating use of lmb for reserving FDT memory region * Return: 0 if ok, <0 on failure */ -int image_setup_libfdt(struct bootm_headers *images, void *blob, - struct lmb *lmb); +int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb); /** * Set up the FDT to use for booting a kernel diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index 9886e6897c..4d50246c8f 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -172,7 +172,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, } fdt_set_totalsize(dtb, *buffer_size); - if (image_setup_libfdt(&img, dtb, NULL)) { + if (image_setup_libfdt(&img, dtb, 0)) { log_err("failed to process device tree\n"); ret = EFI_INVALID_PARAMETER; goto out; diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c index 73d0279e84..2d91f0edc3 100644 --- a/lib/efi_loader/efi_helper.c +++ b/lib/efi_loader/efi_helper.c @@ -469,7 +469,7 @@ efi_status_t efi_install_fdt(void *fdt) return EFI_OUT_OF_RESOURCES; } - if (image_setup_libfdt(&img, fdt, NULL)) { + if (image_setup_libfdt(&img, fdt, 0)) { log_err("ERROR: failed to process device tree\n"); return EFI_LOAD_ERROR; } -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 05/31] lmb: pass a flag to image_setup_libfdt() for lmb reservations 2024-06-07 18:52 ` [RFC PATCH 05/31] lmb: pass a flag to image_setup_libfdt() for lmb reservations Sughosh Ganu @ 2024-06-10 17:12 ` Tom Rini 0 siblings, 0 replies; 127+ messages in thread From: Tom Rini @ 2024-06-10 17:12 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 2520 bytes --] On Sat, Jun 08, 2024 at 12:22:14AM +0530, Sughosh Ganu wrote: > The image_setup_libfdt() function optionally calls the LMB API to > reserve the region of memory occupied by the FDT blob. This was > earlier determined through the presence of the pointer to the lmb > structure, which is no longer present. Pass a flag to the > image_setup_libfdt() function to indicate if the region occupied by > the FDT blob is to be marked as reserved by the LMB module. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> [snip] > --- > arch/mips/lib/bootm.c | 2 +- > boot/image-board.c | 2 +- > boot/image-fdt.c | 7 +++---- > cmd/elf.c | 2 +- > include/image.h | 5 ++--- > lib/efi_loader/efi_dt_fixup.c | 2 +- > lib/efi_loader/efi_helper.c | 2 +- > 7 files changed, 10 insertions(+), 12 deletions(-) > > diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c > index 54d89e9cca..e4fc2e589d 100644 > --- a/arch/mips/lib/bootm.c > +++ b/arch/mips/lib/bootm.c > @@ -247,7 +247,7 @@ static int boot_setup_fdt(struct bootm_headers *images) > images->initrd_start = virt_to_phys((void *)images->initrd_start); > images->initrd_end = virt_to_phys((void *)images->initrd_end); > > - return image_setup_libfdt(images, images->ft_addr, &images->lmb); > + return image_setup_libfdt(images, images->ft_addr, 0); > } > > static void boot_prep_linux(struct bootm_headers *images) > diff --git a/boot/image-board.c b/boot/image-board.c > index 89ccf80066..481b333b4c 100644 > --- a/boot/image-board.c > +++ b/boot/image-board.c > @@ -897,7 +897,7 @@ int image_setup_linux(struct bootm_headers *images) > } > > if (CONFIG_IS_ENABLED(OF_LIBFDT) && of_size) { > - ret = image_setup_libfdt(images, *of_flat_tree, lmb); > + ret = image_setup_libfdt(images, *of_flat_tree, 1); > if (ret) > return ret; > } > diff --git a/boot/image-fdt.c b/boot/image-fdt.c > index 08afde203c..4daced9e99 100644 > --- a/boot/image-fdt.c > +++ b/boot/image-fdt.c > @@ -567,8 +567,7 @@ __weak int arch_fixup_fdt(void *blob) > return 0; > } > > -int image_setup_libfdt(struct bootm_headers *images, void *blob, > - struct lmb *lmb) > +int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb) > { > ulong *initrd_start = &images->initrd_start; > ulong *initrd_end = &images->initrd_end; Since this is a bool, please use true/false in the callers. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 06/31] lmb: reserve and add common memory regions post relocation 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (4 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 05/31] lmb: pass a flag to image_setup_libfdt() for lmb reservations Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 17:30 ` Tom Rini 2024-06-07 18:52 ` [RFC PATCH 07/31] lmb: remove lmb_init_and_reserve_range() function Sughosh Ganu ` (26 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The LMB module provides API's for allocating chunks of memory. The LMB module should not be allocating memory regions that are in use, or that might be occupied by the U-Boot image. Prevent allocations of memory areas used by the U-Boot image by reserving these regions once U-Boot has been relocated. Also add the rest of the memory that is available for allocations to the LMB's memory map. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- common/board_r.c | 15 +++++++++++++++ include/lmb.h | 14 ++++++++++++++ lib/lmb.c | 14 +++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/common/board_r.c b/common/board_r.c index da0b80f24f..a9f0b0cec1 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -22,6 +22,7 @@ #include <hang.h> #include <image.h> #include <irq_func.h> +#include <lmb.h> #include <log.h> #include <net.h> #include <asm/cache.h> @@ -555,6 +556,17 @@ static int run_main_loop(void) return 0; } +#if defined(CONFIG_LMB) +static int initr_lmb(void) +{ + lmb_reserve_common((void *)gd->fdt_blob); + + lmb_add_memory(gd->bd); + + return 0; +} +#endif + /* * Over time we hope to remove these functions with code fragments and * stub functions, and instead call the relevant function directly. @@ -613,6 +625,9 @@ static init_fnc_t init_sequence_r[] = { #endif #ifdef CONFIG_EFI_LOADER efi_memory_init, +#endif +#if defined(CONFIG_LMB) + initr_lmb, #endif initr_binman, #ifdef CONFIG_FSP_VERSION2 diff --git a/include/lmb.h b/include/lmb.h index 8f8a32c2ca..d2b829ace1 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -125,6 +125,20 @@ void board_lmb_reserve(void); void arch_lmb_reserve(void); void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align); +/** + * lmb_reserve_common() - Reserve memory region occupied by U-Boot image + * @fdt_blob: pointer to the FDT blob + * + * Reserve common areas of memory that are occupied by the U-Boot image. + * This function gets called once U-Boot has been relocated, so that any + * request for memory allocations would not touch memory region occupied + * by the U-Boot image, heap, bss etc. + * + * Return: None + * + */ +void lmb_reserve_common(void *fdt_blob); + #endif /* __KERNEL__ */ #endif /* _LINUX_LMB_H */ diff --git a/lib/lmb.c b/lib/lmb.c index b0c9e2ef30..8003aae6f7 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -216,7 +216,19 @@ static __maybe_unused int efi_lmb_reserve(void) return 0; } -static void lmb_reserve_common(void *fdt_blob) +/** + * lmb_reserve_common() - Reserve memory region occupied by U-Boot image + * @fdt_blob: pointer to the FDT blob + * + * Reserve common areas of memory that are occupied by the U-Boot image. + * This function gets called once U-Boot has been relocated, so that any + * request for memory allocations would not touch memory region occupied + * by the U-Boot image, heap, bss etc. + * + * Return: None + * + */ +void lmb_reserve_common(void *fdt_blob) { arch_lmb_reserve(); board_lmb_reserve(); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 06/31] lmb: reserve and add common memory regions post relocation 2024-06-07 18:52 ` [RFC PATCH 06/31] lmb: reserve and add common memory regions post relocation Sughosh Ganu @ 2024-06-10 17:30 ` Tom Rini 0 siblings, 0 replies; 127+ messages in thread From: Tom Rini @ 2024-06-10 17:30 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 595 bytes --] On Sat, Jun 08, 2024 at 12:22:15AM +0530, Sughosh Ganu wrote: > The LMB module provides API's for allocating chunks of memory. The LMB > module should not be allocating memory regions that are in use, or > that might be occupied by the U-Boot image. Prevent allocations of > memory areas used by the U-Boot image by reserving these regions once > U-Boot has been relocated. Also add the rest of the memory that is > available for allocations to the LMB's memory map. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> Reviewed-by: Tom Rini <trini@konsulko.com> -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 07/31] lmb: remove lmb_init_and_reserve_range() function 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (5 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 06/31] lmb: reserve and add common memory regions post relocation Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 17:30 ` Tom Rini 2024-06-10 21:42 ` Ilias Apalodimas 2024-06-07 18:52 ` [RFC PATCH 08/31] lmb: replcace the lmb_init_and_reserve() function Sughosh Ganu ` (25 subsequent siblings) 32 siblings, 2 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu With the move to make the LMB allocations persistent and the common memory regions being reserved during board init, the lmb_init_and_reserve_range() API can be replaced with a simple lmb_add() call. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- boot/bootm.c | 2 +- include/lmb.h | 2 -- lib/lmb.c | 8 -------- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/boot/bootm.c b/boot/bootm.c index cd1003120c..73e72a710d 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -248,7 +248,7 @@ static void boot_start_lmb(void) mem_start = env_get_bootm_low(); mem_size = env_get_bootm_size(); - lmb_init_and_reserve_range(mem_start, mem_size, NULL); + lmb_add(mem_start, mem_size); } #else #define lmb_reserve(base, size) diff --git a/include/lmb.h b/include/lmb.h index d2b829ace1..f3e3f716e5 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -85,8 +85,6 @@ struct lmb { }; void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob); -void lmb_init_and_reserve_range(phys_addr_t base, phys_size_t size, - void *fdt_blob); long lmb_add(phys_addr_t base, phys_size_t size); long lmb_reserve(phys_addr_t base, phys_size_t size); /** diff --git a/lib/lmb.c b/lib/lmb.c index 8003aae6f7..5c056800c3 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -253,14 +253,6 @@ void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob) lmb_reserve_common(fdt_blob); } -/* Initialize the struct, add memory and call arch/board reserve functions */ -void lmb_init_and_reserve_range(phys_addr_t base, phys_size_t size, - void *fdt_blob) -{ - lmb_add(base, size); - lmb_reserve_common(fdt_blob); -} - /* This routine called with relocation disabled. */ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, phys_size_t size, enum lmb_flags flags) -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 07/31] lmb: remove lmb_init_and_reserve_range() function 2024-06-07 18:52 ` [RFC PATCH 07/31] lmb: remove lmb_init_and_reserve_range() function Sughosh Ganu @ 2024-06-10 17:30 ` Tom Rini 2024-06-10 21:42 ` Ilias Apalodimas 1 sibling, 0 replies; 127+ messages in thread From: Tom Rini @ 2024-06-10 17:30 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 396 bytes --] On Sat, Jun 08, 2024 at 12:22:16AM +0530, Sughosh Ganu wrote: > With the move to make the LMB allocations persistent and the common > memory regions being reserved during board init, the > lmb_init_and_reserve_range() API can be replaced with a simple > lmb_add() call. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> Reviewed-by: Tom Rini <trini@konsulko.com> -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 07/31] lmb: remove lmb_init_and_reserve_range() function 2024-06-07 18:52 ` [RFC PATCH 07/31] lmb: remove lmb_init_and_reserve_range() function Sughosh Ganu 2024-06-10 17:30 ` Tom Rini @ 2024-06-10 21:42 ` Ilias Apalodimas 1 sibling, 0 replies; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 21:42 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Sat, Jun 08, 2024 at 12:22:16AM +0530, Sughosh Ganu wrote: > With the move to make the LMB allocations persistent and the common > memory regions being reserved during board init, the > lmb_init_and_reserve_range() API can be replaced with a simple > lmb_add() call. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > boot/bootm.c | 2 +- > include/lmb.h | 2 -- > lib/lmb.c | 8 -------- > 3 files changed, 1 insertion(+), 11 deletions(-) > > diff --git a/boot/bootm.c b/boot/bootm.c > index cd1003120c..73e72a710d 100644 > --- a/boot/bootm.c > +++ b/boot/bootm.c > @@ -248,7 +248,7 @@ static void boot_start_lmb(void) > mem_start = env_get_bootm_low(); > mem_size = env_get_bootm_size(); > > - lmb_init_and_reserve_range(mem_start, mem_size, NULL); > + lmb_add(mem_start, mem_size); > } > #else > #define lmb_reserve(base, size) > diff --git a/include/lmb.h b/include/lmb.h > index d2b829ace1..f3e3f716e5 100644 > --- a/include/lmb.h > +++ b/include/lmb.h > @@ -85,8 +85,6 @@ struct lmb { > }; > > void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob); > -void lmb_init_and_reserve_range(phys_addr_t base, phys_size_t size, > - void *fdt_blob); > long lmb_add(phys_addr_t base, phys_size_t size); > long lmb_reserve(phys_addr_t base, phys_size_t size); > /** > diff --git a/lib/lmb.c b/lib/lmb.c > index 8003aae6f7..5c056800c3 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -253,14 +253,6 @@ void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob) > lmb_reserve_common(fdt_blob); > } > > -/* Initialize the struct, add memory and call arch/board reserve functions */ > -void lmb_init_and_reserve_range(phys_addr_t base, phys_size_t size, > - void *fdt_blob) > -{ > - lmb_add(base, size); > - lmb_reserve_common(fdt_blob); > -} > - > /* This routine called with relocation disabled. */ > static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > phys_size_t size, enum lmb_flags flags) > -- > 2.34.1 > Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 08/31] lmb: replcace the lmb_init_and_reserve() function 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (6 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 07/31] lmb: remove lmb_init_and_reserve_range() function Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 17:31 ` Tom Rini 2024-06-07 18:52 ` [RFC PATCH 09/31] lmb: allow for resizing lmb regions Sughosh Ganu ` (24 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu With the changes to make the Logical Memory Block(LMB) allocations persistent and with the common memory regions being reserved during board init, the lmb_init_and_reserve() API can be removed and replaced with a lmb_add_memory() API, which adds all the available memory to the LMB pool. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- arch/arm/mach-apple/board.c | 2 +- arch/arm/mach-snapdragon/board.c | 2 +- arch/arm/mach-stm32mp/stm32mp1/cpu.c | 2 +- cmd/bdinfo.c | 2 +- cmd/load.c | 2 +- fs/fs.c | 2 +- include/lmb.h | 12 +++++++++++- lib/lmb.c | 15 +++++++++++---- net/tftp.c | 2 +- net/wget.c | 2 +- test/cmd/bdinfo.c | 10 +--------- 11 files changed, 31 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index c877c7b94c..2e72d03edd 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -776,7 +776,7 @@ int board_late_init(void) { u32 status = 0; - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_add_memory(gd->bd); /* somewhat based on the Linux Kernel boot requirements: * align by 2M and maximal FDT size 2M diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c index a63c8bec45..b3c9a21419 100644 --- a/arch/arm/mach-snapdragon/board.c +++ b/arch/arm/mach-snapdragon/board.c @@ -282,7 +282,7 @@ int board_late_init(void) { u32 status = 0; - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_add_memory(gd->bd); /* We need to be fairly conservative here as we support boards with just 1G of TOTAL RAM */ status |= env_set_hex("kernel_addr_r", addr_alloc(SZ_128M)); diff --git a/arch/arm/mach-stm32mp/stm32mp1/cpu.c b/arch/arm/mach-stm32mp/stm32mp1/cpu.c index a223297034..8e3f001f74 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/cpu.c +++ b/arch/arm/mach-stm32mp/stm32mp1/cpu.c @@ -143,7 +143,7 @@ int mach_cpu_init(void) void enable_caches(void) { /* parse device tree when data cache is still activated */ - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_add_memory(gd->bd); /* I-cache is already enabled in start.S: icache_enable() not needed */ diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index e08d3e2cf3..fc408e9820 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -163,7 +163,7 @@ static int bdinfo_print_all(struct bd_info *bd) bdinfo_print_num_l("multi_dtb_fit", (ulong)gd->multi_dtb_fit); #endif if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_add_memory(gd->bd); lmb_dump_all_force(); if (IS_ENABLED(CONFIG_OF_REAL)) printf("devicetree = %s\n", fdtdec_get_srcname()); diff --git a/cmd/load.c b/cmd/load.c index f019111991..9918523806 100644 --- a/cmd/load.c +++ b/cmd/load.c @@ -154,7 +154,7 @@ static ulong load_serial(long offset) int line_count = 0; long ret; - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_add_memory(gd->bd); while (read_record(record, SREC_MAXRECLEN + 1) >= 0) { type = srec_decode(record, &binlen, &addr, binbuf); diff --git a/fs/fs.c b/fs/fs.c index 3c54eaa366..f72d3962d1 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -549,7 +549,7 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, if (len && len < read_len) read_len = len; - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_add_memory(gd->bd); lmb_dump_all(); if (lmb_alloc_addr(addr, read_len) == addr) diff --git a/include/lmb.h b/include/lmb.h index f3e3f716e5..03bce2a50c 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -84,7 +84,17 @@ struct lmb { struct lmb_region reserved; }; -void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob); +/** + * lmb_add_memory() - Add memory range for LMB allocations + * @bd: pointer to board info structure + * + * Add the entire available memory range to the pool of memory that + * can be used by the LMB module for allocations. + * + * Return: None + * + */ +void lmb_add_memory(struct bd_info *bd); long lmb_add(phys_addr_t base, phys_size_t size); long lmb_reserve(phys_addr_t base, phys_size_t size); /** diff --git a/lib/lmb.c b/lib/lmb.c index 5c056800c3..de5a2cf23b 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -240,8 +240,17 @@ void lmb_reserve_common(void *fdt_blob) efi_lmb_reserve(); } -/* Initialize the struct, add memory and call arch/board reserve functions */ -void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob) +/** + * lmb_add_memory() - Add memory range for LMB allocations + * @bd: pointer to board info structure + * + * Add the entire available memory range to the pool of memory that + * can be used by the LMB module for allocations. + * + * Return: None + * + */ +void lmb_add_memory(struct bd_info *bd) { int i; @@ -249,8 +258,6 @@ void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob) if (bd->bi_dram[i].size) lmb_add(bd->bi_dram[i].start, bd->bi_dram[i].size); } - - lmb_reserve_common(fdt_blob); } /* This routine called with relocation disabled. */ diff --git a/net/tftp.c b/net/tftp.c index 02a5ca0f9f..54ac5e1262 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -714,7 +714,7 @@ static int tftp_init_load_addr(void) #ifdef CONFIG_LMB phys_size_t max_size; - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_add_memory(gd->bd); max_size = lmb_get_free_size(image_load_addr); if (!max_size) diff --git a/net/wget.c b/net/wget.c index dbdc519946..87f2f33c8a 100644 --- a/net/wget.c +++ b/net/wget.c @@ -76,7 +76,7 @@ static int wget_init_load_size(void) { phys_size_t max_size; - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_add_memory(gd->bd); max_size = lmb_get_free_size(image_load_addr); if (!max_size) diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c index 31d5e28105..8ba785fc31 100644 --- a/test/cmd/bdinfo.c +++ b/test/cmd/bdinfo.c @@ -114,14 +114,6 @@ static int lmb_test_dump_region(struct unit_test_state *uts, end = base + size - 1; flags = rgn->region[i].flags; - /* - * this entry includes the stack (get_sp()) on many platforms - * so will different each time lmb_init_and_reserve() is called. - * We could instead have the bdinfo command put its lmb region - * in a known location, so we can check it directly, rather than - * calling lmb_init_and_reserve() to create a new (and hopefully - * identical one). But for now this seems good enough. - */ if (!IS_ENABLED(CONFIG_SANDBOX) && i == 3) { ut_assert_nextlinen(" %s[%d]\t[", name, i); continue; @@ -201,7 +193,7 @@ static int bdinfo_test_all(struct unit_test_state *uts) if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { struct lmb lmb; - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); + lmb_add_memory(gd->bd); ut_assertok(lmb_test_dump_all(uts, &lmb)); if (IS_ENABLED(CONFIG_OF_REAL)) ut_assert_nextline("devicetree = %s", fdtdec_get_srcname()); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 08/31] lmb: replcace the lmb_init_and_reserve() function 2024-06-07 18:52 ` [RFC PATCH 08/31] lmb: replcace the lmb_init_and_reserve() function Sughosh Ganu @ 2024-06-10 17:31 ` Tom Rini 2024-06-11 8:50 ` Sughosh Ganu 0 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-10 17:31 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 1671 bytes --] On Sat, Jun 08, 2024 at 12:22:17AM +0530, Sughosh Ganu wrote: > With the changes to make the Logical Memory Block(LMB) allocations > persistent and with the common memory regions being reserved during > board init, the lmb_init_and_reserve() API can be removed and replaced > with a lmb_add_memory() API, which adds all the available memory to > the LMB pool. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > arch/arm/mach-apple/board.c | 2 +- > arch/arm/mach-snapdragon/board.c | 2 +- > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 2 +- > cmd/bdinfo.c | 2 +- > cmd/load.c | 2 +- > fs/fs.c | 2 +- > include/lmb.h | 12 +++++++++++- > lib/lmb.c | 15 +++++++++++---- > net/tftp.c | 2 +- > net/wget.c | 2 +- > test/cmd/bdinfo.c | 10 +--------- > 11 files changed, 31 insertions(+), 22 deletions(-) > > diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c > index c877c7b94c..2e72d03edd 100644 > --- a/arch/arm/mach-apple/board.c > +++ b/arch/arm/mach-apple/board.c > @@ -776,7 +776,7 @@ int board_late_init(void) > { > u32 status = 0; > > - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); > + lmb_add_memory(gd->bd); > > /* somewhat based on the Linux Kernel boot requirements: > * align by 2M and maximal FDT size 2M We already reserved gd->bd as part of the initr_lmb call. So I think this commit needs rethinking, or am I missing something? -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 08/31] lmb: replcace the lmb_init_and_reserve() function 2024-06-10 17:31 ` Tom Rini @ 2024-06-11 8:50 ` Sughosh Ganu 2024-06-11 13:57 ` Tom Rini 0 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-11 8:50 UTC (permalink / raw) To: Tom Rini Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Mon, 10 Jun 2024 at 23:01, Tom Rini <trini@konsulko.com> wrote: > > On Sat, Jun 08, 2024 at 12:22:17AM +0530, Sughosh Ganu wrote: > > With the changes to make the Logical Memory Block(LMB) allocations > > persistent and with the common memory regions being reserved during > > board init, the lmb_init_and_reserve() API can be removed and replaced > > with a lmb_add_memory() API, which adds all the available memory to > > the LMB pool. > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > --- > > arch/arm/mach-apple/board.c | 2 +- > > arch/arm/mach-snapdragon/board.c | 2 +- > > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 2 +- > > cmd/bdinfo.c | 2 +- > > cmd/load.c | 2 +- > > fs/fs.c | 2 +- > > include/lmb.h | 12 +++++++++++- > > lib/lmb.c | 15 +++++++++++---- > > net/tftp.c | 2 +- > > net/wget.c | 2 +- > > test/cmd/bdinfo.c | 10 +--------- > > 11 files changed, 31 insertions(+), 22 deletions(-) > > > > diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c > > index c877c7b94c..2e72d03edd 100644 > > --- a/arch/arm/mach-apple/board.c > > +++ b/arch/arm/mach-apple/board.c > > @@ -776,7 +776,7 @@ int board_late_init(void) > > { > > u32 status = 0; > > > > - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); > > + lmb_add_memory(gd->bd); > > > > /* somewhat based on the Linux Kernel boot requirements: > > * align by 2M and maximal FDT size 2M > > We already reserved gd->bd as part of the initr_lmb call. So I think > this commit needs rethinking, or am I missing something? I believe the LMB memory API's also get called from SPL(not sure about TPL/VPL though). The memory that gets added in the other commit is for U-Boot main, post relocation. These calls will then be needed for prior stages of U-Boot that want to use LMB memory. -sughosh ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 08/31] lmb: replcace the lmb_init_and_reserve() function 2024-06-11 8:50 ` Sughosh Ganu @ 2024-06-11 13:57 ` Tom Rini 0 siblings, 0 replies; 127+ messages in thread From: Tom Rini @ 2024-06-11 13:57 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 2542 bytes --] On Tue, Jun 11, 2024 at 02:20:40PM +0530, Sughosh Ganu wrote: > On Mon, 10 Jun 2024 at 23:01, Tom Rini <trini@konsulko.com> wrote: > > > > On Sat, Jun 08, 2024 at 12:22:17AM +0530, Sughosh Ganu wrote: > > > With the changes to make the Logical Memory Block(LMB) allocations > > > persistent and with the common memory regions being reserved during > > > board init, the lmb_init_and_reserve() API can be removed and replaced > > > with a lmb_add_memory() API, which adds all the available memory to > > > the LMB pool. > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > --- > > > arch/arm/mach-apple/board.c | 2 +- > > > arch/arm/mach-snapdragon/board.c | 2 +- > > > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 2 +- > > > cmd/bdinfo.c | 2 +- > > > cmd/load.c | 2 +- > > > fs/fs.c | 2 +- > > > include/lmb.h | 12 +++++++++++- > > > lib/lmb.c | 15 +++++++++++---- > > > net/tftp.c | 2 +- > > > net/wget.c | 2 +- > > > test/cmd/bdinfo.c | 10 +--------- > > > 11 files changed, 31 insertions(+), 22 deletions(-) > > > > > > diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c > > > index c877c7b94c..2e72d03edd 100644 > > > --- a/arch/arm/mach-apple/board.c > > > +++ b/arch/arm/mach-apple/board.c > > > @@ -776,7 +776,7 @@ int board_late_init(void) > > > { > > > u32 status = 0; > > > > > > - lmb_init_and_reserve(gd->bd, (void *)gd->fdt_blob); > > > + lmb_add_memory(gd->bd); > > > > > > /* somewhat based on the Linux Kernel boot requirements: > > > * align by 2M and maximal FDT size 2M > > > > We already reserved gd->bd as part of the initr_lmb call. So I think > > this commit needs rethinking, or am I missing something? > > I believe the LMB memory API's also get called from SPL(not sure about > TPL/VPL though). The memory that gets added in the other commit is for > U-Boot main, post relocation. These calls will then be needed for > prior stages of U-Boot that want to use LMB memory. We do likely make use of LMB at times in SPL, yes, for OS boot and that does remind me of cases people have had of loading image failures due to LMB-as-security-mechanism today. So we need to make a call to the new lmb init for real, once, rather than ad-hoc like this commit makes it. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (7 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 08/31] lmb: replcace the lmb_init_and_reserve() function Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 12:03 ` Ilias Apalodimas 2024-06-11 9:17 ` Heinrich Schuchardt 2024-06-07 18:52 ` [RFC PATCH 10/31] event: add events to notify memory map changes Sughosh Ganu ` (23 subsequent siblings) 32 siblings, 2 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu Allow for resizing of LMB regions if the region attributes match. The current code returns a failure status on detecting an overlapping address. This worked up until now since the LMB calls were not persistent and global -- the LMB memory map was specific and private to a given caller of the LMB API's. With the change in the LMB code to make the LMB reservations persistent, there needs to be a check on whether the memory region can be resized, and then do it if so. To distinguish between memory that cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region of memory with this attribute would indicate that the region cannot be resized. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- include/lmb.h | 1 + lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 107 insertions(+), 14 deletions(-) diff --git a/include/lmb.h b/include/lmb.h index 03bce2a50c..1d4cd255d2 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -20,6 +20,7 @@ enum lmb_flags { LMB_NONE = 0x0, LMB_NOMAP = 0x4, + LMB_NOOVERWRITE = 0x8, }; /** diff --git a/lib/lmb.c b/lib/lmb.c index de5a2cf23b..0a4f3d5bcd 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) } } +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, + enum lmb_flags flags) +{ + return rgn->region[r1].flags == flags; +} + +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, + phys_addr_t base, phys_size_t size, + enum lmb_flags flags) +{ + phys_size_t rgnsize; + unsigned long rgn_cnt, idx; + phys_addr_t rgnbase, rgnend; + phys_addr_t mergebase, mergeend; + + rgn_cnt = 0; + idx = i; + /* + * First thing to do is to identify how many regions does + * the requested region overlap. + * If the flags match, combine all these overlapping + * regions into a single region, and remove the merged + * regions. + */ + while (idx < rgn->cnt - 1) { + rgnbase = rgn->region[idx].base; + rgnsize = rgn->region[idx].size; + + if (lmb_addrs_overlap(base, size, rgnbase, + rgnsize)) { + if (!lmb_region_flags_match(rgn, idx, flags)) + return -1; + rgn_cnt++; + idx++; + } + } + + /* The merged region's base and size */ + rgnbase = rgn->region[i].base; + mergebase = min(base, rgnbase); + rgnend = rgn->region[idx].base + rgn->region[idx].size; + mergeend = max(rgnend, (base + size)); + + rgn->region[i].base = mergebase; + rgn->region[i].size = mergeend - mergebase; + + /* Now remove the merged regions */ + while (--rgn_cnt) + lmb_remove_region(rgn, i + 1); + + return 0; +} + +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, + phys_addr_t base, phys_size_t size, + enum lmb_flags flags) +{ + long ret = 0; + phys_addr_t rgnend; + + if (i == rgn->cnt - 1 || + base + size < rgn->region[i + 1].base) { + if (!lmb_region_flags_match(rgn, i, flags)) + return -1; + + rgnend = rgn->region[i].base + rgn->region[i].size; + rgn->region[i].base = min(base, rgn->region[i].base); + rgnend = max(base + size, rgnend); + rgn->region[i].size = rgnend - rgn->region[i].base; + } else { + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); + } + + return ret; +} + /* This routine called with relocation disabled. */ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, phys_size_t size, enum lmb_flags flags) { unsigned long coalesced = 0; - long adjacent, i; + long ret, i; if (rgn->cnt == 0) { rgn->region[0].base = base; @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, return -1; /* regions with new flags */ } - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); - if (adjacent > 0) { + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); + if (ret > 0) { if (flags != rgnflags) break; rgn->region[i].base -= size; rgn->region[i].size += size; coalesced++; break; - } else if (adjacent < 0) { + } else if (ret < 0) { if (flags != rgnflags) break; rgn->region[i].size += size; coalesced++; break; } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { - /* regions overlap */ - return -1; + if (flags == LMB_NONE) { + ret = lmb_resize_regions(rgn, i, base, size, + flags); + if (ret < 0) + return -1; + + coalesced++; + break; + } else { + return -1; + } } } @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) } static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, - phys_addr_t max_addr) + phys_addr_t max_addr, enum lmb_flags flags) { long i, rgn; phys_addr_t base = 0; @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) { phys_addr_t alloc; - alloc = __lmb_alloc_base(size, align, max_addr); + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); if (alloc == 0) printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) return alloc; } -/* - * Try to allocate a specific address range: must be in defined memory but not - * reserved - */ -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, + enum lmb_flags flags) { long rgn; @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) lmb.memory.region[rgn].size, base + size - 1, 1)) { /* ok, reserve the memory */ - if (lmb_reserve(base, size) >= 0) + if (lmb_reserve_flags(base, size, flags) >= 0) return base; } } + return 0; } +/* + * Try to allocate a specific address range: must be in defined memory but not + * reserved + */ +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) +{ + return __lmb_alloc_addr(base, size, LMB_NONE); +} + /* Return number of bytes from a given address that are free */ phys_size_t lmb_get_free_size(phys_addr_t addr) { -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-07 18:52 ` [RFC PATCH 09/31] lmb: allow for resizing lmb regions Sughosh Ganu @ 2024-06-10 12:03 ` Ilias Apalodimas 2024-06-10 12:20 ` Sughosh Ganu 2024-06-11 9:17 ` Heinrich Schuchardt 1 sibling, 1 reply; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 12:03 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Sughosh On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > Allow for resizing of LMB regions if the region attributes match. The > current code returns a failure status on detecting an overlapping > address. This worked up until now since the LMB calls were not > persistent and global -- the LMB memory map was specific and private > to a given caller of the LMB API's. > > With the change in the LMB code to make the LMB reservations > persistent, there needs to be a check on whether the memory region can > be resized, and then do it if so. To distinguish between memory that > cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region > of memory with this attribute would indicate that the region cannot be > resized. Can you think of a memory region that needs to be protected from resizing? I think we should design this a bit differently. For example, think of someone loading a file in a memory region and then a subsystem trying to resize its reserved memory overwriting that region. Instead of this flag why don't we add - A flag that indicates whether this region can be re-used (IOW overwrites it), but only if the 'subsytem id' defined below matches - a u32 that indicates the subsystem ID that initiated the transaction -- e.g EFI, load command, U-Boot core .. etc Resizing can be enabled unconditionally in that case as long as there is enough space. The only requirement would be that the request comes from the same subsystem that reserved the memory in the beginning Thanks /Ilias > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > include/lmb.h | 1 + > lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 107 insertions(+), 14 deletions(-) > > diff --git a/include/lmb.h b/include/lmb.h > index 03bce2a50c..1d4cd255d2 100644 > --- a/include/lmb.h > +++ b/include/lmb.h > @@ -20,6 +20,7 @@ > enum lmb_flags { > LMB_NONE = 0x0, > LMB_NOMAP = 0x4, > + LMB_NOOVERWRITE = 0x8, > }; > > /** > diff --git a/lib/lmb.c b/lib/lmb.c > index de5a2cf23b..0a4f3d5bcd 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) > } > } > > +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, > + enum lmb_flags flags) > +{ > + return rgn->region[r1].flags == flags; > +} > + > +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, > + phys_addr_t base, phys_size_t size, > + enum lmb_flags flags) > +{ > + phys_size_t rgnsize; > + unsigned long rgn_cnt, idx; > + phys_addr_t rgnbase, rgnend; > + phys_addr_t mergebase, mergeend; > + > + rgn_cnt = 0; > + idx = i; > + /* > + * First thing to do is to identify how many regions does > + * the requested region overlap. > + * If the flags match, combine all these overlapping > + * regions into a single region, and remove the merged > + * regions. > + */ > + while (idx < rgn->cnt - 1) { > + rgnbase = rgn->region[idx].base; > + rgnsize = rgn->region[idx].size; > + > + if (lmb_addrs_overlap(base, size, rgnbase, > + rgnsize)) { > + if (!lmb_region_flags_match(rgn, idx, flags)) > + return -1; > + rgn_cnt++; > + idx++; > + } > + } > + > + /* The merged region's base and size */ > + rgnbase = rgn->region[i].base; > + mergebase = min(base, rgnbase); > + rgnend = rgn->region[idx].base + rgn->region[idx].size; > + mergeend = max(rgnend, (base + size)); > + > + rgn->region[i].base = mergebase; > + rgn->region[i].size = mergeend - mergebase; > + > + /* Now remove the merged regions */ > + while (--rgn_cnt) > + lmb_remove_region(rgn, i + 1); > + > + return 0; > +} > + > +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, > + phys_addr_t base, phys_size_t size, > + enum lmb_flags flags) > +{ > + long ret = 0; > + phys_addr_t rgnend; > + > + if (i == rgn->cnt - 1 || > + base + size < rgn->region[i + 1].base) { > + if (!lmb_region_flags_match(rgn, i, flags)) > + return -1; > + > + rgnend = rgn->region[i].base + rgn->region[i].size; > + rgn->region[i].base = min(base, rgn->region[i].base); > + rgnend = max(base + size, rgnend); > + rgn->region[i].size = rgnend - rgn->region[i].base; > + } else { > + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); > + } > + > + return ret; > +} > + > /* This routine called with relocation disabled. */ > static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > phys_size_t size, enum lmb_flags flags) > { > unsigned long coalesced = 0; > - long adjacent, i; > + long ret, i; > > if (rgn->cnt == 0) { > rgn->region[0].base = base; > @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > return -1; /* regions with new flags */ > } > > - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > - if (adjacent > 0) { > + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > + if (ret > 0) { > if (flags != rgnflags) > break; > rgn->region[i].base -= size; > rgn->region[i].size += size; > coalesced++; > break; > - } else if (adjacent < 0) { > + } else if (ret < 0) { > if (flags != rgnflags) > break; > rgn->region[i].size += size; > coalesced++; > break; > } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { > - /* regions overlap */ > - return -1; > + if (flags == LMB_NONE) { > + ret = lmb_resize_regions(rgn, i, base, size, > + flags); > + if (ret < 0) > + return -1; > + > + coalesced++; > + break; > + } else { > + return -1; > + } > } > } > > @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) > } > > static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, > - phys_addr_t max_addr) > + phys_addr_t max_addr, enum lmb_flags flags) > { > long i, rgn; > phys_addr_t base = 0; > @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > { > phys_addr_t alloc; > > - alloc = __lmb_alloc_base(size, align, max_addr); > + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); > > if (alloc == 0) > printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > return alloc; > } > > -/* > - * Try to allocate a specific address range: must be in defined memory but not > - * reserved > - */ > -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, > + enum lmb_flags flags) > { > long rgn; > > @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > lmb.memory.region[rgn].size, > base + size - 1, 1)) { > /* ok, reserve the memory */ > - if (lmb_reserve(base, size) >= 0) > + if (lmb_reserve_flags(base, size, flags) >= 0) > return base; > } > } > + > return 0; > } > > +/* > + * Try to allocate a specific address range: must be in defined memory but not > + * reserved > + */ > +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > +{ > + return __lmb_alloc_addr(base, size, LMB_NONE); > +} > + > /* Return number of bytes from a given address that are free */ > phys_size_t lmb_get_free_size(phys_addr_t addr) > { > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-10 12:03 ` Ilias Apalodimas @ 2024-06-10 12:20 ` Sughosh Ganu 2024-06-10 12:47 ` Ilias Apalodimas 2024-06-10 12:54 ` Heinrich Schuchardt 0 siblings, 2 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 12:20 UTC (permalink / raw) To: Ilias Apalodimas Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam hi Ilias, On Mon, 10 Jun 2024 at 17:34, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > Hi Sughosh > > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > Allow for resizing of LMB regions if the region attributes match. The > > current code returns a failure status on detecting an overlapping > > address. This worked up until now since the LMB calls were not > > persistent and global -- the LMB memory map was specific and private > > to a given caller of the LMB API's. > > > > With the change in the LMB code to make the LMB reservations > > persistent, there needs to be a check on whether the memory region can > > be resized, and then do it if so. To distinguish between memory that > > cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region > > of memory with this attribute would indicate that the region cannot be > > resized. > > Can you think of a memory region that needs to be protected from resizing? Actually, I think I could use a better term instead of 'resize'. The aim of this patch is to allow re-allocation/re-reservation of the same region of memory -- this will only be relevant for the LMB reservations, as these are used for loading images into memory. All other allocations(EFI currently) are true allocations in that these should not get overwritten at all. Memory once allocated, say for loading an EFI image, cannot be re-requested. > I think we should design this a bit differently. For example, think > of someone loading a file in a memory region and then a subsystem > trying to resize its reserved memory overwriting that region. Instead > of this flag why don't we add > - A flag that indicates whether this region can be re-used (IOW > overwrites it), but only if the 'subsytem id' defined below matches > - a u32 that indicates the subsystem ID that initiated the transaction > -- e.g EFI, load command, U-Boot core .. etc > > Resizing can be enabled unconditionally in that case as long as there > is enough space. The only requirement would be that the request comes > from the same subsystem that reserved the memory in the beginning Like I mentioned above, resizing(or rather re-allocations) should only be allowed for the LMB subsystem. Any other module should not be returned an already allocated address. Which is why I mark any memory map update coming from the EFI module as no-overwrite. -sughosh > > Thanks > /Ilias > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > --- > > include/lmb.h | 1 + > > lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ > > 2 files changed, 107 insertions(+), 14 deletions(-) > > > > diff --git a/include/lmb.h b/include/lmb.h > > index 03bce2a50c..1d4cd255d2 100644 > > --- a/include/lmb.h > > +++ b/include/lmb.h > > @@ -20,6 +20,7 @@ > > enum lmb_flags { > > LMB_NONE = 0x0, > > LMB_NOMAP = 0x4, > > + LMB_NOOVERWRITE = 0x8, > > }; > > > > /** > > diff --git a/lib/lmb.c b/lib/lmb.c > > index de5a2cf23b..0a4f3d5bcd 100644 > > --- a/lib/lmb.c > > +++ b/lib/lmb.c > > @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) > > } > > } > > > > +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, > > + enum lmb_flags flags) > > +{ > > + return rgn->region[r1].flags == flags; > > +} > > + > > +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, > > + phys_addr_t base, phys_size_t size, > > + enum lmb_flags flags) > > +{ > > + phys_size_t rgnsize; > > + unsigned long rgn_cnt, idx; > > + phys_addr_t rgnbase, rgnend; > > + phys_addr_t mergebase, mergeend; > > + > > + rgn_cnt = 0; > > + idx = i; > > + /* > > + * First thing to do is to identify how many regions does > > + * the requested region overlap. > > + * If the flags match, combine all these overlapping > > + * regions into a single region, and remove the merged > > + * regions. > > + */ > > + while (idx < rgn->cnt - 1) { > > + rgnbase = rgn->region[idx].base; > > + rgnsize = rgn->region[idx].size; > > + > > + if (lmb_addrs_overlap(base, size, rgnbase, > > + rgnsize)) { > > + if (!lmb_region_flags_match(rgn, idx, flags)) > > + return -1; > > + rgn_cnt++; > > + idx++; > > + } > > + } > > + > > + /* The merged region's base and size */ > > + rgnbase = rgn->region[i].base; > > + mergebase = min(base, rgnbase); > > + rgnend = rgn->region[idx].base + rgn->region[idx].size; > > + mergeend = max(rgnend, (base + size)); > > + > > + rgn->region[i].base = mergebase; > > + rgn->region[i].size = mergeend - mergebase; > > + > > + /* Now remove the merged regions */ > > + while (--rgn_cnt) > > + lmb_remove_region(rgn, i + 1); > > + > > + return 0; > > +} > > + > > +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, > > + phys_addr_t base, phys_size_t size, > > + enum lmb_flags flags) > > +{ > > + long ret = 0; > > + phys_addr_t rgnend; > > + > > + if (i == rgn->cnt - 1 || > > + base + size < rgn->region[i + 1].base) { > > + if (!lmb_region_flags_match(rgn, i, flags)) > > + return -1; > > + > > + rgnend = rgn->region[i].base + rgn->region[i].size; > > + rgn->region[i].base = min(base, rgn->region[i].base); > > + rgnend = max(base + size, rgnend); > > + rgn->region[i].size = rgnend - rgn->region[i].base; > > + } else { > > + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); > > + } > > + > > + return ret; > > +} > > + > > /* This routine called with relocation disabled. */ > > static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > phys_size_t size, enum lmb_flags flags) > > { > > unsigned long coalesced = 0; > > - long adjacent, i; > > + long ret, i; > > > > if (rgn->cnt == 0) { > > rgn->region[0].base = base; > > @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > return -1; /* regions with new flags */ > > } > > > > - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > - if (adjacent > 0) { > > + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > + if (ret > 0) { > > if (flags != rgnflags) > > break; > > rgn->region[i].base -= size; > > rgn->region[i].size += size; > > coalesced++; > > break; > > - } else if (adjacent < 0) { > > + } else if (ret < 0) { > > if (flags != rgnflags) > > break; > > rgn->region[i].size += size; > > coalesced++; > > break; > > } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { > > - /* regions overlap */ > > - return -1; > > + if (flags == LMB_NONE) { > > + ret = lmb_resize_regions(rgn, i, base, size, > > + flags); > > + if (ret < 0) > > + return -1; > > + > > + coalesced++; > > + break; > > + } else { > > + return -1; > > + } > > } > > } > > > > @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) > > } > > > > static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, > > - phys_addr_t max_addr) > > + phys_addr_t max_addr, enum lmb_flags flags) > > { > > long i, rgn; > > phys_addr_t base = 0; > > @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > { > > phys_addr_t alloc; > > > > - alloc = __lmb_alloc_base(size, align, max_addr); > > + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); > > > > if (alloc == 0) > > printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > > @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > return alloc; > > } > > > > -/* > > - * Try to allocate a specific address range: must be in defined memory but not > > - * reserved > > - */ > > -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, > > + enum lmb_flags flags) > > { > > long rgn; > > > > @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > lmb.memory.region[rgn].size, > > base + size - 1, 1)) { > > /* ok, reserve the memory */ > > - if (lmb_reserve(base, size) >= 0) > > + if (lmb_reserve_flags(base, size, flags) >= 0) > > return base; > > } > > } > > + > > return 0; > > } > > > > +/* > > + * Try to allocate a specific address range: must be in defined memory but not > > + * reserved > > + */ > > +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > +{ > > + return __lmb_alloc_addr(base, size, LMB_NONE); > > +} > > + > > /* Return number of bytes from a given address that are free */ > > phys_size_t lmb_get_free_size(phys_addr_t addr) > > { > > -- > > 2.34.1 > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-10 12:20 ` Sughosh Ganu @ 2024-06-10 12:47 ` Ilias Apalodimas 2024-06-10 12:57 ` Sughosh Ganu 2024-06-10 12:54 ` Heinrich Schuchardt 1 sibling, 1 reply; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 12:47 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Mon, 10 Jun 2024 at 15:20, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > hi Ilias, > > On Mon, 10 Jun 2024 at 17:34, Ilias Apalodimas > <ilias.apalodimas@linaro.org> wrote: > > > > Hi Sughosh > > > > > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > Allow for resizing of LMB regions if the region attributes match. The > > > current code returns a failure status on detecting an overlapping > > > address. This worked up until now since the LMB calls were not > > > persistent and global -- the LMB memory map was specific and private > > > to a given caller of the LMB API's. > > > > > > With the change in the LMB code to make the LMB reservations > > > persistent, there needs to be a check on whether the memory region can > > > be resized, and then do it if so. To distinguish between memory that > > > cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region > > > of memory with this attribute would indicate that the region cannot be > > > resized. > > > > Can you think of a memory region that needs to be protected from resizing? > > Actually, I think I could use a better term instead of 'resize'. The > aim of this patch is to allow re-allocation/re-reservation of the same > region of memory -- this will only be relevant for the LMB > reservations, as these are used for loading images into memory. All > other allocations(EFI currently) are true allocations in that these > should not get overwritten at all. Memory once allocated, say for > loading an EFI image, cannot be re-requested. > > > > I think we should design this a bit differently. For example, think > > of someone loading a file in a memory region and then a subsystem > > trying to resize its reserved memory overwriting that region. Instead > > of this flag why don't we add > > - A flag that indicates whether this region can be re-used (IOW > > overwrites it), but only if the 'subsytem id' defined below matches > > - a u32 that indicates the subsystem ID that initiated the transaction > > -- e.g EFI, load command, U-Boot core .. etc > > > > Resizing can be enabled unconditionally in that case as long as there > > is enough space. The only requirement would be that the request comes > > from the same subsystem that reserved the memory in the beginning > > Like I mentioned above, resizing(or rather re-allocations) should only > be allowed for the LMB subsystem. Any other module should not be > returned an already allocated address. Which is why I mark any memory > map update coming from the EFI module as no-overwrite. And what happens if someone tries to overwrite 'load' memory? Won't you still corrupt whatever is loaded on that region as it's not marked for protection? /Ilias > > -sughosh > > > > Thanks > > /Ilias > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > --- > > > include/lmb.h | 1 + > > > lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ > > > 2 files changed, 107 insertions(+), 14 deletions(-) > > > > > > diff --git a/include/lmb.h b/include/lmb.h > > > index 03bce2a50c..1d4cd255d2 100644 > > > --- a/include/lmb.h > > > +++ b/include/lmb.h > > > @@ -20,6 +20,7 @@ > > > enum lmb_flags { > > > LMB_NONE = 0x0, > > > LMB_NOMAP = 0x4, > > > + LMB_NOOVERWRITE = 0x8, > > > }; > > > > > > /** > > > diff --git a/lib/lmb.c b/lib/lmb.c > > > index de5a2cf23b..0a4f3d5bcd 100644 > > > --- a/lib/lmb.c > > > +++ b/lib/lmb.c > > > @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) > > > } > > > } > > > > > > +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, > > > + enum lmb_flags flags) > > > +{ > > > + return rgn->region[r1].flags == flags; > > > +} > > > + > > > +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, > > > + phys_addr_t base, phys_size_t size, > > > + enum lmb_flags flags) > > > +{ > > > + phys_size_t rgnsize; > > > + unsigned long rgn_cnt, idx; > > > + phys_addr_t rgnbase, rgnend; > > > + phys_addr_t mergebase, mergeend; > > > + > > > + rgn_cnt = 0; > > > + idx = i; > > > + /* > > > + * First thing to do is to identify how many regions does > > > + * the requested region overlap. > > > + * If the flags match, combine all these overlapping > > > + * regions into a single region, and remove the merged > > > + * regions. > > > + */ > > > + while (idx < rgn->cnt - 1) { > > > + rgnbase = rgn->region[idx].base; > > > + rgnsize = rgn->region[idx].size; > > > + > > > + if (lmb_addrs_overlap(base, size, rgnbase, > > > + rgnsize)) { > > > + if (!lmb_region_flags_match(rgn, idx, flags)) > > > + return -1; > > > + rgn_cnt++; > > > + idx++; > > > + } > > > + } > > > + > > > + /* The merged region's base and size */ > > > + rgnbase = rgn->region[i].base; > > > + mergebase = min(base, rgnbase); > > > + rgnend = rgn->region[idx].base + rgn->region[idx].size; > > > + mergeend = max(rgnend, (base + size)); > > > + > > > + rgn->region[i].base = mergebase; > > > + rgn->region[i].size = mergeend - mergebase; > > > + > > > + /* Now remove the merged regions */ > > > + while (--rgn_cnt) > > > + lmb_remove_region(rgn, i + 1); > > > + > > > + return 0; > > > +} > > > + > > > +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, > > > + phys_addr_t base, phys_size_t size, > > > + enum lmb_flags flags) > > > +{ > > > + long ret = 0; > > > + phys_addr_t rgnend; > > > + > > > + if (i == rgn->cnt - 1 || > > > + base + size < rgn->region[i + 1].base) { > > > + if (!lmb_region_flags_match(rgn, i, flags)) > > > + return -1; > > > + > > > + rgnend = rgn->region[i].base + rgn->region[i].size; > > > + rgn->region[i].base = min(base, rgn->region[i].base); > > > + rgnend = max(base + size, rgnend); > > > + rgn->region[i].size = rgnend - rgn->region[i].base; > > > + } else { > > > + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); > > > + } > > > + > > > + return ret; > > > +} > > > + > > > /* This routine called with relocation disabled. */ > > > static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > > phys_size_t size, enum lmb_flags flags) > > > { > > > unsigned long coalesced = 0; > > > - long adjacent, i; > > > + long ret, i; > > > > > > if (rgn->cnt == 0) { > > > rgn->region[0].base = base; > > > @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > > return -1; /* regions with new flags */ > > > } > > > > > > - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > > - if (adjacent > 0) { > > > + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > > + if (ret > 0) { > > > if (flags != rgnflags) > > > break; > > > rgn->region[i].base -= size; > > > rgn->region[i].size += size; > > > coalesced++; > > > break; > > > - } else if (adjacent < 0) { > > > + } else if (ret < 0) { > > > if (flags != rgnflags) > > > break; > > > rgn->region[i].size += size; > > > coalesced++; > > > break; > > > } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { > > > - /* regions overlap */ > > > - return -1; > > > + if (flags == LMB_NONE) { > > > + ret = lmb_resize_regions(rgn, i, base, size, > > > + flags); > > > + if (ret < 0) > > > + return -1; > > > + > > > + coalesced++; > > > + break; > > > + } else { > > > + return -1; > > > + } > > > } > > > } > > > > > > @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) > > > } > > > > > > static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, > > > - phys_addr_t max_addr) > > > + phys_addr_t max_addr, enum lmb_flags flags) > > > { > > > long i, rgn; > > > phys_addr_t base = 0; > > > @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > > { > > > phys_addr_t alloc; > > > > > > - alloc = __lmb_alloc_base(size, align, max_addr); > > > + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); > > > > > > if (alloc == 0) > > > printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > > > @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > > return alloc; > > > } > > > > > > -/* > > > - * Try to allocate a specific address range: must be in defined memory but not > > > - * reserved > > > - */ > > > -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, > > > + enum lmb_flags flags) > > > { > > > long rgn; > > > > > > @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > lmb.memory.region[rgn].size, > > > base + size - 1, 1)) { > > > /* ok, reserve the memory */ > > > - if (lmb_reserve(base, size) >= 0) > > > + if (lmb_reserve_flags(base, size, flags) >= 0) > > > return base; > > > } > > > } > > > + > > > return 0; > > > } > > > > > > +/* > > > + * Try to allocate a specific address range: must be in defined memory but not > > > + * reserved > > > + */ > > > +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > +{ > > > + return __lmb_alloc_addr(base, size, LMB_NONE); > > > +} > > > + > > > /* Return number of bytes from a given address that are free */ > > > phys_size_t lmb_get_free_size(phys_addr_t addr) > > > { > > > -- > > > 2.34.1 > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-10 12:47 ` Ilias Apalodimas @ 2024-06-10 12:57 ` Sughosh Ganu 2024-06-10 14:21 ` Ilias Apalodimas 0 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 12:57 UTC (permalink / raw) To: Ilias Apalodimas Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Mon, 10 Jun 2024 at 18:17, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > On Mon, 10 Jun 2024 at 15:20, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > hi Ilias, > > > > On Mon, 10 Jun 2024 at 17:34, Ilias Apalodimas > > <ilias.apalodimas@linaro.org> wrote: > > > > > > Hi Sughosh > > > > > > > > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > > > Allow for resizing of LMB regions if the region attributes match. The > > > > current code returns a failure status on detecting an overlapping > > > > address. This worked up until now since the LMB calls were not > > > > persistent and global -- the LMB memory map was specific and private > > > > to a given caller of the LMB API's. > > > > > > > > With the change in the LMB code to make the LMB reservations > > > > persistent, there needs to be a check on whether the memory region can > > > > be resized, and then do it if so. To distinguish between memory that > > > > cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region > > > > of memory with this attribute would indicate that the region cannot be > > > > resized. > > > > > > Can you think of a memory region that needs to be protected from resizing? > > > > Actually, I think I could use a better term instead of 'resize'. The > > aim of this patch is to allow re-allocation/re-reservation of the same > > region of memory -- this will only be relevant for the LMB > > reservations, as these are used for loading images into memory. All > > other allocations(EFI currently) are true allocations in that these > > should not get overwritten at all. Memory once allocated, say for > > loading an EFI image, cannot be re-requested. > > > > > > > I think we should design this a bit differently. For example, think > > > of someone loading a file in a memory region and then a subsystem > > > trying to resize its reserved memory overwriting that region. Instead > > > of this flag why don't we add > > > - A flag that indicates whether this region can be re-used (IOW > > > overwrites it), but only if the 'subsytem id' defined below matches > > > - a u32 that indicates the subsystem ID that initiated the transaction > > > -- e.g EFI, load command, U-Boot core .. etc > > > > > > Resizing can be enabled unconditionally in that case as long as there > > > is enough space. The only requirement would be that the request comes > > > from the same subsystem that reserved the memory in the beginning > > > > Like I mentioned above, resizing(or rather re-allocations) should only > > be allowed for the LMB subsystem. Any other module should not be > > returned an already allocated address. Which is why I mark any memory > > map update coming from the EFI module as no-overwrite. > > And what happens if someone tries to overwrite 'load' memory? Won't > you still corrupt whatever is loaded on that region as it's not marked > for protection? Yes, but that is the expected behaviour in U-Boot for LMB memory. Consider the following flow, 1) load hostfs - $some_addr $some_image 2) fs.write $some_addr $some_destination $filesize 3) load hostfs - $some_addr $some_other_image 4) fs.write $some_addr $some_other_destination $filesize The above flow is very much valid, and this exercises the same region of LMB memory. Which is why we need to allow re-using the same memory address for LMB. This worked up until now since all LMB allocations/reservations were private. This is user visible behaviour, and used in many scripts used by platforms to read and write files. So even after making the LMB memory map global and persistent, this aspect of re-use of LMB memory must be maintained. -sughosh > > /Ilias > > > > -sughosh > > > > > > Thanks > > > /Ilias > > > > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > --- > > > > include/lmb.h | 1 + > > > > lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ > > > > 2 files changed, 107 insertions(+), 14 deletions(-) > > > > > > > > diff --git a/include/lmb.h b/include/lmb.h > > > > index 03bce2a50c..1d4cd255d2 100644 > > > > --- a/include/lmb.h > > > > +++ b/include/lmb.h > > > > @@ -20,6 +20,7 @@ > > > > enum lmb_flags { > > > > LMB_NONE = 0x0, > > > > LMB_NOMAP = 0x4, > > > > + LMB_NOOVERWRITE = 0x8, > > > > }; > > > > > > > > /** > > > > diff --git a/lib/lmb.c b/lib/lmb.c > > > > index de5a2cf23b..0a4f3d5bcd 100644 > > > > --- a/lib/lmb.c > > > > +++ b/lib/lmb.c > > > > @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) > > > > } > > > > } > > > > > > > > +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, > > > > + enum lmb_flags flags) > > > > +{ > > > > + return rgn->region[r1].flags == flags; > > > > +} > > > > + > > > > +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, > > > > + phys_addr_t base, phys_size_t size, > > > > + enum lmb_flags flags) > > > > +{ > > > > + phys_size_t rgnsize; > > > > + unsigned long rgn_cnt, idx; > > > > + phys_addr_t rgnbase, rgnend; > > > > + phys_addr_t mergebase, mergeend; > > > > + > > > > + rgn_cnt = 0; > > > > + idx = i; > > > > + /* > > > > + * First thing to do is to identify how many regions does > > > > + * the requested region overlap. > > > > + * If the flags match, combine all these overlapping > > > > + * regions into a single region, and remove the merged > > > > + * regions. > > > > + */ > > > > + while (idx < rgn->cnt - 1) { > > > > + rgnbase = rgn->region[idx].base; > > > > + rgnsize = rgn->region[idx].size; > > > > + > > > > + if (lmb_addrs_overlap(base, size, rgnbase, > > > > + rgnsize)) { > > > > + if (!lmb_region_flags_match(rgn, idx, flags)) > > > > + return -1; > > > > + rgn_cnt++; > > > > + idx++; > > > > + } > > > > + } > > > > + > > > > + /* The merged region's base and size */ > > > > + rgnbase = rgn->region[i].base; > > > > + mergebase = min(base, rgnbase); > > > > + rgnend = rgn->region[idx].base + rgn->region[idx].size; > > > > + mergeend = max(rgnend, (base + size)); > > > > + > > > > + rgn->region[i].base = mergebase; > > > > + rgn->region[i].size = mergeend - mergebase; > > > > + > > > > + /* Now remove the merged regions */ > > > > + while (--rgn_cnt) > > > > + lmb_remove_region(rgn, i + 1); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, > > > > + phys_addr_t base, phys_size_t size, > > > > + enum lmb_flags flags) > > > > +{ > > > > + long ret = 0; > > > > + phys_addr_t rgnend; > > > > + > > > > + if (i == rgn->cnt - 1 || > > > > + base + size < rgn->region[i + 1].base) { > > > > + if (!lmb_region_flags_match(rgn, i, flags)) > > > > + return -1; > > > > + > > > > + rgnend = rgn->region[i].base + rgn->region[i].size; > > > > + rgn->region[i].base = min(base, rgn->region[i].base); > > > > + rgnend = max(base + size, rgnend); > > > > + rgn->region[i].size = rgnend - rgn->region[i].base; > > > > + } else { > > > > + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); > > > > + } > > > > + > > > > + return ret; > > > > +} > > > > + > > > > /* This routine called with relocation disabled. */ > > > > static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > > > phys_size_t size, enum lmb_flags flags) > > > > { > > > > unsigned long coalesced = 0; > > > > - long adjacent, i; > > > > + long ret, i; > > > > > > > > if (rgn->cnt == 0) { > > > > rgn->region[0].base = base; > > > > @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > > > return -1; /* regions with new flags */ > > > > } > > > > > > > > - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > > > - if (adjacent > 0) { > > > > + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > > > + if (ret > 0) { > > > > if (flags != rgnflags) > > > > break; > > > > rgn->region[i].base -= size; > > > > rgn->region[i].size += size; > > > > coalesced++; > > > > break; > > > > - } else if (adjacent < 0) { > > > > + } else if (ret < 0) { > > > > if (flags != rgnflags) > > > > break; > > > > rgn->region[i].size += size; > > > > coalesced++; > > > > break; > > > > } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { > > > > - /* regions overlap */ > > > > - return -1; > > > > + if (flags == LMB_NONE) { > > > > + ret = lmb_resize_regions(rgn, i, base, size, > > > > + flags); > > > > + if (ret < 0) > > > > + return -1; > > > > + > > > > + coalesced++; > > > > + break; > > > > + } else { > > > > + return -1; > > > > + } > > > > } > > > > } > > > > > > > > @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) > > > > } > > > > > > > > static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, > > > > - phys_addr_t max_addr) > > > > + phys_addr_t max_addr, enum lmb_flags flags) > > > > { > > > > long i, rgn; > > > > phys_addr_t base = 0; > > > > @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > > > { > > > > phys_addr_t alloc; > > > > > > > > - alloc = __lmb_alloc_base(size, align, max_addr); > > > > + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); > > > > > > > > if (alloc == 0) > > > > printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > > > > @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > > > return alloc; > > > > } > > > > > > > > -/* > > > > - * Try to allocate a specific address range: must be in defined memory but not > > > > - * reserved > > > > - */ > > > > -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > > +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, > > > > + enum lmb_flags flags) > > > > { > > > > long rgn; > > > > > > > > @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > > lmb.memory.region[rgn].size, > > > > base + size - 1, 1)) { > > > > /* ok, reserve the memory */ > > > > - if (lmb_reserve(base, size) >= 0) > > > > + if (lmb_reserve_flags(base, size, flags) >= 0) > > > > return base; > > > > } > > > > } > > > > + > > > > return 0; > > > > } > > > > > > > > +/* > > > > + * Try to allocate a specific address range: must be in defined memory but not > > > > + * reserved > > > > + */ > > > > +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > > +{ > > > > + return __lmb_alloc_addr(base, size, LMB_NONE); > > > > +} > > > > + > > > > /* Return number of bytes from a given address that are free */ > > > > phys_size_t lmb_get_free_size(phys_addr_t addr) > > > > { > > > > -- > > > > 2.34.1 > > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-10 12:57 ` Sughosh Ganu @ 2024-06-10 14:21 ` Ilias Apalodimas 2024-06-10 14:33 ` Sughosh Ganu 0 siblings, 1 reply; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 14:21 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Sughosh On Mon, 10 Jun 2024 at 15:57, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > On Mon, 10 Jun 2024 at 18:17, Ilias Apalodimas > <ilias.apalodimas@linaro.org> wrote: > > > > On Mon, 10 Jun 2024 at 15:20, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > hi Ilias, > > > > > > On Mon, 10 Jun 2024 at 17:34, Ilias Apalodimas > > > <ilias.apalodimas@linaro.org> wrote: > > > > > > > > Hi Sughosh > > > > > > > > > > > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > > > > > Allow for resizing of LMB regions if the region attributes match. The > > > > > current code returns a failure status on detecting an overlapping > > > > > address. This worked up until now since the LMB calls were not > > > > > persistent and global -- the LMB memory map was specific and private > > > > > to a given caller of the LMB API's. > > > > > > > > > > With the change in the LMB code to make the LMB reservations > > > > > persistent, there needs to be a check on whether the memory region can > > > > > be resized, and then do it if so. To distinguish between memory that > > > > > cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region > > > > > of memory with this attribute would indicate that the region cannot be > > > > > resized. > > > > > > > > Can you think of a memory region that needs to be protected from resizing? > > > > > > Actually, I think I could use a better term instead of 'resize'. The > > > aim of this patch is to allow re-allocation/re-reservation of the same > > > region of memory -- this will only be relevant for the LMB > > > reservations, as these are used for loading images into memory. All > > > other allocations(EFI currently) are true allocations in that these > > > should not get overwritten at all. Memory once allocated, say for > > > loading an EFI image, cannot be re-requested. > > > > > > > > > > I think we should design this a bit differently. For example, think > > > > of someone loading a file in a memory region and then a subsystem > > > > trying to resize its reserved memory overwriting that region. Instead > > > > of this flag why don't we add > > > > - A flag that indicates whether this region can be re-used (IOW > > > > overwrites it), but only if the 'subsytem id' defined below matches > > > > - a u32 that indicates the subsystem ID that initiated the transaction > > > > -- e.g EFI, load command, U-Boot core .. etc > > > > > > > > Resizing can be enabled unconditionally in that case as long as there > > > > is enough space. The only requirement would be that the request comes > > > > from the same subsystem that reserved the memory in the beginning > > > > > > Like I mentioned above, resizing(or rather re-allocations) should only > > > be allowed for the LMB subsystem. Any other module should not be > > > returned an already allocated address. Which is why I mark any memory > > > map update coming from the EFI module as no-overwrite. > > > > And what happens if someone tries to overwrite 'load' memory? Won't > > you still corrupt whatever is loaded on that region as it's not marked > > for protection? > > Yes, but that is the expected behavior in U-Boot for LMB memory. > Consider the following flow, > > 1) load hostfs - $some_addr $some_image > 2) fs.write $some_addr $some_destination $filesize > 3) load hostfs - $some_addr $some_other_image > 4) fs.write $some_addr $some_other_destination $filesize > > The above flow is very much valid, and this exercises the same region > of LMB memory. Which is why we need to allow re-using the same memory > address for LMB. This worked up until now since all LMB > allocations/reservations were private. This is user visible behaviour, > and used in many scripts used by platforms to read and write files. So > even after making the LMB memory map global and persistent, this > aspect of re-use of LMB memory must be maintained. I am not talking about this. I haven't gone through all the patches yet, so I might be missing something but... What if a user loads a file to boot and then an EFI subsystem decides to allocate memory -- e.g the EventLog and that allocation routine returns memory within the space you just loaded the binary from? Yes memory should be overwritten to preserve the current behavior, but only if you perform the same action/command Thanks /Ilias > > -sughosh > > > > > /Ilias > > > > > > -sughosh > > > > > > > > Thanks > > > > /Ilias > > > > > > > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > > --- > > > > > include/lmb.h | 1 + > > > > > lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ > > > > > 2 files changed, 107 insertions(+), 14 deletions(-) > > > > > > > > > > diff --git a/include/lmb.h b/include/lmb.h > > > > > index 03bce2a50c..1d4cd255d2 100644 > > > > > --- a/include/lmb.h > > > > > +++ b/include/lmb.h > > > > > @@ -20,6 +20,7 @@ > > > > > enum lmb_flags { > > > > > LMB_NONE = 0x0, > > > > > LMB_NOMAP = 0x4, > > > > > + LMB_NOOVERWRITE = 0x8, > > > > > }; > > > > > > > > > > /** > > > > > diff --git a/lib/lmb.c b/lib/lmb.c > > > > > index de5a2cf23b..0a4f3d5bcd 100644 > > > > > --- a/lib/lmb.c > > > > > +++ b/lib/lmb.c > > > > > @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) > > > > > } > > > > > } > > > > > > > > > > +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, > > > > > + enum lmb_flags flags) > > > > > +{ > > > > > + return rgn->region[r1].flags == flags; > > > > > +} > > > > > + > > > > > +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, > > > > > + phys_addr_t base, phys_size_t size, > > > > > + enum lmb_flags flags) > > > > > +{ > > > > > + phys_size_t rgnsize; > > > > > + unsigned long rgn_cnt, idx; > > > > > + phys_addr_t rgnbase, rgnend; > > > > > + phys_addr_t mergebase, mergeend; > > > > > + > > > > > + rgn_cnt = 0; > > > > > + idx = i; > > > > > + /* > > > > > + * First thing to do is to identify how many regions does > > > > > + * the requested region overlap. > > > > > + * If the flags match, combine all these overlapping > > > > > + * regions into a single region, and remove the merged > > > > > + * regions. > > > > > + */ > > > > > + while (idx < rgn->cnt - 1) { > > > > > + rgnbase = rgn->region[idx].base; > > > > > + rgnsize = rgn->region[idx].size; > > > > > + > > > > > + if (lmb_addrs_overlap(base, size, rgnbase, > > > > > + rgnsize)) { > > > > > + if (!lmb_region_flags_match(rgn, idx, flags)) > > > > > + return -1; > > > > > + rgn_cnt++; > > > > > + idx++; > > > > > + } > > > > > + } > > > > > + > > > > > + /* The merged region's base and size */ > > > > > + rgnbase = rgn->region[i].base; > > > > > + mergebase = min(base, rgnbase); > > > > > + rgnend = rgn->region[idx].base + rgn->region[idx].size; > > > > > + mergeend = max(rgnend, (base + size)); > > > > > + > > > > > + rgn->region[i].base = mergebase; > > > > > + rgn->region[i].size = mergeend - mergebase; > > > > > + > > > > > + /* Now remove the merged regions */ > > > > > + while (--rgn_cnt) > > > > > + lmb_remove_region(rgn, i + 1); > > > > > + > > > > > + return 0; > > > > > +} > > > > > + > > > > > +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, > > > > > + phys_addr_t base, phys_size_t size, > > > > > + enum lmb_flags flags) > > > > > +{ > > > > > + long ret = 0; > > > > > + phys_addr_t rgnend; > > > > > + > > > > > + if (i == rgn->cnt - 1 || > > > > > + base + size < rgn->region[i + 1].base) { > > > > > + if (!lmb_region_flags_match(rgn, i, flags)) > > > > > + return -1; > > > > > + > > > > > + rgnend = rgn->region[i].base + rgn->region[i].size; > > > > > + rgn->region[i].base = min(base, rgn->region[i].base); > > > > > + rgnend = max(base + size, rgnend); > > > > > + rgn->region[i].size = rgnend - rgn->region[i].base; > > > > > + } else { > > > > > + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); > > > > > + } > > > > > + > > > > > + return ret; > > > > > +} > > > > > + > > > > > /* This routine called with relocation disabled. */ > > > > > static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > > > > phys_size_t size, enum lmb_flags flags) > > > > > { > > > > > unsigned long coalesced = 0; > > > > > - long adjacent, i; > > > > > + long ret, i; > > > > > > > > > > if (rgn->cnt == 0) { > > > > > rgn->region[0].base = base; > > > > > @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > > > > return -1; /* regions with new flags */ > > > > > } > > > > > > > > > > - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > > > > - if (adjacent > 0) { > > > > > + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > > > > + if (ret > 0) { > > > > > if (flags != rgnflags) > > > > > break; > > > > > rgn->region[i].base -= size; > > > > > rgn->region[i].size += size; > > > > > coalesced++; > > > > > break; > > > > > - } else if (adjacent < 0) { > > > > > + } else if (ret < 0) { > > > > > if (flags != rgnflags) > > > > > break; > > > > > rgn->region[i].size += size; > > > > > coalesced++; > > > > > break; > > > > > } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { > > > > > - /* regions overlap */ > > > > > - return -1; > > > > > + if (flags == LMB_NONE) { > > > > > + ret = lmb_resize_regions(rgn, i, base, size, > > > > > + flags); > > > > > + if (ret < 0) > > > > > + return -1; > > > > > + > > > > > + coalesced++; > > > > > + break; > > > > > + } else { > > > > > + return -1; > > > > > + } > > > > > } > > > > > } > > > > > > > > > > @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) > > > > > } > > > > > > > > > > static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, > > > > > - phys_addr_t max_addr) > > > > > + phys_addr_t max_addr, enum lmb_flags flags) > > > > > { > > > > > long i, rgn; > > > > > phys_addr_t base = 0; > > > > > @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > > > > { > > > > > phys_addr_t alloc; > > > > > > > > > > - alloc = __lmb_alloc_base(size, align, max_addr); > > > > > + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); > > > > > > > > > > if (alloc == 0) > > > > > printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > > > > > @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > > > > return alloc; > > > > > } > > > > > > > > > > -/* > > > > > - * Try to allocate a specific address range: must be in defined memory but not > > > > > - * reserved > > > > > - */ > > > > > -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > > > +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, > > > > > + enum lmb_flags flags) > > > > > { > > > > > long rgn; > > > > > > > > > > @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > > > lmb.memory.region[rgn].size, > > > > > base + size - 1, 1)) { > > > > > /* ok, reserve the memory */ > > > > > - if (lmb_reserve(base, size) >= 0) > > > > > + if (lmb_reserve_flags(base, size, flags) >= 0) > > > > > return base; > > > > > } > > > > > } > > > > > + > > > > > return 0; > > > > > } > > > > > > > > > > +/* > > > > > + * Try to allocate a specific address range: must be in defined memory but not > > > > > + * reserved > > > > > + */ > > > > > +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > > > +{ > > > > > + return __lmb_alloc_addr(base, size, LMB_NONE); > > > > > +} > > > > > + > > > > > /* Return number of bytes from a given address that are free */ > > > > > phys_size_t lmb_get_free_size(phys_addr_t addr) > > > > > { > > > > > -- > > > > > 2.34.1 > > > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-10 14:21 ` Ilias Apalodimas @ 2024-06-10 14:33 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 14:33 UTC (permalink / raw) To: Ilias Apalodimas Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam hi Ilias, On Mon, 10 Jun 2024 at 19:52, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > Hi Sughosh > > On Mon, 10 Jun 2024 at 15:57, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > On Mon, 10 Jun 2024 at 18:17, Ilias Apalodimas > > <ilias.apalodimas@linaro.org> wrote: > > > > > > On Mon, 10 Jun 2024 at 15:20, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > > > hi Ilias, > > > > > > > > On Mon, 10 Jun 2024 at 17:34, Ilias Apalodimas > > > > <ilias.apalodimas@linaro.org> wrote: > > > > > > > > > > Hi Sughosh > > > > > > > > > > > > > > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > > > > > > > Allow for resizing of LMB regions if the region attributes match. The > > > > > > current code returns a failure status on detecting an overlapping > > > > > > address. This worked up until now since the LMB calls were not > > > > > > persistent and global -- the LMB memory map was specific and private > > > > > > to a given caller of the LMB API's. > > > > > > > > > > > > With the change in the LMB code to make the LMB reservations > > > > > > persistent, there needs to be a check on whether the memory region can > > > > > > be resized, and then do it if so. To distinguish between memory that > > > > > > cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region > > > > > > of memory with this attribute would indicate that the region cannot be > > > > > > resized. > > > > > > > > > > Can you think of a memory region that needs to be protected from resizing? > > > > > > > > Actually, I think I could use a better term instead of 'resize'. The > > > > aim of this patch is to allow re-allocation/re-reservation of the same > > > > region of memory -- this will only be relevant for the LMB > > > > reservations, as these are used for loading images into memory. All > > > > other allocations(EFI currently) are true allocations in that these > > > > should not get overwritten at all. Memory once allocated, say for > > > > loading an EFI image, cannot be re-requested. > > > > > > > > > > > > > I think we should design this a bit differently. For example, think > > > > > of someone loading a file in a memory region and then a subsystem > > > > > trying to resize its reserved memory overwriting that region. Instead > > > > > of this flag why don't we add > > > > > - A flag that indicates whether this region can be re-used (IOW > > > > > overwrites it), but only if the 'subsytem id' defined below matches > > > > > - a u32 that indicates the subsystem ID that initiated the transaction > > > > > -- e.g EFI, load command, U-Boot core .. etc > > > > > > > > > > Resizing can be enabled unconditionally in that case as long as there > > > > > is enough space. The only requirement would be that the request comes > > > > > from the same subsystem that reserved the memory in the beginning > > > > > > > > Like I mentioned above, resizing(or rather re-allocations) should only > > > > be allowed for the LMB subsystem. Any other module should not be > > > > returned an already allocated address. Which is why I mark any memory > > > > map update coming from the EFI module as no-overwrite. > > > > > > And what happens if someone tries to overwrite 'load' memory? Won't > > > you still corrupt whatever is loaded on that region as it's not marked > > > for protection? > > > > Yes, but that is the expected behavior in U-Boot for LMB memory. > > Consider the following flow, > > > > 1) load hostfs - $some_addr $some_image > > 2) fs.write $some_addr $some_destination $filesize > > 3) load hostfs - $some_addr $some_other_image > > 4) fs.write $some_addr $some_other_destination $filesize > > > > The above flow is very much valid, and this exercises the same region > > of LMB memory. Which is why we need to allow re-using the same memory > > address for LMB. This worked up until now since all LMB > > allocations/reservations were private. This is user visible behaviour, > > and used in many scripts used by platforms to read and write files. So > > even after making the LMB memory map global and persistent, this > > aspect of re-use of LMB memory must be maintained. > > I am not talking about this. I haven't gone through all the patches > yet, so I might be missing something but... > What if a user loads a file to boot and then an EFI subsystem decides > to allocate memory -- e.g the EventLog and that allocation routine > returns memory within the space you just loaded the binary from? Yes > memory should be overwritten to preserve the current behavior, but > only if you perform the same action/command In the scenario you describe above, what happens is that the file getting loaded to memory by a user is LMB memory. When this action happens, this gets notified to the EFI memory module, and the EFI memory map gets updated, and this region of memory gets marked as not EFI_CONVENTIONAL_MEMORY. So, when the EFI subsystem has to allocate memory, say for the EventLog, the efi_find_free_memory would not return that memory, as the EFI memory map has been updated. Hence the EFI subsystem would allocate the next available memory region that it finds. The idea is pretty simple. Whenever a module allocates memory, it notifies the other module, and that memory can then not be used by the other module. In case of LMB memory, a request to re-use that memory does not fail, because of how LMB memory is used in U-Boot. -sughosh > > Thanks > /Ilias > > > > -sughosh > > > > > > > > /Ilias > > > > > > > > -sughosh > > > > > > > > > > Thanks > > > > > /Ilias > > > > > > > > > > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > > > --- > > > > > > include/lmb.h | 1 + > > > > > > lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ > > > > > > 2 files changed, 107 insertions(+), 14 deletions(-) > > > > > > > > > > > > diff --git a/include/lmb.h b/include/lmb.h > > > > > > index 03bce2a50c..1d4cd255d2 100644 > > > > > > --- a/include/lmb.h > > > > > > +++ b/include/lmb.h > > > > > > @@ -20,6 +20,7 @@ > > > > > > enum lmb_flags { > > > > > > LMB_NONE = 0x0, > > > > > > LMB_NOMAP = 0x4, > > > > > > + LMB_NOOVERWRITE = 0x8, > > > > > > }; > > > > > > > > > > > > /** > > > > > > diff --git a/lib/lmb.c b/lib/lmb.c > > > > > > index de5a2cf23b..0a4f3d5bcd 100644 > > > > > > --- a/lib/lmb.c > > > > > > +++ b/lib/lmb.c > > > > > > @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) > > > > > > } > > > > > > } > > > > > > > > > > > > +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, > > > > > > + enum lmb_flags flags) > > > > > > +{ > > > > > > + return rgn->region[r1].flags == flags; > > > > > > +} > > > > > > + > > > > > > +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, > > > > > > + phys_addr_t base, phys_size_t size, > > > > > > + enum lmb_flags flags) > > > > > > +{ > > > > > > + phys_size_t rgnsize; > > > > > > + unsigned long rgn_cnt, idx; > > > > > > + phys_addr_t rgnbase, rgnend; > > > > > > + phys_addr_t mergebase, mergeend; > > > > > > + > > > > > > + rgn_cnt = 0; > > > > > > + idx = i; > > > > > > + /* > > > > > > + * First thing to do is to identify how many regions does > > > > > > + * the requested region overlap. > > > > > > + * If the flags match, combine all these overlapping > > > > > > + * regions into a single region, and remove the merged > > > > > > + * regions. > > > > > > + */ > > > > > > + while (idx < rgn->cnt - 1) { > > > > > > + rgnbase = rgn->region[idx].base; > > > > > > + rgnsize = rgn->region[idx].size; > > > > > > + > > > > > > + if (lmb_addrs_overlap(base, size, rgnbase, > > > > > > + rgnsize)) { > > > > > > + if (!lmb_region_flags_match(rgn, idx, flags)) > > > > > > + return -1; > > > > > > + rgn_cnt++; > > > > > > + idx++; > > > > > > + } > > > > > > + } > > > > > > + > > > > > > + /* The merged region's base and size */ > > > > > > + rgnbase = rgn->region[i].base; > > > > > > + mergebase = min(base, rgnbase); > > > > > > + rgnend = rgn->region[idx].base + rgn->region[idx].size; > > > > > > + mergeend = max(rgnend, (base + size)); > > > > > > + > > > > > > + rgn->region[i].base = mergebase; > > > > > > + rgn->region[i].size = mergeend - mergebase; > > > > > > + > > > > > > + /* Now remove the merged regions */ > > > > > > + while (--rgn_cnt) > > > > > > + lmb_remove_region(rgn, i + 1); > > > > > > + > > > > > > + return 0; > > > > > > +} > > > > > > + > > > > > > +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, > > > > > > + phys_addr_t base, phys_size_t size, > > > > > > + enum lmb_flags flags) > > > > > > +{ > > > > > > + long ret = 0; > > > > > > + phys_addr_t rgnend; > > > > > > + > > > > > > + if (i == rgn->cnt - 1 || > > > > > > + base + size < rgn->region[i + 1].base) { > > > > > > + if (!lmb_region_flags_match(rgn, i, flags)) > > > > > > + return -1; > > > > > > + > > > > > > + rgnend = rgn->region[i].base + rgn->region[i].size; > > > > > > + rgn->region[i].base = min(base, rgn->region[i].base); > > > > > > + rgnend = max(base + size, rgnend); > > > > > > + rgn->region[i].size = rgnend - rgn->region[i].base; > > > > > > + } else { > > > > > > + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); > > > > > > + } > > > > > > + > > > > > > + return ret; > > > > > > +} > > > > > > + > > > > > > /* This routine called with relocation disabled. */ > > > > > > static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > > > > > phys_size_t size, enum lmb_flags flags) > > > > > > { > > > > > > unsigned long coalesced = 0; > > > > > > - long adjacent, i; > > > > > > + long ret, i; > > > > > > > > > > > > if (rgn->cnt == 0) { > > > > > > rgn->region[0].base = base; > > > > > > @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > > > > > return -1; /* regions with new flags */ > > > > > > } > > > > > > > > > > > > - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > > > > > - if (adjacent > 0) { > > > > > > + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > > > > > + if (ret > 0) { > > > > > > if (flags != rgnflags) > > > > > > break; > > > > > > rgn->region[i].base -= size; > > > > > > rgn->region[i].size += size; > > > > > > coalesced++; > > > > > > break; > > > > > > - } else if (adjacent < 0) { > > > > > > + } else if (ret < 0) { > > > > > > if (flags != rgnflags) > > > > > > break; > > > > > > rgn->region[i].size += size; > > > > > > coalesced++; > > > > > > break; > > > > > > } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { > > > > > > - /* regions overlap */ > > > > > > - return -1; > > > > > > + if (flags == LMB_NONE) { > > > > > > + ret = lmb_resize_regions(rgn, i, base, size, > > > > > > + flags); > > > > > > + if (ret < 0) > > > > > > + return -1; > > > > > > + > > > > > > + coalesced++; > > > > > > + break; > > > > > > + } else { > > > > > > + return -1; > > > > > > + } > > > > > > } > > > > > > } > > > > > > > > > > > > @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) > > > > > > } > > > > > > > > > > > > static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, > > > > > > - phys_addr_t max_addr) > > > > > > + phys_addr_t max_addr, enum lmb_flags flags) > > > > > > { > > > > > > long i, rgn; > > > > > > phys_addr_t base = 0; > > > > > > @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > > > > > { > > > > > > phys_addr_t alloc; > > > > > > > > > > > > - alloc = __lmb_alloc_base(size, align, max_addr); > > > > > > + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); > > > > > > > > > > > > if (alloc == 0) > > > > > > printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > > > > > > @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > > > > > return alloc; > > > > > > } > > > > > > > > > > > > -/* > > > > > > - * Try to allocate a specific address range: must be in defined memory but not > > > > > > - * reserved > > > > > > - */ > > > > > > -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > > > > +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, > > > > > > + enum lmb_flags flags) > > > > > > { > > > > > > long rgn; > > > > > > > > > > > > @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > > > > lmb.memory.region[rgn].size, > > > > > > base + size - 1, 1)) { > > > > > > /* ok, reserve the memory */ > > > > > > - if (lmb_reserve(base, size) >= 0) > > > > > > + if (lmb_reserve_flags(base, size, flags) >= 0) > > > > > > return base; > > > > > > } > > > > > > } > > > > > > + > > > > > > return 0; > > > > > > } > > > > > > > > > > > > +/* > > > > > > + * Try to allocate a specific address range: must be in defined memory but not > > > > > > + * reserved > > > > > > + */ > > > > > > +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > > > > > +{ > > > > > > + return __lmb_alloc_addr(base, size, LMB_NONE); > > > > > > +} > > > > > > + > > > > > > /* Return number of bytes from a given address that are free */ > > > > > > phys_size_t lmb_get_free_size(phys_addr_t addr) > > > > > > { > > > > > > -- > > > > > > 2.34.1 > > > > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-10 12:20 ` Sughosh Ganu 2024-06-10 12:47 ` Ilias Apalodimas @ 2024-06-10 12:54 ` Heinrich Schuchardt 2024-06-10 13:01 ` Sughosh Ganu 1 sibling, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-10 12:54 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Ilias Apalodimas On 10.06.24 14:20, Sughosh Ganu wrote: > hi Ilias, > > On Mon, 10 Jun 2024 at 17:34, Ilias Apalodimas > <ilias.apalodimas@linaro.org> wrote: >> >> Hi Sughosh >> >> >> On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: >>> >>> Allow for resizing of LMB regions if the region attributes match. The >>> current code returns a failure status on detecting an overlapping >>> address. This worked up until now since the LMB calls were not >>> persistent and global -- the LMB memory map was specific and private >>> to a given caller of the LMB API's. >>> >>> With the change in the LMB code to make the LMB reservations >>> persistent, there needs to be a check on whether the memory region can >>> be resized, and then do it if so. To distinguish between memory that >>> cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region >>> of memory with this attribute would indicate that the region cannot be >>> resized. >> >> Can you think of a memory region that needs to be protected from resizing? > > Actually, I think I could use a better term instead of 'resize'. The > aim of this patch is to allow re-allocation/re-reservation of the same > region of memory -- this will only be relevant for the LMB > reservations, as these are used for loading images into memory. All > other allocations(EFI currently) are true allocations in that these > should not get overwritten at all. Memory once allocated, say for > loading an EFI image, cannot be re-requested. > > >> I think we should design this a bit differently. For example, think >> of someone loading a file in a memory region and then a subsystem >> trying to resize its reserved memory overwriting that region. Instead >> of this flag why don't we add >> - A flag that indicates whether this region can be re-used (IOW >> overwrites it), but only if the 'subsytem id' defined below matches >> - a u32 that indicates the subsystem ID that initiated the transaction >> -- e.g EFI, load command, U-Boot core .. etc >> >> Resizing can be enabled unconditionally in that case as long as there >> is enough space. The only requirement would be that the request comes >> from the same subsystem that reserved the memory in the beginning > > Like I mentioned above, resizing(or rather re-allocations) should only > be allowed for the LMB subsystem. Any other module should not be > returned an already allocated address. Which is why I mark any memory > map update coming from the EFI module as no-overwrite. > > -sughosh >> >> Thanks >> /Ilias >> >>> >>> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> >>> --- >>> include/lmb.h | 1 + >>> lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ >>> 2 files changed, 107 insertions(+), 14 deletions(-) >>> >>> diff --git a/include/lmb.h b/include/lmb.h >>> index 03bce2a50c..1d4cd255d2 100644 >>> --- a/include/lmb.h >>> +++ b/include/lmb.h >>> @@ -20,6 +20,7 @@ >>> enum lmb_flags { >>> LMB_NONE = 0x0, >>> LMB_NOMAP = 0x4, >>> + LMB_NOOVERWRITE = 0x8, >>> }; >>> >>> /** >>> diff --git a/lib/lmb.c b/lib/lmb.c >>> index de5a2cf23b..0a4f3d5bcd 100644 >>> --- a/lib/lmb.c >>> +++ b/lib/lmb.c >>> @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) >>> } >>> } >>> >>> +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, >>> + enum lmb_flags flags) >>> +{ >>> + return rgn->region[r1].flags == flags; >>> +} >>> + >>> +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, >>> + phys_addr_t base, phys_size_t size, >>> + enum lmb_flags flags) >>> +{ >>> + phys_size_t rgnsize; >>> + unsigned long rgn_cnt, idx; >>> + phys_addr_t rgnbase, rgnend; >>> + phys_addr_t mergebase, mergeend; >>> + >>> + rgn_cnt = 0; >>> + idx = i; >>> + /* >>> + * First thing to do is to identify how many regions does >>> + * the requested region overlap. >>> + * If the flags match, combine all these overlapping >>> + * regions into a single region, and remove the merged >>> + * regions. >>> + */ >>> + while (idx < rgn->cnt - 1) { >>> + rgnbase = rgn->region[idx].base; >>> + rgnsize = rgn->region[idx].size; It would be preferable to replace fixed size arrays by linked lists. This will allow us to eliminate CONFIG_LMB_MAX_REGIONS. EFI may create any number of non-coalescable memory regions. Best regards Heinrich >>> + >>> + if (lmb_addrs_overlap(base, size, rgnbase, >>> + rgnsize)) { >>> + if (!lmb_region_flags_match(rgn, idx, flags)) >>> + return -1; >>> + rgn_cnt++; >>> + idx++; >>> + } >>> + } >>> + >>> + /* The merged region's base and size */ >>> + rgnbase = rgn->region[i].base; >>> + mergebase = min(base, rgnbase); >>> + rgnend = rgn->region[idx].base + rgn->region[idx].size; >>> + mergeend = max(rgnend, (base + size)); >>> + >>> + rgn->region[i].base = mergebase; >>> + rgn->region[i].size = mergeend - mergebase; >>> + >>> + /* Now remove the merged regions */ >>> + while (--rgn_cnt) >>> + lmb_remove_region(rgn, i + 1); >>> + >>> + return 0; >>> +} >>> + >>> +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, >>> + phys_addr_t base, phys_size_t size, >>> + enum lmb_flags flags) >>> +{ >>> + long ret = 0; >>> + phys_addr_t rgnend; >>> + >>> + if (i == rgn->cnt - 1 || >>> + base + size < rgn->region[i + 1].base) { >>> + if (!lmb_region_flags_match(rgn, i, flags)) >>> + return -1; >>> + >>> + rgnend = rgn->region[i].base + rgn->region[i].size; >>> + rgn->region[i].base = min(base, rgn->region[i].base); >>> + rgnend = max(base + size, rgnend); >>> + rgn->region[i].size = rgnend - rgn->region[i].base; >>> + } else { >>> + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); >>> + } >>> + >>> + return ret; >>> +} >>> + >>> /* This routine called with relocation disabled. */ >>> static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, >>> phys_size_t size, enum lmb_flags flags) >>> { >>> unsigned long coalesced = 0; >>> - long adjacent, i; >>> + long ret, i; >>> >>> if (rgn->cnt == 0) { >>> rgn->region[0].base = base; >>> @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, >>> return -1; /* regions with new flags */ >>> } >>> >>> - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); >>> - if (adjacent > 0) { >>> + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); >>> + if (ret > 0) { >>> if (flags != rgnflags) >>> break; >>> rgn->region[i].base -= size; >>> rgn->region[i].size += size; >>> coalesced++; >>> break; >>> - } else if (adjacent < 0) { >>> + } else if (ret < 0) { >>> if (flags != rgnflags) >>> break; >>> rgn->region[i].size += size; >>> coalesced++; >>> break; >>> } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { >>> - /* regions overlap */ >>> - return -1; >>> + if (flags == LMB_NONE) { >>> + ret = lmb_resize_regions(rgn, i, base, size, >>> + flags); >>> + if (ret < 0) >>> + return -1; >>> + >>> + coalesced++; >>> + break; >>> + } else { >>> + return -1; >>> + } >>> } >>> } >>> >>> @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) >>> } >>> >>> static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, >>> - phys_addr_t max_addr) >>> + phys_addr_t max_addr, enum lmb_flags flags) >>> { >>> long i, rgn; >>> phys_addr_t base = 0; >>> @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) >>> { >>> phys_addr_t alloc; >>> >>> - alloc = __lmb_alloc_base(size, align, max_addr); >>> + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); >>> >>> if (alloc == 0) >>> printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", >>> @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) >>> return alloc; >>> } >>> >>> -/* >>> - * Try to allocate a specific address range: must be in defined memory but not >>> - * reserved >>> - */ >>> -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) >>> +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, >>> + enum lmb_flags flags) >>> { >>> long rgn; >>> >>> @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) >>> lmb.memory.region[rgn].size, >>> base + size - 1, 1)) { >>> /* ok, reserve the memory */ >>> - if (lmb_reserve(base, size) >= 0) >>> + if (lmb_reserve_flags(base, size, flags) >= 0) >>> return base; >>> } >>> } >>> + >>> return 0; >>> } >>> >>> +/* >>> + * Try to allocate a specific address range: must be in defined memory but not >>> + * reserved >>> + */ >>> +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) >>> +{ >>> + return __lmb_alloc_addr(base, size, LMB_NONE); >>> +} >>> + >>> /* Return number of bytes from a given address that are free */ >>> phys_size_t lmb_get_free_size(phys_addr_t addr) >>> { >>> -- >>> 2.34.1 >>> ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-10 12:54 ` Heinrich Schuchardt @ 2024-06-10 13:01 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 13:01 UTC (permalink / raw) To: Heinrich Schuchardt Cc: u-boot, Tom Rini, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Ilias Apalodimas On Mon, 10 Jun 2024 at 18:29, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 10.06.24 14:20, Sughosh Ganu wrote: > > hi Ilias, > > > > On Mon, 10 Jun 2024 at 17:34, Ilias Apalodimas > > <ilias.apalodimas@linaro.org> wrote: > >> > >> Hi Sughosh > >> > >> > >> On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > >>> > >>> Allow for resizing of LMB regions if the region attributes match. The > >>> current code returns a failure status on detecting an overlapping > >>> address. This worked up until now since the LMB calls were not > >>> persistent and global -- the LMB memory map was specific and private > >>> to a given caller of the LMB API's. > >>> > >>> With the change in the LMB code to make the LMB reservations > >>> persistent, there needs to be a check on whether the memory region can > >>> be resized, and then do it if so. To distinguish between memory that > >>> cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region > >>> of memory with this attribute would indicate that the region cannot be > >>> resized. > >> > >> Can you think of a memory region that needs to be protected from resizing? > > > > Actually, I think I could use a better term instead of 'resize'. The > > aim of this patch is to allow re-allocation/re-reservation of the same > > region of memory -- this will only be relevant for the LMB > > reservations, as these are used for loading images into memory. All > > other allocations(EFI currently) are true allocations in that these > > should not get overwritten at all. Memory once allocated, say for > > loading an EFI image, cannot be re-requested. > > > > > >> I think we should design this a bit differently. For example, think > >> of someone loading a file in a memory region and then a subsystem > >> trying to resize its reserved memory overwriting that region. Instead > >> of this flag why don't we add > >> - A flag that indicates whether this region can be re-used (IOW > >> overwrites it), but only if the 'subsytem id' defined below matches > >> - a u32 that indicates the subsystem ID that initiated the transaction > >> -- e.g EFI, load command, U-Boot core .. etc > >> > >> Resizing can be enabled unconditionally in that case as long as there > >> is enough space. The only requirement would be that the request comes > >> from the same subsystem that reserved the memory in the beginning > > > > Like I mentioned above, resizing(or rather re-allocations) should only > > be allowed for the LMB subsystem. Any other module should not be > > returned an already allocated address. Which is why I mark any memory > > map update coming from the EFI module as no-overwrite. > > > > -sughosh > >> > >> Thanks > >> /Ilias > >> > >>> > >>> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > >>> --- > >>> include/lmb.h | 1 + > >>> lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ > >>> 2 files changed, 107 insertions(+), 14 deletions(-) > >>> > >>> diff --git a/include/lmb.h b/include/lmb.h > >>> index 03bce2a50c..1d4cd255d2 100644 > >>> --- a/include/lmb.h > >>> +++ b/include/lmb.h > >>> @@ -20,6 +20,7 @@ > >>> enum lmb_flags { > >>> LMB_NONE = 0x0, > >>> LMB_NOMAP = 0x4, > >>> + LMB_NOOVERWRITE = 0x8, > >>> }; > >>> > >>> /** > >>> diff --git a/lib/lmb.c b/lib/lmb.c > >>> index de5a2cf23b..0a4f3d5bcd 100644 > >>> --- a/lib/lmb.c > >>> +++ b/lib/lmb.c > >>> @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) > >>> } > >>> } > >>> > >>> +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, > >>> + enum lmb_flags flags) > >>> +{ > >>> + return rgn->region[r1].flags == flags; > >>> +} > >>> + > >>> +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, > >>> + phys_addr_t base, phys_size_t size, > >>> + enum lmb_flags flags) > >>> +{ > >>> + phys_size_t rgnsize; > >>> + unsigned long rgn_cnt, idx; > >>> + phys_addr_t rgnbase, rgnend; > >>> + phys_addr_t mergebase, mergeend; > >>> + > >>> + rgn_cnt = 0; > >>> + idx = i; > >>> + /* > >>> + * First thing to do is to identify how many regions does > >>> + * the requested region overlap. > >>> + * If the flags match, combine all these overlapping > >>> + * regions into a single region, and remove the merged > >>> + * regions. > >>> + */ > >>> + while (idx < rgn->cnt - 1) { > >>> + rgnbase = rgn->region[idx].base; > >>> + rgnsize = rgn->region[idx].size; > > It would be preferable to replace fixed size arrays by linked lists. > This will allow us to eliminate CONFIG_LMB_MAX_REGIONS. > > EFI may create any number of non-coalescable memory regions. Noted. I will work on this change for the next version. -sughosh > > Best regards > > Heinrich > > >>> + > >>> + if (lmb_addrs_overlap(base, size, rgnbase, > >>> + rgnsize)) { > >>> + if (!lmb_region_flags_match(rgn, idx, flags)) > >>> + return -1; > >>> + rgn_cnt++; > >>> + idx++; > >>> + } > >>> + } > >>> + > >>> + /* The merged region's base and size */ > >>> + rgnbase = rgn->region[i].base; > >>> + mergebase = min(base, rgnbase); > >>> + rgnend = rgn->region[idx].base + rgn->region[idx].size; > >>> + mergeend = max(rgnend, (base + size)); > >>> + > >>> + rgn->region[i].base = mergebase; > >>> + rgn->region[i].size = mergeend - mergebase; > >>> + > >>> + /* Now remove the merged regions */ > >>> + while (--rgn_cnt) > >>> + lmb_remove_region(rgn, i + 1); > >>> + > >>> + return 0; > >>> +} > >>> + > >>> +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, > >>> + phys_addr_t base, phys_size_t size, > >>> + enum lmb_flags flags) > >>> +{ > >>> + long ret = 0; > >>> + phys_addr_t rgnend; > >>> + > >>> + if (i == rgn->cnt - 1 || > >>> + base + size < rgn->region[i + 1].base) { > >>> + if (!lmb_region_flags_match(rgn, i, flags)) > >>> + return -1; > >>> + > >>> + rgnend = rgn->region[i].base + rgn->region[i].size; > >>> + rgn->region[i].base = min(base, rgn->region[i].base); > >>> + rgnend = max(base + size, rgnend); > >>> + rgn->region[i].size = rgnend - rgn->region[i].base; > >>> + } else { > >>> + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); > >>> + } > >>> + > >>> + return ret; > >>> +} > >>> + > >>> /* This routine called with relocation disabled. */ > >>> static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > >>> phys_size_t size, enum lmb_flags flags) > >>> { > >>> unsigned long coalesced = 0; > >>> - long adjacent, i; > >>> + long ret, i; > >>> > >>> if (rgn->cnt == 0) { > >>> rgn->region[0].base = base; > >>> @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > >>> return -1; /* regions with new flags */ > >>> } > >>> > >>> - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > >>> - if (adjacent > 0) { > >>> + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > >>> + if (ret > 0) { > >>> if (flags != rgnflags) > >>> break; > >>> rgn->region[i].base -= size; > >>> rgn->region[i].size += size; > >>> coalesced++; > >>> break; > >>> - } else if (adjacent < 0) { > >>> + } else if (ret < 0) { > >>> if (flags != rgnflags) > >>> break; > >>> rgn->region[i].size += size; > >>> coalesced++; > >>> break; > >>> } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { > >>> - /* regions overlap */ > >>> - return -1; > >>> + if (flags == LMB_NONE) { > >>> + ret = lmb_resize_regions(rgn, i, base, size, > >>> + flags); > >>> + if (ret < 0) > >>> + return -1; > >>> + > >>> + coalesced++; > >>> + break; > >>> + } else { > >>> + return -1; > >>> + } > >>> } > >>> } > >>> > >>> @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) > >>> } > >>> > >>> static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, > >>> - phys_addr_t max_addr) > >>> + phys_addr_t max_addr, enum lmb_flags flags) > >>> { > >>> long i, rgn; > >>> phys_addr_t base = 0; > >>> @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > >>> { > >>> phys_addr_t alloc; > >>> > >>> - alloc = __lmb_alloc_base(size, align, max_addr); > >>> + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); > >>> > >>> if (alloc == 0) > >>> printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > >>> @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > >>> return alloc; > >>> } > >>> > >>> -/* > >>> - * Try to allocate a specific address range: must be in defined memory but not > >>> - * reserved > >>> - */ > >>> -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > >>> +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, > >>> + enum lmb_flags flags) > >>> { > >>> long rgn; > >>> > >>> @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > >>> lmb.memory.region[rgn].size, > >>> base + size - 1, 1)) { > >>> /* ok, reserve the memory */ > >>> - if (lmb_reserve(base, size) >= 0) > >>> + if (lmb_reserve_flags(base, size, flags) >= 0) > >>> return base; > >>> } > >>> } > >>> + > >>> return 0; > >>> } > >>> > >>> +/* > >>> + * Try to allocate a specific address range: must be in defined memory but not > >>> + * reserved > >>> + */ > >>> +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > >>> +{ > >>> + return __lmb_alloc_addr(base, size, LMB_NONE); > >>> +} > >>> + > >>> /* Return number of bytes from a given address that are free */ > >>> phys_size_t lmb_get_free_size(phys_addr_t addr) > >>> { > >>> -- > >>> 2.34.1 > >>> > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-07 18:52 ` [RFC PATCH 09/31] lmb: allow for resizing lmb regions Sughosh Ganu 2024-06-10 12:03 ` Ilias Apalodimas @ 2024-06-11 9:17 ` Heinrich Schuchardt 2024-06-11 9:50 ` Sughosh Ganu 1 sibling, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-11 9:17 UTC (permalink / raw) To: Sughosh Ganu Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On 07.06.24 20:52, Sughosh Ganu wrote: > Allow for resizing of LMB regions if the region attributes match. The > current code returns a failure status on detecting an overlapping > address. This worked up until now since the LMB calls were not > persistent and global -- the LMB memory map was specific and private > to a given caller of the LMB API's. > > With the change in the LMB code to make the LMB reservations > persistent, there needs to be a check on whether the memory region can > be resized, and then do it if so. To distinguish between memory that > cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region > of memory with this attribute would indicate that the region cannot be > resized. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > include/lmb.h | 1 + > lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 107 insertions(+), 14 deletions(-) > > diff --git a/include/lmb.h b/include/lmb.h > index 03bce2a50c..1d4cd255d2 100644 > --- a/include/lmb.h > +++ b/include/lmb.h > @@ -20,6 +20,7 @@ > enum lmb_flags { > LMB_NONE = 0x0, > LMB_NOMAP = 0x4, > + LMB_NOOVERWRITE = 0x8, Please, add the missing description for the new value. Using the first available bit (0x01) would be expected. Using the BIT macro would make it clearer that these are bits of a bitmap: enum lmb_flags { LMB_NONE = BIT(0), LMB_NOOVERWRITE = BIT(1), }; Best regards Heinrich > }; > > /** > diff --git a/lib/lmb.c b/lib/lmb.c > index de5a2cf23b..0a4f3d5bcd 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) > } > } > > +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, > + enum lmb_flags flags) > +{ > + return rgn->region[r1].flags == flags; > +} > + > +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, > + phys_addr_t base, phys_size_t size, > + enum lmb_flags flags) > +{ > + phys_size_t rgnsize; > + unsigned long rgn_cnt, idx; > + phys_addr_t rgnbase, rgnend; > + phys_addr_t mergebase, mergeend; > + > + rgn_cnt = 0; > + idx = i; > + /* > + * First thing to do is to identify how many regions does > + * the requested region overlap. > + * If the flags match, combine all these overlapping > + * regions into a single region, and remove the merged > + * regions. > + */ > + while (idx < rgn->cnt - 1) { > + rgnbase = rgn->region[idx].base; > + rgnsize = rgn->region[idx].size; > + > + if (lmb_addrs_overlap(base, size, rgnbase, > + rgnsize)) { > + if (!lmb_region_flags_match(rgn, idx, flags)) > + return -1; > + rgn_cnt++; > + idx++; > + } > + } > + > + /* The merged region's base and size */ > + rgnbase = rgn->region[i].base; > + mergebase = min(base, rgnbase); > + rgnend = rgn->region[idx].base + rgn->region[idx].size; > + mergeend = max(rgnend, (base + size)); > + > + rgn->region[i].base = mergebase; > + rgn->region[i].size = mergeend - mergebase; > + > + /* Now remove the merged regions */ > + while (--rgn_cnt) > + lmb_remove_region(rgn, i + 1); > + > + return 0; > +} > + > +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, > + phys_addr_t base, phys_size_t size, > + enum lmb_flags flags) > +{ > + long ret = 0; > + phys_addr_t rgnend; > + > + if (i == rgn->cnt - 1 || > + base + size < rgn->region[i + 1].base) { > + if (!lmb_region_flags_match(rgn, i, flags)) > + return -1; > + > + rgnend = rgn->region[i].base + rgn->region[i].size; > + rgn->region[i].base = min(base, rgn->region[i].base); > + rgnend = max(base + size, rgnend); > + rgn->region[i].size = rgnend - rgn->region[i].base; > + } else { > + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); > + } > + > + return ret; > +} > + > /* This routine called with relocation disabled. */ > static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > phys_size_t size, enum lmb_flags flags) > { > unsigned long coalesced = 0; > - long adjacent, i; > + long ret, i; > > if (rgn->cnt == 0) { > rgn->region[0].base = base; > @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > return -1; /* regions with new flags */ > } > > - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > - if (adjacent > 0) { > + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > + if (ret > 0) { > if (flags != rgnflags) > break; > rgn->region[i].base -= size; > rgn->region[i].size += size; > coalesced++; > break; > - } else if (adjacent < 0) { > + } else if (ret < 0) { > if (flags != rgnflags) > break; > rgn->region[i].size += size; > coalesced++; > break; > } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { > - /* regions overlap */ > - return -1; > + if (flags == LMB_NONE) { > + ret = lmb_resize_regions(rgn, i, base, size, > + flags); > + if (ret < 0) > + return -1; > + > + coalesced++; > + break; > + } else { > + return -1; > + } > } > } > > @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) > } > > static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, > - phys_addr_t max_addr) > + phys_addr_t max_addr, enum lmb_flags flags) > { > long i, rgn; > phys_addr_t base = 0; > @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > { > phys_addr_t alloc; > > - alloc = __lmb_alloc_base(size, align, max_addr); > + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); > > if (alloc == 0) > printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > return alloc; > } > > -/* > - * Try to allocate a specific address range: must be in defined memory but not > - * reserved > - */ > -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, > + enum lmb_flags flags) > { > long rgn; > > @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > lmb.memory.region[rgn].size, > base + size - 1, 1)) { > /* ok, reserve the memory */ > - if (lmb_reserve(base, size) >= 0) > + if (lmb_reserve_flags(base, size, flags) >= 0) > return base; > } > } > + > return 0; > } > > +/* > + * Try to allocate a specific address range: must be in defined memory but not > + * reserved > + */ > +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > +{ > + return __lmb_alloc_addr(base, size, LMB_NONE); > +} > + > /* Return number of bytes from a given address that are free */ > phys_size_t lmb_get_free_size(phys_addr_t addr) > { ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 09/31] lmb: allow for resizing lmb regions 2024-06-11 9:17 ` Heinrich Schuchardt @ 2024-06-11 9:50 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-11 9:50 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On Tue, 11 Jun 2024 at 14:47, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 07.06.24 20:52, Sughosh Ganu wrote: > > Allow for resizing of LMB regions if the region attributes match. The > > current code returns a failure status on detecting an overlapping > > address. This worked up until now since the LMB calls were not > > persistent and global -- the LMB memory map was specific and private > > to a given caller of the LMB API's. > > > > With the change in the LMB code to make the LMB reservations > > persistent, there needs to be a check on whether the memory region can > > be resized, and then do it if so. To distinguish between memory that > > cannot be resized, add a new flag, LMB_NOOVERWRITE. Reserving a region > > of memory with this attribute would indicate that the region cannot be > > resized. > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > --- > > include/lmb.h | 1 + > > lib/lmb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------ > > 2 files changed, 107 insertions(+), 14 deletions(-) > > > > diff --git a/include/lmb.h b/include/lmb.h > > index 03bce2a50c..1d4cd255d2 100644 > > --- a/include/lmb.h > > +++ b/include/lmb.h > > @@ -20,6 +20,7 @@ > > enum lmb_flags { > > LMB_NONE = 0x0, > > LMB_NOMAP = 0x4, > > + LMB_NOOVERWRITE = 0x8, > > Please, add the missing description for the new value. Using the first > available bit (0x01) would be expected. > > Using the BIT macro would make it clearer that these are bits of a bitmap: > > enum lmb_flags { > LMB_NONE = BIT(0), > LMB_NOOVERWRITE = BIT(1), > }; Noted. Will change. -sughosh > > Best regards > > Heinrich > > > > }; > > > > /** > > diff --git a/lib/lmb.c b/lib/lmb.c > > index de5a2cf23b..0a4f3d5bcd 100644 > > --- a/lib/lmb.c > > +++ b/lib/lmb.c > > @@ -260,12 +260,88 @@ void lmb_add_memory(struct bd_info *bd) > > } > > } > > > > +static bool lmb_region_flags_match(struct lmb_region *rgn, unsigned long r1, > > + enum lmb_flags flags) > > +{ > > + return rgn->region[r1].flags == flags; > > +} > > + > > +static long lmb_merge_overlap_regions(struct lmb_region *rgn, unsigned long i, > > + phys_addr_t base, phys_size_t size, > > + enum lmb_flags flags) > > +{ > > + phys_size_t rgnsize; > > + unsigned long rgn_cnt, idx; > > + phys_addr_t rgnbase, rgnend; > > + phys_addr_t mergebase, mergeend; > > + > > + rgn_cnt = 0; > > + idx = i; > > + /* > > + * First thing to do is to identify how many regions does > > + * the requested region overlap. > > + * If the flags match, combine all these overlapping > > + * regions into a single region, and remove the merged > > + * regions. > > + */ > > + while (idx < rgn->cnt - 1) { > > + rgnbase = rgn->region[idx].base; > > + rgnsize = rgn->region[idx].size; > > + > > + if (lmb_addrs_overlap(base, size, rgnbase, > > + rgnsize)) { > > + if (!lmb_region_flags_match(rgn, idx, flags)) > > + return -1; > > + rgn_cnt++; > > + idx++; > > + } > > + } > > + > > + /* The merged region's base and size */ > > + rgnbase = rgn->region[i].base; > > + mergebase = min(base, rgnbase); > > + rgnend = rgn->region[idx].base + rgn->region[idx].size; > > + mergeend = max(rgnend, (base + size)); > > + > > + rgn->region[i].base = mergebase; > > + rgn->region[i].size = mergeend - mergebase; > > + > > + /* Now remove the merged regions */ > > + while (--rgn_cnt) > > + lmb_remove_region(rgn, i + 1); > > + > > + return 0; > > +} > > + > > +static long lmb_resize_regions(struct lmb_region *rgn, unsigned long i, > > + phys_addr_t base, phys_size_t size, > > + enum lmb_flags flags) > > +{ > > + long ret = 0; > > + phys_addr_t rgnend; > > + > > + if (i == rgn->cnt - 1 || > > + base + size < rgn->region[i + 1].base) { > > + if (!lmb_region_flags_match(rgn, i, flags)) > > + return -1; > > + > > + rgnend = rgn->region[i].base + rgn->region[i].size; > > + rgn->region[i].base = min(base, rgn->region[i].base); > > + rgnend = max(base + size, rgnend); > > + rgn->region[i].size = rgnend - rgn->region[i].base; > > + } else { > > + ret = lmb_merge_overlap_regions(rgn, i, base, size, flags); > > + } > > + > > + return ret; > > +} > > + > > /* This routine called with relocation disabled. */ > > static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > phys_size_t size, enum lmb_flags flags) > > { > > unsigned long coalesced = 0; > > - long adjacent, i; > > + long ret, i; > > > > if (rgn->cnt == 0) { > > rgn->region[0].base = base; > > @@ -290,23 +366,32 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, > > return -1; /* regions with new flags */ > > } > > > > - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > - if (adjacent > 0) { > > + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); > > + if (ret > 0) { > > if (flags != rgnflags) > > break; > > rgn->region[i].base -= size; > > rgn->region[i].size += size; > > coalesced++; > > break; > > - } else if (adjacent < 0) { > > + } else if (ret < 0) { > > if (flags != rgnflags) > > break; > > rgn->region[i].size += size; > > coalesced++; > > break; > > } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { > > - /* regions overlap */ > > - return -1; > > + if (flags == LMB_NONE) { > > + ret = lmb_resize_regions(rgn, i, base, size, > > + flags); > > + if (ret < 0) > > + return -1; > > + > > + coalesced++; > > + break; > > + } else { > > + return -1; > > + } > > } > > } > > > > @@ -448,7 +533,7 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) > > } > > > > static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, > > - phys_addr_t max_addr) > > + phys_addr_t max_addr, enum lmb_flags flags) > > { > > long i, rgn; > > phys_addr_t base = 0; > > @@ -498,7 +583,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > { > > phys_addr_t alloc; > > > > - alloc = __lmb_alloc_base(size, align, max_addr); > > + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); > > > > if (alloc == 0) > > printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", > > @@ -507,11 +592,8 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) > > return alloc; > > } > > > > -/* > > - * Try to allocate a specific address range: must be in defined memory but not > > - * reserved > > - */ > > -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, > > + enum lmb_flags flags) > > { > > long rgn; > > > > @@ -526,13 +608,23 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > lmb.memory.region[rgn].size, > > base + size - 1, 1)) { > > /* ok, reserve the memory */ > > - if (lmb_reserve(base, size) >= 0) > > + if (lmb_reserve_flags(base, size, flags) >= 0) > > return base; > > } > > } > > + > > return 0; > > } > > > > +/* > > + * Try to allocate a specific address range: must be in defined memory but not > > + * reserved > > + */ > > +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) > > +{ > > + return __lmb_alloc_addr(base, size, LMB_NONE); > > +} > > + > > /* Return number of bytes from a given address that are free */ > > phys_size_t lmb_get_free_size(phys_addr_t addr) > > { > ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 10/31] event: add events to notify memory map changes 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (8 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 09/31] lmb: allow for resizing lmb regions Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates Sughosh Ganu ` (22 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu Add events which would be used for notifying changes in the respective 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 | 4 ++++ include/event.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/common/event.c b/common/event.c index 16c2ba6cc9..067ee9ee4e 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,10 @@ const char *const type_name[] = { /* main loop events */ "main_loop", + + "lmb_map_update", + + "efi_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..9d8be7a103 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,22 @@ 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_EFI_MEM_MAP_UPDATE: + * This event is triggered on an update to the EFI memory map. + * This can be used to notify about any EFI memory allocation + * or freeing of memory having occurred. + */ + EVT_EFI_MEM_MAP_UPDATE, + /** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when @@ -203,6 +219,18 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup; + + struct event_lmb_map_update { + u64 base; + u64 size; + u8 op; + } lmb_map; + + struct event_efi_mem_map_update { + u64 base; + u64 size; + u8 op; + } efi_mem_map; }; /** -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (9 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 10/31] event: add events to notify memory map changes Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-08 3:53 ` Heinrich Schuchardt 2024-06-10 11:44 ` Ilias Apalodimas 2024-06-07 18:52 ` [RFC PATCH 12/31] add a function to check if an address is in RAM memory Sughosh Ganu ` (21 subsequent siblings) 32 siblings, 2 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu Add a Kconfig symbol to enable getting updates on any memory map changes that might be done by some other 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 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/Kconfig b/lib/Kconfig index 189e6eb31a..9ea02ae006 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -74,6 +74,15 @@ config HAVE_PRIVATE_LIBGCC config LIB_UUID bool +config MEM_MAP_UPDATE_NOTIFY + bool "Get notified of any changes to the memory map" + default y if EVENT && LMB && EFI_LOADER + help + Enable this option to get notification on any changes to the + memory that is allocated or freed. This will allow different + modules that allocate memory to have a synchronous view of available + and allocated memory. + config RANDOM_UUID bool "GPT Random UUID generation" select LIB_UUID -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates 2024-06-07 18:52 ` [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates Sughosh Ganu @ 2024-06-08 3:53 ` Heinrich Schuchardt 2024-06-08 4:34 ` Heinrich Schuchardt 2024-06-10 11:44 ` Ilias Apalodimas 1 sibling, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-08 3:53 UTC (permalink / raw) To: Sughosh Ganu, u-boot Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam Am 7. Juni 2024 20:52:20 MESZ schrieb Sughosh Ganu <sughosh.ganu@linaro.org>: >Add a Kconfig symbol to enable getting updates on any memory map >changes that might be done by some other 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 | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/lib/Kconfig b/lib/Kconfig >index 189e6eb31a..9ea02ae006 100644 >--- a/lib/Kconfig >+++ b/lib/Kconfig >@@ -74,6 +74,15 @@ config HAVE_PRIVATE_LIBGCC > config LIB_UUID > bool > >+config MEM_MAP_UPDATE_NOTIFY >+ bool "Get notified of any changes to the memory map" To the "LMB memory map"? >+ default y if EVENT && LMB && EFI_LOADER I am missing 'depends on EVENT && LMB' here. This should allow to simplify the 'default' statement. But why not use select? Best regards Heinrich >+ help >+ Enable this option to get notification on any changes to the >+ memory that is allocated or freed. This will allow different >+ modules that allocate memory to have a synchronous view of available >+ and allocated memory. >+ > config RANDOM_UUID > bool "GPT Random UUID generation" > select LIB_UUID ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates 2024-06-08 3:53 ` Heinrich Schuchardt @ 2024-06-08 4:34 ` Heinrich Schuchardt 0 siblings, 0 replies; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-08 4:34 UTC (permalink / raw) To: Sughosh Ganu Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On 6/8/24 05:53, Heinrich Schuchardt wrote: > > > Am 7. Juni 2024 20:52:20 MESZ schrieb Sughosh Ganu <sughosh.ganu@linaro.org>: >> Add a Kconfig symbol to enable getting updates on any memory map >> changes that might be done by some other 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 | 9 +++++++++ >> 1 file changed, 9 insertions(+) >> >> diff --git a/lib/Kconfig b/lib/Kconfig >> index 189e6eb31a..9ea02ae006 100644 >> --- a/lib/Kconfig >> +++ b/lib/Kconfig >> @@ -74,6 +74,15 @@ config HAVE_PRIVATE_LIBGCC >> config LIB_UUID >> bool >> >> +config MEM_MAP_UPDATE_NOTIFY >> + bool "Get notified of any changes to the memory map" Looking at later patches it seems you are sending memory map events from different memory maps: LMB and EFI. %s/to the memory map/to a memory map/ > > To the "LMB memory map"? > >> + default y if EVENT && LMB && EFI_LOADER > > I am missing 'depends on EVENT && LMB' here. This should allow to simplify the 'default' statement. But why not use select? Sending messaging makes only sense if two memory management systems are present. How about: depends on EVENT && LMB && EFI_LOADER default y > > Best regards > > Heinrich > > > >> + help >> + Enable this option to get notification on any changes to the >> + memory that is allocated or freed. This will allow different >> + modules that allocate memory to have a synchronous view of available >> + and allocated memory. Mentioning LMB and EFI here would be helpful: help U-Boot manages memory allocation in multiple modules: LMB and EFI. To keep them synchronized memory change messages are used. Enable this symbol to ensure synchronization. Best regards Heinrich >> + >> config RANDOM_UUID >> bool "GPT Random UUID generation" >> select LIB_UUID ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates 2024-06-07 18:52 ` [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates Sughosh Ganu 2024-06-08 3:53 ` Heinrich Schuchardt @ 2024-06-10 11:44 ` Ilias Apalodimas 2024-06-10 11:47 ` Sughosh Ganu 1 sibling, 1 reply; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 11:44 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > Add a Kconfig symbol to enable getting updates on any memory map > changes that might be done by some other module. This notification > mechanism can then be used to have a synchronous view of allocated and > free memory. Is there any chance we want to build a firmware that allows memory not to be reserved? I think we should make the feature mandatory Cheers /Ilias > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > lib/Kconfig | 9 +++++++++ > 1 file changed, 9 insertions(+) > > diff --git a/lib/Kconfig b/lib/Kconfig > index 189e6eb31a..9ea02ae006 100644 > --- a/lib/Kconfig > +++ b/lib/Kconfig > @@ -74,6 +74,15 @@ config HAVE_PRIVATE_LIBGCC > config LIB_UUID > bool > > +config MEM_MAP_UPDATE_NOTIFY > + bool "Get notified of any changes to the memory map" > + default y if EVENT && LMB && EFI_LOADER > + help > + Enable this option to get notification on any changes to the > + memory that is allocated or freed. This will allow different > + modules that allocate memory to have a synchronous view of available > + and allocated memory. > + > config RANDOM_UUID > bool "GPT Random UUID generation" > select LIB_UUID > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates 2024-06-10 11:44 ` Ilias Apalodimas @ 2024-06-10 11:47 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 11:47 UTC (permalink / raw) To: Ilias Apalodimas Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam hi Ilias, On Mon, 10 Jun 2024 at 17:15, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > Add a Kconfig symbol to enable getting updates on any memory map > > changes that might be done by some other module. This notification > > mechanism can then be used to have a synchronous view of allocated and > > free memory. > > Is there any chance we want to build a firmware that allows memory not > to be reserved? > I think we should make the feature mandatory LMB is enabled for all architectures, but the EFI code is not. This config is only for enabling the notification code. Which is why it is enabled only when LMB and EFI_LOADER configs are enabled. -sughosh > > Cheers > /Ilias > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > --- > > lib/Kconfig | 9 +++++++++ > > 1 file changed, 9 insertions(+) > > > > diff --git a/lib/Kconfig b/lib/Kconfig > > index 189e6eb31a..9ea02ae006 100644 > > --- a/lib/Kconfig > > +++ b/lib/Kconfig > > @@ -74,6 +74,15 @@ config HAVE_PRIVATE_LIBGCC > > config LIB_UUID > > bool > > > > +config MEM_MAP_UPDATE_NOTIFY > > + bool "Get notified of any changes to the memory map" > > + default y if EVENT && LMB && EFI_LOADER > > + help > > + Enable this option to get notification on any changes to the > > + memory that is allocated or freed. This will allow different > > + modules that allocate memory to have a synchronous view of available > > + and allocated memory. > > + > > config RANDOM_UUID > > bool "GPT Random UUID generation" > > select LIB_UUID > > -- > > 2.34.1 > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 12/31] add a function to check if an address is in RAM memory 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (10 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 13/31] efi_memory: notify of any changes to the EFI memory map Sughosh Ganu ` (20 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu 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> --- arch/sandbox/cpu/cpu.c | 5 +++++ common/board_r.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index 0ed85b354c..d7a0176497 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -413,3 +413,8 @@ int sandbox_load_other_fdt(void **fdtp, int *sizep) return 0; } + +bool __maybe_unused is_addr_in_ram(uintptr_t addr) +{ + return is_in_sandbox_mem((const void *)addr); +} diff --git a/common/board_r.c b/common/board_r.c index a9f0b0cec1..aabc0cdf26 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) { /* -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 13/31] efi_memory: notify of any changes to the EFI memory map 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (11 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 12/31] add a function to check if an address is in RAM memory Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 14/31] lmb: notify of any changes to the LMB " Sughosh Ganu ` (19 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu 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 EFI memory map update event to notify other interested listeners about a change in the EFI memory map. This can then be used by the other module to allocate memory only from available regions, instead of overwriting already allocated memory. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- lib/efi_loader/efi_memory.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 12cf23fa3f..435e580fb3 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -8,6 +8,7 @@ #define LOG_CATEGORY LOGC_EFI #include <efi_loader.h> +#include <event.h> #include <init.h> #include <log.h> #include <malloc.h> @@ -36,6 +37,9 @@ struct efi_mem_list { #define EFI_CARVE_OVERLAPS_NONRAM -3 #define EFI_CARVE_OUT_OF_RESOURCES -4 +#define MAP_OP_RESERVE (u8)0x1 +#define MAP_OP_FREE (u8)0x2 + /* This list contains all memory map items */ static LIST_HEAD(efi_mem); @@ -66,6 +70,22 @@ struct efi_pool_allocation { char data[] __aligned(ARCH_DMA_MINALIGN); }; +#if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) +extern bool is_addr_in_ram(uintptr_t addr); + +static void efi_map_update_notify(u64 addr, u64 size, u8 op) +{ + struct event_efi_mem_map_update efi_map = {0}; + + efi_map.base = addr; + efi_map.size = size; + efi_map.op = op; + + if (is_addr_in_ram((uintptr_t)addr)) + event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); +} +#endif /* MEM_MAP_UPDATE_NOTIFY */ + /** * checksum() - calculate checksum for memory allocated from pool * @@ -375,6 +395,11 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, } } + if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) + efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, + memory_type == EFI_CONVENTIONAL_MEMORY ? + MAP_OP_FREE : MAP_OP_RESERVE); + return EFI_SUCCESS; } -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 14/31] lmb: notify of any changes to the LMB memory map 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (12 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 13/31] efi_memory: notify of any changes to the EFI memory map Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 15/31] efi_memory: add an event handler to update " Sughosh Ganu ` (18 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu 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 allocate memory only from available regions, instead of overwriting already allocated memory. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- lib/lmb.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/lib/lmb.c b/lib/lmb.c index 0a4f3d5bcd..313735dbe3 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -7,6 +7,7 @@ */ #include <efi_loader.h> +#include <event.h> #include <image.h> #include <mapmem.h> #include <lmb.h> @@ -18,8 +19,13 @@ DECLARE_GLOBAL_DATA_PTR; +#define MAP_OP_RESERVE (u8)0x1 +#define MAP_OP_FREE (u8)0x2 + #define LMB_ALLOC_ANYWHERE 0 +extern bool is_addr_in_ram(uintptr_t addr); + #if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS]; struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS]; @@ -39,6 +45,19 @@ struct lmb lmb = { .reserved.cnt = 0, }; +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_dump_region(struct lmb_region *rgn, char *name) { unsigned long long base, size, end; @@ -450,7 +469,7 @@ long lmb_add(phys_addr_t base, phys_size_t size) return lmb_add_region(_rgn, 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 = &lmb.reserved; phys_addr_t rgnbegin, rgnend; @@ -500,11 +519,33 @@ long lmb_free(phys_addr_t base, phys_size_t size) rgn->region[i].flags); } +long lmb_free(phys_addr_t base, phys_size_t size) +{ + long ret; + + ret = __lmb_free(base, size); + if (ret < 0) + return ret; + + if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) + lmb_map_update_notify(base, size, MAP_OP_FREE); + + return 0; +} + long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags) { + long ret = 0; struct lmb_region *_rgn = &lmb.reserved; - return lmb_add_region_flags(_rgn, base, size, flags); + ret = lmb_add_region_flags(_rgn, base, size, flags); + if (ret < 0) + return -1; + + if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) + lmb_map_update_notify(base, size, MAP_OP_RESERVE); + + return ret; } long lmb_reserve(phys_addr_t base, phys_size_t size) @@ -563,6 +604,10 @@ static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, if (lmb_add_region(&lmb.reserved, base, size) < 0) return 0; + + if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) + lmb_map_update_notify(base, size, + MAP_OP_RESERVE); return base; } res_base = lmb.reserved.region[rgn].base; -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (13 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 14/31] lmb: notify of any changes to the LMB " Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 12:09 ` Ilias Apalodimas ` (2 more replies) 2024-06-07 18:52 ` [RFC PATCH 16/31] lmb: " Sughosh Ganu ` (17 subsequent siblings) 32 siblings, 3 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 435e580fb3..93244161b0 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -73,6 +73,10 @@ struct efi_pool_allocation { #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) extern bool is_addr_in_ram(uintptr_t addr); +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, + int memory_type, + bool overlap_only_ram); + static void efi_map_update_notify(u64 addr, u64 size, u8 op) { struct event_efi_mem_map_update efi_map = {0}; @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) if (is_addr_in_ram((uintptr_t)addr)) event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); } + +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) { + log_debug("Invalid map update op received (%d)\n", op); + return -1; + } + + status = __efi_add_memory_map_pg(addr, pages, + op == MAP_OP_FREE ? + EFI_CONVENTIONAL_MEMORY : + EFI_BOOT_SERVICES_DATA, + true); + + return status == EFI_SUCCESS ? 0 : -1; +} +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); #endif /* MEM_MAP_UPDATE_NOTIFY */ /** @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, return EFI_CARVE_LOOP_AGAIN; } -/** - * efi_add_memory_map_pg() - add pages to the memory map - * - * @start: start address, must be a multiple of EFI_PAGE_SIZE - * @pages: number of pages to add - * @memory_type: type of memory added - * @overlap_only_ram: region may only overlap RAM - * Return: status code - */ -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, - int memory_type, - bool overlap_only_ram) +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, + int memory_type, + bool overlap_only_ram) { struct list_head *lhandle; struct efi_mem_list *newlist; @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, } } + return EFI_SUCCESS; +} + +/** + * efi_add_memory_map_pg() - add pages to the memory map + * + * @start: start address, must be a multiple of EFI_PAGE_SIZE + * @pages: number of pages to add + * @memory_type: type of memory added + * @overlap_only_ram: region may only overlap RAM + * Return: status code + */ +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, + int memory_type, + bool overlap_only_ram) +{ + efi_status_t status; + + status = __efi_add_memory_map_pg(start, pages, memory_type, + overlap_only_ram); + if (status != EFI_SUCCESS) + return status; + if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, memory_type == EFI_CONVENTIONAL_MEMORY ? -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-07 18:52 ` [RFC PATCH 15/31] efi_memory: add an event handler to update " Sughosh Ganu @ 2024-06-10 12:09 ` Ilias Apalodimas 2024-06-10 12:25 ` Sughosh Ganu 2024-06-10 15:12 ` Heinrich Schuchardt 2024-06-11 10:17 ` Heinrich Schuchardt 2 siblings, 1 reply; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 12:09 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > 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. So the question here, is why do we need a notifier chain overall? Can't we change the EFI subsystem and allocate memory with lmb now? And any special functions we have in EFI (e.g allocate aligned memory) can migrate to lmb() Cheers /Ilias > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > lib/efi_loader/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > 1 file changed, 58 insertions(+), 12 deletions(-) > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > index 435e580fb3..93244161b0 100644 > --- a/lib/efi_loader/efi_memory.c > +++ b/lib/efi_loader/efi_memory.c > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > extern bool is_addr_in_ram(uintptr_t addr); > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > + int memory_type, > + bool overlap_only_ram); > + > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > { > struct event_efi_mem_map_update efi_map = {0}; > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > if (is_addr_in_ram((uintptr_t)addr)) > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > } > + > +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) { > + log_debug("Invalid map update op received (%d)\n", op); > + return -1; > + } > + > + status = __efi_add_memory_map_pg(addr, pages, > + op == MAP_OP_FREE ? > + EFI_CONVENTIONAL_MEMORY : > + EFI_BOOT_SERVICES_DATA, > + true); > + > + return status == EFI_SUCCESS ? 0 : -1; > +} > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > /** > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > return EFI_CARVE_LOOP_AGAIN; > } > > -/** > - * efi_add_memory_map_pg() - add pages to the memory map > - * > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > - * @pages: number of pages to add > - * @memory_type: type of memory added > - * @overlap_only_ram: region may only overlap RAM > - * Return: status code > - */ > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > - int memory_type, > - bool overlap_only_ram) > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > + int memory_type, > + bool overlap_only_ram) > { > struct list_head *lhandle; > struct efi_mem_list *newlist; > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > } > } > > + return EFI_SUCCESS; > +} > + > +/** > + * efi_add_memory_map_pg() - add pages to the memory map > + * > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > + * @pages: number of pages to add > + * @memory_type: type of memory added > + * @overlap_only_ram: region may only overlap RAM > + * Return: status code > + */ > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > + int memory_type, > + bool overlap_only_ram) > +{ > + efi_status_t status; > + > + status = __efi_add_memory_map_pg(start, pages, memory_type, > + overlap_only_ram); > + if (status != EFI_SUCCESS) > + return status; > + > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > memory_type == EFI_CONVENTIONAL_MEMORY ? > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-10 12:09 ` Ilias Apalodimas @ 2024-06-10 12:25 ` Sughosh Ganu 2024-06-10 14:17 ` Ilias Apalodimas 0 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 12:25 UTC (permalink / raw) To: Ilias Apalodimas Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Mon, 10 Jun 2024 at 17:40, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > 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. > > So the question here, is why do we need a notifier chain overall? > Can't we change the EFI subsystem and allocate memory with lmb now? > And any special functions we have in EFI (e.g allocate aligned memory) > can migrate to lmb() Like we discussed offline, that was my initial attempt -- to use the LMB allocation API's from inside the EFI allocate pages module. But I was facing a lot of corner case issues, primarily in keeping the two memory maps the same. Which is why I moved to the current implementation of notifying other modules, and that too only for the addresses in the RAM region. -sughosh > > Cheers > /Ilias > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > --- > > lib/efi_loader/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > index 435e580fb3..93244161b0 100644 > > --- a/lib/efi_loader/efi_memory.c > > +++ b/lib/efi_loader/efi_memory.c > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > extern bool is_addr_in_ram(uintptr_t addr); > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram); > > + > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > { > > struct event_efi_mem_map_update efi_map = {0}; > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > if (is_addr_in_ram((uintptr_t)addr)) > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > } > > + > > +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) { > > + log_debug("Invalid map update op received (%d)\n", op); > > + return -1; > > + } > > + > > + status = __efi_add_memory_map_pg(addr, pages, > > + op == MAP_OP_FREE ? > > + EFI_CONVENTIONAL_MEMORY : > > + EFI_BOOT_SERVICES_DATA, > > + true); > > + > > + return status == EFI_SUCCESS ? 0 : -1; > > +} > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > /** > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > return EFI_CARVE_LOOP_AGAIN; > > } > > > > -/** > > - * efi_add_memory_map_pg() - add pages to the memory map > > - * > > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > > - * @pages: number of pages to add > > - * @memory_type: type of memory added > > - * @overlap_only_ram: region may only overlap RAM > > - * Return: status code > > - */ > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > - int memory_type, > > - bool overlap_only_ram) > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram) > > { > > struct list_head *lhandle; > > struct efi_mem_list *newlist; > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > } > > } > > > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + * efi_add_memory_map_pg() - add pages to the memory map > > + * > > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > > + * @pages: number of pages to add > > + * @memory_type: type of memory added > > + * @overlap_only_ram: region may only overlap RAM > > + * Return: status code > > + */ > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram) > > +{ > > + efi_status_t status; > > + > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > + overlap_only_ram); > > + if (status != EFI_SUCCESS) > > + return status; > > + > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > > memory_type == EFI_CONVENTIONAL_MEMORY ? > > -- > > 2.34.1 > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-10 12:25 ` Sughosh Ganu @ 2024-06-10 14:17 ` Ilias Apalodimas 2024-06-10 14:52 ` Sughosh Ganu 0 siblings, 1 reply; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 14:17 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Sughosh On Mon, 10 Jun 2024 at 15:25, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > On Mon, 10 Jun 2024 at 17:40, Ilias Apalodimas > <ilias.apalodimas@linaro.org> wrote: > > > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > 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. > > > > So the question here, is why do we need a notifier chain overall? > > Can't we change the EFI subsystem and allocate memory with lmb now? > > And any special functions we have in EFI (e.g allocate aligned memory) > > can migrate to lmb() > > Like we discussed offline, that was my initial attempt -- to use the > LMB allocation API's from inside the EFI allocate pages module. But I > was facing a lot of corner case issues, primarily in keeping the two > memory maps the same. I think it would worth discussing this a bit more. I like the idea of having a single allocator more than having events to update memory reservations > Which is why I moved to the current > implementation of notifying other modules, and that too only for the > addresses in the RAM region. The notification to 'other modules' i still done by updating the static memory map though no? So what corner cases we couldn't solve by having a single allocator? Thanks /Ilias > > -sughosh > > > > > Cheers > > /Ilias > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > --- > > > lib/efi_loader/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > index 435e580fb3..93244161b0 100644 > > > --- a/lib/efi_loader/efi_memory.c > > > +++ b/lib/efi_loader/efi_memory.c > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > + int memory_type, > > > + bool overlap_only_ram); > > > + > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > { > > > struct event_efi_mem_map_update efi_map = {0}; > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > if (is_addr_in_ram((uintptr_t)addr)) > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > } > > > + > > > +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) { > > > + log_debug("Invalid map update op received (%d)\n", op); > > > + return -1; > > > + } > > > + > > > + status = __efi_add_memory_map_pg(addr, pages, > > > + op == MAP_OP_FREE ? > > > + EFI_CONVENTIONAL_MEMORY : > > > + EFI_BOOT_SERVICES_DATA, > > > + true); > > > + > > > + return status == EFI_SUCCESS ? 0 : -1; > > > +} > > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > > > /** > > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > > return EFI_CARVE_LOOP_AGAIN; > > > } > > > > > > -/** > > > - * efi_add_memory_map_pg() - add pages to the memory map > > > - * > > > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > - * @pages: number of pages to add > > > - * @memory_type: type of memory added > > > - * @overlap_only_ram: region may only overlap RAM > > > - * Return: status code > > > - */ > > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > - int memory_type, > > > - bool overlap_only_ram) > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > + int memory_type, > > > + bool overlap_only_ram) > > > { > > > struct list_head *lhandle; > > > struct efi_mem_list *newlist; > > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > } > > > } > > > > > > + return EFI_SUCCESS; > > > +} > > > + > > > +/** > > > + * efi_add_memory_map_pg() - add pages to the memory map > > > + * > > > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > + * @pages: number of pages to add > > > + * @memory_type: type of memory added > > > + * @overlap_only_ram: region may only overlap RAM > > > + * Return: status code > > > + */ > > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > + int memory_type, > > > + bool overlap_only_ram) > > > +{ > > > + efi_status_t status; > > > + > > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > > + overlap_only_ram); > > > + if (status != EFI_SUCCESS) > > > + return status; > > > + > > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > > > memory_type == EFI_CONVENTIONAL_MEMORY ? > > > -- > > > 2.34.1 > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-10 14:17 ` Ilias Apalodimas @ 2024-06-10 14:52 ` Sughosh Ganu 2024-06-10 14:54 ` Sughosh Ganu 2024-06-11 6:19 ` Ilias Apalodimas 0 siblings, 2 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 14:52 UTC (permalink / raw) To: Ilias Apalodimas Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam hi Ilias, On Mon, 10 Jun 2024 at 19:48, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > Hi Sughosh > > On Mon, 10 Jun 2024 at 15:25, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > On Mon, 10 Jun 2024 at 17:40, Ilias Apalodimas > > <ilias.apalodimas@linaro.org> wrote: > > > > > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > > > 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. > > > > > > So the question here, is why do we need a notifier chain overall? > > > Can't we change the EFI subsystem and allocate memory with lmb now? > > > And any special functions we have in EFI (e.g allocate aligned memory) > > > can migrate to lmb() > > > > Like we discussed offline, that was my initial attempt -- to use the > > LMB allocation API's from inside the EFI allocate pages module. But I > > was facing a lot of corner case issues, primarily in keeping the two > > memory maps the same. > > I think it would worth discussing this a bit more. I like the idea of > having a single allocator more than having events to update memory > reservations > > > Which is why I moved to the current > > implementation of notifying other modules, and that too only for the > > addresses in the RAM region. > > The notification to 'other modules' i still done by updating the > static memory map though no? > So what corner cases we couldn't solve by having a single allocator? I can re-check what were the issues that I faced when trying with a single allocator. But please note that we are not making any significant gains by having a single allocator. Even with a common allocator(say LMB), it would still be required to have the same notification mechanism to update the EFI memory map. Else the EFI memory map would show regions of memory as conventional memory, while they are being used by the other subsystem. So, all in all, I think that the notification mechanism is not that inefficient. Thanks. -sughosh > > Thanks > /Ilias > > > > -sughosh > > > > > > > > Cheers > > > /Ilias > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > --- > > > > lib/efi_loader/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > > index 435e580fb3..93244161b0 100644 > > > > --- a/lib/efi_loader/efi_memory.c > > > > +++ b/lib/efi_loader/efi_memory.c > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > + int memory_type, > > > > + bool overlap_only_ram); > > > > + > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > { > > > > struct event_efi_mem_map_update efi_map = {0}; > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > if (is_addr_in_ram((uintptr_t)addr)) > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > > } > > > > + > > > > +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) { > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > + return -1; > > > > + } > > > > + > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > + op == MAP_OP_FREE ? > > > > + EFI_CONVENTIONAL_MEMORY : > > > > + EFI_BOOT_SERVICES_DATA, > > > > + true); > > > > + > > > > + return status == EFI_SUCCESS ? 0 : -1; > > > > +} > > > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > > > > > /** > > > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > > > return EFI_CARVE_LOOP_AGAIN; > > > > } > > > > > > > > -/** > > > > - * efi_add_memory_map_pg() - add pages to the memory map > > > > - * > > > > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > > - * @pages: number of pages to add > > > > - * @memory_type: type of memory added > > > > - * @overlap_only_ram: region may only overlap RAM > > > > - * Return: status code > > > > - */ > > > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > - int memory_type, > > > > - bool overlap_only_ram) > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > + int memory_type, > > > > + bool overlap_only_ram) > > > > { > > > > struct list_head *lhandle; > > > > struct efi_mem_list *newlist; > > > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > } > > > > } > > > > > > > > + return EFI_SUCCESS; > > > > +} > > > > + > > > > +/** > > > > + * efi_add_memory_map_pg() - add pages to the memory map > > > > + * > > > > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > > + * @pages: number of pages to add > > > > + * @memory_type: type of memory added > > > > + * @overlap_only_ram: region may only overlap RAM > > > > + * Return: status code > > > > + */ > > > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > + int memory_type, > > > > + bool overlap_only_ram) > > > > +{ > > > > + efi_status_t status; > > > > + > > > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > > > + overlap_only_ram); > > > > + if (status != EFI_SUCCESS) > > > > + return status; > > > > + > > > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > > > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > > > > memory_type == EFI_CONVENTIONAL_MEMORY ? > > > > -- > > > > 2.34.1 > > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-10 14:52 ` Sughosh Ganu @ 2024-06-10 14:54 ` Sughosh Ganu 2024-06-11 6:19 ` Ilias Apalodimas 1 sibling, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 14:54 UTC (permalink / raw) To: Ilias Apalodimas Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Mon, 10 Jun 2024 at 20:22, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > hi Ilias, > > On Mon, 10 Jun 2024 at 19:48, Ilias Apalodimas > <ilias.apalodimas@linaro.org> wrote: > > > > Hi Sughosh > > > > On Mon, 10 Jun 2024 at 15:25, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > On Mon, 10 Jun 2024 at 17:40, Ilias Apalodimas > > > <ilias.apalodimas@linaro.org> wrote: > > > > > > > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > > > > > 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. > > > > > > > > So the question here, is why do we need a notifier chain overall? > > > > Can't we change the EFI subsystem and allocate memory with lmb now? > > > > And any special functions we have in EFI (e.g allocate aligned memory) > > > > can migrate to lmb() > > > > > > Like we discussed offline, that was my initial attempt -- to use the > > > LMB allocation API's from inside the EFI allocate pages module. But I > > > was facing a lot of corner case issues, primarily in keeping the two > > > memory maps the same. > > > > I think it would worth discussing this a bit more. I like the idea of > > having a single allocator more than having events to update memory > > reservations > > > > > Which is why I moved to the current > > > implementation of notifying other modules, and that too only for the > > > addresses in the RAM region. > > > > The notification to 'other modules' i still done by updating the > > static memory map though no? > > So what corner cases we couldn't solve by having a single allocator? > > I can re-check what were the issues that I faced when trying with a > single allocator. But please note that we are not making any > significant gains by having a single allocator. Even with a common > allocator(say LMB), it would still be required to have the same > notification mechanism to update the EFI memory map. Else the EFI > memory map would show regions of memory as conventional memory, while > they are being used by the other subsystem. So, all in all, I think > that the notification mechanism is not that inefficient. Thanks. Or rather, "the notification mechanism is not inefficient". -sughosh > > -sughosh > > > > > Thanks > > /Ilias > > > > > > -sughosh > > > > > > > > > > > Cheers > > > > /Ilias > > > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > > --- > > > > > lib/efi_loader/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > > > index 435e580fb3..93244161b0 100644 > > > > > --- a/lib/efi_loader/efi_memory.c > > > > > +++ b/lib/efi_loader/efi_memory.c > > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram); > > > > > + > > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > { > > > > > struct event_efi_mem_map_update efi_map = {0}; > > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > if (is_addr_in_ram((uintptr_t)addr)) > > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > > > } > > > > > + > > > > > +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) { > > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > > + op == MAP_OP_FREE ? > > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > + EFI_BOOT_SERVICES_DATA, > > > > > + true); > > > > > + > > > > > + return status == EFI_SUCCESS ? 0 : -1; > > > > > +} > > > > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > > > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > > > > > > > /** > > > > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > > > > return EFI_CARVE_LOOP_AGAIN; > > > > > } > > > > > > > > > > -/** > > > > > - * efi_add_memory_map_pg() - add pages to the memory map > > > > > - * > > > > > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > > > - * @pages: number of pages to add > > > > > - * @memory_type: type of memory added > > > > > - * @overlap_only_ram: region may only overlap RAM > > > > > - * Return: status code > > > > > - */ > > > > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > > - int memory_type, > > > > > - bool overlap_only_ram) > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram) > > > > > { > > > > > struct list_head *lhandle; > > > > > struct efi_mem_list *newlist; > > > > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > > } > > > > > } > > > > > > > > > > + return EFI_SUCCESS; > > > > > +} > > > > > + > > > > > +/** > > > > > + * efi_add_memory_map_pg() - add pages to the memory map > > > > > + * > > > > > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > > > + * @pages: number of pages to add > > > > > + * @memory_type: type of memory added > > > > > + * @overlap_only_ram: region may only overlap RAM > > > > > + * Return: status code > > > > > + */ > > > > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram) > > > > > +{ > > > > > + efi_status_t status; > > > > > + > > > > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > > > > + overlap_only_ram); > > > > > + if (status != EFI_SUCCESS) > > > > > + return status; > > > > > + > > > > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > > > > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > > > > > memory_type == EFI_CONVENTIONAL_MEMORY ? > > > > > -- > > > > > 2.34.1 > > > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-10 14:52 ` Sughosh Ganu 2024-06-10 14:54 ` Sughosh Ganu @ 2024-06-11 6:19 ` Ilias Apalodimas 1 sibling, 0 replies; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-11 6:19 UTC (permalink / raw) To: Sughosh Ganu Cc: U-Boot Mailing List, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Mon, Jun 10, 2024, 5:52 PM Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > hi Ilias, > > On Mon, 10 Jun 2024 at 19:48, Ilias Apalodimas > <ilias.apalodimas@linaro.org> wrote: > > > > Hi Sughosh > > > > On Mon, 10 Jun 2024 at 15:25, Sughosh Ganu <sughosh.ganu@linaro.org> > wrote: > > > > > > On Mon, 10 Jun 2024 at 17:40, Ilias Apalodimas > > > <ilias.apalodimas@linaro.org> wrote: > > > > > > > > On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> > wrote: > > > > > > > > > > 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. > > > > > > > > So the question here, is why do we need a notifier chain overall? > > > > Can't we change the EFI subsystem and allocate memory with lmb now? > > > > And any special functions we have in EFI (e.g allocate aligned > memory) > > > > can migrate to lmb() > > > > > > Like we discussed offline, that was my initial attempt -- to use the > > > LMB allocation API's from inside the EFI allocate pages module. But I > > > was facing a lot of corner case issues, primarily in keeping the two > > > memory maps the same. > > > > I think it would worth discussing this a bit more. I like the idea of > > having a single allocator more than having events to update memory > > reservations > > > > > Which is why I moved to the current > > > implementation of notifying other modules, and that too only for the > > > addresses in the RAM region. > > > > The notification to 'other modules' i still done by updating the > > static memory map though no? > > So what corner cases we couldn't solve by having a single allocator? > > I can re-check what were the issues that I faced when trying with a > single allocator. But please note that we are not making any > significant gains by having a single allocator. Even with a common > allocator(say LMB), it would still be required to have the same > notification mechanism to update the EFI memory map. I am not sure about this. With the proposal I did on the other thread, you would have the allocations updated at runtime and an ID of the subsystem that allocated the memory. The only difference with having a central allocator is that we will need a 'flags' field to store the EFI-specific options. Else the EFI > memory map would show regions of memory as conventional memory, while > they are being used by the other subsystem. So, all in all, I think > that the notification mechanism is not that inefficient. Thanks. > > Regards /Ilias > -sughosh > > > > > Thanks > > /Ilias > > > > > > -sughosh > > > > > > > > > > > Cheers > > > > /Ilias > > > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > > --- > > > > > lib/efi_loader/efi_memory.c | 70 > ++++++++++++++++++++++++++++++------- > > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > > > > > diff --git a/lib/efi_loader/efi_memory.c > b/lib/efi_loader/efi_memory.c > > > > > index 435e580fb3..93244161b0 100644 > > > > > --- a/lib/efi_loader/efi_memory.c > > > > > +++ b/lib/efi_loader/efi_memory.c > > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram); > > > > > + > > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > { > > > > > struct event_efi_mem_map_update efi_map = {0}; > > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 > size, u8 op) > > > > > if (is_addr_in_ram((uintptr_t)addr)) > > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, > sizeof(efi_map)); > > > > > } > > > > > + > > > > > +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) { > > > > > + log_debug("Invalid map update op received (%d)\n", > op); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > > + op == MAP_OP_FREE ? > > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > + EFI_BOOT_SERVICES_DATA, > > > > > + true); > > > > > + > > > > > + return status == EFI_SUCCESS ? 0 : -1; > > > > > +} > > > > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > > > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > > > > > > > /** > > > > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct > efi_mem_list *map, > > > > > return EFI_CARVE_LOOP_AGAIN; > > > > > } > > > > > > > > > > -/** > > > > > - * efi_add_memory_map_pg() - add pages to the memory map > > > > > - * > > > > > - * @start: start address, must be a multiple of > EFI_PAGE_SIZE > > > > > - * @pages: number of pages to add > > > > > - * @memory_type: type of memory added > > > > > - * @overlap_only_ram: region may only overlap RAM > > > > > - * Return: status code > > > > > - */ > > > > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > > - int memory_type, > > > > > - bool overlap_only_ram) > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram) > > > > > { > > > > > struct list_head *lhandle; > > > > > struct efi_mem_list *newlist; > > > > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 > start, u64 pages, > > > > > } > > > > > } > > > > > > > > > > + return EFI_SUCCESS; > > > > > +} > > > > > + > > > > > +/** > > > > > + * efi_add_memory_map_pg() - add pages to the memory map > > > > > + * > > > > > + * @start: start address, must be a multiple of > EFI_PAGE_SIZE > > > > > + * @pages: number of pages to add > > > > > + * @memory_type: type of memory added > > > > > + * @overlap_only_ram: region may only overlap RAM > > > > > + * Return: status code > > > > > + */ > > > > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram) > > > > > +{ > > > > > + efi_status_t status; > > > > > + > > > > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > > > > + overlap_only_ram); > > > > > + if (status != EFI_SUCCESS) > > > > > + return status; > > > > > + > > > > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > > > > efi_map_update_notify(start, pages << > EFI_PAGE_SHIFT, > > > > > memory_type == > EFI_CONVENTIONAL_MEMORY ? > > > > > -- > > > > > 2.34.1 > > > > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-07 18:52 ` [RFC PATCH 15/31] efi_memory: add an event handler to update " Sughosh Ganu 2024-06-10 12:09 ` Ilias Apalodimas @ 2024-06-10 15:12 ` Heinrich Schuchardt 2024-06-10 15:42 ` Sughosh Ganu 2024-06-11 10:17 ` Heinrich Schuchardt 2 siblings, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-10 15:12 UTC (permalink / raw) To: Sughosh Ganu, Tom Rini Cc: Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On 07.06.24 20:52, Sughosh Ganu wrote: > 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 I am worried about the "frees up memory" case. When LMB frees memory we cannot add it back to EFI conventional memory as there might still be a file image lingering around that EFI should not overwrite. It has to stay marked as EfiLoaderCode or EfiLoaderData. How do you ensure that if a region reserved by LMB notification as EfiLoaderData is coalesced with some other allocation LMB is not requested to mark the coalesced region as reserved? @Tom Clinging to the existing logic that you can do anything when loading files is obviously leading us into coding hell. If somebody wants to load two images into the same location, he should be forced to unload the first image. This will allow us to have a single memory management system. Best regards Heinrich > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > 1 file changed, 58 insertions(+), 12 deletions(-) > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > index 435e580fb3..93244161b0 100644 > --- a/lib/efi_loader/efi_memory.c > +++ b/lib/efi_loader/efi_memory.c > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > extern bool is_addr_in_ram(uintptr_t addr); > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > + int memory_type, > + bool overlap_only_ram); > + > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > { > struct event_efi_mem_map_update efi_map = {0}; > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > if (is_addr_in_ram((uintptr_t)addr)) > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > } > + > +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) { > + log_debug("Invalid map update op received (%d)\n", op); > + return -1; > + } > + > + status = __efi_add_memory_map_pg(addr, pages, > + op == MAP_OP_FREE ? > + EFI_CONVENTIONAL_MEMORY : > + EFI_BOOT_SERVICES_DATA, > + true); > + > + return status == EFI_SUCCESS ? 0 : -1; > +} > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > /** > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > return EFI_CARVE_LOOP_AGAIN; > } > > -/** > - * efi_add_memory_map_pg() - add pages to the memory map > - * > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > - * @pages: number of pages to add > - * @memory_type: type of memory added > - * @overlap_only_ram: region may only overlap RAM > - * Return: status code > - */ > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > - int memory_type, > - bool overlap_only_ram) > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > + int memory_type, > + bool overlap_only_ram) > { > struct list_head *lhandle; > struct efi_mem_list *newlist; > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > } > } > > + return EFI_SUCCESS; > +} > + > +/** > + * efi_add_memory_map_pg() - add pages to the memory map > + * > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > + * @pages: number of pages to add > + * @memory_type: type of memory added > + * @overlap_only_ram: region may only overlap RAM > + * Return: status code > + */ > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > + int memory_type, > + bool overlap_only_ram) > +{ > + efi_status_t status; > + > + status = __efi_add_memory_map_pg(start, pages, memory_type, > + overlap_only_ram); > + if (status != EFI_SUCCESS) > + return status; > + > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > memory_type == EFI_CONVENTIONAL_MEMORY ? ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-10 15:12 ` Heinrich Schuchardt @ 2024-06-10 15:42 ` Sughosh Ganu 2024-06-10 15:54 ` Simon Glass 0 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 15:42 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On Mon, 10 Jun 2024 at 20:47, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 07.06.24 20:52, Sughosh Ganu wrote: > > 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 > > I am worried about the "frees up memory" case. > > When LMB frees memory we cannot add it back to EFI conventional memory > as there might still be a file image lingering around that EFI should > not overwrite. It has to stay marked as EfiLoaderCode or EfiLoaderData. So here is my basic doubt. Why would LMB free up memory if it still has a valid image. If that is the case, the lmb_free API should not be called? -sughosh > > How do you ensure that if a region reserved by LMB notification as > EfiLoaderData is coalesced with some other allocation LMB is not > requested to mark the coalesced region as reserved? > > @Tom > > Clinging to the existing logic that you can do anything when loading > files is obviously leading us into coding hell. > > If somebody wants to load two images into the same location, he should > be forced to unload the first image. This will allow us to have a single > memory management system. > > Best regards > > Heinrich > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > index 435e580fb3..93244161b0 100644 > > --- a/lib/efi_loader/efi_memory.c > > +++ b/lib/efi_loader/efi_memory.c > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > extern bool is_addr_in_ram(uintptr_t addr); > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram); > > + > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > { > > struct event_efi_mem_map_update efi_map = {0}; > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > if (is_addr_in_ram((uintptr_t)addr)) > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > } > > + > > +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) { > > + log_debug("Invalid map update op received (%d)\n", op); > > + return -1; > > + } > > + > > + status = __efi_add_memory_map_pg(addr, pages, > > + op == MAP_OP_FREE ? > > + EFI_CONVENTIONAL_MEMORY : > > + EFI_BOOT_SERVICES_DATA, > > + true); > > + > > + return status == EFI_SUCCESS ? 0 : -1; > > +} > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > /** > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > return EFI_CARVE_LOOP_AGAIN; > > } > > > > -/** > > - * efi_add_memory_map_pg() - add pages to the memory map > > - * > > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > > - * @pages: number of pages to add > > - * @memory_type: type of memory added > > - * @overlap_only_ram: region may only overlap RAM > > - * Return: status code > > - */ > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > - int memory_type, > > - bool overlap_only_ram) > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram) > > { > > struct list_head *lhandle; > > struct efi_mem_list *newlist; > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > } > > } > > > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + * efi_add_memory_map_pg() - add pages to the memory map > > + * > > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > > + * @pages: number of pages to add > > + * @memory_type: type of memory added > > + * @overlap_only_ram: region may only overlap RAM > > + * Return: status code > > + */ > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram) > > +{ > > + efi_status_t status; > > + > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > + overlap_only_ram); > > + if (status != EFI_SUCCESS) > > + return status; > > + > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > > memory_type == EFI_CONVENTIONAL_MEMORY ? > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-10 15:42 ` Sughosh Ganu @ 2024-06-10 15:54 ` Simon Glass 2024-06-12 6:45 ` Ilias Apalodimas 0 siblings, 1 reply; 127+ messages in thread From: Simon Glass @ 2024-06-10 15:54 UTC (permalink / raw) To: Sughosh Ganu Cc: Heinrich Schuchardt, Tom Rini, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot Hi, On Mon, 10 Jun 2024 at 09:42, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > On Mon, 10 Jun 2024 at 20:47, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > On 07.06.24 20:52, Sughosh Ganu wrote: > > > 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 > > > > I am worried about the "frees up memory" case. > > > > When LMB frees memory we cannot add it back to EFI conventional memory > > as there might still be a file image lingering around that EFI should > > not overwrite. It has to stay marked as EfiLoaderCode or EfiLoaderData. > > So here is my basic doubt. Why would LMB free up memory if it still > has a valid image. If that is the case, the lmb_free API should not be > called? > > -sughosh > > > > > > How do you ensure that if a region reserved by LMB notification as > > EfiLoaderData is coalesced with some other allocation LMB is not > > requested to mark the coalesced region as reserved? > > > > @Tom > > > > Clinging to the existing logic that you can do anything when loading > > files is obviously leading us into coding hell. > > > > If somebody wants to load two images into the same location, he should > > be forced to unload the first image. This will allow us to have a single > > memory management system. It seems we really shouldn't use the words 'allocate' and 'free' when talking about LMB. They are simply reservations. I believe we have got into this situation due to an assumption that these two things are the same, but in U-Boot they certainly are not. LMB is a very lighweight and temporary reservation system to be used for a single boot process. Regards, Simon > > > > Best regards > > > > Heinrich > > > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > index 435e580fb3..93244161b0 100644 > > > --- a/lib/efi_loader/efi_memory.c > > > +++ b/lib/efi_loader/efi_memory.c > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > + int memory_type, > > > + bool overlap_only_ram); > > > + > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > { > > > struct event_efi_mem_map_update efi_map = {0}; > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > if (is_addr_in_ram((uintptr_t)addr)) > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > } > > > + > > > +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) { > > > + log_debug("Invalid map update op received (%d)\n", op); > > > + return -1; > > > + } > > > + > > > + status = __efi_add_memory_map_pg(addr, pages, > > > + op == MAP_OP_FREE ? > > > + EFI_CONVENTIONAL_MEMORY : > > > + EFI_BOOT_SERVICES_DATA, > > > + true); > > > + > > > + return status == EFI_SUCCESS ? 0 : -1; > > > +} > > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > > > /** > > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > > return EFI_CARVE_LOOP_AGAIN; > > > } > > > > > > -/** > > > - * efi_add_memory_map_pg() - add pages to the memory map > > > - * > > > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > - * @pages: number of pages to add > > > - * @memory_type: type of memory added > > > - * @overlap_only_ram: region may only overlap RAM > > > - * Return: status code > > > - */ > > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > - int memory_type, > > > - bool overlap_only_ram) > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > + int memory_type, > > > + bool overlap_only_ram) > > > { > > > struct list_head *lhandle; > > > struct efi_mem_list *newlist; > > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > } > > > } > > > > > > + return EFI_SUCCESS; > > > +} > > > + > > > +/** > > > + * efi_add_memory_map_pg() - add pages to the memory map > > > + * > > > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > + * @pages: number of pages to add > > > + * @memory_type: type of memory added > > > + * @overlap_only_ram: region may only overlap RAM > > > + * Return: status code > > > + */ > > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > + int memory_type, > > > + bool overlap_only_ram) > > > +{ > > > + efi_status_t status; > > > + > > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > > + overlap_only_ram); > > > + if (status != EFI_SUCCESS) > > > + return status; > > > + > > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > > > memory_type == EFI_CONVENTIONAL_MEMORY ? > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-10 15:54 ` Simon Glass @ 2024-06-12 6:45 ` Ilias Apalodimas 2024-06-12 7:11 ` Sughosh Ganu 0 siblings, 1 reply; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-12 6:45 UTC (permalink / raw) To: Simon Glass, Sughosh Ganu Cc: Heinrich Schuchardt, Tom Rini, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On Mon, 10 Jun 2024 at 18:54, Simon Glass <sjg@chromium.org> wrote: > > Hi, > > On Mon, 10 Jun 2024 at 09:42, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > On Mon, 10 Jun 2024 at 20:47, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > > > On 07.06.24 20:52, Sughosh Ganu wrote: > > > > 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 > > > > > > I am worried about the "frees up memory" case. > > > > > > When LMB frees memory we cannot add it back to EFI conventional memory > > > as there might still be a file image lingering around that EFI should > > > not overwrite. It has to stay marked as EfiLoaderCode or EfiLoaderData. > > > > So here is my basic doubt. Why would LMB free up memory if it still > > has a valid image. If that is the case, the lmb_free API should not be > > called? > > > > -sughosh > > > > > > > > > > How do you ensure that if a region reserved by LMB notification as > > > EfiLoaderData is coalesced with some other allocation LMB is not > > > requested to mark the coalesced region as reserved? > > > > > > @Tom > > > > > > Clinging to the existing logic that you can do anything when loading > > > files is obviously leading us into coding hell. > > > > > > If somebody wants to load two images into the same location, he should > > > be forced to unload the first image. This will allow us to have a single > > > memory management system. > > It seems we really shouldn't use the words 'allocate' and 'free' when > talking about LMB. They are simply reservations. Correct and while at it can we please make the code less confusing to read. What we today mark as reserved isnt even trully reserved as it can be overwritten. struct lmb_region memory -> available memory we added on LMB. That's fine struct lmb_region reserved -> can we rename this to 'used' and rename LMB_NOOVERWRITE to LMB_RESERVED? Thanks /Ilias > I believe we have got > into this situation due to an assumption that these two things are the > same, but in U-Boot they certainly are not. LMB is a very lighweight > and temporary reservation system to be used for a single boot process. > > Regards, > Simon > > > > > > > > Best regards > > > > > > Heinrich > > > > > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > > index 435e580fb3..93244161b0 100644 > > > > --- a/lib/efi_loader/efi_memory.c > > > > +++ b/lib/efi_loader/efi_memory.c > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > + int memory_type, > > > > + bool overlap_only_ram); > > > > + > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > { > > > > struct event_efi_mem_map_update efi_map = {0}; > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > if (is_addr_in_ram((uintptr_t)addr)) > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > > } > > > > + > > > > +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) { > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > + return -1; > > > > + } > > > > + > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > + op == MAP_OP_FREE ? > > > > + EFI_CONVENTIONAL_MEMORY : > > > > + EFI_BOOT_SERVICES_DATA, > > > > + true); > > > > + > > > > + return status == EFI_SUCCESS ? 0 : -1; > > > > +} > > > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > > > > > /** > > > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > > > return EFI_CARVE_LOOP_AGAIN; > > > > } > > > > > > > > -/** > > > > - * efi_add_memory_map_pg() - add pages to the memory map > > > > - * > > > > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > > - * @pages: number of pages to add > > > > - * @memory_type: type of memory added > > > > - * @overlap_only_ram: region may only overlap RAM > > > > - * Return: status code > > > > - */ > > > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > - int memory_type, > > > > - bool overlap_only_ram) > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > + int memory_type, > > > > + bool overlap_only_ram) > > > > { > > > > struct list_head *lhandle; > > > > struct efi_mem_list *newlist; > > > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > } > > > > } > > > > > > > > + return EFI_SUCCESS; > > > > +} > > > > + > > > > +/** > > > > + * efi_add_memory_map_pg() - add pages to the memory map > > > > + * > > > > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > > + * @pages: number of pages to add > > > > + * @memory_type: type of memory added > > > > + * @overlap_only_ram: region may only overlap RAM > > > > + * Return: status code > > > > + */ > > > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > + int memory_type, > > > > + bool overlap_only_ram) > > > > +{ > > > > + efi_status_t status; > > > > + > > > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > > > + overlap_only_ram); > > > > + if (status != EFI_SUCCESS) > > > > + return status; > > > > + > > > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > > > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > > > > memory_type == EFI_CONVENTIONAL_MEMORY ? > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-12 6:45 ` Ilias Apalodimas @ 2024-06-12 7:11 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-12 7:11 UTC (permalink / raw) To: Ilias Apalodimas Cc: Simon Glass, Heinrich Schuchardt, Tom Rini, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On Wed, 12 Jun 2024 at 12:16, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > On Mon, 10 Jun 2024 at 18:54, Simon Glass <sjg@chromium.org> wrote: > > > > Hi, > > > > On Mon, 10 Jun 2024 at 09:42, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > > > > On Mon, 10 Jun 2024 at 20:47, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > > > > > On 07.06.24 20:52, Sughosh Ganu wrote: > > > > > 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 > > > > > > > > I am worried about the "frees up memory" case. > > > > > > > > When LMB frees memory we cannot add it back to EFI conventional memory > > > > as there might still be a file image lingering around that EFI should > > > > not overwrite. It has to stay marked as EfiLoaderCode or EfiLoaderData. > > > > > > So here is my basic doubt. Why would LMB free up memory if it still > > > has a valid image. If that is the case, the lmb_free API should not be > > > called? > > > > > > -sughosh > > > > > > > > > > > > > > How do you ensure that if a region reserved by LMB notification as > > > > EfiLoaderData is coalesced with some other allocation LMB is not > > > > requested to mark the coalesced region as reserved? > > > > > > > > @Tom > > > > > > > > Clinging to the existing logic that you can do anything when loading > > > > files is obviously leading us into coding hell. > > > > > > > > If somebody wants to load two images into the same location, he should > > > > be forced to unload the first image. This will allow us to have a single > > > > memory management system. > > > > It seems we really shouldn't use the words 'allocate' and 'free' when > > talking about LMB. They are simply reservations. > > Correct and while at it can we please make the code less confusing to > read. What we today mark as reserved isnt even trully reserved as it > can be overwritten. > struct lmb_region memory -> available memory we added on LMB. That's fine > struct lmb_region reserved -> can we rename this to 'used' and rename > LMB_NOOVERWRITE to LMB_RESERVED? Okay. Will incorporate this change in the next version. Thanks. -sughosh > > Thanks > /Ilias > > > I believe we have got > > into this situation due to an assumption that these two things are the > > same, but in U-Boot they certainly are not. LMB is a very lighweight > > and temporary reservation system to be used for a single boot process. > > > > Regards, > > Simon > > > > > > > > > > > > Best regards > > > > > > > > Heinrich > > > > > > > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > > > index 435e580fb3..93244161b0 100644 > > > > > --- a/lib/efi_loader/efi_memory.c > > > > > +++ b/lib/efi_loader/efi_memory.c > > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram); > > > > > + > > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > { > > > > > struct event_efi_mem_map_update efi_map = {0}; > > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > if (is_addr_in_ram((uintptr_t)addr)) > > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > > > } > > > > > + > > > > > +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) { > > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > > + op == MAP_OP_FREE ? > > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > + EFI_BOOT_SERVICES_DATA, > > > > > + true); > > > > > + > > > > > + return status == EFI_SUCCESS ? 0 : -1; > > > > > +} > > > > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > > > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > > > > > > > /** > > > > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > > > > return EFI_CARVE_LOOP_AGAIN; > > > > > } > > > > > > > > > > -/** > > > > > - * efi_add_memory_map_pg() - add pages to the memory map > > > > > - * > > > > > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > > > - * @pages: number of pages to add > > > > > - * @memory_type: type of memory added > > > > > - * @overlap_only_ram: region may only overlap RAM > > > > > - * Return: status code > > > > > - */ > > > > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > > - int memory_type, > > > > > - bool overlap_only_ram) > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram) > > > > > { > > > > > struct list_head *lhandle; > > > > > struct efi_mem_list *newlist; > > > > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > > } > > > > > } > > > > > > > > > > + return EFI_SUCCESS; > > > > > +} > > > > > + > > > > > +/** > > > > > + * efi_add_memory_map_pg() - add pages to the memory map > > > > > + * > > > > > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > > > > > + * @pages: number of pages to add > > > > > + * @memory_type: type of memory added > > > > > + * @overlap_only_ram: region may only overlap RAM > > > > > + * Return: status code > > > > > + */ > > > > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram) > > > > > +{ > > > > > + efi_status_t status; > > > > > + > > > > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > > > > + overlap_only_ram); > > > > > + if (status != EFI_SUCCESS) > > > > > + return status; > > > > > + > > > > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > > > > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > > > > > memory_type == EFI_CONVENTIONAL_MEMORY ? > > > > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-07 18:52 ` [RFC PATCH 15/31] efi_memory: add an event handler to update " Sughosh Ganu 2024-06-10 12:09 ` Ilias Apalodimas 2024-06-10 15:12 ` Heinrich Schuchardt @ 2024-06-11 10:17 ` Heinrich Schuchardt 2024-06-11 10:27 ` Sughosh Ganu 2024-06-11 14:36 ` Tom Rini 2 siblings, 2 replies; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-11 10:17 UTC (permalink / raw) To: Sughosh Ganu Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On 07.06.24 20:52, Sughosh Ganu wrote: > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > 1 file changed, 58 insertions(+), 12 deletions(-) > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > index 435e580fb3..93244161b0 100644 > --- a/lib/efi_loader/efi_memory.c > +++ b/lib/efi_loader/efi_memory.c > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > extern bool is_addr_in_ram(uintptr_t addr); > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > + int memory_type, > + bool overlap_only_ram); > + > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > { > struct event_efi_mem_map_update efi_map = {0}; > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > if (is_addr_in_ram((uintptr_t)addr)) > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > } > + > +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) { > + log_debug("Invalid map update op received (%d)\n", op); > + return -1; > + } > + > + status = __efi_add_memory_map_pg(addr, pages, > + op == MAP_OP_FREE ? > + EFI_CONVENTIONAL_MEMORY : This is dangerous. LMB might turn memory that is marked as EfiReservedMemory which the OS must respect into EfiBootServicesData which the OS may discard. E.g. initr_lmb() is being called after efi_memory_init(). Getting all cases of synchronization properly tested seems very hard to me. Everything would be much easier if we had only a single memory management system. Best regards Heinrich > + EFI_BOOT_SERVICES_DATA, > + true); > + > + return status == EFI_SUCCESS ? 0 : -1; > +} > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > /** > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > return EFI_CARVE_LOOP_AGAIN; > } > > -/** > - * efi_add_memory_map_pg() - add pages to the memory map > - * > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > - * @pages: number of pages to add > - * @memory_type: type of memory added > - * @overlap_only_ram: region may only overlap RAM > - * Return: status code > - */ > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > - int memory_type, > - bool overlap_only_ram) > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > + int memory_type, > + bool overlap_only_ram) > { > struct list_head *lhandle; > struct efi_mem_list *newlist; > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > } > } > > + return EFI_SUCCESS; > +} > + > +/** > + * efi_add_memory_map_pg() - add pages to the memory map > + * > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > + * @pages: number of pages to add > + * @memory_type: type of memory added > + * @overlap_only_ram: region may only overlap RAM > + * Return: status code > + */ > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > + int memory_type, > + bool overlap_only_ram) > +{ > + efi_status_t status; > + > + status = __efi_add_memory_map_pg(start, pages, memory_type, > + overlap_only_ram); > + if (status != EFI_SUCCESS) > + return status; > + > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > memory_type == EFI_CONVENTIONAL_MEMORY ? ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-11 10:17 ` Heinrich Schuchardt @ 2024-06-11 10:27 ` Sughosh Ganu 2024-06-11 14:36 ` Tom Rini 1 sibling, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-11 10:27 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On Tue, 11 Jun 2024 at 15:47, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 07.06.24 20:52, Sughosh Ganu wrote: > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > index 435e580fb3..93244161b0 100644 > > --- a/lib/efi_loader/efi_memory.c > > +++ b/lib/efi_loader/efi_memory.c > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > extern bool is_addr_in_ram(uintptr_t addr); > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram); > > + > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > { > > struct event_efi_mem_map_update efi_map = {0}; > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > if (is_addr_in_ram((uintptr_t)addr)) > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > } > > + > > +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) { > > + log_debug("Invalid map update op received (%d)\n", op); > > + return -1; > > + } > > + > > + status = __efi_add_memory_map_pg(addr, pages, > > + op == MAP_OP_FREE ? > > + EFI_CONVENTIONAL_MEMORY : > > This is dangerous. LMB might turn memory that is marked as > EfiReservedMemory which the OS must respect into EfiBootServicesData > which the OS may discard. If memory is being marked as EfiReservedMemory, that will also update the LMB memory map to have it marked as reserved. So a correct implementation should then not be freeing memory that is not allocated by that module. -sughosh > > E.g. initr_lmb() is being called after efi_memory_init(). > > Getting all cases of synchronization properly tested seems very hard to > me. Everything would be much easier if we had only a single memory > management system. > > Best regards > > Heinrich > > > + EFI_BOOT_SERVICES_DATA, > > + true); > > + > > + return status == EFI_SUCCESS ? 0 : -1; > > +} > > +EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > > /** > > @@ -275,18 +307,9 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > return EFI_CARVE_LOOP_AGAIN; > > } > > > > -/** > > - * efi_add_memory_map_pg() - add pages to the memory map > > - * > > - * @start: start address, must be a multiple of EFI_PAGE_SIZE > > - * @pages: number of pages to add > > - * @memory_type: type of memory added > > - * @overlap_only_ram: region may only overlap RAM > > - * Return: status code > > - */ > > -static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > - int memory_type, > > - bool overlap_only_ram) > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram) > > { > > struct list_head *lhandle; > > struct efi_mem_list *newlist; > > @@ -395,6 +418,29 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > } > > } > > > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + * efi_add_memory_map_pg() - add pages to the memory map > > + * > > + * @start: start address, must be a multiple of EFI_PAGE_SIZE > > + * @pages: number of pages to add > > + * @memory_type: type of memory added > > + * @overlap_only_ram: region may only overlap RAM > > + * Return: status code > > + */ > > +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram) > > +{ > > + efi_status_t status; > > + > > + status = __efi_add_memory_map_pg(start, pages, memory_type, > > + overlap_only_ram); > > + if (status != EFI_SUCCESS) > > + return status; > > + > > if (CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)) > > efi_map_update_notify(start, pages << EFI_PAGE_SHIFT, > > memory_type == EFI_CONVENTIONAL_MEMORY ? > ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-11 10:17 ` Heinrich Schuchardt 2024-06-11 10:27 ` Sughosh Ganu @ 2024-06-11 14:36 ` Tom Rini 2024-06-11 18:52 ` Simon Glass 1 sibling, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-11 14:36 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Sughosh Ganu, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot [-- Attachment #1: Type: text/plain, Size: 3209 bytes --] On Tue, Jun 11, 2024 at 12:17:16PM +0200, Heinrich Schuchardt wrote: > On 07.06.24 20:52, Sughosh Ganu wrote: > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > index 435e580fb3..93244161b0 100644 > > --- a/lib/efi_loader/efi_memory.c > > +++ b/lib/efi_loader/efi_memory.c > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > extern bool is_addr_in_ram(uintptr_t addr); > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > + int memory_type, > > + bool overlap_only_ram); > > + > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > { > > struct event_efi_mem_map_update efi_map = {0}; > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > if (is_addr_in_ram((uintptr_t)addr)) > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > } > > + > > +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) { > > + log_debug("Invalid map update op received (%d)\n", op); > > + return -1; > > + } > > + > > + status = __efi_add_memory_map_pg(addr, pages, > > + op == MAP_OP_FREE ? > > + EFI_CONVENTIONAL_MEMORY : > > This is dangerous. LMB might turn memory that is marked as > EfiReservedMemory which the OS must respect into EfiBootServicesData > which the OS may discard. > > E.g. initr_lmb() is being called after efi_memory_init(). > > Getting all cases of synchronization properly tested seems very hard to > me. Everything would be much easier if we had only a single memory > management system. Yes, Sughosh is working on the single memory reservation system for everyone to use. This pairs with the single memory allocation system (malloc) that we have. Parts of the code base that aren't keeping these systems up to date / obeying their results need to be corrected. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-11 14:36 ` Tom Rini @ 2024-06-11 18:52 ` Simon Glass 2024-06-11 21:01 ` Tom Rini 0 siblings, 1 reply; 127+ messages in thread From: Simon Glass @ 2024-06-11 18:52 UTC (permalink / raw) To: Tom Rini Cc: Heinrich Schuchardt, Sughosh Ganu, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot Hi, On Tue, 11 Jun 2024 at 08:36, Tom Rini <trini@konsulko.com> wrote: > > On Tue, Jun 11, 2024 at 12:17:16PM +0200, Heinrich Schuchardt wrote: > > On 07.06.24 20:52, Sughosh Ganu wrote: > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > index 435e580fb3..93244161b0 100644 > > > --- a/lib/efi_loader/efi_memory.c > > > +++ b/lib/efi_loader/efi_memory.c > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > + int memory_type, > > > + bool overlap_only_ram); > > > + > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > { > > > struct event_efi_mem_map_update efi_map = {0}; > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > if (is_addr_in_ram((uintptr_t)addr)) > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > } > > > + > > > +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) { > > > + log_debug("Invalid map update op received (%d)\n", op); > > > + return -1; > > > + } > > > + > > > + status = __efi_add_memory_map_pg(addr, pages, > > > + op == MAP_OP_FREE ? > > > + EFI_CONVENTIONAL_MEMORY : > > > > This is dangerous. LMB might turn memory that is marked as > > EfiReservedMemory which the OS must respect into EfiBootServicesData > > which the OS may discard. > > > > E.g. initr_lmb() is being called after efi_memory_init(). > > > > Getting all cases of synchronization properly tested seems very hard to > > me. Everything would be much easier if we had only a single memory > > management system. > > Yes, Sughosh is working on the single memory reservation system for > everyone to use. This pairs with the single memory allocation system > (malloc) that we have. Parts of the code base that aren't keeping these > systems up to date / obeying their results need to be corrected. The EFI allocations don't happen until boot time...so why do we need to do this now? We can instead have an EFI function to scan LMB and add to its memory map. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-11 18:52 ` Simon Glass @ 2024-06-11 21:01 ` Tom Rini 2024-06-11 22:22 ` Simon Glass 0 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-11 21:01 UTC (permalink / raw) To: Simon Glass Cc: Heinrich Schuchardt, Sughosh Ganu, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot [-- Attachment #1: Type: text/plain, Size: 4149 bytes --] On Tue, Jun 11, 2024 at 12:52:19PM -0600, Simon Glass wrote: > Hi, > > On Tue, 11 Jun 2024 at 08:36, Tom Rini <trini@konsulko.com> wrote: > > > > On Tue, Jun 11, 2024 at 12:17:16PM +0200, Heinrich Schuchardt wrote: > > > On 07.06.24 20:52, Sughosh Ganu wrote: > > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > > index 435e580fb3..93244161b0 100644 > > > > --- a/lib/efi_loader/efi_memory.c > > > > +++ b/lib/efi_loader/efi_memory.c > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > + int memory_type, > > > > + bool overlap_only_ram); > > > > + > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > { > > > > struct event_efi_mem_map_update efi_map = {0}; > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > if (is_addr_in_ram((uintptr_t)addr)) > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > > } > > > > + > > > > +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) { > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > + return -1; > > > > + } > > > > + > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > + op == MAP_OP_FREE ? > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > > This is dangerous. LMB might turn memory that is marked as > > > EfiReservedMemory which the OS must respect into EfiBootServicesData > > > which the OS may discard. > > > > > > E.g. initr_lmb() is being called after efi_memory_init(). > > > > > > Getting all cases of synchronization properly tested seems very hard to > > > me. Everything would be much easier if we had only a single memory > > > management system. > > > > Yes, Sughosh is working on the single memory reservation system for > > everyone to use. This pairs with the single memory allocation system > > (malloc) that we have. Parts of the code base that aren't keeping these > > systems up to date / obeying their results need to be corrected. > > The EFI allocations don't happen until boot time...so why do we need > to do this now? We can instead have an EFI function to scan LMB and > add to its memory map. We're talking about reservations, not allocations. So yes, when someone is making their reservation, they need to make it. I don't understand your question. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-11 21:01 ` Tom Rini @ 2024-06-11 22:22 ` Simon Glass 2024-06-11 22:54 ` Tom Rini 0 siblings, 1 reply; 127+ messages in thread From: Simon Glass @ 2024-06-11 22:22 UTC (permalink / raw) To: Tom Rini Cc: Heinrich Schuchardt, Sughosh Ganu, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot Hi Tom, On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: > > On Tue, Jun 11, 2024 at 12:52:19PM -0600, Simon Glass wrote: > > Hi, > > > > On Tue, 11 Jun 2024 at 08:36, Tom Rini <trini@konsulko.com> wrote: > > > > > > On Tue, Jun 11, 2024 at 12:17:16PM +0200, Heinrich Schuchardt wrote: > > > > On 07.06.24 20:52, Sughosh Ganu wrote: > > > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > > > index 435e580fb3..93244161b0 100644 > > > > > --- a/lib/efi_loader/efi_memory.c > > > > > +++ b/lib/efi_loader/efi_memory.c > > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > > + int memory_type, > > > > > + bool overlap_only_ram); > > > > > + > > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > { > > > > > struct event_efi_mem_map_update efi_map = {0}; > > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > if (is_addr_in_ram((uintptr_t)addr)) > > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > > > } > > > > > + > > > > > +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) { > > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > > + op == MAP_OP_FREE ? > > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > > > > This is dangerous. LMB might turn memory that is marked as > > > > EfiReservedMemory which the OS must respect into EfiBootServicesData > > > > which the OS may discard. > > > > > > > > E.g. initr_lmb() is being called after efi_memory_init(). > > > > > > > > Getting all cases of synchronization properly tested seems very hard to > > > > me. Everything would be much easier if we had only a single memory > > > > management system. > > > > > > Yes, Sughosh is working on the single memory reservation system for > > > everyone to use. This pairs with the single memory allocation system > > > (malloc) that we have. Parts of the code base that aren't keeping these > > > systems up to date / obeying their results need to be corrected. > > > > The EFI allocations don't happen until boot time...so why do we need > > to do this now? We can instead have an EFI function to scan LMB and > > add to its memory map. > > We're talking about reservations, not allocations. So yes, when someone > is making their reservation, they need to make it. I don't understand > your question. As I understand it, this is used to tell EFI about a memory reservation. But the EFI code can scan the LMB reservations just before booting and update its tables. I don't see a need to keep them in sync before the boot actually happens. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-11 22:22 ` Simon Glass @ 2024-06-11 22:54 ` Tom Rini 2024-06-12 2:42 ` Simon Glass 0 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-11 22:54 UTC (permalink / raw) To: Simon Glass Cc: Heinrich Schuchardt, Sughosh Ganu, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot [-- Attachment #1: Type: text/plain, Size: 5207 bytes --] On Tue, Jun 11, 2024 at 04:22:25PM -0600, Simon Glass wrote: > Hi Tom, > > On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: > > > > On Tue, Jun 11, 2024 at 12:52:19PM -0600, Simon Glass wrote: > > > Hi, > > > > > > On Tue, 11 Jun 2024 at 08:36, Tom Rini <trini@konsulko.com> wrote: > > > > > > > > On Tue, Jun 11, 2024 at 12:17:16PM +0200, Heinrich Schuchardt wrote: > > > > > On 07.06.24 20:52, Sughosh Ganu wrote: > > > > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > > > > index 435e580fb3..93244161b0 100644 > > > > > > --- a/lib/efi_loader/efi_memory.c > > > > > > +++ b/lib/efi_loader/efi_memory.c > > > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > > > + int memory_type, > > > > > > + bool overlap_only_ram); > > > > > > + > > > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > > { > > > > > > struct event_efi_mem_map_update efi_map = {0}; > > > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > > if (is_addr_in_ram((uintptr_t)addr)) > > > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > > > > } > > > > > > + > > > > > > +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) { > > > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > > > + return -1; > > > > > > + } > > > > > > + > > > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > > > + op == MAP_OP_FREE ? > > > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > > > > > > This is dangerous. LMB might turn memory that is marked as > > > > > EfiReservedMemory which the OS must respect into EfiBootServicesData > > > > > which the OS may discard. > > > > > > > > > > E.g. initr_lmb() is being called after efi_memory_init(). > > > > > > > > > > Getting all cases of synchronization properly tested seems very hard to > > > > > me. Everything would be much easier if we had only a single memory > > > > > management system. > > > > > > > > Yes, Sughosh is working on the single memory reservation system for > > > > everyone to use. This pairs with the single memory allocation system > > > > (malloc) that we have. Parts of the code base that aren't keeping these > > > > systems up to date / obeying their results need to be corrected. > > > > > > The EFI allocations don't happen until boot time...so why do we need > > > to do this now? We can instead have an EFI function to scan LMB and > > > add to its memory map. > > > > We're talking about reservations, not allocations. So yes, when someone > > is making their reservation, they need to make it. I don't understand > > your question. > > As I understand it, this is used to tell EFI about a memory reservation. This patch, or this series? This series isn't about EFI. This patch is, yes. > But the EFI code can scan the LMB reservations just before booting and > update its tables. I don't see a need to keep them in sync before the > boot actually happens. But that wouldn't work. If something needs to reserve a region it needs to do it when it starts using it. It's not about the EFI map for the OS, it's about making sure that U-Boot doesn't scribble over a now-reserved area. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-11 22:54 ` Tom Rini @ 2024-06-12 2:42 ` Simon Glass 2024-06-12 5:48 ` Ilias Apalodimas 2024-06-12 6:06 ` Heinrich Schuchardt 0 siblings, 2 replies; 127+ messages in thread From: Simon Glass @ 2024-06-12 2:42 UTC (permalink / raw) To: Tom Rini Cc: Heinrich Schuchardt, Sughosh Ganu, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot Hi Tom, On Tue, 11 Jun 2024 at 16:54, Tom Rini <trini@konsulko.com> wrote: > > On Tue, Jun 11, 2024 at 04:22:25PM -0600, Simon Glass wrote: > > Hi Tom, > > > > On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: > > > > > > On Tue, Jun 11, 2024 at 12:52:19PM -0600, Simon Glass wrote: > > > > Hi, > > > > > > > > On Tue, 11 Jun 2024 at 08:36, Tom Rini <trini@konsulko.com> wrote: > > > > > > > > > > On Tue, Jun 11, 2024 at 12:17:16PM +0200, Heinrich Schuchardt wrote: > > > > > > On 07.06.24 20:52, Sughosh Ganu wrote: > > > > > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > > > > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > > > > > > > > > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > > > > > > index 435e580fb3..93244161b0 100644 > > > > > > > --- a/lib/efi_loader/efi_memory.c > > > > > > > +++ b/lib/efi_loader/efi_memory.c > > > > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > > > > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > > > > > > > extern bool is_addr_in_ram(uintptr_t addr); > > > > > > > > > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > > > > > > > + int memory_type, > > > > > > > + bool overlap_only_ram); > > > > > > > + > > > > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > > > { > > > > > > > struct event_efi_mem_map_update efi_map = {0}; > > > > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > > > > > > > if (is_addr_in_ram((uintptr_t)addr)) > > > > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > > > > > > > } > > > > > > > + > > > > > > > +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) { > > > > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > > > > + return -1; > > > > > > > + } > > > > > > > + > > > > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > > > > + op == MAP_OP_FREE ? > > > > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > > > > > > > > This is dangerous. LMB might turn memory that is marked as > > > > > > EfiReservedMemory which the OS must respect into EfiBootServicesData > > > > > > which the OS may discard. > > > > > > > > > > > > E.g. initr_lmb() is being called after efi_memory_init(). > > > > > > > > > > > > Getting all cases of synchronization properly tested seems very hard to > > > > > > me. Everything would be much easier if we had only a single memory > > > > > > management system. > > > > > > > > > > Yes, Sughosh is working on the single memory reservation system for > > > > > everyone to use. This pairs with the single memory allocation system > > > > > (malloc) that we have. Parts of the code base that aren't keeping these > > > > > systems up to date / obeying their results need to be corrected. > > > > > > > > The EFI allocations don't happen until boot time...so why do we need > > > > to do this now? We can instead have an EFI function to scan LMB and > > > > add to its memory map. > > > > > > We're talking about reservations, not allocations. So yes, when someone > > > is making their reservation, they need to make it. I don't understand > > > your question. > > > > As I understand it, this is used to tell EFI about a memory reservation. > > This patch, or this series? This series isn't about EFI. This patch is, > yes. > > > But the EFI code can scan the LMB reservations just before booting and > > update its tables. I don't see a need to keep them in sync before the > > boot actually happens. > > But that wouldn't work. If something needs to reserve a region it needs > to do it when it starts using it. It's not about the EFI map for the OS, > it's about making sure that U-Boot doesn't scribble over a now-reserved > area. I'm not convinced of that yet. EFI does not do allocations until it starts loading images, and it uses LMB for those (or at least it does with bootstd). I'm just trying to keep this all as simple as possible. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-12 2:42 ` Simon Glass @ 2024-06-12 5:48 ` Ilias Apalodimas 2024-06-12 6:20 ` Sughosh Ganu 2024-06-12 20:24 ` Simon Glass 2024-06-12 6:06 ` Heinrich Schuchardt 1 sibling, 2 replies; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-12 5:48 UTC (permalink / raw) To: Simon Glass Cc: Tom Rini, Heinrich Schuchardt, Sughosh Ganu, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot [...] > > > > > > > > + 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) { > > > > > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > > > > > + return -1; > > > > > > > > + } > > > > > > > > + > > > > > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > > > > > + op == MAP_OP_FREE ? > > > > > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > > > > > > > > > > This is dangerous. LMB might turn memory that is marked as > > > > > > > EfiReservedMemory which the OS must respect into EfiBootServicesData > > > > > > > which the OS may discard. > > > > > > > > > > > > > > E.g. initr_lmb() is being called after efi_memory_init(). > > > > > > > > > > > > > > Getting all cases of synchronization properly tested seems very hard to > > > > > > > me. Everything would be much easier if we had only a single memory > > > > > > > management system. > > > > > > > > > > > > Yes, Sughosh is working on the single memory reservation system for > > > > > > everyone to use. This pairs with the single memory allocation system > > > > > > (malloc) that we have. Parts of the code base that aren't keeping these > > > > > > systems up to date / obeying their results need to be corrected. > > > > > > > > > > The EFI allocations don't happen until boot time...so why do we need > > > > > to do this now? We can instead have an EFI function to scan LMB and > > > > > add to its memory map. > > > > > > > > We're talking about reservations, not allocations. So yes, when someone > > > > is making their reservation, they need to make it. I don't understand > > > > your question. > > > > > > As I understand it, this is used to tell EFI about a memory reservation. > > > > This patch, or this series? This series isn't about EFI. This patch is, > > yes. > > > > > But the EFI code can scan the LMB reservations just before booting and > > > update its tables. I don't see a need to keep them in sync before the > > > boot actually happens. > > > > But that wouldn't work. If something needs to reserve a region it needs > > to do it when it starts using it. It's not about the EFI map for the OS, > > it's about making sure that U-Boot doesn't scribble over a now-reserved > > area. > > I'm not convinced of that yet. EFI does not do allocations until it > starts loading images, It does in some cases. E.g The efi variables allocate some pages when the subsystem starts, the TCG protocol allocates the EventLog once it's installed and I am pretty sure we have more. > and it uses LMB for those (or at least it does > with bootstd). I'm just trying to keep this all as simple as possible. Heinrich already pointed out a potential danger in the current design. If an EFI allocation happens *before* LMB comes up, we might end up updating the efi memory map with the wrong attributes. That would lead to the OS discarding memory areas that should be preserved and we won't figure that out until the OS boots and blows up. Cheers /Ilias > > Regards, > Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-12 5:48 ` Ilias Apalodimas @ 2024-06-12 6:20 ` Sughosh Ganu 2024-06-12 20:24 ` Simon Glass 1 sibling, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-12 6:20 UTC (permalink / raw) To: Ilias Apalodimas Cc: Simon Glass, Tom Rini, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot hi Ilias, On Wed, 12 Jun 2024 at 11:19, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > [...] > > > > > > > > > > + 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) { > > > > > > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > > > > > > + return -1; > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > > > > > > + op == MAP_OP_FREE ? > > > > > > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > > > > > > > > > > > > This is dangerous. LMB might turn memory that is marked as > > > > > > > > EfiReservedMemory which the OS must respect into EfiBootServicesData > > > > > > > > which the OS may discard. > > > > > > > > > > > > > > > > E.g. initr_lmb() is being called after efi_memory_init(). > > > > > > > > > > > > > > > > Getting all cases of synchronization properly tested seems very hard to > > > > > > > > me. Everything would be much easier if we had only a single memory > > > > > > > > management system. > > > > > > > > > > > > > > Yes, Sughosh is working on the single memory reservation system for > > > > > > > everyone to use. This pairs with the single memory allocation system > > > > > > > (malloc) that we have. Parts of the code base that aren't keeping these > > > > > > > systems up to date / obeying their results need to be corrected. > > > > > > > > > > > > The EFI allocations don't happen until boot time...so why do we need > > > > > > to do this now? We can instead have an EFI function to scan LMB and > > > > > > add to its memory map. > > > > > > > > > > We're talking about reservations, not allocations. So yes, when someone > > > > > is making their reservation, they need to make it. I don't understand > > > > > your question. > > > > > > > > As I understand it, this is used to tell EFI about a memory reservation. > > > > > > This patch, or this series? This series isn't about EFI. This patch is, > > > yes. > > > > > > > But the EFI code can scan the LMB reservations just before booting and > > > > update its tables. I don't see a need to keep them in sync before the > > > > boot actually happens. > > > > > > But that wouldn't work. If something needs to reserve a region it needs > > > to do it when it starts using it. It's not about the EFI map for the OS, > > > it's about making sure that U-Boot doesn't scribble over a now-reserved > > > area. > > > > I'm not convinced of that yet. EFI does not do allocations until it > > starts loading images, > > It does in some cases. E.g The efi variables allocate some pages when > the subsystem starts, the TCG protocol allocates the EventLog once > it's installed and I am pretty sure we have more. > > > and it uses LMB for those (or at least it does > > with bootstd). I'm just trying to keep this all as simple as possible. > > Heinrich already pointed out a potential danger in the current design. > If an EFI allocation happens *before* LMB comes up, we might end up > updating the efi memory map with the wrong attributes. That would lead > to the OS discarding memory areas that should be preserved and we > won't figure that out until the OS boots and blows up. Like I mentioned in one of the earlier replies [1], this is actually not an issue, as long as modules are freeing memory that was actually allocated/reserved by them. In case of the EFI subsystem marking some memory region as EfiReservedMemory, this will send a notification to the LMB module, and the LMB module will mark this region as reserved. So unless some LMB user decides on freeing up memory that was not reserved by it, this should be just fine. Making use of the LMB API's as the common backend for allocating memory is a separate thing, and I will look into that. But the above highlighted issue is not one, with correctly working code. -sughosh [1] - https://lists.denx.de/pipermail/u-boot/2024-June/555883.html ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-12 5:48 ` Ilias Apalodimas 2024-06-12 6:20 ` Sughosh Ganu @ 2024-06-12 20:24 ` Simon Glass 1 sibling, 0 replies; 127+ messages in thread From: Simon Glass @ 2024-06-12 20:24 UTC (permalink / raw) To: Ilias Apalodimas Cc: Tom Rini, Heinrich Schuchardt, Sughosh Ganu, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot Hi Ilias, On Tue, 11 Jun 2024 at 23:49, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > [...] > > > > > > > > > > + 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) { > > > > > > > > > + log_debug("Invalid map update op received (%d)\n", op); > > > > > > > > > + return -1; > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + status = __efi_add_memory_map_pg(addr, pages, > > > > > > > > > + op == MAP_OP_FREE ? > > > > > > > > > + EFI_CONVENTIONAL_MEMORY : > > > > > > > > > > > > > > > > This is dangerous. LMB might turn memory that is marked as > > > > > > > > EfiReservedMemory which the OS must respect into EfiBootServicesData > > > > > > > > which the OS may discard. > > > > > > > > > > > > > > > > E.g. initr_lmb() is being called after efi_memory_init(). > > > > > > > > > > > > > > > > Getting all cases of synchronization properly tested seems very hard to > > > > > > > > me. Everything would be much easier if we had only a single memory > > > > > > > > management system. > > > > > > > > > > > > > > Yes, Sughosh is working on the single memory reservation system for > > > > > > > everyone to use. This pairs with the single memory allocation system > > > > > > > (malloc) that we have. Parts of the code base that aren't keeping these > > > > > > > systems up to date / obeying their results need to be corrected. > > > > > > > > > > > > The EFI allocations don't happen until boot time...so why do we need > > > > > > to do this now? We can instead have an EFI function to scan LMB and > > > > > > add to its memory map. > > > > > > > > > > We're talking about reservations, not allocations. So yes, when someone > > > > > is making their reservation, they need to make it. I don't understand > > > > > your question. > > > > > > > > As I understand it, this is used to tell EFI about a memory reservation. > > > > > > This patch, or this series? This series isn't about EFI. This patch is, > > > yes. > > > > > > > But the EFI code can scan the LMB reservations just before booting and > > > > update its tables. I don't see a need to keep them in sync before the > > > > boot actually happens. > > > > > > But that wouldn't work. If something needs to reserve a region it needs > > > to do it when it starts using it. It's not about the EFI map for the OS, > > > it's about making sure that U-Boot doesn't scribble over a now-reserved > > > area. > > > > I'm not convinced of that yet. EFI does not do allocations until it > > starts loading images, > > It does in some cases. E.g The efi variables allocate some pages when > the subsystem starts, the TCG protocol allocates the EventLog once > it's installed and I am pretty sure we have more. Both of those seem wrong to me, though. - EFI variables should use malloc() like other small amounts of data - TCG should probably use a bloblist, but in any case I suspect it is needed beyond EFI > > > and it uses LMB for those (or at least it does > > with bootstd). I'm just trying to keep this all as simple as possible. > > Heinrich already pointed out a potential danger in the current design. > If an EFI allocation happens *before* LMB comes up, we might end up > updating the efi memory map with the wrong attributes. That would lead > to the OS discarding memory areas that should be preserved and we > won't figure that out until the OS boots and blows up. Yes, I believe the EFI memory sort-out should happen when booting and not before. It is a bit like creating a plate of spaghetti if we do all this stuff randomly while trying to boot different things, retrying, etc.... Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-12 2:42 ` Simon Glass 2024-06-12 5:48 ` Ilias Apalodimas @ 2024-06-12 6:06 ` Heinrich Schuchardt 2024-06-12 20:24 ` Simon Glass 1 sibling, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-12 6:06 UTC (permalink / raw) To: Simon Glass, Tom Rini Cc: Sughosh Ganu, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot Am 12. Juni 2024 04:42:00 MESZ schrieb Simon Glass <sjg@chromium.org>: >Hi Tom, > >On Tue, 11 Jun 2024 at 16:54, Tom Rini <trini@konsulko.com> wrote: >> >> On Tue, Jun 11, 2024 at 04:22:25PM -0600, Simon Glass wrote: >> > Hi Tom, >> > >> > On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: >> > > >> > > On Tue, Jun 11, 2024 at 12:52:19PM -0600, Simon Glass wrote: >> > > > Hi, >> > > > >> > > > On Tue, 11 Jun 2024 at 08:36, Tom Rini <trini@konsulko.com> wrote: >> > > > > >> > > > > On Tue, Jun 11, 2024 at 12:17:16PM +0200, Heinrich Schuchardt wrote: >> > > > > > On 07.06.24 20:52, Sughosh Ganu wrote: >> > > > > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- >> > > > > > > 1 file changed, 58 insertions(+), 12 deletions(-) >> > > > > > > >> > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c >> > > > > > > index 435e580fb3..93244161b0 100644 >> > > > > > > --- a/lib/efi_loader/efi_memory.c >> > > > > > > +++ b/lib/efi_loader/efi_memory.c >> > > > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { >> > > > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) >> > > > > > > extern bool is_addr_in_ram(uintptr_t addr); >> > > > > > > >> > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, >> > > > > > > + int memory_type, >> > > > > > > + bool overlap_only_ram); >> > > > > > > + >> > > > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) >> > > > > > > { >> > > > > > > struct event_efi_mem_map_update efi_map = {0}; >> > > > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) >> > > > > > > if (is_addr_in_ram((uintptr_t)addr)) >> > > > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); >> > > > > > > } >> > > > > > > + >> > > > > > > +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) { >> > > > > > > + log_debug("Invalid map update op received (%d)\n", op); >> > > > > > > + return -1; >> > > > > > > + } >> > > > > > > + >> > > > > > > + status = __efi_add_memory_map_pg(addr, pages, >> > > > > > > + op == MAP_OP_FREE ? >> > > > > > > + EFI_CONVENTIONAL_MEMORY : >> > > > > > >> > > > > > This is dangerous. LMB might turn memory that is marked as >> > > > > > EfiReservedMemory which the OS must respect into EfiBootServicesData >> > > > > > which the OS may discard. >> > > > > > >> > > > > > E.g. initr_lmb() is being called after efi_memory_init(). >> > > > > > >> > > > > > Getting all cases of synchronization properly tested seems very hard to >> > > > > > me. Everything would be much easier if we had only a single memory >> > > > > > management system. >> > > > > >> > > > > Yes, Sughosh is working on the single memory reservation system for >> > > > > everyone to use. This pairs with the single memory allocation system >> > > > > (malloc) that we have. Parts of the code base that aren't keeping these >> > > > > systems up to date / obeying their results need to be corrected. >> > > > >> > > > The EFI allocations don't happen until boot time...so why do we need >> > > > to do this now? We can instead have an EFI function to scan LMB and >> > > > add to its memory map. >> > > >> > > We're talking about reservations, not allocations. So yes, when someone >> > > is making their reservation, they need to make it. I don't understand >> > > your question. >> > >> > As I understand it, this is used to tell EFI about a memory reservation. >> >> This patch, or this series? This series isn't about EFI. This patch is, >> yes. >> >> > But the EFI code can scan the LMB reservations just before booting and >> > update its tables. I don't see a need to keep them in sync before the >> > boot actually happens. >> >> But that wouldn't work. If something needs to reserve a region it needs >> to do it when it starts using it. It's not about the EFI map for the OS, >> it's about making sure that U-Boot doesn't scribble over a now-reserved >> area. > >I'm not convinced of that yet. EFI does not do allocations until it >starts loading images, and it uses LMB for those (or at least it does >with bootstd). I'm just trying to keep this all as simple as possible. You can load a boot time EFI driver which keeps running while you return to U-Boot to load another file. The background activity of the EFI driver binary can result in any number of allocations. Best regards Heinrich > >Regards, >Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 15/31] efi_memory: add an event handler to update memory map 2024-06-12 6:06 ` Heinrich Schuchardt @ 2024-06-12 20:24 ` Simon Glass 0 siblings, 0 replies; 127+ messages in thread From: Simon Glass @ 2024-06-12 20:24 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Tom Rini, Sughosh Ganu, Ilias Apalodimas, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot Hi Heinrich, On Wed, 12 Jun 2024 at 00:11, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > Am 12. Juni 2024 04:42:00 MESZ schrieb Simon Glass <sjg@chromium.org>: > >Hi Tom, > > > >On Tue, 11 Jun 2024 at 16:54, Tom Rini <trini@konsulko.com> wrote: > >> > >> On Tue, Jun 11, 2024 at 04:22:25PM -0600, Simon Glass wrote: > >> > Hi Tom, > >> > > >> > On Tue, 11 Jun 2024 at 15:01, Tom Rini <trini@konsulko.com> wrote: > >> > > > >> > > On Tue, Jun 11, 2024 at 12:52:19PM -0600, Simon Glass wrote: > >> > > > Hi, > >> > > > > >> > > > On Tue, 11 Jun 2024 at 08:36, Tom Rini <trini@konsulko.com> wrote: > >> > > > > > >> > > > > On Tue, Jun 11, 2024 at 12:17:16PM +0200, Heinrich Schuchardt wrote: > >> > > > > > On 07.06.24 20:52, Sughosh Ganu wrote: > >> > > > > > > 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/efi_memory.c | 70 ++++++++++++++++++++++++++++++------- > >> > > > > > > 1 file changed, 58 insertions(+), 12 deletions(-) > >> > > > > > > > >> > > > > > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > >> > > > > > > index 435e580fb3..93244161b0 100644 > >> > > > > > > --- a/lib/efi_loader/efi_memory.c > >> > > > > > > +++ b/lib/efi_loader/efi_memory.c > >> > > > > > > @@ -73,6 +73,10 @@ struct efi_pool_allocation { > >> > > > > > > #if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) > >> > > > > > > extern bool is_addr_in_ram(uintptr_t addr); > >> > > > > > > > >> > > > > > > +static efi_status_t __efi_add_memory_map_pg(u64 start, u64 pages, > >> > > > > > > + int memory_type, > >> > > > > > > + bool overlap_only_ram); > >> > > > > > > + > >> > > > > > > static void efi_map_update_notify(u64 addr, u64 size, u8 op) > >> > > > > > > { > >> > > > > > > struct event_efi_mem_map_update efi_map = {0}; > >> > > > > > > @@ -84,6 +88,34 @@ static void efi_map_update_notify(u64 addr, u64 size, u8 op) > >> > > > > > > if (is_addr_in_ram((uintptr_t)addr)) > >> > > > > > > event_notify(EVT_EFI_MEM_MAP_UPDATE, &efi_map, sizeof(efi_map)); > >> > > > > > > } > >> > > > > > > + > >> > > > > > > +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) { > >> > > > > > > + log_debug("Invalid map update op received (%d)\n", op); > >> > > > > > > + return -1; > >> > > > > > > + } > >> > > > > > > + > >> > > > > > > + status = __efi_add_memory_map_pg(addr, pages, > >> > > > > > > + op == MAP_OP_FREE ? > >> > > > > > > + EFI_CONVENTIONAL_MEMORY : > >> > > > > > > >> > > > > > This is dangerous. LMB might turn memory that is marked as > >> > > > > > EfiReservedMemory which the OS must respect into EfiBootServicesData > >> > > > > > which the OS may discard. > >> > > > > > > >> > > > > > E.g. initr_lmb() is being called after efi_memory_init(). > >> > > > > > > >> > > > > > Getting all cases of synchronization properly tested seems very hard to > >> > > > > > me. Everything would be much easier if we had only a single memory > >> > > > > > management system. > >> > > > > > >> > > > > Yes, Sughosh is working on the single memory reservation system for > >> > > > > everyone to use. This pairs with the single memory allocation system > >> > > > > (malloc) that we have. Parts of the code base that aren't keeping these > >> > > > > systems up to date / obeying their results need to be corrected. > >> > > > > >> > > > The EFI allocations don't happen until boot time...so why do we need > >> > > > to do this now? We can instead have an EFI function to scan LMB and > >> > > > add to its memory map. > >> > > > >> > > We're talking about reservations, not allocations. So yes, when someone > >> > > is making their reservation, they need to make it. I don't understand > >> > > your question. > >> > > >> > As I understand it, this is used to tell EFI about a memory reservation. > >> > >> This patch, or this series? This series isn't about EFI. This patch is, > >> yes. > >> > >> > But the EFI code can scan the LMB reservations just before booting and > >> > update its tables. I don't see a need to keep them in sync before the > >> > boot actually happens. > >> > >> But that wouldn't work. If something needs to reserve a region it needs > >> to do it when it starts using it. It's not about the EFI map for the OS, > >> it's about making sure that U-Boot doesn't scribble over a now-reserved > >> area. > > > >I'm not convinced of that yet. EFI does not do allocations until it > >starts loading images, and it uses LMB for those (or at least it does > >with bootstd). I'm just trying to keep this all as simple as possible. > > You can load a boot time EFI driver which keeps running while you return to U-Boot to load another file. > > The background activity of the EFI driver binary can result in any number of allocations. U-Boot isn't multi-threaded so I am really not sure what would happen in that case. Does it actually work? Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 16/31] lmb: add an event handler to update memory map 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (14 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 15/31] efi_memory: add an event handler to update " Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 17/31] lmb: remove call to efi_lmb_reserve() Sughosh Ganu ` (16 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu 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 LMB module to update it's memory map accordingly when such changes happen. As a consequence, any subsequent memory request would honour the updated memory map and allocations would only happen from available memory. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- lib/Kconfig | 1 + lib/lmb.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/Kconfig b/lib/Kconfig index 9ea02ae006..9e465a748b 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -1111,6 +1111,7 @@ config LMB bool "Enable the logical memory blocks library (lmb)" default y if ARC || ARM || M68K || MICROBLAZE || MIPS || \ NIOS2 || PPC || RISCV || SANDBOX || SH || X86 || XTENSA + select EVENT help Support the library logical memory blocks. diff --git a/lib/lmb.c b/lib/lmb.c index 313735dbe3..3059609aea 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -16,6 +16,7 @@ #include <asm/global_data.h> #include <asm/sections.h> +#include <asm-generic/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -719,3 +720,36 @@ __weak void arch_lmb_reserve(void) { /* please define platform specific arch_lmb_reserve() */ } + +#if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY) +static long lmb_reserve_nooverwrite(phys_addr_t base, phys_size_t size) +{ + struct lmb_region *_rgn = &lmb.reserved; + + return lmb_add_region_flags(_rgn, base, size, LMB_NOOVERWRITE); +} + +static int efi_mem_map_update_sync(void *ctx, struct event *event) +{ + u8 op; + long ret; + phys_addr_t addr; + phys_size_t size; + struct event_efi_mem_map_update *efi_map = &event->data.efi_mem_map; + + addr = virt_to_phys((void *)(uintptr_t)efi_map->base); + size = efi_map->size; + op = efi_map->op; + + if (op != MAP_OP_RESERVE && op != MAP_OP_FREE) { + log_debug("Invalid map update op received (%d)\n", op); + return -1; + } + + ret = op == MAP_OP_RESERVE ? lmb_reserve_nooverwrite(addr, size) : + __lmb_free(addr, size); + + return !ret ? 0 : -1; +} +EVENT_SPY_FULL(EVT_EFI_MEM_MAP_UPDATE, efi_mem_map_update_sync); +#endif /* MEM_MAP_UPDATE_NOTIFY */ -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 17/31] lmb: remove call to efi_lmb_reserve() 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (15 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 16/31] lmb: " Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 11:46 ` Ilias Apalodimas 2024-06-11 9:11 ` Heinrich Schuchardt 2024-06-07 18:52 ` [RFC PATCH 18/31] sandbox: iommu: remove lmb allocation in the driver Sughosh Ganu ` (15 subsequent siblings) 32 siblings, 2 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The changes in the EFI memory map are now notified to the LMB module. There is therefore no need to explicitly get the efi memory map and set aside the EFI allocated memory. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- lib/lmb.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/lib/lmb.c b/lib/lmb.c index 3059609aea..c9f6ca692e 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -204,38 +204,6 @@ void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align) } } -/** - * 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; -} - /** * lmb_reserve_common() - Reserve memory region occupied by U-Boot image * @fdt_blob: pointer to the FDT blob @@ -255,9 +223,6 @@ 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(); } /** -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 17/31] lmb: remove call to efi_lmb_reserve() 2024-06-07 18:52 ` [RFC PATCH 17/31] lmb: remove call to efi_lmb_reserve() Sughosh Ganu @ 2024-06-10 11:46 ` Ilias Apalodimas 2024-06-11 9:11 ` Heinrich Schuchardt 1 sibling, 0 replies; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 11:46 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Fri, 7 Jun 2024 at 21:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > The changes in the EFI memory map are now notified to the LMB > module. There is therefore no need to explicitly get the efi memory > map and set aside the EFI allocated memory. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > lib/lmb.c | 35 ----------------------------------- > 1 file changed, 35 deletions(-) > > diff --git a/lib/lmb.c b/lib/lmb.c > index 3059609aea..c9f6ca692e 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -204,38 +204,6 @@ void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align) > } > } > > -/** > - * 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; > -} > - > /** > * lmb_reserve_common() - Reserve memory region occupied by U-Boot image > * @fdt_blob: pointer to the FDT blob > @@ -255,9 +223,6 @@ 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(); > } > > /** > -- > 2.34.1 > Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 17/31] lmb: remove call to efi_lmb_reserve() 2024-06-07 18:52 ` [RFC PATCH 17/31] lmb: remove call to efi_lmb_reserve() Sughosh Ganu 2024-06-10 11:46 ` Ilias Apalodimas @ 2024-06-11 9:11 ` Heinrich Schuchardt 2024-06-11 9:49 ` Sughosh Ganu 1 sibling, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-11 9:11 UTC (permalink / raw) To: Sughosh Ganu Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On 07.06.24 20:52, Sughosh Ganu wrote: > The changes in the EFI memory map are now notified to the LMB > module. There is therefore no need to explicitly get the efi memory > map and set aside the EFI allocated memory. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > lib/lmb.c | 35 ----------------------------------- > 1 file changed, 35 deletions(-) > > diff --git a/lib/lmb.c b/lib/lmb.c > index 3059609aea..c9f6ca692e 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -204,38 +204,6 @@ void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align) > } > } > > -/** > - * 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); Now that you have removed the last usage of LMB_NOMAP, please, remove it from enum lmb_flags. Best regards Heinrich > - } > - } > - efi_free_pool(memmap); > - > - return 0; > -} > - > /** > * lmb_reserve_common() - Reserve memory region occupied by U-Boot image > * @fdt_blob: pointer to the FDT blob > @@ -255,9 +223,6 @@ 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(); > } > > /** ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 17/31] lmb: remove call to efi_lmb_reserve() 2024-06-11 9:11 ` Heinrich Schuchardt @ 2024-06-11 9:49 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-11 9:49 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On Tue, 11 Jun 2024 at 14:42, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 07.06.24 20:52, Sughosh Ganu wrote: > > The changes in the EFI memory map are now notified to the LMB > > module. There is therefore no need to explicitly get the efi memory > > map and set aside the EFI allocated memory. > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > --- > > lib/lmb.c | 35 ----------------------------------- > > 1 file changed, 35 deletions(-) > > > > diff --git a/lib/lmb.c b/lib/lmb.c > > index 3059609aea..c9f6ca692e 100644 > > --- a/lib/lmb.c > > +++ b/lib/lmb.c > > @@ -204,38 +204,6 @@ void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align) > > } > > } > > > > -/** > > - * 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); > > > Now that you have removed the last usage of LMB_NOMAP, please, remove it > from enum lmb_flags. Not all instances are removed. This flag gets used for reserving FDT memory areas as well. Used in boot/image-fdt.c:boot_fdt_add_mem_rsv_regions(). -sughosh > > - } > > - efi_free_pool(memmap); > > - > > - return 0; > > -} > > - > > /** > > * lmb_reserve_common() - Reserve memory region occupied by U-Boot image > > * @fdt_blob: pointer to the FDT blob > > @@ -255,9 +223,6 @@ 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(); > > } > > > > /** > ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 18/31] sandbox: iommu: remove lmb allocation in the driver 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (16 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 17/31] lmb: remove call to efi_lmb_reserve() Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 19/31] zynq: lmb: do not add to lmb map before relocation Sughosh Ganu ` (14 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The sandbox iommu driver uses the LMB module to allocate a particular range of memory for the device virtual address(DVA). This used to work earlier since the LMB memory map was caller specific and not global. But with the change to make the LMB allocations global and persistent, adding this memory range has other side effects. On the other hand, the sandbox iommu test expects to see this particular value of the DVA. Use the DVA address directly, instead of mapping it in the LMB memory map, and then have it allocated. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- drivers/iommu/sandbox_iommu.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/sandbox_iommu.c b/drivers/iommu/sandbox_iommu.c index c5bb88d299..67293e20f4 100644 --- a/drivers/iommu/sandbox_iommu.c +++ b/drivers/iommu/sandbox_iommu.c @@ -10,6 +10,7 @@ #include <asm/io.h> #include <linux/sizes.h> +#define DVA_ADDR 0x89abc000 #define IOMMU_PAGE_SIZE SZ_4K static dma_addr_t sandbox_iommu_map(struct udevice *dev, void *addr, @@ -22,7 +23,7 @@ static dma_addr_t sandbox_iommu_map(struct udevice *dev, void *addr, off = virt_to_phys(addr) - paddr; psize = ALIGN(size + off, IOMMU_PAGE_SIZE); - dva = lmb_alloc(psize, IOMMU_PAGE_SIZE); + dva = (phys_addr_t)DVA_ADDR; return dva + off; } @@ -36,8 +37,6 @@ static void sandbox_iommu_unmap(struct udevice *dev, dma_addr_t addr, dva = ALIGN_DOWN(addr, IOMMU_PAGE_SIZE); psize = size + (addr - dva); psize = ALIGN(psize, IOMMU_PAGE_SIZE); - - lmb_free(dva, psize); } static struct iommu_ops sandbox_iommu_ops = { @@ -47,8 +46,6 @@ static struct iommu_ops sandbox_iommu_ops = { static int sandbox_iommu_probe(struct udevice *dev) { - lmb_add(0x89abc000, SZ_16K); - return 0; } -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 19/31] zynq: lmb: do not add to lmb map before relocation 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (17 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 18/31] sandbox: iommu: remove lmb allocation in the driver Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 20/31] test: cedit: use allocated address for reading file Sughosh Ganu ` (13 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The LMB memory is typically not needed very early in the platform's boot. Do not add memory to the LMB map before relocation. Reservation of common areas and adding of memory is done after relocation. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- board/xilinx/common/board.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 7be1b6e511..38967fc705 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -13,7 +13,6 @@ #include <image.h> #include <init.h> #include <jffs2/load_kernel.h> -#include <lmb.h> #include <log.h> #include <asm/global_data.h> #include <asm/sections.h> @@ -666,36 +665,6 @@ int embedded_dtb_select(void) } #endif -#if defined(CONFIG_LMB) - -#ifndef MMU_SECTION_SIZE -#define MMU_SECTION_SIZE (1 * 1024 * 1024) -#endif - -phys_addr_t board_get_usable_ram_top(phys_size_t total_size) -{ - phys_size_t size; - phys_addr_t reg; - - if (!total_size) - return gd->ram_top; - - if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8)) - panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob); - - /* found enough not-reserved memory to relocated U-Boot */ - lmb_add(gd->ram_base, gd->ram_size); - boot_fdt_add_mem_rsv_regions((void *)gd->fdt_blob); - size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); - reg = lmb_alloc(size, MMU_SECTION_SIZE); - - if (!reg) - reg = gd->ram_top - size; - - return reg + size; -} -#endif - #ifdef CONFIG_OF_BOARD_SETUP #define MAX_RAND_SIZE 8 int ft_board_setup(void *blob, struct bd_info *bd) -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 20/31] test: cedit: use allocated address for reading file 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (18 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 19/31] zynq: lmb: do not add to lmb map before relocation Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-11 18:52 ` Simon Glass 2024-06-07 18:52 ` [RFC PATCH 21/31] test: event: update the expected event dump output Sughosh Ganu ` (12 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu Instead of a randomly selected address, use an LMB allocated one for reading the file into memory. With the LMB map now being persistent and global, the address used for reading the file might be already allocated as non-overwritable, resulting in a failure. Get a valid address from LMB and then read the file to that address. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- test/boot/cedit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/boot/cedit.c b/test/boot/cedit.c index aa41719048..1f4147da89 100644 --- a/test/boot/cedit.c +++ b/test/boot/cedit.c @@ -8,6 +8,7 @@ #include <cedit.h> #include <env.h> #include <expo.h> +#include <lmb.h> #include <mapmem.h> #include <dm/ofnode.h> #include <test/ut.h> @@ -62,7 +63,7 @@ static int cedit_fdt(struct unit_test_state *uts) struct video_priv *vid_priv; extern struct expo *cur_exp; struct scene_obj_menu *menu; - ulong addr = 0x1000; + ulong addr; struct ofprop prop; struct scene *scn; oftree tree; @@ -87,6 +88,8 @@ static int cedit_fdt(struct unit_test_state *uts) str = abuf_data(&tline->buf); strcpy(str, "my-machine"); + addr = lmb_alloc(1024, 1024); + ut_asserteq(!!addr, !0); ut_assertok(run_command("cedit write_fdt hostfs - settings.dtb", 0)); ut_assertok(run_commandf("load hostfs - %lx settings.dtb", addr)); ut_assert_nextlinen("1024 bytes read"); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 20/31] test: cedit: use allocated address for reading file 2024-06-07 18:52 ` [RFC PATCH 20/31] test: cedit: use allocated address for reading file Sughosh Ganu @ 2024-06-11 18:52 ` Simon Glass 0 siblings, 0 replies; 127+ messages in thread From: Simon Glass @ 2024-06-11 18:52 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Sughosh, On Fri, 7 Jun 2024 at 12:54, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > Instead of a randomly selected address, use an LMB allocated one for > reading the file into memory. With the LMB map now being persistent > and global, the address used for reading the file might be already > allocated as non-overwritable, resulting in a failure. Get a valid > address from LMB and then read the file to that address. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > test/boot/cedit.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/test/boot/cedit.c b/test/boot/cedit.c > index aa41719048..1f4147da89 100644 > --- a/test/boot/cedit.c > +++ b/test/boot/cedit.c > @@ -8,6 +8,7 @@ > #include <cedit.h> > #include <env.h> > #include <expo.h> > +#include <lmb.h> > #include <mapmem.h> > #include <dm/ofnode.h> > #include <test/ut.h> > @@ -62,7 +63,7 @@ static int cedit_fdt(struct unit_test_state *uts) > struct video_priv *vid_priv; > extern struct expo *cur_exp; > struct scene_obj_menu *menu; > - ulong addr = 0x1000; > + ulong addr; > struct ofprop prop; > struct scene *scn; > oftree tree; > @@ -87,6 +88,8 @@ static int cedit_fdt(struct unit_test_state *uts) > str = abuf_data(&tline->buf); > strcpy(str, "my-machine"); > > + addr = lmb_alloc(1024, 1024); > + ut_asserteq(!!addr, !0); > ut_assertok(run_command("cedit write_fdt hostfs - settings.dtb", 0)); > ut_assertok(run_commandf("load hostfs - %lx settings.dtb", addr)); > ut_assert_nextlinen("1024 bytes read"); > -- > 2.34.1 > This is a situation where we don't want to make changes. We know that address is valid for testing. We won't have LMB allocations that persist across tests...even if that were to happen we would want the test to reset the lmb state. That is how the sandbox test-system works. Regards, Simon ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 21/31] test: event: update the expected event dump output 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (19 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 20/31] test: cedit: use allocated address for reading file Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox Sughosh Ganu ` (11 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu 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 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py index e282c67335..b14e098895 100644 --- a/test/py/tests/test_event_dump.py +++ b/test/py/tests/test_event_dump.py @@ -16,9 +16,11 @@ def test_event_dump(u_boot_console): out = util.run_and_log(cons, ['scripts/event_dump.py', sandbox]) expect = '''.*Event type Id Source location -------------------- ------------------------------ ------------------------------ +EVT_EFI_MEM_MAP_UPDATE efi_mem_map_update_sync .*lib/lmb.c:.* 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 -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (20 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 21/31] test: event: update the expected event dump output Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-10 17:44 ` Tom Rini 2024-06-07 18:52 ` [RFC PATCH 23/31] test: lmb: initialise the lmb structure before tests Sughosh Ganu ` (10 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The LMB memory map is now persistent and global. Running the tests for the LMB module will result in the memory map getting reset, and this will have side-effects on the rest of the working of the platform. Run the LMB tests only on the sandbox platform, which is meant for running such kinds of tests. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- test/lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lib/Makefile b/test/lib/Makefile index e75a263e6a..9154e07993 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -9,7 +9,7 @@ obj-$(CONFIG_EFI_LOADER) += efi_device_path.o obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o obj-y += hexdump.o obj-$(CONFIG_SANDBOX) += kconfig.o -obj-y += lmb.o +obj-$(CONFIG_SANDBOX) += lmb.o obj-y += longjmp.o obj-$(CONFIG_CONSOLE_RECORD) += test_print.o obj-$(CONFIG_SSCANF) += sscanf.o -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox 2024-06-07 18:52 ` [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox Sughosh Ganu @ 2024-06-10 17:44 ` Tom Rini 2024-06-11 8:55 ` Sughosh Ganu 0 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-10 17:44 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 596 bytes --] On Sat, Jun 08, 2024 at 12:22:31AM +0530, Sughosh Ganu wrote: > The LMB memory map is now persistent and global. Running the tests for > the LMB module will result in the memory map getting reset, and this > will have side-effects on the rest of the working of the platform. Run > the LMB tests only on the sandbox platform, which is meant for running > such kinds of tests. > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> I'm not sure about this. We can reset real hardware as often as we need, too. Did you run in to problems with this test on non-sandbox? -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox 2024-06-10 17:44 ` Tom Rini @ 2024-06-11 8:55 ` Sughosh Ganu 2024-06-11 9:56 ` Heinrich Schuchardt 2024-06-11 14:05 ` Tom Rini 0 siblings, 2 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-11 8:55 UTC (permalink / raw) To: Tom Rini Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Mon, 10 Jun 2024 at 23:14, Tom Rini <trini@konsulko.com> wrote: > > On Sat, Jun 08, 2024 at 12:22:31AM +0530, Sughosh Ganu wrote: > > > The LMB memory map is now persistent and global. Running the tests for > > the LMB module will result in the memory map getting reset, and this > > will have side-effects on the rest of the working of the platform. Run > > the LMB tests only on the sandbox platform, which is meant for running > > such kinds of tests. > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > I'm not sure about this. We can reset real hardware as often as we need, > too. Did you run in to problems with this test on non-sandbox? But do we want to reset the state of the LMB memory map on real hardware? This was working up until now because of the local nature of the LMB variables. But if the LMB memory map is to be persistent, should we allow it to be changed for running some test? That would have side effects? I think running these tests on sandbox should suffice. I mean there isn't any aspect of the LMB module that is not getting tested on sandbox, right? -sughosh ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox 2024-06-11 8:55 ` Sughosh Ganu @ 2024-06-11 9:56 ` Heinrich Schuchardt 2024-06-11 10:09 ` Sughosh Ganu 2024-06-11 14:05 ` Tom Rini 1 sibling, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-11 9:56 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini On 11.06.24 10:55, Sughosh Ganu wrote: > On Mon, 10 Jun 2024 at 23:14, Tom Rini <trini@konsulko.com> wrote: >> >> On Sat, Jun 08, 2024 at 12:22:31AM +0530, Sughosh Ganu wrote: >> >>> The LMB memory map is now persistent and global. Running the tests for >>> the LMB module will result in the memory map getting reset, and this >>> will have side-effects on the rest of the working of the platform. Run >>> the LMB tests only on the sandbox platform, which is meant for running >>> such kinds of tests. >>> >>> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> >> >> I'm not sure about this. We can reset real hardware as often as we need, >> too. Did you run in to problems with this test on non-sandbox? > > But do we want to reset the state of the LMB memory map on real > hardware? This was working up until now because of the local nature of > the LMB variables. But if the LMB memory map is to be persistent, > should we allow it to be changed for running some test? That would > have side effects? I think running these tests on sandbox should > suffice. I mean there isn't any aspect of the LMB module that is not > getting tested on sandbox, right? > > -sughosh We should run tests on systems with different bitness and endianness. As the LMB test does not rely on any sandbox driver we should be able to run it on any system. If the memory map is not usable anymore after the test, the system should be rebooted. Best regards Heinrich ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox 2024-06-11 9:56 ` Heinrich Schuchardt @ 2024-06-11 10:09 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-11 10:09 UTC (permalink / raw) To: Heinrich Schuchardt Cc: u-boot, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Tom Rini On Tue, 11 Jun 2024 at 15:31, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 11.06.24 10:55, Sughosh Ganu wrote: > > On Mon, 10 Jun 2024 at 23:14, Tom Rini <trini@konsulko.com> wrote: > >> > >> On Sat, Jun 08, 2024 at 12:22:31AM +0530, Sughosh Ganu wrote: > >> > >>> The LMB memory map is now persistent and global. Running the tests for > >>> the LMB module will result in the memory map getting reset, and this > >>> will have side-effects on the rest of the working of the platform. Run > >>> the LMB tests only on the sandbox platform, which is meant for running > >>> such kinds of tests. > >>> > >>> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > >> > >> I'm not sure about this. We can reset real hardware as often as we need, > >> too. Did you run in to problems with this test on non-sandbox? > > > > But do we want to reset the state of the LMB memory map on real > > hardware? This was working up until now because of the local nature of > > the LMB variables. But if the LMB memory map is to be persistent, > > should we allow it to be changed for running some test? That would > > have side effects? I think running these tests on sandbox should > > suffice. I mean there isn't any aspect of the LMB module that is not > > getting tested on sandbox, right? > > > > -sughosh > > We should run tests on systems with different bitness and endianness. > I would think there are platforms in the CI suite that are big-endian, because if there are, they are surely exercising the LMB memory reservation functions multiple times. I am only talking about running the unit tests on sandbox. > As the LMB test does not rely on any sandbox driver we should be able to > run it on any system. > > If the memory map is not usable anymore after the test, the system > should be rebooted. Yes, that will happen when the test is run in CI -- I am working on changes to have the LMB tests run separately and then reboot the system. But if the tests are run by a user manually, that might have side-effects. Btw, even today, the LMB tests only get run on sandbox as part of the CI run. What happens is that the tests are enabled to be run on other platforms as well(snow as of now). But OTOH, an explicit reboot can be called after having run the tests. This would handle the scenario of a user running these manually from command-line. -sughosh > > Best regards > > Heinrich ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox 2024-06-11 8:55 ` Sughosh Ganu 2024-06-11 9:56 ` Heinrich Schuchardt @ 2024-06-11 14:05 ` Tom Rini 2024-06-11 14:06 ` Ilias Apalodimas 1 sibling, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-11 14:05 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 1542 bytes --] On Tue, Jun 11, 2024 at 02:25:05PM +0530, Sughosh Ganu wrote: > On Mon, 10 Jun 2024 at 23:14, Tom Rini <trini@konsulko.com> wrote: > > > > On Sat, Jun 08, 2024 at 12:22:31AM +0530, Sughosh Ganu wrote: > > > > > The LMB memory map is now persistent and global. Running the tests for > > > the LMB module will result in the memory map getting reset, and this > > > will have side-effects on the rest of the working of the platform. Run > > > the LMB tests only on the sandbox platform, which is meant for running > > > such kinds of tests. > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > I'm not sure about this. We can reset real hardware as often as we need, > > too. Did you run in to problems with this test on non-sandbox? > > But do we want to reset the state of the LMB memory map on real > hardware? This was working up until now because of the local nature of > the LMB variables. But if the LMB memory map is to be persistent, > should we allow it to be changed for running some test? That would > have side effects? I think running these tests on sandbox should > suffice. I mean there isn't any aspect of the LMB module that is not > getting tested on sandbox, right? When running our test/ test code on hardware side effects are fine, this isn't a POST type test that gets used in production. Do changes, reset platform as needed just like sandbox, etc. And yes, a user running tests that have side effects manually and then not dealing with them is user error. -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox 2024-06-11 14:05 ` Tom Rini @ 2024-06-11 14:06 ` Ilias Apalodimas 0 siblings, 0 replies; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-11 14:06 UTC (permalink / raw) To: Tom Rini Cc: Sughosh Ganu, u-boot, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Tue, 11 Jun 2024 at 17:05, Tom Rini <trini@konsulko.com> wrote: > > On Tue, Jun 11, 2024 at 02:25:05PM +0530, Sughosh Ganu wrote: > > On Mon, 10 Jun 2024 at 23:14, Tom Rini <trini@konsulko.com> wrote: > > > > > > On Sat, Jun 08, 2024 at 12:22:31AM +0530, Sughosh Ganu wrote: > > > > > > > The LMB memory map is now persistent and global. Running the tests for > > > > the LMB module will result in the memory map getting reset, and this > > > > will have side-effects on the rest of the working of the platform. Run > > > > the LMB tests only on the sandbox platform, which is meant for running > > > > such kinds of tests. > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > > > > > I'm not sure about this. We can reset real hardware as often as we need, > > > too. Did you run in to problems with this test on non-sandbox? > > > > But do we want to reset the state of the LMB memory map on real > > hardware? This was working up until now because of the local nature of > > the LMB variables. But if the LMB memory map is to be persistent, > > should we allow it to be changed for running some test? That would > > have side effects? I think running these tests on sandbox should > > suffice. I mean there isn't any aspect of the LMB module that is not > > getting tested on sandbox, right? > > When running our test/ test code on hardware side effects are fine, this > isn't a POST type test that gets used in production. Do changes, reset > platform as needed just like sandbox, etc. And yes, a user running tests > that have side effects manually and then not dealing with them is user > error. > So the lmb changes are scary to begin with. I think the tests shouldn't be limited to sandbox. Can't we plan c tests in test/dm etc that call functions and test? IOW we could allocate EFI memory and try to overwrite it with LMB, vice versa etc, without having to deal with the predefined areas. Regards /Ilias > -- > Tom ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 23/31] test: lmb: initialise the lmb structure before tests 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (21 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 24/31] test: lmb: add a test case for checking overlapping region add Sughosh Ganu ` (9 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The LMB allocations are now persistent and global, and with that all the local instances of the structure variable have been removed. Every LMB test cases that are run require a clean slate of the structure -- facilitate that by adding an initialisation function which gets called at the start of every test. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- include/lmb.h | 4 ++++ lib/lmb.c | 17 +++++++++++++++++ test/lib/lmb.c | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/include/lmb.h b/include/lmb.h index 1d4cd255d2..08ece0a90b 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -148,6 +148,10 @@ void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align); */ void lmb_reserve_common(void *fdt_blob); +#if defined(CONFIG_SANDBOX) +void lmb_init(void); +#endif /* CONFIG_SANDBOX */ + #endif /* __KERNEL__ */ #endif /* _LINUX_LMB_H */ diff --git a/lib/lmb.c b/lib/lmb.c index c9f6ca692e..2798ce0989 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -718,3 +718,20 @@ static int efi_mem_map_update_sync(void *ctx, struct event *event) } EVENT_SPY_FULL(EVT_EFI_MEM_MAP_UPDATE, efi_mem_map_update_sync); #endif /* MEM_MAP_UPDATE_NOTIFY */ + +#if CONFIG_IS_ENABLED(SANDBOX) +void lmb_init(void) +{ +#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) + lmb.memory.max = CONFIG_LMB_MAX_REGIONS; + lmb.reserved.max = CONFIG_LMB_MAX_REGIONS; +#else + lmb.memory.max = CONFIG_LMB_MEMORY_REGIONS; + lmb.reserved.max = CONFIG_LMB_RESERVED_REGIONS; + lmb.memory.region = memory_regions; + lmb.reserved.region = reserved_regions; +#endif + lmb.memory.cnt = 0; + lmb.reserved.cnt = 0; +} +#endif /* SANDBOX */ diff --git a/test/lib/lmb.c b/test/lib/lmb.c index ace1ddf4e4..260ebcfcd3 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -77,6 +77,8 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, ut_assert(alloc_64k_addr >= ram + 8); ut_assert(alloc_64k_end <= ram_end - 8); + lmb_init(); + if (ram0_size) { ret = lmb_add(ram0, ram0_size); ut_asserteq(ret, 0); @@ -235,6 +237,8 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); + lmb_init(); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); @@ -299,6 +303,8 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); + lmb_init(); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); @@ -382,6 +388,8 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) long ret; phys_addr_t a, b; + lmb_init(); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); @@ -418,6 +426,8 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) const phys_size_t ram_size = 0x20000000; long ret; + lmb_init(); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); @@ -473,6 +483,8 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); + lmb_init(); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); @@ -597,6 +609,8 @@ static int test_get_unreserved_size(struct unit_test_state *uts, /* check for overflow */ ut_assert(ram_end == 0 || ram_end > ram); + lmb_init(); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); @@ -664,6 +678,8 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) phys_addr_t offset; int ret, i; + lmb_init(); + ut_asserteq(lmb.memory.cnt, 0); ut_asserteq(lmb.memory.max, CONFIG_LMB_MAX_REGIONS); ut_asserteq(lmb.reserved.cnt, 0); @@ -722,6 +738,8 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) const phys_size_t ram_size = 0x20000000; long ret; + lmb_init(); + ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 24/31] test: lmb: add a test case for checking overlapping region add 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (22 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 23/31] test: lmb: initialise the lmb structure before tests Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 25/31] test: lmb: adjust the test case to handle overlapping regions Sughosh Ganu ` (8 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu Memory managed by LMB is now persistent and global. With that, it could be possible for multiple callers to try to add memory that has already been added. Add a test case to check that the LMB module handles it as expected. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- test/lib/lmb.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 260ebcfcd3..9b0e023b67 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -419,6 +419,22 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) } LIB_TEST(lib_test_lmb_at_0, 0); +static int lib_test_lmb_overlapping_add(struct unit_test_state *uts) +{ + const phys_addr_t ram = 0x40000000; + const phys_size_t ram_size = 0x20000000; + long ret; + + ret = lmb_add(ram, ram_size); + ut_asserteq(ret, 0); + + ret = lmb_add(ram, ram_size); + ut_asserteq(ret, 0); + + return 0; +} +LIB_TEST(lib_test_lmb_overlapping_add, 0); + /* Check that calling lmb_reserve with overlapping regions fails. */ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) { -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 25/31] test: lmb: adjust the test case to handle overlapping regions 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (23 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 24/31] test: lmb: add a test case for checking overlapping region add Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 26/31] test: lmb: run lmb tests only manually Sughosh Ganu ` (7 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The LMB code can now accept reserving and adding overlapping regions of memory. Adjust the test for checking the reservation of overlapping memory regions to work with this corresponding change in the LMB code. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- test/lib/lmb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 9b0e023b67..67a6be5bc3 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -451,15 +451,15 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) ut_asserteq(ret, 0); ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); - /* allocate overlapping region should fail */ + /* allocate overlapping region should return the coalesced count */ ret = lmb_reserve(0x40011000, 0x10000); - ut_asserteq(ret, -1); - ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, + ut_asserteq(ret, 1); + ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x11000, 0, 0, 0, 0); /* allocate 3nd region */ ret = lmb_reserve(0x40030000, 0x10000); ut_asserteq(ret, 0); - ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x10000, + ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x11000, 0x40030000, 0x10000, 0, 0); /* allocate 2nd region , This should coalesced all region into one */ ret = lmb_reserve(0x40020000, 0x10000); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 26/31] test: lmb: run lmb tests only manually 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (24 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 25/31] test: lmb: adjust the test case to handle overlapping regions Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-08 4:39 ` Heinrich Schuchardt 2024-06-07 18:52 ` [RFC PATCH 27/31] test: bdinfo: dump the global LMB memory map Sughosh Ganu ` (6 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The LMB code has been changed so that the memory reservations and allocations are now persistent and global. With this change, the design of the LMB tests needs to be changed accordingly. For now, mark the LMB tests to be run only manually. The tests won't be run as part of the unit test suite, and thus would not interfere with the running of the rest of the tests. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- test/lib/lmb.c | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 67a6be5bc3..813f7e3100 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -195,7 +195,7 @@ static int test_multi_alloc_512mb_x2(struct unit_test_state *uts, } /* Create a memory region with one reserved region and allocate */ -static int lib_test_lmb_simple(struct unit_test_state *uts) +static int lib_test_lmb_simple_norun(struct unit_test_state *uts) { int ret; @@ -207,10 +207,10 @@ static int lib_test_lmb_simple(struct unit_test_state *uts) /* simulate 512 MiB RAM beginning at 1.5GiB */ return test_multi_alloc_512mb(uts, 0xE0000000); } -LIB_TEST(lib_test_lmb_simple, 0); +LIB_TEST(lib_test_lmb_simple_norun, UT_TESTF_MANUAL); /* Create two memory regions with one reserved region and allocate */ -static int lib_test_lmb_simple_x2(struct unit_test_state *uts) +static int lib_test_lmb_simple_x2_norun(struct unit_test_state *uts) { int ret; @@ -222,7 +222,7 @@ static int lib_test_lmb_simple_x2(struct unit_test_state *uts) /* simulate 512 MiB RAM beginning at 3.5GiB and 1 GiB */ return test_multi_alloc_512mb_x2(uts, 0xE0000000, 0x40000000); } -LIB_TEST(lib_test_lmb_simple_x2, 0); +LIB_TEST(lib_test_lmb_simple_x2_norun, UT_TESTF_MANUAL); /* Simulate 512 MiB RAM, allocate some blocks that fit/don't fit */ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) @@ -275,7 +275,7 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) return 0; } -static int lib_test_lmb_big(struct unit_test_state *uts) +static int lib_test_lmb_big_norun(struct unit_test_state *uts) { int ret; @@ -287,7 +287,7 @@ static int lib_test_lmb_big(struct unit_test_state *uts) /* simulate 512 MiB RAM beginning at 1.5GiB */ return test_bigblock(uts, 0xE0000000); } -LIB_TEST(lib_test_lmb_big, 0); +LIB_TEST(lib_test_lmb_big_norun, UT_TESTF_MANUAL); /* Simulate 512 MiB RAM, allocate a block without previous reservation */ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, @@ -348,7 +348,7 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, return 0; } -static int lib_test_lmb_noreserved(struct unit_test_state *uts) +static int lib_test_lmb_noreserved_norun(struct unit_test_state *uts) { int ret; @@ -360,10 +360,9 @@ static int lib_test_lmb_noreserved(struct unit_test_state *uts) /* simulate 512 MiB RAM beginning at 1.5GiB */ return test_noreserved(uts, 0xE0000000, 4, 1); } +LIB_TEST(lib_test_lmb_noreserved_norun, UT_TESTF_MANUAL); -LIB_TEST(lib_test_lmb_noreserved, 0); - -static int lib_test_lmb_unaligned_size(struct unit_test_state *uts) +static int lib_test_lmb_unaligned_size_norun(struct unit_test_state *uts) { int ret; @@ -375,13 +374,13 @@ static int lib_test_lmb_unaligned_size(struct unit_test_state *uts) /* simulate 512 MiB RAM beginning at 1.5GiB */ return test_noreserved(uts, 0xE0000000, 5, 8); } -LIB_TEST(lib_test_lmb_unaligned_size, 0); +LIB_TEST(lib_test_lmb_unaligned_size_norun, UT_TESTF_MANUAL); /* * Simulate a RAM that starts at 0 and allocate down to address 0, which must * fail as '0' means failure for the lmb_alloc functions. */ -static int lib_test_lmb_at_0(struct unit_test_state *uts) +static int lib_test_lmb_at_0_norun(struct unit_test_state *uts) { const phys_addr_t ram = 0; const phys_size_t ram_size = 0x20000000; @@ -417,9 +416,9 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) return 0; } -LIB_TEST(lib_test_lmb_at_0, 0); +LIB_TEST(lib_test_lmb_at_0_norun, UT_TESTF_MANUAL); -static int lib_test_lmb_overlapping_add(struct unit_test_state *uts) +static int lib_test_lmb_overlapping_add_norun(struct unit_test_state *uts) { const phys_addr_t ram = 0x40000000; const phys_size_t ram_size = 0x20000000; @@ -433,10 +432,10 @@ static int lib_test_lmb_overlapping_add(struct unit_test_state *uts) return 0; } -LIB_TEST(lib_test_lmb_overlapping_add, 0); +LIB_TEST(lib_test_lmb_overlapping_add_norun, UT_TESTF_MANUAL); /* Check that calling lmb_reserve with overlapping regions fails. */ -static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) +static int lib_test_lmb_overlapping_reserve_norun(struct unit_test_state *uts) { const phys_addr_t ram = 0x40000000; const phys_size_t ram_size = 0x20000000; @@ -480,7 +479,7 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) 0, 0, 0, 0); return 0; } -LIB_TEST(lib_test_lmb_overlapping_reserve, 0); +LIB_TEST(lib_test_lmb_overlapping_reserve_norun, UT_TESTF_MANUAL); /* * Simulate 512 MiB RAM, reserve 3 blocks, allocate addresses in between. @@ -596,7 +595,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) return 0; } -static int lib_test_lmb_alloc_addr(struct unit_test_state *uts) +static int lib_test_lmb_alloc_addr_norun(struct unit_test_state *uts) { int ret; @@ -608,7 +607,7 @@ static int lib_test_lmb_alloc_addr(struct unit_test_state *uts) /* simulate 512 MiB RAM beginning at 1.5GiB */ return test_alloc_addr(uts, 0xE0000000); } -LIB_TEST(lib_test_lmb_alloc_addr, 0); +LIB_TEST(lib_test_lmb_alloc_addr_norun, UT_TESTF_MANUAL); /* Simulate 512 MiB RAM, reserve 3 blocks, check addresses in between */ static int test_get_unreserved_size(struct unit_test_state *uts, @@ -665,7 +664,7 @@ static int test_get_unreserved_size(struct unit_test_state *uts, return 0; } -static int lib_test_lmb_get_free_size(struct unit_test_state *uts) +static int lib_test_lmb_get_free_size_norun(struct unit_test_state *uts) { int ret; @@ -677,10 +676,10 @@ static int lib_test_lmb_get_free_size(struct unit_test_state *uts) /* simulate 512 MiB RAM beginning at 1.5GiB */ return test_get_unreserved_size(uts, 0xE0000000); } -LIB_TEST(lib_test_lmb_get_free_size, 0); +LIB_TEST(lib_test_lmb_get_free_size_norun, UT_TESTF_MANUAL); #ifdef CONFIG_LMB_USE_MAX_REGIONS -static int lib_test_lmb_max_regions(struct unit_test_state *uts) +static int lib_test_lmb_max_regions_norun(struct unit_test_state *uts) { const phys_addr_t ram = 0x00000000; /* @@ -745,10 +744,10 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) return 0; } -LIB_TEST(lib_test_lmb_max_regions, 0); +LIB_TEST(lib_test_lmb_max_regions_norun, UT_TESTF_MANUAL); #endif -static int lib_test_lmb_flags(struct unit_test_state *uts) +static int lib_test_lmb_flags_norun(struct unit_test_state *uts) { const phys_addr_t ram = 0x40000000; const phys_size_t ram_size = 0x20000000; @@ -832,4 +831,4 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) return 0; } -LIB_TEST(lib_test_lmb_flags, 0); +LIB_TEST(lib_test_lmb_flags_norun, UT_TESTF_MANUAL); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 26/31] test: lmb: run lmb tests only manually 2024-06-07 18:52 ` [RFC PATCH 26/31] test: lmb: run lmb tests only manually Sughosh Ganu @ 2024-06-08 4:39 ` Heinrich Schuchardt 2024-06-10 6:22 ` Sughosh Ganu 0 siblings, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-08 4:39 UTC (permalink / raw) To: Sughosh Ganu Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On 6/7/24 20:52, Sughosh Ganu wrote: > The LMB code has been changed so that the memory reservations and > allocations are now persistent and global. With this change, the > design of the LMB tests needs to be changed accordingly. For now, mark > the LMB tests to be run only manually. The tests won't be run as part > of the unit test suite, and thus would not interfere with the running > of the rest of the tests. We should run important tests in the CI. You could trigger the 'manual' test from a Python test and reboot the system to get into an initial state. Best regards Heinrich > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > test/lib/lmb.c | 49 ++++++++++++++++++++++++------------------------- > 1 file changed, 24 insertions(+), 25 deletions(-) > > diff --git a/test/lib/lmb.c b/test/lib/lmb.c > index 67a6be5bc3..813f7e3100 100644 > --- a/test/lib/lmb.c > +++ b/test/lib/lmb.c > @@ -195,7 +195,7 @@ static int test_multi_alloc_512mb_x2(struct unit_test_state *uts, > } > > /* Create a memory region with one reserved region and allocate */ > -static int lib_test_lmb_simple(struct unit_test_state *uts) > +static int lib_test_lmb_simple_norun(struct unit_test_state *uts) > { > int ret; > > @@ -207,10 +207,10 @@ static int lib_test_lmb_simple(struct unit_test_state *uts) > /* simulate 512 MiB RAM beginning at 1.5GiB */ > return test_multi_alloc_512mb(uts, 0xE0000000); > } > -LIB_TEST(lib_test_lmb_simple, 0); > +LIB_TEST(lib_test_lmb_simple_norun, UT_TESTF_MANUAL); > > /* Create two memory regions with one reserved region and allocate */ > -static int lib_test_lmb_simple_x2(struct unit_test_state *uts) > +static int lib_test_lmb_simple_x2_norun(struct unit_test_state *uts) > { > int ret; > > @@ -222,7 +222,7 @@ static int lib_test_lmb_simple_x2(struct unit_test_state *uts) > /* simulate 512 MiB RAM beginning at 3.5GiB and 1 GiB */ > return test_multi_alloc_512mb_x2(uts, 0xE0000000, 0x40000000); > } > -LIB_TEST(lib_test_lmb_simple_x2, 0); > +LIB_TEST(lib_test_lmb_simple_x2_norun, UT_TESTF_MANUAL); > > /* Simulate 512 MiB RAM, allocate some blocks that fit/don't fit */ > static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) > @@ -275,7 +275,7 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) > return 0; > } > > -static int lib_test_lmb_big(struct unit_test_state *uts) > +static int lib_test_lmb_big_norun(struct unit_test_state *uts) > { > int ret; > > @@ -287,7 +287,7 @@ static int lib_test_lmb_big(struct unit_test_state *uts) > /* simulate 512 MiB RAM beginning at 1.5GiB */ > return test_bigblock(uts, 0xE0000000); > } > -LIB_TEST(lib_test_lmb_big, 0); > +LIB_TEST(lib_test_lmb_big_norun, UT_TESTF_MANUAL); > > /* Simulate 512 MiB RAM, allocate a block without previous reservation */ > static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, > @@ -348,7 +348,7 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, > return 0; > } > > -static int lib_test_lmb_noreserved(struct unit_test_state *uts) > +static int lib_test_lmb_noreserved_norun(struct unit_test_state *uts) > { > int ret; > > @@ -360,10 +360,9 @@ static int lib_test_lmb_noreserved(struct unit_test_state *uts) > /* simulate 512 MiB RAM beginning at 1.5GiB */ > return test_noreserved(uts, 0xE0000000, 4, 1); > } > +LIB_TEST(lib_test_lmb_noreserved_norun, UT_TESTF_MANUAL); > > -LIB_TEST(lib_test_lmb_noreserved, 0); > - > -static int lib_test_lmb_unaligned_size(struct unit_test_state *uts) > +static int lib_test_lmb_unaligned_size_norun(struct unit_test_state *uts) > { > int ret; > > @@ -375,13 +374,13 @@ static int lib_test_lmb_unaligned_size(struct unit_test_state *uts) > /* simulate 512 MiB RAM beginning at 1.5GiB */ > return test_noreserved(uts, 0xE0000000, 5, 8); > } > -LIB_TEST(lib_test_lmb_unaligned_size, 0); > +LIB_TEST(lib_test_lmb_unaligned_size_norun, UT_TESTF_MANUAL); > > /* > * Simulate a RAM that starts at 0 and allocate down to address 0, which must > * fail as '0' means failure for the lmb_alloc functions. > */ > -static int lib_test_lmb_at_0(struct unit_test_state *uts) > +static int lib_test_lmb_at_0_norun(struct unit_test_state *uts) > { > const phys_addr_t ram = 0; > const phys_size_t ram_size = 0x20000000; > @@ -417,9 +416,9 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) > > return 0; > } > -LIB_TEST(lib_test_lmb_at_0, 0); > +LIB_TEST(lib_test_lmb_at_0_norun, UT_TESTF_MANUAL); > > -static int lib_test_lmb_overlapping_add(struct unit_test_state *uts) > +static int lib_test_lmb_overlapping_add_norun(struct unit_test_state *uts) > { > const phys_addr_t ram = 0x40000000; > const phys_size_t ram_size = 0x20000000; > @@ -433,10 +432,10 @@ static int lib_test_lmb_overlapping_add(struct unit_test_state *uts) > > return 0; > } > -LIB_TEST(lib_test_lmb_overlapping_add, 0); > +LIB_TEST(lib_test_lmb_overlapping_add_norun, UT_TESTF_MANUAL); > > /* Check that calling lmb_reserve with overlapping regions fails. */ > -static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) > +static int lib_test_lmb_overlapping_reserve_norun(struct unit_test_state *uts) > { > const phys_addr_t ram = 0x40000000; > const phys_size_t ram_size = 0x20000000; > @@ -480,7 +479,7 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) > 0, 0, 0, 0); > return 0; > } > -LIB_TEST(lib_test_lmb_overlapping_reserve, 0); > +LIB_TEST(lib_test_lmb_overlapping_reserve_norun, UT_TESTF_MANUAL); > > /* > * Simulate 512 MiB RAM, reserve 3 blocks, allocate addresses in between. > @@ -596,7 +595,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) > return 0; > } > > -static int lib_test_lmb_alloc_addr(struct unit_test_state *uts) > +static int lib_test_lmb_alloc_addr_norun(struct unit_test_state *uts) > { > int ret; > > @@ -608,7 +607,7 @@ static int lib_test_lmb_alloc_addr(struct unit_test_state *uts) > /* simulate 512 MiB RAM beginning at 1.5GiB */ > return test_alloc_addr(uts, 0xE0000000); > } > -LIB_TEST(lib_test_lmb_alloc_addr, 0); > +LIB_TEST(lib_test_lmb_alloc_addr_norun, UT_TESTF_MANUAL); > > /* Simulate 512 MiB RAM, reserve 3 blocks, check addresses in between */ > static int test_get_unreserved_size(struct unit_test_state *uts, > @@ -665,7 +664,7 @@ static int test_get_unreserved_size(struct unit_test_state *uts, > return 0; > } > > -static int lib_test_lmb_get_free_size(struct unit_test_state *uts) > +static int lib_test_lmb_get_free_size_norun(struct unit_test_state *uts) > { > int ret; > > @@ -677,10 +676,10 @@ static int lib_test_lmb_get_free_size(struct unit_test_state *uts) > /* simulate 512 MiB RAM beginning at 1.5GiB */ > return test_get_unreserved_size(uts, 0xE0000000); > } > -LIB_TEST(lib_test_lmb_get_free_size, 0); > +LIB_TEST(lib_test_lmb_get_free_size_norun, UT_TESTF_MANUAL); > > #ifdef CONFIG_LMB_USE_MAX_REGIONS > -static int lib_test_lmb_max_regions(struct unit_test_state *uts) > +static int lib_test_lmb_max_regions_norun(struct unit_test_state *uts) > { > const phys_addr_t ram = 0x00000000; > /* > @@ -745,10 +744,10 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) > > return 0; > } > -LIB_TEST(lib_test_lmb_max_regions, 0); > +LIB_TEST(lib_test_lmb_max_regions_norun, UT_TESTF_MANUAL); > #endif > > -static int lib_test_lmb_flags(struct unit_test_state *uts) > +static int lib_test_lmb_flags_norun(struct unit_test_state *uts) > { > const phys_addr_t ram = 0x40000000; > const phys_size_t ram_size = 0x20000000; > @@ -832,4 +831,4 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) > > return 0; > } > -LIB_TEST(lib_test_lmb_flags, 0); > +LIB_TEST(lib_test_lmb_flags_norun, UT_TESTF_MANUAL); ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 26/31] test: lmb: run lmb tests only manually 2024-06-08 4:39 ` Heinrich Schuchardt @ 2024-06-10 6:22 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 6:22 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, u-boot On Sat, 8 Jun 2024 at 10:09, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 6/7/24 20:52, Sughosh Ganu wrote: > > The LMB code has been changed so that the memory reservations and > > allocations are now persistent and global. With this change, the > > design of the LMB tests needs to be changed accordingly. For now, mark > > the LMB tests to be run only manually. The tests won't be run as part > > of the unit test suite, and thus would not interfere with the running > > of the rest of the tests. > > We should run important tests in the CI. > > You could trigger the 'manual' test from a Python test and reboot the > system to get into an initial state. Yes, that is one of the solutions that I have in mind. Will work on this for the next version. Thanks. -sughosh > > Best regards > > Heinrich > > > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > --- > > test/lib/lmb.c | 49 ++++++++++++++++++++++++------------------------- > > 1 file changed, 24 insertions(+), 25 deletions(-) > > > > diff --git a/test/lib/lmb.c b/test/lib/lmb.c > > index 67a6be5bc3..813f7e3100 100644 > > --- a/test/lib/lmb.c > > +++ b/test/lib/lmb.c > > @@ -195,7 +195,7 @@ static int test_multi_alloc_512mb_x2(struct unit_test_state *uts, > > } > > > > /* Create a memory region with one reserved region and allocate */ > > -static int lib_test_lmb_simple(struct unit_test_state *uts) > > +static int lib_test_lmb_simple_norun(struct unit_test_state *uts) > > { > > int ret; > > > > @@ -207,10 +207,10 @@ static int lib_test_lmb_simple(struct unit_test_state *uts) > > /* simulate 512 MiB RAM beginning at 1.5GiB */ > > return test_multi_alloc_512mb(uts, 0xE0000000); > > } > > -LIB_TEST(lib_test_lmb_simple, 0); > > +LIB_TEST(lib_test_lmb_simple_norun, UT_TESTF_MANUAL); > > > > /* Create two memory regions with one reserved region and allocate */ > > -static int lib_test_lmb_simple_x2(struct unit_test_state *uts) > > +static int lib_test_lmb_simple_x2_norun(struct unit_test_state *uts) > > { > > int ret; > > > > @@ -222,7 +222,7 @@ static int lib_test_lmb_simple_x2(struct unit_test_state *uts) > > /* simulate 512 MiB RAM beginning at 3.5GiB and 1 GiB */ > > return test_multi_alloc_512mb_x2(uts, 0xE0000000, 0x40000000); > > } > > -LIB_TEST(lib_test_lmb_simple_x2, 0); > > +LIB_TEST(lib_test_lmb_simple_x2_norun, UT_TESTF_MANUAL); > > > > /* Simulate 512 MiB RAM, allocate some blocks that fit/don't fit */ > > static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) > > @@ -275,7 +275,7 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) > > return 0; > > } > > > > -static int lib_test_lmb_big(struct unit_test_state *uts) > > +static int lib_test_lmb_big_norun(struct unit_test_state *uts) > > { > > int ret; > > > > @@ -287,7 +287,7 @@ static int lib_test_lmb_big(struct unit_test_state *uts) > > /* simulate 512 MiB RAM beginning at 1.5GiB */ > > return test_bigblock(uts, 0xE0000000); > > } > > -LIB_TEST(lib_test_lmb_big, 0); > > +LIB_TEST(lib_test_lmb_big_norun, UT_TESTF_MANUAL); > > > > /* Simulate 512 MiB RAM, allocate a block without previous reservation */ > > static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, > > @@ -348,7 +348,7 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, > > return 0; > > } > > > > -static int lib_test_lmb_noreserved(struct unit_test_state *uts) > > +static int lib_test_lmb_noreserved_norun(struct unit_test_state *uts) > > { > > int ret; > > > > @@ -360,10 +360,9 @@ static int lib_test_lmb_noreserved(struct unit_test_state *uts) > > /* simulate 512 MiB RAM beginning at 1.5GiB */ > > return test_noreserved(uts, 0xE0000000, 4, 1); > > } > > +LIB_TEST(lib_test_lmb_noreserved_norun, UT_TESTF_MANUAL); > > > > -LIB_TEST(lib_test_lmb_noreserved, 0); > > - > > -static int lib_test_lmb_unaligned_size(struct unit_test_state *uts) > > +static int lib_test_lmb_unaligned_size_norun(struct unit_test_state *uts) > > { > > int ret; > > > > @@ -375,13 +374,13 @@ static int lib_test_lmb_unaligned_size(struct unit_test_state *uts) > > /* simulate 512 MiB RAM beginning at 1.5GiB */ > > return test_noreserved(uts, 0xE0000000, 5, 8); > > } > > -LIB_TEST(lib_test_lmb_unaligned_size, 0); > > +LIB_TEST(lib_test_lmb_unaligned_size_norun, UT_TESTF_MANUAL); > > > > /* > > * Simulate a RAM that starts at 0 and allocate down to address 0, which must > > * fail as '0' means failure for the lmb_alloc functions. > > */ > > -static int lib_test_lmb_at_0(struct unit_test_state *uts) > > +static int lib_test_lmb_at_0_norun(struct unit_test_state *uts) > > { > > const phys_addr_t ram = 0; > > const phys_size_t ram_size = 0x20000000; > > @@ -417,9 +416,9 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) > > > > return 0; > > } > > -LIB_TEST(lib_test_lmb_at_0, 0); > > +LIB_TEST(lib_test_lmb_at_0_norun, UT_TESTF_MANUAL); > > > > -static int lib_test_lmb_overlapping_add(struct unit_test_state *uts) > > +static int lib_test_lmb_overlapping_add_norun(struct unit_test_state *uts) > > { > > const phys_addr_t ram = 0x40000000; > > const phys_size_t ram_size = 0x20000000; > > @@ -433,10 +432,10 @@ static int lib_test_lmb_overlapping_add(struct unit_test_state *uts) > > > > return 0; > > } > > -LIB_TEST(lib_test_lmb_overlapping_add, 0); > > +LIB_TEST(lib_test_lmb_overlapping_add_norun, UT_TESTF_MANUAL); > > > > /* Check that calling lmb_reserve with overlapping regions fails. */ > > -static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) > > +static int lib_test_lmb_overlapping_reserve_norun(struct unit_test_state *uts) > > { > > const phys_addr_t ram = 0x40000000; > > const phys_size_t ram_size = 0x20000000; > > @@ -480,7 +479,7 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) > > 0, 0, 0, 0); > > return 0; > > } > > -LIB_TEST(lib_test_lmb_overlapping_reserve, 0); > > +LIB_TEST(lib_test_lmb_overlapping_reserve_norun, UT_TESTF_MANUAL); > > > > /* > > * Simulate 512 MiB RAM, reserve 3 blocks, allocate addresses in between. > > @@ -596,7 +595,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) > > return 0; > > } > > > > -static int lib_test_lmb_alloc_addr(struct unit_test_state *uts) > > +static int lib_test_lmb_alloc_addr_norun(struct unit_test_state *uts) > > { > > int ret; > > > > @@ -608,7 +607,7 @@ static int lib_test_lmb_alloc_addr(struct unit_test_state *uts) > > /* simulate 512 MiB RAM beginning at 1.5GiB */ > > return test_alloc_addr(uts, 0xE0000000); > > } > > -LIB_TEST(lib_test_lmb_alloc_addr, 0); > > +LIB_TEST(lib_test_lmb_alloc_addr_norun, UT_TESTF_MANUAL); > > > > /* Simulate 512 MiB RAM, reserve 3 blocks, check addresses in between */ > > static int test_get_unreserved_size(struct unit_test_state *uts, > > @@ -665,7 +664,7 @@ static int test_get_unreserved_size(struct unit_test_state *uts, > > return 0; > > } > > > > -static int lib_test_lmb_get_free_size(struct unit_test_state *uts) > > +static int lib_test_lmb_get_free_size_norun(struct unit_test_state *uts) > > { > > int ret; > > > > @@ -677,10 +676,10 @@ static int lib_test_lmb_get_free_size(struct unit_test_state *uts) > > /* simulate 512 MiB RAM beginning at 1.5GiB */ > > return test_get_unreserved_size(uts, 0xE0000000); > > } > > -LIB_TEST(lib_test_lmb_get_free_size, 0); > > +LIB_TEST(lib_test_lmb_get_free_size_norun, UT_TESTF_MANUAL); > > > > #ifdef CONFIG_LMB_USE_MAX_REGIONS > > -static int lib_test_lmb_max_regions(struct unit_test_state *uts) > > +static int lib_test_lmb_max_regions_norun(struct unit_test_state *uts) > > { > > const phys_addr_t ram = 0x00000000; > > /* > > @@ -745,10 +744,10 @@ static int lib_test_lmb_max_regions(struct unit_test_state *uts) > > > > return 0; > > } > > -LIB_TEST(lib_test_lmb_max_regions, 0); > > +LIB_TEST(lib_test_lmb_max_regions_norun, UT_TESTF_MANUAL); > > #endif > > > > -static int lib_test_lmb_flags(struct unit_test_state *uts) > > +static int lib_test_lmb_flags_norun(struct unit_test_state *uts) > > { > > const phys_addr_t ram = 0x40000000; > > const phys_size_t ram_size = 0x20000000; > > @@ -832,4 +831,4 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) > > > > return 0; > > } > > -LIB_TEST(lib_test_lmb_flags, 0); > > +LIB_TEST(lib_test_lmb_flags_norun, UT_TESTF_MANUAL); > ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 27/31] test: bdinfo: dump the global LMB memory map 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (25 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 26/31] test: lmb: run lmb tests only manually Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 28/31] cmd: bdinfo: only dump the current LMB memory Sughosh Ganu ` (5 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The LMB code has been changed to make the memory reservations persistent and global. Make corresponding change the the lmb_test_dump_all() function to print the global LMB added and reserved memory. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- test/cmd/bdinfo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c index 8ba785fc31..2f90c04b70 100644 --- a/test/cmd/bdinfo.c +++ b/test/cmd/bdinfo.c @@ -25,6 +25,8 @@ DECLARE_GLOBAL_DATA_PTR; +extern struct lmb lmb; + /* Declare a new bdinfo test */ #define BDINFO_TEST(_name, _flags) UNIT_TEST(_name, _flags, bdinfo_test) @@ -125,11 +127,11 @@ static int lmb_test_dump_region(struct unit_test_state *uts, return 0; } -static int lmb_test_dump_all(struct unit_test_state *uts, struct lmb *lmb) +static int lmb_test_dump_all(struct unit_test_state *uts) { ut_assert_nextline("lmb_dump_all:"); - ut_assertok(lmb_test_dump_region(uts, &lmb->memory, "memory")); - ut_assertok(lmb_test_dump_region(uts, &lmb->reserved, "reserved")); + ut_assertok(lmb_test_dump_region(uts, &lmb.memory, "memory")); + ut_assertok(lmb_test_dump_region(uts, &lmb.reserved, "reserved")); return 0; } @@ -191,10 +193,8 @@ static int bdinfo_test_all(struct unit_test_state *uts) #endif if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { - struct lmb lmb; - lmb_add_memory(gd->bd); - ut_assertok(lmb_test_dump_all(uts, &lmb)); + ut_assertok(lmb_test_dump_all(uts)); if (IS_ENABLED(CONFIG_OF_REAL)) ut_assert_nextline("devicetree = %s", fdtdec_get_srcname()); } -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 28/31] cmd: bdinfo: only dump the current LMB memory 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (26 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 27/31] test: bdinfo: dump the global LMB memory map Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-08 3:59 ` Heinrich Schuchardt 2024-06-07 18:52 ` [RFC PATCH 29/31] temp: mx6sabresd: bump up the size limit of the board Sughosh Ganu ` (4 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu The LMB memory map is now persistent and global. There is therefore no need to add memory to the LMB memory map as part of the bdinfo command. Only dump the current available and reserved memory as part of the bdinfo command. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- cmd/bdinfo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index fc408e9820..0f343203ef 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -163,7 +163,6 @@ static int bdinfo_print_all(struct bd_info *bd) bdinfo_print_num_l("multi_dtb_fit", (ulong)gd->multi_dtb_fit); #endif if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { - lmb_add_memory(gd->bd); lmb_dump_all_force(); if (IS_ENABLED(CONFIG_OF_REAL)) printf("devicetree = %s\n", fdtdec_get_srcname()); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 28/31] cmd: bdinfo: only dump the current LMB memory 2024-06-07 18:52 ` [RFC PATCH 28/31] cmd: bdinfo: only dump the current LMB memory Sughosh Ganu @ 2024-06-08 3:59 ` Heinrich Schuchardt 2024-06-10 11:42 ` Ilias Apalodimas 0 siblings, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-08 3:59 UTC (permalink / raw) To: Sughosh Ganu, u-boot Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam Am 7. Juni 2024 20:52:37 MESZ schrieb Sughosh Ganu <sughosh.ganu@linaro.org>: >The LMB memory map is now persistent and global. There is therefore no >need to add memory to the LMB memory map as part of the bdinfo >command. Only dump the current available and reserved memory as part >of the bdinfo command. Would it make sense to move printing lmb memory to a separate command instead? Best regards Heinrich > >Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> >--- > cmd/bdinfo.c | 1 - > 1 file changed, 1 deletion(-) > >diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c >index fc408e9820..0f343203ef 100644 >--- a/cmd/bdinfo.c >+++ b/cmd/bdinfo.c >@@ -163,7 +163,6 @@ static int bdinfo_print_all(struct bd_info *bd) > bdinfo_print_num_l("multi_dtb_fit", (ulong)gd->multi_dtb_fit); > #endif > if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { >- lmb_add_memory(gd->bd); > lmb_dump_all_force(); > if (IS_ENABLED(CONFIG_OF_REAL)) > printf("devicetree = %s\n", fdtdec_get_srcname()); ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 28/31] cmd: bdinfo: only dump the current LMB memory 2024-06-08 3:59 ` Heinrich Schuchardt @ 2024-06-10 11:42 ` Ilias Apalodimas 0 siblings, 0 replies; 127+ messages in thread From: Ilias Apalodimas @ 2024-06-10 11:42 UTC (permalink / raw) To: Heinrich Schuchardt Cc: Sughosh Ganu, u-boot, Tom Rini, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Sat, 8 Jun 2024 at 06:59, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > Am 7. Juni 2024 20:52:37 MESZ schrieb Sughosh Ganu <sughosh.ganu@linaro.org>: > >The LMB memory map is now persistent and global. There is therefore no > >need to add memory to the LMB memory map as part of the bdinfo > >command. Only dump the current available and reserved memory as part > >of the bdinfo command. > > Would it make sense to move printing lmb memory to a separate command instead? Yes. Since are permanently reserving memory regions now we should have a command to dump them. Perhaps re-use cmd/mem.c? Regards /Ilias > > Best regards > > Heinrich > > > > >Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > >--- > > cmd/bdinfo.c | 1 - > > 1 file changed, 1 deletion(-) > > > >diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c > >index fc408e9820..0f343203ef 100644 > >--- a/cmd/bdinfo.c > >+++ b/cmd/bdinfo.c > >@@ -163,7 +163,6 @@ static int bdinfo_print_all(struct bd_info *bd) > > bdinfo_print_num_l("multi_dtb_fit", (ulong)gd->multi_dtb_fit); > > #endif > > if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { > >- lmb_add_memory(gd->bd); > > lmb_dump_all_force(); > > if (IS_ENABLED(CONFIG_OF_REAL)) > > printf("devicetree = %s\n", fdtdec_get_srcname()); ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 29/31] temp: mx6sabresd: bump up the size limit of the board 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (27 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 28/31] cmd: bdinfo: only dump the current LMB memory Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 30/31] temp: cmd: efi_mem: add a command to test efi alloc/free Sughosh Ganu ` (3 subsequent siblings) 32 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu With the changes to add notifications for any changes to the LMB map, the size of the image exceeds the limit set. Bump up the image size limit for now to get the platform to build. This is not for committing. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- Note: @Fabio Estevam, please check if it would be okay to increase the board size limit. Else other ways to reduce image size will have to be checked. configs/mx6sabresd_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig index 868f6b1551..7308ae2ec6 100644 --- a/configs/mx6sabresd_defconfig +++ b/configs/mx6sabresd_defconfig @@ -23,7 +23,7 @@ CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_PCI=y CONFIG_LTO=y CONFIG_HAS_BOARD_SIZE_LIMIT=y -CONFIG_BOARD_SIZE_LIMIT=715766 +CONFIG_BOARD_SIZE_LIMIT=718108 CONFIG_FIT=y CONFIG_SPL_FIT_PRINT=y CONFIG_SPL_LOAD_FIT=y -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* [RFC PATCH 30/31] temp: cmd: efi_mem: add a command to test efi alloc/free 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (28 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 29/31] temp: mx6sabresd: bump up the size limit of the board Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-08 3:37 ` Heinrich Schuchardt 2024-06-07 18:52 ` [RFC PATCH 31/31] temp: cmd: efi: add a command to dump EFI memory map Sughosh Ganu ` (2 subsequent siblings) 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu Not for committing. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- cmd/Makefile | 1 + cmd/efi_memory.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 cmd/efi_memory.c diff --git a/cmd/Makefile b/cmd/Makefile index 87133cc27a..35fcc4af5a 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += help.o obj-y += panic.o obj-y += version.o +obj-y += efi_memory.o # command obj-$(CONFIG_CMD_ARMFFA) += armffa.o diff --git a/cmd/efi_memory.c b/cmd/efi_memory.c new file mode 100644 index 0000000000..52ddcb7146 --- /dev/null +++ b/cmd/efi_memory.c @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Allocate and Free EFI memory + * + * Copyright (c) 2024 Linaro Limited + */ + +#include <command.h> +#include <efi_loader.h> +#include <lmb.h> +#include <vsprintf.h> + +#include <linux/types.h> + +static int do_efi_mem_free(struct cmd_tbl *cmdtp, int flag, int argc, + char * const argv[]) +{ + uint64_t addr = 0, size = 0; + efi_uintn_t pages; + efi_status_t status; + + if (argc != 3) + return CMD_RET_USAGE; + + argc--; argv++; + + size = simple_strtoul(argv[0], NULL, 16); + if (!size) { + printf("Enter valid size for free in Hex\n"); + return CMD_RET_USAGE; + } + + + addr = simple_strtoul(argv[1], NULL, 16); + if (!addr) { + printf("Enter a valid address in Hex\n"); + return CMD_RET_USAGE; + } + + pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK)); + + status = efi_free_pages(addr, pages); + if (status != EFI_SUCCESS) { + printf("Unable to free memory, error (%#lx)\n", status); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +static int do_efi_mem_alloc(struct cmd_tbl *cmdtp, int flag, int argc, + char * const argv[]) +{ + enum efi_allocate_type type; + uint64_t addr = 0, size = 0; + efi_uintn_t pages; + efi_status_t status; + bool max = false; + + if (argc < 2) + return CMD_RET_USAGE; + + argc--; argv++; + + if (!strcmp("max", argv[0])) { + if (argc != 3) + return CMD_RET_USAGE; + + max = true; + argv++; + argc--; + } + + size = simple_strtoul(argv[0], NULL, 16); + if (!size) { + printf("Enter valid size for allocation in Hex\n"); + return CMD_RET_USAGE; + } + + if (max || argc == 2) { + addr = simple_strtoul(argv[1], NULL, 16); + if (!addr) { + printf("Enter a valid address in Hex\n"); + return CMD_RET_USAGE; + } + } + + if (max) + type = EFI_ALLOCATE_MAX_ADDRESS; + else if (addr) + type = EFI_ALLOCATE_ADDRESS; + else + type = EFI_ALLOCATE_ANY_PAGES; + + pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK)); + status = efi_allocate_pages(type, EFI_BOOT_SERVICES_DATA, pages, + &addr); + if (status != EFI_SUCCESS) { + printf("efi_allocate_pages failed %lx\n", status); + return CMD_RET_FAILURE; + } else { + printf("Address returned %#llx\n", addr); + } + + return CMD_RET_SUCCESS; +} + +static struct cmd_tbl cmd_efi_mem_sub[] = { + U_BOOT_CMD_MKENT(alloc, 3, 0, do_efi_mem_alloc, + "", ""), + U_BOOT_CMD_MKENT(free, 2, 0, do_efi_mem_free, + "", ""), +}; + +static int do_efi_mem(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct cmd_tbl *cp; + efi_status_t r; + + if (argc < 3) + return CMD_RET_USAGE; + + argc--; argv++; + + /* Initialize UEFI subsystem */ + r = efi_init_obj_list(); + if (r != EFI_SUCCESS) { + printf("Error: Cannot initialize UEFI sub-system, r = %lu\n", + r & ~EFI_ERROR_MASK); + return CMD_RET_FAILURE; + } + + cp = find_cmd_tbl(argv[0], cmd_efi_mem_sub, + ARRAY_SIZE(cmd_efi_mem_sub)); + if (!cp) + return CMD_RET_USAGE; + + return cp->cmd(cmdtp, flag, argc, argv); +} + +U_BOOT_LONGHELP(efi_mem, + "Functions to allocate and free memory\n" + "\n" + "efi_mem alloc <size> [addr]\n" + "efi_mem alloc max <size> <max-addr>\n" + "efi_mem free <size> <addr>\n" + "\n" +); + +U_BOOT_CMD( + efi_mem, CONFIG_SYS_MAXARGS, 0, do_efi_mem, + "Allocate and free EFI memory", + efi_mem_help_text +); -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 30/31] temp: cmd: efi_mem: add a command to test efi alloc/free 2024-06-07 18:52 ` [RFC PATCH 30/31] temp: cmd: efi_mem: add a command to test efi alloc/free Sughosh Ganu @ 2024-06-08 3:37 ` Heinrich Schuchardt 2024-06-10 6:44 ` Sughosh Ganu 0 siblings, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-08 3:37 UTC (permalink / raw) To: Sughosh Ganu, u-boot Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam Am 7. Juni 2024 20:52:39 MESZ schrieb Sughosh Ganu <sughosh.ganu@linaro.org>: >Not for committing. Best put "DON'T MERGE" into the title to avoid mishaps in future versions. In the final series we should have unit test covering all relevant aspects of the memory system. Best regards Heinrich > >Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> >--- > cmd/Makefile | 1 + > cmd/efi_memory.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 156 insertions(+) > create mode 100644 cmd/efi_memory.c > >diff --git a/cmd/Makefile b/cmd/Makefile >index 87133cc27a..35fcc4af5a 100644 >--- a/cmd/Makefile >+++ b/cmd/Makefile >@@ -10,6 +10,7 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o > obj-y += help.o > obj-y += panic.o > obj-y += version.o >+obj-y += efi_memory.o > > # command > obj-$(CONFIG_CMD_ARMFFA) += armffa.o >diff --git a/cmd/efi_memory.c b/cmd/efi_memory.c >new file mode 100644 >index 0000000000..52ddcb7146 >--- /dev/null >+++ b/cmd/efi_memory.c >@@ -0,0 +1,155 @@ >+// SPDX-License-Identifier: GPL-2.0+ >+/* >+ * Allocate and Free EFI memory >+ * >+ * Copyright (c) 2024 Linaro Limited >+ */ >+ >+#include <command.h> >+#include <efi_loader.h> >+#include <lmb.h> >+#include <vsprintf.h> >+ >+#include <linux/types.h> >+ >+static int do_efi_mem_free(struct cmd_tbl *cmdtp, int flag, int argc, >+ char * const argv[]) >+{ >+ uint64_t addr = 0, size = 0; >+ efi_uintn_t pages; >+ efi_status_t status; >+ >+ if (argc != 3) >+ return CMD_RET_USAGE; >+ >+ argc--; argv++; >+ >+ size = simple_strtoul(argv[0], NULL, 16); >+ if (!size) { >+ printf("Enter valid size for free in Hex\n"); >+ return CMD_RET_USAGE; >+ } >+ >+ >+ addr = simple_strtoul(argv[1], NULL, 16); >+ if (!addr) { >+ printf("Enter a valid address in Hex\n"); >+ return CMD_RET_USAGE; >+ } >+ >+ pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK)); >+ >+ status = efi_free_pages(addr, pages); >+ if (status != EFI_SUCCESS) { >+ printf("Unable to free memory, error (%#lx)\n", status); >+ return CMD_RET_FAILURE; >+ } >+ >+ return CMD_RET_SUCCESS; >+} >+ >+static int do_efi_mem_alloc(struct cmd_tbl *cmdtp, int flag, int argc, >+ char * const argv[]) >+{ >+ enum efi_allocate_type type; >+ uint64_t addr = 0, size = 0; >+ efi_uintn_t pages; >+ efi_status_t status; >+ bool max = false; >+ >+ if (argc < 2) >+ return CMD_RET_USAGE; >+ >+ argc--; argv++; >+ >+ if (!strcmp("max", argv[0])) { >+ if (argc != 3) >+ return CMD_RET_USAGE; >+ >+ max = true; >+ argv++; >+ argc--; >+ } >+ >+ size = simple_strtoul(argv[0], NULL, 16); >+ if (!size) { >+ printf("Enter valid size for allocation in Hex\n"); >+ return CMD_RET_USAGE; >+ } >+ >+ if (max || argc == 2) { >+ addr = simple_strtoul(argv[1], NULL, 16); >+ if (!addr) { >+ printf("Enter a valid address in Hex\n"); >+ return CMD_RET_USAGE; >+ } >+ } >+ >+ if (max) >+ type = EFI_ALLOCATE_MAX_ADDRESS; >+ else if (addr) >+ type = EFI_ALLOCATE_ADDRESS; >+ else >+ type = EFI_ALLOCATE_ANY_PAGES; >+ >+ pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK)); >+ status = efi_allocate_pages(type, EFI_BOOT_SERVICES_DATA, pages, >+ &addr); >+ if (status != EFI_SUCCESS) { >+ printf("efi_allocate_pages failed %lx\n", status); >+ return CMD_RET_FAILURE; >+ } else { >+ printf("Address returned %#llx\n", addr); >+ } >+ >+ return CMD_RET_SUCCESS; >+} >+ >+static struct cmd_tbl cmd_efi_mem_sub[] = { >+ U_BOOT_CMD_MKENT(alloc, 3, 0, do_efi_mem_alloc, >+ "", ""), >+ U_BOOT_CMD_MKENT(free, 2, 0, do_efi_mem_free, >+ "", ""), >+}; >+ >+static int do_efi_mem(struct cmd_tbl *cmdtp, int flag, int argc, >+ char *const argv[]) >+{ >+ struct cmd_tbl *cp; >+ efi_status_t r; >+ >+ if (argc < 3) >+ return CMD_RET_USAGE; >+ >+ argc--; argv++; >+ >+ /* Initialize UEFI subsystem */ >+ r = efi_init_obj_list(); >+ if (r != EFI_SUCCESS) { >+ printf("Error: Cannot initialize UEFI sub-system, r = %lu\n", >+ r & ~EFI_ERROR_MASK); >+ return CMD_RET_FAILURE; >+ } >+ >+ cp = find_cmd_tbl(argv[0], cmd_efi_mem_sub, >+ ARRAY_SIZE(cmd_efi_mem_sub)); >+ if (!cp) >+ return CMD_RET_USAGE; >+ >+ return cp->cmd(cmdtp, flag, argc, argv); >+} >+ >+U_BOOT_LONGHELP(efi_mem, >+ "Functions to allocate and free memory\n" >+ "\n" >+ "efi_mem alloc <size> [addr]\n" >+ "efi_mem alloc max <size> <max-addr>\n" >+ "efi_mem free <size> <addr>\n" >+ "\n" >+); >+ >+U_BOOT_CMD( >+ efi_mem, CONFIG_SYS_MAXARGS, 0, do_efi_mem, >+ "Allocate and free EFI memory", >+ efi_mem_help_text >+); ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 30/31] temp: cmd: efi_mem: add a command to test efi alloc/free 2024-06-08 3:37 ` Heinrich Schuchardt @ 2024-06-10 6:44 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 6:44 UTC (permalink / raw) To: Heinrich Schuchardt Cc: u-boot, Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Sat, 8 Jun 2024 at 09:07, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > Am 7. Juni 2024 20:52:39 MESZ schrieb Sughosh Ganu <sughosh.ganu@linaro.org>: > >Not for committing. > > Best put "DON'T MERGE" into the title to avoid mishaps in future versions. Will do. > > In the final series we should have unit test covering all relevant aspects of the memory system. Yes, that's the plan. -sughosh > > Best regards > > Heinrich > > > > >Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > >--- > > cmd/Makefile | 1 + > > cmd/efi_memory.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++ > > 2 files changed, 156 insertions(+) > > create mode 100644 cmd/efi_memory.c > > > >diff --git a/cmd/Makefile b/cmd/Makefile > >index 87133cc27a..35fcc4af5a 100644 > >--- a/cmd/Makefile > >+++ b/cmd/Makefile > >@@ -10,6 +10,7 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o > > obj-y += help.o > > obj-y += panic.o > > obj-y += version.o > >+obj-y += efi_memory.o > > > > # command > > obj-$(CONFIG_CMD_ARMFFA) += armffa.o > >diff --git a/cmd/efi_memory.c b/cmd/efi_memory.c > >new file mode 100644 > >index 0000000000..52ddcb7146 > >--- /dev/null > >+++ b/cmd/efi_memory.c > >@@ -0,0 +1,155 @@ > >+// SPDX-License-Identifier: GPL-2.0+ > >+/* > >+ * Allocate and Free EFI memory > >+ * > >+ * Copyright (c) 2024 Linaro Limited > >+ */ > >+ > >+#include <command.h> > >+#include <efi_loader.h> > >+#include <lmb.h> > >+#include <vsprintf.h> > >+ > >+#include <linux/types.h> > >+ > >+static int do_efi_mem_free(struct cmd_tbl *cmdtp, int flag, int argc, > >+ char * const argv[]) > >+{ > >+ uint64_t addr = 0, size = 0; > >+ efi_uintn_t pages; > >+ efi_status_t status; > >+ > >+ if (argc != 3) > >+ return CMD_RET_USAGE; > >+ > >+ argc--; argv++; > >+ > >+ size = simple_strtoul(argv[0], NULL, 16); > >+ if (!size) { > >+ printf("Enter valid size for free in Hex\n"); > >+ return CMD_RET_USAGE; > >+ } > >+ > >+ > >+ addr = simple_strtoul(argv[1], NULL, 16); > >+ if (!addr) { > >+ printf("Enter a valid address in Hex\n"); > >+ return CMD_RET_USAGE; > >+ } > >+ > >+ pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK)); > >+ > >+ status = efi_free_pages(addr, pages); > >+ if (status != EFI_SUCCESS) { > >+ printf("Unable to free memory, error (%#lx)\n", status); > >+ return CMD_RET_FAILURE; > >+ } > >+ > >+ return CMD_RET_SUCCESS; > >+} > >+ > >+static int do_efi_mem_alloc(struct cmd_tbl *cmdtp, int flag, int argc, > >+ char * const argv[]) > >+{ > >+ enum efi_allocate_type type; > >+ uint64_t addr = 0, size = 0; > >+ efi_uintn_t pages; > >+ efi_status_t status; > >+ bool max = false; > >+ > >+ if (argc < 2) > >+ return CMD_RET_USAGE; > >+ > >+ argc--; argv++; > >+ > >+ if (!strcmp("max", argv[0])) { > >+ if (argc != 3) > >+ return CMD_RET_USAGE; > >+ > >+ max = true; > >+ argv++; > >+ argc--; > >+ } > >+ > >+ size = simple_strtoul(argv[0], NULL, 16); > >+ if (!size) { > >+ printf("Enter valid size for allocation in Hex\n"); > >+ return CMD_RET_USAGE; > >+ } > >+ > >+ if (max || argc == 2) { > >+ addr = simple_strtoul(argv[1], NULL, 16); > >+ if (!addr) { > >+ printf("Enter a valid address in Hex\n"); > >+ return CMD_RET_USAGE; > >+ } > >+ } > >+ > >+ if (max) > >+ type = EFI_ALLOCATE_MAX_ADDRESS; > >+ else if (addr) > >+ type = EFI_ALLOCATE_ADDRESS; > >+ else > >+ type = EFI_ALLOCATE_ANY_PAGES; > >+ > >+ pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK)); > >+ status = efi_allocate_pages(type, EFI_BOOT_SERVICES_DATA, pages, > >+ &addr); > >+ if (status != EFI_SUCCESS) { > >+ printf("efi_allocate_pages failed %lx\n", status); > >+ return CMD_RET_FAILURE; > >+ } else { > >+ printf("Address returned %#llx\n", addr); > >+ } > >+ > >+ return CMD_RET_SUCCESS; > >+} > >+ > >+static struct cmd_tbl cmd_efi_mem_sub[] = { > >+ U_BOOT_CMD_MKENT(alloc, 3, 0, do_efi_mem_alloc, > >+ "", ""), > >+ U_BOOT_CMD_MKENT(free, 2, 0, do_efi_mem_free, > >+ "", ""), > >+}; > >+ > >+static int do_efi_mem(struct cmd_tbl *cmdtp, int flag, int argc, > >+ char *const argv[]) > >+{ > >+ struct cmd_tbl *cp; > >+ efi_status_t r; > >+ > >+ if (argc < 3) > >+ return CMD_RET_USAGE; > >+ > >+ argc--; argv++; > >+ > >+ /* Initialize UEFI subsystem */ > >+ r = efi_init_obj_list(); > >+ if (r != EFI_SUCCESS) { > >+ printf("Error: Cannot initialize UEFI sub-system, r = %lu\n", > >+ r & ~EFI_ERROR_MASK); > >+ return CMD_RET_FAILURE; > >+ } > >+ > >+ cp = find_cmd_tbl(argv[0], cmd_efi_mem_sub, > >+ ARRAY_SIZE(cmd_efi_mem_sub)); > >+ if (!cp) > >+ return CMD_RET_USAGE; > >+ > >+ return cp->cmd(cmdtp, flag, argc, argv); > >+} > >+ > >+U_BOOT_LONGHELP(efi_mem, > >+ "Functions to allocate and free memory\n" > >+ "\n" > >+ "efi_mem alloc <size> [addr]\n" > >+ "efi_mem alloc max <size> <max-addr>\n" > >+ "efi_mem free <size> <addr>\n" > >+ "\n" > >+); > >+ > >+U_BOOT_CMD( > >+ efi_mem, CONFIG_SYS_MAXARGS, 0, do_efi_mem, > >+ "Allocate and free EFI memory", > >+ efi_mem_help_text > >+); ^ permalink raw reply [flat|nested] 127+ messages in thread
* [RFC PATCH 31/31] temp: cmd: efi: add a command to dump EFI memory map 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (29 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 30/31] temp: cmd: efi_mem: add a command to test efi alloc/free Sughosh Ganu @ 2024-06-07 18:52 ` Sughosh Ganu 2024-06-08 3:28 ` Heinrich Schuchardt 2024-06-10 21:05 ` [RFC PATCH 00/31] Make U-Boot memory reservations coherent Tom Rini 2024-06-11 18:52 ` Simon Glass 32 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-07 18:52 UTC (permalink / raw) To: u-boot Cc: Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam, Sughosh Ganu Add a command to dump the EFI memory map. Not for committing. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- cmd/Makefile | 1 + cmd/efi_map_dump.c | 28 ++++++++++++++++++++++++++++ include/efi_loader.h | 2 ++ lib/efi_loader/efi_memory.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 cmd/efi_map_dump.c diff --git a/cmd/Makefile b/cmd/Makefile index 35fcc4af5a..315046def6 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -11,6 +11,7 @@ obj-y += help.o obj-y += panic.o obj-y += version.o obj-y += efi_memory.o +obj-y += efi_map_dump.o # command obj-$(CONFIG_CMD_ARMFFA) += armffa.o diff --git a/cmd/efi_map_dump.c b/cmd/efi_map_dump.c new file mode 100644 index 0000000000..f2a5932767 --- /dev/null +++ b/cmd/efi_map_dump.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Allocate and Free EFI memory + * + * Copyright (c) 2024 Linaro Limited + */ + +#include <command.h> +#include <efi_loader.h> + +static int do_efi_map_dump(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ +// printf("%s: argc => %d\n", __func__, argc); + + if (argc != 1) + return CMD_RET_USAGE; + + dump_efi_memory_map(); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + efi_map_dump, 1, 0, do_efi_map_dump, + "Dump the EFI memory map", + "" +); diff --git a/include/efi_loader.h b/include/efi_loader.h index 9600941aa3..40f894f182 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -791,6 +791,8 @@ 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); +/* Dump the contents of the EFI memory map */ +void dump_efi_memory_map(void); /* 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); diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 93244161b0..7ab1b86140 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -47,6 +47,8 @@ static LIST_HEAD(efi_mem); void *efi_bounce_buffer; #endif +static uint64_t desc_get_end(struct efi_mem_desc *desc); + /** * struct efi_pool_allocation - memory block allocated from pool * @@ -118,6 +120,36 @@ static int lmb_mem_map_update_sync(void *ctx, struct event *event) EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); #endif /* MEM_MAP_UPDATE_NOTIFY */ +static void dump_efi_mem_desc(struct efi_mem_desc *desc) +{ + u64 end; + + end = desc_get_end(desc); + + printf("-----------------------------------\n"); + printf("Memory Range [0x%llx - 0x%llx]\n", + desc->physical_start, end); + printf("Num Pages [0x%llx]\n", desc->num_pages); + printf("Memory Type [0x%x]\n", desc->type); + printf("Attribute [0x%llx]\n", desc->attribute); + printf("-----------------------------------\n"); +} + +void dump_efi_memory_map(void) +{ + struct list_head *lhandle; + + list_for_each(lhandle, &efi_mem) { + struct efi_mem_list *lmem; + struct efi_mem_desc *desc; + + lmem = list_entry(lhandle, struct efi_mem_list, link); + desc = &lmem->desc; + + dump_efi_mem_desc(desc); + } +} + /** * checksum() - calculate checksum for memory allocated from pool * -- 2.34.1 ^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 31/31] temp: cmd: efi: add a command to dump EFI memory map 2024-06-07 18:52 ` [RFC PATCH 31/31] temp: cmd: efi: add a command to dump EFI memory map Sughosh Ganu @ 2024-06-08 3:28 ` Heinrich Schuchardt 2024-06-10 6:45 ` Sughosh Ganu 0 siblings, 1 reply; 127+ messages in thread From: Heinrich Schuchardt @ 2024-06-08 3:28 UTC (permalink / raw) To: Sughosh Ganu, u-boot Cc: Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam Am 7. Juni 2024 20:52:40 MESZ schrieb Sughosh Ganu <sughosh.ganu@linaro.org>: >Add a command to dump the EFI memory map. What are you missing in 'efidebug memmap'? Best regards Heinrich > >Not for committing. > >Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> >--- > cmd/Makefile | 1 + > cmd/efi_map_dump.c | 28 ++++++++++++++++++++++++++++ > include/efi_loader.h | 2 ++ > lib/efi_loader/efi_memory.c | 32 ++++++++++++++++++++++++++++++++ > 4 files changed, 63 insertions(+) > create mode 100644 cmd/efi_map_dump.c > >diff --git a/cmd/Makefile b/cmd/Makefile >index 35fcc4af5a..315046def6 100644 >--- a/cmd/Makefile >+++ b/cmd/Makefile >@@ -11,6 +11,7 @@ obj-y += help.o > obj-y += panic.o > obj-y += version.o > obj-y += efi_memory.o >+obj-y += efi_map_dump.o > > # command > obj-$(CONFIG_CMD_ARMFFA) += armffa.o >diff --git a/cmd/efi_map_dump.c b/cmd/efi_map_dump.c >new file mode 100644 >index 0000000000..f2a5932767 >--- /dev/null >+++ b/cmd/efi_map_dump.c >@@ -0,0 +1,28 @@ >+// SPDX-License-Identifier: GPL-2.0+ >+/* >+ * Allocate and Free EFI memory >+ * >+ * Copyright (c) 2024 Linaro Limited >+ */ >+ >+#include <command.h> >+#include <efi_loader.h> >+ >+static int do_efi_map_dump(struct cmd_tbl *cmdtp, int flag, int argc, >+ char *const argv[]) >+{ >+// printf("%s: argc => %d\n", __func__, argc); >+ >+ if (argc != 1) >+ return CMD_RET_USAGE; >+ >+ dump_efi_memory_map(); >+ >+ return CMD_RET_SUCCESS; >+} >+ >+U_BOOT_CMD( >+ efi_map_dump, 1, 0, do_efi_map_dump, >+ "Dump the EFI memory map", >+ "" >+); >diff --git a/include/efi_loader.h b/include/efi_loader.h >index 9600941aa3..40f894f182 100644 >--- a/include/efi_loader.h >+++ b/include/efi_loader.h >@@ -791,6 +791,8 @@ 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); >+/* Dump the contents of the EFI memory map */ >+void dump_efi_memory_map(void); > /* 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); >diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c >index 93244161b0..7ab1b86140 100644 >--- a/lib/efi_loader/efi_memory.c >+++ b/lib/efi_loader/efi_memory.c >@@ -47,6 +47,8 @@ static LIST_HEAD(efi_mem); > void *efi_bounce_buffer; > #endif > >+static uint64_t desc_get_end(struct efi_mem_desc *desc); >+ > /** > * struct efi_pool_allocation - memory block allocated from pool > * >@@ -118,6 +120,36 @@ static int lmb_mem_map_update_sync(void *ctx, struct event *event) > EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > #endif /* MEM_MAP_UPDATE_NOTIFY */ > >+static void dump_efi_mem_desc(struct efi_mem_desc *desc) >+{ >+ u64 end; >+ >+ end = desc_get_end(desc); >+ >+ printf("-----------------------------------\n"); >+ printf("Memory Range [0x%llx - 0x%llx]\n", >+ desc->physical_start, end); >+ printf("Num Pages [0x%llx]\n", desc->num_pages); >+ printf("Memory Type [0x%x]\n", desc->type); >+ printf("Attribute [0x%llx]\n", desc->attribute); >+ printf("-----------------------------------\n"); >+} >+ >+void dump_efi_memory_map(void) >+{ >+ struct list_head *lhandle; >+ >+ list_for_each(lhandle, &efi_mem) { >+ struct efi_mem_list *lmem; >+ struct efi_mem_desc *desc; >+ >+ lmem = list_entry(lhandle, struct efi_mem_list, link); >+ desc = &lmem->desc; >+ >+ dump_efi_mem_desc(desc); >+ } >+} >+ > /** > * checksum() - calculate checksum for memory allocated from pool > * ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 31/31] temp: cmd: efi: add a command to dump EFI memory map 2024-06-08 3:28 ` Heinrich Schuchardt @ 2024-06-10 6:45 ` Sughosh Ganu 0 siblings, 0 replies; 127+ messages in thread From: Sughosh Ganu @ 2024-06-10 6:45 UTC (permalink / raw) To: Heinrich Schuchardt Cc: u-boot, Tom Rini, Ilias Apalodimas, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Sat, 8 Jun 2024 at 09:03, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > > > Am 7. Juni 2024 20:52:40 MESZ schrieb Sughosh Ganu <sughosh.ganu@linaro.org>: > >Add a command to dump the EFI memory map. > > What are you missing in 'efidebug memmap'? Nothing. I wasn't aware of this sub-command. Thanks for pointing it out. -sughosh > > Best regards > > Heinrich > > > > >Not for committing. > > > >Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > >--- > > cmd/Makefile | 1 + > > cmd/efi_map_dump.c | 28 ++++++++++++++++++++++++++++ > > include/efi_loader.h | 2 ++ > > lib/efi_loader/efi_memory.c | 32 ++++++++++++++++++++++++++++++++ > > 4 files changed, 63 insertions(+) > > create mode 100644 cmd/efi_map_dump.c > > > >diff --git a/cmd/Makefile b/cmd/Makefile > >index 35fcc4af5a..315046def6 100644 > >--- a/cmd/Makefile > >+++ b/cmd/Makefile > >@@ -11,6 +11,7 @@ obj-y += help.o > > obj-y += panic.o > > obj-y += version.o > > obj-y += efi_memory.o > >+obj-y += efi_map_dump.o > > > > # command > > obj-$(CONFIG_CMD_ARMFFA) += armffa.o > >diff --git a/cmd/efi_map_dump.c b/cmd/efi_map_dump.c > >new file mode 100644 > >index 0000000000..f2a5932767 > >--- /dev/null > >+++ b/cmd/efi_map_dump.c > >@@ -0,0 +1,28 @@ > >+// SPDX-License-Identifier: GPL-2.0+ > >+/* > >+ * Allocate and Free EFI memory > >+ * > >+ * Copyright (c) 2024 Linaro Limited > >+ */ > >+ > >+#include <command.h> > >+#include <efi_loader.h> > >+ > >+static int do_efi_map_dump(struct cmd_tbl *cmdtp, int flag, int argc, > >+ char *const argv[]) > >+{ > >+// printf("%s: argc => %d\n", __func__, argc); > >+ > >+ if (argc != 1) > >+ return CMD_RET_USAGE; > >+ > >+ dump_efi_memory_map(); > >+ > >+ return CMD_RET_SUCCESS; > >+} > >+ > >+U_BOOT_CMD( > >+ efi_map_dump, 1, 0, do_efi_map_dump, > >+ "Dump the EFI memory map", > >+ "" > >+); > >diff --git a/include/efi_loader.h b/include/efi_loader.h > >index 9600941aa3..40f894f182 100644 > >--- a/include/efi_loader.h > >+++ b/include/efi_loader.h > >@@ -791,6 +791,8 @@ 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); > >+/* Dump the contents of the EFI memory map */ > >+void dump_efi_memory_map(void); > > /* 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); > >diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > >index 93244161b0..7ab1b86140 100644 > >--- a/lib/efi_loader/efi_memory.c > >+++ b/lib/efi_loader/efi_memory.c > >@@ -47,6 +47,8 @@ static LIST_HEAD(efi_mem); > > void *efi_bounce_buffer; > > #endif > > > >+static uint64_t desc_get_end(struct efi_mem_desc *desc); > >+ > > /** > > * struct efi_pool_allocation - memory block allocated from pool > > * > >@@ -118,6 +120,36 @@ static int lmb_mem_map_update_sync(void *ctx, struct event *event) > > EVENT_SPY_FULL(EVT_LMB_MAP_UPDATE, lmb_mem_map_update_sync); > > #endif /* MEM_MAP_UPDATE_NOTIFY */ > > > >+static void dump_efi_mem_desc(struct efi_mem_desc *desc) > >+{ > >+ u64 end; > >+ > >+ end = desc_get_end(desc); > >+ > >+ printf("-----------------------------------\n"); > >+ printf("Memory Range [0x%llx - 0x%llx]\n", > >+ desc->physical_start, end); > >+ printf("Num Pages [0x%llx]\n", desc->num_pages); > >+ printf("Memory Type [0x%x]\n", desc->type); > >+ printf("Attribute [0x%llx]\n", desc->attribute); > >+ printf("-----------------------------------\n"); > >+} > >+ > >+void dump_efi_memory_map(void) > >+{ > >+ struct list_head *lhandle; > >+ > >+ list_for_each(lhandle, &efi_mem) { > >+ struct efi_mem_list *lmem; > >+ struct efi_mem_desc *desc; > >+ > >+ lmem = list_entry(lhandle, struct efi_mem_list, link); > >+ desc = &lmem->desc; > >+ > >+ dump_efi_mem_desc(desc); > >+ } > >+} > >+ > > /** > > * checksum() - calculate checksum for memory allocated from pool > > * ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 00/31] Make U-Boot memory reservations coherent 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (30 preceding siblings ...) 2024-06-07 18:52 ` [RFC PATCH 31/31] temp: cmd: efi: add a command to dump EFI memory map Sughosh Ganu @ 2024-06-10 21:05 ` Tom Rini 2024-06-11 9:01 ` Sughosh Ganu 2024-06-11 18:52 ` Simon Glass 32 siblings, 1 reply; 127+ messages in thread From: Tom Rini @ 2024-06-10 21:05 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 26240 bytes --] On Sat, Jun 08, 2024 at 12:22:09AM +0530, Sughosh Ganu wrote: > The aim of this patch series is to fix the current state of > incoherence between modules when it comes to memory usage. The primary > issue that this series is trying to fix is that the EFI memory module > which is responsible for allocating and freeing memory, does not have > any visibility of the memory that is being used by the LMB > module. This is further complicated by the fact that the LMB > allocations are caller specific -- the LMB memory map is not global > nor persistent. This means that the memory "allocated" by the LMB > module might be relevant only for a given function. Hence one of the > requirements for making the memory usage visible across modules is to > make LMB allocations persistent and global, and then have means to > communicate the use of memory across modules. > > The first set of patches in this series work on making the LMB memory > map persistent and global. This is being done keeping in mind the > usage of LMB memory by platforms where the same memory region can be > used to load multiple different images. What is not allowed is to > overwrite memory that has been allocated by the other module, > currently the EFI memory module. This is being achieved by introducing > a new flag, LMB_NOOVERWRITE, which represents memory which cannot be > re-requested once allocated. > > The second set of patches are then introducing a notification > mechanism to indicate any changes to a respective module's memory > map. This way, any memory allocation/reservation by a module gets > notified to any interested listners, who then update their memory map > accordingly, thus keeping memory usage coherent. > > Todo's > ------ > I have run these patches through CI, but the LMB unit tests need an > overhaul. I have currently marked these tests for manual run, as > running these would obviously tamper the LMB memory map, thus > affecting subsequent tests. The current set of LMB tests are written > with the assumption of local LMB memory maps. This needs to be > reworked. > > Secondly, there needs to be a test written for testing the various > scenarios of memory being allocated and freed by different modules, > namely LMB and EFI. I have written a couple of commands for testing > the changes that I have made -- I have also included these temporary > commands to assist anyone who might want to test these changes. But I > will be working on adding a more comprehensive test. > > Lastly, as the series touches common code, there is obviously an > increase in the size of the image, moreover since the LMB memory is > now persistent, and the variables do not reside on the stack. I want > to check if there can be ways of decreasing the size impact of the > changes. So, I think you made some changes between your last CI run and posting? A ton of platforms (basically anything with EFI_LOADER disabled) fail to build now because the two "temp" commits at the end of the series are always enabled. I took those commits out and ran my world build size check tests and the results are at: https://gist.github.com/trini/d42bd392463c39766a5f872c190ccf27 And 64bit ARM looks very reasonable, but I wonder if we can improve the 32bit ARM results? I also did an every commit run for a 32bit ARM board without EFI_LOADER (which is going to be the case for size constrained systems) and see that the series isn't bisect'able to start with, so please fix that for the next go-round. That said: Summary of 30 commits for 1 boards (1 thread, 12 jobs per thread) 01: Added arm64 assembly for examples/api crt0 02: lmb: remove the unused lmb_is_reserved() function 03: lmb: staticize __lmb_alloc_base() arm: (for 1/1 boards) all -16.0 text -16.0 omapl138_lcdk : all -16 text -16 u-boot: add: 0/-1, grow: 1/0 bytes: 172/-186 (-14) function old new delta lmb_alloc_base 40 212 +172 __lmb_alloc_base 186 - -186 04: lmb: make the lmb reservations persistent arm: + omapl138_lcdk +(omapl138_lcdk) lib/lmb.c: In function 'lmb_dump_all_force': +(omapl138_lcdk) lib/lmb.c:64:29: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 64 | lmb_dump_region(&lmb.memory, "memory"); +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:65:29: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 65 | lmb_dump_region(&lmb.reserved, "reserved"); +(omapl138_lcdk) lib/lmb.c: In function 'lmb_add': +(omapl138_lcdk) lib/lmb.c:356:39: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 356 | struct lmb_region *_rgn = &lmb.memory; +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c: In function 'lmb_free': +(omapl138_lcdk) lib/lmb.c:363:38: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 363 | struct lmb_region *rgn = &lmb.reserved; +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c: In function 'lmb_reserve_flags': +(omapl138_lcdk) lib/lmb.c:414:39: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 414 | struct lmb_region *_rgn = &lmb.reserved; +(omapl138_lcdk) lib/lmb.c: In function '__lmb_alloc_base': +(omapl138_lcdk) lib/lmb.c:451:21: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 451 | for (i = lmb.memory.cnt - 1; i >= 0; i--) { +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:452:42: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 452 | phys_addr_t lmbbase = lmb.memory.region[i].base; +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:453:42: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 453 | phys_size_t lmbsize = lmb.memory.region[i].size; +(omapl138_lcdk) lib/lmb.c:469:55: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 469 | rgn = lmb_overlaps_region(&lmb.reserved, base, size); +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:472:56: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 472 | if (lmb_add_region(&lmb.reserved, base, +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:477:39: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 477 | res_base = lmb.reserved.region[rgn].base; +(omapl138_lcdk) lib/lmb.c: In function 'lmb_alloc_addr': +(omapl138_lcdk) lib/lmb.c:513:39: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 513 | rgn = lmb_overlaps_region(&lmb.memory, base, size); +(omapl138_lcdk) lib/lmb.c:519:42: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 519 | if (lmb_addrs_overlap(lmb.memory.region[rgn].base, +(omapl138_lcdk) lib/lmb.c:520:42: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 520 | lmb.memory.region[rgn].size, +(omapl138_lcdk) lib/lmb.c: In function 'lmb_get_free_size': +(omapl138_lcdk) lib/lmb.c:537:39: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 537 | rgn = lmb_overlaps_region(&lmb.memory, addr, 1); +(omapl138_lcdk) lib/lmb.c:539:36: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 539 | for (i = 0; i < lmb.reserved.cnt; i++) { +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:540:39: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 540 | if (addr < lmb.reserved.region[i].base) { +(omapl138_lcdk) lib/lmb.c:542:43: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 542 | return lmb.reserved.region[i].base - addr; +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:544:32: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 544 | if (lmb.reserved.region[i].base + +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:545:32: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 545 | lmb.reserved.region[i].size > addr) { +(omapl138_lcdk) lib/lmb.c:551:27: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 551 | return lmb.memory.region[lmb.memory.cnt - 1].base + +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:551:45: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:552:27: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 552 | lmb.memory.region[lmb.memory.cnt - 1].size - addr; +(omapl138_lcdk) lib/lmb.c:552:45: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) lib/lmb.c: In function 'lmb_is_reserved_flags': +(omapl138_lcdk) lib/lmb.c:561:28: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 561 | for (i = 0; i < lmb.reserved.cnt; i++) { +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:562:40: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 562 | phys_addr_t upper = lmb.reserved.region[i].base + +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:563:28: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 563 | lmb.reserved.region[i].size - 1; +(omapl138_lcdk) lib/lmb.c:564:33: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 564 | if ((addr >= lmb.reserved.region[i].base) && (addr <= upper)) +(omapl138_lcdk) | ^ +(omapl138_lcdk) | -> +(omapl138_lcdk) lib/lmb.c:565:36: error: 'lmb' is a pointer; did you mean to use '->'? +(omapl138_lcdk) 565 | return (lmb.reserved.region[i].flags & flags) == flags; +(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: lib/lmb.o] Error 1 +(omapl138_lcdk) make[1]: *** [Makefile:1892: lib] Error 2 +(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:256: spl/lib/lmb.o] Error 1 +(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/lib] Error 2 +(omapl138_lcdk) make[1]: *** [Makefile:2092: spl/u-boot-spl] Error 2 +(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 05: lmb: remove local instances of the lmb structure variable -(omapl138_lcdk) lib/lmb.c: In function 'lmb_dump_all_force': -(omapl138_lcdk) lib/lmb.c:64:29: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 64 | lmb_dump_region(&lmb.memory, "memory"); -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:65:29: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 65 | lmb_dump_region(&lmb.reserved, "reserved"); -(omapl138_lcdk) lib/lmb.c: In function 'lmb_add': -(omapl138_lcdk) lib/lmb.c:356:39: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 356 | struct lmb_region *_rgn = &lmb.memory; -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c: In function 'lmb_free': -(omapl138_lcdk) lib/lmb.c:363:38: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 363 | struct lmb_region *rgn = &lmb.reserved; -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c: In function 'lmb_reserve_flags': -(omapl138_lcdk) lib/lmb.c:414:39: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 414 | struct lmb_region *_rgn = &lmb.reserved; -(omapl138_lcdk) lib/lmb.c: In function '__lmb_alloc_base': -(omapl138_lcdk) lib/lmb.c:451:21: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 451 | for (i = lmb.memory.cnt - 1; i >= 0; i--) { -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:452:42: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 452 | phys_addr_t lmbbase = lmb.memory.region[i].base; -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:453:42: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 453 | phys_size_t lmbsize = lmb.memory.region[i].size; -(omapl138_lcdk) lib/lmb.c:469:55: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 469 | rgn = lmb_overlaps_region(&lmb.reserved, base, size); -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:472:56: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 472 | if (lmb_add_region(&lmb.reserved, base, -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:477:39: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 477 | res_base = lmb.reserved.region[rgn].base; -(omapl138_lcdk) lib/lmb.c: In function 'lmb_alloc_addr': -(omapl138_lcdk) lib/lmb.c:513:39: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 513 | rgn = lmb_overlaps_region(&lmb.memory, base, size); -(omapl138_lcdk) lib/lmb.c:519:42: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 519 | if (lmb_addrs_overlap(lmb.memory.region[rgn].base, -(omapl138_lcdk) lib/lmb.c:520:42: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 520 | lmb.memory.region[rgn].size, -(omapl138_lcdk) lib/lmb.c: In function 'lmb_get_free_size': -(omapl138_lcdk) lib/lmb.c:537:39: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 537 | rgn = lmb_overlaps_region(&lmb.memory, addr, 1); -(omapl138_lcdk) lib/lmb.c:539:36: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 539 | for (i = 0; i < lmb.reserved.cnt; i++) { -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:540:39: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 540 | if (addr < lmb.reserved.region[i].base) { -(omapl138_lcdk) lib/lmb.c:542:43: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 542 | return lmb.reserved.region[i].base - addr; -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:544:32: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 544 | if (lmb.reserved.region[i].base + -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:545:32: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 545 | lmb.reserved.region[i].size > addr) { -(omapl138_lcdk) lib/lmb.c:551:27: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 551 | return lmb.memory.region[lmb.memory.cnt - 1].base + -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:551:45: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:552:27: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 552 | lmb.memory.region[lmb.memory.cnt - 1].size - addr; -(omapl138_lcdk) lib/lmb.c:552:45: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) lib/lmb.c: In function 'lmb_is_reserved_flags': -(omapl138_lcdk) lib/lmb.c:561:28: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 561 | for (i = 0; i < lmb.reserved.cnt; i++) { -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:562:40: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 562 | phys_addr_t upper = lmb.reserved.region[i].base + -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:563:28: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 563 | lmb.reserved.region[i].size - 1; -(omapl138_lcdk) lib/lmb.c:564:33: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 564 | if ((addr >= lmb.reserved.region[i].base) && (addr <= upper)) -(omapl138_lcdk) | ^ -(omapl138_lcdk) | -> -(omapl138_lcdk) lib/lmb.c:565:36: error: 'lmb' is a pointer; did you mean to use '->'? -(omapl138_lcdk) 565 | return (lmb.reserved.region[i].flags & flags) == flags; -(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: lib/lmb.o] Error 1 -(omapl138_lcdk) make[1]: *** [Makefile:1892: lib] Error 2 -(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:256: spl/lib/lmb.o] Error 1 -(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/lib] Error 2 +(omapl138_lcdk) boot/image-board.c: In function 'image_setup_linux': +(omapl138_lcdk) boot/image-board.c:907:65: error: 'lmb' undeclared (first use in this function) +(omapl138_lcdk) 907 | ret = image_setup_libfdt(images, *of_flat_tree, lmb); +(omapl138_lcdk) | ^~~ +(omapl138_lcdk) boot/image-board.c:907:65: note: each undeclared identifier is reported only once for each function it appears in +(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: boot/image-board.o] Error 1 +(omapl138_lcdk) make[1]: *** [Makefile:1892: boot] Error 2 +(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:257: spl/boot/image-board.o] Error 1 +(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/boot] Error 2 06: lmb: pass a flag to image_setup_libfdt() for lmb reservations arm: omapl138_lcdk -(omapl138_lcdk) boot/image-board.c: In function 'image_setup_linux': -(omapl138_lcdk) boot/image-board.c:907:65: error: 'lmb' undeclared (first use in this function) -(omapl138_lcdk) 907 | ret = image_setup_libfdt(images, *of_flat_tree, lmb); -(omapl138_lcdk) | ^~~ -(omapl138_lcdk) boot/image-board.c:907:65: note: each undeclared identifier is reported only once for each function it appears in -(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: boot/image-board.o] Error 1 -(omapl138_lcdk) make[1]: *** [Makefile:1892: boot] Error 2 -(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:257: spl/boot/image-board.o] Error 1 -(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/boot] Error 2 -(omapl138_lcdk) make[1]: *** [Makefile:2092: spl/u-boot-spl] Error 2 -(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 07: lmb: reserve and add common memory regions post relocation arm: + omapl138_lcdk +(omapl138_lcdk) common/board_r.c: In function 'initr_lmb': +(omapl138_lcdk) common/board_r.c:564:9: error: implicit declaration of function 'lmb_add_memory' [-Werror=implicit-function-declaration] +(omapl138_lcdk) 564 | lmb_add_memory(gd->bd); +(omapl138_lcdk) | ^~~~~~~~~~~~~~ +(omapl138_lcdk) cc1: all warnings being treated as errors +(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: common/board_r.o] Error 1 +(omapl138_lcdk) make[1]: *** [Makefile:1892: common] Error 2 +(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 08: lmb: remove lmb_init_and_reserve_range() function 09: lmb: replcace the lmb_init_and_reserve() function arm: omapl138_lcdk -(omapl138_lcdk) common/board_r.c: In function 'initr_lmb': -(omapl138_lcdk) common/board_r.c:564:9: error: implicit declaration of function 'lmb_add_memory' [-Werror=implicit-function-declaration] -(omapl138_lcdk) 564 | lmb_add_memory(gd->bd); -(omapl138_lcdk) | ^~~~~~~~~~~~~~ -(omapl138_lcdk) cc1: all warnings being treated as errors -(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: common/board_r.o] Error 1 -(omapl138_lcdk) make[1]: *** [Makefile:1892: common] Error 2 -(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 10: lmb: allow for resizing lmb regions arm: (for 1/1 boards) all +224.0 text +224.0 omapl138_lcdk : all +224 text +224 u-boot: add: 0/0, grow: 1/0 bytes: 224/0 (224) function old new delta lmb_add_region_flags 416 640 +224 11: event: add events to notify memory map changes 12: lib: Kconfig: add a config symbol for getting memory map updates 13: add a function to check if an address is in RAM memory 14: efi_memory: notify of any changes to the EFI memory map 15: lmb: notify of any changes to the LMB memory map arm: (for 1/1 boards) all +8.0 text +8.0 omapl138_lcdk : all +8 text +8 u-boot: add: 0/0, grow: 2/0 bytes: 12/0 (12) function old new delta lmb_reserve_flags 32 40 +8 lmb_free 192 196 +4 16: efi_memory: add an event handler to update memory map 17: lmb: add an event handler to update memory map arm: (for 1/1 boards) all +349.0 rodata +61.0 text +288.0 omapl138_lcdk : all +349 rodata +61 text +288 u-boot: add: 3/0, grow: 3/0 bytes: 232/0 (232) function old new delta event_notify - 104 +104 initcall_run_list 96 144 +48 image_setup_libfdt 236 284 +48 event_notify_null - 18 +18 event_type_name - 8 +8 run_main_loop 10 16 +6 18: lmb: remove call to efi_lmb_reserve() 19: sandbox: iommu: remove lmb allocation in the driver 20: zynq: lmb: do not add to lmb map before relocation 21: test: cedit: use allocated address for reading file 22: test: event: update the expected event dump output 23: test: lmb: run the LMB tests only on sandbox 24: test: lmb: initialise the lmb structure before tests 25: test: lmb: add a test case for checking overlapping region add 26: test: lmb: adjust the test case to handle overlapping regions 27: test: lmb: run lmb tests only manually 28: test: bdinfo: dump the global LMB memory map 29: cmd: bdinfo: only dump the current LMB memory arm: (for 1/1 boards) all -8.0 text -8.0 omapl138_lcdk : all -8 text -8 u-boot: add: 0/0, grow: 0/-1 bytes: 0/-8 (-8) function old new delta do_bdinfo 472 464 -8 30: temp: mx6sabresd: bump up the size limit of the board So my first thought is, do we really need the event notifier framework in the case where it's NOT also using EFI_LOADER? Or is perhaps that Kconfig logic not quite right? -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 00/31] Make U-Boot memory reservations coherent 2024-06-10 21:05 ` [RFC PATCH 00/31] Make U-Boot memory reservations coherent Tom Rini @ 2024-06-11 9:01 ` Sughosh Ganu 2024-06-11 14:39 ` Tom Rini 0 siblings, 1 reply; 127+ messages in thread From: Sughosh Ganu @ 2024-06-11 9:01 UTC (permalink / raw) To: Tom Rini Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam On Tue, 11 Jun 2024 at 02:35, Tom Rini <trini@konsulko.com> wrote: > > On Sat, Jun 08, 2024 at 12:22:09AM +0530, Sughosh Ganu wrote: > > > The aim of this patch series is to fix the current state of > > incoherence between modules when it comes to memory usage. The primary > > issue that this series is trying to fix is that the EFI memory module > > which is responsible for allocating and freeing memory, does not have > > any visibility of the memory that is being used by the LMB > > module. This is further complicated by the fact that the LMB > > allocations are caller specific -- the LMB memory map is not global > > nor persistent. This means that the memory "allocated" by the LMB > > module might be relevant only for a given function. Hence one of the > > requirements for making the memory usage visible across modules is to > > make LMB allocations persistent and global, and then have means to > > communicate the use of memory across modules. > > > > The first set of patches in this series work on making the LMB memory > > map persistent and global. This is being done keeping in mind the > > usage of LMB memory by platforms where the same memory region can be > > used to load multiple different images. What is not allowed is to > > overwrite memory that has been allocated by the other module, > > currently the EFI memory module. This is being achieved by introducing > > a new flag, LMB_NOOVERWRITE, which represents memory which cannot be > > re-requested once allocated. > > > > The second set of patches are then introducing a notification > > mechanism to indicate any changes to a respective module's memory > > map. This way, any memory allocation/reservation by a module gets > > notified to any interested listners, who then update their memory map > > accordingly, thus keeping memory usage coherent. > > > > Todo's > > ------ > > I have run these patches through CI, but the LMB unit tests need an > > overhaul. I have currently marked these tests for manual run, as > > running these would obviously tamper the LMB memory map, thus > > affecting subsequent tests. The current set of LMB tests are written > > with the assumption of local LMB memory maps. This needs to be > > reworked. > > > > Secondly, there needs to be a test written for testing the various > > scenarios of memory being allocated and freed by different modules, > > namely LMB and EFI. I have written a couple of commands for testing > > the changes that I have made -- I have also included these temporary > > commands to assist anyone who might want to test these changes. But I > > will be working on adding a more comprehensive test. > > > > Lastly, as the series touches common code, there is obviously an > > increase in the size of the image, moreover since the LMB memory is > > now persistent, and the variables do not reside on the stack. I want > > to check if there can be ways of decreasing the size impact of the > > changes. > > So, I think you made some changes between your last CI run and posting? > A ton of platforms (basically anything with EFI_LOADER disabled) fail to > build now because the two "temp" commits at the end of the series are > always enabled. I took those commits out and ran my world build size > check tests and the results are at: > https://gist.github.com/trini/d42bd392463c39766a5f872c190ccf27 > > And 64bit ARM looks very reasonable, but I wonder if we can improve the > 32bit ARM results? > > I also did an every commit run for a 32bit ARM board without EFI_LOADER > (which is going to be the case for size constrained systems) and see > that the series isn't bisect'able to start with, so please fix that for > the next go-round. That said: Yes, I should have mentioned it in the cover letter about issues with bisectability, primarily because some code under boot/ uses the lmb API's unconditionally, without having a check for LMB being enabled or not. > Summary of 30 commits for 1 boards (1 thread, 12 jobs per thread) > 01: Added arm64 assembly for examples/api crt0 > 02: lmb: remove the unused lmb_is_reserved() function > 03: lmb: staticize __lmb_alloc_base() > arm: (for 1/1 boards) all -16.0 text -16.0 > omapl138_lcdk : all -16 text -16 > u-boot: add: 0/-1, grow: 1/0 bytes: 172/-186 (-14) > function old new delta > lmb_alloc_base 40 212 +172 > __lmb_alloc_base 186 - -186 > 04: lmb: make the lmb reservations persistent > arm: + omapl138_lcdk > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_dump_all_force': > +(omapl138_lcdk) lib/lmb.c:64:29: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 64 | lmb_dump_region(&lmb.memory, "memory"); > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:65:29: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 65 | lmb_dump_region(&lmb.reserved, "reserved"); > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_add': > +(omapl138_lcdk) lib/lmb.c:356:39: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 356 | struct lmb_region *_rgn = &lmb.memory; > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_free': > +(omapl138_lcdk) lib/lmb.c:363:38: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 363 | struct lmb_region *rgn = &lmb.reserved; > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_reserve_flags': > +(omapl138_lcdk) lib/lmb.c:414:39: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 414 | struct lmb_region *_rgn = &lmb.reserved; > +(omapl138_lcdk) lib/lmb.c: In function '__lmb_alloc_base': > +(omapl138_lcdk) lib/lmb.c:451:21: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 451 | for (i = lmb.memory.cnt - 1; i >= 0; i--) { > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:452:42: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 452 | phys_addr_t lmbbase = lmb.memory.region[i].base; > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:453:42: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 453 | phys_size_t lmbsize = lmb.memory.region[i].size; > +(omapl138_lcdk) lib/lmb.c:469:55: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 469 | rgn = lmb_overlaps_region(&lmb.reserved, base, size); > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:472:56: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 472 | if (lmb_add_region(&lmb.reserved, base, > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:477:39: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 477 | res_base = lmb.reserved.region[rgn].base; > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_alloc_addr': > +(omapl138_lcdk) lib/lmb.c:513:39: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 513 | rgn = lmb_overlaps_region(&lmb.memory, base, size); > +(omapl138_lcdk) lib/lmb.c:519:42: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 519 | if (lmb_addrs_overlap(lmb.memory.region[rgn].base, > +(omapl138_lcdk) lib/lmb.c:520:42: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 520 | lmb.memory.region[rgn].size, > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_get_free_size': > +(omapl138_lcdk) lib/lmb.c:537:39: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 537 | rgn = lmb_overlaps_region(&lmb.memory, addr, 1); > +(omapl138_lcdk) lib/lmb.c:539:36: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 539 | for (i = 0; i < lmb.reserved.cnt; i++) { > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:540:39: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 540 | if (addr < lmb.reserved.region[i].base) { > +(omapl138_lcdk) lib/lmb.c:542:43: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 542 | return lmb.reserved.region[i].base - addr; > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:544:32: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 544 | if (lmb.reserved.region[i].base + > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:545:32: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 545 | lmb.reserved.region[i].size > addr) { > +(omapl138_lcdk) lib/lmb.c:551:27: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 551 | return lmb.memory.region[lmb.memory.cnt - 1].base + > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:551:45: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:552:27: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 552 | lmb.memory.region[lmb.memory.cnt - 1].size - addr; > +(omapl138_lcdk) lib/lmb.c:552:45: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_is_reserved_flags': > +(omapl138_lcdk) lib/lmb.c:561:28: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 561 | for (i = 0; i < lmb.reserved.cnt; i++) { > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:562:40: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 562 | phys_addr_t upper = lmb.reserved.region[i].base + > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:563:28: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 563 | lmb.reserved.region[i].size - 1; > +(omapl138_lcdk) lib/lmb.c:564:33: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 564 | if ((addr >= lmb.reserved.region[i].base) && (addr <= upper)) > +(omapl138_lcdk) | ^ > +(omapl138_lcdk) | -> > +(omapl138_lcdk) lib/lmb.c:565:36: error: 'lmb' is a pointer; did you mean to use '->'? > +(omapl138_lcdk) 565 | return (lmb.reserved.region[i].flags & flags) == flags; > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: lib/lmb.o] Error 1 > +(omapl138_lcdk) make[1]: *** [Makefile:1892: lib] Error 2 > +(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:256: spl/lib/lmb.o] Error 1 > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/lib] Error 2 > +(omapl138_lcdk) make[1]: *** [Makefile:2092: spl/u-boot-spl] Error 2 > +(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 > 05: lmb: remove local instances of the lmb structure variable > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_dump_all_force': > -(omapl138_lcdk) lib/lmb.c:64:29: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 64 | lmb_dump_region(&lmb.memory, "memory"); > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:65:29: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 65 | lmb_dump_region(&lmb.reserved, "reserved"); > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_add': > -(omapl138_lcdk) lib/lmb.c:356:39: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 356 | struct lmb_region *_rgn = &lmb.memory; > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_free': > -(omapl138_lcdk) lib/lmb.c:363:38: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 363 | struct lmb_region *rgn = &lmb.reserved; > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_reserve_flags': > -(omapl138_lcdk) lib/lmb.c:414:39: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 414 | struct lmb_region *_rgn = &lmb.reserved; > -(omapl138_lcdk) lib/lmb.c: In function '__lmb_alloc_base': > -(omapl138_lcdk) lib/lmb.c:451:21: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 451 | for (i = lmb.memory.cnt - 1; i >= 0; i--) { > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:452:42: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 452 | phys_addr_t lmbbase = lmb.memory.region[i].base; > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:453:42: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 453 | phys_size_t lmbsize = lmb.memory.region[i].size; > -(omapl138_lcdk) lib/lmb.c:469:55: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 469 | rgn = lmb_overlaps_region(&lmb.reserved, base, size); > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:472:56: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 472 | if (lmb_add_region(&lmb.reserved, base, > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:477:39: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 477 | res_base = lmb.reserved.region[rgn].base; > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_alloc_addr': > -(omapl138_lcdk) lib/lmb.c:513:39: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 513 | rgn = lmb_overlaps_region(&lmb.memory, base, size); > -(omapl138_lcdk) lib/lmb.c:519:42: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 519 | if (lmb_addrs_overlap(lmb.memory.region[rgn].base, > -(omapl138_lcdk) lib/lmb.c:520:42: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 520 | lmb.memory.region[rgn].size, > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_get_free_size': > -(omapl138_lcdk) lib/lmb.c:537:39: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 537 | rgn = lmb_overlaps_region(&lmb.memory, addr, 1); > -(omapl138_lcdk) lib/lmb.c:539:36: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 539 | for (i = 0; i < lmb.reserved.cnt; i++) { > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:540:39: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 540 | if (addr < lmb.reserved.region[i].base) { > -(omapl138_lcdk) lib/lmb.c:542:43: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 542 | return lmb.reserved.region[i].base - addr; > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:544:32: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 544 | if (lmb.reserved.region[i].base + > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:545:32: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 545 | lmb.reserved.region[i].size > addr) { > -(omapl138_lcdk) lib/lmb.c:551:27: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 551 | return lmb.memory.region[lmb.memory.cnt - 1].base + > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:551:45: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:552:27: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 552 | lmb.memory.region[lmb.memory.cnt - 1].size - addr; > -(omapl138_lcdk) lib/lmb.c:552:45: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_is_reserved_flags': > -(omapl138_lcdk) lib/lmb.c:561:28: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 561 | for (i = 0; i < lmb.reserved.cnt; i++) { > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:562:40: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 562 | phys_addr_t upper = lmb.reserved.region[i].base + > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:563:28: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 563 | lmb.reserved.region[i].size - 1; > -(omapl138_lcdk) lib/lmb.c:564:33: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 564 | if ((addr >= lmb.reserved.region[i].base) && (addr <= upper)) > -(omapl138_lcdk) | ^ > -(omapl138_lcdk) | -> > -(omapl138_lcdk) lib/lmb.c:565:36: error: 'lmb' is a pointer; did you mean to use '->'? > -(omapl138_lcdk) 565 | return (lmb.reserved.region[i].flags & flags) == flags; > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: lib/lmb.o] Error 1 > -(omapl138_lcdk) make[1]: *** [Makefile:1892: lib] Error 2 > -(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:256: spl/lib/lmb.o] Error 1 > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/lib] Error 2 > +(omapl138_lcdk) boot/image-board.c: In function 'image_setup_linux': > +(omapl138_lcdk) boot/image-board.c:907:65: error: 'lmb' undeclared (first use in this function) > +(omapl138_lcdk) 907 | ret = image_setup_libfdt(images, *of_flat_tree, lmb); > +(omapl138_lcdk) | ^~~ > +(omapl138_lcdk) boot/image-board.c:907:65: note: each undeclared identifier is reported only once for each function it appears in > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: boot/image-board.o] Error 1 > +(omapl138_lcdk) make[1]: *** [Makefile:1892: boot] Error 2 > +(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:257: spl/boot/image-board.o] Error 1 > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/boot] Error 2 > 06: lmb: pass a flag to image_setup_libfdt() for lmb reservations > arm: omapl138_lcdk > -(omapl138_lcdk) boot/image-board.c: In function 'image_setup_linux': > -(omapl138_lcdk) boot/image-board.c:907:65: error: 'lmb' undeclared (first use in this function) > -(omapl138_lcdk) 907 | ret = image_setup_libfdt(images, *of_flat_tree, lmb); > -(omapl138_lcdk) | ^~~ > -(omapl138_lcdk) boot/image-board.c:907:65: note: each undeclared identifier is reported only once for each function it appears in > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: boot/image-board.o] Error 1 > -(omapl138_lcdk) make[1]: *** [Makefile:1892: boot] Error 2 > -(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:257: spl/boot/image-board.o] Error 1 > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/boot] Error 2 > -(omapl138_lcdk) make[1]: *** [Makefile:2092: spl/u-boot-spl] Error 2 > -(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 > 07: lmb: reserve and add common memory regions post relocation > arm: + omapl138_lcdk > +(omapl138_lcdk) common/board_r.c: In function 'initr_lmb': > +(omapl138_lcdk) common/board_r.c:564:9: error: implicit declaration of function 'lmb_add_memory' [-Werror=implicit-function-declaration] > +(omapl138_lcdk) 564 | lmb_add_memory(gd->bd); > +(omapl138_lcdk) | ^~~~~~~~~~~~~~ > +(omapl138_lcdk) cc1: all warnings being treated as errors > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: common/board_r.o] Error 1 > +(omapl138_lcdk) make[1]: *** [Makefile:1892: common] Error 2 > +(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 > 08: lmb: remove lmb_init_and_reserve_range() function > 09: lmb: replcace the lmb_init_and_reserve() function > arm: omapl138_lcdk > -(omapl138_lcdk) common/board_r.c: In function 'initr_lmb': > -(omapl138_lcdk) common/board_r.c:564:9: error: implicit declaration of function 'lmb_add_memory' [-Werror=implicit-function-declaration] > -(omapl138_lcdk) 564 | lmb_add_memory(gd->bd); > -(omapl138_lcdk) | ^~~~~~~~~~~~~~ > -(omapl138_lcdk) cc1: all warnings being treated as errors > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: common/board_r.o] Error 1 > -(omapl138_lcdk) make[1]: *** [Makefile:1892: common] Error 2 > -(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 > 10: lmb: allow for resizing lmb regions > arm: (for 1/1 boards) all +224.0 text +224.0 > omapl138_lcdk : all +224 text +224 > u-boot: add: 0/0, grow: 1/0 bytes: 224/0 (224) > function old new delta > lmb_add_region_flags 416 640 +224 > 11: event: add events to notify memory map changes > 12: lib: Kconfig: add a config symbol for getting memory map updates > 13: add a function to check if an address is in RAM memory > 14: efi_memory: notify of any changes to the EFI memory map > 15: lmb: notify of any changes to the LMB memory map > arm: (for 1/1 boards) all +8.0 text +8.0 > omapl138_lcdk : all +8 text +8 > u-boot: add: 0/0, grow: 2/0 bytes: 12/0 (12) > function old new delta > lmb_reserve_flags 32 40 +8 > lmb_free 192 196 +4 > 16: efi_memory: add an event handler to update memory map > 17: lmb: add an event handler to update memory map > arm: (for 1/1 boards) all +349.0 rodata +61.0 text +288.0 > omapl138_lcdk : all +349 rodata +61 text +288 > u-boot: add: 3/0, grow: 3/0 bytes: 232/0 (232) > function old new delta > event_notify - 104 +104 > initcall_run_list 96 144 +48 > image_setup_libfdt 236 284 +48 > event_notify_null - 18 +18 > event_type_name - 8 +8 > run_main_loop 10 16 +6 > 18: lmb: remove call to efi_lmb_reserve() > 19: sandbox: iommu: remove lmb allocation in the driver > 20: zynq: lmb: do not add to lmb map before relocation > 21: test: cedit: use allocated address for reading file > 22: test: event: update the expected event dump output > 23: test: lmb: run the LMB tests only on sandbox > 24: test: lmb: initialise the lmb structure before tests > 25: test: lmb: add a test case for checking overlapping region add > 26: test: lmb: adjust the test case to handle overlapping regions > 27: test: lmb: run lmb tests only manually > 28: test: bdinfo: dump the global LMB memory map > 29: cmd: bdinfo: only dump the current LMB memory > arm: (for 1/1 boards) all -8.0 text -8.0 > omapl138_lcdk : all -8 text -8 > u-boot: add: 0/0, grow: 0/-1 bytes: 0/-8 (-8) > function old new delta > do_bdinfo 472 464 -8 > 30: temp: mx6sabresd: bump up the size limit of the board > > So my first thought is, do we really need the event notifier framework > in the case where it's NOT also using EFI_LOADER? Or is perhaps that > Kconfig logic not quite right? So, I had actually tried putting all the notification code under the newly introduced config symbol, but I get build warnings on sandbox spl and sandbox vpl builds, which result in CI failures. I would have thought that having the function call under a CONFIG_IS_ENABLED check would result in the linker to discard the function call. But that is not happening. I will check if this can be handled by introducing SPL, TPL and VPL variants of this config. -sughosh > > -- > Tom ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 00/31] Make U-Boot memory reservations coherent 2024-06-11 9:01 ` Sughosh Ganu @ 2024-06-11 14:39 ` Tom Rini 0 siblings, 0 replies; 127+ messages in thread From: Tom Rini @ 2024-06-11 14:39 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Ilias Apalodimas, Heinrich Schuchardt, Simon Glass, Marek Vasut, Mark Kettenis, Fabio Estevam [-- Attachment #1: Type: text/plain, Size: 28823 bytes --] On Tue, Jun 11, 2024 at 02:31:27PM +0530, Sughosh Ganu wrote: > On Tue, 11 Jun 2024 at 02:35, Tom Rini <trini@konsulko.com> wrote: > > > > On Sat, Jun 08, 2024 at 12:22:09AM +0530, Sughosh Ganu wrote: > > > > > The aim of this patch series is to fix the current state of > > > incoherence between modules when it comes to memory usage. The primary > > > issue that this series is trying to fix is that the EFI memory module > > > which is responsible for allocating and freeing memory, does not have > > > any visibility of the memory that is being used by the LMB > > > module. This is further complicated by the fact that the LMB > > > allocations are caller specific -- the LMB memory map is not global > > > nor persistent. This means that the memory "allocated" by the LMB > > > module might be relevant only for a given function. Hence one of the > > > requirements for making the memory usage visible across modules is to > > > make LMB allocations persistent and global, and then have means to > > > communicate the use of memory across modules. > > > > > > The first set of patches in this series work on making the LMB memory > > > map persistent and global. This is being done keeping in mind the > > > usage of LMB memory by platforms where the same memory region can be > > > used to load multiple different images. What is not allowed is to > > > overwrite memory that has been allocated by the other module, > > > currently the EFI memory module. This is being achieved by introducing > > > a new flag, LMB_NOOVERWRITE, which represents memory which cannot be > > > re-requested once allocated. > > > > > > The second set of patches are then introducing a notification > > > mechanism to indicate any changes to a respective module's memory > > > map. This way, any memory allocation/reservation by a module gets > > > notified to any interested listners, who then update their memory map > > > accordingly, thus keeping memory usage coherent. > > > > > > Todo's > > > ------ > > > I have run these patches through CI, but the LMB unit tests need an > > > overhaul. I have currently marked these tests for manual run, as > > > running these would obviously tamper the LMB memory map, thus > > > affecting subsequent tests. The current set of LMB tests are written > > > with the assumption of local LMB memory maps. This needs to be > > > reworked. > > > > > > Secondly, there needs to be a test written for testing the various > > > scenarios of memory being allocated and freed by different modules, > > > namely LMB and EFI. I have written a couple of commands for testing > > > the changes that I have made -- I have also included these temporary > > > commands to assist anyone who might want to test these changes. But I > > > will be working on adding a more comprehensive test. > > > > > > Lastly, as the series touches common code, there is obviously an > > > increase in the size of the image, moreover since the LMB memory is > > > now persistent, and the variables do not reside on the stack. I want > > > to check if there can be ways of decreasing the size impact of the > > > changes. > > > > So, I think you made some changes between your last CI run and posting? > > A ton of platforms (basically anything with EFI_LOADER disabled) fail to > > build now because the two "temp" commits at the end of the series are > > always enabled. I took those commits out and ran my world build size > > check tests and the results are at: > > https://gist.github.com/trini/d42bd392463c39766a5f872c190ccf27 > > > > And 64bit ARM looks very reasonable, but I wonder if we can improve the > > 32bit ARM results? > > > > I also did an every commit run for a 32bit ARM board without EFI_LOADER > > (which is going to be the case for size constrained systems) and see > > that the series isn't bisect'able to start with, so please fix that for > > the next go-round. That said: > > Yes, I should have mentioned it in the cover letter about issues with > bisectability, primarily because some code under boot/ uses the lmb > API's unconditionally, without having a check for LMB being enabled or > not. Yeah, today at least LMB functionally should be a def_bool y instead of a choice. > > Summary of 30 commits for 1 boards (1 thread, 12 jobs per thread) > > 01: Added arm64 assembly for examples/api crt0 > > 02: lmb: remove the unused lmb_is_reserved() function > > 03: lmb: staticize __lmb_alloc_base() > > arm: (for 1/1 boards) all -16.0 text -16.0 > > omapl138_lcdk : all -16 text -16 > > u-boot: add: 0/-1, grow: 1/0 bytes: 172/-186 (-14) > > function old new delta > > lmb_alloc_base 40 212 +172 > > __lmb_alloc_base 186 - -186 > > 04: lmb: make the lmb reservations persistent > > arm: + omapl138_lcdk > > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_dump_all_force': > > +(omapl138_lcdk) lib/lmb.c:64:29: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 64 | lmb_dump_region(&lmb.memory, "memory"); > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:65:29: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 65 | lmb_dump_region(&lmb.reserved, "reserved"); > > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_add': > > +(omapl138_lcdk) lib/lmb.c:356:39: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 356 | struct lmb_region *_rgn = &lmb.memory; > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_free': > > +(omapl138_lcdk) lib/lmb.c:363:38: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 363 | struct lmb_region *rgn = &lmb.reserved; > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_reserve_flags': > > +(omapl138_lcdk) lib/lmb.c:414:39: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 414 | struct lmb_region *_rgn = &lmb.reserved; > > +(omapl138_lcdk) lib/lmb.c: In function '__lmb_alloc_base': > > +(omapl138_lcdk) lib/lmb.c:451:21: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 451 | for (i = lmb.memory.cnt - 1; i >= 0; i--) { > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:452:42: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 452 | phys_addr_t lmbbase = lmb.memory.region[i].base; > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:453:42: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 453 | phys_size_t lmbsize = lmb.memory.region[i].size; > > +(omapl138_lcdk) lib/lmb.c:469:55: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 469 | rgn = lmb_overlaps_region(&lmb.reserved, base, size); > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:472:56: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 472 | if (lmb_add_region(&lmb.reserved, base, > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:477:39: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 477 | res_base = lmb.reserved.region[rgn].base; > > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_alloc_addr': > > +(omapl138_lcdk) lib/lmb.c:513:39: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 513 | rgn = lmb_overlaps_region(&lmb.memory, base, size); > > +(omapl138_lcdk) lib/lmb.c:519:42: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 519 | if (lmb_addrs_overlap(lmb.memory.region[rgn].base, > > +(omapl138_lcdk) lib/lmb.c:520:42: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 520 | lmb.memory.region[rgn].size, > > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_get_free_size': > > +(omapl138_lcdk) lib/lmb.c:537:39: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 537 | rgn = lmb_overlaps_region(&lmb.memory, addr, 1); > > +(omapl138_lcdk) lib/lmb.c:539:36: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 539 | for (i = 0; i < lmb.reserved.cnt; i++) { > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:540:39: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 540 | if (addr < lmb.reserved.region[i].base) { > > +(omapl138_lcdk) lib/lmb.c:542:43: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 542 | return lmb.reserved.region[i].base - addr; > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:544:32: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 544 | if (lmb.reserved.region[i].base + > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:545:32: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 545 | lmb.reserved.region[i].size > addr) { > > +(omapl138_lcdk) lib/lmb.c:551:27: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 551 | return lmb.memory.region[lmb.memory.cnt - 1].base + > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:551:45: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:552:27: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 552 | lmb.memory.region[lmb.memory.cnt - 1].size - addr; > > +(omapl138_lcdk) lib/lmb.c:552:45: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) lib/lmb.c: In function 'lmb_is_reserved_flags': > > +(omapl138_lcdk) lib/lmb.c:561:28: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 561 | for (i = 0; i < lmb.reserved.cnt; i++) { > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:562:40: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 562 | phys_addr_t upper = lmb.reserved.region[i].base + > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:563:28: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 563 | lmb.reserved.region[i].size - 1; > > +(omapl138_lcdk) lib/lmb.c:564:33: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 564 | if ((addr >= lmb.reserved.region[i].base) && (addr <= upper)) > > +(omapl138_lcdk) | ^ > > +(omapl138_lcdk) | -> > > +(omapl138_lcdk) lib/lmb.c:565:36: error: 'lmb' is a pointer; did you mean to use '->'? > > +(omapl138_lcdk) 565 | return (lmb.reserved.region[i].flags & flags) == flags; > > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: lib/lmb.o] Error 1 > > +(omapl138_lcdk) make[1]: *** [Makefile:1892: lib] Error 2 > > +(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:256: spl/lib/lmb.o] Error 1 > > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/lib] Error 2 > > +(omapl138_lcdk) make[1]: *** [Makefile:2092: spl/u-boot-spl] Error 2 > > +(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 > > 05: lmb: remove local instances of the lmb structure variable > > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_dump_all_force': > > -(omapl138_lcdk) lib/lmb.c:64:29: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 64 | lmb_dump_region(&lmb.memory, "memory"); > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:65:29: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 65 | lmb_dump_region(&lmb.reserved, "reserved"); > > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_add': > > -(omapl138_lcdk) lib/lmb.c:356:39: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 356 | struct lmb_region *_rgn = &lmb.memory; > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_free': > > -(omapl138_lcdk) lib/lmb.c:363:38: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 363 | struct lmb_region *rgn = &lmb.reserved; > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_reserve_flags': > > -(omapl138_lcdk) lib/lmb.c:414:39: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 414 | struct lmb_region *_rgn = &lmb.reserved; > > -(omapl138_lcdk) lib/lmb.c: In function '__lmb_alloc_base': > > -(omapl138_lcdk) lib/lmb.c:451:21: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 451 | for (i = lmb.memory.cnt - 1; i >= 0; i--) { > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:452:42: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 452 | phys_addr_t lmbbase = lmb.memory.region[i].base; > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:453:42: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 453 | phys_size_t lmbsize = lmb.memory.region[i].size; > > -(omapl138_lcdk) lib/lmb.c:469:55: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 469 | rgn = lmb_overlaps_region(&lmb.reserved, base, size); > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:472:56: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 472 | if (lmb_add_region(&lmb.reserved, base, > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:477:39: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 477 | res_base = lmb.reserved.region[rgn].base; > > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_alloc_addr': > > -(omapl138_lcdk) lib/lmb.c:513:39: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 513 | rgn = lmb_overlaps_region(&lmb.memory, base, size); > > -(omapl138_lcdk) lib/lmb.c:519:42: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 519 | if (lmb_addrs_overlap(lmb.memory.region[rgn].base, > > -(omapl138_lcdk) lib/lmb.c:520:42: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 520 | lmb.memory.region[rgn].size, > > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_get_free_size': > > -(omapl138_lcdk) lib/lmb.c:537:39: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 537 | rgn = lmb_overlaps_region(&lmb.memory, addr, 1); > > -(omapl138_lcdk) lib/lmb.c:539:36: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 539 | for (i = 0; i < lmb.reserved.cnt; i++) { > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:540:39: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 540 | if (addr < lmb.reserved.region[i].base) { > > -(omapl138_lcdk) lib/lmb.c:542:43: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 542 | return lmb.reserved.region[i].base - addr; > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:544:32: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 544 | if (lmb.reserved.region[i].base + > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:545:32: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 545 | lmb.reserved.region[i].size > addr) { > > -(omapl138_lcdk) lib/lmb.c:551:27: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 551 | return lmb.memory.region[lmb.memory.cnt - 1].base + > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:551:45: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:552:27: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 552 | lmb.memory.region[lmb.memory.cnt - 1].size - addr; > > -(omapl138_lcdk) lib/lmb.c:552:45: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) lib/lmb.c: In function 'lmb_is_reserved_flags': > > -(omapl138_lcdk) lib/lmb.c:561:28: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 561 | for (i = 0; i < lmb.reserved.cnt; i++) { > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:562:40: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 562 | phys_addr_t upper = lmb.reserved.region[i].base + > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:563:28: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 563 | lmb.reserved.region[i].size - 1; > > -(omapl138_lcdk) lib/lmb.c:564:33: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 564 | if ((addr >= lmb.reserved.region[i].base) && (addr <= upper)) > > -(omapl138_lcdk) | ^ > > -(omapl138_lcdk) | -> > > -(omapl138_lcdk) lib/lmb.c:565:36: error: 'lmb' is a pointer; did you mean to use '->'? > > -(omapl138_lcdk) 565 | return (lmb.reserved.region[i].flags & flags) == flags; > > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: lib/lmb.o] Error 1 > > -(omapl138_lcdk) make[1]: *** [Makefile:1892: lib] Error 2 > > -(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:256: spl/lib/lmb.o] Error 1 > > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/lib] Error 2 > > +(omapl138_lcdk) boot/image-board.c: In function 'image_setup_linux': > > +(omapl138_lcdk) boot/image-board.c:907:65: error: 'lmb' undeclared (first use in this function) > > +(omapl138_lcdk) 907 | ret = image_setup_libfdt(images, *of_flat_tree, lmb); > > +(omapl138_lcdk) | ^~~ > > +(omapl138_lcdk) boot/image-board.c:907:65: note: each undeclared identifier is reported only once for each function it appears in > > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: boot/image-board.o] Error 1 > > +(omapl138_lcdk) make[1]: *** [Makefile:1892: boot] Error 2 > > +(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:257: spl/boot/image-board.o] Error 1 > > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/boot] Error 2 > > 06: lmb: pass a flag to image_setup_libfdt() for lmb reservations > > arm: omapl138_lcdk > > -(omapl138_lcdk) boot/image-board.c: In function 'image_setup_linux': > > -(omapl138_lcdk) boot/image-board.c:907:65: error: 'lmb' undeclared (first use in this function) > > -(omapl138_lcdk) 907 | ret = image_setup_libfdt(images, *of_flat_tree, lmb); > > -(omapl138_lcdk) | ^~~ > > -(omapl138_lcdk) boot/image-board.c:907:65: note: each undeclared identifier is reported only once for each function it appears in > > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: boot/image-board.o] Error 1 > > -(omapl138_lcdk) make[1]: *** [Makefile:1892: boot] Error 2 > > -(omapl138_lcdk) make[3]: *** [scripts/Makefile.build:257: spl/boot/image-board.o] Error 1 > > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.spl:538: spl/boot] Error 2 > > -(omapl138_lcdk) make[1]: *** [Makefile:2092: spl/u-boot-spl] Error 2 > > -(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 > > 07: lmb: reserve and add common memory regions post relocation > > arm: + omapl138_lcdk > > +(omapl138_lcdk) common/board_r.c: In function 'initr_lmb': > > +(omapl138_lcdk) common/board_r.c:564:9: error: implicit declaration of function 'lmb_add_memory' [-Werror=implicit-function-declaration] > > +(omapl138_lcdk) 564 | lmb_add_memory(gd->bd); > > +(omapl138_lcdk) | ^~~~~~~~~~~~~~ > > +(omapl138_lcdk) cc1: all warnings being treated as errors > > +(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: common/board_r.o] Error 1 > > +(omapl138_lcdk) make[1]: *** [Makefile:1892: common] Error 2 > > +(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 > > 08: lmb: remove lmb_init_and_reserve_range() function > > 09: lmb: replcace the lmb_init_and_reserve() function > > arm: omapl138_lcdk > > -(omapl138_lcdk) common/board_r.c: In function 'initr_lmb': > > -(omapl138_lcdk) common/board_r.c:564:9: error: implicit declaration of function 'lmb_add_memory' [-Werror=implicit-function-declaration] > > -(omapl138_lcdk) 564 | lmb_add_memory(gd->bd); > > -(omapl138_lcdk) | ^~~~~~~~~~~~~~ > > -(omapl138_lcdk) cc1: all warnings being treated as errors > > -(omapl138_lcdk) make[2]: *** [scripts/Makefile.build:256: common/board_r.o] Error 1 > > -(omapl138_lcdk) make[1]: *** [Makefile:1892: common] Error 2 > > -(omapl138_lcdk) make: *** [Makefile:177: sub-make] Error 2 > > 10: lmb: allow for resizing lmb regions > > arm: (for 1/1 boards) all +224.0 text +224.0 > > omapl138_lcdk : all +224 text +224 > > u-boot: add: 0/0, grow: 1/0 bytes: 224/0 (224) > > function old new delta > > lmb_add_region_flags 416 640 +224 > > 11: event: add events to notify memory map changes > > 12: lib: Kconfig: add a config symbol for getting memory map updates > > 13: add a function to check if an address is in RAM memory > > 14: efi_memory: notify of any changes to the EFI memory map > > 15: lmb: notify of any changes to the LMB memory map > > arm: (for 1/1 boards) all +8.0 text +8.0 > > omapl138_lcdk : all +8 text +8 > > u-boot: add: 0/0, grow: 2/0 bytes: 12/0 (12) > > function old new delta > > lmb_reserve_flags 32 40 +8 > > lmb_free 192 196 +4 > > 16: efi_memory: add an event handler to update memory map > > 17: lmb: add an event handler to update memory map > > arm: (for 1/1 boards) all +349.0 rodata +61.0 text +288.0 > > omapl138_lcdk : all +349 rodata +61 text +288 > > u-boot: add: 3/0, grow: 3/0 bytes: 232/0 (232) > > function old new delta > > event_notify - 104 +104 > > initcall_run_list 96 144 +48 > > image_setup_libfdt 236 284 +48 > > event_notify_null - 18 +18 > > event_type_name - 8 +8 > > run_main_loop 10 16 +6 > > 18: lmb: remove call to efi_lmb_reserve() > > 19: sandbox: iommu: remove lmb allocation in the driver > > 20: zynq: lmb: do not add to lmb map before relocation > > 21: test: cedit: use allocated address for reading file > > 22: test: event: update the expected event dump output > > 23: test: lmb: run the LMB tests only on sandbox > > 24: test: lmb: initialise the lmb structure before tests > > 25: test: lmb: add a test case for checking overlapping region add > > 26: test: lmb: adjust the test case to handle overlapping regions > > 27: test: lmb: run lmb tests only manually > > 28: test: bdinfo: dump the global LMB memory map > > 29: cmd: bdinfo: only dump the current LMB memory > > arm: (for 1/1 boards) all -8.0 text -8.0 > > omapl138_lcdk : all -8 text -8 > > u-boot: add: 0/0, grow: 0/-1 bytes: 0/-8 (-8) > > function old new delta > > do_bdinfo 472 464 -8 > > 30: temp: mx6sabresd: bump up the size limit of the board > > > > So my first thought is, do we really need the event notifier framework > > in the case where it's NOT also using EFI_LOADER? Or is perhaps that > > Kconfig logic not quite right? > > So, I had actually tried putting all the notification code under the > newly introduced config symbol, but I get build warnings on sandbox > spl and sandbox vpl builds, which result in CI failures. I would have > thought that having the function call under a CONFIG_IS_ENABLED check > would result in the linker to discard the function call. But that is > not happening. I will check if this can be handled by introducing SPL, > TPL and VPL variants of this config. It's also possible that some stages aren't passing -ffunction-sections/-fdata-sections/--gc-sections ? A testing option would be to enable (and be sure it's used) LTO ? -- Tom [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 659 bytes --] ^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [RFC PATCH 00/31] Make U-Boot memory reservations coherent 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu ` (31 preceding siblings ...) 2024-06-10 21:05 ` [RFC PATCH 00/31] Make U-Boot memory reservations coherent Tom Rini @ 2024-06-11 18:52 ` Simon Glass 32 siblings, 0 replies; 127+ messages in thread From: Simon Glass @ 2024-06-11 18:52 UTC (permalink / raw) To: Sughosh Ganu Cc: u-boot, Tom Rini, Ilias Apalodimas, Heinrich Schuchardt, Marek Vasut, Mark Kettenis, Fabio Estevam Hi Sughosh, On Fri, 7 Jun 2024 at 12:53, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > > The aim of this patch series is to fix the current state of > incoherence between modules when it comes to memory usage. The primary > issue that this series is trying to fix is that the EFI memory module > which is responsible for allocating and freeing memory, does not have > any visibility of the memory that is being used by the LMB > module. This is further complicated by the fact that the LMB > allocations are caller specific -- the LMB memory map is not global > nor persistent. This means that the memory "allocated" by the LMB > module might be relevant only for a given function. Hence one of the > requirements for making the memory usage visible across modules is to > make LMB allocations persistent and global, and then have means to > communicate the use of memory across modules. > > The first set of patches in this series work on making the LMB memory > map persistent and global. For the purposes of testing at least, it should be possible to create a new LMB. You could have a global_data pointer to the current (global) one, like we do with driver model. > This is being done keeping in mind the > usage of LMB memory by platforms where the same memory region can be > used to load multiple different images. What is not allowed is to > overwrite memory that has been allocated by the other module, > currently the EFI memory module. This is being achieved by introducing > a new flag, LMB_NOOVERWRITE, which represents memory which cannot be > re-requested once allocated. > > The second set of patches are then introducing a notification > mechanism to indicate any changes to a respective module's memory > map. This way, any memory allocation/reservation by a module gets > notified to any interested listners, who then update their memory map > accordingly, thus keeping memory usage coherent. What is the need for this listener? > > Todo's > ------ > I have run these patches through CI, but the LMB unit tests need an > overhaul. I have currently marked these tests for manual run, as > running these would obviously tamper the LMB memory map, thus > affecting subsequent tests. The current set of LMB tests are written > with the assumption of local LMB memory maps. This needs to be > reworked. See above > > Secondly, there needs to be a test written for testing the various > scenarios of memory being allocated and freed by different modules, > namely LMB and EFI. I have written a couple of commands for testing > the changes that I have made -- I have also included these temporary > commands to assist anyone who might want to test these changes. But I > will be working on adding a more comprehensive test. > > Lastly, as the series touches common code, there is obviously an > increase in the size of the image, moreover since the LMB memory is > now persistent, and the variables do not reside on the stack. I want > to check if there can be ways of decreasing the size impact of the > changes. Perhaps some part of the feature set could be made optional? Regards, Simon > > > Sughosh Ganu (31): > lmb: remove the unused lmb_is_reserved() function > lmb: staticize __lmb_alloc_base() > lmb: make the lmb reservations persistent > lmb: remove local instances of the lmb structure variable > lmb: pass a flag to image_setup_libfdt() for lmb reservations > lmb: reserve and add common memory regions post relocation > lmb: remove lmb_init_and_reserve_range() function > lmb: replcace the lmb_init_and_reserve() function > lmb: allow for resizing lmb regions > event: add events to notify memory map changes > lib: Kconfig: add a config symbol for getting memory map updates > add a function to check if an address is in RAM memory > efi_memory: notify of any changes to the EFI memory map > lmb: notify of any changes to the LMB memory map > efi_memory: add an event handler to update memory map > lmb: add an event handler to update memory map > lmb: remove call to efi_lmb_reserve() > sandbox: iommu: remove lmb allocation in the driver > zynq: lmb: do not add to lmb map before relocation > test: cedit: use allocated address for reading file > test: event: update the expected event dump output > test: lmb: run the LMB tests only on sandbox > test: lmb: initialise the lmb structure before tests > test: lmb: add a test case for checking overlapping region add > test: lmb: adjust the test case to handle overlapping regions > test: lmb: run lmb tests only manually > test: bdinfo: dump the global LMB memory map > cmd: bdinfo: only dump the current LMB memory > temp: mx6sabresd: bump up the size limit of the board > temp: cmd: efi_mem: add a command to test efi alloc/free > temp: cmd: efi: add a command to dump EFI memory map > > arch/arc/lib/cache.c | 4 +- > arch/arm/lib/stack.c | 4 +- > arch/arm/mach-apple/board.c | 17 +- > arch/arm/mach-snapdragon/board.c | 17 +- > arch/arm/mach-stm32mp/dram_init.c | 8 +- > arch/arm/mach-stm32mp/stm32mp1/cpu.c | 6 +- > arch/m68k/lib/bootm.c | 7 +- > arch/microblaze/lib/bootm.c | 4 +- > arch/mips/lib/bootm.c | 11 +- > arch/nios2/lib/bootm.c | 4 +- > arch/powerpc/cpu/mpc85xx/mp.c | 4 +- > arch/powerpc/include/asm/mp.h | 4 +- > arch/powerpc/lib/bootm.c | 14 +- > arch/riscv/lib/bootm.c | 4 +- > arch/sandbox/cpu/cpu.c | 5 + > arch/sh/lib/bootm.c | 4 +- > arch/x86/lib/bootm.c | 4 +- > arch/xtensa/lib/bootm.c | 4 +- > board/xilinx/common/board.c | 33 -- > boot/bootm.c | 26 +- > boot/bootm_os.c | 5 +- > boot/image-board.c | 34 +-- > boot/image-fdt.c | 36 +-- > cmd/Makefile | 2 + > cmd/bdinfo.c | 5 +- > cmd/booti.c | 2 +- > cmd/bootz.c | 2 +- > cmd/efi_map_dump.c | 28 ++ > cmd/efi_memory.c | 155 ++++++++++ > cmd/elf.c | 2 +- > cmd/load.c | 7 +- > common/board_r.c | 20 ++ > common/event.c | 4 + > configs/mx6sabresd_defconfig | 2 +- > drivers/iommu/apple_dart.c | 8 +- > drivers/iommu/sandbox_iommu.c | 17 +- > fs/fs.c | 7 +- > include/efi_loader.h | 2 + > include/event.h | 28 ++ > include/image.h | 27 +- > include/lmb.h | 96 +++--- > lib/Kconfig | 10 + > lib/efi_loader/efi_dt_fixup.c | 2 +- > lib/efi_loader/efi_helper.c | 2 +- > lib/efi_loader/efi_memory.c | 127 +++++++- > lib/lmb.c | 442 ++++++++++++++++++--------- > net/tftp.c | 5 +- > net/wget.c | 5 +- > test/boot/cedit.c | 5 +- > test/cmd/bdinfo.c | 22 +- > test/lib/Makefile | 2 +- > test/lib/lmb.c | 274 +++++++++-------- > test/py/tests/test_event_dump.py | 2 + > 53 files changed, 1001 insertions(+), 570 deletions(-) > create mode 100644 cmd/efi_map_dump.c > create mode 100644 cmd/efi_memory.c > > -- > 2.34.1 > > ^ permalink raw reply [flat|nested] 127+ messages in thread
end of thread, other threads:[~2024-06-19 3:03 UTC | newest] Thread overview: 127+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-06-07 18:52 [RFC PATCH 00/31] Make U-Boot memory reservations coherent Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 01/31] lmb: remove the unused lmb_is_reserved() function Sughosh Ganu 2024-06-10 9:33 ` Ilias Apalodimas 2024-06-07 18:52 ` [RFC PATCH 02/31] lmb: staticize __lmb_alloc_base() Sughosh Ganu 2024-06-10 9:37 ` Ilias Apalodimas 2024-06-07 18:52 ` [RFC PATCH 03/31] lmb: make the lmb reservations persistent Sughosh Ganu 2024-06-10 21:17 ` Ilias Apalodimas 2024-06-10 11:23 ` Heinrich Schuchardt 2024-06-10 16:55 ` Tom Rini 2024-06-11 18:52 ` Simon Glass 2024-06-07 18:52 ` [RFC PATCH 04/31] lmb: remove local instances of the lmb structure variable Sughosh Ganu 2024-06-11 18:52 ` Simon Glass 2024-06-11 21:01 ` Tom Rini 2024-06-11 22:08 ` Simon Glass 2024-06-11 22:55 ` Tom Rini 2024-06-12 2:41 ` Simon Glass 2024-06-12 5:41 ` Ilias Apalodimas 2024-06-12 6:13 ` Heinrich Schuchardt 2024-06-12 17:22 ` Tom Rini 2024-06-12 20:24 ` Simon Glass 2024-06-12 21:40 ` Tom Rini 2024-06-13 15:22 ` Simon Glass 2024-06-13 15:42 ` Tom Rini 2024-06-13 16:59 ` Simon Glass 2024-06-13 17:27 ` Heinrich Schuchardt 2024-06-13 18:17 ` Sughosh Ganu 2024-06-13 19:06 ` Simon Glass 2024-06-13 19:05 ` Simon Glass 2024-06-13 20:11 ` Heinrich Schuchardt 2024-06-14 5:58 ` Ilias Apalodimas 2024-06-19 3:01 ` Simon Glass 2024-06-19 3:03 ` Simon Glass 2024-06-13 20:06 ` Tom Rini 2024-06-07 18:52 ` [RFC PATCH 05/31] lmb: pass a flag to image_setup_libfdt() for lmb reservations Sughosh Ganu 2024-06-10 17:12 ` Tom Rini 2024-06-07 18:52 ` [RFC PATCH 06/31] lmb: reserve and add common memory regions post relocation Sughosh Ganu 2024-06-10 17:30 ` Tom Rini 2024-06-07 18:52 ` [RFC PATCH 07/31] lmb: remove lmb_init_and_reserve_range() function Sughosh Ganu 2024-06-10 17:30 ` Tom Rini 2024-06-10 21:42 ` Ilias Apalodimas 2024-06-07 18:52 ` [RFC PATCH 08/31] lmb: replcace the lmb_init_and_reserve() function Sughosh Ganu 2024-06-10 17:31 ` Tom Rini 2024-06-11 8:50 ` Sughosh Ganu 2024-06-11 13:57 ` Tom Rini 2024-06-07 18:52 ` [RFC PATCH 09/31] lmb: allow for resizing lmb regions Sughosh Ganu 2024-06-10 12:03 ` Ilias Apalodimas 2024-06-10 12:20 ` Sughosh Ganu 2024-06-10 12:47 ` Ilias Apalodimas 2024-06-10 12:57 ` Sughosh Ganu 2024-06-10 14:21 ` Ilias Apalodimas 2024-06-10 14:33 ` Sughosh Ganu 2024-06-10 12:54 ` Heinrich Schuchardt 2024-06-10 13:01 ` Sughosh Ganu 2024-06-11 9:17 ` Heinrich Schuchardt 2024-06-11 9:50 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 10/31] event: add events to notify memory map changes Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 11/31] lib: Kconfig: add a config symbol for getting memory map updates Sughosh Ganu 2024-06-08 3:53 ` Heinrich Schuchardt 2024-06-08 4:34 ` Heinrich Schuchardt 2024-06-10 11:44 ` Ilias Apalodimas 2024-06-10 11:47 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 12/31] add a function to check if an address is in RAM memory Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 13/31] efi_memory: notify of any changes to the EFI memory map Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 14/31] lmb: notify of any changes to the LMB " Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 15/31] efi_memory: add an event handler to update " Sughosh Ganu 2024-06-10 12:09 ` Ilias Apalodimas 2024-06-10 12:25 ` Sughosh Ganu 2024-06-10 14:17 ` Ilias Apalodimas 2024-06-10 14:52 ` Sughosh Ganu 2024-06-10 14:54 ` Sughosh Ganu 2024-06-11 6:19 ` Ilias Apalodimas 2024-06-10 15:12 ` Heinrich Schuchardt 2024-06-10 15:42 ` Sughosh Ganu 2024-06-10 15:54 ` Simon Glass 2024-06-12 6:45 ` Ilias Apalodimas 2024-06-12 7:11 ` Sughosh Ganu 2024-06-11 10:17 ` Heinrich Schuchardt 2024-06-11 10:27 ` Sughosh Ganu 2024-06-11 14:36 ` Tom Rini 2024-06-11 18:52 ` Simon Glass 2024-06-11 21:01 ` Tom Rini 2024-06-11 22:22 ` Simon Glass 2024-06-11 22:54 ` Tom Rini 2024-06-12 2:42 ` Simon Glass 2024-06-12 5:48 ` Ilias Apalodimas 2024-06-12 6:20 ` Sughosh Ganu 2024-06-12 20:24 ` Simon Glass 2024-06-12 6:06 ` Heinrich Schuchardt 2024-06-12 20:24 ` Simon Glass 2024-06-07 18:52 ` [RFC PATCH 16/31] lmb: " Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 17/31] lmb: remove call to efi_lmb_reserve() Sughosh Ganu 2024-06-10 11:46 ` Ilias Apalodimas 2024-06-11 9:11 ` Heinrich Schuchardt 2024-06-11 9:49 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 18/31] sandbox: iommu: remove lmb allocation in the driver Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 19/31] zynq: lmb: do not add to lmb map before relocation Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 20/31] test: cedit: use allocated address for reading file Sughosh Ganu 2024-06-11 18:52 ` Simon Glass 2024-06-07 18:52 ` [RFC PATCH 21/31] test: event: update the expected event dump output Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 22/31] test: lmb: run the LMB tests only on sandbox Sughosh Ganu 2024-06-10 17:44 ` Tom Rini 2024-06-11 8:55 ` Sughosh Ganu 2024-06-11 9:56 ` Heinrich Schuchardt 2024-06-11 10:09 ` Sughosh Ganu 2024-06-11 14:05 ` Tom Rini 2024-06-11 14:06 ` Ilias Apalodimas 2024-06-07 18:52 ` [RFC PATCH 23/31] test: lmb: initialise the lmb structure before tests Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 24/31] test: lmb: add a test case for checking overlapping region add Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 25/31] test: lmb: adjust the test case to handle overlapping regions Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 26/31] test: lmb: run lmb tests only manually Sughosh Ganu 2024-06-08 4:39 ` Heinrich Schuchardt 2024-06-10 6:22 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 27/31] test: bdinfo: dump the global LMB memory map Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 28/31] cmd: bdinfo: only dump the current LMB memory Sughosh Ganu 2024-06-08 3:59 ` Heinrich Schuchardt 2024-06-10 11:42 ` Ilias Apalodimas 2024-06-07 18:52 ` [RFC PATCH 29/31] temp: mx6sabresd: bump up the size limit of the board Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 30/31] temp: cmd: efi_mem: add a command to test efi alloc/free Sughosh Ganu 2024-06-08 3:37 ` Heinrich Schuchardt 2024-06-10 6:44 ` Sughosh Ganu 2024-06-07 18:52 ` [RFC PATCH 31/31] temp: cmd: efi: add a command to dump EFI memory map Sughosh Ganu 2024-06-08 3:28 ` Heinrich Schuchardt 2024-06-10 6:45 ` Sughosh Ganu 2024-06-10 21:05 ` [RFC PATCH 00/31] Make U-Boot memory reservations coherent Tom Rini 2024-06-11 9:01 ` Sughosh Ganu 2024-06-11 14:39 ` Tom Rini 2024-06-11 18:52 ` Simon Glass
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox