Some new ACPI 5.0 tables reference resources stored in boot services memory, so keep that memory around until we have ACPI and can extract data from it. Signed-off-by: Josh Triplett <josh@xxxxxxxxxxxxxxxx> --- arch/x86/platform/efi/efi.c | 31 ++++++++++++++++++------------- include/linux/efi.h | 2 ++ init/main.c | 2 ++ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 92660eda..ab2cfe8 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -419,10 +419,21 @@ void __init efi_reserve_boot_services(void) } } -static void __init efi_free_boot_services(void) +static void __init efi_unmap_memmap(void) +{ + if (memmap.map) { + early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); + memmap.map = NULL; + } +} + +void __init efi_free_boot_services(void) { void *p; + if (!efi_native) + return; + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { efi_memory_desc_t *md = p; unsigned long long start = md->phys_addr; @@ -438,6 +449,8 @@ static void __init efi_free_boot_services(void) free_bootmem_late(start, size); } + + efi_unmap_memmap(); } static int __init efi_systab_init(void *phys) @@ -787,8 +800,10 @@ void __init efi_enter_virtual_mode(void) * non-native EFI */ - if (!efi_native) - goto out; + if (!efi_native) { + efi_unmap_memmap(); + return; + } /* Merge contiguous regions of the same type and attribute */ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { @@ -878,13 +893,6 @@ void __init efi_enter_virtual_mode(void) } /* - * Thankfully, it does seem that no runtime services other than - * SetVirtualAddressMap() will touch boot services code, so we can - * get rid of it all at this point - */ - efi_free_boot_services(); - - /* * Now that EFI is in virtual mode, update the function * pointers in the runtime service table to the new virtual addresses. * @@ -906,9 +914,6 @@ void __init efi_enter_virtual_mode(void) if (__supported_pte_mask & _PAGE_NX) runtime_code_page_mkexec(); -out: - early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); - memmap.map = NULL; kfree(new_memmap); } diff --git a/include/linux/efi.h b/include/linux/efi.h index 52fbedf..3c72c27 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -497,8 +497,10 @@ extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg); extern void efi_gettimeofday (struct timespec *ts); #ifdef CONFIG_X86 extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */ +extern void efi_free_boot_services(void); #else static void efi_enter_virtual_mode(void) {} +static void efi_free_boot_services(void) {} #endif extern u64 efi_get_iobase (void); extern u32 efi_mem_type (unsigned long phys_addr); diff --git a/init/main.c b/init/main.c index ebb1ba5..80a2e97 100644 --- a/init/main.c +++ b/init/main.c @@ -799,6 +799,8 @@ static noinline int init_post(void) { /* need to finish all async __init code before freeing the memory */ async_synchronize_full(); + if (efi_enabled) + efi_free_boot_services(); free_initmem(); mark_rodata_ro(); system_state = SYSTEM_RUNNING; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html