There are about a dozen places in the x86 EFI code which loop through the EFI memory map descriptors. All of these places use essentially the same for-loop code. This patch adds a for_each_efi_memory_desc() helper to clean up all of the duplicate code and make it available for other architectures to use. Signed-off-by: Mark Salter <msalter@xxxxxxxxxx> --- arch/x86/platform/efi/efi.c | 48 +++++++++++++----------------------------- arch/x86/platform/efi/efi_64.c | 5 +---- drivers/firmware/efi/efi.c | 5 ++--- include/linux/efi.h | 6 ++++++ 4 files changed, 24 insertions(+), 40 deletions(-) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index cceb813..211aa57 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -328,10 +328,9 @@ void efi_get_time(struct timespec *now) 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(&memmap, md) { unsigned long long start = md->phys_addr; unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; int e820_type; @@ -402,16 +401,12 @@ int __init efi_memblock_x86_reserve_range(void) static void __init print_efi_memmap(void) { 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++) { - md = p; + for_each_efi_memory_desc(&memmap, md) { pr_info("mem%02u: type=%u, attr=0x%llx, " "range=[0x%016llx-0x%016llx) (%lluMB)\n", - i, md->type, md->attribute, md->phys_addr, + i++, md->type, md->attribute, md->phys_addr, md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), (md->num_pages >> (20 - EFI_PAGE_SHIFT))); } @@ -420,10 +415,9 @@ static void __init print_efi_memmap(void) 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(&memmap, md) { u64 start = md->phys_addr; u64 size = md->num_pages << EFI_PAGE_SHIFT; @@ -461,13 +455,12 @@ void __init efi_unmap_memmap(void) void __init efi_free_boot_services(void) { - void *p; + efi_memory_desc_t *md; if (!efi_is_native()) return; - for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { - efi_memory_desc_t *md = p; + for_each_efi_memory_desc(&memmap, md) { unsigned long long start = md->phys_addr; unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; @@ -718,12 +711,9 @@ void __init efi_set_executable(efi_memory_desc_t *md, bool executable) static 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(&memmap, md) { if (md->type != EFI_RUNTIME_SERVICES_CODE) continue; @@ -755,7 +745,7 @@ void __init efi_enter_virtual_mode(void) efi_status_t status; unsigned long size; u64 end, systab, start_pfn, end_pfn; - void *p, *va, *new_memmap = NULL; + void *va, *new_memmap = NULL; int count = 0; efi.systab = NULL; @@ -771,9 +761,8 @@ void __init efi_enter_virtual_mode(void) } /* Merge contiguous regions of the same type and attribute */ - for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + for_each_efi_memory_desc(&memmap, md) { u64 prev_size; - md = p; if (!prev_md) { prev_md = md; @@ -797,8 +786,7 @@ void __init efi_enter_virtual_mode(void) prev_md = md; } - for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { - md = p; + for_each_efi_memory_desc(&memmap, md) { if (!(md->attribute & EFI_MEMORY_RUNTIME)) { #ifdef CONFIG_X86_64 if (md->type != EFI_BOOT_SERVICES_CODE && @@ -895,33 +883,27 @@ 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(&memmap, md) if ((md->phys_addr <= phys_addr) && (phys_addr < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)))) return md->type; - } return 0; } u64 efi_mem_attributes(unsigned long phys_addr) { efi_memory_desc_t *md; - void *p; - for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { - md = p; + for_each_efi_memory_desc(&memmap, md) if ((md->phys_addr <= phys_addr) && (phys_addr < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)))) return md->attribute; - } return 0; } diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 39a0e7f..90aaefc 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -45,18 +45,15 @@ static unsigned long efi_flags __initdata; 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(&memmap, md) if (md->type == EFI_RUNTIME_SERVICES_CODE || md->type == EFI_BOOT_SERVICES_CODE) efi_set_executable(md, executable); - } } void __init efi_call_phys_prelog(void) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 2e2fbde..70648da 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -158,14 +158,13 @@ subsys_initcall(efisubsys_init); void __iomem *efi_lookup_mapped_addr(u64 phys_addr) { struct efi_memory_map *map; - void *p; + efi_memory_desc_t *md; map = efi.memmap; if (!map) return NULL; if (WARN_ON(!map->map)) return NULL; - for (p = map->map; p < map->map_end; p += map->desc_size) { - efi_memory_desc_t *md = p; + for_each_efi_memory_desc(map, md) { u64 size = md->num_pages << EFI_PAGE_SHIFT; u64 end = md->phys_addr + size; if (!(md->attribute & EFI_MEMORY_RUNTIME) && diff --git a/include/linux/efi.h b/include/linux/efi.h index 11ce678..9dc5b05 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -618,6 +618,12 @@ extern int efi_set_rtc_mmss(const struct timespec *now); extern void efi_reserve_boot_services(void); extern struct efi_memory_map memmap; +/* Iterate through an efi_memory_map */ +#define for_each_efi_memory_desc(m, md) \ + for ((md) = (m)->map; \ + (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \ + (md) = (void *)(md) + (m)->desc_size) + /** * efi_range_is_wc - check the WC bit on an address range * @start: starting kvirt address -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html