From patchwork Thu Mar 13 22:47:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leif Lindholm X-Patchwork-Id: 26235 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f200.google.com (mail-qc0-f200.google.com [209.85.216.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 59F4B203AC for ; Thu, 13 Mar 2014 22:51:55 +0000 (UTC) Received: by mail-qc0-f200.google.com with SMTP id i17sf3727176qcy.3 for ; Thu, 13 Mar 2014 15:51:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=tUTWGGBmvIYX7SLnY+QY9QviQcHTLChDFoM6xVOvXFs=; b=E/5gWwe7kApmjlphTuOAKxTvUOJqoS1PPtabUJWFHrlR1CxFYtw4m2p930dhx3ekKO V4exp0dws1b2hG+rN8GSGZVC5sVzEn3yTdOp7KbiWJJTs+QxBbK6jd0/xajWYKgZUriH 0qh4ZuUAYu0/TUWZBrcD3hp//MGVyonsmer81E63Rd7FDzqpLGmM+amsZ31wwHwFNcg8 m1/9hqx+D8PUpZonjqsxjgWqLfY0Oa78O8nVbo1Au4XZK3ZnZjCL/w1npxmyJ3JXCune ynrnpgiviX+o1Z+iDWnqN1czORR3feDVX/vlEpSvHzQTB9WemVKp+wS4Iqshlee5ROZ6 qi5g== X-Gm-Message-State: ALoCoQk0EvtT5VJe7wJxZ/dxE9oBgx3KhuEoLCnCoGhX9VSOLU45iWDQwG2nNDjr5Mhe0IlS/7L2 X-Received: by 10.224.13.12 with SMTP id z12mr1771507qaz.7.1394751115161; Thu, 13 Mar 2014 15:51:55 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.37.225 with SMTP id r88ls478565qgr.2.gmail; Thu, 13 Mar 2014 15:51:55 -0700 (PDT) X-Received: by 10.52.171.68 with SMTP id as4mr2998369vdc.0.1394751115086; Thu, 13 Mar 2014 15:51:55 -0700 (PDT) Received: from mail-vc0-f180.google.com (mail-vc0-f180.google.com [209.85.220.180]) by mx.google.com with ESMTPS id tt2si1390522vdc.126.2014.03.13.15.51.55 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 13 Mar 2014 15:51:55 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.180 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.180; Received: by mail-vc0-f180.google.com with SMTP id lf12so1854473vcb.25 for ; Thu, 13 Mar 2014 15:51:55 -0700 (PDT) X-Received: by 10.58.248.163 with SMTP id yn3mr1368359vec.0.1394751114994; Thu, 13 Mar 2014 15:51:54 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.78.9 with SMTP id i9csp10377vck; Thu, 13 Mar 2014 15:51:54 -0700 (PDT) X-Received: by 10.68.237.133 with SMTP id vc5mr5438457pbc.92.1394751113878; Thu, 13 Mar 2014 15:51:53 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id pi6si3645128pbb.190.2014.03.13.15.51.53; Thu, 13 Mar 2014 15:51:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755631AbaCMWvm (ORCPT + 26 others); Thu, 13 Mar 2014 18:51:42 -0400 Received: from mail-wg0-f52.google.com ([74.125.82.52]:36461 "EHLO mail-wg0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755264AbaCMWsQ (ORCPT ); Thu, 13 Mar 2014 18:48:16 -0400 Received: by mail-wg0-f52.google.com with SMTP id k14so1447495wgh.23 for ; Thu, 13 Mar 2014 15:48:14 -0700 (PDT) X-Received: by 10.180.93.133 with SMTP id cu5mr3477397wib.47.1394750894890; Thu, 13 Mar 2014 15:48:14 -0700 (PDT) Received: from mohikan.mushroom.smurfnet.nu (cpc4-cmbg17-2-0-cust71.5-4.cable.virginm.net. [86.14.224.72]) by mx.google.com with ESMTPSA id dk9sm9072133wjb.4.2014.03.13.15.48.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Mar 2014 15:48:14 -0700 (PDT) From: Leif Lindholm To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-efi@vger.kernel.org, catalin.marinas@arm.com, matt.fleming@intel.com Cc: msalter@redhat.com, roy.franz@linaro.org, Leif Lindholm Subject: [PATCH v2 10/15] arm64: Add function to create identity mappings Date: Thu, 13 Mar 2014 22:47:03 +0000 Message-Id: <1394750828-16351-11-git-send-email-leif.lindholm@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1394750828-16351-1-git-send-email-leif.lindholm@linaro.org> References: <1394750828-16351-1-git-send-email-leif.lindholm@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: leif.lindholm@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.180 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Mark Salter At boot time, before switching to a virtual UEFI memory map, firmware expects UEFI memory and IO regions to be identity mapped whenever kernel makes runtime services calls. The existing early boot code creates an identity map of kernel text/data but this is not sufficient for UEFI. This patch adds a create_id_mapping() function which reuses the core code of the existing create_mapping(). Signed-off-by: Mark Salter Signed-off-by: Leif Lindholm --- arch/arm64/include/asm/mmu.h | 2 ++ arch/arm64/mm/mmu.c | 65 ++++++++++++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index f600d40..29ed1d8 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -28,5 +28,7 @@ extern void paging_init(void); extern void setup_mm_for_reboot(void); extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt); extern void init_mem_pgprot(void); +/* create an identity mapping for memory (or io if map_io is true) */ +extern void create_id_mapping(phys_addr_t addr, phys_addr_t size, int map_io); #endif diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 6b7e895..357956a 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -168,7 +168,8 @@ static void __init *early_alloc(unsigned long sz) } static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, - unsigned long end, unsigned long pfn) + unsigned long end, unsigned long pfn, + pgprot_t prot) { pte_t *pte; @@ -180,16 +181,28 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, pte = pte_offset_kernel(pmd, addr); do { - set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); + set_pte(pte, pfn_pte(pfn, prot)); pfn++; } while (pte++, addr += PAGE_SIZE, addr != end); } static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, - unsigned long end, phys_addr_t phys) + unsigned long end, phys_addr_t phys, + int map_io) { pmd_t *pmd; unsigned long next; + pmdval_t prot_sect; + pgprot_t prot_pte; + + if (map_io) { + prot_sect = PMD_TYPE_SECT | PMD_SECT_AF | + PMD_ATTRINDX(MT_DEVICE_nGnRE); + prot_pte = __pgprot(PROT_DEVICE_nGnRE); + } else { + prot_sect = prot_sect_kernel; + prot_pte = PAGE_KERNEL_EXEC; + } /* * Check for initial section mappings in the pgd/pud and remove them. @@ -205,7 +218,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, /* try section mapping first */ if (((addr | next | phys) & ~SECTION_MASK) == 0) { pmd_t old_pmd =*pmd; - set_pmd(pmd, __pmd(phys | prot_sect_kernel)); + set_pmd(pmd, __pmd(phys | prot_sect)); /* * Check for previous table entries created during * boot (__create_page_tables) and flush them. @@ -213,21 +226,23 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, if (!pmd_none(old_pmd)) flush_tlb_all(); } else { - alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys)); + alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), + prot_pte); } phys += next - addr; } while (pmd++, addr = next, addr != end); } static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, - unsigned long end, unsigned long phys) + unsigned long end, unsigned long phys, + int map_io) { pud_t *pud = pud_offset(pgd, addr); unsigned long next; do { next = pud_addr_end(addr, end); - alloc_init_pmd(pud, addr, next, phys); + alloc_init_pmd(pud, addr, next, phys, map_io); phys += next - addr; } while (pud++, addr = next, addr != end); } @@ -236,30 +251,44 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, * Create the page directory entries and any necessary page tables for the * mapping specified by 'md'. */ -static void __init create_mapping(phys_addr_t phys, unsigned long virt, - phys_addr_t size) +static void __init __create_mapping(pgd_t *pgd, phys_addr_t phys, + unsigned long virt, phys_addr_t size, + int map_io) { unsigned long addr, length, end, next; - pgd_t *pgd; - - if (virt < VMALLOC_START) { - pr_warning("BUG: not creating mapping for 0x%016llx at 0x%016lx - outside kernel range\n", - phys, virt); - return; - } addr = virt & PAGE_MASK; length = PAGE_ALIGN(size + (virt & ~PAGE_MASK)); - pgd = pgd_offset_k(addr); end = addr + length; do { next = pgd_addr_end(addr, end); - alloc_init_pud(pgd, addr, next, phys); + alloc_init_pud(pgd, addr, next, phys, map_io); phys += next - addr; } while (pgd++, addr = next, addr != end); } +static void __init create_mapping(phys_addr_t phys, unsigned long virt, + phys_addr_t size) +{ + if (virt < VMALLOC_START) { + pr_warn("BUG: not creating mapping for 0x%016llx at 0x%016lx - outside kernel range\n", + phys, virt); + return; + } + __create_mapping(pgd_offset_k(virt & PAGE_MASK), phys, virt, size, 0); +} + +void __init create_id_mapping(phys_addr_t addr, phys_addr_t size, int map_io) +{ + if ((addr >> PGDIR_SHIFT) >= ARRAY_SIZE(idmap_pg_dir)) { + pr_warn("BUG: not creating id mapping for 0x%016llx\n", addr); + return; + } + __create_mapping(&idmap_pg_dir[pgd_index(addr)], + addr, addr, size, map_io); +} + static void __init map_mem(void) { struct memblock_region *reg;