aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/platform/efi/quirks.c4
-rw-r--r--drivers/firmware/efi/fake_mem.c3
-rw-r--r--drivers/firmware/efi/memmap.c38
-rw-r--r--include/linux/efi.h1
4 files changed, 42 insertions, 4 deletions
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 10aca63a50d7..30031d5293c4 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -214,7 +214,7 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
214 214
215 new_size = efi.memmap.desc_size * num_entries; 215 new_size = efi.memmap.desc_size * num_entries;
216 216
217 new_phys = memblock_alloc(new_size, 0); 217 new_phys = efi_memmap_alloc(num_entries);
218 if (!new_phys) { 218 if (!new_phys) {
219 pr_err("Could not allocate boot services memmap\n"); 219 pr_err("Could not allocate boot services memmap\n");
220 return; 220 return;
@@ -355,7 +355,7 @@ void __init efi_free_boot_services(void)
355 } 355 }
356 356
357 new_size = efi.memmap.desc_size * num_entries; 357 new_size = efi.memmap.desc_size * num_entries;
358 new_phys = memblock_alloc(new_size, 0); 358 new_phys = efi_memmap_alloc(num_entries);
359 if (!new_phys) { 359 if (!new_phys) {
360 pr_err("Failed to allocate new EFI memmap\n"); 360 pr_err("Failed to allocate new EFI memmap\n");
361 return; 361 return;
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
index 520a40e5e0e4..6c7d60c239b5 100644
--- a/drivers/firmware/efi/fake_mem.c
+++ b/drivers/firmware/efi/fake_mem.c
@@ -71,8 +71,7 @@ void __init efi_fake_memmap(void)
71 } 71 }
72 72
73 /* allocate memory for new EFI memmap */ 73 /* allocate memory for new EFI memmap */
74 new_memmap_phy = memblock_alloc(efi.memmap.desc_size * new_nr_map, 74 new_memmap_phy = efi_memmap_alloc(new_nr_map);
75 PAGE_SIZE);
76 if (!new_memmap_phy) 75 if (!new_memmap_phy)
77 return; 76 return;
78 77
diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c
index f03ddecd232b..78686443cb37 100644
--- a/drivers/firmware/efi/memmap.c
+++ b/drivers/firmware/efi/memmap.c
@@ -9,6 +9,44 @@
9#include <linux/efi.h> 9#include <linux/efi.h>
10#include <linux/io.h> 10#include <linux/io.h>
11#include <asm/early_ioremap.h> 11#include <asm/early_ioremap.h>
12#include <linux/memblock.h>
13#include <linux/slab.h>
14
15static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size)
16{
17 return memblock_alloc(size, 0);
18}
19
20static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
21{
22 unsigned int order = get_order(size);
23 struct page *p = alloc_pages(GFP_KERNEL, order);
24
25 if (!p)
26 return 0;
27
28 return PFN_PHYS(page_to_pfn(p));
29}
30
31/**
32 * efi_memmap_alloc - Allocate memory for the EFI memory map
33 * @num_entries: Number of entries in the allocated map.
34 *
35 * Depending on whether mm_init() has already been invoked or not,
36 * either memblock or "normal" page allocation is used.
37 *
38 * Returns the physical address of the allocated memory map on
39 * success, zero on failure.
40 */
41phys_addr_t __init efi_memmap_alloc(unsigned int num_entries)
42{
43 unsigned long size = num_entries * efi.memmap.desc_size;
44
45 if (slab_is_available())
46 return __efi_memmap_alloc_late(size);
47
48 return __efi_memmap_alloc_early(size);
49}
12 50
13/** 51/**
14 * __efi_memmap_init - Common code for mapping the EFI memory map 52 * __efi_memmap_init - Common code for mapping the EFI memory map
diff --git a/include/linux/efi.h b/include/linux/efi.h
index fda79cdf9f10..cba7177cbec7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -931,6 +931,7 @@ static inline efi_status_t efi_query_variable_store(u32 attributes,
931#endif 931#endif
932extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); 932extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
933 933
934extern phys_addr_t __init efi_memmap_alloc(unsigned int num_entries);
934extern int __init efi_memmap_init_early(struct efi_memory_map_data *data); 935extern int __init efi_memmap_init_early(struct efi_memory_map_data *data);
935extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size); 936extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size);
936extern void __init efi_memmap_unmap(void); 937extern void __init efi_memmap_unmap(void);