From patchwork Sat Sep 8 22:09:19 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Triplett X-Patchwork-Id: 1427301 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id D9D2CDF2AB for ; Sat, 8 Sep 2012 22:09:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754022Ab2IHWJ1 (ORCPT ); Sat, 8 Sep 2012 18:09:27 -0400 Received: from relay4-d.mail.gandi.net ([217.70.183.196]:48137 "EHLO relay4-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753947Ab2IHWJ0 (ORCPT ); Sat, 8 Sep 2012 18:09:26 -0400 X-Originating-IP: 217.70.178.134 Received: from mfilter4-d.gandi.net (mfilter4-d.gandi.net [217.70.178.134]) by relay4-d.mail.gandi.net (Postfix) with ESMTP id 71233172089; Sun, 9 Sep 2012 00:09:25 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter4-d.gandi.net Received: from relay4-d.mail.gandi.net ([217.70.183.196]) by mfilter4-d.gandi.net (mfilter4-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id 2GVw3tuIn9aF; Sun, 9 Sep 2012 00:09:24 +0200 (CEST) X-Originating-IP: 50.43.46.74 Received: from leaf (static-50-43-46-74.bvtn.or.frontiernet.net [50.43.46.74]) (Authenticated sender: josh@joshtriplett.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id D3366172070; Sun, 9 Sep 2012 00:09:20 +0200 (CEST) Date: Sat, 8 Sep 2012 15:09:19 -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 , linux-acpi@vger.kernel.org Subject: [PATCHv3 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);