* [PATCH for-4.17 v3 0/2] amd/virt_ssbd: refactoring and fixes
@ 2022-11-03 17:02 Roger Pau Monne
2022-11-03 17:02 ` [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch Roger Pau Monne
2022-11-03 17:02 ` [PATCH for-4.17 v3 2/2] amd: remove VIRT_SC_MSR_HVM synthetic feature Roger Pau Monne
0 siblings, 2 replies; 9+ messages in thread
From: Roger Pau Monne @ 2022-11-03 17:02 UTC (permalink / raw)
To: xen-devel
Cc: Henry.Wang, Roger Pau Monne, Andrew Cooper, George Dunlap,
Jan Beulich, Julien Grall, Stefano Stabellini, Wei Liu
Hello,
Just two patches remaining, and the last one is already Acked.
First patch deals with moving the switching of SSBD from guest
vm{entry,exit} to vCPU context switch, and lets Xen run with the guest
SSBD selection under some circumstances by default.
Thanks, Roger.
Roger Pau Monne (2):
amd/virt_ssbd: set SSBD at vCPU context switch
amd: remove VIRT_SC_MSR_HVM synthetic feature
docs/misc/xen-command-line.pandoc | 10 +++--
xen/arch/x86/cpu/amd.c | 56 ++++++++++++++------------
xen/arch/x86/cpuid.c | 9 +++--
xen/arch/x86/hvm/svm/entry.S | 6 ---
xen/arch/x86/hvm/svm/svm.c | 45 ++++++++-------------
xen/arch/x86/include/asm/amd.h | 3 +-
xen/arch/x86/include/asm/cpufeatures.h | 2 +-
xen/arch/x86/msr.c | 9 +++++
xen/arch/x86/spec_ctrl.c | 8 ++--
9 files changed, 75 insertions(+), 73 deletions(-)
--
2.37.3
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch 2022-11-03 17:02 [PATCH for-4.17 v3 0/2] amd/virt_ssbd: refactoring and fixes Roger Pau Monne @ 2022-11-03 17:02 ` Roger Pau Monne 2022-11-03 17:06 ` Henry Wang ` (2 more replies) 2022-11-03 17:02 ` [PATCH for-4.17 v3 2/2] amd: remove VIRT_SC_MSR_HVM synthetic feature Roger Pau Monne 1 sibling, 3 replies; 9+ messages in thread From: Roger Pau Monne @ 2022-11-03 17:02 UTC (permalink / raw) To: xen-devel Cc: Henry.Wang, Roger Pau Monne, Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall, Stefano Stabellini, Wei Liu The current logic for AMD SSBD context switches it on every vm{entry,exit} if the Xen and guest selections don't match. This is expensive when not using SPEC_CTRL, and hence should be avoided as much as possible. When SSBD is not being set from SPEC_CTRL on AMD don't context switch at vm{entry,exit} and instead only context switch SSBD when switching vCPUs. This has the side effect of running Xen code with the guest selection of SSBD, the documentation is updated to note this behavior. Also note that then when `ssbd` is selected on the command line guest SSBD selection will not have an effect, and the hypervisor will run with SSBD unconditionally enabled when not using SPEC_CTRL itself. This fixes an issue with running C code in a GIF=0 region, that's problematic when using UBSAN or other instrumentation techniques. As a result of no longer running the code to set SSBD in a GIF=0 region the locking of amd_set_legacy_ssbd() can be done using normal spinlocks, and some more checks can be added to assure it works as intended. Finally it's also worth noticing that since the guest SSBD selection is no longer set on vmentry the VIRT_SPEC_MSR handling needs to propagate the value to the hardware as part of handling the wrmsr. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> --- Changes since v2: - Fix calling set_reg unconditionally. - Fix comment. - Call amd_set_ssbd() from guest_wrmsr(). Changes since v1: - Just check virt_spec_ctrl value != 0 on context switch. - Remove stray asm newline. - Use val in svm_set_reg(). - Fix style in amd.c. - Do not clear ssbd --- docs/misc/xen-command-line.pandoc | 10 +++--- xen/arch/x86/cpu/amd.c | 55 +++++++++++++++++-------------- xen/arch/x86/hvm/svm/entry.S | 6 ---- xen/arch/x86/hvm/svm/svm.c | 45 ++++++++++--------------- xen/arch/x86/include/asm/amd.h | 2 +- xen/arch/x86/msr.c | 9 +++++ 6 files changed, 63 insertions(+), 64 deletions(-) diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc index 0fbdcb574f..424b12cfb2 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -2372,10 +2372,12 @@ By default, Xen will use STIBP when IBRS is in use (IBRS implies STIBP), and when hardware hints recommend using it as a blanket setting. On hardware supporting SSBD (Speculative Store Bypass Disable), the `ssbd=` -option can be used to force or prevent Xen using the feature itself. On AMD -hardware, this is a global option applied at boot, and not virtualised for -guest use. On Intel hardware, the feature is virtualised for guests, -independently of Xen's choice of setting. +option can be used to force or prevent Xen using the feature itself. The +feature is virtualised for guests, independently of Xen's choice of setting. +On AMD hardware, disabling Xen SSBD usage on the command line (`ssbd=0` which +is the default value) can lead to Xen running with the guest SSBD selection +depending on hardware support, on the same hardware setting `ssbd=1` will +result in SSBD always being enabled, regardless of guest choice. On hardware supporting PSFD (Predictive Store Forwarding Disable), the `psfd=` option can be used to force or prevent Xen using the feature itself. By diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c index 98c52d0686..05d72c6501 100644 --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -742,7 +742,7 @@ void amd_init_ssbd(const struct cpuinfo_x86 *c) } static struct ssbd_ls_cfg { - bool locked; + spinlock_t lock; unsigned int count; } __cacheline_aligned *ssbd_ls_cfg; static unsigned int __ro_after_init ssbd_max_cores; @@ -753,7 +753,7 @@ bool __init amd_setup_legacy_ssbd(void) unsigned int i; if ((boot_cpu_data.x86 != 0x17 && boot_cpu_data.x86 != 0x18) || - boot_cpu_data.x86_num_siblings <= 1) + boot_cpu_data.x86_num_siblings <= 1 || opt_ssbd) return true; /* @@ -776,46 +776,51 @@ bool __init amd_setup_legacy_ssbd(void) if (!ssbd_ls_cfg) return false; - if (opt_ssbd) - for (i = 0; i < ssbd_max_cores * AMD_FAM17H_MAX_SOCKETS; i++) - /* Set initial state, applies to any (hotplug) CPU. */ - ssbd_ls_cfg[i].count = boot_cpu_data.x86_num_siblings; + for (i = 0; i < ssbd_max_cores * AMD_FAM17H_MAX_SOCKETS; i++) + spin_lock_init(&ssbd_ls_cfg[i].lock); return true; } -/* - * Executed from GIF==0 context: avoid using BUG/ASSERT or other functionality - * that relies on exceptions as those are not expected to run in GIF==0 - * context. - */ -void amd_set_legacy_ssbd(bool enable) +static void core_set_legacy_ssbd(bool enable) { const struct cpuinfo_x86 *c = ¤t_cpu_data; struct ssbd_ls_cfg *status; + unsigned long flags; if ((c->x86 != 0x17 && c->x86 != 0x18) || c->x86_num_siblings <= 1) { - set_legacy_ssbd(c, enable); + BUG_ON(!set_legacy_ssbd(c, enable)); return; } + BUG_ON(c->phys_proc_id >= AMD_FAM17H_MAX_SOCKETS); + BUG_ON(c->cpu_core_id >= ssbd_max_cores); status = &ssbd_ls_cfg[c->phys_proc_id * ssbd_max_cores + c->cpu_core_id]; - /* - * Open code a very simple spinlock: this function is used with GIF==0 - * and different IF values, so would trigger the checklock detector. - * Instead of trying to workaround the detector, use a very simple lock - * implementation: it's better to reduce the amount of code executed - * with GIF==0. - */ - while (test_and_set_bool(status->locked)) - cpu_relax(); + spin_lock_irqsave(&status->lock, flags); status->count += enable ? 1 : -1; + ASSERT(status->count <= c->x86_num_siblings); if (enable ? status->count == 1 : !status->count) - set_legacy_ssbd(c, enable); - barrier(); - write_atomic(&status->locked, false); + BUG_ON(!set_legacy_ssbd(c, enable)); + spin_unlock_irqrestore(&status->lock, flags); +} + +void amd_set_ssbd(bool enable) +{ + if (opt_ssbd) + /* + * Ignore attempts to turn off SSBD, it's hardcoded on the + * command line. + */ + return; + + if (cpu_has_virt_ssbd) + wrmsr(MSR_VIRT_SPEC_CTRL, enable ? SPEC_CTRL_SSBD : 0, 0); + else if (amd_legacy_ssbd) + core_set_legacy_ssbd(enable); + else + ASSERT_UNREACHABLE(); } /* diff --git a/xen/arch/x86/hvm/svm/entry.S b/xen/arch/x86/hvm/svm/entry.S index a26589aa9a..981cd82e7c 100644 --- a/xen/arch/x86/hvm/svm/entry.S +++ b/xen/arch/x86/hvm/svm/entry.S @@ -59,9 +59,6 @@ __UNLIKELY_END(nsvm_hap) clgi - ALTERNATIVE "", STR(call vmentry_virt_spec_ctrl), \ - X86_FEATURE_VIRT_SC_MSR_HVM - /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */ /* SPEC_CTRL_EXIT_TO_SVM Req: b=curr %rsp=regs/cpuinfo, Clob: acd */ .macro svm_vmentry_spec_ctrl @@ -131,9 +128,6 @@ __UNLIKELY_END(nsvm_hap) ALTERNATIVE "", svm_vmexit_spec_ctrl, X86_FEATURE_SC_MSR_HVM /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */ - ALTERNATIVE "", STR(call vmexit_virt_spec_ctrl), \ - X86_FEATURE_VIRT_SC_MSR_HVM - /* * STGI is executed unconditionally, and is sufficiently serialising * to safely resolve any Spectre-v1 concerns in the above logic. diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 1aeaabcb13..8b101d4f27 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -973,6 +973,16 @@ static void cf_check svm_ctxt_switch_from(struct vcpu *v) /* Resume use of ISTs now that the host TR is reinstated. */ enable_each_ist(idt_tables[cpu]); + + /* + * Clear previous guest selection of SSBD if set. Note that SPEC_CTRL.SSBD + * is already cleared by svm_vmexit_spec_ctrl. + */ + if ( v->arch.msrs->virt_spec_ctrl.raw & SPEC_CTRL_SSBD ) + { + ASSERT(v->domain->arch.cpuid->extd.virt_ssbd); + amd_set_ssbd(false); + } } static void cf_check svm_ctxt_switch_to(struct vcpu *v) @@ -1000,6 +1010,13 @@ static void cf_check svm_ctxt_switch_to(struct vcpu *v) if ( cpu_has_msr_tsc_aux ) wrmsr_tsc_aux(v->arch.msrs->tsc_aux); + + /* Load SSBD if set by the guest. */ + if ( v->arch.msrs->virt_spec_ctrl.raw & SPEC_CTRL_SSBD ) + { + ASSERT(v->domain->arch.cpuid->extd.virt_ssbd); + amd_set_ssbd(true); + } } static void noreturn cf_check svm_do_resume(void) @@ -3116,34 +3133,6 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) vmcb_set_vintr(vmcb, intr); } -/* Called with GIF=0. */ -void vmexit_virt_spec_ctrl(void) -{ - unsigned int val = opt_ssbd ? SPEC_CTRL_SSBD : 0; - - if ( val == current->arch.msrs->virt_spec_ctrl.raw ) - return; - - if ( cpu_has_virt_ssbd ) - wrmsr(MSR_VIRT_SPEC_CTRL, val, 0); - else - amd_set_legacy_ssbd(val); -} - -/* Called with GIF=0. */ -void vmentry_virt_spec_ctrl(void) -{ - unsigned int val = current->arch.msrs->virt_spec_ctrl.raw; - - if ( val == (opt_ssbd ? SPEC_CTRL_SSBD : 0) ) - return; - - if ( cpu_has_virt_ssbd ) - wrmsr(MSR_VIRT_SPEC_CTRL, val, 0); - else - amd_set_legacy_ssbd(val); -} - /* * Local variables: * mode: C diff --git a/xen/arch/x86/include/asm/amd.h b/xen/arch/x86/include/asm/amd.h index 6a42f68542..81ed71710f 100644 --- a/xen/arch/x86/include/asm/amd.h +++ b/xen/arch/x86/include/asm/amd.h @@ -153,6 +153,6 @@ void amd_check_disable_c1e(unsigned int port, u8 value); extern bool amd_legacy_ssbd; bool amd_setup_legacy_ssbd(void); -void amd_set_legacy_ssbd(bool enable); +void amd_set_ssbd(bool enable); #endif /* __AMD_H__ */ diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c index 95416995a5..5609b71e99 100644 --- a/xen/arch/x86/msr.c +++ b/xen/arch/x86/msr.c @@ -24,6 +24,7 @@ #include <xen/nospec.h> #include <xen/sched.h> +#include <asm/amd.h> #include <asm/debugreg.h> #include <asm/hvm/nestedhvm.h> #include <asm/hvm/viridian.h> @@ -697,7 +698,15 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) msrs->spec_ctrl.raw &= ~SPEC_CTRL_SSBD; } else + { msrs->virt_spec_ctrl.raw = val & SPEC_CTRL_SSBD; + if ( v == curr ) + /* + * Propagate the value to hardware, as it won't be set on guest + * resume path. + */ + amd_set_ssbd(val & SPEC_CTRL_SSBD); + } break; case MSR_AMD64_DE_CFG: -- 2.37.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* RE: [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch 2022-11-03 17:02 ` [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch Roger Pau Monne @ 2022-11-03 17:06 ` Henry Wang 2022-11-04 8:10 ` Jan Beulich 2022-11-14 21:39 ` Andrew Cooper 2 siblings, 0 replies; 9+ messages in thread From: Henry Wang @ 2022-11-03 17:06 UTC (permalink / raw) To: Roger Pau Monne, xen-devel@lists.xenproject.org Cc: Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall, Stefano Stabellini, Wei Liu Hi Roger, > -----Original Message----- > From: Roger Pau Monne <roger.pau@citrix.com> > Subject: [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context > switch > > The current logic for AMD SSBD context switches it on every > vm{entry,exit} if the Xen and guest selections don't match. This is > expensive when not using SPEC_CTRL, and hence should be avoided as > much as possible. > > When SSBD is not being set from SPEC_CTRL on AMD don't context switch > at vm{entry,exit} and instead only context switch SSBD when switching > vCPUs. This has the side effect of running Xen code with the guest > selection of SSBD, the documentation is updated to note this behavior. > Also note that then when `ssbd` is selected on the command line guest > SSBD selection will not have an effect, and the hypervisor will run > with SSBD unconditionally enabled when not using SPEC_CTRL itself. > > This fixes an issue with running C code in a GIF=0 region, that's > problematic when using UBSAN or other instrumentation techniques. > > As a result of no longer running the code to set SSBD in a GIF=0 > region the locking of amd_set_legacy_ssbd() can be done using normal > spinlocks, and some more checks can be added to assure it works as > intended. > > Finally it's also worth noticing that since the guest SSBD selection > is no longer set on vmentry the VIRT_SPEC_MSR handling needs to > propagate the value to the hardware as part of handling the wrmsr. > > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Thanks for respinning the patch! Release-acked-by: Henry Wang <Henry.Wang@arm.com> Kind regards, Henry ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch 2022-11-03 17:02 ` [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch Roger Pau Monne 2022-11-03 17:06 ` Henry Wang @ 2022-11-04 8:10 ` Jan Beulich 2022-11-04 10:37 ` Roger Pau Monné 2022-11-09 11:00 ` Henry Wang 2022-11-14 21:39 ` Andrew Cooper 2 siblings, 2 replies; 9+ messages in thread From: Jan Beulich @ 2022-11-04 8:10 UTC (permalink / raw) To: Roger Pau Monne Cc: Henry.Wang, Andrew Cooper, George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu, xen-devel On 03.11.2022 18:02, Roger Pau Monne wrote: > The current logic for AMD SSBD context switches it on every > vm{entry,exit} if the Xen and guest selections don't match. This is > expensive when not using SPEC_CTRL, and hence should be avoided as > much as possible. > > When SSBD is not being set from SPEC_CTRL on AMD don't context switch > at vm{entry,exit} and instead only context switch SSBD when switching > vCPUs. This has the side effect of running Xen code with the guest > selection of SSBD, the documentation is updated to note this behavior. > Also note that then when `ssbd` is selected on the command line guest > SSBD selection will not have an effect, and the hypervisor will run > with SSBD unconditionally enabled when not using SPEC_CTRL itself. > > This fixes an issue with running C code in a GIF=0 region, that's > problematic when using UBSAN or other instrumentation techniques. > > As a result of no longer running the code to set SSBD in a GIF=0 > region the locking of amd_set_legacy_ssbd() can be done using normal > spinlocks, and some more checks can be added to assure it works as > intended. > > Finally it's also worth noticing that since the guest SSBD selection > is no longer set on vmentry the VIRT_SPEC_MSR handling needs to > propagate the value to the hardware as part of handling the wrmsr. > > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> with one further remark: > --- a/xen/arch/x86/hvm/svm/svm.c > +++ b/xen/arch/x86/hvm/svm/svm.c > @@ -973,6 +973,16 @@ static void cf_check svm_ctxt_switch_from(struct vcpu *v) > > /* Resume use of ISTs now that the host TR is reinstated. */ > enable_each_ist(idt_tables[cpu]); > + > + /* > + * Clear previous guest selection of SSBD if set. Note that SPEC_CTRL.SSBD > + * is already cleared by svm_vmexit_spec_ctrl. > + */ > + if ( v->arch.msrs->virt_spec_ctrl.raw & SPEC_CTRL_SSBD ) > + { > + ASSERT(v->domain->arch.cpuid->extd.virt_ssbd); > + amd_set_ssbd(false); > + } > } Is "cleared" in the comment correct when "spec-ctrl=ssbd"? I think "suitably set" or "cleared/set" or some such would be wanted. This could certainly be adjusted while committing (if you agree), but I will want to give Andrew some time anyway before putting it in, to avoid there again being objections after a change in this area has gone in. Jan ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch 2022-11-04 8:10 ` Jan Beulich @ 2022-11-04 10:37 ` Roger Pau Monné 2022-11-09 11:00 ` Henry Wang 1 sibling, 0 replies; 9+ messages in thread From: Roger Pau Monné @ 2022-11-04 10:37 UTC (permalink / raw) To: Jan Beulich Cc: Henry.Wang, Andrew Cooper, George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu, xen-devel On Fri, Nov 04, 2022 at 09:10:21AM +0100, Jan Beulich wrote: > On 03.11.2022 18:02, Roger Pau Monne wrote: > > The current logic for AMD SSBD context switches it on every > > vm{entry,exit} if the Xen and guest selections don't match. This is > > expensive when not using SPEC_CTRL, and hence should be avoided as > > much as possible. > > > > When SSBD is not being set from SPEC_CTRL on AMD don't context switch > > at vm{entry,exit} and instead only context switch SSBD when switching > > vCPUs. This has the side effect of running Xen code with the guest > > selection of SSBD, the documentation is updated to note this behavior. > > Also note that then when `ssbd` is selected on the command line guest > > SSBD selection will not have an effect, and the hypervisor will run > > with SSBD unconditionally enabled when not using SPEC_CTRL itself. > > > > This fixes an issue with running C code in a GIF=0 region, that's > > problematic when using UBSAN or other instrumentation techniques. > > > > As a result of no longer running the code to set SSBD in a GIF=0 > > region the locking of amd_set_legacy_ssbd() can be done using normal > > spinlocks, and some more checks can be added to assure it works as > > intended. > > > > Finally it's also worth noticing that since the guest SSBD selection > > is no longer set on vmentry the VIRT_SPEC_MSR handling needs to > > propagate the value to the hardware as part of handling the wrmsr. > > > > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> > > Reviewed-by: Jan Beulich <jbeulich@suse.com> > with one further remark: > > > --- a/xen/arch/x86/hvm/svm/svm.c > > +++ b/xen/arch/x86/hvm/svm/svm.c > > @@ -973,6 +973,16 @@ static void cf_check svm_ctxt_switch_from(struct vcpu *v) > > > > /* Resume use of ISTs now that the host TR is reinstated. */ > > enable_each_ist(idt_tables[cpu]); > > + > > + /* > > + * Clear previous guest selection of SSBD if set. Note that SPEC_CTRL.SSBD > > + * is already cleared by svm_vmexit_spec_ctrl. > > + */ > > + if ( v->arch.msrs->virt_spec_ctrl.raw & SPEC_CTRL_SSBD ) > > + { > > + ASSERT(v->domain->arch.cpuid->extd.virt_ssbd); > > + amd_set_ssbd(false); > > + } > > } > > Is "cleared" in the comment correct when "spec-ctrl=ssbd"? I think "suitably > set" or "cleared/set" or some such would be wanted. This could certainly be > adjusted while committing (if you agree), but I will want to give Andrew some > time anyway before putting it in, to avoid there again being objections after > a change in this area has gone in. Hm, indeed, maybe "already handled" to avoid getting into the set/clear nomenclature. Thanks, Roger. ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch 2022-11-04 8:10 ` Jan Beulich 2022-11-04 10:37 ` Roger Pau Monné @ 2022-11-09 11:00 ` Henry Wang 1 sibling, 0 replies; 9+ messages in thread From: Henry Wang @ 2022-11-09 11:00 UTC (permalink / raw) To: Jan Beulich, Roger Pau Monne, Andrew Cooper Cc: George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu, xen-devel@lists.xenproject.org Hi Andrew, > Subject: Re: [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context > switch > > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> > > Reviewed-by: Jan Beulich <jbeulich@suse.com> > with one further remark: > > Is "cleared" in the comment correct when "spec-ctrl=ssbd"? I think "suitably > set" or "cleared/set" or some such would be wanted. This could certainly be > adjusted while committing (if you agree), but I will want to give Andrew some > time anyway before putting it in, to avoid there again being objections after > a change in this area has gone in. Also this one please :) Any feedback would be appreciated. Kind regards, Henry > > Jan ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch 2022-11-03 17:02 ` [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch Roger Pau Monne 2022-11-03 17:06 ` Henry Wang 2022-11-04 8:10 ` Jan Beulich @ 2022-11-14 21:39 ` Andrew Cooper 2022-11-15 9:33 ` Roger Pau Monné 2 siblings, 1 reply; 9+ messages in thread From: Andrew Cooper @ 2022-11-14 21:39 UTC (permalink / raw) To: Roger Pau Monne, xen-devel@lists.xenproject.org Cc: Henry.Wang@arm.com, George Dunlap, Jan Beulich, Julien Grall, Stefano Stabellini, Wei Liu On 03/11/2022 17:02, Roger Pau Monne wrote: > The current logic for AMD SSBD context switches it on every > vm{entry,exit} if the Xen and guest selections don't match. This is > expensive when not using SPEC_CTRL, and hence should be avoided as > much as possible. > > When SSBD is not being set from SPEC_CTRL on AMD don't context switch > at vm{entry,exit} and instead only context switch SSBD when switching > vCPUs. This has the side effect of running Xen code with the guest > selection of SSBD, the documentation is updated to note this behavior. > Also note that then when `ssbd` is selected on the command line guest > SSBD selection will not have an effect, and the hypervisor will run > with SSBD unconditionally enabled when not using SPEC_CTRL itself. > > This fixes an issue with running C code in a GIF=0 region, that's > problematic when using UBSAN or other instrumentation techniques. This paragraph needs to be at the top, because it's the reason why this is a blocker bug for 4.17. Everything else is discussing why we take the approach we take. (and to be clear, it's slow even with MSR_SPEC_CTRL. It's just that its a whole lot less slow than with the LS_CFG MSR.) > > As a result of no longer running the code to set SSBD in a GIF=0 > region the locking of amd_set_legacy_ssbd() can be done using normal > spinlocks, and some more checks can be added to assure it works as > intended. > > Finally it's also worth noticing that since the guest SSBD selection > is no longer set on vmentry the VIRT_SPEC_MSR handling needs to > propagate the value to the hardware as part of handling the wrmsr. > > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> > --- > Changes since v2: > - Fix calling set_reg unconditionally. > - Fix comment. > - Call amd_set_ssbd() from guest_wrmsr(). > > Changes since v1: > - Just check virt_spec_ctrl value != 0 on context switch. > - Remove stray asm newline. > - Use val in svm_set_reg(). > - Fix style in amd.c. > - Do not clear ssbd > --- > docs/misc/xen-command-line.pandoc | 10 +++--- > xen/arch/x86/cpu/amd.c | 55 +++++++++++++++++-------------- > xen/arch/x86/hvm/svm/entry.S | 6 ---- > xen/arch/x86/hvm/svm/svm.c | 45 ++++++++++--------------- > xen/arch/x86/include/asm/amd.h | 2 +- > xen/arch/x86/msr.c | 9 +++++ Need to patch msr.h now that the semantics of virt_spec_ctrl have changed. > diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c > index 98c52d0686..05d72c6501 100644 > --- a/xen/arch/x86/cpu/amd.c > +++ b/xen/arch/x86/cpu/amd.c > <snip> > +void amd_set_ssbd(bool enable) > +{ > + if (opt_ssbd) > + /* > + * Ignore attempts to turn off SSBD, it's hardcoded on the > + * command line. > + */ > + return; > + > + if (cpu_has_virt_ssbd) > + wrmsr(MSR_VIRT_SPEC_CTRL, enable ? SPEC_CTRL_SSBD : 0, 0); > + else if (amd_legacy_ssbd) > + core_set_legacy_ssbd(enable); > + else > + ASSERT_UNREACHABLE(); This assert is reachable on Fam14 and older, I think. > diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c > index 1aeaabcb13..8b101d4f27 100644 > --- a/xen/arch/x86/hvm/svm/svm.c > +++ b/xen/arch/x86/hvm/svm/svm.c > @@ -973,6 +973,16 @@ static void cf_check svm_ctxt_switch_from(struct vcpu *v) > > /* Resume use of ISTs now that the host TR is reinstated. */ > enable_each_ist(idt_tables[cpu]); > + > + /* > + * Clear previous guest selection of SSBD if set. Note that SPEC_CTRL.SSBD > + * is already cleared by svm_vmexit_spec_ctrl. > + */ > + if ( v->arch.msrs->virt_spec_ctrl.raw & SPEC_CTRL_SSBD ) > + { > + ASSERT(v->domain->arch.cpuid->extd.virt_ssbd); > + amd_set_ssbd(false); > + } > } > > static void cf_check svm_ctxt_switch_to(struct vcpu *v) > @@ -1000,6 +1010,13 @@ static void cf_check svm_ctxt_switch_to(struct vcpu *v) > > if ( cpu_has_msr_tsc_aux ) > wrmsr_tsc_aux(v->arch.msrs->tsc_aux); > + > + /* Load SSBD if set by the guest. */ > + if ( v->arch.msrs->virt_spec_ctrl.raw & SPEC_CTRL_SSBD ) > + { > + ASSERT(v->domain->arch.cpuid->extd.virt_ssbd); > + amd_set_ssbd(true); > + } While this functions, it's still a perf problem. You now flip the bit twice when switching between vcpus with legacy SSBD. This wouldn't be so bad if you'd also fixed the inner function to not do a read/modify/write on the very slow MSR, because then we'd only be touching it twice, not 4 times. This isn't critical to fix for 4.17, but will need addressing in due course. However, as the patch does need a respin, amd_set_ssbd() is too generic. It's previous name, amd_set_legacy_ssbd(), was more appropriate, as it clearly highlights the fact that it's the non-MSR_SPEC_CTRL path. ~Andrew ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch 2022-11-14 21:39 ` Andrew Cooper @ 2022-11-15 9:33 ` Roger Pau Monné 0 siblings, 0 replies; 9+ messages in thread From: Roger Pau Monné @ 2022-11-15 9:33 UTC (permalink / raw) To: Andrew Cooper Cc: xen-devel@lists.xenproject.org, Henry.Wang@arm.com, George Dunlap, Jan Beulich, Julien Grall, Stefano Stabellini, Wei Liu On Mon, Nov 14, 2022 at 09:39:50PM +0000, Andrew Cooper wrote: > On 03/11/2022 17:02, Roger Pau Monne wrote: > > The current logic for AMD SSBD context switches it on every > > vm{entry,exit} if the Xen and guest selections don't match. This is > > expensive when not using SPEC_CTRL, and hence should be avoided as > > much as possible. > > > > When SSBD is not being set from SPEC_CTRL on AMD don't context switch > > at vm{entry,exit} and instead only context switch SSBD when switching > > vCPUs. This has the side effect of running Xen code with the guest > > selection of SSBD, the documentation is updated to note this behavior. > > Also note that then when `ssbd` is selected on the command line guest > > SSBD selection will not have an effect, and the hypervisor will run > > with SSBD unconditionally enabled when not using SPEC_CTRL itself. > > > > This fixes an issue with running C code in a GIF=0 region, that's > > problematic when using UBSAN or other instrumentation techniques. > > This paragraph needs to be at the top, because it's the reason why this > is a blocker bug for 4.17. Everything else is discussing why we take > the approach we take. Done. > (and to be clear, it's slow even with MSR_SPEC_CTRL. It's just that its > a whole lot less slow than with the LS_CFG MSR.) > > > > > As a result of no longer running the code to set SSBD in a GIF=0 > > region the locking of amd_set_legacy_ssbd() can be done using normal > > spinlocks, and some more checks can be added to assure it works as > > intended. > > > > Finally it's also worth noticing that since the guest SSBD selection > > is no longer set on vmentry the VIRT_SPEC_MSR handling needs to > > propagate the value to the hardware as part of handling the wrmsr. > > > > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> > > --- > > Changes since v2: > > - Fix calling set_reg unconditionally. > > - Fix comment. > > - Call amd_set_ssbd() from guest_wrmsr(). > > > > Changes since v1: > > - Just check virt_spec_ctrl value != 0 on context switch. > > - Remove stray asm newline. > > - Use val in svm_set_reg(). > > - Fix style in amd.c. > > - Do not clear ssbd > > --- > > docs/misc/xen-command-line.pandoc | 10 +++--- > > xen/arch/x86/cpu/amd.c | 55 +++++++++++++++++-------------- > > xen/arch/x86/hvm/svm/entry.S | 6 ---- > > xen/arch/x86/hvm/svm/svm.c | 45 ++++++++++--------------- > > xen/arch/x86/include/asm/amd.h | 2 +- > > xen/arch/x86/msr.c | 9 +++++ > > Need to patch msr.h now that the semantics of virt_spec_ctrl have changed. Sure, will adjust the comment there. > > > diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c > > index 98c52d0686..05d72c6501 100644 > > --- a/xen/arch/x86/cpu/amd.c > > +++ b/xen/arch/x86/cpu/amd.c > > <snip> > > +void amd_set_ssbd(bool enable) > > +{ > > + if (opt_ssbd) > > + /* > > + * Ignore attempts to turn off SSBD, it's hardcoded on the > > + * command line. > > + */ > > + return; > > + > > + if (cpu_has_virt_ssbd) > > + wrmsr(MSR_VIRT_SPEC_CTRL, enable ? SPEC_CTRL_SSBD : 0, 0); > > + else if (amd_legacy_ssbd) > > + core_set_legacy_ssbd(enable); > > + else > > + ASSERT_UNREACHABLE(); > > This assert is reachable on Fam14 and older, I think. Hm, I'm unsure how. Calls to this function are gated on the vCPU having virt_ssbd set in the CPUID policy, and that can only happen if there's a way to set SSBD. Can you elaborate on the path that you think can trigger this? As I would think that's the path that needs fixing, rather than removing the assert here. > > diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c > > index 1aeaabcb13..8b101d4f27 100644 > > --- a/xen/arch/x86/hvm/svm/svm.c > > +++ b/xen/arch/x86/hvm/svm/svm.c > > @@ -973,6 +973,16 @@ static void cf_check svm_ctxt_switch_from(struct vcpu *v) > > > > /* Resume use of ISTs now that the host TR is reinstated. */ > > enable_each_ist(idt_tables[cpu]); > > + > > + /* > > + * Clear previous guest selection of SSBD if set. Note that SPEC_CTRL.SSBD > > + * is already cleared by svm_vmexit_spec_ctrl. > > + */ > > + if ( v->arch.msrs->virt_spec_ctrl.raw & SPEC_CTRL_SSBD ) > > + { > > + ASSERT(v->domain->arch.cpuid->extd.virt_ssbd); > > + amd_set_ssbd(false); > > + } > > } > > > > static void cf_check svm_ctxt_switch_to(struct vcpu *v) > > @@ -1000,6 +1010,13 @@ static void cf_check svm_ctxt_switch_to(struct vcpu *v) > > > > if ( cpu_has_msr_tsc_aux ) > > wrmsr_tsc_aux(v->arch.msrs->tsc_aux); > > + > > + /* Load SSBD if set by the guest. */ > > + if ( v->arch.msrs->virt_spec_ctrl.raw & SPEC_CTRL_SSBD ) > > + { > > + ASSERT(v->domain->arch.cpuid->extd.virt_ssbd); > > + amd_set_ssbd(true); > > + } > > While this functions, it's still a perf problem. You now flip the bit > twice when switching between vcpus with legacy SSBD. > > This wouldn't be so bad if you'd also fixed the inner function to not do > a read/modify/write on the very slow MSR, because then we'd only be > touching it twice, not 4 times. > > This isn't critical to fix for 4.17, but will need addressing in due course. Indeed. I know about this, but didn't consider it critical enough to fix in the current release status. > However, as the patch does need a respin, amd_set_ssbd() is too > generic. It's previous name, amd_set_legacy_ssbd(), was more > appropriate, as it clearly highlights the fact that it's the > non-MSR_SPEC_CTRL path. Can adjust the function name, not a problem. Thanks, Roger. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH for-4.17 v3 2/2] amd: remove VIRT_SC_MSR_HVM synthetic feature 2022-11-03 17:02 [PATCH for-4.17 v3 0/2] amd/virt_ssbd: refactoring and fixes Roger Pau Monne 2022-11-03 17:02 ` [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch Roger Pau Monne @ 2022-11-03 17:02 ` Roger Pau Monne 1 sibling, 0 replies; 9+ messages in thread From: Roger Pau Monne @ 2022-11-03 17:02 UTC (permalink / raw) To: xen-devel Cc: Henry.Wang, Roger Pau Monne, Jan Beulich, Andrew Cooper, Wei Liu Since the VIRT_SPEC_CTRL.SSBD selection is no longer context switched on vm{entry,exit} there's no need to use a synthetic feature bit for it anymore. Remove the bit and instead use a global variable. No functional change intended. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Release-acked-by: Henry Wang <Henry.Wang@arm.com> --- xen/arch/x86/cpu/amd.c | 1 + xen/arch/x86/cpuid.c | 9 +++++---- xen/arch/x86/include/asm/amd.h | 1 + xen/arch/x86/include/asm/cpufeatures.h | 2 +- xen/arch/x86/spec_ctrl.c | 8 ++++---- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c index 05d72c6501..11f8e1d359 100644 --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -49,6 +49,7 @@ boolean_param("allow_unsafe", opt_allow_unsafe); /* Signal whether the ACPI C1E quirk is required. */ bool __read_mostly amd_acpi_c1e_quirk; bool __ro_after_init amd_legacy_ssbd; +bool __ro_after_init amd_virt_spec_ctrl; static inline int rdmsr_amd_safe(unsigned int msr, unsigned int *lo, unsigned int *hi) diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c index 822f9ace10..acc2f606ce 100644 --- a/xen/arch/x86/cpuid.c +++ b/xen/arch/x86/cpuid.c @@ -3,6 +3,7 @@ #include <xen/param.h> #include <xen/sched.h> #include <xen/nospec.h> +#include <asm/amd.h> #include <asm/cpuid.h> #include <asm/hvm/hvm.h> #include <asm/hvm/nestedhvm.h> @@ -543,9 +544,9 @@ static void __init calculate_hvm_max_policy(void) /* * VIRT_SSBD is exposed in the default policy as a result of - * VIRT_SC_MSR_HVM being set, it also needs exposing in the max policy. + * amd_virt_spec_ctrl being set, it also needs exposing in the max policy. */ - if ( boot_cpu_has(X86_FEATURE_VIRT_SC_MSR_HVM) ) + if ( amd_virt_spec_ctrl ) __set_bit(X86_FEATURE_VIRT_SSBD, hvm_featureset); /* @@ -606,9 +607,9 @@ static void __init calculate_hvm_def_policy(void) /* * Only expose VIRT_SSBD if AMD_SSBD is not available, and thus - * VIRT_SC_MSR_HVM is set. + * amd_virt_spec_ctrl is set. */ - if ( boot_cpu_has(X86_FEATURE_VIRT_SC_MSR_HVM) ) + if ( amd_virt_spec_ctrl ) __set_bit(X86_FEATURE_VIRT_SSBD, hvm_featureset); sanitise_featureset(hvm_featureset); diff --git a/xen/arch/x86/include/asm/amd.h b/xen/arch/x86/include/asm/amd.h index 81ed71710f..5c100784dd 100644 --- a/xen/arch/x86/include/asm/amd.h +++ b/xen/arch/x86/include/asm/amd.h @@ -152,6 +152,7 @@ extern bool amd_acpi_c1e_quirk; void amd_check_disable_c1e(unsigned int port, u8 value); extern bool amd_legacy_ssbd; +extern bool amd_virt_spec_ctrl; bool amd_setup_legacy_ssbd(void); void amd_set_ssbd(bool enable); diff --git a/xen/arch/x86/include/asm/cpufeatures.h b/xen/arch/x86/include/asm/cpufeatures.h index 3895de4faf..efd3a667ef 100644 --- a/xen/arch/x86/include/asm/cpufeatures.h +++ b/xen/arch/x86/include/asm/cpufeatures.h @@ -24,7 +24,7 @@ XEN_CPUFEATURE(APERFMPERF, X86_SYNTH( 8)) /* APERFMPERF */ XEN_CPUFEATURE(MFENCE_RDTSC, X86_SYNTH( 9)) /* MFENCE synchronizes RDTSC */ XEN_CPUFEATURE(XEN_SMEP, X86_SYNTH(10)) /* SMEP gets used by Xen itself */ XEN_CPUFEATURE(XEN_SMAP, X86_SYNTH(11)) /* SMAP gets used by Xen itself */ -XEN_CPUFEATURE(VIRT_SC_MSR_HVM, X86_SYNTH(12)) /* MSR_VIRT_SPEC_CTRL exposed to HVM */ +/* Bit 12 unused. */ XEN_CPUFEATURE(IND_THUNK_LFENCE, X86_SYNTH(13)) /* Use IND_THUNK_LFENCE */ XEN_CPUFEATURE(IND_THUNK_JMP, X86_SYNTH(14)) /* Use IND_THUNK_JMP */ XEN_CPUFEATURE(SC_NO_BRANCH_HARDEN, X86_SYNTH(15)) /* (Disable) Conditional branch hardening */ diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c index 4e53056624..0b94af6b86 100644 --- a/xen/arch/x86/spec_ctrl.c +++ b/xen/arch/x86/spec_ctrl.c @@ -514,12 +514,12 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps) (boot_cpu_has(X86_FEATURE_SC_MSR_HVM) || boot_cpu_has(X86_FEATURE_SC_RSB_HVM) || boot_cpu_has(X86_FEATURE_IBPB_ENTRY_HVM) || - boot_cpu_has(X86_FEATURE_VIRT_SC_MSR_HVM) || + amd_virt_spec_ctrl || opt_eager_fpu || opt_md_clear_hvm) ? "" : " None", boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ? " MSR_SPEC_CTRL" : "", (boot_cpu_has(X86_FEATURE_SC_MSR_HVM) || - boot_cpu_has(X86_FEATURE_VIRT_SC_MSR_HVM)) ? " MSR_VIRT_SPEC_CTRL" - : "", + amd_virt_spec_ctrl) ? " MSR_VIRT_SPEC_CTRL" + : "", boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : "", opt_eager_fpu ? " EAGER_FPU" : "", opt_md_clear_hvm ? " MD_CLEAR" : "", @@ -1247,7 +1247,7 @@ void __init init_speculation_mitigations(void) /* Support VIRT_SPEC_CTRL.SSBD if AMD_SSBD is not available. */ if ( opt_msr_sc_hvm && !cpu_has_amd_ssbd && (cpu_has_virt_ssbd || (amd_legacy_ssbd && amd_setup_legacy_ssbd())) ) - setup_force_cpu_cap(X86_FEATURE_VIRT_SC_MSR_HVM); + amd_virt_spec_ctrl = true; /* Figure out default_xen_spec_ctrl. */ if ( has_spec_ctrl && ibrs ) -- 2.37.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-11-15 9:34 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-11-03 17:02 [PATCH for-4.17 v3 0/2] amd/virt_ssbd: refactoring and fixes Roger Pau Monne 2022-11-03 17:02 ` [PATCH for-4.17 v3 1/2] amd/virt_ssbd: set SSBD at vCPU context switch Roger Pau Monne 2022-11-03 17:06 ` Henry Wang 2022-11-04 8:10 ` Jan Beulich 2022-11-04 10:37 ` Roger Pau Monné 2022-11-09 11:00 ` Henry Wang 2022-11-14 21:39 ` Andrew Cooper 2022-11-15 9:33 ` Roger Pau Monné 2022-11-03 17:02 ` [PATCH for-4.17 v3 2/2] amd: remove VIRT_SC_MSR_HVM synthetic feature Roger Pau Monne
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.