Message ID | 2f2cfb59ecf0457095c9c09b0e310677@rwthex-w2-b.rwth-ad.de |
---|---|
State | Accepted |
Delegated to: | Alexander Graf |
Headers | show |
> Currently each allocation creates a new mapping. Readding the mapping > as free memory (EFI_CONVENTIONAL_MEMORY) potentially allows to hand out > an existing mapping, thus limiting the number of mapping descriptors in > the memory map. > > Mitigates a problem with current (4.8rc7) linux kernels when doing an > efi_get_memory map, resulting in an infinite loop. Space for the memory > map is reserved with allocate_pool (implicitly creating a new mapping) and > filled. If there is insufficient slack space (8 entries) in the map, the > space is freed and a new round is started, with space for one more entry. > As each round increases requirement and allocation by exactly one, there > is never enough slack space. (At least 32 entries are allocated, so as > long as there are less than 24 entries, there is enough slack). > Earlier kernels reserved no slack, and did less allocations, so this > problem was not visible. > > Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> > Reviewed-by: Alexander Graf <agraf@suse.de> Thanks, applied to
diff --git a/include/efi_loader.h b/include/efi_loader.h index 341d4a4..6d64f4b 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -117,7 +117,7 @@ void *efi_alloc(uint64_t len, int memory_type); /* More specific EFI memory allocator, called by EFI payloads */ efi_status_t efi_allocate_pages(int type, int memory_type, unsigned long pages, uint64_t *memory); -/* EFI memory free function. Not implemented today */ +/* EFI memory free function. */ efi_status_t efi_free_pages(uint64_t memory, unsigned long pages); /* EFI memory allocator for small allocations, called by EFI payloads */ efi_status_t efi_allocate_pool(int pool_type, unsigned long size, diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index fa5c639..7051948 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -335,8 +335,15 @@ void *efi_alloc(uint64_t len, int memory_type) efi_status_t efi_free_pages(uint64_t memory, unsigned long pages) { - /* We don't free, let's cross our fingers we have plenty RAM */ - return EFI_SUCCESS; + uint64_t r = 0; + + r = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false); + /* Merging of adjacent free regions is missing */ + + if (r == memory) + return EFI_SUCCESS; + + return EFI_NOT_FOUND; } efi_status_t efi_allocate_pool(int pool_type, unsigned long size,