Message ID | 4bfa79c70aad066342940b93f375b247be48e1ad.1471371711.git.pfeiner@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Peter, Thanks for the fix! Comments on the commit message below. On 08/16/16 11:28, Peter Feiner wrote: > When the host supported TSC scaling, L2 would use a TSC multipler of 0 > -- i.e., TSC wouldn't tick in L2. s/multipler/multiplier/ According to VMX TSC scaling spec, a zero TSC multiplier will cause a vm entry failure if VMX TSC scaling is enabled, so L2 guest would not have a chance to start in such circumstance, rather than seeing a stopped TSC. Haozhong > Now L2's TSC runs at the same > frequency as L1's TSC. > > Signed-off-by: Peter Feiner <pfeiner@google.com> > --- > 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; > -- > 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
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;
When the host supported TSC scaling, L2 would use a TSC multipler of 0 -- i.e., TSC wouldn't tick in L2. Now L2's TSC runs at the same frequency as L1's TSC. Signed-off-by: Peter Feiner <pfeiner@google.com> --- arch/x86/kvm/vmx.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)