diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2021-10-25 18:14:31 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2021-10-27 16:58:26 +0200 |
commit | 9b0971ca7fc75daca80c0bb6c02e96059daea90a (patch) | |
tree | 0c2f994c2eaeffaa02392cbe3e08909d70f61b71 /arch | |
parent | KVM: x86/xen: Fix kvm_xen_has_interrupt() sleeping in kvm_vcpu_block() (diff) | |
download | linux-9b0971ca7fc75daca80c0bb6c02e96059daea90a.tar.xz linux-9b0971ca7fc75daca80c0bb6c02e96059daea90a.zip |
KVM: SEV-ES: fix another issue with string I/O VMGEXITs
If the guest requests string I/O from the hypervisor via VMGEXIT,
SW_EXITINFO2 will contain the REP count. However, sev_es_string_io
was incorrectly treating it as the size of the GHCB buffer in
bytes.
This fixes the "outsw" test in the experimental SEV tests of
kvm-unit-tests.
Cc: stable@vger.kernel.org
Fixes: 7ed9abfe8e9f ("KVM: SVM: Support string IO operations for an SEV-ES guest")
Reported-by: Marc Orr <marcorr@google.com>
Tested-by: Marc Orr <marcorr@google.com>
Reviewed-by: Marc Orr <marcorr@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/svm/sev.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index e672493b5d8d..efd207fd335e 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -2579,11 +2579,20 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) { - if (!setup_vmgexit_scratch(svm, in, svm->vmcb->control.exit_info_2)) + int count; + int bytes; + + if (svm->vmcb->control.exit_info_2 > INT_MAX) + return -EINVAL; + + count = svm->vmcb->control.exit_info_2; + if (unlikely(check_mul_overflow(count, size, &bytes))) + return -EINVAL; + + if (!setup_vmgexit_scratch(svm, in, bytes)) return -EINVAL; - return kvm_sev_es_string_io(&svm->vcpu, size, port, - svm->ghcb_sa, svm->ghcb_sa_len / size, in); + return kvm_sev_es_string_io(&svm->vcpu, size, port, svm->ghcb_sa, count, in); } void sev_es_init_vmcb(struct vcpu_svm *svm) |