Re: [PATCH v2 1/8] KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req

Vitaly Kuznetsov
2021-11-01T09:05:35Z

Sean Christopherson <seanjc@google.com> writes:

> 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>
> ---
> arch/x86/kvm/hyperv.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
> index 4f15c0165c05..814d1a1f2cb8 100644
> --- a/arch/x86/kvm/hyperv.c
> +++ b/arch/x86/kvm/hyperv.c
> @@ -1922,11 +1922,13 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool
>
> 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,
> hc->ingpa + offsetof(struct hv_send_ipi_ex,
> vp_set.bank_contents),
> sparse_banks,
> @@ -1934,6 +1936,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool
> 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;

Nice catch! It's possible that genuine Windows/Hyper-V guests never hit
the bug because they don't use 'ex' version to send IPIs to all CPUs. It
is also possible that Windows/Hyper-V guests with > 64 vCPUs are just
undertested.

Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>

--
Vitaly