diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2026-04-08 11:42:16 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2026-05-10 14:55:08 +0200 |
| commit | 878fffd76c22b8afb53e4b9409f355a99b9f3ee1 (patch) | |
| tree | 1196f9c1606c54ad6ca0f102ae9aaf70e17b021f /arch | |
| parent | fe080f58dec24049b4e5ecfaab28ba0881c67abe (diff) | |
| download | linux-next-878fffd76c22b8afb53e4b9409f355a99b9f3ee1.tar.gz linux-next-878fffd76c22b8afb53e4b9409f355a99b9f3ee1.zip | |
KVM: SVM: work around errata 1218
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>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86/kvm/svm/svm.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 3895d8794366..fd79874c5f4b 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -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; |
