Mapping the MEMRESERVE EFI configuration table from an early initcall is too late: the GICv3 ITS code that creates persistent reservations for the boot CPU's LPI tables is invoked from init_IRQ(), which runs much earlier than the handling of the initcalls. So instead, move the initialization performed by the initcall into efi_mem_reserve_persistent() itself. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> --- drivers/firmware/efi/efi.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index fad7c62cfc0e..40de2f6734cc 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -967,15 +967,23 @@ bool efi_is_table_address(unsigned long phys_addr) } static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock); -static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init; +static struct linux_efi_memreserve *efi_memreserve_root; int efi_mem_reserve_persistent(phys_addr_t addr, u64 size) { struct linux_efi_memreserve *rsv; - if (!efi_memreserve_root) + if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR) return -ENODEV; + if (!efi_memreserve_root) { + efi_memreserve_root = memremap(efi.mem_reserve, + sizeof(*efi_memreserve_root), + MEMREMAP_WB); + if (WARN_ON_ONCE(!efi_memreserve_root)) + return -ENOMEM; + } + rsv = kmalloc(sizeof(*rsv), GFP_ATOMIC); if (!rsv) return -ENOMEM; @@ -991,20 +999,6 @@ int efi_mem_reserve_persistent(phys_addr_t addr, u64 size) return 0; } -static int __init efi_memreserve_root_init(void) -{ - if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR) - return -ENODEV; - - efi_memreserve_root = memremap(efi.mem_reserve, - sizeof(*efi_memreserve_root), - MEMREMAP_WB); - if (!efi_memreserve_root) - return -ENOMEM; - return 0; -} -early_initcall(efi_memreserve_root_init); - #ifdef CONFIG_KEXEC static int update_efi_random_seed(struct notifier_block *nb, unsigned long code, void *unused) -- 2.17.1