From: Sean Christopherson Date: Fri, 29 May 2026 18:35:48 +0000 (+0200) Subject: KVM: SEV: Turn sev_es_validate_vmgexit() into a dedicated predicate X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=abb97ac118f03cb2f5007edb1cf9d4e9d53704df;p=thirdparty%2Fkernel%2Flinux.git KVM: SEV: Turn sev_es_validate_vmgexit() into a dedicated predicate 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 Reviewed-by: Michael Roth Signed-off-by: Sean Christopherson Message-ID: <20260501202250.2115252-24-seanjc@google.com> Signed-off-by: Paolo Bonzini Message-ID: <20260529183549.1104619-24-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini --- diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 864d6aea544b..bb70df2bf1a4 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -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));