[PATCH 19/24] KVM: SEV: Move GHCB "usage" check out of sev_es_validate_vmgexit()
From: Paolo Bonzini
Date: Fri May 29 2026 - 14:46:33 EST
From: Sean Christopherson <seanjc@xxxxxxxxxx>
Move the check to verify the guest's requested GHCB out of
sev_es_validate_vmgexit() as the first step towards making said helper a
predicate whose sole purpose is to verify the guest has marked required
GHCB fields as valid.
Using a single "validate" helper sounds good on paper, but in practice it's
difficult to verify that KVM is performing the necessary sanity checks (the
usage of state is far removed from the relevant checks), makes it difficult
to understand that "legacy" exits are simply routed to KVM's existing exit
handlers, and most importantly, has directly contributed to a number of
bugs as adding case-statements to the validation subtly removes them from
the default path that rejects unknown exit codes with INVALID_EVENT.
Deliberately extract the usage code check first so as to preserve the order
of KVM's checks, even though future code extraction will technically fix
bugs.
No functional change intended.
Reviewed-by: Tom Lendacky <thomas.lendacky@xxxxxxx>
Reviewed-by: Michael Roth <michael.roth@xxxxxxx>
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
Message-ID: <20260501202250.2115252-20-seanjc@xxxxxxxxxx>
Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
arch/x86/kvm/svm/sev.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 7c2ebc81306f..880a2acd77bf 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3416,12 +3416,6 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
struct kvm_vcpu *vcpu = &svm->vcpu;
u64 reason;
- /* Only GHCB Usage code 0 is supported */
- if (svm->sev_es.ghcb->ghcb_usage) {
- reason = GHCB_ERR_INVALID_USAGE;
- goto vmgexit_err;
- }
-
reason = GHCB_ERR_MISSING_INPUT;
if (!kvm_ghcb_sw_exit_code_is_valid(svm) ||
@@ -3534,10 +3528,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
* Print the exit code even though it may not be marked valid as it
* could help with debugging.
*/
- if (reason == GHCB_ERR_INVALID_USAGE) {
- vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n",
- svm->sev_es.ghcb->ghcb_usage);
- } else if (reason == GHCB_ERR_INVALID_EVENT) {
+ if (reason == GHCB_ERR_INVALID_EVENT) {
vcpu_unimpl(vcpu, "vmgexit: exit code %#llx is not valid\n",
control->exit_code);
} else {
@@ -4528,6 +4519,14 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
return 1;
}
+ /* Only GHCB Usage code 0 is supported */
+ if (svm->sev_es.ghcb->ghcb_usage) {
+ vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n",
+ svm->sev_es.ghcb->ghcb_usage);
+ svm_vmgexit_bad_input(svm, GHCB_ERR_INVALID_USAGE);
+ return 1;
+ }
+
ret = sev_es_validate_vmgexit(svm);
if (ret)
return ret;
--
2.54.0