From patchwork Mon Nov 24 15:06:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Catalin Marinas X-Patchwork-Id: 5367941 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2A2C1C11AC for ; Mon, 24 Nov 2014 15:11:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 36D3B2041C for ; Mon, 24 Nov 2014 15:11:08 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 45AE12041A for ; Mon, 24 Nov 2014 15:11:07 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XsvEj-0006B5-Pt; Mon, 24 Nov 2014 15:07:33 +0000 Received: from foss-mx-na.foss.arm.com ([217.140.108.86]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XsvEg-00066O-9W for linux-arm-kernel@lists.infradead.org; Mon, 24 Nov 2014 15:07:30 +0000 Received: from foss-smtp-na-1.foss.arm.com (unknown [10.80.61.8]) by foss-mx-na.foss.arm.com (Postfix) with ESMTP id 9250BD6; Mon, 24 Nov 2014 09:06:58 -0600 (CST) Received: from collaborate-mta1.arm.com (highbank-bc01-b06.austin.arm.com [10.112.81.134]) by foss-smtp-na-1.foss.arm.com (Postfix) with ESMTP id 6A9EC5FAD7; Mon, 24 Nov 2014 09:06:56 -0600 (CST) Received: from e104818-lin.cambridge.arm.com (e104818-lin.cambridge.arm.com [10.1.203.148]) by collaborate-mta1.arm.com (Postfix) with ESMTPS id 3FA4913F8D8; Mon, 24 Nov 2014 09:06:55 -0600 (CST) Date: Mon, 24 Nov 2014 15:06:53 +0000 From: Catalin Marinas To: Jungseung Lee Subject: Re: [PATCH v1] arm: Support for the PXN CPU feature on ARMv7 Message-ID: <20141124150652.GF15872@e104818-lin.cambridge.arm.com> References: <1416652956-24207-1-git-send-email-js07.lee@gmail.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1416652956-24207-1-git-send-email-js07.lee@gmail.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141124_070730_349049_E3219EE3 X-CRM114-Status: GOOD ( 18.37 ) X-Spam-Score: -0.0 (/) Cc: Laura Abbott , Russell King , "linux-arm-kernel@lists.infradead.org" , Will Deacon , Ard Biesheuvel X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Sat, Nov 22, 2014 at 10:42:36AM +0000, Jungseung Lee wrote: > diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h > index 78a7793..e63c633 100644 > --- a/arch/arm/include/asm/pgalloc.h > +++ b/arch/arm/include/asm/pgalloc.h > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > > #define check_pgt_cache() do { } while (0) > > @@ -25,6 +26,19 @@ > #define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER)) > #define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL)) > > +static inline bool cpu_has_classic_pxn(void) > +{ > +#ifdef CONFIG_CPU_V7 I don't think shouldn't trigger this when LPAE is enabled. > + unsigned int vmsa; > + > + /* LPAE implies atomic ldrd/strd instructions */ How is this comment relevant? Copy/paste? > + vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0; > + if (vmsa == 4) > + return 1; > +#endif > + return 0; > +} In general we put the #ifdef outside the function: #if __LINUX_ARM_ARCH__ >= 7 && !defined(CONFIG_ARM_LPAE) static inline bool cpu_has_classic_pxn(void) { unsigned int vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0; return vmsa == 4; } #else static inline bool cpu_has_classic_pxn(void) { return false; } #endif I used __LINUX_ARM_ARCH__ instead of CONFIG_CPU_V7 to cope with kernel images built for both v6 and v7. You could also check for cpu_architecture() >= 7, though with a bit of performance impact. > static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) > @@ -157,7 +171,11 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) > static inline void > pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep) > { > - __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE); > + if (cpu_has_classic_pxn()) > + __pmd_populate(pmdp, page_to_phys(ptep), > + _PAGE_USER_TABLE | PMD_PXNTABLE); > + else > + __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE); > } Nitpick (personal preference): pmdval_t pmdval = _PAGE_USER_TABLE; if (cpu_has_classic_pxn()) pmdval |= PMD_PXNTABLE; __pmd_populate(pmdp, page_to_phys(ptep), pmdval); > #define pmd_pgtable(pmd) pmd_page(pmd) > > diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h > index 5cfba15..5e68278 100644 > --- a/arch/arm/include/asm/pgtable-2level-hwdef.h > +++ b/arch/arm/include/asm/pgtable-2level-hwdef.h > @@ -20,12 +20,14 @@ > #define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0) > #define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0) > #define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0) > +#define PMD_PXNTABLE (_AT(pmdval_t, 1) << 2) /* v7 */ > #define PMD_BIT4 (_AT(pmdval_t, 1) << 4) > #define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5) > #define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */ > /* > * - section > */ > +#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 0) /* v7 */ > #define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2) > #define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3) > #define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */ > diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h > index 9fd61c7..f8f1cff 100644 > --- a/arch/arm/include/asm/pgtable-3level-hwdef.h > +++ b/arch/arm/include/asm/pgtable-3level-hwdef.h > @@ -76,6 +76,7 @@ > #define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ > #define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ > #define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */ > +#define PTE_EXT_PXN (_AT(pteval_t, 1) << 53) /* PXN */ > #define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */ > > /* > diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h > index 3b30062..04db03c 100644 > --- a/arch/arm/include/asm/pgtable.h > +++ b/arch/arm/include/asm/pgtable.h > @@ -247,6 +247,9 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, > if (!pte_special(pteval)) > __sync_icache_dcache(pteval); > ext |= PTE_EXT_NG; > +#ifdef CONFIG_ARM_LPAE > + ext |= PTE_EXT_PXN; > +#endif I think you can avoid touching set_pte_at() and instead: diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9f98cec7fe1e..5b0a0472e689 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -605,6 +605,11 @@ static void __init build_mem_type_table(void) } kern_pgprot |= PTE_EXT_AF; vecs_pgprot |= PTE_EXT_AF; + + /* + * Set PXN for user mappings + */ + user_pgprot |= PTE_EXT_PXN; #endif for (i = 0; i < 16; i++) {