Received: by 10.192.165.148 with SMTP id m20csp4062885imm; Mon, 30 Apr 2018 11:01:46 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqtYr8EvuV15KZG4ts67BjHq50hqVHsHNkalF46OIsxsJ5eaP17t71DeanZDEYmvYsfTGzr X-Received: by 2002:a17:902:70c4:: with SMTP id l4-v6mr10623858plt.174.1525111306018; Mon, 30 Apr 2018 11:01:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525111305; cv=none; d=google.com; s=arc-20160816; b=eYH2b9IhkkcCzoK+77CXlnEqA2+ywYaA+yvvZXfv/e95DQWxM1ABsVnufkPxic4TIs W3zgjjpSYDSRxLV3VixRxSZvlyJhKECXZtMtivBct0oHoSMyD9UFawNwqIC6zqJ7SHEs yJ3Lkw9QlnFGK99gnGr5NOAX6eCoJecdGKUIXM3t9S8GL/S6DHsqhuYQooNeNY0Ao7lO PnI7nHadXlzKtqZcnbOiCt6bAfoAbbffSUt8hqdVBC+ug3a+QXz4vr5DQT7eR/xUA47d hIrilGLcW3MrAZrtdylCMg4iz+W0AcOhK6UTsesTYs0y+/YcPKRkZN1EB6SrXbGyz/LE I2Uw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=eFRWTzR9zuTtzStOfD+nrQZMjhxcfV9CVR28R5Wduik=; b=zbVLJG2UQIBQGp7t16othAbxwwxLsOtRVdRnOzzWRV8AV5PwNndSxtRTeFDgNh+McE eD9chSeq8z3I56SNPqTvmqlRPDhaiEg7rtJyFjWsmJ1BupLoVFYfFuPGry5/SsR1C4cc mtdZ0TaiNaPrr7egMsX+jmg0AMHN4DdfQILusIJQki/MUeE5ZlhrDFSS7SCeWxGBDATW qilZw4jbbpsj1RDEQwkMWBtjyAevZBNUJEqu//Fx7nJrH33WA1yBTtFCHLeW+CE+39lS 8YIa6KoEKhGcn2xXSTYSnS5dNNfIqxMJ55tWlx0ncXcnYimlfdO+CmTS4n2iAXrMuzVr URqw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c4-v6si6449791pgt.264.2018.04.30.11.01.31; Mon, 30 Apr 2018 11:01:45 -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; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754534AbeD3SAy (ORCPT + 99 others); Mon, 30 Apr 2018 14:00:54 -0400 Received: from g9t5009.houston.hpe.com ([15.241.48.73]:56060 "EHLO g9t5009.houston.hpe.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754104AbeD3SA0 (ORCPT ); Mon, 30 Apr 2018 14:00:26 -0400 Received: from g9t2301.houston.hpecorp.net (g9t2301.houston.hpecorp.net [16.220.97.129]) by g9t5009.houston.hpe.com (Postfix) with ESMTP id 25CE694; Mon, 30 Apr 2018 18:00:25 +0000 (UTC) Received: from misato.americas.hpqcorp.net (misato.americas.hpqcorp.net [10.34.81.122]) by g9t2301.houston.hpecorp.net (Postfix) with ESMTP id E18FB76E; Mon, 30 Apr 2018 18:00:23 +0000 (UTC) From: Toshi Kani To: mhocko@suse.com, akpm@linux-foundation.org, tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com Cc: cpandya@codeaurora.org, linux-mm@kvack.org, x86@kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Toshi Kani , Joerg Roedel , stable@vger.kernel.org Subject: [PATCH 2/3] x86/mm: add TLB purge to free pmd/pte page interfaces Date: Mon, 30 Apr 2018 11:59:24 -0600 Message-Id: <20180430175925.2657-3-toshi.kani@hpe.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180430175925.2657-1-toshi.kani@hpe.com> References: <20180430175925.2657-1-toshi.kani@hpe.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org ioremap() calls pud_free_pmd_page() / pmd_free_pte_page() when it creates a pud / pmd map. The following preconditions are met at their entry. - All pte entries for a target pud/pmd address range have been cleared. - System-wide TLB purges have been peformed for a target pud/pmd address range. The preconditions assure that there is no stale TLB entry for the range. Speculation may not cache TLB entries since it requires all levels of page entries, including ptes, to have P & A-bits set for an associated address. However, speculation may cache pud/pmd entries (paging-structure caches) when they have P-bit set. Add a system-wide TLB purge (INVLPG) to a single page after clearing pud/pmd entry's P-bit. SDM 4.10.4.1, Operation that Invalidate TLBs and Paging-Structure Caches, states that: INVLPG invalidates all paging-structure caches associated with the current PCID regardless of the liner addresses to which they correspond. Fixes: 28ee90fe6048 ("x86/mm: implement free pmd/pte page interfaces") Signed-off-by: Toshi Kani Cc: Andrew Morton Cc: Michal Hocko Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Joerg Roedel Cc: --- arch/x86/mm/pgtable.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 37e3cbac59b9..816fd41ee854 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -720,24 +720,40 @@ int pmd_clear_huge(pmd_t *pmd) * @pud: Pointer to a PUD. * @addr: Virtual address associated with pud. * - * Context: The pud range has been unmaped and TLB purged. + * Context: The pud range has been unmapped and TLB purged. * Return: 1 if clearing the entry succeeded. 0 otherwise. */ int pud_free_pmd_page(pud_t *pud, unsigned long addr) { - pmd_t *pmd; + pmd_t *pmd, *pmd_sv; + pte_t *pte; int i; if (pud_none(*pud)) return 1; pmd = (pmd_t *)pud_page_vaddr(*pud); + pmd_sv = (pmd_t *)__get_free_page(GFP_KERNEL); - for (i = 0; i < PTRS_PER_PMD; i++) - if (!pmd_free_pte_page(&pmd[i], addr + (i * PMD_SIZE))) - return 0; + for (i = 0; i < PTRS_PER_PMD; i++) { + pmd_sv[i] = pmd[i]; + if (!pmd_none(pmd[i])) + pmd_clear(&pmd[i]); + } pud_clear(pud); + + /* INVLPG to clear all paging-structure caches */ + flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1); + + for (i = 0; i < PTRS_PER_PMD; i++) { + if (!pmd_none(pmd_sv[i])) { + pte = (pte_t *)pmd_page_vaddr(pmd_sv[i]); + free_page((unsigned long)pte); + } + } + + free_page((unsigned long)pmd_sv); free_page((unsigned long)pmd); return 1; @@ -748,7 +764,7 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr) * @pmd: Pointer to a PMD. * @addr: Virtual address associated with pmd. * - * Context: The pmd range has been unmaped and TLB purged. + * Context: The pmd range has been unmapped and TLB purged. * Return: 1 if clearing the entry succeeded. 0 otherwise. */ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) @@ -760,6 +776,10 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) pte = (pte_t *)pmd_page_vaddr(*pmd); pmd_clear(pmd); + + /* INVLPG to clear all paging-structure caches */ + flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1); + free_page((unsigned long)pte); return 1;