From: Vitaly Kuznetsov <vkuznets@redhat.com>
To: Maxim Levitsky <mlevitsk@redhat.com>
Cc: Sean Christopherson <seanjc@google.com>,
Wanpeng Li <wanpengli@tencent.com>,
Jim Mattson <jmattson@google.com>,
Siddharth Chandrasekaran <sidcha@amazon.de>,
linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [PATCH 4/4] KVM: x86: hyper-v: HVCALL_SEND_IPI_EX is an XMM fast hypercall
Date: Mon, 28 Feb 2022 11:02:20 +0100 [thread overview]
Message-ID: <87v8wzcnrn.fsf@redhat.com> (raw)
In-Reply-To: <6d01c59eab7f31eef1b4249a85869600410336b7.camel@redhat.com>
Maxim Levitsky <mlevitsk@redhat.com> writes:
> On Tue, 2022-02-22 at 16:46 +0100, Vitaly Kuznetsov wrote:
>> It has been proven on practice that at least Windows Server 2019 tries
>> using HVCALL_SEND_IPI_EX in 'XMM fast' mode when it has more than 64 vCPUs
>> and it needs to send an IPI to a vCPU > 63. Similarly to other XMM Fast
>> hypercalls (HVCALL_FLUSH_VIRTUAL_ADDRESS_{LIST,SPACE}{,_EX}), this
>> information is missing in TLFS as of 6.0b. Currently, KVM returns an error
>> (HV_STATUS_INVALID_HYPERCALL_INPUT) and Windows crashes.
>>
>> Note, HVCALL_SEND_IPI is a 'standard' fast hypercall (not 'XMM fast') as
>> all its parameters fit into RDX:R8 and this is handled by KVM correctly.
>>
>> Fixes: d8f5537a8816 ("KVM: hyper-v: Advertise support for fast XMM hypercalls")
>> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
>> ---
>> arch/x86/kvm/hyperv.c | 52 ++++++++++++++++++++++++++++---------------
>> 1 file changed, 34 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
>> index 6dda93bf98ae..3060057bdfd4 100644
>> --- a/arch/x86/kvm/hyperv.c
>> +++ b/arch/x86/kvm/hyperv.c
>> @@ -1890,6 +1890,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
>> int sparse_banks_len;
>> u32 vector;
>> bool all_cpus;
>> + int i;
>>
>> if (hc->code == HVCALL_SEND_IPI) {
>> if (!hc->fast) {
>> @@ -1910,9 +1911,15 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
>>
>> trace_kvm_hv_send_ipi(vector, sparse_banks[0]);
>> } else {
>> - if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi_ex,
>> - sizeof(send_ipi_ex))))
>> - return HV_STATUS_INVALID_HYPERCALL_INPUT;
>> + if (!hc->fast) {
>> + if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi_ex,
>> + sizeof(send_ipi_ex))))
>> + return HV_STATUS_INVALID_HYPERCALL_INPUT;
>> + } else {
>> + send_ipi_ex.vector = (u32)hc->ingpa;
>> + send_ipi_ex.vp_set.format = hc->outgpa;
>> + send_ipi_ex.vp_set.valid_bank_mask = sse128_lo(hc->xmm[0]);
>> + }
>>
>> trace_kvm_hv_send_ipi_ex(send_ipi_ex.vector,
>> send_ipi_ex.vp_set.format,
>> @@ -1920,8 +1927,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
>>
>> vector = send_ipi_ex.vector;
>> valid_bank_mask = send_ipi_ex.vp_set.valid_bank_mask;
>> - sparse_banks_len = bitmap_weight(&valid_bank_mask, 64) *
>> - sizeof(sparse_banks[0]);
>> + sparse_banks_len = bitmap_weight(&valid_bank_mask, 64);
> Is this change intentional?
>
Yes it is. Previously, 'sparse_banks_len' was the number of bytes to
read, now it's in u64-s.
(see below)
> I haven't fully reviewed this, because kvm/queue seem to have a bit different
> version of this, and I didn't fully follow on all of this.
>
>>
>> all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL;
>>
>> @@ -1931,12 +1937,27 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
>> if (!sparse_banks_len)
>> goto ret_success;
>>
>> - if (kvm_read_guest(kvm,
>> - hc->ingpa + offsetof(struct hv_send_ipi_ex,
>> - vp_set.bank_contents),
>> - sparse_banks,
>> - sparse_banks_len))
>> - return HV_STATUS_INVALID_HYPERCALL_INPUT;
>> + if (!hc->fast) {
>> + if (kvm_read_guest(kvm,
>> + hc->ingpa + offsetof(struct hv_send_ipi_ex,
>> + vp_set.bank_contents),
>> + sparse_banks,
>> + sparse_banks_len * sizeof(sparse_banks[0])))
^^^ here ^^^
>> + return HV_STATUS_INVALID_HYPERCALL_INPUT;
>> + } else {
>> + /*
>> + * The lower half of XMM0 is already consumed, each XMM holds
>> + * two sparse banks.
>> + */
>> + if (sparse_banks_len > (2 * HV_HYPERCALL_MAX_XMM_REGISTERS - 1))
>> + return HV_STATUS_INVALID_HYPERCALL_INPUT;
And here. This is the reason for change: it's more convenient to count
it 'xmm halves' than in bytes.
>> + for (i = 0; i < sparse_banks_len; i++) {
>> + if (i % 2)
>> + sparse_banks[i] = sse128_lo(hc->xmm[(i + 1) / 2]);
>> + else
>> + sparse_banks[i] = sse128_hi(hc->xmm[i / 2]);
>> + }
>> + }
>> }
>>
>> check_and_send_ipi:
>> @@ -2098,6 +2119,7 @@ static bool is_xmm_fast_hypercall(struct kvm_hv_hcall *hc)
>> case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
>> case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
>> case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX:
>> + case HVCALL_SEND_IPI_EX:
>> return true;
>> }
>>
>> @@ -2265,14 +2287,8 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
>> ret = kvm_hv_flush_tlb(vcpu, &hc);
>> break;
>> case HVCALL_SEND_IPI:
>> - if (unlikely(hc.rep)) {
>> - ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
>> - break;
>> - }
>> - ret = kvm_hv_send_ipi(vcpu, &hc);
>> - break;
>> case HVCALL_SEND_IPI_EX:
>> - if (unlikely(hc.fast || hc.rep)) {
>> + if (unlikely(hc.rep)) {
>> ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
>> break;
>> }
>
>
--
Vitaly
next prev parent reply other threads:[~2022-02-28 10:03 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-22 15:46 [PATCH 0/4] KVM: x86: hyper-v: XMM fast hypercalls fixes Vitaly Kuznetsov
2022-02-22 15:46 ` [PATCH 1/4] KVM: x86: hyper-v: Drop redundant 'ex' parameter from kvm_hv_send_ipi() Vitaly Kuznetsov
2022-02-25 18:21 ` Maxim Levitsky
2022-02-28 9:58 ` Vitaly Kuznetsov
2022-02-28 10:45 ` Siddharth Chandrasekaran
2022-02-22 15:46 ` [PATCH 2/4] KVM: x86: hyper-v: Drop redundant 'ex' parameter from kvm_hv_flush_tlb() Vitaly Kuznetsov
2022-02-25 18:22 ` Maxim Levitsky
2022-02-28 10:46 ` Siddharth Chandrasekaran
2022-02-22 15:46 ` [PATCH 3/4] KVM: x86: hyper-v: Fix the maximum number of sparse banks for XMM fast TLB flush hypercalls Vitaly Kuznetsov
2022-02-28 10:47 ` Siddharth Chandrasekaran
2022-02-22 15:46 ` [PATCH 4/4] KVM: x86: hyper-v: HVCALL_SEND_IPI_EX is an XMM fast hypercall Vitaly Kuznetsov
2022-02-25 18:33 ` Maxim Levitsky
2022-02-28 10:02 ` Vitaly Kuznetsov [this message]
2022-02-28 10:48 ` Siddharth Chandrasekaran
2022-02-25 11:55 ` [PATCH 0/4] KVM: x86: hyper-v: XMM fast hypercalls fixes Paolo Bonzini
2022-02-25 13:13 ` Vitaly Kuznetsov
2022-02-25 13:17 ` Paolo Bonzini
2022-02-28 10:52 ` Siddharth Chandrasekaran
2022-02-28 11:09 ` Vitaly Kuznetsov
2022-02-28 16:18 ` Siddharth Chandrasekaran
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87v8wzcnrn.fsf@redhat.com \
--to=vkuznets@redhat.com \
--cc=jmattson@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mlevitsk@redhat.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=sidcha@amazon.de \
--cc=wanpengli@tencent.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.