[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen stable-4.17] x86/spec-ctrl: Mitigate Gather Data Sampling
commit b9ade05cbba977673d5a08bc7a5940c5fd8add0e Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Wed Jan 4 16:32:44 2023 +0000 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Tue Aug 8 16:02:17 2023 +0100 x86/spec-ctrl: Mitigate Gather Data Sampling This is part of XSA-435 / CVE-2022-40982 Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> (cherry picked from commit 56d690efd3ca3c68e1d222f259fb3d216206e8e5) --- docs/misc/xen-command-line.pandoc | 10 ++- xen/arch/x86/spec_ctrl.c | 158 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc index 6169c52018..d9dae740cc 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -2315,7 +2315,7 @@ By default SSBD will be mitigated at runtime (i.e `ssbd=runtime`). > {msr-sc,rsb,md-clear,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}=<bool> ]` +> unpriv-mmio,gds-mit}=<bool> ]` Controls for speculative execution sidechannel mitigations. By default, Xen will pick the most appropriate mitigations based on compiled in support, @@ -2429,6 +2429,14 @@ and/or `SRBDS_CTRL` functionality available in the Intel May 2022 microcode release to mitigate cross-domain leakage of data via the MMIO Stale Data vulnerabilities. +On all hardware, the `gds-mit=` option can be used to force or prevent Xen +from mitigating the GDS (Gather Data Sampling) vulnerability. By default, Xen +will mitigate GDS on hardware believed to be vulnerable. On hardware +supporting GDS_CTRL (requires the August 2023 microcode), and where firmware +has elected not to lock the configuration, Xen will use GDS_CTRL to mitigate +GDS with. Otherwise, Xen will mitigate by disabling AVX, which blocks the use +of the AVX2 Gather instructions. + ### sync_console > `= <boolean>` diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c index d79374d63c..79b98f0fe7 100644 --- a/xen/arch/x86/spec_ctrl.c +++ b/xen/arch/x86/spec_ctrl.c @@ -78,6 +78,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 __ro_after_init opt_fb_clear_mmio; +static int8_t __initdata opt_gds_mit = -1; static int __init cf_check parse_spec_ctrl(const char *s) { @@ -131,6 +132,7 @@ static int __init cf_check parse_spec_ctrl(const char *s) opt_branch_harden = false; opt_srb_lock = 0; opt_unpriv_mmio = false; + opt_gds_mit = 0; } else if ( val > 0 ) rc = -EINVAL; @@ -281,6 +283,8 @@ static int __init cf_check parse_spec_ctrl(const char *s) opt_srb_lock = val; else if ( (val = parse_boolean("unpriv-mmio", s, ss)) >= 0 ) opt_unpriv_mmio = val; + else if ( (val = parse_boolean("gds-mit", s, ss)) >= 0 ) + opt_gds_mit = val; else rc = -EINVAL; @@ -1279,6 +1283,158 @@ static __init void mds_calculations(void) } } +static bool __init cpu_has_gds(void) +{ + /* + * Any part advertising GDS_NO should be not vulnerable to GDS. This + * includes cases where the hypervisor is mitigating behind our backs, or + * has synthesized GDS_NO on older parts for levelling purposes. + */ + if ( cpu_has_gds_no ) + return false; + + /* + * On real hardware the GDS_CTRL control only exists on parts vulnerable + * to GDS and with up-to-date microcode. It might also be virtualised by + * an aware hypervisor, meaning "somewhere you might migrate to is + * vulnerable". + */ + if ( cpu_has_gds_ctrl ) + return true; + + /* + * An attacker requires the use of the AVX2 GATHER instructions to leak + * data with GDS. However, the only way to block those instructions is to + * prevent XCR0[2] from being set, which is original AVX. A hypervisor + * might do this as a stopgap mitigation. + */ + if ( !cpu_has_avx ) + return false; + + /* + * GDS affects the Core line from Skylake up to but not including Golden + * Cove (Alder Lake, Sapphire Rapids). Broadwell and older, and the Atom + * line, and all hybrid parts are unaffected. + */ + switch ( boot_cpu_data.x86_model ) + { + case 0x55: /* Skylake/Cascade Lake/Cooper Lake SP */ + case 0x6a: /* Ice Lake SP */ + case 0x6c: /* Ice Lake D */ + case 0x7e: /* Ice Lake U/Y */ + case 0x8c: /* Tiger Lake U */ + case 0x8d: /* Tiger Lake H */ + case 0x8e: /* Amber/Kaby/Coffee/Whiskey/Comet lake U/Y */ + case 0x9e: /* Kaby/Coffee lake H/S/Xeon */ + case 0xa5: /* Comet Lake H/S */ + case 0xa6: /* Comet Lake U */ + case 0xa7: /* Rocket Lake */ + return true; + + default: + /* + * If we've got here and are virtualised, we're most likely under a + * hypervisor unaware of GDS at which point we've lost. Err on the + * safe side. + */ + return cpu_has_hypervisor; + } +} + +static void __init gds_calculations(void) +{ + bool cpu_has_bug_gds, mitigated = false; + + /* GDS is only known to affect Intel Family 6 processors at this time. */ + if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || + boot_cpu_data.x86 != 6 ) + return; + + cpu_has_bug_gds = cpu_has_gds(); + + /* + * If we've got GDS_CTRL, we're either native with up-to-date microcode on + * a GDS-vulnerable part, or virtualised under a GDS-aware hypervisor. + */ + if ( cpu_has_gds_ctrl ) + { + bool locked; + uint64_t opt_ctrl; + + if ( cpu_has_gds_no ) + { + /* + * We don't expect to ever see GDS_CTL and GDS_NO set together. + * Complain loudly, and forgo playing with other features. + */ + printk(XENLOG_ERR + "FIRMWARE BUG: CPU %02x-%02x-%02x, ucode 0x%08x: GDS_CTRL && GDS_NO\n", + boot_cpu_data.x86, boot_cpu_data.x86_model, + boot_cpu_data.x86_mask, this_cpu(cpu_sig).rev); + return add_taint(TAINT_CPU_OUT_OF_SPEC); + } + + rdmsrl(MSR_MCU_OPT_CTRL, opt_ctrl); + + mitigated = !(opt_ctrl & MCU_OPT_CTRL_GDS_MIT_DIS); + locked = opt_ctrl & MCU_OPT_CTRL_GDS_MIT_LOCK; + + /* + * Firmware will lock the GDS mitigation if e.g. SGX is active. + * Alternatively, a hypervisor might virtualise GDS_CTRL as locked. + * Warn if the mitigiation is locked and the user requested the + * opposite configuration. + */ + if ( locked ) + { + if ( opt_gds_mit >= 0 && opt_gds_mit != mitigated ) + printk(XENLOG_WARNING + "GDS_MIT locked by firwmare - ignoring spec-ctrl=gds-mit setting\n"); + opt_gds_mit = mitigated; + } + else if ( opt_gds_mit == -1 ) + opt_gds_mit = cpu_has_bug_gds; /* Mitigate GDS by default */ + + /* + * Latch our choice of GDS_MIT for all CPUs to pick up. If LOCK is + * set, we latch the same value as it currently holds. + */ + set_in_mcu_opt_ctrl(MCU_OPT_CTRL_GDS_MIT_DIS, + opt_gds_mit ? 0 : MCU_OPT_CTRL_GDS_MIT_DIS); + mitigated = opt_gds_mit; + } + else if ( opt_gds_mit == -1 ) + opt_gds_mit = cpu_has_bug_gds; /* Mitigate GDS by default */ + + /* + * If we think we're not on vulnerable hardware, or we've mitigated GDS, + * synthesize GDS_NO. This is mostly for the benefit of guests, to inform + * them not to panic. + */ + if ( !cpu_has_bug_gds || mitigated ) + return setup_force_cpu_cap(X86_FEATURE_GDS_NO); + + /* + * If all else has failed, mitigate by disabling AVX. This prevents + * guests from enabling %xcr0.ymm, thereby blocking the use of VGATHER + * instructions. + * + * There's at least one affected CPU not expected to recieve a microcode + * update, and this is the only remaining mitigation. + * + * If we're virtualised, this prevents our guests attacking each other, + * but it doesn't stop the outer hypervisor's guests attacking us. Leave + * a note to this effect. + */ + if ( cpu_has_avx && opt_gds_mit ) + { + setup_clear_cpu_cap(X86_FEATURE_AVX); + printk(XENLOG_WARNING "Mitigating GDS by disabling AVX%s\n", + cpu_has_hypervisor ? + " while virtualised - protections are best-effort" : ""); + } +} + void spec_ctrl_init_domain(struct domain *d) { bool pv = is_pv_domain(d); @@ -1758,6 +1914,8 @@ void __init init_speculation_mitigations(void) opt_srb_lock ? 0 : MCU_OPT_CTRL_RNGDS_MITG_DIS); } + gds_calculations(); + print_details(thunk); /* -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.17
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |