| From 3244867af8c065e51969f1bffe732d3ebfd9a7d2 Mon Sep 17 00:00:00 2001 |
| From: Sean Christopherson <seanjc@google.com> |
| Date: Tue, 7 Dec 2021 22:09:19 +0000 |
| Subject: KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req |
| |
| From: Sean Christopherson <seanjc@google.com> |
| |
| commit 3244867af8c065e51969f1bffe732d3ebfd9a7d2 upstream. |
| |
| Do not bail early if there are no bits set in the sparse banks for a |
| non-sparse, a.k.a. "all CPUs", IPI request. Per the Hyper-V spec, it is |
| legal to have a variable length of '0', e.g. VP_SET's BankContents in |
| this case, if the request can be serviced without the extra info. |
| |
| It is possible that for a given invocation of a hypercall that does |
| accept variable sized input headers that all the header input fits |
| entirely within the fixed size header. In such cases the variable sized |
| input header is zero-sized and the corresponding bits in the hypercall |
| input should be set to zero. |
| |
| Bailing early results in KVM failing to send IPIs to all CPUs as expected |
| by the guest. |
| |
| Fixes: 214ff83d4473 ("KVM: x86: hyperv: implement PV IPI send hypercalls") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Sean Christopherson <seanjc@google.com> |
| Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com> |
| Message-Id: <20211207220926.718794-2-seanjc@google.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/kvm/hyperv.c | 7 +++++-- |
| 1 file changed, 5 insertions(+), 2 deletions(-) |
| |
| --- a/arch/x86/kvm/hyperv.c |
| +++ b/arch/x86/kvm/hyperv.c |
| @@ -1501,11 +1501,13 @@ static u64 kvm_hv_send_ipi(struct kvm_vc |
| |
| all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL; |
| |
| + if (all_cpus) |
| + goto check_and_send_ipi; |
| + |
| if (!sparse_banks_len) |
| goto ret_success; |
| |
| - if (!all_cpus && |
| - kvm_read_guest(kvm, |
| + if (kvm_read_guest(kvm, |
| ingpa + offsetof(struct hv_send_ipi_ex, |
| vp_set.bank_contents), |
| sparse_banks, |
| @@ -1513,6 +1515,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vc |
| return HV_STATUS_INVALID_HYPERCALL_INPUT; |
| } |
| |
| +check_and_send_ipi: |
| if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR)) |
| return HV_STATUS_INVALID_HYPERCALL_INPUT; |
| |