diff mbox

[v2] kvm: nVMX: fix nested tsc scaling

Message ID 3a9bc47e8a8025f9c84153083d374757a4ca4c44.1471451802.git.pfeiner@google.com (mailing list archive)
State New, archived
Headers show

Commit Message

Peter Feiner Aug. 17, 2016, 4:36 p.m. UTC
When the host supported TSC scaling, L2 would use a TSC multiplier of
0, which causes a VM entry failure. Now L2's TSC uses the same
multiplier as L1.

Signed-off-by: Peter Feiner <pfeiner@google.com>
---

v1->v2: Updated commit message per VMX spec and fixed spelling.
---
 arch/x86/kvm/vmx.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

Comments

Haozhong Zhang Aug. 18, 2016, 7:29 a.m. UTC | #1
On 08/17/16 09:36, Peter Feiner wrote:
> When the host supported TSC scaling, L2 would use a TSC multiplier of
> 0, which causes a VM entry failure. Now L2's TSC uses the same
> multiplier as L1.
> 
> Signed-off-by: Peter Feiner <pfeiner@google.com>
> ---
> 
> v1->v2: Updated commit message per VMX spec and fixed spelling.
> ---
>  arch/x86/kvm/vmx.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
>

Reviewed-by: Haozhong Zhang <haozhong.zhang@intel.com>

> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index a45d858..9d1d0dc 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -2198,6 +2198,12 @@ static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
>  			new.control) != old.control);
>  }
>  
> +static void decache_tsc_multiplier(struct vcpu_vmx *vmx)
> +{
> +	vmx->current_tsc_ratio = vmx->vcpu.arch.tsc_scaling_ratio;
> +	vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
> +}
> +
>  /*
>   * Switches to specified vcpu, until a matching vcpu_put(), but assumes
>   * vcpu mutex is already taken.
> @@ -2256,10 +2262,8 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  
>  	/* Setup TSC multiplier */
>  	if (kvm_has_tsc_control &&
> -	    vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) {
> -		vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio;
> -		vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
> -	}
> +	    vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio)
> +		decache_tsc_multiplier(vmx);
>  
>  	vmx_vcpu_pi_load(vcpu, cpu);
>  	vmx->host_pkru = read_pkru();
> @@ -10011,6 +10015,8 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
>  			vmx->nested.vmcs01_tsc_offset + vmcs12->tsc_offset);
>  	else
>  		vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset);
> +	if (kvm_has_tsc_control)
> +		decache_tsc_multiplier(vmx);
>  
>  	if (enable_vpid) {
>  		/*
> @@ -10767,6 +10773,8 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
>  	else
>  		vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL,
>  			      PIN_BASED_VMX_PREEMPTION_TIMER);
> +	if (kvm_has_tsc_control)
> +		decache_tsc_multiplier(vmx);
>  
>  	/* This is needed for same reason as it was needed in prepare_vmcs02 */
>  	vmx->host_rsp = 0;
> -- 
> 2.8.0.rc3.226.g39d4020
> 
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini Aug. 18, 2016, 8:59 a.m. UTC | #2
On 17/08/2016 18:36, Peter Feiner wrote:
> When the host supported TSC scaling, L2 would use a TSC multiplier of
> 0, which causes a VM entry failure. Now L2's TSC uses the same
> multiplier as L1.
> 
> Signed-off-by: Peter Feiner <pfeiner@google.com>
> ---
> 
> v1->v2: Updated commit message per VMX spec and fixed spelling.
> ---
>  arch/x86/kvm/vmx.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index a45d858..9d1d0dc 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -2198,6 +2198,12 @@ static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
>  			new.control) != old.control);
>  }
>  
> +static void decache_tsc_multiplier(struct vcpu_vmx *vmx)
> +{
> +	vmx->current_tsc_ratio = vmx->vcpu.arch.tsc_scaling_ratio;
> +	vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
> +}
> +
>  /*
>   * Switches to specified vcpu, until a matching vcpu_put(), but assumes
>   * vcpu mutex is already taken.
> @@ -2256,10 +2262,8 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  
>  	/* Setup TSC multiplier */
>  	if (kvm_has_tsc_control &&
> -	    vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) {
> -		vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio;
> -		vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
> -	}
> +	    vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio)
> +		decache_tsc_multiplier(vmx);
>  
>  	vmx_vcpu_pi_load(vcpu, cpu);
>  	vmx->host_pkru = read_pkru();
> @@ -10011,6 +10015,8 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
>  			vmx->nested.vmcs01_tsc_offset + vmcs12->tsc_offset);
>  	else
>  		vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset);
> +	if (kvm_has_tsc_control)
> +		decache_tsc_multiplier(vmx);
>  
>  	if (enable_vpid) {
>  		/*
> @@ -10767,6 +10773,8 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
>  	else
>  		vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL,
>  			      PIN_BASED_VMX_PREEMPTION_TIMER);
> +	if (kvm_has_tsc_control)
> +		decache_tsc_multiplier(vmx);
>  
>  	/* This is needed for same reason as it was needed in prepare_vmcs02 */
>  	vmx->host_rsp = 0;
> 

Queued for 4.8-rc, thanks.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index a45d858..9d1d0dc 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2198,6 +2198,12 @@  static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
 			new.control) != old.control);
 }
 
+static void decache_tsc_multiplier(struct vcpu_vmx *vmx)
+{
+	vmx->current_tsc_ratio = vmx->vcpu.arch.tsc_scaling_ratio;
+	vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
+}
+
 /*
  * Switches to specified vcpu, until a matching vcpu_put(), but assumes
  * vcpu mutex is already taken.
@@ -2256,10 +2262,8 @@  static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 	/* Setup TSC multiplier */
 	if (kvm_has_tsc_control &&
-	    vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) {
-		vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio;
-		vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
-	}
+	    vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio)
+		decache_tsc_multiplier(vmx);
 
 	vmx_vcpu_pi_load(vcpu, cpu);
 	vmx->host_pkru = read_pkru();
@@ -10011,6 +10015,8 @@  static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
 			vmx->nested.vmcs01_tsc_offset + vmcs12->tsc_offset);
 	else
 		vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset);
+	if (kvm_has_tsc_control)
+		decache_tsc_multiplier(vmx);
 
 	if (enable_vpid) {
 		/*
@@ -10767,6 +10773,8 @@  static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
 	else
 		vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL,
 			      PIN_BASED_VMX_PREEMPTION_TIMER);
+	if (kvm_has_tsc_control)
+		decache_tsc_multiplier(vmx);
 
 	/* This is needed for same reason as it was needed in prepare_vmcs02 */
 	vmx->host_rsp = 0;