diff options
| author | Sean Christopherson <seanjc@google.com> | 2026-05-29 21:35:45 +0300 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2026-06-03 17:59:19 +0300 |
| commit | 95d8c59cdf6d6c49b24cda1de595ed409cbb8596 (patch) | |
| tree | c6ea69bdfa954efe21ae49873efb6459a99beb67 | |
| parent | 9a6e8d23dd6129eef5bfa474ddf161d732613701 (diff) | |
| download | linux-95d8c59cdf6d6c49b24cda1de595ed409cbb8596.tar.xz | |
KVM: SEV: Return INVALID_EVENT for SNP-only #VMGEXIT from non-SNP guest
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>
| -rw-r--r-- | arch/x86/kvm/svm/sev.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 880a2acd77bf..b59adddfdbcc 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -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; |
