From patchwork Fri Dec 13 19:05:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Capper X-Patchwork-Id: 3342191 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 A2877C0D4A for ; Fri, 13 Dec 2013 19:09:05 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A7799207D1 for ; Fri, 13 Dec 2013 19:09:04 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (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 3EB01207B8 for ; Fri, 13 Dec 2013 19:09:03 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VrY5D-0001Z5-CD; Fri, 13 Dec 2013 19:07:32 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VrY4o-0006RE-Dk; Fri, 13 Dec 2013 19:07:06 +0000 Received: from mail-wi0-f179.google.com ([209.85.212.179]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VrY4C-0006Mq-WA for linux-arm-kernel@lists.infradead.org; Fri, 13 Dec 2013 19:06:32 +0000 Received: by mail-wi0-f179.google.com with SMTP id z2so1536437wiv.0 for ; Fri, 13 Dec 2013 11:06:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KWZHxDy2YAqmpuTpAnv1ydeiqOFIKvqOLkeKUFTLXyc=; b=heZ9sbfFaNcMID0SJZcatXw0WDSnjTR6Ca1VmdmW/EKDjpnvIvdB1dGQ220/UpfsG/ bJyPmiecCovcQMTyPTn3iocXcYyYxza0GxoEkKb23lp9MXHe7BRCjetNANRfXP+ZHtZ8 JYyv506y1M7mrJRpm8Htu0qPMDEASxRBh9icz7MnmJJ3VGIuv736xstiNqq/Mgg+jG2i ulCjB/TuiOmz0RG2gpfk+/pW9wVsuPLo5wKZHXZTZPRJ4ozfEy+sXRHhUUNC+gu6gmCU BZ2xSrKJa8/thO7zEZRcOuE185Ipewv3gUwEqfR2QAiNGBgoBL8aN86MX1CO9KZ4t5yV yjkQ== X-Gm-Message-State: ALoCoQlLoExbbG6JhcZB9BG6x+C6MeSLLffYDSNW0iIq3qewycFXctqScdmQgXw+nEHrz/6djN0R X-Received: by 10.180.95.105 with SMTP id dj9mr4320576wib.22.1386961561579; Fri, 13 Dec 2013 11:06:01 -0800 (PST) Received: from marmot.wormnet.eu (marmot.wormnet.eu. [188.246.204.87]) by mx.google.com with ESMTPSA id o9sm289604wib.10.2013.12.13.11.05.59 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 13 Dec 2013 11:06:00 -0800 (PST) From: Steve Capper To: linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH 4/6] arm: mm: Compute pgprot values for huge page sections Date: Fri, 13 Dec 2013 19:05:44 +0000 Message-Id: <1386961546-10061-5-git-send-email-steve.capper@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1386961546-10061-1-git-send-email-steve.capper@linaro.org> References: <1386961546-10061-1-git-send-email-steve.capper@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131213_140629_364552_EF4A68B4 X-CRM114-Status: GOOD ( 13.66 ) X-Spam-Score: -2.6 (--) Cc: deepak.saxena@linaro.org, linux@arm.linux.org.uk, patches@linaro.org, catalin.marinas@arm.com, will.deacon@arm.com, Steve Capper X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 The short descriptors memory code stores separate software and hardware ptes. All the pgprot values that vmas inherit and all the pte manipulation functions operate in terms of software ptes. The actual hardware bits are then controlled by the pte setter functions. For short descriptor transparent huge pages we can't really store separate copies of the huge pages without fundamentally changing the pmd traversing code. So one strategy is to work directly with the hardware bits. This patch adds code to compute the appropriate memory description bits for an MT_MEMORY section and translates the executable, writable and PROT_NONE information from the software pgprot to give us a hardware pgprot that can be manipulated directly by the HugeTLB and THP code. Signed-off-by: Steve Capper --- arch/arm/mm/mmu.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 580ef2d..476a668 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -338,6 +338,45 @@ const struct mem_type *get_mem_type(unsigned int type) EXPORT_SYMBOL(get_mem_type); /* + * If the system supports huge pages and we are running with short descriptors, + * then compute the pgprot values for a huge page. We do not need to do this + * with LPAE as there is no software/hardware bit distinction for ptes. + * + * We are only interested in: + * 1) The memory type: huge pages are user pages so a section of type + * MT_MEMORY. This is used to create new huge ptes/thps. + * + * 2) XN, PROT_NONE, WRITE. These are set/unset through protection changes + * by pte_modify or pmd_modify and are used to make new ptes/thps. + * + * The other bits: dirty, young, splitting are not modified by pte_modify + * or pmd_modify nor are they used to create new ptes or pmds thus they are not + * considered here. + */ +#if defined(CONFIG_SYS_SUPPORTS_HUGETLBFS) && !defined(CONFIG_ARM_LPAE) +static pgprot_t _hugepgprotval; + +pgprot_t get_huge_pgprot(pgprot_t newprot) +{ + pte_t inprot = __pte(pgprot_val(newprot)); + pmd_t pmdret = __pmd(pgprot_val(_hugepgprotval)); + + if (!pte_exec(inprot)) + pmdret = pmd_mknexec(pmdret); + + if (pte_write(inprot)) + pmdret = pmd_mkwrite(pmdret); + + if (!pte_protnone(inprot)) + pmdret = pmd_rmprotnone(pmdret); + + return __pgprot(pmd_val(pmdret)); +} +EXPORT_SYMBOL(get_huge_pgprot); +#endif + + +/* * Adjust the PMD section entries according to the CPU in use. */ static void __init build_mem_type_table(void) @@ -568,6 +607,19 @@ static void __init build_mem_type_table(void) if (t->prot_sect) t->prot_sect |= PMD_DOMAIN(t->domain); } + +#if defined(CONFIG_SYS_SUPPORTS_HUGETLBFS) && !defined(CONFIG_ARM_LPAE) + /* + * we assume all huge pages are user pages and that hardware access + * flag updates are disabled (which is the case for short descriptors). + */ + pgprot_val(_hugepgprotval) = mem_types[MT_MEMORY].prot_sect + | PMD_SECT_AP_READ | PMD_SECT_nG; + + pgprot_val(_hugepgprotval) &= ~(PMD_SECT_AP_WRITE | PMD_SECT_XN + | PMD_TYPE_SECT); +#endif + } #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE