diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index f5bf654f025e..bc14c3d0c0cc 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1757,11 +1757,16 @@ struct kvm_hv_hcall { static u64 kvm_get_sparse_vp_set(struct kvm *kvm, struct kvm_hv_hcall *hc, u64 *sparse_banks, gpa_t offset) { + u16 var_cnt; + if (hc->var_cnt > 64) return -EINVAL; + /* Ignore banks that cannot possibly contain a legal VP index. */ + var_cnt = min_t(u16, hc->var_cnt, KVM_HV_MAX_SPARSE_VCPU_SET_BITS); + return kvm_read_guest(kvm, hc->ingpa + offset, sparse_banks, - hc->var_cnt * sizeof(*sparse_banks)); + var_cnt * sizeof(*sparse_banks)); } static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool ex) @@ -1774,9 +1779,17 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool DECLARE_BITMAP(vcpu_bitmap, KVM_MAX_VCPUS); unsigned long *vcpu_mask; u64 valid_bank_mask; - u64 sparse_banks[64]; + u64 sparse_banks[KVM_HV_MAX_SPARSE_VCPU_SET_BITS]; bool all_cpus; + /* + * The Hyper-V TLFS doesn't allow more than 64 sparse banks, e.g. the + * valid mask is a u64. Fail the build if KVM's max allowed number of + * vCPUs (>4096) would exceed this limit, KVM will additional changes + * for Hyper-V support to avoid setting the guest up to fail. + */ + BUILD_BUG_ON(KVM_HV_MAX_SPARSE_VCPU_SET_BITS > 64); + if (!ex) { if (hc->fast) { flush.address_space = hc->ingpa; @@ -1898,7 +1911,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool DECLARE_BITMAP(vcpu_bitmap, KVM_MAX_VCPUS); unsigned long *vcpu_mask; unsigned long valid_bank_mask; - u64 sparse_banks[64]; + u64 sparse_banks[KVM_HV_MAX_SPARSE_VCPU_SET_BITS]; u32 vector; bool all_cpus;