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 */
|
/* first try to find a slot in an existing linked list entry */
|
||||||
for (prsv = efi_memreserve_root->next; prsv; prsv = rsv->next) {
|
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);
|
index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size);
|
||||||
if (index < rsv->size) {
|
if (index < rsv->size) {
|
||||||
rsv->entry[index].base = addr;
|
rsv->entry[index].base = addr;
|
||||||
rsv->entry[index].size = size;
|
rsv->entry[index].size = size;
|
||||||
|
|
||||||
|
memunmap(rsv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
memunmap(rsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no slot found - allocate a new linked list entry */
|
/* 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)
|
if (!rsv)
|
||||||
return -ENOMEM;
|
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);
|
atomic_set(&rsv->count, 1);
|
||||||
rsv->entry[0].base = addr;
|
rsv->entry[0].base = addr;
|
||||||
rsv->entry[0].size = size;
|
rsv->entry[0].size = size;
|
||||||
|
|
Loading…
Reference in New Issue