From patchwork Tue Sep 4 21:23:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Triplett X-Patchwork-Id: 1404251 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 7347B4025E for ; Tue, 4 Sep 2012 21:24:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932651Ab2IDVYK (ORCPT ); Tue, 4 Sep 2012 17:24:10 -0400 Received: from relay4-d.mail.gandi.net ([217.70.183.196]:43639 "EHLO relay4-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757785Ab2IDVYH (ORCPT ); Tue, 4 Sep 2012 17:24:07 -0400 X-Originating-IP: 217.70.178.131 Received: from mfilter11-d.gandi.net (mfilter11-d.gandi.net [217.70.178.131]) by relay4-d.mail.gandi.net (Postfix) with ESMTP id 2CEA2172097; Tue, 4 Sep 2012 23:24:06 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter11-d.gandi.net Received: from relay4-d.mail.gandi.net ([217.70.183.196]) by mfilter11-d.gandi.net (mfilter11-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id 8jQjH2FgXuTD; Tue, 4 Sep 2012 23:24:04 +0200 (CEST) X-Originating-IP: 173.246.103.110 Received: from jtriplet-mobl1 (joshtriplett.org [173.246.103.110]) (Authenticated sender: josh@joshtriplett.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id A1E7F172077; Tue, 4 Sep 2012 23:24:01 +0200 (CEST) Date: Tue, 4 Sep 2012 14:23:59 -0700 From: Josh Triplett To: linux-kernel@vger.kernel.org Cc: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , x86@kernel.org, Len Brown , Matt Fleming , Olof Johansson , Matthew Garrett , David Howells , Rusty Russell , Peter Zijlstra , Pawel Moll , linux-acpi@vger.kernel.org Subject: [PATCHv2 2/4] efi: Defer freeing boot services memory until freeing __init memory Message-ID: <8b9dd2ab34cecdf02f83d2a0c81f76632dfcf0e0.1346792566.git.josh@joshtriplett.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org 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 --- 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;