From: Sai Praneeth <[email protected]>
Presently, in efi subsystem of kernel, every time kernel allocates
memory for a new memory map, it forgets to free the memory occupied by
old memory map. It does clear the mappings though (using efi_memmap_unmap()),
but forgets to free up the memory. Also, there is another minor issue,
where in the newly allocated memory isn't freed, should remap fail.
The bug might sound very simple but the fix looks a bit complicated
because memory used by efi memory map could be of three different types,
namely a) memblock_reserved b) memblock_alloc'ed c) normal paged memory.
The fix requires changes to many already existing efi memory map API's
because whenever the memory map is updated, the type of memory allocation
should be recorded, so that we could use it while freeing.
"efi.memmap.alloc_type" is introduced for the same reason as "bool late"
wouldn't suffice.
More detailed explanation:
--------------------------
A typical boot flow on EFI supported x86_64 machines might look something
like below
1. EFI memory map is passed by firmware to kernel.
2. Kernel does a memblock_reserve() on this memory
(see efi_memblock_x86_reserve_range()).
3. To further process this memory map (see efi_fake_memmap(), efi_bgrt_init()
and efi_esrt_init()), kernel might allocate some memory using
memblock_alloc() and copies the processed memory map to newly
allocated memory but it forgets to free memory occupied by old
memory map i.e. the memblock_reserved memory.
4. Further, the new memblock allocated memory map is again processed
(see efi_map_regions() in efi_enter_virtual_mode()). Kernel again
allocates memory to store the processed memory map, but this time
using realloc_pages() as paging is initialized. Old memory map i.e.
the memblock_allocated memory is not freed.
6. A third processing is performed by efi_free_boot_services() and this
time paged memory isn't freed.
Brief summary of patches:
-------------------------
Patch 1 introduces a new API called efi_memmap_free() which frees memory
allocated by efi_memmap_alloc(). This API will be used in later patches
i.e. 4, 5 and 6.
Patch 2 modifies efi_memmap_alloc(), an existing API, so that it lets
the user know about the type of allocation performed. It's used to free
the allocated memory, should remap fail.
Patch 3 modifies many existing API's in drivers/firmware/efi/memmap.c
file, so that "efi.memmap.alloc_type" now rightly records the type of
memory associated with efi memory map. As said earlier, this memory
could be of three types a) memblock_reserved b) memblock_alloc'ed
c) normal paged memory. Previously, "efi.memmap.late" recorded only two
types of memory, namely, memblock_alloc'ed and normal paged memory and
hence this approach cannot be used to fix memory leak.
Patch 4 actually fixes the issue by freeing up the memory allocated to
previous memory map before installing a new memory map.
Patch 5 fixes another issue where in the newly allocated memory isn't
freed, should remap fail.
Patch 6 fixes yet another issue in efi_fake_memmap(), unrelated to this
patch set but found in the testing process.
Testing:
--------
Tested with LUV on qemu-x86_64 and on my dev machine. Checked for
unchanged boot behavior i.e. shouldn't break any existing stuff. Built
for arm, arm64 and ia64 and found no new warnings/errors. Would
appreciate the effort if someone could test on arm machines.
Although majority of the changes are made to drivers/firmware/efi/memmap.c
file (which is common across architectures), this bug is only limited to
x86_64 machines and hence this patch set shouldn't effect any other
architectures.
Note: This patch set is based on Linus's mainline tree v4.18-rc3.
1. Please also note that this patch set makes commit "3551b85ed8bf (x86/efi:
Free allocated memory if remap fails) in efi tree[1] obsolete.
2. This patch set is an outcome of the discussion at [2] and should
actually be V2. But, as it now evolved into a patch set instead of
single patch and also fixes another two issues, I have started it as
a new series and hence V1.
[1] git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
[2] https://lkml.org/lkml/2018/6/25/1113
Sai Praneeth (6):
efi: Introduce efi_memmap_free() to free memory allocated by
efi_memmap_alloc()
efi: Let the user of efi_memmap_alloc() know the type of allocation
performed
efi: Use efi.memmap.alloc_type instead of efi.memmap.late
x86/efi: Free existing memory map before installing new memory map
x86/efi: Free allocated memory if remap fails
efi: Fix unaligned fake memmap entries corrupting efi memory map
arch/x86/platform/efi/efi.c | 7 +++-
arch/x86/platform/efi/quirks.c | 34 ++++++++++++----
drivers/firmware/efi/arm-init.c | 2 +-
drivers/firmware/efi/fake_mem.c | 21 +++++++---
drivers/firmware/efi/memmap.c | 86 +++++++++++++++++++++++++++++++----------
include/linux/efi.h | 23 ++++++++---
6 files changed, 131 insertions(+), 42 deletions(-)
Signed-off-by: Sai Praneeth Prakhya <[email protected]>
Suggested-by: Ard Biesheuvel <[email protected]>
Cc: Lee Chun-Yi <[email protected]>
Cc: Dave Young <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Laszlo Ersek <[email protected]>
Cc: Jan Kiszka <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Bhupesh Sharma <[email protected]>
Cc: Nicolai Stange <[email protected]>
Cc: Naresh Bhat <[email protected]>
Cc: Ricardo Neri <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Taku Izumi <[email protected]>
Cc: Ravi Shankar <[email protected]>
Cc: Matt Fleming <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
--
2.7.4
From: Sai Praneeth <[email protected]>
efi_memmap_alloc() allocates memory depending on whether mm_init() has
already been invoked or not. Apart from memblock_alloc() memory and
alloc_pages() memory, efi memory map could also have a third variant of
memory allocation and that is memblock_reserved. This happens only for
the memory map passed to kernel by firmware and thus can happen only
once during boot process.
In order to identify these three different types of allocations and thus
to call the appropriate free() variant, introduce an enum named
efi_memmap_type and also introduce a efi memmap API named
efi_memmap_free() to free memory allocated by efi_memmap_alloc().
Signed-off-by: Sai Praneeth Prakhya <[email protected]>
Suggested-by: Ard Biesheuvel <[email protected]>
Cc: Lee Chun-Yi <[email protected]>
Cc: Dave Young <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Laszlo Ersek <[email protected]>
Cc: Jan Kiszka <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Bhupesh Sharma <[email protected]>
Cc: Nicolai Stange <[email protected]>
Cc: Naresh Bhat <[email protected]>
Cc: Ricardo Neri <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Taku Izumi <[email protected]>
Cc: Ravi Shankar <[email protected]>
Cc: Matt Fleming <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
---
drivers/firmware/efi/memmap.c | 28 ++++++++++++++++++++++++++++
include/linux/efi.h | 8 ++++++++
2 files changed, 36 insertions(+)
diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c
index 5fc70520e04c..0686e063c644 100644
--- a/drivers/firmware/efi/memmap.c
+++ b/drivers/firmware/efi/memmap.c
@@ -12,6 +12,7 @@
#include <asm/early_ioremap.h>
#include <linux/memblock.h>
#include <linux/slab.h>
+#include <linux/bootmem.h>
static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size)
{
@@ -50,6 +51,33 @@ phys_addr_t __init efi_memmap_alloc(unsigned int num_entries)
}
/**
+ * efi_memmap_free - Free memory allocated by efi_memmap_alloc()
+ * @mem: Physical address allocated by efi_memmap_alloc().
+ * @num_entries: Number of entries in the allocated map.
+ * @alloc_type: What type of allocation did efi_memmap_alloc() perform?
+ *
+ * Use this function to free memory allocated by efi_memmap_alloc().
+ * efi_memmap_alloc() allocates memory depending on whether mm_init()
+ * has already been invoked or not. It uses either memblock or "normal"
+ * page allocation, similarly, we free it in two different ways. Also
+ * note that there is a third type of memory used by memmap which is
+ * memblock_reserved() and is passed by EFI stub to kernel.
+ */
+void __init efi_memmap_free(phys_addr_t mem, unsigned int num_entries,
+ enum efi_memmap_type alloc_type)
+{
+ unsigned long size = num_entries * efi.memmap.desc_size;
+ unsigned int order = get_order(size);
+
+ if (alloc_type == BUDDY_ALLOCATOR)
+ __free_pages(pfn_to_page(PHYS_PFN(mem)), order);
+ else if (alloc_type == MEMBLOCK)
+ memblock_free(mem, size);
+ else
+ free_bootmem(mem, size);
+}
+
+/**
* __efi_memmap_init - Common code for mapping the EFI memory map
* @data: EFI memory map data
* @late: Use early or late mapping function?
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 56add823f190..455875c01ed1 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -765,6 +765,12 @@ struct efi_memory_map_data {
unsigned long desc_size;
};
+enum efi_memmap_type {
+ EFI_STUB,
+ MEMBLOCK,
+ BUDDY_ALLOCATOR,
+};
+
struct efi_memory_map {
phys_addr_t phys_map;
void *map;
@@ -1016,6 +1022,8 @@ extern int __init efi_memmap_split_count(efi_memory_desc_t *md,
struct range *range);
extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap,
void *buf, struct efi_mem_range *mem);
+extern void __init efi_memmap_free(phys_addr_t mem, unsigned int num_entries,
+ enum efi_memmap_type alloc_type);
extern int efi_config_init(efi_config_table_type_t *arch_tables);
#ifdef CONFIG_EFI_ESRT
--
2.7.4
From: Sai Praneeth <[email protected]>
efi_fake_memmap() inserts user given fake memory map entries into the
original efi memory map using efi_memmmap_insert(). efi_memmmap_insert()
checks for EFI_PAGE_SIZE alignment and could fail if an unaligned efi
memory region is passed (Eg: efi_fake_memmap=1K@0x73ae0000:
0x8000000000000000). Since EFI_PAGE_SIZE is 4K the above request fails,
but efi_fake_memmap() doesn't check for failures in efi_memmap_insert()
and installs an empty efi memory map from efi_memmap_alloc(). Since efi
memory map is corrupted all the later efi calls fail too. Hence, fix
this bug by changing the return type of efi_memmap_insert() from void to
int.
Signed-off-by: Sai Praneeth Prakhya <[email protected]>
Suggested-by: Ard Biesheuvel <[email protected]>
Cc: Lee Chun-Yi <[email protected]>
Cc: Dave Young <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Laszlo Ersek <[email protected]>
Cc: Jan Kiszka <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Bhupesh Sharma <[email protected]>
Cc: Nicolai Stange <[email protected]>
Cc: Naresh Bhat <[email protected]>
Cc: Ricardo Neri <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Taku Izumi <[email protected]>
Cc: Ravi Shankar <[email protected]>
Cc: Matt Fleming <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
---
arch/x86/platform/efi/quirks.c | 8 +++++++-
drivers/firmware/efi/fake_mem.c | 11 +++++++++--
drivers/firmware/efi/memmap.c | 12 ++++++++----
include/linux/efi.h | 4 ++--
4 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 8fce327387e5..0e607ac24a3b 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -290,7 +290,13 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
return;
}
- efi_memmap_insert(&efi.memmap, new, &mr);
+ if (efi_memmap_insert(&efi.memmap, new, &mr)) {
+ pr_err("Failed to reserve EFI memory region\n");
+ early_memunmap(new, new_size);
+ efi_memmap_free(new_phys, num_entries, alloc_type);
+ return;
+ }
+
early_memunmap(new, new_size);
/* Free existing memory map before installing new memory map */
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
index 09b0fabf07fd..ae373af6931b 100644
--- a/drivers/firmware/efi/fake_mem.c
+++ b/drivers/firmware/efi/fake_mem.c
@@ -84,8 +84,15 @@ void __init efi_fake_memmap(void)
return;
}
- for (i = 0; i < nr_fake_mem; i++)
- efi_memmap_insert(&efi.memmap, new_memmap, &fake_mems[i]);
+ for (i = 0; i < nr_fake_mem; i++) {
+ if (efi_memmap_insert(&efi.memmap, new_memmap, &fake_mems[i])) {
+ pr_err("efi_fake_mem: Failed to create fake memmap\n");
+ early_memunmap(new_memmap,
+ efi.memmap.desc_size * new_nr_map);
+ efi_memmap_free(new_memmap_phy, new_nr_map, alloc_type);
+ return;
+ }
+ }
/* swap into new EFI memmap */
early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map);
diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c
index d4e3e114cf86..05a556e63ec2 100644
--- a/drivers/firmware/efi/memmap.c
+++ b/drivers/firmware/efi/memmap.c
@@ -290,9 +290,11 @@ int __init efi_memmap_split_count(efi_memory_desc_t *md, struct range *range)
*
* It is suggested that you call efi_memmap_split_count() first
* to see how large @buf needs to be.
+ *
+ * Returns zero on success, a negative error code on failure.
*/
-void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf,
- struct efi_mem_range *mem)
+int __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf,
+ struct efi_mem_range *mem)
{
u64 m_start, m_end, m_attr;
efi_memory_desc_t *md;
@@ -311,8 +313,9 @@ void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf,
*/
if (!IS_ALIGNED(m_start, EFI_PAGE_SIZE) ||
!IS_ALIGNED(m_end + 1, EFI_PAGE_SIZE)) {
- WARN_ON(1);
- return;
+ WARN(1, "Address 0x%llx - 0x%llx is not EFI_PAGE_SIZE aligned",
+ m_start, m_end);
+ return -EINVAL;
}
for (old = old_memmap->map, new = buf;
@@ -379,4 +382,5 @@ void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf,
md->attribute |= m_attr;
}
}
+ return 0;
}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index c9752c67d184..bca955205a3f 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1023,8 +1023,8 @@ extern int __init efi_memmap_install(phys_addr_t addr, unsigned int nr_map,
enum efi_memmap_type alloc_type);
extern int __init efi_memmap_split_count(efi_memory_desc_t *md,
struct range *range);
-extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap,
- void *buf, struct efi_mem_range *mem);
+extern int __init efi_memmap_insert(struct efi_memory_map *old_memmap,
+ void *buf, struct efi_mem_range *mem);
extern void __init efi_memmap_free(phys_addr_t mem, unsigned int num_entries,
enum efi_memmap_type alloc_type);
--
2.7.4
From: Sai Praneeth <[email protected]>
efi_memmap_alloc(), as the name suggests, allocates memory for a new efi
memory map. It's referenced from couple of places, namely,
efi_arch_mem_reserve() and efi_free_boot_services(). These callers,
after allocating memory, remap it for further use. As usual, a routine
check is performed to confirm successful remap. If the remap fails,
ideally, the allocated memory should be freed but presently we just
return without freeing it up. Hence, fix this bug by freeing the memory
with efi_memmap_free().
Also, efi_fake_memmap() references efi_memmap_alloc() but it frees
memory correctly using memblock_free(), but replace it with
efi_memmap_free() to maintain consistency, as in, allocate memory with
efi_memmap_alloc() and free memory with efi_memmap_free().
It's a fact that memremap() and early_memremap() might never fail and
this code might never get a chance to run but to maintain good kernel
programming semantics, we might need this patch.
Signed-off-by: Sai Praneeth Prakhya <[email protected]>
Suggested-by: Ard Biesheuvel <[email protected]>
Cc: Lee Chun-Yi <[email protected]>
Cc: Dave Young <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Laszlo Ersek <[email protected]>
Cc: Jan Kiszka <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Bhupesh Sharma <[email protected]>
Cc: Nicolai Stange <[email protected]>
Cc: Naresh Bhat <[email protected]>
Cc: Ricardo Neri <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Taku Izumi <[email protected]>
Cc: Ravi Shankar <[email protected]>
Cc: Matt Fleming <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
---
arch/x86/platform/efi/quirks.c | 10 ++++++++--
drivers/firmware/efi/fake_mem.c | 2 +-
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 11800f3cbb93..8fce327387e5 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -286,6 +286,7 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
new = early_memremap(new_phys, new_size);
if (!new) {
pr_err("Failed to map new boot services memmap\n");
+ efi_memmap_free(new_phys, num_entries, alloc_type);
return;
}
@@ -434,7 +435,7 @@ void __init efi_free_boot_services(void)
new = memremap(new_phys, new_size, MEMREMAP_WB);
if (!new) {
pr_err("Failed to map new EFI memmap\n");
- return;
+ goto free_mem;
}
/*
@@ -460,8 +461,13 @@ void __init efi_free_boot_services(void)
efi.memmap.alloc_type);
if (efi_memmap_install(new_phys, num_entries, alloc_type)) {
pr_err("Could not install new EFI memmap\n");
- return;
+ goto free_mem;
}
+
+ return;
+
+free_mem:
+ efi_memmap_free(new_phys, num_entries, alloc_type);
}
/*
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
index a47754efb796..09b0fabf07fd 100644
--- a/drivers/firmware/efi/fake_mem.c
+++ b/drivers/firmware/efi/fake_mem.c
@@ -80,7 +80,7 @@ void __init efi_fake_memmap(void)
new_memmap = early_memremap(new_memmap_phy,
efi.memmap.desc_size * new_nr_map);
if (!new_memmap) {
- memblock_free(new_memmap_phy, efi.memmap.desc_size * new_nr_map);
+ efi_memmap_free(new_memmap_phy, new_nr_map, alloc_type);
return;
}
--
2.7.4
From: Sai Praneeth <[email protected]>
efi_memmap_install(), unmaps the existing memory map and installs a new
memory map but doesn't free the memory allocated to the existing
memory map. Fortunately, the details about the existing memory map (like
the physical address, number of entries and type of memory) are
stored in efi.memmap. Hence, use them to free the memory.
In __efi_enter_virtual_mode(), we don't use efi_memmap_install() to
install a new memory map, instead we use efi_memmap_init_late(). Hence,
free existing memory map there too before installing a new memory map.
Generally, memory for new memory map is allocated using
efi_memmap_alloc() but in __efi_enter_virtual_mode() it's done using
realloc_pages() [please see efi_map_regions()]. So, it's OK to free this
memory using efi_memmap_free() in efi_free_boot_services().
Also, note that the first time efi_free_memmap() is called either from
efi_fake_memmap() or efi_arch_mem_reserve() [depending on the boot
sequence], we are actually freeing memblock_reserved memory which isn't
allocated by efi_memmap_alloc(). So, there are two outliers where we use
efi_free_memmap() to free memory allocated through other sources
rather than efi_memmap_alloc().
Signed-off-by: Sai Praneeth Prakhya <[email protected]>
Suggested-by: Ard Biesheuvel <[email protected]>
Cc: Lee Chun-Yi <[email protected]>
Cc: Dave Young <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Laszlo Ersek <[email protected]>
Cc: Jan Kiszka <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Bhupesh Sharma <[email protected]>
Cc: Nicolai Stange <[email protected]>
Cc: Naresh Bhat <[email protected]>
Cc: Ricardo Neri <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Taku Izumi <[email protected]>
Cc: Ravi Shankar <[email protected]>
Cc: Matt Fleming <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
---
arch/x86/platform/efi/efi.c | 3 +++
arch/x86/platform/efi/quirks.c | 6 ++++++
drivers/firmware/efi/fake_mem.c | 3 +++
3 files changed, 12 insertions(+)
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index cda54abf25a6..7756426e93b5 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -952,6 +952,9 @@ static void __init __efi_enter_virtual_mode(void)
* firmware via SetVirtualAddressMap().
*/
efi_memmap_unmap();
+ /* Free existing memory map before installing new memory map */
+ efi_memmap_free(efi.memmap.phys_map, efi.memmap.nr_map,
+ efi.memmap.alloc_type);
if (efi_memmap_init_late(pa, efi.memmap.desc_size * count)) {
pr_err("Failed to remap late EFI memory map\n");
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 11fa6ac9f0c2..11800f3cbb93 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -292,6 +292,9 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
efi_memmap_insert(&efi.memmap, new, &mr);
early_memunmap(new, new_size);
+ /* Free existing memory map before installing new memory map */
+ efi_memmap_free(efi.memmap.phys_map, efi.memmap.nr_map,
+ efi.memmap.alloc_type);
efi_memmap_install(new_phys, num_entries, alloc_type);
}
@@ -452,6 +455,9 @@ void __init efi_free_boot_services(void)
memunmap(new);
+ /* Free existing memory map before installing new memory map */
+ efi_memmap_free(efi.memmap.phys_map, efi.memmap.nr_map,
+ efi.memmap.alloc_type);
if (efi_memmap_install(new_phys, num_entries, alloc_type)) {
pr_err("Could not install new EFI memmap\n");
return;
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
index 82dcfa1c340b..a47754efb796 100644
--- a/drivers/firmware/efi/fake_mem.c
+++ b/drivers/firmware/efi/fake_mem.c
@@ -90,6 +90,9 @@ void __init efi_fake_memmap(void)
/* swap into new EFI memmap */
early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map);
+ /* Free existing memory map before installing new memory map */
+ efi_memmap_free(efi.memmap.phys_map, efi.memmap.nr_map,
+ efi.memmap.alloc_type);
efi_memmap_install(new_memmap_phy, new_nr_map, alloc_type);
/* print new EFI memmap */
--
2.7.4
From: Sai Praneeth <[email protected]>
Memory used by efi memory map could be one among the three different
types, namely a) memblock_reserved b) memblock_alloc'ed c) normal paged
memory. Presently, we use efi.memmap.late which is of type "bool" to
record the type of memory in use by efi memory map. As "bool" doesn't
suffice our needs, replace it with enum to represent one among the three
different available types of memory and hence also change all the
corresponding memmap API's to reflect the same.
Also, presently, we never freed memblock_reserved memory and hence never
recorded it's usage. Change efi_memmap_init_early() so that it could now
record the usage of memblock_reserved memory and can be freed when
appropriate. Also, change efi_memmap_install() and __efi_memmap_init()
so that at every point of time we could record the type of memory in use
by efi memory map and hence use "efi.memmap.alloc_type" to free the
existing memory before installing a new memory map.
Signed-off-by: Sai Praneeth Prakhya <[email protected]>
Suggested-by: Ard Biesheuvel <[email protected]>
Cc: Lee Chun-Yi <[email protected]>
Cc: Dave Young <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Laszlo Ersek <[email protected]>
Cc: Jan Kiszka <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Bhupesh Sharma <[email protected]>
Cc: Nicolai Stange <[email protected]>
Cc: Naresh Bhat <[email protected]>
Cc: Ricardo Neri <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Taku Izumi <[email protected]>
Cc: Ravi Shankar <[email protected]>
Cc: Matt Fleming <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
---
arch/x86/platform/efi/efi.c | 4 ++--
arch/x86/platform/efi/quirks.c | 4 ++--
drivers/firmware/efi/arm-init.c | 2 +-
drivers/firmware/efi/fake_mem.c | 2 +-
drivers/firmware/efi/memmap.c | 34 +++++++++++++++++++---------------
include/linux/efi.h | 8 +++++---
6 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 9061babfbc83..cda54abf25a6 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -196,7 +196,7 @@ int __init efi_memblock_x86_reserve_range(void)
data.desc_size = e->efi_memdesc_size;
data.desc_version = e->efi_memdesc_version;
- rv = efi_memmap_init_early(&data);
+ rv = efi_memmap_init_early(&data, EFI_STUB);
if (rv)
return rv;
@@ -272,7 +272,7 @@ static void __init efi_clean_memmap(void)
u64 size = efi.memmap.nr_map - n_removal;
pr_warn("Removing %d invalid memory map entries.\n", n_removal);
- efi_memmap_install(efi.memmap.phys_map, size);
+ efi_memmap_install(efi.memmap.phys_map, size, EFI_STUB);
}
}
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 84e8d077adf6..11fa6ac9f0c2 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -292,7 +292,7 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
efi_memmap_insert(&efi.memmap, new, &mr);
early_memunmap(new, new_size);
- efi_memmap_install(new_phys, num_entries);
+ efi_memmap_install(new_phys, num_entries, alloc_type);
}
/*
@@ -452,7 +452,7 @@ void __init efi_free_boot_services(void)
memunmap(new);
- if (efi_memmap_install(new_phys, num_entries)) {
+ if (efi_memmap_install(new_phys, num_entries, alloc_type)) {
pr_err("Could not install new EFI memmap\n");
return;
}
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index b5214c143fee..f0de8df6f396 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -239,7 +239,7 @@ void __init efi_init(void)
data.size = params.mmap_size;
data.phys_map = params.mmap;
- if (efi_memmap_init_early(&data) < 0) {
+ if (efi_memmap_init_early(&data, EFI_STUB) < 0) {
/*
* If we are booting via UEFI, the UEFI memory map is the only
* description of memory we have, so there is little point in
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
index 955e690b8325..82dcfa1c340b 100644
--- a/drivers/firmware/efi/fake_mem.c
+++ b/drivers/firmware/efi/fake_mem.c
@@ -90,7 +90,7 @@ void __init efi_fake_memmap(void)
/* swap into new EFI memmap */
early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map);
- efi_memmap_install(new_memmap_phy, new_nr_map);
+ efi_memmap_install(new_memmap_phy, new_nr_map, alloc_type);
/* print new EFI memmap */
efi_print_memmap();
diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c
index 69b81d355619..d4e3e114cf86 100644
--- a/drivers/firmware/efi/memmap.c
+++ b/drivers/firmware/efi/memmap.c
@@ -88,7 +88,7 @@ void __init efi_memmap_free(phys_addr_t mem, unsigned int num_entries,
/**
* __efi_memmap_init - Common code for mapping the EFI memory map
* @data: EFI memory map data
- * @late: Use early or late mapping function?
+ * @alloc_type: Use early or late mapping function?
*
* This function takes care of figuring out which function to use to
* map the EFI memory map in efi.memmap based on how far into the boot
@@ -101,8 +101,8 @@ void __init efi_memmap_free(phys_addr_t mem, unsigned int num_entries,
*
* Returns zero on success, a negative error code on failure.
*/
-static int __init
-__efi_memmap_init(struct efi_memory_map_data *data, bool late)
+static int __init __efi_memmap_init(struct efi_memory_map_data *data,
+ enum efi_memmap_type alloc_type)
{
struct efi_memory_map map;
phys_addr_t phys_map;
@@ -112,7 +112,7 @@ __efi_memmap_init(struct efi_memory_map_data *data, bool late)
phys_map = data->phys_map;
- if (late)
+ if (alloc_type == BUDDY_ALLOCATOR)
map.map = memremap(phys_map, data->size, MEMREMAP_WB);
else
map.map = early_memremap(phys_map, data->size);
@@ -128,7 +128,7 @@ __efi_memmap_init(struct efi_memory_map_data *data, bool late)
map.desc_version = data->desc_version;
map.desc_size = data->desc_size;
- map.late = late;
+ map.alloc_type = alloc_type;
set_bit(EFI_MEMMAP, &efi.flags);
@@ -140,27 +140,29 @@ __efi_memmap_init(struct efi_memory_map_data *data, bool late)
/**
* efi_memmap_init_early - Map the EFI memory map data structure
* @data: EFI memory map data
+ * @alloc_type: Type of allocated memory map (EFI_STUB or MEMBLOCK)?
*
* Use early_memremap() to map the passed in EFI memory map and assign
* it to efi.memmap.
*/
-int __init efi_memmap_init_early(struct efi_memory_map_data *data)
+int __init efi_memmap_init_early(struct efi_memory_map_data *data,
+ enum efi_memmap_type alloc_type)
{
/* Cannot go backwards */
- WARN_ON(efi.memmap.late);
+ WARN_ON(efi.memmap.alloc_type == BUDDY_ALLOCATOR);
- return __efi_memmap_init(data, false);
+ return __efi_memmap_init(data, alloc_type);
}
void __init efi_memmap_unmap(void)
{
- if (!efi.memmap.late) {
+ if (efi.memmap.alloc_type == BUDDY_ALLOCATOR) {
+ memunmap(efi.memmap.map);
+ } else {
unsigned long size;
size = efi.memmap.desc_size * efi.memmap.nr_map;
early_memunmap(efi.memmap.map, size);
- } else {
- memunmap(efi.memmap.map);
}
efi.memmap.map = NULL;
@@ -201,7 +203,7 @@ int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size)
WARN_ON(efi.memmap.map);
/* Were we already called? */
- WARN_ON(efi.memmap.late);
+ WARN_ON(efi.memmap.alloc_type == BUDDY_ALLOCATOR);
/*
* It makes no sense to allow callers to register different
@@ -211,13 +213,14 @@ int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size)
data.desc_version = efi.memmap.desc_version;
data.desc_size = efi.memmap.desc_size;
- return __efi_memmap_init(&data, true);
+ return __efi_memmap_init(&data, BUDDY_ALLOCATOR);
}
/**
* efi_memmap_install - Install a new EFI memory map in efi.memmap
* @addr: Physical address of the memory map
* @nr_map: Number of entries in the memory map
+ * @alloc_type: Type of allocation performed to get @addr.
*
* Unlike efi_memmap_init_*(), this function does not allow the caller
* to switch from early to late mappings. It simply uses the existing
@@ -225,7 +228,8 @@ int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size)
*
* Returns zero on success, a negative error code on failure.
*/
-int __init efi_memmap_install(phys_addr_t addr, unsigned int nr_map)
+int __init efi_memmap_install(phys_addr_t addr, unsigned int nr_map,
+ enum efi_memmap_type alloc_type)
{
struct efi_memory_map_data data;
@@ -236,7 +240,7 @@ int __init efi_memmap_install(phys_addr_t addr, unsigned int nr_map)
data.desc_version = efi.memmap.desc_version;
data.desc_size = efi.memmap.desc_size;
- return __efi_memmap_init(&data, efi.memmap.late);
+ return __efi_memmap_init(&data, alloc_type);
}
/**
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 53495e854d2a..c9752c67d184 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -778,7 +778,7 @@ struct efi_memory_map {
int nr_map;
unsigned long desc_version;
unsigned long desc_size;
- bool late;
+ enum efi_memmap_type alloc_type;
};
struct efi_mem_range {
@@ -1015,10 +1015,12 @@ extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
extern phys_addr_t __init efi_memmap_alloc(unsigned int num_entries,
enum efi_memmap_type *alloc_type);
-extern int __init efi_memmap_init_early(struct efi_memory_map_data *data);
+extern int __init efi_memmap_init_early(struct efi_memory_map_data *data,
+ enum efi_memmap_type alloc_type);
extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size);
extern void __init efi_memmap_unmap(void);
-extern int __init efi_memmap_install(phys_addr_t addr, unsigned int nr_map);
+extern int __init efi_memmap_install(phys_addr_t addr, unsigned int nr_map,
+ enum efi_memmap_type alloc_type);
extern int __init efi_memmap_split_count(efi_memory_desc_t *md,
struct range *range);
extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap,
--
2.7.4
From: Sai Praneeth <[email protected]>
efi_memmap_alloc(), as the name suggests, allocates memory for a new efi
memory map and it does so depending on whether mm_init() has already
been invoked or not. As we have introduced efi_memmap_free() to free the
memory allocated by efi_memmap_alloc(), modify efi_memmap_alloc() to
include "efi_memmap_type", so that the caller of efi_memmap_alloc() will
know the type of allocation performed and later use the same to free the
memory should remap fail. Without "efi_memmap_type" there would be no
way for efi_memmap_free() to know the type of allocation performed by
efi_memmap_alloc().
Also, "efi_memmap_type" will make sure that efi_memmap_alloc() and
efi_memmap_free() are always binded properly i.e. a user could use
efi_memmap_alloc() before slab_is_available() and use efi_memmap_free()
on the same memory but after slab_is_available(). Without
"efi_memmap_type", efi_memmap_free() would be using wrong free variant.
With "efi_memmap_type", we make this relationship between
efi_memmap_alloc() and efi_memmap_free() explicit to the user.
Signed-off-by: Sai Praneeth Prakhya <[email protected]>
Suggested-by: Ard Biesheuvel <[email protected]>
Cc: Lee Chun-Yi <[email protected]>
Cc: Dave Young <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Laszlo Ersek <[email protected]>
Cc: Jan Kiszka <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Bhupesh Sharma <[email protected]>
Cc: Nicolai Stange <[email protected]>
Cc: Naresh Bhat <[email protected]>
Cc: Ricardo Neri <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Taku Izumi <[email protected]>
Cc: Ravi Shankar <[email protected]>
Cc: Matt Fleming <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
---
arch/x86/platform/efi/quirks.c | 6 ++++--
drivers/firmware/efi/fake_mem.c | 3 ++-
drivers/firmware/efi/memmap.c | 12 ++++++++++--
include/linux/efi.h | 3 ++-
4 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 36c1f8b9f7e0..84e8d077adf6 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -248,6 +248,7 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
efi_memory_desc_t md;
int num_entries;
void *new;
+ enum efi_memmap_type alloc_type;
if (efi_mem_desc_lookup(addr, &md)) {
pr_err("Failed to lookup EFI memory descriptor for %pa\n", &addr);
@@ -276,7 +277,7 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
new_size = efi.memmap.desc_size * num_entries;
- new_phys = efi_memmap_alloc(num_entries);
+ new_phys = efi_memmap_alloc(num_entries, &alloc_type);
if (!new_phys) {
pr_err("Could not allocate boot services memmap\n");
return;
@@ -375,6 +376,7 @@ void __init efi_free_boot_services(void)
efi_memory_desc_t *md;
int num_entries = 0;
void *new, *new_md;
+ enum efi_memmap_type alloc_type;
for_each_efi_memory_desc(md) {
unsigned long long start = md->phys_addr;
@@ -420,7 +422,7 @@ void __init efi_free_boot_services(void)
return;
new_size = efi.memmap.desc_size * num_entries;
- new_phys = efi_memmap_alloc(num_entries);
+ new_phys = efi_memmap_alloc(num_entries, &alloc_type);
if (!new_phys) {
pr_err("Failed to allocate new EFI memmap\n");
return;
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
index 6c7d60c239b5..955e690b8325 100644
--- a/drivers/firmware/efi/fake_mem.c
+++ b/drivers/firmware/efi/fake_mem.c
@@ -57,6 +57,7 @@ void __init efi_fake_memmap(void)
phys_addr_t new_memmap_phy;
void *new_memmap;
int i;
+ enum efi_memmap_type alloc_type;
if (!nr_fake_mem)
return;
@@ -71,7 +72,7 @@ void __init efi_fake_memmap(void)
}
/* allocate memory for new EFI memmap */
- new_memmap_phy = efi_memmap_alloc(new_nr_map);
+ new_memmap_phy = efi_memmap_alloc(new_nr_map, &alloc_type);
if (!new_memmap_phy)
return;
diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c
index 0686e063c644..69b81d355619 100644
--- a/drivers/firmware/efi/memmap.c
+++ b/drivers/firmware/efi/memmap.c
@@ -33,6 +33,7 @@ static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
/**
* efi_memmap_alloc - Allocate memory for the EFI memory map
* @num_entries: Number of entries in the allocated map.
+ * @alloc_type: Type of allocation performed (memblock or normal)?
*
* Depending on whether mm_init() has already been invoked or not,
* either memblock or "normal" page allocation is used.
@@ -40,13 +41,20 @@ static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
* Returns the physical address of the allocated memory map on
* success, zero on failure.
*/
-phys_addr_t __init efi_memmap_alloc(unsigned int num_entries)
+phys_addr_t __init efi_memmap_alloc(unsigned int num_entries,
+ enum efi_memmap_type *alloc_type)
{
unsigned long size = num_entries * efi.memmap.desc_size;
- if (slab_is_available())
+ if (!alloc_type)
+ return 0;
+
+ if (slab_is_available()) {
+ *alloc_type = BUDDY_ALLOCATOR;
return __efi_memmap_alloc_late(size);
+ }
+ *alloc_type = MEMBLOCK;
return __efi_memmap_alloc_early(size);
}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 455875c01ed1..53495e854d2a 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1013,7 +1013,8 @@ static inline efi_status_t efi_query_variable_store(u32 attributes,
#endif
extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
-extern phys_addr_t __init efi_memmap_alloc(unsigned int num_entries);
+extern phys_addr_t __init efi_memmap_alloc(unsigned int num_entries,
+ enum efi_memmap_type *alloc_type);
extern int __init efi_memmap_init_early(struct efi_memory_map_data *data);
extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size);
extern void __init efi_memmap_unmap(void);
--
2.7.4
On 3 July 2018 at 03:50, Sai Praneeth Prakhya
<[email protected]> wrote:
> From: Sai Praneeth <[email protected]>
>
> efi_memmap_alloc() allocates memory depending on whether mm_init() has
> already been invoked or not. Apart from memblock_alloc() memory and
> alloc_pages() memory, efi memory map could also have a third variant of
> memory allocation and that is memblock_reserved. This happens only for
> the memory map passed to kernel by firmware and thus can happen only
> once during boot process.
>
> In order to identify these three different types of allocations and thus
> to call the appropriate free() variant, introduce an enum named
> efi_memmap_type and also introduce a efi memmap API named
> efi_memmap_free() to free memory allocated by efi_memmap_alloc().
>
> Signed-off-by: Sai Praneeth Prakhya <[email protected]>
> Suggested-by: Ard Biesheuvel <[email protected]>
> Cc: Lee Chun-Yi <[email protected]>
> Cc: Dave Young <[email protected]>
> Cc: Borislav Petkov <[email protected]>
> Cc: Laszlo Ersek <[email protected]>
> Cc: Jan Kiszka <[email protected]>
> Cc: Dave Hansen <[email protected]>
> Cc: Bhupesh Sharma <[email protected]>
> Cc: Nicolai Stange <[email protected]>
> Cc: Naresh Bhat <[email protected]>
> Cc: Ricardo Neri <[email protected]>
> Cc: Peter Zijlstra <[email protected]>
> Cc: Taku Izumi <[email protected]>
> Cc: Ravi Shankar <[email protected]>
> Cc: Matt Fleming <[email protected]>
> Cc: Dan Williams <[email protected]>
> Cc: Ard Biesheuvel <[email protected]>
Do you really think you should cc all these people?
> ---
> drivers/firmware/efi/memmap.c | 28 ++++++++++++++++++++++++++++
> include/linux/efi.h | 8 ++++++++
> 2 files changed, 36 insertions(+)
>
> diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c
> index 5fc70520e04c..0686e063c644 100644
> --- a/drivers/firmware/efi/memmap.c
> +++ b/drivers/firmware/efi/memmap.c
> @@ -12,6 +12,7 @@
> #include <asm/early_ioremap.h>
> #include <linux/memblock.h>
> #include <linux/slab.h>
> +#include <linux/bootmem.h>
>
> static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size)
> {
> @@ -50,6 +51,33 @@ phys_addr_t __init efi_memmap_alloc(unsigned int num_entries)
> }
>
> /**
> + * efi_memmap_free - Free memory allocated by efi_memmap_alloc()
> + * @mem: Physical address allocated by efi_memmap_alloc().
> + * @num_entries: Number of entries in the allocated map.
> + * @alloc_type: What type of allocation did efi_memmap_alloc() perform?
> + *
> + * Use this function to free memory allocated by efi_memmap_alloc().
> + * efi_memmap_alloc() allocates memory depending on whether mm_init()
> + * has already been invoked or not. It uses either memblock or "normal"
> + * page allocation, similarly, we free it in two different ways. Also
> + * note that there is a third type of memory used by memmap which is
> + * memblock_reserved() and is passed by EFI stub to kernel.
> + */
> +void __init efi_memmap_free(phys_addr_t mem, unsigned int num_entries,
> + enum efi_memmap_type alloc_type)
> +{
> + unsigned long size = num_entries * efi.memmap.desc_size;
> + unsigned int order = get_order(size);
> +
> + if (alloc_type == BUDDY_ALLOCATOR)
> + __free_pages(pfn_to_page(PHYS_PFN(mem)), order);
> + else if (alloc_type == MEMBLOCK)
> + memblock_free(mem, size);
> + else
> + free_bootmem(mem, size);
> +}
> +
> +/**
> * __efi_memmap_init - Common code for mapping the EFI memory map
> * @data: EFI memory map data
> * @late: Use early or late mapping function?
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 56add823f190..455875c01ed1 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -765,6 +765,12 @@ struct efi_memory_map_data {
> unsigned long desc_size;
> };
>
> +enum efi_memmap_type {
> + EFI_STUB,
> + MEMBLOCK,
> + BUDDY_ALLOCATOR,
> +};
> +
> struct efi_memory_map {
> phys_addr_t phys_map;
> void *map;
> @@ -1016,6 +1022,8 @@ extern int __init efi_memmap_split_count(efi_memory_desc_t *md,
> struct range *range);
> extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap,
> void *buf, struct efi_mem_range *mem);
> +extern void __init efi_memmap_free(phys_addr_t mem, unsigned int num_entries,
> + enum efi_memmap_type alloc_type);
>
> extern int efi_config_init(efi_config_table_type_t *arch_tables);
> #ifdef CONFIG_EFI_ESRT
> --
> 2.7.4
>
Sai,
Thanks a lot for respinning all of this.
I am now thinking we should perhaps hide the allocation type from the
callers rather than passing around implementation details of the
allocator, and have explicit alloc/free operations.
Could we instead have a single 'efi_realloc_memmap()' function that
takes care of all of this? We'd still need a free routine for error
handling, I suppose, but it would get rid of the need for obscure
enums or bools that the callers have to pass around.
> > Signed-off-by: Sai Praneeth Prakhya <[email protected]>
> > Suggested-by: Ard Biesheuvel <[email protected]>
> > Cc: Lee Chun-Yi <[email protected]>
> > Cc: Dave Young <[email protected]>
> > Cc: Borislav Petkov <[email protected]>
> > Cc: Laszlo Ersek <[email protected]>
> > Cc: Jan Kiszka <[email protected]>
> > Cc: Dave Hansen <[email protected]>
> > Cc: Bhupesh Sharma <[email protected]>
> > Cc: Nicolai Stange <[email protected]>
> > Cc: Naresh Bhat <[email protected]>
> > Cc: Ricardo Neri <[email protected]>
> > Cc: Peter Zijlstra <[email protected]>
> > Cc: Taku Izumi <[email protected]>
> > Cc: Ravi Shankar <[email protected]>
> > Cc: Matt Fleming <[email protected]>
> > Cc: Dan Williams <[email protected]>
> > Cc: Ard Biesheuvel <[email protected]>
>
> Do you really think you should cc all these people?
>
Sorry! I get that..
> > ---
> > drivers/firmware/efi/memmap.c | 28 ++++++++++++++++++++++++++++
> > include/linux/efi.h | 8 ++++++++
> > 2 files changed, 36 insertions(+)
> >
[snip]
> I am now thinking we should perhaps hide the allocation type from the callers
> rather than passing around implementation details of the allocator, and have
> explicit alloc/free operations.
>
> Could we instead have a single 'efi_realloc_memmap()' function that takes care
> of all of this?
Sure! I will give it a try.
Regards,
Sai