[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2] x86/SVM: restrict hardware SSBD update upon guest VIRT_SPEC_CTRL write
core_set_legacy_ssbd() counts the number of times SSBD is being enabled via LS_CFG on a core. This assumes that calls there only occur if the state actually changes. While svm_ctxt_switch_{to,from}() conform to this, guest_wrmsr() doesn't: It also calls the function when the bit doesn't actually change. Make core_set_legacy_ssbd() track per-thread enabled state by converting the "count" field to a bitmap, thus allowing to skip redundant enable/disable requests, constraining amd_setup_legacy_ssbd() accordingly. Fixes: b2030e6730a2 ("amd/virt_ssbd: set SSBD at vCPU context switch") Reported-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- This wants properly testing on affected hardware. From Andrew's description it's also not clear whether this really is addressing that problem, or yet another one in this same area. --- v2: Change core_set_legacy_ssbd() itself rather than the problematic caller. --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -744,7 +744,7 @@ void amd_init_ssbd(const struct cpuinfo_ static struct ssbd_ls_cfg { spinlock_t lock; - unsigned int count; + unsigned long enabled; } __cacheline_aligned *ssbd_ls_cfg; static unsigned int __ro_after_init ssbd_max_cores; #define AMD_FAM17H_MAX_SOCKETS 2 @@ -757,6 +757,11 @@ bool __init amd_setup_legacy_ssbd(void) boot_cpu_data.x86_num_siblings <= 1 || opt_ssbd) return true; + if (boot_cpu_data.x86_num_siblings > BITS_PER_LONG || + (boot_cpu_data.x86_num_siblings & + (boot_cpu_data.x86_num_siblings - 1))) + return false; + /* * One could be forgiven for thinking that c->x86_max_cores is the * correct value to use here. @@ -800,10 +805,12 @@ static void core_set_legacy_ssbd(bool en c->cpu_core_id]; 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) + if (!enable) + __clear_bit(c->apicid & (c->x86_num_siblings - 1), &status->enabled); + if (!status->enabled) BUG_ON(!set_legacy_ssbd(c, enable)); + if (enable) + __set_bit(c->apicid & (c->x86_num_siblings - 1), &status->enabled); spin_unlock_irqrestore(&status->lock, flags); }
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |