ab31640
From 09d533f4c80b7eaf9fb4e36ebba8259580857a9d Mon Sep 17 00:00:00 2001
ab31640
From: Andrew Cooper <andrew.cooper3@citrix.com>
ab31640
Date: Tue, 12 Jul 2022 11:12:46 +0200
ab31640
Subject: [PATCH] x86/spec-ctrl: Only adjust MSR_SPEC_CTRL for idle with legacy
ab31640
 IBRS
ab31640
MIME-Version: 1.0
ab31640
Content-Type: text/plain; charset=utf8
ab31640
Content-Transfer-Encoding: 8bit
ab31640
ab31640
Back at the time of the original Spectre-v2 fixes, it was recommended to clear
ab31640
MSR_SPEC_CTRL when going idle.  This is because of the side effects on the
ab31640
sibling thread caused by the microcode IBRS and STIBP implementations which
ab31640
were retrofitted to existing CPUs.
ab31640
ab31640
However, there are no relevant cross-thread impacts for the hardware
ab31640
IBRS/STIBP implementations, so this logic should not be used on Intel CPUs
ab31640
supporting eIBRS, or any AMD CPUs; doing so only adds unnecessary latency to
ab31640
the idle path.
ab31640
ab31640
Furthermore, there's no point playing with MSR_SPEC_CTRL in the idle paths if
ab31640
SMT is disabled for other reasons.
ab31640
ab31640
Fixes: 8d03080d2a33 ("x86/spec-ctrl: Cease using thunk=lfence on AMD")
ab31640
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
ab31640
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
ab31640
master commit: ffc7694e0c99eea158c32aa164b7d1e1bb1dc46b
ab31640
master date: 2022-06-30 18:07:13 +0100
ab31640
---
ab31640
 xen/arch/x86/spec_ctrl.c          | 10 ++++++++--
ab31640
 xen/include/asm-x86/cpufeatures.h |  2 +-
ab31640
 xen/include/asm-x86/spec_ctrl.h   |  5 +++--
ab31640
 3 files changed, 12 insertions(+), 5 deletions(-)
ab31640
ab31640
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
ab31640
index 099113ba41..1ed5ceda8b 100644
ab31640
--- a/xen/arch/x86/spec_ctrl.c
ab31640
+++ b/xen/arch/x86/spec_ctrl.c
ab31640
@@ -1150,8 +1150,14 @@ void __init init_speculation_mitigations(void)
ab31640
     /* (Re)init BSP state now that default_spec_ctrl_flags has been calculated. */
ab31640
     init_shadow_spec_ctrl_state();
ab31640
 
ab31640
-    /* If Xen is using any MSR_SPEC_CTRL settings, adjust the idle path. */
ab31640
-    if ( default_xen_spec_ctrl )
ab31640
+    /*
ab31640
+     * For microcoded IBRS only (i.e. Intel, pre eIBRS), it is recommended to
ab31640
+     * clear MSR_SPEC_CTRL before going idle, to avoid impacting sibling
ab31640
+     * threads.  Activate this if SMT is enabled, and Xen is using a non-zero
ab31640
+     * MSR_SPEC_CTRL setting.
ab31640
+     */
ab31640
+    if ( boot_cpu_has(X86_FEATURE_IBRSB) && !(caps & ARCH_CAPS_IBRS_ALL) &&
ab31640
+         hw_smt_enabled && default_xen_spec_ctrl )
ab31640
         setup_force_cpu_cap(X86_FEATURE_SC_MSR_IDLE);
ab31640
 
ab31640
     xpti_init_default(caps);
ab31640
diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h
ab31640
index bd45a144ee..493d338a08 100644
ab31640
--- a/xen/include/asm-x86/cpufeatures.h
ab31640
+++ b/xen/include/asm-x86/cpufeatures.h
ab31640
@@ -33,7 +33,7 @@ XEN_CPUFEATURE(SC_MSR_HVM,        X86_SYNTH(17)) /* MSR_SPEC_CTRL used by Xen fo
ab31640
 XEN_CPUFEATURE(SC_RSB_PV,         X86_SYNTH(18)) /* RSB overwrite needed for PV */
ab31640
 XEN_CPUFEATURE(SC_RSB_HVM,        X86_SYNTH(19)) /* RSB overwrite needed for HVM */
ab31640
 XEN_CPUFEATURE(XEN_SELFSNOOP,     X86_SYNTH(20)) /* SELFSNOOP gets used by Xen itself */
ab31640
-XEN_CPUFEATURE(SC_MSR_IDLE,       X86_SYNTH(21)) /* (SC_MSR_PV || SC_MSR_HVM) && default_xen_spec_ctrl */
ab31640
+XEN_CPUFEATURE(SC_MSR_IDLE,       X86_SYNTH(21)) /* Clear MSR_SPEC_CTRL on idle */
ab31640
 XEN_CPUFEATURE(XEN_LBR,           X86_SYNTH(22)) /* Xen uses MSR_DEBUGCTL.LBR */
ab31640
 /* Bits 23,24 unused. */
ab31640
 XEN_CPUFEATURE(SC_VERW_IDLE,      X86_SYNTH(25)) /* VERW used by Xen for idle */
ab31640
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
ab31640
index 751355f471..7e83e0179f 100644
ab31640
--- a/xen/include/asm-x86/spec_ctrl.h
ab31640
+++ b/xen/include/asm-x86/spec_ctrl.h
ab31640
@@ -78,7 +78,8 @@ static always_inline void spec_ctrl_enter_idle(struct cpu_info *info)
ab31640
     uint32_t val = 0;
ab31640
 
ab31640
     /*
ab31640
-     * Branch Target Injection:
ab31640
+     * It is recommended in some cases to clear MSR_SPEC_CTRL when going idle,
ab31640
+     * to avoid impacting sibling threads.
ab31640
      *
ab31640
      * Latch the new shadow value, then enable shadowing, then update the MSR.
ab31640
      * There are no SMP issues here; only local processor ordering concerns.
ab31640
@@ -114,7 +115,7 @@ static always_inline void spec_ctrl_exit_idle(struct cpu_info *info)
ab31640
     uint32_t val = info->xen_spec_ctrl;
ab31640
 
ab31640
     /*
ab31640
-     * Branch Target Injection:
ab31640
+     * Restore MSR_SPEC_CTRL on exit from idle.
ab31640
      *
ab31640
      * Disable shadowing before updating the MSR.  There are no SMP issues
ab31640
      * here; only local processor ordering concerns.
ab31640
-- 
ab31640
2.30.2
ab31640