diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2021-10-25 12:14:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-11-02 19:51:02 +0100 |
commit | 9ab39a3d0cec142c424fae4186684fcea90df0de (patch) | |
tree | d4f29c187057cf639d01d4519f5e93b4ca33d6ec | |
parent | eb0461c572e902680383b52c091449f4035e2105 (diff) | |
download | linux-stable-9ab39a3d0cec142c424fae4186684fcea90df0de.tar.gz linux-stable-9ab39a3d0cec142c424fae4186684fcea90df0de.tar.bz2 linux-stable-9ab39a3d0cec142c424fae4186684fcea90df0de.zip |
KVM: SEV-ES: fix another issue with string I/O VMGEXITs
commit 9b0971ca7fc75daca80c0bb6c02e96059daea90a upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 9959888cb10c..675a9bbf322e 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -2592,11 +2592,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) |