aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/vmx.c19
-rw-r--r--arch/x86/kvm/x86.c2
3 files changed, 14 insertions, 8 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index c2a01d0513f5..9efc446b5ac6 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -398,6 +398,7 @@ struct kvm_arch{
398 398
399 unsigned long irq_sources_bitmap; 399 unsigned long irq_sources_bitmap;
400 unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; 400 unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
401 u64 vm_init_tsc;
401}; 402};
402 403
403struct kvm_vm_stat { 404struct kvm_vm_stat {
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index cee81c9a6653..3312047664a4 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -865,11 +865,8 @@ static u64 guest_read_tsc(void)
865 * writes 'guest_tsc' into guest's timestamp counter "register" 865 * writes 'guest_tsc' into guest's timestamp counter "register"
866 * guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc 866 * guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc
867 */ 867 */
868static void guest_write_tsc(u64 guest_tsc) 868static void guest_write_tsc(u64 guest_tsc, u64 host_tsc)
869{ 869{
870 u64 host_tsc;
871
872 rdtscll(host_tsc);
873 vmcs_write64(TSC_OFFSET, guest_tsc - host_tsc); 870 vmcs_write64(TSC_OFFSET, guest_tsc - host_tsc);
874} 871}
875 872
@@ -934,6 +931,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
934{ 931{
935 struct vcpu_vmx *vmx = to_vmx(vcpu); 932 struct vcpu_vmx *vmx = to_vmx(vcpu);
936 struct kvm_msr_entry *msr; 933 struct kvm_msr_entry *msr;
934 u64 host_tsc;
937 int ret = 0; 935 int ret = 0;
938 936
939 switch (msr_index) { 937 switch (msr_index) {
@@ -959,7 +957,8 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
959 vmcs_writel(GUEST_SYSENTER_ESP, data); 957 vmcs_writel(GUEST_SYSENTER_ESP, data);
960 break; 958 break;
961 case MSR_IA32_TIME_STAMP_COUNTER: 959 case MSR_IA32_TIME_STAMP_COUNTER:
962 guest_write_tsc(data); 960 rdtscll(host_tsc);
961 guest_write_tsc(data, host_tsc);
963 break; 962 break;
964 case MSR_P6_PERFCTR0: 963 case MSR_P6_PERFCTR0:
965 case MSR_P6_PERFCTR1: 964 case MSR_P6_PERFCTR1:
@@ -2109,7 +2108,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
2109{ 2108{
2110 u32 host_sysenter_cs, msr_low, msr_high; 2109 u32 host_sysenter_cs, msr_low, msr_high;
2111 u32 junk; 2110 u32 junk;
2112 u64 host_pat; 2111 u64 host_pat, tsc_this, tsc_base;
2113 unsigned long a; 2112 unsigned long a;
2114 struct descriptor_table dt; 2113 struct descriptor_table dt;
2115 int i; 2114 int i;
@@ -2237,6 +2236,12 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
2237 vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL); 2236 vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
2238 vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK); 2237 vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
2239 2238
2239 tsc_base = vmx->vcpu.kvm->arch.vm_init_tsc;
2240 rdtscll(tsc_this);
2241 if (tsc_this < vmx->vcpu.kvm->arch.vm_init_tsc)
2242 tsc_base = tsc_this;
2243
2244 guest_write_tsc(0, tsc_base);
2240 2245
2241 return 0; 2246 return 0;
2242} 2247}
@@ -2328,8 +2333,6 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
2328 vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); 2333 vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0);
2329 vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0); 2334 vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0);
2330 2335
2331 guest_write_tsc(0);
2332
2333 /* Special registers */ 2336 /* Special registers */
2334 vmcs_write64(GUEST_IA32_DEBUGCTL, 0); 2337 vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
2335 2338
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 873602b5edfd..3b2acfd72d7f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4170,6 +4170,8 @@ struct kvm *kvm_arch_create_vm(void)
4170 /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ 4170 /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
4171 set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); 4171 set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap);
4172 4172
4173 rdtscll(kvm->arch.vm_init_tsc);
4174
4173 return kvm; 4175 return kvm;
4174} 4176}
4175 4177