Mailing List Archive

[xen stable-4.15] x86/spec-ctrl: Rename VERW related options
commit a8f99b49075ea30e5a074eb0579609a4ea0a44a3
Author: Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Mon Feb 12 17:50:43 2024 +0000
Commit: Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Tue Mar 12 16:37:44 2024 +0000

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)
---
docs/misc/xen-command-line.pandoc | 15 +++++-----
xen/arch/x86/spec_ctrl.c | 62 ++++++++++++++++++++-------------------
2 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index f3d1009f2d..d020d79dde 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -2186,7 +2186,7 @@ By default SSBD will be mitigated at runtime (i.e `ssbd=runtime`).

### 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> ]`
@@ -2211,7 +2211,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.
@@ -2228,11 +2228,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
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index f75124117b..43449b4c7a 100644
--- 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 = true;
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; /* Any other M{LP,SB,FB}DS combination.

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 char *s)
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 char *s)
{
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 char *s)
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;
@@ -512,8 +513,8 @@ static void __init print_details(enum ind_thunk thunk)
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" : "");

@@ -533,11 +534,11 @@ static void __init print_details(enum ind_thunk thunk)
(boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ||
boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ||
boot_cpu_has(X86_FEATURE_IBPB_ENTRY_HVM) ||
- opt_eager_fpu || opt_md_clear_hvm) ? "" : " 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" : "",
- opt_md_clear_hvm ? " MD_CLEAR" : "",
+ opt_verw_hvm ? " VERW" : "",
boot_cpu_has(X86_FEATURE_IBPB_ENTRY_HVM) ? " IBPB-entry" : "");

#endif
@@ -546,11 +547,11 @@ static void __init print_details(enum ind_thunk thunk)
(boot_cpu_has(X86_FEATURE_SC_MSR_PV) ||
boot_cpu_has(X86_FEATURE_SC_RSB_PV) ||
boot_cpu_has(X86_FEATURE_IBPB_ENTRY_PV) ||
- opt_eager_fpu || opt_md_clear_pv) ? "" : " 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" : "",
- opt_md_clear_pv ? " 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",
@@ -1450,8 +1451,8 @@ void spec_ctrl_init_domain(struct domain *d)
{
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));
@@ -1765,19 +1766,20 @@ void __init init_speculation_mitigations(void)
* 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
@@ -1790,12 +1792,12 @@ void __init init_speculation_mitigations(void)
* 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
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.15