From patchwork Tue May 24 21:39:20 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Catalin Marinas X-Patchwork-Id: 814172 Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p4OLjWpl002181 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 24 May 2011 21:45:53 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by bombadil.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QOzOI-0003iv-Ry; Tue, 24 May 2011 21:43:51 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QOzOH-0004LP-1G; Tue, 24 May 2011 21:43:49 +0000 Received: from service87.mimecast.com ([94.185.240.25]) by canuck.infradead.org with smtp (Exim 4.76 #1 (Red Hat Linux)) id 1QOzKP-00047O-6l for linux-arm-kernel@lists.infradead.org; Tue, 24 May 2011 21:39:58 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Tue, 24 May 2011 22:39:46 +0100 Received: from e102109-lin.cambridge.arm.com ([10.1.255.212]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 24 May 2011 22:39:48 +0100 From: Catalin Marinas To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 14/18] ARM: LPAE: Add identity mapping support for the 3-level page table format Date: Tue, 24 May 2011 22:39:20 +0100 Message-Id: <1306273164-18217-15-git-send-email-catalin.marinas@arm.com> X-Mailer: git-send-email 1.7.4.2.g597a6 In-Reply-To: <1306273164-18217-1-git-send-email-catalin.marinas@arm.com> References: <1306273164-18217-1-git-send-email-catalin.marinas@arm.com> X-OriginalArrivalTime: 24 May 2011 21:39:49.0005 (UTC) FILETIME=[1B58C3D0:01CC1A5B] X-MC-Unique: 111052422394600801 X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110524_173949_816044_C4C58E9E X-CRM114-Status: GOOD ( 14.75 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [94.185.240.25 listed in list.dnswl.org] Cc: Russell King - ARM Linux X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 24 May 2011 21:45:53 +0000 (UTC) With LPAE, the pgd is a separate page table with entries pointing to the pmd. The identity_mapping_add() function needs to ensure that the pgd is populated before populating the pmd level. The do..while blocks now loop over the pmd in order to have the same implementation for the two page table formats. The pmd_addr_end() definition has been removed and the generic one used instead. The pmd clean-up is done in the pgd_free() function. Signed-off-by: Catalin Marinas --- arch/arm/include/asm/pgtable.h | 4 ---- arch/arm/mm/idmap.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 1db9ad6..9645e52 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -263,10 +263,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) -/* we don't need complex calculations here as the pmd is folded into the pgd */ -#define pmd_addr_end(addr,end) (end) - - #ifndef CONFIG_HIGHPTE #define __pte_map(pmd) pmd_page_vaddr(*(pmd)) #define __pte_unmap(pte) do { } while (0) diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 2be9139..24e0655 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -1,9 +1,36 @@ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include #include +#ifdef CONFIG_ARM_LPAE +static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, + unsigned long prot) +{ + pmd_t *pmd; + unsigned long next; + + if (pud_none_or_clear_bad(pud) || (pud_val(*pud) & L_PGD_SWAPPER)) { + pmd = pmd_alloc_one(NULL, addr); + if (!pmd) { + pr_warning("Failed to allocate identity pmd.\n"); + return; + } + pud_populate(NULL, pud, pmd); + pmd += pmd_index(addr); + } else + pmd = pmd_offset(pud, addr); + + do { + next = pmd_addr_end(addr, end); + *pmd = __pmd((addr & PMD_MASK) | prot); + flush_pmd_entry(pmd); + } while (pmd++, addr = next, addr != end); +} +#else /* !CONFIG_ARM_LPAE */ static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, unsigned long prot) { @@ -15,6 +42,7 @@ static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, pmd[1] = __pmd(addr); flush_pmd_entry(pmd); } +#endif /* CONFIG_ARM_LPAE */ static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end, unsigned long prot) @@ -32,7 +60,7 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) { unsigned long prot, next; - prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE; + prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) prot |= PMD_BIT4; @@ -46,7 +74,11 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) #ifdef CONFIG_SMP static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end) { - pmd_t *pmd = pmd_offset(pud, addr); + pmd_t *pmd; + + if (pud_none_or_clear_bad(pud)) + return; + pmd = pmd_offset(pud, addr); pmd_clear(pmd); }