All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Xiaoyao Li <xiaoyao.li@linux.intel.com>
Cc: kvm@vger.kernel.org, "Paolo Bonzini" <pbonzini@redhat.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	"Thomas Gleixner" <tglx@linutronix.de>,
	"Ingo Molnar" <mingo@redhat.com>,
	"Borislav Petkov" <bp@alien8.de>,
	"H. Peter Anvin" <hpa@zytor.com>,
	linux-kernel@vger.kernel.org, chao.gao@intel.com
Subject: Re: [PATCH v2 2/2] kvm/vmx: Using hardware cpuid faulting to avoid emulation overhead
Date: Mon, 18 Mar 2019 09:38:32 -0700	[thread overview]
Message-ID: <20190318163832.GB13528@linux.intel.com> (raw)
In-Reply-To: <20190318114324.14198-3-xiaoyao.li@linux.intel.com>

On Mon, Mar 18, 2019 at 07:43:24PM +0800, Xiaoyao Li wrote:
> Current cpuid faulting of guest is purely emulated in kvm, which exploits
> CPUID vm exit to inject #GP to guest. However, if host hardware cpu has
> X86_FEATURE_CPUID_FAULT, we can just use the hardware cpuid faulting for
> guest to avoid the vm exit overhead.

Heh, I obviously didn't look at this patch before responding to patch 1/2.

> Note: cpuid faulting takes higher priority over CPUID instruction vm
> exit (Intel SDM vol3.25.1.1).
> 
> Since cpuid faulting only exists on some Intel's cpu, just apply this
> optimization to vmx.
> 
> Signed-off-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  2 ++
>  arch/x86/kvm/vmx/vmx.c          | 19 +++++++++++++++----
>  arch/x86/kvm/x86.c              | 15 ++++++++++++---
>  3 files changed, 29 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index ce79d7bfe1fd..14cad587b804 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1339,6 +1339,8 @@ void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
>  void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l);
>  int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr);
>  
> +int kvm_supported_msr_misc_features_enables(struct kvm_vcpu *vcpu, u64 data);
> +
>  int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr);
>  int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr);
>  
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 2c59e0209e36..6b413e471dca 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -1037,7 +1037,7 @@ static void pt_guest_exit(struct vcpu_vmx *vmx)
>  
>  static void vmx_save_host_cpuid_fault(struct vcpu_vmx *vmx)
>  {
> -	u64 host_val;
> +	u64 host_val, guest_val;
>  
>  	if (!boot_cpu_has(X86_FEATURE_CPUID_FAULT))
>  		return;
> @@ -1045,10 +1045,12 @@ static void vmx_save_host_cpuid_fault(struct vcpu_vmx *vmx)
>  	rdmsrl(MSR_MISC_FEATURES_ENABLES, host_val);
>  	vmx->host_msr_misc_features_enables = host_val;
>  
> -	/* clear cpuid fault bit to avoid it leak to guest */
> -	if (host_val & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT) {
> +	guest_val = vmx->vcpu.arch.msr_misc_features_enables;
> +
> +	/* we can use the hardware cpuid faulting to avoid emulation overhead */
> +	if ((host_val ^ guest_val) & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT) {
>  		wrmsrl(MSR_MISC_FEATURES_ENABLES,
> -		       host_val & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT);
> +		       host_val ^ MSR_MISC_FEATURES_ENABLES_CPUID_FAULT);
>  	}
>  }
>  
> @@ -2057,6 +2059,15 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  		else
>  			vmx->pt_desc.guest.addr_a[index / 2] = data;
>  		break;
> +	case MSR_MISC_FEATURES_ENABLES:
> +		if (!kvm_supported_msr_misc_features_enables(vcpu, data))
> +			return 1;
> +		if (boot_cpu_has(X86_FEATURE_CPUID_FAULT)) {
> +			if (vmx->loaded_cpu_state)

No need for two separate if statements.  And assuming we're checking the
existing shadow value when loading guest/host state, the WRMSR should
only be done if the host's value is non-zero.

> +				wrmsrl(MSR_MISC_FEATURES_ENABLES, data);
> +		}
> +		vcpu->arch.msr_misc_features_enables = data;
> +		break;
>  	case MSR_TSC_AUX:
>  		if (!msr_info->host_initiated &&
>  		    !guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP))
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 434ec113cc79..33a8c95b2f2e 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2449,6 +2449,17 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
>  		&vcpu->arch.st.steal, sizeof(struct kvm_steal_time));
>  }
>  
> +int kvm_supported_msr_misc_features_enables(struct kvm_vcpu *vcpu, u64 data)
> +{
> +	if (data & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT ||
> +	    (data & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> +	     !supports_cpuid_fault(vcpu)))
> +		return 0;
> +	else
> +		return 1;
> +}
> +EXPORT_SYMBOL_GPL(kvm_supported_msr_misc_features_enables);
> +
>  int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  {
>  	bool pr = false;
> @@ -2669,9 +2680,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  		vcpu->arch.msr_platform_info = data;
>  		break;
>  	case MSR_MISC_FEATURES_ENABLES:
> -		if (data & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT ||
> -		    (data & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> -		     !supports_cpuid_fault(vcpu)))
> +		if (!kvm_supported_msr_misc_features_enables(vcpu, data))
>  			return 1;
>  		vcpu->arch.msr_misc_features_enables = data;
>  		break;
> -- 
> 2.19.1
> 

  reply	other threads:[~2019-03-18 16:38 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-18 11:43 [PATCH v2 0/2] Avoid cpuid faulting leaking and one optimization Xiaoyao Li
2019-03-18 11:43 ` [PATCH v2 1/2] kvm/vmx: avoid CPUID faulting leaking to guest Xiaoyao Li
2019-03-18 16:23   ` Sean Christopherson
     [not found]     ` <676340c3796e588900658475dbbcb7d1c6e8ecfe.camel@linux.intel.com>
2019-03-19 14:18       ` Sean Christopherson
2019-03-18 11:43 ` [PATCH v2 2/2] kvm/vmx: Using hardware cpuid faulting to avoid emulation overhead Xiaoyao Li
2019-03-18 16:38   ` Sean Christopherson [this message]
2019-03-19  4:37     ` Xiaoyao Li
2019-03-19 14:28       ` Sean Christopherson
2019-03-19 17:51         ` Xiaoyao Li
2019-03-20  0:09           ` Sean Christopherson
2019-03-20 13:26             ` Xiaoyao Li

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=20190318163832.GB13528@linux.intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=bp@alien8.de \
    --cc=chao.gao@intel.com \
    --cc=hpa@zytor.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=xiaoyao.li@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.