]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
efi: Defer freeing boot services memory until after ACPI init
authorJosh Triplett <josh@joshtriplett.org>
Sat, 29 Sep 2012 00:55:44 +0000 (17:55 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 31 Oct 2012 17:03:18 +0000 (10:03 -0700)
commit 785107923a83d8456bbd8564e288a24d84109a46 upstream.

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@joshtriplett.org>
Link: http://lkml.kernel.org/r/baaa6d44bdc4eb0c58e5d1b4ccd2c729f854ac55.1348876882.git.josh@joshtriplett.org
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/platform/efi/efi.c
include/linux/efi.h
init/main.c

index f55a4ce6dc494d7375dcd564d40424a0b416ce7f..b3dbbdbd2a42b4b4a2658dd7b850b1fdb7acafbc 100644 (file)
@@ -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) {
@@ -877,13 +892,6 @@ void __init efi_enter_virtual_mode(void)
                panic("EFI call to SetVirtualAddressMap() failed!");
        }
 
-       /*
-        * 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.
@@ -907,9 +915,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);
 }
 
index ec45ccd8708a85f54a903d769b0b5c2fbaf8bc3f..5782114f4838658fc75802ba5e26e68e64ff2ed7 100644 (file)
@@ -496,6 +496,11 @@ extern void efi_map_pal_code (void);
 extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
 extern void efi_gettimeofday (struct timespec *ts);
 extern void efi_enter_virtual_mode (void);     /* switch EFI to virtual mode, if possible */
+#ifdef CONFIG_X86
+extern void efi_free_boot_services(void);
+#else
+static inline void efi_free_boot_services(void) {}
+#endif
 extern u64 efi_get_iobase (void);
 extern u32 efi_mem_type (unsigned long phys_addr);
 extern u64 efi_mem_attributes (unsigned long phys_addr);
index b08c5f75974f5f23638138163a1e45a9fdbcfff4..c2178d267c1ae8e7948832cdeba0c96b76b9b35d 100644 (file)
@@ -630,6 +630,9 @@ asmlinkage void __init start_kernel(void)
        acpi_early_init(); /* before LAPIC and SMP init */
        sfi_init_late();
 
+       if (efi_enabled)
+               efi_free_boot_services();
+
        ftrace_init();
 
        /* Do the rest non-__init'ed, we're now alive */