All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxim Levitsky <mlevitsk@redhat.com>
To: Vitaly Kuznetsov <vkuznets@redhat.com>,
	kvm@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>
Cc: Sean Christopherson <seanjc@google.com>,
	Wanpeng Li <wanpengli@tencent.com>,
	Jim Mattson <jmattson@google.com>,
	Michael Kelley <mikelley@microsoft.com>,
	Siddharth Chandrasekaran <sidcha@amazon.de>,
	Yuan Yao <yuan.yao@linux.intel.com>,
	linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v6 21/38] KVM: nVMX: hyper-v: Enable L2 TLB flush
Date: Tue, 07 Jun 2022 13:02:15 +0300	[thread overview]
Message-ID: <33ddebdb9bc7283acd3d70c39e03645580089795.camel@redhat.com> (raw)
In-Reply-To: <20220606083655.2014609-22-vkuznets@redhat.com>

On Mon, 2022-06-06 at 10:36 +0200, Vitaly Kuznetsov wrote:
> Enable L2 TLB flush feature on nVMX when:
> - Enlightened VMCS is in use.
> - The feature flag is enabled in eVMCS.
> - The feature flag is enabled in partition assist page.
> 
> Perform synthetic vmexit to L1 after processing TLB flush call upon
> request (HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH).
> 
> Note: nested_evmcs_l2_tlb_flush_enabled() uses cached VP assist page copy
> which gets updated from nested_vmx_handle_enlightened_vmptrld(). This is
> also guaranteed to happen post migration with eVMCS backed L2 running.
> 
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> ---
>  arch/x86/kvm/vmx/evmcs.c  | 17 +++++++++++++++++
>  arch/x86/kvm/vmx/evmcs.h  | 10 ++++++++++
>  arch/x86/kvm/vmx/nested.c | 22 ++++++++++++++++++++++
>  3 files changed, 49 insertions(+)
> 
> diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c
> index 7cd7b16942c6..870de69172be 100644
> --- a/arch/x86/kvm/vmx/evmcs.c
> +++ b/arch/x86/kvm/vmx/evmcs.c
> @@ -6,6 +6,7 @@
>  #include "../hyperv.h"
>  #include "../cpuid.h"
>  #include "evmcs.h"
> +#include "nested.h"
>  #include "vmcs.h"
>  #include "vmx.h"
>  #include "trace.h"
> @@ -433,6 +434,22 @@ int nested_enable_evmcs(struct kvm_vcpu *vcpu,
>         return 0;
>  }
>  
> +bool nested_evmcs_l2_tlb_flush_enabled(struct kvm_vcpu *vcpu)
> +{
> +       struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
> +       struct vcpu_vmx *vmx = to_vmx(vcpu);
> +       struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
> +
> +       if (!hv_vcpu || !evmcs)
> +               return false;
> +
> +       if (!evmcs->hv_enlightenments_control.nested_flush_hypercall)
> +               return false;
> +
> +       return hv_vcpu->vp_assist_page.nested_control.features.directhypercall;
> +}
> +
>  void vmx_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu)
>  {
> +       nested_vmx_vmexit(vcpu, HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH, 0, 0);
>  }
> diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h
> index 22d238b36238..0267b6191e6c 100644
> --- a/arch/x86/kvm/vmx/evmcs.h
> +++ b/arch/x86/kvm/vmx/evmcs.h
> @@ -66,6 +66,15 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs);
>  #define EVMCS1_UNSUPPORTED_VMENTRY_CTRL (VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
>  #define EVMCS1_UNSUPPORTED_VMFUNC (VMX_VMFUNC_EPTP_SWITCHING)
>  
> +/*
> + * Note, Hyper-V isn't actually stealing bit 28 from Intel, just abusing it by
> + * pairing it with architecturally impossible exit reasons.  Bit 28 is set only
> + * on SMI exits to a SMI transfer monitor (STM) and if and only if a MTF VM-Exit
> + * is pending.  I.e. it will never be set by hardware for non-SMI exits (there
> + * are only three), nor will it ever be set unless the VMM is an STM.
> + */
> +#define HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH 0x10000031
> +
>  struct evmcs_field {
>         u16 offset;
>         u16 clean_field;
> @@ -245,6 +254,7 @@ int nested_enable_evmcs(struct kvm_vcpu *vcpu,
>                         uint16_t *vmcs_version);
>  void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata);
>  int nested_evmcs_check_controls(struct vmcs12 *vmcs12);
> +bool nested_evmcs_l2_tlb_flush_enabled(struct kvm_vcpu *vcpu);
>  void vmx_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu);
>  
>  #endif /* __KVM_X86_VMX_EVMCS_H */
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index 87bff81f7f3e..69d06f77d7b4 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -1170,6 +1170,17 @@ static void nested_vmx_transition_tlb_flush(struct kvm_vcpu *vcpu,
>  {
>         struct vcpu_vmx *vmx = to_vmx(vcpu);
>  
> +       /*
> +        * KVM_REQ_HV_TLB_FLUSH flushes entries from either L1's VP_ID or
> +        * L2's VP_ID upon request from the guest. Make sure we check for
> +        * pending entries for the case when the request got misplaced (e.g.
> +        * a transition from L2->L1 happened while processing L2 TLB flush
> +        * request or vice versa). kvm_hv_vcpu_flush_tlb() will not flush
> +        * anything if there are no requests in the corresponding buffer.
> +        */
> +       if (to_hv_vcpu(vcpu))
> +               kvm_make_request(KVM_REQ_HV_TLB_FLUSH, vcpu);
> +
>         /*
>          * If vmcs12 doesn't use VPID, L1 expects linear and combined mappings
>          * for *all* contexts to be flushed on VM-Enter/VM-Exit, i.e. it's a
> @@ -3278,6 +3289,12 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
>  
>  static bool vmx_get_nested_state_pages(struct kvm_vcpu *vcpu)
>  {
> +       /*
> +        * Note: nested_get_evmcs_page() also updates 'vp_assist_page' copy
> +        * in 'struct kvm_vcpu_hv' in case eVMCS is in use, this is mandatory
> +        * to make nested_evmcs_l2_tlb_flush_enabled() work correctly post
> +        * migration.
> +        */
>         if (!nested_get_evmcs_page(vcpu)) {
>                 pr_debug_ratelimited("%s: enlightened vmptrld failed\n",
>                                      __func__);
> @@ -6007,6 +6024,11 @@ static bool nested_vmx_l0_wants_exit(struct kvm_vcpu *vcpu,
>                  * Handle L2's bus locks in L0 directly.
>                  */
>                 return true;
> +       case EXIT_REASON_VMCALL:
> +               /* Hyper-V L2 TLB flush hypercall is handled by L0 */
> +               return guest_hv_cpuid_has_l2_tlb_flush(vcpu) &&
> +                       nested_evmcs_l2_tlb_flush_enabled(vcpu) &&
> +                       kvm_hv_is_tlb_flush_hcall(vcpu);
>         default:
>                 break;
>         }


Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>

Best regards,
	Maxim Levitsky


  reply	other threads:[~2022-06-07 10:02 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-06  8:36 [PATCH v6 00/38] KVM: x86: hyper-v: Fine-grained TLB flush + L2 TLB flush features Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 01/38] KVM: x86: Rename 'enable_direct_tlbflush' to 'enable_l2_tlb_flush' Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 02/38] KVM: x86: hyper-v: Resurrect dedicated KVM_REQ_HV_TLB_FLUSH flag Vitaly Kuznetsov
2022-06-07  8:46   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 03/38] KVM: x86: hyper-v: Introduce TLB flush fifo Vitaly Kuznetsov
2022-06-07  8:57   ` Maxim Levitsky
2022-06-08  7:47     ` Vitaly Kuznetsov
2022-06-08  8:46       ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 04/38] KVM: x86: hyper-v: Add helper to read hypercall data for array Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 05/38] KVM: x86: hyper-v: Handle HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST{,EX} calls gently Vitaly Kuznetsov
2022-06-07  9:30   ` Maxim Levitsky
2022-06-13 12:58     ` Vitaly Kuznetsov
2022-06-08 10:18   ` Yuan Yao
2022-06-09  9:13     ` Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 06/38] KVM: x86: hyper-v: Expose support for extended gva ranges for flush hypercalls Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 07/38] KVM: x86: Prepare kvm_hv_flush_tlb() to handle L2's GPAs Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 08/38] x86/hyperv: Introduce HV_MAX_SPARSE_VCPU_BANKS/HV_VCPUS_PER_SPARSE_BANK constants Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 09/38] KVM: x86: hyper-v: Use HV_MAX_SPARSE_VCPU_BANKS/HV_VCPUS_PER_SPARSE_BANK instead of raw '64' Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 10/38] KVM: x86: hyper-v: Don't use sparse_set_to_vcpu_mask() in kvm_hv_send_ipi() Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 11/38] KVM: x86: hyper-v: Create a separate fifo for L2 TLB flush Vitaly Kuznetsov
2022-06-07  9:33   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 12/38] KVM: x86: hyper-v: Use preallocated buffer in 'struct kvm_vcpu_hv' instead of on-stack 'sparse_banks' Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 13/38] KVM: nVMX: Keep track of hv_vm_id/hv_vp_id when eVMCS is in use Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 14/38] KVM: nSVM: Keep track of Hyper-V hv_vm_id/hv_vp_id Vitaly Kuznetsov
2022-06-07  9:36   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 15/38] KVM: x86: Introduce .hv_inject_synthetic_vmexit_post_tlb_flush() nested hook Vitaly Kuznetsov
2022-06-07  9:41   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 16/38] KVM: x86: hyper-v: Introduce kvm_hv_is_tlb_flush_hcall() Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 17/38] KVM: x86: hyper-v: L2 TLB flush Vitaly Kuznetsov
2022-06-07  9:47   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 18/38] KVM: x86: hyper-v: Introduce fast guest_hv_cpuid_has_l2_tlb_flush() check Vitaly Kuznetsov
2022-06-07  9:48   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 19/38] x86/hyperv: Fix 'struct hv_enlightened_vmcs' definition Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 20/38] KVM: nVMX: hyper-v: Cache VP assist page in 'struct kvm_vcpu_hv' Vitaly Kuznetsov
2022-06-07  9:56   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 21/38] KVM: nVMX: hyper-v: Enable L2 TLB flush Vitaly Kuznetsov
2022-06-07 10:02   ` Maxim Levitsky [this message]
2022-06-06  8:36 ` [PATCH v6 22/38] KVM: nSVM: " Vitaly Kuznetsov
2022-06-07 10:02   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 23/38] KVM: x86: Expose Hyper-V L2 TLB flush feature Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 24/38] KVM: selftests: Better XMM read/write helpers Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 25/38] KVM: selftests: Move HYPERV_LINUX_OS_ID definition to a common header Vitaly Kuznetsov
2022-06-07 10:03   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 26/38] KVM: selftests: Move the function doing Hyper-V hypercall " Vitaly Kuznetsov
2022-06-07 10:03   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 27/38] KVM: selftests: Hyper-V PV IPI selftest Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 28/38] KVM: selftests: Fill in vm->vpages_mapped bitmap in virt_map() too Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 29/38] KVM: selftests: Export vm_vaddr_unused_gap() to make it possible to request unmapped ranges Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 30/38] KVM: selftests: Export _vm_get_page_table_entry() Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 31/38] KVM: selftests: Hyper-V PV TLB flush selftest Vitaly Kuznetsov
2022-06-07 12:14   ` Maxim Levitsky
2022-06-06  8:36 ` [PATCH v6 32/38] KVM: selftests: Sync 'struct hv_enlightened_vmcs' definition with hyperv-tlfs.h Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 33/38] KVM: selftests: nVMX: Allocate Hyper-V partition assist page Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 34/38] KVM: selftests: nSVM: Allocate Hyper-V partition assist and VP assist pages Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 35/38] KVM: selftests: Sync 'struct hv_vp_assist_page' definition with hyperv-tlfs.h Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 36/38] KVM: selftests: evmcs_test: Introduce L2 TLB flush test Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 37/38] KVM: selftests: Move Hyper-V VP assist page enablement out of evmcs.h Vitaly Kuznetsov
2022-06-06  8:36 ` [PATCH v6 38/38] KVM: selftests: hyperv_svm_test: Introduce L2 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=33ddebdb9bc7283acd3d70c39e03645580089795.camel@redhat.com \
    --to=mlevitsk@redhat.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikelley@microsoft.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=sidcha@amazon.de \
    --cc=vkuznets@redhat.com \
    --cc=wanpengli@tencent.com \
    --cc=yuan.yao@linux.intel.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.