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: 80424b02d4
("efi: Reduce the amount of memblock reservations ...")
Cc: <stable@vger.kernel.org> # 5.0+
Reported-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
Reviewed-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
Tested-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
This commit is contained in:
parent
d1fdb6d8f6
commit
18df7577ad
|
@ -1009,14 +1009,16 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
|
|||
|
||||
/* first try to find a slot in an existing linked list entry */
|
||||
for (prsv = efi_memreserve_root->next; prsv; prsv = rsv->next) {
|
||||
rsv = __va(prsv);
|
||||
rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB);
|
||||
index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size);
|
||||
if (index < rsv->size) {
|
||||
rsv->entry[index].base = addr;
|
||||
rsv->entry[index].size = size;
|
||||
|
||||
memunmap(rsv);
|
||||
return 0;
|
||||
}
|
||||
memunmap(rsv);
|
||||
}
|
||||
|
||||
/* no slot found - allocate a new linked list entry */
|
||||
|
@ -1024,7 +1026,13 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
|
|||
if (!rsv)
|
||||
return -ENOMEM;
|
||||
|
||||
rsv->size = EFI_MEMRESERVE_COUNT(PAGE_SIZE);
|
||||
/*
|
||||
* The memremap() call above assumes that a linux_efi_memreserve entry
|
||||
* never crosses a page boundary, so let's ensure that this remains true
|
||||
* even when kexec'ing a 4k pages kernel from a >4k pages kernel, by
|
||||
* using SZ_4K explicitly in the size calculation below.
|
||||
*/
|
||||
rsv->size = EFI_MEMRESERVE_COUNT(SZ_4K);
|
||||
atomic_set(&rsv->count, 1);
|
||||
rsv->entry[0].base = addr;
|
||||
rsv->entry[0].size = size;
|
||||
|
|
Loading…
Reference in New Issue