From patchwork Thu Aug 30 21:28:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Triplett X-Patchwork-Id: 1390071 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 3FF3EDF264 for ; Thu, 30 Aug 2012 21:29:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752746Ab2H3V2z (ORCPT ); Thu, 30 Aug 2012 17:28:55 -0400 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:38068 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752532Ab2H3V2x (ORCPT ); Thu, 30 Aug 2012 17:28:53 -0400 X-Originating-IP: 217.70.178.144 Received: from mfilter16-d.gandi.net (mfilter16-d.gandi.net [217.70.178.144]) by relay3-d.mail.gandi.net (Postfix) with ESMTP id 53198A806E; Thu, 30 Aug 2012 23:28:52 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter16-d.gandi.net Received: from relay3-d.mail.gandi.net ([217.70.183.195]) by mfilter16-d.gandi.net (mfilter16-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id hdsEfvVhZRui; Thu, 30 Aug 2012 23:28:50 +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 21980A8077; Thu, 30 Aug 2012 23:28:46 +0200 (CEST) Date: Thu, 30 Aug 2012 14:28:45 -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 2/3] efi: Add a function to look up existing IO memory mappings Message-ID: <5563b7d0ce3577f421e9622063a58aa4003ec917.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 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 8af329f..ae35cc8 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 00ec70f..0c11a58 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 __iomem *efi_lookup_mapped_addr(u64 phys_addr); extern void efi_free_boot_services(void); extern u64 efi_get_iobase (void); extern u32 efi_mem_type (unsigned long phys_addr);