From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753799AbcGHATn (ORCPT ); Thu, 7 Jul 2016 20:19:43 -0400 Received: from mga09.intel.com ([134.134.136.24]:51737 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753600AbcGHATO (ORCPT ); Thu, 7 Jul 2016 20:19:14 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,326,1464678000"; d="scan'208";a="991091646" Subject: [PATCH 2/4] x86, pagetable: ignore A/D bits in pte/pmd/pud_none() To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, linux-mm@kvack.org, torvalds@linux-foundation.org, akpm@linux-foundation.org, bp@alien8.de, ak@linux.intel.com, mhocko@suse.com, dave.hansen@intel.com, Dave Hansen , dave.hansen@linux.intel.com From: Dave Hansen Date: Thu, 07 Jul 2016 17:19:12 -0700 References: <20160708001909.FB2443E2@viggo.jf.intel.com> In-Reply-To: <20160708001909.FB2443E2@viggo.jf.intel.com> Message-Id: <20160708001912.5216F89C@viggo.jf.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dave Hansen The erratum we are fixing here can lead to stray setting of the A and D bits. That means that a pte that we cleared might suddenly have A/D set. So, stop considering those bits when determining if a pte is pte_none(). The same goes for the other pmd_none() and pud_none(). pgd_none() can be skipped because it is not affected; we do not use PGD entries for anything other than pagetables on affected configurations. This adds a tiny amount of overhead to all pte_none() checks. I doubt we'll be able to measure it anywhere. Signed-off-by: Dave Hansen --- b/arch/x86/include/asm/pgtable.h | 13 ++++++++++--- b/arch/x86/include/asm/pgtable_types.h | 6 ++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff -puN arch/x86/include/asm/pgtable.h~knl-strays-20-mod-pte-none arch/x86/include/asm/pgtable.h --- a/arch/x86/include/asm/pgtable.h~knl-strays-20-mod-pte-none 2016-07-07 17:17:43.974764976 -0700 +++ b/arch/x86/include/asm/pgtable.h 2016-07-07 17:17:43.980765246 -0700 @@ -480,7 +480,7 @@ pte_t *populate_extra_pte(unsigned long static inline int pte_none(pte_t pte) { - return !pte.pte; + return !(pte.pte & ~(_PAGE_KNL_ERRATUM_MASK)); } #define __HAVE_ARCH_PTE_SAME @@ -552,7 +552,8 @@ static inline int pmd_none(pmd_t pmd) { /* Only check low word on 32-bit platforms, since it might be out of sync with upper half. */ - return (unsigned long)native_pmd_val(pmd) == 0; + unsigned long val = native_pmd_val(pmd); + return (val & ~_PAGE_KNL_ERRATUM_MASK) == 0; } static inline unsigned long pmd_page_vaddr(pmd_t pmd) @@ -616,7 +617,7 @@ static inline unsigned long pages_to_mb( #if CONFIG_PGTABLE_LEVELS > 2 static inline int pud_none(pud_t pud) { - return native_pud_val(pud) == 0; + return (native_pud_val(pud) & ~(_PAGE_KNL_ERRATUM_MASK)) == 0; } static inline int pud_present(pud_t pud) @@ -694,6 +695,12 @@ static inline int pgd_bad(pgd_t pgd) static inline int pgd_none(pgd_t pgd) { + /* + * There is no need to do a workaround for the KNL stray + * A/D bit erratum here. PGDs only point to page tables + * except on 32-bit non-PAE which is not supported on + * KNL. + */ return !native_pgd_val(pgd); } #endif /* CONFIG_PGTABLE_LEVELS > 3 */ diff -puN arch/x86/include/asm/pgtable_types.h~knl-strays-20-mod-pte-none arch/x86/include/asm/pgtable_types.h --- a/arch/x86/include/asm/pgtable_types.h~knl-strays-20-mod-pte-none 2016-07-07 17:17:43.976765066 -0700 +++ b/arch/x86/include/asm/pgtable_types.h 2016-07-07 17:17:43.980765246 -0700 @@ -70,6 +70,12 @@ _PAGE_PKEY_BIT2 | \ _PAGE_PKEY_BIT3) +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) +#define _PAGE_KNL_ERRATUM_MASK (_PAGE_DIRTY | _PAGE_ACCESSED) +#else +#define _PAGE_KNL_ERRATUM_MASK 0 +#endif + #ifdef CONFIG_KMEMCHECK #define _PAGE_HIDDEN (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN) #else _