Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp1150024imm; Tue, 15 May 2018 14:41:18 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpBrO5R3+Yiioc+ZYTaiX0PKdS4j1o9SbQdvz77RVVgcJw0Al4l5uy7Yil9W5Cc4tuiiaZy X-Received: by 2002:a17:902:14b:: with SMTP id 69-v6mr16289498plb.184.1526420478123; Tue, 15 May 2018 14:41:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526420478; cv=none; d=google.com; s=arc-20160816; b=O1As928+s2stS1p7dM8BJ1S8J8WgqELOjuTTBE0kD5Dpc60AXDYtmm9uiogvvSBg6Z y2+4X9vB8DH4mCzB59P4jWs5ML5edvxyMlRg2isT8nz7tGvOEX1Y9GhvoDOJA2E1Qez1 Gotj9JdzKBGb4fjSV3YilMEhogJACSLEDo3K/wxjc3lcW8HzP1LS3gJcNCQWpfG0uXH5 JZBXWalm58fA5/eyXOV3zLBp2mRN6n0ZiuXIeFkxaHQ5rIbc/JmroEGLgMFA6FbX0wzp cv8/cWKjpwY08XHyXWInh/zRT1pxsSGaGdRWTIpHhtJgNCdocbX71rbevsZtTUFvNVqo B5NA== 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=o8sgoZjOxvubH3vqlI10o5Q7nh1e1mqbGOKF/LOEVSM=; b=GwtfbBNu0dOwcvHAYviKmTB6sJXQrN7/zg3wR9ZDn75DmKEWpS7MhBpSNJG6JkE9p5 P4+BSaSfjI8nYNp86PmlgoDcq/9batZGr9HqXRwNCqa/+e/ayGzSsBJ24SFhQZHDZssZ hfpewBY6/vV8oyUp1jmUtkexWiB/5Bp3N/cGaeO1cKc0W0OY3p5y3XNpvX6lnzXOo/5K ln4QvaYMXIqTXDFZfRL0r/r+022VenFaxR0rS9VVCQP975Qel3WVzAU4G5+QDFzy8ruU NxiQsX9R4FlCORl4BH7eYdCgeQT20bMjzmFM+AJt6etNUE9XrVsPlYoCCq6iNxpX47Rm NW+g== 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 v81-v6si987645pfi.22.2018.05.15.14.41.03; Tue, 15 May 2018 14:41:18 -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 S1752357AbeEOVky (ORCPT + 99 others); Tue, 15 May 2018 17:40:54 -0400 Received: from g2t2352.austin.hpe.com ([15.233.44.25]:23599 "EHLO g2t2352.austin.hpe.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752243AbeEOVkw (ORCPT ); Tue, 15 May 2018 17:40:52 -0400 Received: from g2t2360.austin.hpecorp.net (g2t2360.austin.hpecorp.net [16.196.225.135]) by g2t2352.austin.hpe.com (Postfix) with ESMTP id 6038085; Tue, 15 May 2018 21:40:51 +0000 (UTC) Received: from misato.americas.hpqcorp.net (unknown [10.34.81.122]) by g2t2360.austin.hpecorp.net (Postfix) with ESMTP id AE7C044; Tue, 15 May 2018 21:40:50 +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 v2 3/3] x86/mm: add TLB purge to free pmd/pte page interfaces Date: Tue, 15 May 2018 15:39:31 -0600 Message-Id: <20180515213931.23885-4-toshi.kani@hpe.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180515213931.23885-1-toshi.kani@hpe.com> References: <20180515213931.23885-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 | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index f60fdf411103..7e96594c7e97 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -721,24 +721,42 @@ 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); + if (!pmd_sv) + return 0; - 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; @@ -749,7 +767,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) @@ -761,6 +779,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;