]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: SEV: Turn sev_es_validate_vmgexit() into a dedicated predicate
authorSean Christopherson <seanjc@google.com>
Fri, 29 May 2026 18:35:48 +0000 (20:35 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 3 Jun 2026 14:59:19 +0000 (16:59 +0200)
Now that sev_es_validate_vmgexit() is only responsible for checking that
all required GHCB fields are marked valid, turn it into a predicate whose
name reflects exactly that.

No functional change intended.

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-24-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20260529183549.1104619-24-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm/sev.c

index 864d6aea544bbefab0014ad3606f0b252e358735..bb70df2bf1a4845bcec06f03ba3803a04b5fa336 100644 (file)
@@ -3410,7 +3410,7 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
        memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
 }
 
-static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
+static bool sev_es_are_required_ghcb_fields_valid(struct vcpu_svm *svm)
 {
        struct vmcb_control_area *control = &svm->vmcb->control;
        struct kvm_vcpu *vcpu = &svm->vcpu;
@@ -3418,92 +3418,53 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
        if (!kvm_ghcb_sw_exit_code_is_valid(svm) ||
            !kvm_ghcb_sw_exit_info_1_is_valid(svm) ||
            !kvm_ghcb_sw_exit_info_2_is_valid(svm))
-               goto vmgexit_err;
+               return false;
 
        switch (control->exit_code) {
        case SVM_EXIT_WRITE_DR7:
-               if (!kvm_ghcb_rax_is_valid(svm))
-                       goto vmgexit_err;
-               break;
+               return kvm_ghcb_rax_is_valid(svm);
        case SVM_EXIT_RDPMC:
-               if (!kvm_ghcb_rcx_is_valid(svm))
-                       goto vmgexit_err;
-               break;
+               return kvm_ghcb_rcx_is_valid(svm);
        case SVM_EXIT_CPUID:
                if (!kvm_ghcb_rax_is_valid(svm) ||
                    !kvm_ghcb_rcx_is_valid(svm))
-                       goto vmgexit_err;
-               if (vcpu->arch.regs[VCPU_REGS_RAX] == 0xd)
-                       if (!kvm_ghcb_xcr0_is_valid(svm))
-                               goto vmgexit_err;
-               break;
+                       return false;
+
+               return vcpu->arch.regs[VCPU_REGS_RAX] != 0xd ||
+                      kvm_ghcb_xcr0_is_valid(svm);
        case SVM_EXIT_IOIO:
-               if (control->exit_info_1 & SVM_IOIO_STR_MASK) {
-                       if (!kvm_ghcb_sw_scratch_is_valid(svm))
-                               goto vmgexit_err;
-               } else {
-                       if (!(control->exit_info_1 & SVM_IOIO_TYPE_MASK))
-                               if (!kvm_ghcb_rax_is_valid(svm))
-                                       goto vmgexit_err;
-               }
-               break;
+               if (control->exit_info_1 & SVM_IOIO_STR_MASK)
+                       return kvm_ghcb_sw_scratch_is_valid(svm);
+
+               if (!(control->exit_info_1 & SVM_IOIO_TYPE_MASK))
+                       return kvm_ghcb_rax_is_valid(svm);
+
+               return true;
        case SVM_EXIT_MSR:
                if (!kvm_ghcb_rcx_is_valid(svm))
-                       goto vmgexit_err;
-               if (control->exit_info_1) {
-                       if (!kvm_ghcb_rax_is_valid(svm) ||
-                           !kvm_ghcb_rdx_is_valid(svm))
-                               goto vmgexit_err;
-               }
-               break;
+                       return false;
+
+               return !control->exit_info_1 ||
+                      (kvm_ghcb_rax_is_valid(svm) && kvm_ghcb_rdx_is_valid(svm));
        case SVM_EXIT_VMMCALL:
-               if (!kvm_ghcb_rax_is_valid(svm) ||
-                   !kvm_ghcb_cpl_is_valid(svm))
-                       goto vmgexit_err;
-               break;
+               return kvm_ghcb_rax_is_valid(svm) && kvm_ghcb_cpl_is_valid(svm);
        case SVM_EXIT_MONITOR:
-               if (!kvm_ghcb_rax_is_valid(svm) ||
-                   !kvm_ghcb_rcx_is_valid(svm) ||
-                   !kvm_ghcb_rdx_is_valid(svm))
-                       goto vmgexit_err;
-               break;
+               return kvm_ghcb_rax_is_valid(svm) &&
+                      kvm_ghcb_rcx_is_valid(svm) &&
+                      kvm_ghcb_rdx_is_valid(svm);
        case SVM_EXIT_MWAIT:
-               if (!kvm_ghcb_rax_is_valid(svm) ||
-                   !kvm_ghcb_rcx_is_valid(svm))
-                       goto vmgexit_err;
+               return kvm_ghcb_rax_is_valid(svm) && kvm_ghcb_rcx_is_valid(svm);
+       case SVM_VMGEXIT_AP_CREATION:
+               return kvm_ghcb_rax_is_valid(svm) ||
+                      lower_32_bits(control->exit_info_1) == SVM_VMGEXIT_AP_DESTROY;
                break;
        case SVM_VMGEXIT_MMIO_READ:
        case SVM_VMGEXIT_MMIO_WRITE:
-               if (!kvm_ghcb_sw_scratch_is_valid(svm))
-                       goto vmgexit_err;
-               break;
-       case SVM_VMGEXIT_AP_CREATION:
-               if (lower_32_bits(control->exit_info_1) != SVM_VMGEXIT_AP_DESTROY)
-                       if (!kvm_ghcb_rax_is_valid(svm))
-                               goto vmgexit_err;
-               break;
        case SVM_VMGEXIT_PSC:
-               if (!kvm_ghcb_sw_scratch_is_valid(svm))
-                       goto vmgexit_err;
-               break;
+               return kvm_ghcb_sw_scratch_is_valid(svm);
        default:
-               break;
+               return true;
        }
-
-       return 0;
-
-vmgexit_err:
-       /*
-        * Print the exit code even though it may not be marked valid as it
-        * could help with debugging.
-        */
-       vcpu_unimpl(vcpu, "vmgexit: exit code %#llx input is not valid\n",
-                   control->exit_code);
-       dump_ghcb(svm);
-       svm_vmgexit_bad_input(svm, GHCB_ERR_MISSING_INPUT);
-
-       /* Resume the guest to "return" the error code. */
-       return 1;
 }
 
 static void __sev_es_unmap_ghcb(struct vcpu_svm *svm)
@@ -4510,9 +4471,17 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
                return 1;
        }
 
-       ret = sev_es_validate_vmgexit(svm);
-       if (ret)
-               return ret;
+       if (!sev_es_are_required_ghcb_fields_valid(svm)) {
+               /*
+                * Print the exit code even though it may not be marked valid
+                * as it could help with debugging.
+                */
+               vcpu_unimpl(vcpu, "vmgexit: exit code %#llx input is not valid\n",
+                           control->exit_code);
+               dump_ghcb(svm);
+               svm_vmgexit_bad_input(svm, GHCB_ERR_MISSING_INPUT);
+               return 1;
+       }
 
        svm_vmgexit_success(svm, 0);
 
@@ -4599,6 +4568,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
                vcpu->run->system_event.type = KVM_SYSTEM_EVENT_SEV_TERM;
                vcpu->run->system_event.ndata = 1;
                vcpu->run->system_event.data[0] = control->ghcb_gpa;
+               ret = 0;
                break;
        case SVM_VMGEXIT_PSC:
                ret = setup_vmgexit_scratch(svm, true, sizeof(struct psc_hdr));