From f35043d0f973504e5f199be6287159dc5b373deb Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Thu, 13 Nov 2025 15:14:16 -0800 Subject: [PATCH] KVM: SVM: Serialize updates to global OS-Visible Workarounds variables Guard writes to the global osvw_status and osvw_len variables with a spinlock to ensure enabling virtualization on multiple CPUs in parallel doesn't effectively drop any writes due to writing back stale data. Don't bother taking the lock when the boot CPU doesn't support the feature, as that check is constant for all CPUs, i.e. racing writes will always write the same value (zero). Note, the bug was inadvertently "fixed" by commit 9a798b1337af ("KVM: Register cpuhp and syscore callbacks when enabling hardware"), which effectively serialized calls to enable virtualization due to how the cpuhp framework "brings up" CPU. But KVM shouldn't rely on the mechanics of cphup to provide serialization. Link: https://patch.msgid.link/20251113231420.1695919-2-seanjc@google.com Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/svm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index e0da247ee594..9d611bfbcc8c 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -77,6 +77,7 @@ static bool erratum_383_found __read_mostly; * are published and we know what the new status bits are */ static uint64_t osvw_len = 4, osvw_status; +static DEFINE_SPINLOCK(osvw_lock); static DEFINE_PER_CPU(u64, current_tsc_ratio); @@ -558,16 +559,19 @@ static int svm_enable_virtualization_cpu(void) if (!err) err = native_read_msr_safe(MSR_AMD64_OSVW_STATUS, &status); - if (err) + guard(spinlock)(&osvw_lock); + + if (err) { osvw_status = osvw_len = 0; - else { + } else { if (len < osvw_len) osvw_len = len; osvw_status |= status; osvw_status &= (1ULL << osvw_len) - 1; } - } else + } else { osvw_status = osvw_len = 0; + } svm_init_erratum_383();