]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: SEV: Return INVALID_EVENT for SNP-only #VMGEXIT from non-SNP guest
authorSean Christopherson <seanjc@google.com>
Fri, 29 May 2026 18:35:45 +0000 (20:35 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 3 Jun 2026 14:59:19 +0000 (16:59 +0200)
Signal INVALID_EVENT, not MISSING_INPUT, if a non-SNP guest attempts to
invoke an SNP-only #VMGEXIT.  Opportunistically move the checks out of
sev_es_validate_vmgexit() to continue the march towards making said helper
a predicate whose sole purpose is to verify the guest has marked required
GHCB fields as valid.

Fixes: e366f92ea99e ("KVM: SEV: Support SEV-SNP AP Creation NAE event")
Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT")
Fixes: 88caf544c930 ("KVM: SEV: Provide support for SNP_GUEST_REQUEST NAE event")
Fixes: 74458e4859d8 ("KVM: SEV: Provide support for SNP_EXTENDED_GUEST_REQUEST NAE event")
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20260501202250.2115252-21-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20260529183549.1104619-21-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm/sev.c

index 880a2acd77bffead19d16c7d07bcdd71636ab94b..b59adddfdbccb06cd5d6142c2629f190b9c9c2fb 100644 (file)
@@ -3491,8 +3491,6 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
                        goto vmgexit_err;
                break;
        case SVM_VMGEXIT_AP_CREATION:
-               if (!is_sev_snp_guest(vcpu))
-                       goto vmgexit_err;
                if (lower_32_bits(control->exit_info_1) != SVM_VMGEXIT_AP_DESTROY)
                        if (!kvm_ghcb_rax_is_valid(svm))
                                goto vmgexit_err;
@@ -3505,13 +3503,12 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
        case SVM_VMGEXIT_TERM_REQUEST:
                break;
        case SVM_VMGEXIT_PSC:
-               if (!is_sev_snp_guest(vcpu) || !kvm_ghcb_sw_scratch_is_valid(svm))
+               if (!kvm_ghcb_sw_scratch_is_valid(svm))
                        goto vmgexit_err;
                break;
        case SVM_VMGEXIT_GUEST_REQUEST:
        case SVM_VMGEXIT_EXT_GUEST_REQUEST:
-               if (!is_sev_snp_guest(vcpu) ||
-                   !PAGE_ALIGNED(control->exit_info_1) ||
+               if (!PAGE_ALIGNED(control->exit_info_1) ||
                    !PAGE_ALIGNED(control->exit_info_2) ||
                    control->exit_info_1 == control->exit_info_2)
                        goto vmgexit_err;
@@ -4476,6 +4473,19 @@ out_terminate:
        return 0;
 }
 
+static bool is_snp_only_vmgexit(u64 exit_code)
+{
+       switch (exit_code) {
+       case SVM_VMGEXIT_AP_CREATION:
+       case SVM_VMGEXIT_GUEST_REQUEST:
+       case SVM_VMGEXIT_EXT_GUEST_REQUEST:
+       case SVM_VMGEXIT_PSC:
+               return true;
+       default:
+               return false;
+       }
+}
+
 int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
@@ -4527,6 +4537,13 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
                return 1;
        }
 
+       if (is_snp_only_vmgexit(control->exit_code) && !is_sev_snp_guest(vcpu)) {
+               vcpu_unimpl(vcpu, "vmgexit: exit code %#llx is SNP-only\n",
+                           control->exit_code);
+               svm_vmgexit_bad_input(svm, GHCB_ERR_INVALID_EVENT);
+               return 1;
+       }
+
        ret = sev_es_validate_vmgexit(svm);
        if (ret)
                return ret;