Skip to content

Commit 18df757

Browse files
author
Ard Biesheuvel
committed
efi/memreserve: deal with memreserve entries in unmapped memory
Ensure that the EFI memreserve entries can be accessed, even if they are located in memory that the kernel (e.g., a crashkernel) omits from the linear map. Fixes: 80424b0 ("efi: Reduce the amount of memblock reservations ...") Cc: <[email protected]> # 5.0+ Reported-by: Jonathan Richardson <[email protected]> Reviewed-by: Jonathan Richardson <[email protected]> Tested-by: Jonathan Richardson <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent d1fdb6d commit 18df757

File tree

1 file changed

+10
-2
lines changed
  • drivers/firmware/efi

1 file changed

+10
-2
lines changed

drivers/firmware/efi/efi.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,22 +1009,30 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
10091009

10101010
/* first try to find a slot in an existing linked list entry */
10111011
for (prsv = efi_memreserve_root->next; prsv; prsv = rsv->next) {
1012-
rsv = __va(prsv);
1012+
rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB);
10131013
index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size);
10141014
if (index < rsv->size) {
10151015
rsv->entry[index].base = addr;
10161016
rsv->entry[index].size = size;
10171017

1018+
memunmap(rsv);
10181019
return 0;
10191020
}
1021+
memunmap(rsv);
10201022
}
10211023

10221024
/* no slot found - allocate a new linked list entry */
10231025
rsv = (struct linux_efi_memreserve *)__get_free_page(GFP_ATOMIC);
10241026
if (!rsv)
10251027
return -ENOMEM;
10261028

1027-
rsv->size = EFI_MEMRESERVE_COUNT(PAGE_SIZE);
1029+
/*
1030+
* The memremap() call above assumes that a linux_efi_memreserve entry
1031+
* never crosses a page boundary, so let's ensure that this remains true
1032+
* even when kexec'ing a 4k pages kernel from a >4k pages kernel, by
1033+
* using SZ_4K explicitly in the size calculation below.
1034+
*/
1035+
rsv->size = EFI_MEMRESERVE_COUNT(SZ_4K);
10281036
atomic_set(&rsv->count, 1);
10291037
rsv->entry[0].base = addr;
10301038
rsv->entry[0].size = size;

0 commit comments

Comments
 (0)