Skip to content

Commit 2bab693

Browse files
Marc Zyngierardbiesheuvel
authored andcommitted
firmware/efi: Tell memblock about EFI iomem reservations
kexec_load_file() relies on the memblock infrastructure to avoid stamping over regions of memory that are essential to the survival of the system. However, nobody seems to agree how to flag these regions as reserved, and (for example) EFI only publishes its reservations in /proc/iomem for the benefit of the traditional, userspace based kexec tool. On arm64 platforms with GICv3, this can result in the payload being placed at the location of the LPI tables. Shock, horror! Let's augment the EFI reservation code with a memblock_reserve() call, protecting our dear tables from the secondary kernel invasion. Reported-by: Moritz Fischer <[email protected]> Tested-by: Moritz Fischer <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Cc: [email protected] Cc: Ard Biesheuvel <[email protected]> Cc: James Morse <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent 674a9f1 commit 2bab693

File tree

1 file changed

+12
-1
lines changed
  • drivers/firmware/efi

1 file changed

+12
-1
lines changed

drivers/firmware/efi/efi.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,7 @@ static int __init efi_memreserve_map_root(void)
896896
static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size)
897897
{
898898
struct resource *res, *parent;
899+
int ret;
899900

900901
res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
901902
if (!res)
@@ -908,7 +909,17 @@ static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size)
908909

909910
/* we expect a conflict with a 'System RAM' region */
910911
parent = request_resource_conflict(&iomem_resource, res);
911-
return parent ? request_resource(parent, res) : 0;
912+
ret = parent ? request_resource(parent, res) : 0;
913+
914+
/*
915+
* Given that efi_mem_reserve_iomem() can be called at any
916+
* time, only call memblock_reserve() if the architecture
917+
* keeps the infrastructure around.
918+
*/
919+
if (IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK) && !ret)
920+
memblock_reserve(addr, size);
921+
922+
return ret;
912923
}
913924

914925
int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size)

0 commit comments

Comments
 (0)