efi: Iterate over efi.memmap in for_each_efi_memory_desc()
authorMatt Fleming <matt@codeblueprint.co.uk>
Mon, 25 Apr 2016 20:06:38 +0000 (21:06 +0100)
committerIngo Molnar <mingo@kernel.org>
Thu, 28 Apr 2016 09:33:50 +0000 (11:33 +0200)
Most of the users of for_each_efi_memory_desc() are equally happy
iterating over the EFI memory map in efi.memmap instead of 'memmap',
since the former is usually a pointer to the latter.

For those users that want to specify an EFI memory map other than
efi.memmap, that can be done using for_each_efi_memory_desc_in_map().
One such example is in the libstub code where the firmware is queried
directly for the memory map, it gets iterated over, and then freed.

This change goes part of the way toward deleting the global 'memmap'
variable, which is not universally available on all architectures
(notably IA64) and is rather poorly named.

Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Mark Salter <msalter@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/1461614832-17633-7-git-send-email-matt@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/efi_64.c
arch/x86/platform/efi/quirks.c
drivers/firmware/efi/arm-init.c
drivers/firmware/efi/arm-runtime.c
drivers/firmware/efi/efi.c
drivers/firmware/efi/fake_mem.c
drivers/firmware/efi/libstub/efi-stub-helper.c
include/linux/efi.h

index df393eab0e509bd63da08b1da6a3ec8f435b91a8..6f499819a27f954d4e4db1a2ead41627de66cf63 100644 (file)
@@ -119,11 +119,10 @@ void efi_get_time(struct timespec *now)
 
 void __init efi_find_mirror(void)
 {
-       void *p;
+       efi_memory_desc_t *md;
        u64 mirror_size = 0, total_size = 0;
 
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               efi_memory_desc_t *md = p;
+       for_each_efi_memory_desc(md) {
                unsigned long long start = md->phys_addr;
                unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
 
@@ -146,10 +145,9 @@ void __init efi_find_mirror(void)
 
 static void __init do_add_efi_memmap(void)
 {
-       void *p;
+       efi_memory_desc_t *md;
 
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               efi_memory_desc_t *md = p;
+       for_each_efi_memory_desc(md) {
                unsigned long long start = md->phys_addr;
                unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
                int e820_type;
@@ -226,17 +224,13 @@ void __init efi_print_memmap(void)
 {
 #ifdef EFI_DEBUG
        efi_memory_desc_t *md;
-       void *p;
-       int i;
+       int i = 0;
 
-       for (p = memmap.map, i = 0;
-            p < memmap.map_end;
-            p += memmap.desc_size, i++) {
+       for_each_efi_memory_desc(md) {
                char buf[64];
 
-               md = p;
                pr_info("mem%02u: %s range=[0x%016llx-0x%016llx] (%lluMB)\n",
-                       i, efi_md_typeattr_format(buf, sizeof(buf), md),
+                       i++, efi_md_typeattr_format(buf, sizeof(buf), md),
                        md->phys_addr,
                        md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1,
                        (md->num_pages >> (20 - EFI_PAGE_SHIFT)));
@@ -550,12 +544,9 @@ void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
 void __init runtime_code_page_mkexec(void)
 {
        efi_memory_desc_t *md;
-       void *p;
 
        /* Make EFI runtime service code area executable */
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               md = p;
-
+       for_each_efi_memory_desc(md) {
                if (md->type != EFI_RUNTIME_SERVICES_CODE)
                        continue;
 
@@ -602,12 +593,10 @@ void __init old_map_region(efi_memory_desc_t *md)
 /* Merge contiguous regions of the same type and attribute */
 static void __init efi_merge_regions(void)
 {
-       void *p;
        efi_memory_desc_t *md, *prev_md = NULL;
 
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+       for_each_efi_memory_desc(md) {
                u64 prev_size;
-               md = p;
 
                if (!prev_md) {
                        prev_md = md;
@@ -650,15 +639,13 @@ static void __init save_runtime_map(void)
 {
 #ifdef CONFIG_KEXEC_CORE
        efi_memory_desc_t *md;
-       void *tmp, *p, *q = NULL;
+       void *tmp, *q = NULL;
        int count = 0;
 
        if (efi_enabled(EFI_OLD_MEMMAP))
                return;
 
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               md = p;
-
+       for_each_efi_memory_desc(md) {
                if (!(md->attribute & EFI_MEMORY_RUNTIME) ||
                    (md->type == EFI_BOOT_SERVICES_CODE) ||
                    (md->type == EFI_BOOT_SERVICES_DATA))
@@ -814,7 +801,6 @@ static void __init kexec_enter_virtual_mode(void)
 #ifdef CONFIG_KEXEC_CORE
        efi_memory_desc_t *md;
        unsigned int num_pages;
-       void *p;
 
        efi.systab = NULL;
 
@@ -838,8 +824,7 @@ static void __init kexec_enter_virtual_mode(void)
        * Map efi regions which were passed via setup_data. The virt_addr is a
        * fixed addr which was used in first kernel of a kexec boot.
        */
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               md = p;
+       for_each_efi_memory_desc(md) {
                efi_map_region_fixed(md); /* FIXME: add error handling */
                get_systab_virt_addr(md);
        }
@@ -1009,13 +994,11 @@ void __init efi_enter_virtual_mode(void)
 u32 efi_mem_type(unsigned long phys_addr)
 {
        efi_memory_desc_t *md;
-       void *p;
 
        if (!efi_enabled(EFI_MEMMAP))
                return 0;
 
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               md = p;
+       for_each_efi_memory_desc(md) {
                if ((md->phys_addr <= phys_addr) &&
                    (phys_addr < (md->phys_addr +
                                  (md->num_pages << EFI_PAGE_SHIFT))))
index 49e4dd4a1f58257630c8b341bf8b12922200cd2e..6e7242be1c8744b89af4a96587fb79d3a387e77a 100644 (file)
@@ -55,14 +55,12 @@ struct efi_scratch efi_scratch;
 static void __init early_code_mapping_set_exec(int executable)
 {
        efi_memory_desc_t *md;
-       void *p;
 
        if (!(__supported_pte_mask & _PAGE_NX))
                return;
 
        /* Make EFI service code area executable */
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               md = p;
+       for_each_efi_memory_desc(md) {
                if (md->type == EFI_RUNTIME_SERVICES_CODE ||
                    md->type == EFI_BOOT_SERVICES_CODE)
                        efi_set_executable(md, executable);
@@ -253,7 +251,7 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
         * Map all of RAM so that we can access arguments in the 1:1
         * mapping when making EFI runtime calls.
         */
-       for_each_efi_memory_desc(&memmap, md) {
+       for_each_efi_memory_desc(md) {
                if (md->type != EFI_CONVENTIONAL_MEMORY &&
                    md->type != EFI_LOADER_DATA &&
                    md->type != EFI_LOADER_CODE)
@@ -398,7 +396,6 @@ void __init efi_runtime_update_mappings(void)
        unsigned long pfn;
        pgd_t *pgd = efi_pgd;
        efi_memory_desc_t *md;
-       void *p;
 
        if (efi_enabled(EFI_OLD_MEMMAP)) {
                if (__supported_pte_mask & _PAGE_NX)
@@ -409,9 +406,8 @@ void __init efi_runtime_update_mappings(void)
        if (!efi_enabled(EFI_NX_PE_DATA))
                return;
 
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+       for_each_efi_memory_desc(md) {
                unsigned long pf = 0;
-               md = p;
 
                if (!(md->attribute & EFI_MEMORY_RUNTIME))
                        continue;
index ab50ada1d56e4f87f6fff3207995ea32312fb37b..097cb09d917b1f826c13d6fb498115a2dd690d31 100644 (file)
@@ -195,10 +195,9 @@ static bool can_free_region(u64 start, u64 size)
 */
 void __init efi_reserve_boot_services(void)
 {
-       void *p;
+       efi_memory_desc_t *md;
 
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               efi_memory_desc_t *md = p;
+       for_each_efi_memory_desc(md) {
                u64 start = md->phys_addr;
                u64 size = md->num_pages << EFI_PAGE_SHIFT;
                bool already_reserved;
@@ -250,10 +249,9 @@ void __init efi_reserve_boot_services(void)
 
 void __init efi_free_boot_services(void)
 {
-       void *p;
+       efi_memory_desc_t *md;
 
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               efi_memory_desc_t *md = p;
+       for_each_efi_memory_desc(md) {
                unsigned long long start = md->phys_addr;
                unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
 
index 008ed1993b720da5eec2a858f4faddb7a7f53f93..d5f6b0ca521e7d49b5070f4cd043c3c064d86344 100644 (file)
@@ -40,7 +40,7 @@ static phys_addr_t efi_to_phys(unsigned long addr)
 {
        efi_memory_desc_t *md;
 
-       for_each_efi_memory_desc(&memmap, md) {
+       for_each_efi_memory_desc_in_map(&memmap, md) {
                if (!(md->attribute & EFI_MEMORY_RUNTIME))
                        continue;
                if (md->virt_addr == 0)
@@ -145,7 +145,7 @@ static __init void reserve_regions(void)
        if (efi_enabled(EFI_DBG))
                pr_info("Processing EFI memory map:\n");
 
-       for_each_efi_memory_desc(&memmap, md) {
+       for_each_efi_memory_desc_in_map(&memmap, md) {
                paddr = md->phys_addr;
                npages = md->num_pages;
 
index 771750df6b7dbe3f083b2920236f4174c31f34cc..1cfbfaf57a2d9683dd9153d72d78b75228b8a85a 100644 (file)
@@ -48,7 +48,7 @@ static bool __init efi_virtmap_init(void)
        init_new_context(NULL, &efi_mm);
 
        systab_found = false;
-       for_each_efi_memory_desc(&memmap, md) {
+       for_each_efi_memory_desc(md) {
                phys_addr_t phys = md->phys_addr;
                int ret;
 
index 3a69ed5ecfcb5f1254eaf1b0c3fb53cbdbcc61fb..4b533ce733747b4a1aea389ec24b79e14398045d 100644 (file)
@@ -620,16 +620,12 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
  */
 u64 __weak efi_mem_attributes(unsigned long phys_addr)
 {
-       struct efi_memory_map *map;
        efi_memory_desc_t *md;
-       void *p;
 
        if (!efi_enabled(EFI_MEMMAP))
                return 0;
 
-       map = efi.memmap;
-       for (p = map->map; p < map->map_end; p += map->desc_size) {
-               md = p;
+       for_each_efi_memory_desc(md) {
                if ((md->phys_addr <= phys_addr) &&
                    (phys_addr < (md->phys_addr +
                    (md->num_pages << EFI_PAGE_SHIFT))))
index ed3a854950cca80b0a29bb8a38362d61b083b701..f55b75b2e1f4c44bdfa81ab3ffc626ffd8125ffa 100644 (file)
@@ -68,8 +68,7 @@ void __init efi_fake_memmap(void)
                return;
 
        /* count up the number of EFI memory descriptor */
-       for (old = memmap.map; old < memmap.map_end; old += memmap.desc_size) {
-               md = old;
+       for_each_efi_memory_desc(md) {
                start = md->phys_addr;
                end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1;
 
index 29ed2f9b218ca9892bfcc72da2d91ba4750f4c97..3bd127f953151dff89d0563db13deb12046e4315 100644 (file)
@@ -125,10 +125,12 @@ unsigned long get_dram_base(efi_system_table_t *sys_table_arg)
 
        map.map_end = map.map + map_size;
 
-       for_each_efi_memory_desc(&map, md)
-               if (md->attribute & EFI_MEMORY_WB)
+       for_each_efi_memory_desc_in_map(&map, md) {
+               if (md->attribute & EFI_MEMORY_WB) {
                        if (membase > md->phys_addr)
                                membase = md->phys_addr;
+               }
+       }
 
        efi_call_early(free_pool, map.map);
 
index 1545098b056530b5dfd64bc11a48f880a10d8c4f..17ef4471e6034f0e691a96ea88558f53da761afe 100644 (file)
@@ -958,11 +958,20 @@ static inline void efi_fake_memmap(void) { }
 #endif
 
 /* Iterate through an efi_memory_map */
-#define for_each_efi_memory_desc(m, md)                                           \
+#define for_each_efi_memory_desc_in_map(m, md)                            \
        for ((md) = (m)->map;                                              \
             (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \
             (md) = (void *)(md) + (m)->desc_size)
 
+/**
+ * for_each_efi_memory_desc - iterate over descriptors in efi.memmap
+ * @md: the efi_memory_desc_t * iterator
+ *
+ * Once the loop finishes @md must not be accessed.
+ */
+#define for_each_efi_memory_desc(md) \
+       for_each_efi_memory_desc_in_map(efi.memmap, md)
+
 /*
  * Format an EFI memory descriptor's type and attributes to a user-provided
  * character buffer, as per snprintf(), and return the buffer.