[PATCH 1/6] efi: Introduce efi_memmap_free() to free memory allocated by efi_memmap_alloc()

From: Sai Praneeth Prakhya
Date: Mon Jul 02 2018 - 21:51:30 EST


From: Sai Praneeth <sai.praneeth.prakhya@xxxxxxxxx>

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 <sai.praneeth.prakhya@xxxxxxxxx>
Suggested-by: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx>
Cc: Lee Chun-Yi <jlee@xxxxxxxx>
Cc: Dave Young <dyoung@xxxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxxxx>
Cc: Laszlo Ersek <lersek@xxxxxxxxxx>
Cc: Jan Kiszka <jan.kiszka@xxxxxxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxx>
Cc: Bhupesh Sharma <bhsharma@xxxxxxxxxx>
Cc: Nicolai Stange <nicstange@xxxxxxxxx>
Cc: Naresh Bhat <naresh.bhat@xxxxxxxxxx>
Cc: Ricardo Neri <ricardo.neri@xxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Taku Izumi <izumi.taku@xxxxxxxxxxxxxx>
Cc: Ravi Shankar <ravi.v.shankar@xxxxxxxxx>
Cc: Matt Fleming <matt@xxxxxxxxxxxxxxxxxxx>
Cc: Dan Williams <dan.j.williams@xxxxxxxxx>
Cc: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx>
---
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