efi: Fix efi_memmap_alloc() leaks
[linux-2.6-microblaze.git] / drivers / firmware / efi / memmap.c
index 04dfa56..5016721 100644 (file)
@@ -29,6 +29,28 @@ static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
        return PFN_PHYS(page_to_pfn(p));
 }
 
+static void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags)
+{
+       if (flags & EFI_MEMMAP_MEMBLOCK) {
+               if (slab_is_available())
+                       memblock_free_late(phys, size);
+               else
+                       memblock_free(phys, size);
+       } else if (flags & EFI_MEMMAP_SLAB) {
+               struct page *p = pfn_to_page(PHYS_PFN(phys));
+               unsigned int order = get_order(size);
+
+               free_pages((unsigned long) page_address(p), order);
+       }
+}
+
+static void __init efi_memmap_free(void)
+{
+       __efi_memmap_free(efi.memmap.phys_map,
+                       efi.memmap.desc_size * efi.memmap.nr_map,
+                       efi.memmap.flags);
+}
+
 /**
  * efi_memmap_alloc - Allocate memory for the EFI memory map
  * @num_entries: Number of entries in the allocated map.
@@ -100,6 +122,9 @@ static int __init __efi_memmap_init(struct efi_memory_map_data *data)
                return -ENOMEM;
        }
 
+       /* NOP if data->flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB) == 0 */
+       efi_memmap_free();
+
        map.phys_map = data->phys_map;
        map.nr_map = data->size / data->desc_size;
        map.map_end = map.map + data->size;