summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Christopherson <seanjc@google.com>2026-05-29 21:35:48 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2026-06-03 17:59:19 +0300
commitabb97ac118f03cb2f5007edb1cf9d4e9d53704df (patch)
tree9fee074fb28b6181cff6f54f0b90de047e11641d
parentb9114841777021ddc3b975c05fd5998a47b44587 (diff)
downloadlinux-abb97ac118f03cb2f5007edb1cf9d4e9d53704df.tar.xz
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 <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>
-rw-r--r--arch/x86/kvm/svm/sev.c112
1 files changed, 41 insertions, 71 deletions
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));