Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935375AbcCPXyp (ORCPT ); Wed, 16 Mar 2016 19:54:45 -0400 Received: from g4t3426.houston.hp.com ([15.201.208.54]:49435 "EHLO g4t3426.houston.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755678AbcCPXyo (ORCPT ); Wed, 16 Mar 2016 19:54:44 -0400 From: Toshi Kani To: mingo@kernel.org, bp@suse.de, hpa@zytor.com, tglx@linutronix.de Cc: mcgrof@suse.com, jgross@suse.com, paul.gortmaker@windriver.com, konrad.wilk@oracle.com, elliott@hpe.com, x86@kernel.org, xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, Toshi Kani Subject: [PATCH v2 2/6] x86/mm/pat: Add pat_disable() interface Date: Wed, 16 Mar 2016 18:46:55 -0600 Message-Id: <1458175619-32206-1-git-send-email-toshi.kani@hpe.com> X-Mailer: git-send-email 2.5.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2890 Lines: 91 In preparation to fix a regression caused by 'commit 9cd25aac1f44 ("x86/mm/pat: Emulate PAT when it is disabled")', PAT needs to provide an interface that disables the OS to initialize PAT MSR. PAT MSR initialization must be done on all CPUs with the specific sequence of operations defined in Intel SDM. This requires MTRR to be enabled since pat_init() is called as part of MTRR init from mtrr_rendezvous_handler(). Change pat_disable() as the interface to disable the OS to initialize PAT MSR, and set PAT table with pat_keep_handoff_state(). This interface can be called when PAT initialization may not be performed. This also assures that pat_disable() called from pat_bsp_init() to set PAT table properly when CPU does not support PAT. Signed-off-by: Toshi Kani Cc: Borislav Petkov Cc: Luis R. Rodriguez Cc: Juergen Gross Cc: Robert Elliott Cc: Ingo Molnar Cc: H. Peter Anvin Cc: Thomas Gleixner --- arch/x86/include/asm/pat.h | 1 + arch/x86/mm/pat.c | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h index ca6c228..016142b 100644 --- a/arch/x86/include/asm/pat.h +++ b/arch/x86/include/asm/pat.h @@ -5,6 +5,7 @@ #include bool pat_enabled(void); +void pat_disable(const char *reason); extern void pat_init(void); void pat_init_cache_modes(u64); diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index e0a34b0..48d1619 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -40,11 +40,26 @@ static bool boot_cpu_done; static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT); +static void pat_keep_handoff_state(void); -static inline void pat_disable(const char *reason) +/** + * pat_disable() - Disable the OS to initialize PAT MSR + * + * This function disables the OS to initialize PAT MSR, and calls + * pat_keep_handoff_state() to set PAT table to the handoff state. + */ +void pat_disable(const char *reason) { + if (boot_cpu_done) { + pr_err("x86/PAT: PAT cannot be disabled after initialization " + "(attempting: %s)\n", reason); + return; + } + __pat_enabled = 0; pr_info("x86/PAT: %s\n", reason); + + pat_keep_handoff_state(); } static int __init nopat(char *str) @@ -202,7 +217,7 @@ static void pat_bsp_init(u64 pat) { u64 tmp_pat; - if (!cpu_has_pat) { + if (!boot_cpu_has(X86_FEATURE_PAT)) { pat_disable("PAT not supported by CPU."); return; } @@ -220,7 +235,7 @@ static void pat_bsp_init(u64 pat) static void pat_ap_init(u64 pat) { - if (!cpu_has_pat) { + if (!boot_cpu_has(X86_FEATURE_PAT)) { /* * If this happens we are on a secondary CPU, but switched to * PAT on the boot CPU. We have no way to undo PAT.