Message ID | 20211213095012.15021-1-vkuznets@redhat.com |
---|---|
State | New |
Headers | show |
Series | [5.10] KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req | expand |
On Mon, Dec 13, 2021 at 10:50:12AM +0100, Vitaly Kuznetsov wrote: > 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> > --- > arch/x86/kvm/hyperv.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) Both now queued up, thanks. greg k-h
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index bb39f493447c..328f37e4fd3a 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1641,11 +1641,13 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *current_vcpu, u64 ingpa, u64 outgpa, 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, @@ -1653,6 +1655,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *current_vcpu, u64 ingpa, u64 outgpa, 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;