aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firmware/efi/efi.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 72a4da76d274..fad7c62cfc0e 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -967,36 +967,43 @@ bool efi_is_table_address(unsigned long phys_addr)
967} 967}
968 968
969static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock); 969static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
970static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
970 971
971int efi_mem_reserve_persistent(phys_addr_t addr, u64 size) 972int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
972{ 973{
973 struct linux_efi_memreserve *rsv, *parent; 974 struct linux_efi_memreserve *rsv;
974 975
975 if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR) 976 if (!efi_memreserve_root)
976 return -ENODEV; 977 return -ENODEV;
977 978
978 rsv = kmalloc(sizeof(*rsv), GFP_KERNEL); 979 rsv = kmalloc(sizeof(*rsv), GFP_ATOMIC);
979 if (!rsv) 980 if (!rsv)
980 return -ENOMEM; 981 return -ENOMEM;
981 982
982 parent = memremap(efi.mem_reserve, sizeof(*rsv), MEMREMAP_WB);
983 if (!parent) {
984 kfree(rsv);
985 return -ENOMEM;
986 }
987
988 rsv->base = addr; 983 rsv->base = addr;
989 rsv->size = size; 984 rsv->size = size;
990 985
991 spin_lock(&efi_mem_reserve_persistent_lock); 986 spin_lock(&efi_mem_reserve_persistent_lock);
992 rsv->next = parent->next; 987 rsv->next = efi_memreserve_root->next;
993 parent->next = __pa(rsv); 988 efi_memreserve_root->next = __pa(rsv);
994 spin_unlock(&efi_mem_reserve_persistent_lock); 989 spin_unlock(&efi_mem_reserve_persistent_lock);
995 990
996 memunmap(parent); 991 return 0;
992}
997 993
994static int __init efi_memreserve_root_init(void)
995{
996 if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
997 return -ENODEV;
998
999 efi_memreserve_root = memremap(efi.mem_reserve,
1000 sizeof(*efi_memreserve_root),
1001 MEMREMAP_WB);
1002 if (!efi_memreserve_root)
1003 return -ENOMEM;
998 return 0; 1004 return 0;
999} 1005}
1006early_initcall(efi_memreserve_root_init);
1000 1007
1001#ifdef CONFIG_KEXEC 1008#ifdef CONFIG_KEXEC
1002static int update_efi_random_seed(struct notifier_block *nb, 1009static int update_efi_random_seed(struct notifier_block *nb,