]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: SVM: work around errata 1218
authorPaolo Bonzini <pbonzini@redhat.com>
Wed, 8 Apr 2026 15:42:16 +0000 (11:42 -0400)
committerPaolo Bonzini <pbonzini@redhat.com>
Sun, 10 May 2026 12:55:08 +0000 (14:55 +0200)
According to AMD, the hypervisor may not be able to determine whether a
fault was a GMET fault or an NX fault based on EXITINFO1, and software
"must read the relevant VMCB to determine whether a fault was a GMET
fault or an NX fault".  The APM further details that they meant the
CPL field.

KVM uses the page fault error code to distinguish the causes of a
nested page fault, so recalculate the PFERR_USER_MASK bit of the
vmexit information.  Only do it for fetches and only if GMET is in
use, because KVM does not differentiate based on PFERR_USER_MASK
for other nested NPT page faults.

Tested-by: David Riley <d.riley@proxmox.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm/svm.c

index 3895d87943665f3b9315e296f1908481287cac96..fd79874c5f4bca165122a8cab2f297fea685f20d 100644 (file)
@@ -1993,6 +1993,18 @@ static int npf_interception(struct kvm_vcpu *vcpu)
                }
        }
 
+       if (!is_sev_es_guest(vcpu) &&
+           (svm->vmcb->control.misc_ctl & SVM_MISC_ENABLE_GMET) &&
+           (error_code & PFERR_FETCH_MASK)) {
+               /*
+                * Work around errata 1218: EXITINFO1[2] May Be Incorrectly Set
+                * When GMET (Guest Mode Execute Trap extension) is Enabled
+                */
+               error_code |= PFERR_USER_MASK;
+               if (svm_get_cpl(vcpu) != 3)
+                       error_code &= ~PFERR_USER_MASK;
+       }
+
        if (is_sev_snp_guest(vcpu) && (error_code & PFERR_GUEST_ENC_MASK))
                error_code |= PFERR_PRIVATE_ACCESS;