From patchwork Thu Aug 30 21:28:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Triplett X-Patchwork-Id: 1390041 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 CFA0B3FC33 for ; Thu, 30 Aug 2012 21:28:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752416Ab2H3V2n (ORCPT ); Thu, 30 Aug 2012 17:28:43 -0400 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:58086 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752746Ab2H3V2n (ORCPT ); Thu, 30 Aug 2012 17:28:43 -0400 X-Originating-IP: 217.70.178.129 Received: from mfilter12-d.gandi.net (mfilter12-d.gandi.net [217.70.178.129]) by relay3-d.mail.gandi.net (Postfix) with ESMTP id 1E18DA80A2; Thu, 30 Aug 2012 23:28:42 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter12-d.gandi.net Received: from relay3-d.mail.gandi.net ([217.70.183.195]) by mfilter12-d.gandi.net (mfilter12-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id kMMQlDdzxppG; Thu, 30 Aug 2012 23:28:37 +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 relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 092E6A807A; Thu, 30 Aug 2012 23:28:33 +0200 (CEST) Date: Thu, 30 Aug 2012 14:28:32 -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 , Jim Cromie , Peter Zijlstra , Pawel Moll , linux-acpi@vger.kernel.org Subject: [PATCH 1/3] efi: Defer freeing boot services memory until after ACPI init Message-ID: <57c1a3301fe9eb417d227e3f0ae4fe4d30bef203.1346361959.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 | 1 + init/main.c | 5 +++++ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 92660eda..8af329f 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) +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 ec45ccd..00ec70f 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -496,6 +496,7 @@ 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 */ +extern void efi_free_boot_services(void); extern u64 efi_get_iobase (void); extern u32 efi_mem_type (unsigned long phys_addr); extern u64 efi_mem_attributes (unsigned long phys_addr); diff --git a/init/main.c b/init/main.c index b286730..391a291 100644 --- a/init/main.c +++ b/init/main.c @@ -631,6 +631,11 @@ asmlinkage void __init start_kernel(void) acpi_early_init(); /* before LAPIC and SMP init */ sfi_init_late(); +#ifdef CONFIG_X86 + if (efi_enabled) + efi_free_boot_services(); +#endif + ftrace_init(); /* Do the rest non-__init'ed, we're now alive */