aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform
diff options
context:
space:
mode:
authorJosh Triplett <josh@joshtriplett.org>2012-09-28 20:55:44 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2012-09-29 15:21:01 -0400
commit785107923a83d8456bbd8564e288a24d84109a46 (patch)
treecda886bdf9d5f33a524b740e7807d17e079cb6b7 /arch/x86/platform
parent984ff8a4d2251fbd09b1e8515133bdfe9ef4bcd6 (diff)
efi: Defer freeing boot services memory until after ACPI init
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>
Diffstat (limited to 'arch/x86/platform')
-rw-r--r--arch/x86/platform/efi/efi.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index f55a4ce6dc49..b3dbbdbd2a42 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)
419 } 419 }
420} 420}
421 421
422static void __init efi_free_boot_services(void) 422static void __init efi_unmap_memmap(void)
423{
424 if (memmap.map) {
425 early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
426 memmap.map = NULL;
427 }
428}
429
430void __init efi_free_boot_services(void)
423{ 431{
424 void *p; 432 void *p;
425 433
434 if (!efi_native)
435 return;
436
426 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 437 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
427 efi_memory_desc_t *md = p; 438 efi_memory_desc_t *md = p;
428 unsigned long long start = md->phys_addr; 439 unsigned long long start = md->phys_addr;
@@ -438,6 +449,8 @@ static void __init efi_free_boot_services(void)
438 449
439 free_bootmem_late(start, size); 450 free_bootmem_late(start, size);
440 } 451 }
452
453 efi_unmap_memmap();
441} 454}
442 455
443static int __init efi_systab_init(void *phys) 456static int __init efi_systab_init(void *phys)
@@ -787,8 +800,10 @@ void __init efi_enter_virtual_mode(void)
787 * non-native EFI 800 * non-native EFI
788 */ 801 */
789 802
790 if (!efi_native) 803 if (!efi_native) {
791 goto out; 804 efi_unmap_memmap();
805 return;
806 }
792 807
793 /* Merge contiguous regions of the same type and attribute */ 808 /* Merge contiguous regions of the same type and attribute */
794 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 809 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
@@ -878,13 +893,6 @@ void __init efi_enter_virtual_mode(void)
878 } 893 }
879 894
880 /* 895 /*
881 * Thankfully, it does seem that no runtime services other than
882 * SetVirtualAddressMap() will touch boot services code, so we can
883 * get rid of it all at this point
884 */
885 efi_free_boot_services();
886
887 /*
888 * Now that EFI is in virtual mode, update the function 896 * Now that EFI is in virtual mode, update the function
889 * pointers in the runtime service table to the new virtual addresses. 897 * pointers in the runtime service table to the new virtual addresses.
890 * 898 *
@@ -907,9 +915,6 @@ void __init efi_enter_virtual_mode(void)
907 if (__supported_pte_mask & _PAGE_NX) 915 if (__supported_pte_mask & _PAGE_NX)
908 runtime_code_page_mkexec(); 916 runtime_code_page_mkexec();
909 917
910out:
911 early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
912 memmap.map = NULL;
913 kfree(new_memmap); 918 kfree(new_memmap);
914} 919}
915 920