Re: [PATCH 05/11] kvm: x86: Add ability to skip TLB flush when switching CR3

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



----- junaids@xxxxxxxxxx wrote:

> Add a parameter to the set_cr3 handlers to allow skipping the TLB
> flush.
> 
> Signed-off-by: Junaid Shahid <junaids@xxxxxxxxxx>
> ---
>  arch/x86/include/asm/kvm_host.h |  9 ++++++---
>  arch/x86/kvm/mmu.c              |  4 ++--
>  arch/x86/kvm/svm.c              | 17 +++++++++++------
>  arch/x86/kvm/vmx.c              |  7 +++++--
>  4 files changed, 24 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h
> b/arch/x86/include/asm/kvm_host.h
> index e9c56f21ac3c..21eb513205b0 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -330,7 +330,8 @@ struct rsvd_bits_validate {
>   * current mmu mode.
>   */
>  struct kvm_mmu {
> -	void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root);
> +	void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root,
> +			bool skip_tlb_flush);
>  	unsigned long (*get_cr3)(struct kvm_vcpu *vcpu);
>  	u64 (*get_pdptr)(struct kvm_vcpu *vcpu, int index);
>  	int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err,
> @@ -957,7 +958,8 @@ struct kvm_x86_ops {
>  	void (*decache_cr3)(struct kvm_vcpu *vcpu);
>  	void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu);
>  	void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0);
> -	void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3);
> +	void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3,
> +			bool skip_tlb_flush);
>  	int (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4);
>  	void (*set_efer)(struct kvm_vcpu *vcpu, u64 efer);
>  	void (*get_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt);
> @@ -1009,7 +1011,8 @@ struct kvm_x86_ops {
>  	bool (*rdtscp_supported)(void);
>  	bool (*invpcid_supported)(void);
>  
> -	void (*set_tdp_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3);
> +	void (*set_tdp_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3,
> +			    bool skip_tlb_flush);
>  
>  	void (*set_supported_cpuid)(u32 func, struct kvm_cpuid_entry2
> *entry);
>  
> diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> index 0107129d8ed9..611ecc37e5d2 100644
> --- a/arch/x86/kvm/mmu.c
> +++ b/arch/x86/kvm/mmu.c
> @@ -4048,7 +4048,7 @@ static bool fast_cr3_switch(struct kvm_vcpu
> *vcpu, gpa_t old_cr3)
>  			kvm_mmu_sync_roots(vcpu);
>  			__clear_sp_write_flooding_count(
>  						page_header(mmu->root_hpa));
> -			mmu->set_cr3(vcpu, mmu->root_hpa);
> +			mmu->set_cr3(vcpu, mmu->root_hpa, false);
>  			return true;
>  		}
>  	}
> @@ -4774,7 +4774,7 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
>  	if (r)
>  		goto out;
>  	/* set_cr3() should ensure TLB has been flushed */
> -	vcpu->arch.mmu.set_cr3(vcpu, vcpu->arch.mmu.root_hpa);
> +	vcpu->arch.mmu.set_cr3(vcpu, vcpu->arch.mmu.root_hpa, false);
>  out:
>  	return r;
>  }
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index b58787daf9f8..fd8b0dc5136f 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -2855,13 +2855,14 @@ static u64 nested_svm_get_tdp_pdptr(struct
> kvm_vcpu *vcpu, int index)
>  }
>  
>  static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu,
> -				   unsigned long root)
> +				   unsigned long root, bool skip_tlb_flush)
>  {
>  	struct vcpu_svm *svm = to_svm(vcpu);
>  
>  	svm->vmcb->control.nested_cr3 = __sme_set(root);
>  	mark_dirty(svm->vmcb, VMCB_NPT);
> -	svm_flush_tlb(vcpu, true);
> +	if (!skip_tlb_flush)
> +		svm_flush_tlb(vcpu, true);
>  }
>  
>  static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
> @@ -5727,16 +5728,19 @@ static void svm_vcpu_run(struct kvm_vcpu
> *vcpu)
>  }
>  STACK_FRAME_NON_STANDARD(svm_vcpu_run);
>  
> -static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
> +static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root,
> +			bool skip_tlb_flush)
>  {
>  	struct vcpu_svm *svm = to_svm(vcpu);
>  
>  	svm->vmcb->save.cr3 = __sme_set(root);
>  	mark_dirty(svm->vmcb, VMCB_CR);
> -	svm_flush_tlb(vcpu, true);
> +	if (!skip_tlb_flush)
> +		svm_flush_tlb(vcpu, true);
>  }
>  
> -static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root)
> +static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root,
> +			bool skip_tlb_flush)
>  {
>  	struct vcpu_svm *svm = to_svm(vcpu);
>  
> @@ -5747,7 +5751,8 @@ static void set_tdp_cr3(struct kvm_vcpu *vcpu,
> unsigned long root)
>  	svm->vmcb->save.cr3 = kvm_read_cr3(vcpu);
>  	mark_dirty(svm->vmcb, VMCB_CR);
>  
> -	svm_flush_tlb(vcpu, true);
> +	if (!skip_tlb_flush)
> +		svm_flush_tlb(vcpu, true);
>  }
>  
>  static int is_disabled(void)
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index aafcc9881e88..7a73e97bae61 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -4738,7 +4738,8 @@ static u64 construct_eptp(struct kvm_vcpu *vcpu,
> unsigned long root_hpa)
>  	return eptp;
>  }
>  
> -static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
> +static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3,
> +			bool skip_tlb_flush)
>  {
>  	unsigned long guest_cr3;
>  	u64 eptp;
> @@ -4755,7 +4756,9 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu,
> unsigned long cr3)
>  		ept_load_pdptrs(vcpu);
>  	}
>  
> -	vmx_flush_tlb(vcpu, true);
> +	if (!skip_tlb_flush)
> +		vmx_flush_tlb(vcpu, true);
> +
>  	vmcs_writel(GUEST_CR3, guest_cr3);
>  }
>  
> -- 
> 2.17.0.441.gb46fe60e1d-goog

Reviewed-by: Liran Alon <liran.alon@xxxxxxxxxx>




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux