Message ID | 20241025111411.165904-3-sughosh.ganu@linaro.org |
---|---|
State | New |
Headers | show |
Series | Add pmem node for preserving distro ISO's | expand |
+CC Anton On Fri, 25 Oct 2024 at 14:14, Sughosh Ganu <sughosh.ganu@linaro.org> wrote: > > From: Ilias Apalodimas <ilias.apalodimas@linaro.org> > > With upcoming changes supporting pmem nodes, we need to ommit the > pmem area rfom the EFI memory map. Add a function to do that > > Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > --- > include/efi_loader.h | 11 +++++--- > lib/efi_loader/efi_memory.c | 51 +++++++++++++++++++++++++++---------- > lib/lmb.c | 4 +-- > 3 files changed, 47 insertions(+), 19 deletions(-) > > diff --git a/include/efi_loader.h b/include/efi_loader.h > index 291eca5c07..d450e304c6 100644 > --- a/include/efi_loader.h > +++ b/include/efi_loader.h > @@ -786,7 +786,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, > efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); > > /** > - * efi_add_memory_map_pg() - add pages to the memory map > + * efi_update_memory_map() - update the memory map by adding/removing pages > * > * @start: start address, must be a multiple of > * EFI_PAGE_SIZE > @@ -794,11 +794,14 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); > * @memory_type: type of memory added > * @overlap_conventional: region may only overlap free(conventional) > * memory > + * @remove: remove memory map > * Return: status code > */ > -efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > - int memory_type, > - bool overlap_conventional); > +efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type, > + bool overlap_conventional, bool remove); > + > +/* Remove memory from the EFI memory map */ > +efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type); > > /* Called by board init to initialize the EFI drivers */ > efi_status_t efi_driver_init(void); > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > index 3d742fa191..cb93bfa55f 100644 > --- a/lib/efi_loader/efi_memory.c > +++ b/lib/efi_loader/efi_memory.c > @@ -258,7 +258,7 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > } > > /** > - * efi_add_memory_map_pg() - add pages to the memory map > + * efi_update_memory_map() - update the memory map by adding/removing pages > * > * @start: start address, must be a multiple of > * EFI_PAGE_SIZE > @@ -266,11 +266,11 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > * @memory_type: type of memory added > * @overlap_conventional: region may only overlap free(conventional) > * memory > + * @remove: remove memory map > * Return: status code > */ > -efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > - int memory_type, > - bool overlap_conventional) > +efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type, > + bool overlap_conventional, bool remove) > { > struct efi_mem_list *lmem; > struct efi_mem_list *newlist; > @@ -278,9 +278,9 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > uint64_t carved_pages = 0; > struct efi_event *evt; > > - EFI_PRINT("%s: 0x%llx 0x%llx %d %s\n", __func__, > + EFI_PRINT("%s: 0x%llx 0x%llx %d %s %s\n", __func__, > start, pages, memory_type, overlap_conventional ? > - "yes" : "no"); > + "yes" : "no", remove ? "remove" : "add"); > > if (memory_type >= EFI_MAX_MEMORY_TYPE) > return EFI_INVALID_PARAMETER; > @@ -363,7 +363,10 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > } > > /* Add our new map */ > - list_add_tail(&newlist->link, &efi_mem); > + if (!remove) > + list_add_tail(&newlist->link, &efi_mem); > + else > + free(newlist); > > /* And make sure memory is listed in descending order */ > efi_mem_sort(); > @@ -400,7 +403,29 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type) > pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK)); > start &= ~EFI_PAGE_MASK; > > - return efi_add_memory_map_pg(start, pages, memory_type, false); > + return efi_update_memory_map(start, pages, memory_type, false, false); > +} > + > +/** > + * efi_remove_memory_map() - remove memory area to the memory map > + * > + * @start: start address of the memory area > + * @size: length in bytes of the memory area > + * @memory_type: type of memory removed > + * > + * Return: status code > + * > + * This function automatically aligns the start and size of the memory area > + * to EFI_PAGE_SIZE. > + */ > +efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type) > +{ > + u64 pages; > + > + pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK)); > + start &= ~EFI_PAGE_MASK; > + > + return efi_update_memory_map(start, pages, memory_type, false, true); > } > > /** > @@ -500,7 +525,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, > > addr = (u64)(uintptr_t)map_sysmem(addr, 0); > /* Reserve that map in our memory maps */ > - ret = efi_add_memory_map_pg(addr, pages, memory_type, true); > + ret = efi_update_memory_map(addr, pages, memory_type, true, false); > if (ret != EFI_SUCCESS) > /* Map would overlap, bail out */ > return EFI_OUT_OF_RESOURCES; > @@ -542,8 +567,8 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) > if (status) > return EFI_NOT_FOUND; > > - ret = efi_add_memory_map_pg(memory, pages, EFI_CONVENTIONAL_MEMORY, > - false); > + ret = efi_update_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, > + false, false); > if (ret != EFI_SUCCESS) > return EFI_NOT_FOUND; > > @@ -828,8 +853,8 @@ static void add_u_boot_and_runtime(void) > runtime_end = (uintptr_t)__efi_runtime_stop; > runtime_end = (runtime_end + runtime_mask) & ~runtime_mask; > runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT; > - efi_add_memory_map_pg(runtime_start, runtime_pages, > - EFI_RUNTIME_SERVICES_CODE, false); > + efi_update_memory_map(runtime_start, runtime_pages, > + EFI_RUNTIME_SERVICES_CODE, false, false); > } > > int efi_memory_init(void) > diff --git a/lib/lmb.c b/lib/lmb.c > index 7e90f17876..05f3cd093d 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -55,11 +55,11 @@ static int __maybe_unused lmb_map_update_notify(phys_addr_t addr, > pages = efi_size_in_pages(size + (efi_addr & EFI_PAGE_MASK)); > efi_addr &= ~EFI_PAGE_MASK; > > - status = efi_add_memory_map_pg(efi_addr, pages, > + status = efi_update_memory_map(efi_addr, pages, > op == MAP_OP_RESERVE ? > EFI_BOOT_SERVICES_DATA : > EFI_CONVENTIONAL_MEMORY, > - false); > + false, false); > if (status != EFI_SUCCESS) { > log_err("%s: LMB Map notify failure %lu\n", __func__, > status & ~EFI_ERROR_MASK); > -- > 2.34.1 >
On 10/25/24 13:14, Sughosh Ganu wrote: > From: Ilias Apalodimas <ilias.apalodimas@linaro.org> > > With upcoming changes supporting pmem nodes, we need to ommit the Nits: %s/ommit/remove/ > pmem area rfom the EFI memory map. Add a function to do that %s/rfom/from/ %s/that/that./ > > Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> The patch is not applicable. Please, rebase on origin/master. In the medium term we should get rid of the double book keeping. The memory map should be generated on the fly from LMB data. Best regards Heinrich > --- > include/efi_loader.h | 11 +++++--- > lib/efi_loader/efi_memory.c | 51 +++++++++++++++++++++++++++---------- > lib/lmb.c | 4 +-- > 3 files changed, 47 insertions(+), 19 deletions(-) > > diff --git a/include/efi_loader.h b/include/efi_loader.h > index 291eca5c07..d450e304c6 100644 > --- a/include/efi_loader.h > +++ b/include/efi_loader.h > @@ -786,7 +786,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, > efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); > > /** > - * efi_add_memory_map_pg() - add pages to the memory map > + * efi_update_memory_map() - update the memory map by adding/removing pages > * > * @start: start address, must be a multiple of > * EFI_PAGE_SIZE > @@ -794,11 +794,14 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); > * @memory_type: type of memory added > * @overlap_conventional: region may only overlap free(conventional) > * memory > + * @remove: remove memory map > * Return: status code > */ > -efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > - int memory_type, > - bool overlap_conventional); > +efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type, > + bool overlap_conventional, bool remove); > + > +/* Remove memory from the EFI memory map */ > +efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type); > > /* Called by board init to initialize the EFI drivers */ > efi_status_t efi_driver_init(void); > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > index 3d742fa191..cb93bfa55f 100644 > --- a/lib/efi_loader/efi_memory.c > +++ b/lib/efi_loader/efi_memory.c > @@ -258,7 +258,7 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > } > > /** > - * efi_add_memory_map_pg() - add pages to the memory map > + * efi_update_memory_map() - update the memory map by adding/removing pages > * > * @start: start address, must be a multiple of > * EFI_PAGE_SIZE > @@ -266,11 +266,11 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > * @memory_type: type of memory added > * @overlap_conventional: region may only overlap free(conventional) > * memory > + * @remove: remove memory map > * Return: status code > */ > -efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > - int memory_type, > - bool overlap_conventional) > +efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type, > + bool overlap_conventional, bool remove) > { > struct efi_mem_list *lmem; > struct efi_mem_list *newlist; > @@ -278,9 +278,9 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > uint64_t carved_pages = 0; > struct efi_event *evt; > > - EFI_PRINT("%s: 0x%llx 0x%llx %d %s\n", __func__, > + EFI_PRINT("%s: 0x%llx 0x%llx %d %s %s\n", __func__, > start, pages, memory_type, overlap_conventional ? > - "yes" : "no"); > + "yes" : "no", remove ? "remove" : "add"); > > if (memory_type >= EFI_MAX_MEMORY_TYPE) > return EFI_INVALID_PARAMETER; > @@ -363,7 +363,10 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > } > > /* Add our new map */ > - list_add_tail(&newlist->link, &efi_mem); > + if (!remove) > + list_add_tail(&newlist->link, &efi_mem); > + else > + free(newlist); > > /* And make sure memory is listed in descending order */ > efi_mem_sort(); > @@ -400,7 +403,29 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type) > pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK)); > start &= ~EFI_PAGE_MASK; > > - return efi_add_memory_map_pg(start, pages, memory_type, false); > + return efi_update_memory_map(start, pages, memory_type, false, false); > +} > + > +/** > + * efi_remove_memory_map() - remove memory area to the memory map > + * > + * @start: start address of the memory area > + * @size: length in bytes of the memory area > + * @memory_type: type of memory removed > + * > + * Return: status code > + * > + * This function automatically aligns the start and size of the memory area > + * to EFI_PAGE_SIZE. > + */ > +efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type) > +{ > + u64 pages; > + > + pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK)); > + start &= ~EFI_PAGE_MASK; > + > + return efi_update_memory_map(start, pages, memory_type, false, true); > } > > /** > @@ -500,7 +525,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, > > addr = (u64)(uintptr_t)map_sysmem(addr, 0); > /* Reserve that map in our memory maps */ > - ret = efi_add_memory_map_pg(addr, pages, memory_type, true); > + ret = efi_update_memory_map(addr, pages, memory_type, true, false); > if (ret != EFI_SUCCESS) > /* Map would overlap, bail out */ > return EFI_OUT_OF_RESOURCES; > @@ -542,8 +567,8 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) > if (status) > return EFI_NOT_FOUND; > > - ret = efi_add_memory_map_pg(memory, pages, EFI_CONVENTIONAL_MEMORY, > - false); > + ret = efi_update_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, > + false, false); > if (ret != EFI_SUCCESS) > return EFI_NOT_FOUND; > > @@ -828,8 +853,8 @@ static void add_u_boot_and_runtime(void) > runtime_end = (uintptr_t)__efi_runtime_stop; > runtime_end = (runtime_end + runtime_mask) & ~runtime_mask; > runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT; > - efi_add_memory_map_pg(runtime_start, runtime_pages, > - EFI_RUNTIME_SERVICES_CODE, false); > + efi_update_memory_map(runtime_start, runtime_pages, > + EFI_RUNTIME_SERVICES_CODE, false, false); > } > > int efi_memory_init(void) > diff --git a/lib/lmb.c b/lib/lmb.c > index 7e90f17876..05f3cd093d 100644 > --- a/lib/lmb.c > +++ b/lib/lmb.c > @@ -55,11 +55,11 @@ static int __maybe_unused lmb_map_update_notify(phys_addr_t addr, > pages = efi_size_in_pages(size + (efi_addr & EFI_PAGE_MASK)); > efi_addr &= ~EFI_PAGE_MASK; > > - status = efi_add_memory_map_pg(efi_addr, pages, > + status = efi_update_memory_map(efi_addr, pages, > op == MAP_OP_RESERVE ? > EFI_BOOT_SERVICES_DATA : > EFI_CONVENTIONAL_MEMORY, > - false); > + false, false); > if (status != EFI_SUCCESS) { > log_err("%s: LMB Map notify failure %lu\n", __func__, > status & ~EFI_ERROR_MASK);
Hi Heinrich On Mon, 11 Nov 2024 at 09:52, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 10/25/24 13:14, Sughosh Ganu wrote: > > From: Ilias Apalodimas <ilias.apalodimas@linaro.org> > > > > With upcoming changes supporting pmem nodes, we need to ommit the > > Nits: > %s/ommit/remove/ > > > pmem area rfom the EFI memory map. Add a function to do that > > %s/rfom/from/ > %s/that/that./ > > > > > Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> > > The patch is not applicable. Please, rebase on origin/master. Will do thanks! > > In the medium term we should get rid of the double book keeping. The > memory map should be generated on the fly from LMB data. Yes, I plan to have an RFC so we can see how that looks like Thanks /Ilias > > Best regards > > Heinrich > > > --- > > include/efi_loader.h | 11 +++++--- > > lib/efi_loader/efi_memory.c | 51 +++++++++++++++++++++++++++---------- > > lib/lmb.c | 4 +-- > > 3 files changed, 47 insertions(+), 19 deletions(-) > > > > diff --git a/include/efi_loader.h b/include/efi_loader.h > > index 291eca5c07..d450e304c6 100644 > > --- a/include/efi_loader.h > > +++ b/include/efi_loader.h > > @@ -786,7 +786,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, > > efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); > > > > /** > > - * efi_add_memory_map_pg() - add pages to the memory map > > + * efi_update_memory_map() - update the memory map by adding/removing pages > > * > > * @start: start address, must be a multiple of > > * EFI_PAGE_SIZE > > @@ -794,11 +794,14 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); > > * @memory_type: type of memory added > > * @overlap_conventional: region may only overlap free(conventional) > > * memory > > + * @remove: remove memory map > > * Return: status code > > */ > > -efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > - int memory_type, > > - bool overlap_conventional); > > +efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type, > > + bool overlap_conventional, bool remove); > > + > > +/* Remove memory from the EFI memory map */ > > +efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type); > > > > /* Called by board init to initialize the EFI drivers */ > > efi_status_t efi_driver_init(void); > > diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c > > index 3d742fa191..cb93bfa55f 100644 > > --- a/lib/efi_loader/efi_memory.c > > +++ b/lib/efi_loader/efi_memory.c > > @@ -258,7 +258,7 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > } > > > > /** > > - * efi_add_memory_map_pg() - add pages to the memory map > > + * efi_update_memory_map() - update the memory map by adding/removing pages > > * > > * @start: start address, must be a multiple of > > * EFI_PAGE_SIZE > > @@ -266,11 +266,11 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, > > * @memory_type: type of memory added > > * @overlap_conventional: region may only overlap free(conventional) > > * memory > > + * @remove: remove memory map > > * Return: status code > > */ > > -efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > - int memory_type, > > - bool overlap_conventional) > > +efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type, > > + bool overlap_conventional, bool remove) > > { > > struct efi_mem_list *lmem; > > struct efi_mem_list *newlist; > > @@ -278,9 +278,9 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > uint64_t carved_pages = 0; > > struct efi_event *evt; > > > > - EFI_PRINT("%s: 0x%llx 0x%llx %d %s\n", __func__, > > + EFI_PRINT("%s: 0x%llx 0x%llx %d %s %s\n", __func__, > > start, pages, memory_type, overlap_conventional ? > > - "yes" : "no"); > > + "yes" : "no", remove ? "remove" : "add"); > > > > if (memory_type >= EFI_MAX_MEMORY_TYPE) > > return EFI_INVALID_PARAMETER; > > @@ -363,7 +363,10 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, > > } > > > > /* Add our new map */ > > - list_add_tail(&newlist->link, &efi_mem); > > + if (!remove) > > + list_add_tail(&newlist->link, &efi_mem); > > + else > > + free(newlist); > > > > /* And make sure memory is listed in descending order */ > > efi_mem_sort(); > > @@ -400,7 +403,29 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type) > > pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK)); > > start &= ~EFI_PAGE_MASK; > > > > - return efi_add_memory_map_pg(start, pages, memory_type, false); > > + return efi_update_memory_map(start, pages, memory_type, false, false); > > +} > > + > > +/** > > + * efi_remove_memory_map() - remove memory area to the memory map > > + * > > + * @start: start address of the memory area > > + * @size: length in bytes of the memory area > > + * @memory_type: type of memory removed > > + * > > + * Return: status code > > + * > > + * This function automatically aligns the start and size of the memory area > > + * to EFI_PAGE_SIZE. > > + */ > > +efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type) > > +{ > > + u64 pages; > > + > > + pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK)); > > + start &= ~EFI_PAGE_MASK; > > + > > + return efi_update_memory_map(start, pages, memory_type, false, true); > > } > > > > /** > > @@ -500,7 +525,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, > > > > addr = (u64)(uintptr_t)map_sysmem(addr, 0); > > /* Reserve that map in our memory maps */ > > - ret = efi_add_memory_map_pg(addr, pages, memory_type, true); > > + ret = efi_update_memory_map(addr, pages, memory_type, true, false); > > if (ret != EFI_SUCCESS) > > /* Map would overlap, bail out */ > > return EFI_OUT_OF_RESOURCES; > > @@ -542,8 +567,8 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) > > if (status) > > return EFI_NOT_FOUND; > > > > - ret = efi_add_memory_map_pg(memory, pages, EFI_CONVENTIONAL_MEMORY, > > - false); > > + ret = efi_update_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, > > + false, false); > > if (ret != EFI_SUCCESS) > > return EFI_NOT_FOUND; > > > > @@ -828,8 +853,8 @@ static void add_u_boot_and_runtime(void) > > runtime_end = (uintptr_t)__efi_runtime_stop; > > runtime_end = (runtime_end + runtime_mask) & ~runtime_mask; > > runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT; > > - efi_add_memory_map_pg(runtime_start, runtime_pages, > > - EFI_RUNTIME_SERVICES_CODE, false); > > + efi_update_memory_map(runtime_start, runtime_pages, > > + EFI_RUNTIME_SERVICES_CODE, false, false); > > } > > > > int efi_memory_init(void) > > diff --git a/lib/lmb.c b/lib/lmb.c > > index 7e90f17876..05f3cd093d 100644 > > --- a/lib/lmb.c > > +++ b/lib/lmb.c > > @@ -55,11 +55,11 @@ static int __maybe_unused lmb_map_update_notify(phys_addr_t addr, > > pages = efi_size_in_pages(size + (efi_addr & EFI_PAGE_MASK)); > > efi_addr &= ~EFI_PAGE_MASK; > > > > - status = efi_add_memory_map_pg(efi_addr, pages, > > + status = efi_update_memory_map(efi_addr, pages, > > op == MAP_OP_RESERVE ? > > EFI_BOOT_SERVICES_DATA : > > EFI_CONVENTIONAL_MEMORY, > > - false); > > + false, false); > > if (status != EFI_SUCCESS) { > > log_err("%s: LMB Map notify failure %lu\n", __func__, > > status & ~EFI_ERROR_MASK); >
diff --git a/include/efi_loader.h b/include/efi_loader.h index 291eca5c07..d450e304c6 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -786,7 +786,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); /** - * efi_add_memory_map_pg() - add pages to the memory map + * efi_update_memory_map() - update the memory map by adding/removing pages * * @start: start address, must be a multiple of * EFI_PAGE_SIZE @@ -794,11 +794,14 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); * @memory_type: type of memory added * @overlap_conventional: region may only overlap free(conventional) * memory + * @remove: remove memory map * Return: status code */ -efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, - int memory_type, - bool overlap_conventional); +efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type, + bool overlap_conventional, bool remove); + +/* Remove memory from the EFI memory map */ +efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type); /* Called by board init to initialize the EFI drivers */ efi_status_t efi_driver_init(void); diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 3d742fa191..cb93bfa55f 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -258,7 +258,7 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, } /** - * efi_add_memory_map_pg() - add pages to the memory map + * efi_update_memory_map() - update the memory map by adding/removing pages * * @start: start address, must be a multiple of * EFI_PAGE_SIZE @@ -266,11 +266,11 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, * @memory_type: type of memory added * @overlap_conventional: region may only overlap free(conventional) * memory + * @remove: remove memory map * Return: status code */ -efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, - int memory_type, - bool overlap_conventional) +efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type, + bool overlap_conventional, bool remove) { struct efi_mem_list *lmem; struct efi_mem_list *newlist; @@ -278,9 +278,9 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, uint64_t carved_pages = 0; struct efi_event *evt; - EFI_PRINT("%s: 0x%llx 0x%llx %d %s\n", __func__, + EFI_PRINT("%s: 0x%llx 0x%llx %d %s %s\n", __func__, start, pages, memory_type, overlap_conventional ? - "yes" : "no"); + "yes" : "no", remove ? "remove" : "add"); if (memory_type >= EFI_MAX_MEMORY_TYPE) return EFI_INVALID_PARAMETER; @@ -363,7 +363,10 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, } /* Add our new map */ - list_add_tail(&newlist->link, &efi_mem); + if (!remove) + list_add_tail(&newlist->link, &efi_mem); + else + free(newlist); /* And make sure memory is listed in descending order */ efi_mem_sort(); @@ -400,7 +403,29 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type) pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK)); start &= ~EFI_PAGE_MASK; - return efi_add_memory_map_pg(start, pages, memory_type, false); + return efi_update_memory_map(start, pages, memory_type, false, false); +} + +/** + * efi_remove_memory_map() - remove memory area to the memory map + * + * @start: start address of the memory area + * @size: length in bytes of the memory area + * @memory_type: type of memory removed + * + * Return: status code + * + * This function automatically aligns the start and size of the memory area + * to EFI_PAGE_SIZE. + */ +efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type) +{ + u64 pages; + + pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK)); + start &= ~EFI_PAGE_MASK; + + return efi_update_memory_map(start, pages, memory_type, false, true); } /** @@ -500,7 +525,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, addr = (u64)(uintptr_t)map_sysmem(addr, 0); /* Reserve that map in our memory maps */ - ret = efi_add_memory_map_pg(addr, pages, memory_type, true); + ret = efi_update_memory_map(addr, pages, memory_type, true, false); if (ret != EFI_SUCCESS) /* Map would overlap, bail out */ return EFI_OUT_OF_RESOURCES; @@ -542,8 +567,8 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) if (status) return EFI_NOT_FOUND; - ret = efi_add_memory_map_pg(memory, pages, EFI_CONVENTIONAL_MEMORY, - false); + ret = efi_update_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, + false, false); if (ret != EFI_SUCCESS) return EFI_NOT_FOUND; @@ -828,8 +853,8 @@ static void add_u_boot_and_runtime(void) runtime_end = (uintptr_t)__efi_runtime_stop; runtime_end = (runtime_end + runtime_mask) & ~runtime_mask; runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT; - efi_add_memory_map_pg(runtime_start, runtime_pages, - EFI_RUNTIME_SERVICES_CODE, false); + efi_update_memory_map(runtime_start, runtime_pages, + EFI_RUNTIME_SERVICES_CODE, false, false); } int efi_memory_init(void) diff --git a/lib/lmb.c b/lib/lmb.c index 7e90f17876..05f3cd093d 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -55,11 +55,11 @@ static int __maybe_unused lmb_map_update_notify(phys_addr_t addr, pages = efi_size_in_pages(size + (efi_addr & EFI_PAGE_MASK)); efi_addr &= ~EFI_PAGE_MASK; - status = efi_add_memory_map_pg(efi_addr, pages, + status = efi_update_memory_map(efi_addr, pages, op == MAP_OP_RESERVE ? EFI_BOOT_SERVICES_DATA : EFI_CONVENTIONAL_MEMORY, - false); + false, false); if (status != EFI_SUCCESS) { log_err("%s: LMB Map notify failure %lu\n", __func__, status & ~EFI_ERROR_MASK);