Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <seanjc@google.com>

+7 -3
+7 -3
arch/x86/kvm/svm/svm.c
··· 77 77 * are published and we know what the new status bits are 78 78 */ 79 79 static uint64_t osvw_len = 4, osvw_status; 80 + static DEFINE_SPINLOCK(osvw_lock); 80 81 81 82 static DEFINE_PER_CPU(u64, current_tsc_ratio); 82 83 ··· 559 558 if (!err) 560 559 err = native_read_msr_safe(MSR_AMD64_OSVW_STATUS, &status); 561 560 562 - if (err) 561 + guard(spinlock)(&osvw_lock); 562 + 563 + if (err) { 563 564 osvw_status = osvw_len = 0; 564 - else { 565 + } else { 565 566 if (len < osvw_len) 566 567 osvw_len = len; 567 568 osvw_status |= status; 568 569 osvw_status &= (1ULL << osvw_len) - 1; 569 570 } 570 - } else 571 + } else { 571 572 osvw_status = osvw_len = 0; 573 + } 572 574 573 575 svm_init_erratum_383(); 574 576