From patchwork Tue Sep 4 21:24:08 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Triplett X-Patchwork-Id: 1404241 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 21BD74025E for ; Tue, 4 Sep 2012 21:24:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932695Ab2IDVYS (ORCPT ); Tue, 4 Sep 2012 17:24:18 -0400 Received: from relay4-d.mail.gandi.net ([217.70.183.196]:60163 "EHLO relay4-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757785Ab2IDVYQ (ORCPT ); Tue, 4 Sep 2012 17:24:16 -0400 X-Originating-IP: 217.70.178.130 Received: from mfilter1-d.gandi.net (mfilter1-d.gandi.net [217.70.178.130]) by relay4-d.mail.gandi.net (Postfix) with ESMTP id 9C8D917208F; Tue, 4 Sep 2012 23:24:15 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter1-d.gandi.net Received: from relay4-d.mail.gandi.net ([217.70.183.196]) by mfilter1-d.gandi.net (mfilter1-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id SCeVF8AK-icv; Tue, 4 Sep 2012 23:24:14 +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 D3069172076; Tue, 4 Sep 2012 23:24:10 +0200 (CEST) Date: Tue, 4 Sep 2012 14:24:08 -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 3/4] efi: Add a function to look up existing IO memory mappings Message-ID: 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 The EFI initialization creates virtual mappings for EFI boot services memory, so if a driver wants to access EFI boot services memory, it cannot call ioremap itself; doing so will trip the WARN about mapping RAM twice. Thus, a driver accessing EFI boot services memory must do so via the existing mapping already created during EFI intiialization. Since the EFI code already maintains a memory map for that memory, add a function efi_lookup_mapped_addr to look up mappings in that memory map. Signed-off-by: Josh Triplett --- arch/x86/platform/efi/efi.c | 28 ++++++++++++++++++++++++++++ include/linux/efi.h | 1 + 2 files changed, 29 insertions(+) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index ab2cfe8..90023d1 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -777,6 +777,34 @@ static void __init runtime_code_page_mkexec(void) } /* + * We can't ioremap data in EFI boot services RAM, because we've already mapped + * it as RAM. So, look it up in the existing EFI memory map instead. Only + * callable after efi_enter_virtual_mode and before efi_free_boot_services. + */ +void __iomem *efi_lookup_mapped_addr(u64 phys_addr) +{ + void *p; + if (WARN_ON(!memmap.map)) + return NULL; + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + efi_memory_desc_t *md = p; + u64 size = md->num_pages << EFI_PAGE_SHIFT; + u64 end = md->phys_addr + size; + if (!(md->attribute & EFI_MEMORY_RUNTIME) && + md->type != EFI_BOOT_SERVICES_CODE && + md->type != EFI_BOOT_SERVICES_DATA) + continue; + if (!md->virt_addr) + continue; + if (phys_addr >= md->phys_addr && phys_addr < end) { + phys_addr += md->virt_addr - md->phys_addr; + return (__force void __iomem *)phys_addr; + } + } + return NULL; +} + +/* * This function will switch the EFI runtime services to virtual mode. * Essentially, look through the EFI memmap and map every region that * has the runtime attribute bit set in its memory descriptor and update diff --git a/include/linux/efi.h b/include/linux/efi.h index 3c72c27..00aa5de 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -502,6 +502,7 @@ extern void efi_free_boot_services(void); static void efi_enter_virtual_mode(void) {} static void efi_free_boot_services(void) {} #endif +extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); extern u64 efi_get_iobase (void); extern u32 efi_mem_type (unsigned long phys_addr); extern u64 efi_mem_attributes (unsigned long phys_addr);