aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/efi/efi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware/efi/efi.c')
-rw-r--r--drivers/firmware/efi/efi.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 249eb70691b0..fad7c62cfc0e 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -592,7 +592,11 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
592 592
593 early_memunmap(tbl, sizeof(*tbl)); 593 early_memunmap(tbl, sizeof(*tbl));
594 } 594 }
595 return 0;
596}
595 597
598int __init efi_apply_persistent_mem_reservations(void)
599{
596 if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) { 600 if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {
597 unsigned long prsv = efi.mem_reserve; 601 unsigned long prsv = efi.mem_reserve;
598 602
@@ -963,36 +967,43 @@ bool efi_is_table_address(unsigned long phys_addr)
963} 967}
964 968
965static 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;
966 971
967int efi_mem_reserve_persistent(phys_addr_t addr, u64 size) 972int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
968{ 973{
969 struct linux_efi_memreserve *rsv, *parent; 974 struct linux_efi_memreserve *rsv;
970 975
971 if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR) 976 if (!efi_memreserve_root)
972 return -ENODEV; 977 return -ENODEV;
973 978
974 rsv = kmalloc(sizeof(*rsv), GFP_KERNEL); 979 rsv = kmalloc(sizeof(*rsv), GFP_ATOMIC);
975 if (!rsv) 980 if (!rsv)
976 return -ENOMEM; 981 return -ENOMEM;
977 982
978 parent = memremap(efi.mem_reserve, sizeof(*rsv), MEMREMAP_WB);
979 if (!parent) {
980 kfree(rsv);
981 return -ENOMEM;
982 }
983
984 rsv->base = addr; 983 rsv->base = addr;
985 rsv->size = size; 984 rsv->size = size;
986 985
987 spin_lock(&efi_mem_reserve_persistent_lock); 986 spin_lock(&efi_mem_reserve_persistent_lock);
988 rsv->next = parent->next; 987 rsv->next = efi_memreserve_root->next;
989 parent->next = __pa(rsv); 988 efi_memreserve_root->next = __pa(rsv);
990 spin_unlock(&efi_mem_reserve_persistent_lock); 989 spin_unlock(&efi_mem_reserve_persistent_lock);
991 990
992 memunmap(parent); 991 return 0;
992}
993 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;
994 return 0; 1004 return 0;
995} 1005}
1006early_initcall(efi_memreserve_root_init);
996 1007
997#ifdef CONFIG_KEXEC 1008#ifdef CONFIG_KEXEC
998static int update_efi_random_seed(struct notifier_block *nb, 1009static int update_efi_random_seed(struct notifier_block *nb,