From: Sean Christopherson <seanjc@google.com>
To: Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: kvm@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>,
Wanpeng Li <wanpengli@tencent.com>,
Jim Mattson <jmattson@google.com>,
Michael Kelley <mikelley@microsoft.com>,
Siddharth Chandrasekaran <sidcha@amazon.de>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 13/31] KVM: x86: hyper-v: Direct TLB flush
Date: Thu, 7 Apr 2022 18:27:24 +0000 [thread overview]
Message-ID: <Yk8tDHc5E8SkOVqB@google.com> (raw)
In-Reply-To: <20220407155645.940890-14-vkuznets@redhat.com>
On Thu, Apr 07, 2022, Vitaly Kuznetsov wrote:
> Handle Direct TLB flush requests from L2 by going through all vCPUs
What is a "Direct TLB flush request" in this context? I can't tell if "direct"
refers to the MMU being direct, or if it has some other Hyper-V specific meaning.
Ewww, it looks to be Hyper-V terminology. Now I see that @direct=true is getting
L2's ring, not L1's ring. That's all kinds of evil. That confusion goes away with
my suggestion below, but this shortlog and changelog (and the ones for nVMX and
nSVM enabling) absolutely need to clarify "direct" since it conflicts mightily
with KVM's "direct" terminology.
In fact, unless I'm missing a patch where "Direct" doesn't mean "From L2", I vote
to not use the "Direct TLB flush" terminology in any of the shortlogs or changelogs
and only add a footnote to this first changelog to call out that the TLFS (or
wherever this terminology came from) calls these types of flushes "Direct".
> and checking whether there are vCPUs running the same VM_ID with a
> VP_ID specified in the requests. Perform synthetic exit to L2 upon
> finish.
>
> Note, while checking VM_ID/VP_ID of running vCPUs seem to be a bit
> racy, we count on the fact that KVM flushes the whole L2 VPID upon
> transition. Also, KVM_REQ_HV_TLB_FLUSH request needs to be done upon
> transition between L1 and L2 to make sure all pending requests are
> always processed.
>
> Note, while nVMX/nSVM code does not handle VMCALL/VMMCALL from L2 yet.
Spurious "while"? Or is there a missing second half of the note?
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> ---
> arch/x86/kvm/hyperv.c | 65 ++++++++++++++++++++++++++++++++++++-------
> arch/x86/kvm/trace.h | 21 ++++++++------
> 2 files changed, 68 insertions(+), 18 deletions(-)
>
> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
> index 705c0b739c1b..2b12f1b5c992 100644
> --- a/arch/x86/kvm/hyperv.c
> +++ b/arch/x86/kvm/hyperv.c
> @@ -34,6 +34,7 @@
> #include <linux/eventfd.h>
>
> #include <asm/apicdef.h>
> +#include <asm/mshyperv.h>
> #include <trace/events/kvm.h>
>
> #include "trace.h"
> @@ -1849,8 +1850,8 @@ static inline int hv_tlb_flush_ring_free(struct kvm_vcpu_hv *hv_vcpu,
> return read_idx - write_idx - 1;
> }
>
> -static void hv_tlb_flush_ring_enqueue(struct kvm_vcpu *vcpu, bool flush_all,
> - u64 *entries, int count)
> +static void hv_tlb_flush_ring_enqueue(struct kvm_vcpu *vcpu, bool direct,
> + bool flush_all, u64 *entries, int count)
> {
> struct kvm_vcpu_hv_tlbflush_ring *tlb_flush_ring;
> struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
> @@ -1861,7 +1862,7 @@ static void hv_tlb_flush_ring_enqueue(struct kvm_vcpu *vcpu, bool flush_all,
> if (!hv_vcpu)
> return;
>
> - tlb_flush_ring = &hv_vcpu->tlb_flush_ring[0];
> + tlb_flush_ring = direct ? &hv_vcpu->tlb_flush_ring[1] : &hv_vcpu->tlb_flush_ring[0];
Rather than pass in @direct and open code indexing into the ring array, pass in
the ring, then the magic boolean goes away along with its confusing terminology.
tlb_flush_ring = kvm_hv_get_tlb_flush_ring(vcpu);
/*
* vcpu->arch.cr3 may not be up-to-date for running vCPUs so we can't
* analyze it here, flush TLB regardless of the specified address space.
*/
if (all_cpus && !is_guest_mode(vcpu)) {
kvm_for_each_vcpu(i, v, kvm)
hv_tlb_flush_ring_enqueue(v, tlb_flush_ring,
tlb_flush_entries, hc->rep_cnt);
kvm_make_all_cpus_request(kvm, KVM_REQ_HV_TLB_FLUSH);
} else if (!is_guest_mode(vcpu)) {
sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask, vcpu_mask);
for_each_set_bit(i, vcpu_mask, KVM_MAX_VCPUS) {
v = kvm_get_vcpu(kvm, i);
if (!v)
continue;
hv_tlb_flush_ring_enqueue(v, tlb_flush_ring,
tlb_flush_entries, hc->rep_cnt);
}
kvm_make_vcpus_request_mask(kvm, KVM_REQ_HV_TLB_FLUSH, vcpu_mask);
} else {
struct kvm_vcpu_hv *hv_v;
bitmap_zero(vcpu_mask, KVM_MAX_VCPUS);
kvm_for_each_vcpu(i, v, kvm) {
hv_v = to_hv_vcpu(v);
/*
* TLB is fully flushed on L2 VM change: either by KVM
* (on a eVMPTR switch) or by L1 hypervisor (in case it
* re-purposes the active eVMCS for a different VM/VP).
*/
if (!hv_v || hv_v->nested.vm_id != hv_vcpu->nested.vm_id)
continue;
if (!all_cpus &&
!hv_is_vp_in_sparse_set(hv_v->nested.vp_id, valid_bank_mask,
sparse_banks))
continue;
__set_bit(i, vcpu_mask);
hv_tlb_flush_ring_enqueue(v, tlb_flush_ring, tlb_flush_entries, hc->rep_cnt);
}
kvm_make_vcpus_request_mask(kvm, KVM_REQ_HV_TLB_FLUSH, vcpu_mask);
}
> spin_lock_irqsave(&tlb_flush_ring->write_lock, flags);
>
...
> static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
> diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
> index e3a24b8f04be..4241b7c0245e 100644
> --- a/arch/x86/kvm/trace.h
> +++ b/arch/x86/kvm/trace.h
> @@ -1479,38 +1479,41 @@ TRACE_EVENT(kvm_hv_timer_state,
> * Tracepoint for kvm_hv_flush_tlb.
> */
> TRACE_EVENT(kvm_hv_flush_tlb,
> - TP_PROTO(u64 processor_mask, u64 address_space, u64 flags),
> - TP_ARGS(processor_mask, address_space, flags),
> + TP_PROTO(u64 processor_mask, u64 address_space, u64 flags, bool direct),
> + TP_ARGS(processor_mask, address_space, flags, direct),
I very strongly prefer direct be guest_mode here, and then print out L1 vs L2 in
the tracepoint itself. There's no reason to overload "direct".
> TP_STRUCT__entry(
> __field(u64, processor_mask)
> __field(u64, address_space)
> __field(u64, flags)
> + __field(bool, direct)
> ),
>
> TP_fast_assign(
> __entry->processor_mask = processor_mask;
> __entry->address_space = address_space;
> __entry->flags = flags;
> + __entry->direct = direct;
> ),
>
> - TP_printk("processor_mask 0x%llx address_space 0x%llx flags 0x%llx",
> + TP_printk("processor_mask 0x%llx address_space 0x%llx flags 0x%llx %s",
> __entry->processor_mask, __entry->address_space,
> - __entry->flags)
> + __entry->flags, __entry->direct ? "(direct)" : "")
> );
>
> /*
> * Tracepoint for kvm_hv_flush_tlb_ex.
> */
> TRACE_EVENT(kvm_hv_flush_tlb_ex,
> - TP_PROTO(u64 valid_bank_mask, u64 format, u64 address_space, u64 flags),
> - TP_ARGS(valid_bank_mask, format, address_space, flags),
> + TP_PROTO(u64 valid_bank_mask, u64 format, u64 address_space, u64 flags, bool direct),
> + TP_ARGS(valid_bank_mask, format, address_space, flags, direct),
>
> TP_STRUCT__entry(
> __field(u64, valid_bank_mask)
> __field(u64, format)
> __field(u64, address_space)
> __field(u64, flags)
> + __field(bool, direct)
> ),
>
> TP_fast_assign(
> @@ -1518,12 +1521,14 @@ TRACE_EVENT(kvm_hv_flush_tlb_ex,
> __entry->format = format;
> __entry->address_space = address_space;
> __entry->flags = flags;
> + __entry->direct = direct;
> ),
>
> TP_printk("valid_bank_mask 0x%llx format 0x%llx "
> - "address_space 0x%llx flags 0x%llx",
> + "address_space 0x%llx flags 0x%llx %s",
> __entry->valid_bank_mask, __entry->format,
> - __entry->address_space, __entry->flags)
> + __entry->address_space, __entry->flags,
> + __entry->direct ? "(direct)" : "")
> );
>
> /*
> --
> 2.35.1
>
next prev parent reply other threads:[~2022-04-07 18:27 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-07 15:56 [PATCH v2 00/31] KVM: x86: hyper-v: Fine-grained TLB flush + Direct TLB flush feature Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 01/31] KVM: x86: hyper-v: Resurrect dedicated KVM_REQ_HV_TLB_FLUSH flag Vitaly Kuznetsov
2022-04-07 18:02 ` Sean Christopherson
2022-04-07 15:56 ` [PATCH v2 02/31] KVM: x86: hyper-v: Introduce TLB flush ring Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 03/31] KVM: x86: hyper-v: Handle HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST{,EX} calls gently Vitaly Kuznetsov
2022-04-07 17:33 ` Sean Christopherson
2022-04-07 17:47 ` Sean Christopherson
2022-04-11 11:15 ` Vitaly Kuznetsov
2022-04-07 17:44 ` Sean Christopherson
2022-04-11 11:31 ` Vitaly Kuznetsov
2022-04-11 20:37 ` Sean Christopherson
2022-04-07 15:56 ` [PATCH v2 04/31] KVM: x86: hyper-v: Expose support for extended gva ranges for flush hypercalls Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 05/31] KVM: x86: Prepare kvm_hv_flush_tlb() to handle L2's GPAs Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 06/31] KVM: x86: hyper-v: Don't use sparse_set_to_vcpu_mask() in kvm_hv_send_ipi() Vitaly Kuznetsov
2022-04-07 17:48 ` Sean Christopherson
2022-04-07 15:56 ` [PATCH v2 07/31] KVM: x86: hyper-v: Create a separate ring for Direct TLB flush Vitaly Kuznetsov
2022-04-07 17:57 ` Sean Christopherson
2022-04-07 15:56 ` [PATCH v2 08/31] KVM: x86: hyper-v: Use preallocated buffer in 'struct kvm_vcpu_hv' instead of on-stack 'sparse_banks' Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 09/31] KVM: nVMX: Keep track of hv_vm_id/hv_vp_id when eVMCS is in use Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 10/31] KVM: nSVM: Keep track of Hyper-V hv_vm_id/hv_vp_id Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 11/31] KVM: x86: Introduce .post_hv_direct_flush() nested hook Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 12/31] KVM: x86: hyper-v: Introduce kvm_hv_is_tlb_flush_hcall() Vitaly Kuznetsov
2022-04-07 18:07 ` Sean Christopherson
2022-04-07 15:56 ` [PATCH v2 13/31] KVM: x86: hyper-v: Direct TLB flush Vitaly Kuznetsov
2022-04-07 18:27 ` Sean Christopherson [this message]
2022-04-14 12:24 ` Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 14/31] KVM: x86: hyper-v: Introduce fast kvm_hv_direct_tlb_flush_exposed() check Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 15/31] x86/hyperv: Fix 'struct hv_enlightened_vmcs' definition Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 16/31] KVM: nVMX: hyper-v: Direct TLB flush Vitaly Kuznetsov
2022-04-07 18:47 ` Sean Christopherson
2022-04-11 11:19 ` Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 17/31] KVM: x86: KVM_REQ_TLB_FLUSH_CURRENT is a superset of KVM_REQ_HV_TLB_FLUSH too Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 18/31] KVM: nSVM: hyper-v: Direct TLB flush Vitaly Kuznetsov
2022-04-07 18:50 ` Sean Christopherson
2022-04-07 15:56 ` [PATCH v2 19/31] KVM: x86: Expose Hyper-V Direct TLB flush feature Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 20/31] KVM: selftests: add hyperv_svm_test to .gitignore Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 21/31] KVM: selftests: Better XMM read/write helpers Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 22/31] KVM: selftests: Hyper-V PV IPI selftest Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 23/31] KVM: selftests: Make it possible to replace PTEs with __virt_pg_map() Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 24/31] KVM: selftests: Hyper-V PV TLB flush selftest Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 25/31] KVM: selftests: Sync 'struct hv_enlightened_vmcs' definition with hyperv-tlfs.h Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 26/31] KVM: selftests: nVMX: Allocate Hyper-V partition assist page Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 27/31] KVM: selftests: nSVM: Allocate Hyper-V partition assist and VP assist pages Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 28/31] KVM: selftests: Sync 'struct hv_vp_assist_page' definition with hyperv-tlfs.h Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 29/31] KVM: selftests: evmcs_test: Direct TLB flush test Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 30/31] KVM: selftests: Move Hyper-V VP assist page enablement out of evmcs.h Vitaly Kuznetsov
2022-04-07 15:56 ` [PATCH v2 31/31] KVM: selftests: hyperv_svm_test: Add Direct TLB flush test Vitaly Kuznetsov
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=Yk8tDHc5E8SkOVqB@google.com \
--to=seanjc@google.com \
--cc=jmattson@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mikelley@microsoft.com \
--cc=pbonzini@redhat.com \
--cc=sidcha@amazon.de \
--cc=vkuznets@redhat.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox