From: Andrew Cooper <andrew.cooper3@citrix.com>
Subject: x86/spec-ctrl: Rename VERW related options

VERW is going to be used for a 3rd purpose, and the existing nomenclature
didn't survive the Stale MMIO issues terribly well.

Rename the command line option from `md-clear=` to `verw=`.  This is more
consistent with other options which tend to be named based on what they're
doing, not which feature enumeration they use behind the scenes.  Retain
`md-clear=` as a deprecated alias.

Rename opt_md_clear_{pv,hvm} and opt_fb_clear_mmio to opt_verw_{pv,hvm,mmio},
which has a side effect of making spec_ctrl_init_domain() rather clearer to
follow.

No functional change.

This is part of XSA-452 / CVE-2023-28746.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit f7603ca252e4226739eb3129a5290ee3da3f8ea4)

--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -2050,7 +2050,7 @@ By default SSBD will be mitigated at run
 
 ### spec-ctrl (x86)
 > `= List of [ <bool>, xen=<bool>, {pv,hvm}=<bool>,
->              {msr-sc,rsb,md-clear,ibpb-entry}=<bool>|{pv,hvm}=<bool>,
+>              {msr-sc,rsb,verw,ibpb-entry}=<bool>|{pv,hvm}=<bool>,
 >              bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,psfd,
 >              eager-fpu,l1d-flush,branch-harden,srb-lock,
 >              unpriv-mmio,gds-mit,div-scrub}=<bool> ]`
@@ -2075,7 +2075,7 @@ in place for guests to use.
 
 Use of a positive boolean value for either of these options is invalid.
 
-The `pv=`, `hvm=`, `msr-sc=`, `rsb=`, `md-clear=` and `ibpb-entry=` options
+The `pv=`, `hvm=`, `msr-sc=`, `rsb=`, `verw=` and `ibpb-entry=` options
 offer fine grained control over the primitives by Xen.  These impact Xen's
 ability to protect itself, and/or Xen's ability to virtualise support for
 guests to use.
@@ -2092,11 +2092,12 @@ guests to use.
   guests and if disabled, guests will be unable to use IBRS/STIBP/SSBD/etc.
 * `rsb=` offers control over whether to overwrite the Return Stack Buffer /
   Return Address Stack on entry to Xen.
-* `md-clear=` offers control over whether to use VERW to flush
-  microarchitectural buffers on idle and exit from Xen.  *Note: For
-  compatibility with development versions of this fix, `mds=` is also accepted
-  on Xen 4.12 and earlier as an alias.  Consult vendor documentation in
-  preference to here.*
+* `verw=` offers control over whether to use VERW for its scrubbing side
+  effects at appropriate privilege transitions.  The exact side effects are
+  microarchitecture and microcode specific.  *Note: `md-clear=` is accepted as
+  a deprecated alias.  For compatibility with development versions of XSA-297,
+  `mds=` is also accepted on Xen 4.12 and earlier as an alias.  Consult vendor
+  documentation in preference to here.*
 * `ibpb-entry=` offers control over whether IBPB (Indirect Branch Prediction
   Barrier) is used on entry to Xen.  This is used by default on hardware
   vulnerable to Branch Type Confusion, and hardware vulnerable to Speculative
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -37,8 +37,8 @@ static bool __initdata opt_msr_sc_pv = t
 static bool __initdata opt_msr_sc_hvm = true;
 static bool __initdata opt_rsb_pv = true;
 static bool __initdata opt_rsb_hvm = true;
-static int8_t __read_mostly opt_md_clear_pv = -1;
-static int8_t __read_mostly opt_md_clear_hvm = -1;
+static int8_t __read_mostly opt_verw_pv = -1;
+static int8_t __read_mostly opt_verw_hvm = -1;
 
 static int8_t __read_mostly opt_ibpb_entry_pv = -1;
 static int8_t __read_mostly opt_ibpb_entry_hvm = -1;
@@ -77,7 +77,7 @@ static bool __initdata cpu_has_bug_mds;
 
 static int8_t __initdata opt_srb_lock = -1;
 static bool __initdata opt_unpriv_mmio;
-static bool __read_mostly opt_fb_clear_mmio;
+static bool __read_mostly opt_verw_mmio;
 static int8_t __initdata opt_gds_mit = -1;
 static int8_t __initdata opt_div_scrub = -1;
 
@@ -119,8 +119,8 @@ static int __init parse_spec_ctrl(const
         disable_common:
             opt_rsb_pv = false;
             opt_rsb_hvm = false;
-            opt_md_clear_pv = 0;
-            opt_md_clear_hvm = 0;
+            opt_verw_pv = 0;
+            opt_verw_hvm = 0;
             opt_ibpb_entry_pv = 0;
             opt_ibpb_entry_hvm = 0;
             opt_ibpb_entry_dom0 = false;
@@ -151,14 +151,14 @@ static int __init parse_spec_ctrl(const
         {
             opt_msr_sc_pv = val;
             opt_rsb_pv = val;
-            opt_md_clear_pv = val;
+            opt_verw_pv = val;
             opt_ibpb_entry_pv = val;
         }
         else if ( (val = parse_boolean("hvm", s, ss)) >= 0 )
         {
             opt_msr_sc_hvm = val;
             opt_rsb_hvm = val;
-            opt_md_clear_hvm = val;
+            opt_verw_hvm = val;
             opt_ibpb_entry_hvm = val;
         }
         else if ( (val = parse_boolean("msr-sc", s, ss)) != -1 )
@@ -203,21 +203,22 @@ static int __init parse_spec_ctrl(const
                 break;
             }
         }
-        else if ( (val = parse_boolean("md-clear", s, ss)) != -1 )
+        else if ( (val = parse_boolean("verw", s, ss)) != -1 ||
+                  (val = parse_boolean("md-clear", s, ss)) != -1 )
         {
             switch ( val )
             {
             case 0:
             case 1:
-                opt_md_clear_pv = opt_md_clear_hvm = val;
+                opt_verw_pv = opt_verw_hvm = val;
                 break;
 
             case -2:
-                s += strlen("md-clear=");
+                s += (*s == 'v') ? strlen("verw=") : strlen("md-clear=");
                 if ( (val = parse_boolean("pv", s, ss)) >= 0 )
-                    opt_md_clear_pv = val;
+                    opt_verw_pv = val;
                 else if ( (val = parse_boolean("hvm", s, ss)) >= 0 )
-                    opt_md_clear_hvm = val;
+                    opt_verw_hvm = val;
                 else
             default:
                     rc = -EINVAL;
@@ -511,8 +512,8 @@ static void __init print_details(enum in
            opt_srb_lock                              ? " SRB_LOCK+" : " SRB_LOCK-",
            opt_ibpb_ctxt_switch                      ? " IBPB-ctxt" : "",
            opt_l1d_flush                             ? " L1D_FLUSH" : "",
-           opt_md_clear_pv || opt_md_clear_hvm ||
-           opt_fb_clear_mmio                         ? " VERW"  : "",
+           opt_verw_pv || opt_verw_hvm ||
+           opt_verw_mmio                             ? " VERW"  : "",
            opt_div_scrub                             ? " DIV" : "",
            opt_branch_harden                         ? " BRANCH_HARDEN" : "");
 
@@ -531,13 +532,12 @@ static void __init print_details(enum in
     printk("  Support for HVM VMs:%s%s%s%s%s%s\n",
            (boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ||
             boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ||
-            boot_cpu_has(X86_FEATURE_MD_CLEAR)   ||
             boot_cpu_has(X86_FEATURE_IBPB_ENTRY_HVM) ||
-            opt_eager_fpu)                           ? ""               : " None",
+            opt_eager_fpu || opt_verw_hvm)           ? ""               : " None",
            boot_cpu_has(X86_FEATURE_SC_MSR_HVM)      ? " MSR_SPEC_CTRL" : "",
            boot_cpu_has(X86_FEATURE_SC_RSB_HVM)      ? " RSB"           : "",
            opt_eager_fpu                             ? " EAGER_FPU"     : "",
-           boot_cpu_has(X86_FEATURE_MD_CLEAR)        ? " MD_CLEAR"      : "",
+           opt_verw_hvm                              ? " VERW"          : "",
            boot_cpu_has(X86_FEATURE_IBPB_ENTRY_HVM)  ? " IBPB-entry"    : "");
 
 #endif
@@ -545,13 +545,12 @@ static void __init print_details(enum in
     printk("  Support for PV VMs:%s%s%s%s%s%s\n",
            (boot_cpu_has(X86_FEATURE_SC_MSR_PV) ||
             boot_cpu_has(X86_FEATURE_SC_RSB_PV) ||
-            boot_cpu_has(X86_FEATURE_MD_CLEAR)  ||
             boot_cpu_has(X86_FEATURE_IBPB_ENTRY_PV) ||
-            opt_eager_fpu)                           ? ""               : " None",
+            opt_eager_fpu || opt_verw_pv)            ? ""               : " None",
            boot_cpu_has(X86_FEATURE_SC_MSR_PV)       ? " MSR_SPEC_CTRL" : "",
            boot_cpu_has(X86_FEATURE_SC_RSB_PV)       ? " RSB"           : "",
            opt_eager_fpu                             ? " EAGER_FPU"     : "",
-           boot_cpu_has(X86_FEATURE_MD_CLEAR)        ? " MD_CLEAR"      : "",
+           opt_verw_pv                               ? " VERW"          : "",
            boot_cpu_has(X86_FEATURE_IBPB_ENTRY_PV)   ? " IBPB-entry"    : "");
 
     printk("  XPTI (64-bit PV only): Dom0 %s, DomU %s (with%s PCID)\n",
@@ -1451,8 +1450,8 @@ void spec_ctrl_init_domain(struct domain
 {
     bool pv = is_pv_domain(d);
 
-    bool verw = ((pv ? opt_md_clear_pv : opt_md_clear_hvm) ||
-                 (opt_fb_clear_mmio && is_iommu_enabled(d)));
+    bool verw = ((pv ? opt_verw_pv : opt_verw_hvm) ||
+                 (opt_verw_mmio && is_iommu_enabled(d)));
 
     bool ibpb = ((pv ? opt_ibpb_entry_pv : opt_ibpb_entry_hvm) &&
                  (d->domain_id != 0 || opt_ibpb_entry_dom0));
@@ -1727,19 +1726,20 @@ void __init init_speculation_mitigations
      * the return-to-guest path.
      */
     if ( opt_unpriv_mmio )
-        opt_fb_clear_mmio = cpu_has_fb_clear;
+        opt_verw_mmio = cpu_has_fb_clear;
 
     /*
      * By default, enable PV and HVM mitigations on MDS-vulnerable hardware.
      * This will only be a token effort for MLPDS/MFBDS when HT is enabled,
      * but it is somewhat better than nothing.
      */
-    if ( opt_md_clear_pv == -1 )
-        opt_md_clear_pv = ((cpu_has_bug_mds || cpu_has_bug_msbds_only) &&
-                           boot_cpu_has(X86_FEATURE_MD_CLEAR));
-    if ( opt_md_clear_hvm == -1 )
-        opt_md_clear_hvm = ((cpu_has_bug_mds || cpu_has_bug_msbds_only) &&
-                            boot_cpu_has(X86_FEATURE_MD_CLEAR));
+    if ( opt_verw_pv == -1 )
+        opt_verw_pv = ((cpu_has_bug_mds || cpu_has_bug_msbds_only) &&
+                       cpu_has_md_clear);
+
+    if ( opt_verw_hvm == -1 )
+        opt_verw_hvm = ((cpu_has_bug_mds || cpu_has_bug_msbds_only) &&
+                        cpu_has_md_clear);
 
     /*
      * Enable MDS/MMIO defences as applicable.  The Idle blocks need using if
@@ -1752,12 +1752,12 @@ void __init init_speculation_mitigations
      * MDS mitigations.  L1D_FLUSH is not safe for MMIO mitigations.)
      *
      * After calculating the appropriate idle setting, simplify
-     * opt_md_clear_hvm to mean just "should we VERW on the way into HVM
+     * opt_verw_hvm to mean just "should we VERW on the way into HVM
      * guests", so spec_ctrl_init_domain() can calculate suitable settings.
      */
-    if ( opt_md_clear_pv || opt_md_clear_hvm || opt_fb_clear_mmio )
+    if ( opt_verw_pv || opt_verw_hvm || opt_verw_mmio )
         setup_force_cpu_cap(X86_FEATURE_SC_VERW_IDLE);
-    opt_md_clear_hvm &= !cpu_has_skip_l1dfl && !opt_l1d_flush;
+    opt_verw_hvm &= !cpu_has_skip_l1dfl && !opt_l1d_flush;
 
     /*
      * Warn the user if they are on MLPDS/MFBDS-vulnerable hardware with HT
