lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251113231420.1695919-5-seanjc@google.com>
Date: Thu, 13 Nov 2025 15:14:19 -0800
From: Sean Christopherson <seanjc@...gle.com>
To: Sean Christopherson <seanjc@...gle.com>, Paolo Bonzini <pbonzini@...hat.com>
Cc: kvm@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH 4/5] 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.

Signed-off-by: Sean Christopherson <seanjc@...gle.com>
---
 arch/x86/kvm/svm/svm.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index d3f0cc5632d1..152c56762b26 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -420,7 +420,6 @@ static void svm_init_osvw(struct kvm_vcpu *vcpu)
 static void svm_init_os_visible_workarounds(void)
 {
 	u64 len, status;
-	int err;
 
 	/*
 	 * Get OS-Visible Workarounds (OSVW) bits.
@@ -449,20 +448,19 @@ static void svm_init_os_visible_workarounds(void)
 		return;
 	}
 
-	err = native_read_msr_safe(MSR_AMD64_OSVW_ID_LENGTH, &len);
-	if (!err)
-		err = native_read_msr_safe(MSR_AMD64_OSVW_STATUS, &status);
+	if (native_read_msr_safe(MSR_AMD64_OSVW_ID_LENGTH, &len) ||
+	    native_read_msr_safe(MSR_AMD64_OSVW_STATUS, &status))
+		len = status = 0;
+
+	if (status == READ_ONCE(osvw_status) && len >= READ_ONCE(osvw_len))
+		return;
 
 	guard(spinlock)(&osvw_lock);
 
-	if (err) {
-		osvw_status = osvw_len = 0;
-	} else {
-		if (len < osvw_len)
-			osvw_len = len;
-		osvw_status |= status;
-		osvw_status &= (1ULL << osvw_len) - 1;
-	}
+	if (len < osvw_len)
+		osvw_len = len;
+	osvw_status |= status;
+	osvw_status &= (1ULL << osvw_len) - 1;
 }
 
 static bool __kvm_is_svm_supported(void)
-- 
2.52.0.rc1.455.g30608eb744-goog


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ