Commit c8cc238093ca for kernel

commit c8cc238093ca6c99267032f6cfe78f59389f3157
Author: Sean Christopherson <seanjc@google.com>
Date:   Fri May 1 13:22:35 2026 -0700

    KVM: SEV: Use READ_ONCE() when reading entries/indices from PSC buffer

    Use READ_ONCE() when reading entries/indices from the guest-accessible
    Page State Change buffer to defend against TOCTOU bugs.

    Don't bother with READ_ONCE()/WRITE_ONCE() for cases where KVM is writing
    (and not consuming the result!), as the guest isn't supposed to touch the
    buffer while it's being processed.  I.e. using READ_ONCE() is all about
    protecting against misbehaving guests.

    Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT")
    Cc: stable@vger.kernel.org
    Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
    Signed-off-by: Sean Christopherson <seanjc@google.com>
    Message-ID: <20260501202250.2115252-11-seanjc@google.com>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 6e8cbae2135a..62b5befe0eed 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3872,9 +3872,9 @@ static void __snp_complete_one_psc(struct vcpu_svm *svm)
 	 */
 	for (idx = svm->sev_es.psc_idx; svm->sev_es.psc_inflight;
 	     svm->sev_es.psc_inflight--, idx++) {
-		struct psc_entry *entry = &entries[idx];
+		struct psc_entry entry = READ_ONCE(entries[idx]);

-		entry->cur_page = entry->pagesize ? 512 : 1;
+		entries[idx].cur_page = entry.pagesize ? 512 : 1;
 	}

 	hdr->cur_entry = idx;
@@ -3938,8 +3938,8 @@ static int snp_begin_psc(struct vcpu_svm *svm)
 	 * validation, so take care to only use validated copies of values used
 	 * for things like array indexing.
 	 */
-	idx_start = hdr->cur_entry;
-	idx_end = hdr->end_entry;
+	idx_start = READ_ONCE(hdr->cur_entry);
+	idx_end = READ_ONCE(hdr->end_entry);

 	if (idx_end >= max_nr_entries) {
 		snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR);
@@ -3948,7 +3948,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)

 	/* Find the start of the next range which needs processing. */
 	for (idx = idx_start; idx <= idx_end; idx++, hdr->cur_entry++) {
-		entry_start = entries[idx];
+		entry_start = READ_ONCE(entries[idx]);

 		gfn = entry_start.gfn;
 		huge = entry_start.pagesize;
@@ -3992,7 +3992,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
 	 * KVM_HC_MAP_GPA_RANGE exit.
 	 */
 	while (++idx <= idx_end) {
-		struct psc_entry entry = entries[idx];
+		struct psc_entry entry = READ_ONCE(entries[idx]);

 		if (entry.operation != entry_start.operation ||
 		    entry.gfn != entry_start.gfn + npages ||