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: Skip OSVW variable updates if current CPU's errata are a subset

Elide the OSVW variable updates if the current CPU's set of errata are a
subset of the errata tracked in the global values, i.e. if no update is
needed. There's no danger of under-reporting errata due to bailing early
as KVM is purely reducing the set of "known fixed" errata. I.e. a racing
update on a different CPU with _more_ errata doesn't change anything if
the current CPU has the same or fewer errata relative to the status quo.

If another CPU is writing osvw_len, then "len" is guaranteed to be larger
than the new osvw_len and so the osvw_len update would be skipped anyways.

If another CPU is setting new bits in osvw_status, then "status" is
guaranteed to be a subset of the new osvw_status and the bitwise-OR would
be an effective nop anyways.

Link: https://patch.msgid.link/20251113231420.1695919-5-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>

+10 -12
+10 -12
arch/x86/kvm/svm/svm.c
··· 424 424 static void svm_init_os_visible_workarounds(void) 425 425 { 426 426 u64 len, status; 427 - int err; 428 427 429 428 /* 430 429 * Get OS-Visible Workarounds (OSVW) bits. ··· 452 453 return; 453 454 } 454 455 455 - err = native_read_msr_safe(MSR_AMD64_OSVW_ID_LENGTH, &len); 456 - if (!err) 457 - err = native_read_msr_safe(MSR_AMD64_OSVW_STATUS, &status); 456 + if (native_read_msr_safe(MSR_AMD64_OSVW_ID_LENGTH, &len) || 457 + native_read_msr_safe(MSR_AMD64_OSVW_STATUS, &status)) 458 + len = status = 0; 459 + 460 + if (status == READ_ONCE(osvw_status) && len >= READ_ONCE(osvw_len)) 461 + return; 458 462 459 463 guard(spinlock)(&osvw_lock); 460 464 461 - if (err) { 462 - osvw_status = osvw_len = 0; 463 - } else { 464 - if (len < osvw_len) 465 - osvw_len = len; 466 - osvw_status |= status; 467 - osvw_status &= (1ULL << osvw_len) - 1; 468 - } 465 + if (len < osvw_len) 466 + osvw_len = len; 467 + osvw_status |= status; 468 + osvw_status &= (1ULL << osvw_len) - 1; 469 469 } 470 470 471 471 static bool __kvm_is_svm_supported(void)