aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2011-03-25 04:44:47 -0400
committerAvi Kivity <avi@redhat.com>2011-05-11 07:57:04 -0400
commit1e993611d0dc879fde25515dc9867d1cfd4c5137 (patch)
tree39bb576e536d5d3a1194118935c87b5257b04369 /arch/x86/kvm/x86.c
parentfbc0db76b77125e0a5131fb886cbaafa1ec5c525 (diff)
KVM: X86: Let kvm-clock report the right tsc frequency
This patch changes the kvm_guest_time_update function to use TSC frequency the guest actually has for updating its clock. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0d6524fa2aff..78d729174d99 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -969,6 +969,14 @@ static inline int kvm_tsc_changes_freq(void)
969 return ret; 969 return ret;
970} 970}
971 971
972static u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu)
973{
974 if (vcpu->arch.virtual_tsc_khz)
975 return vcpu->arch.virtual_tsc_khz;
976 else
977 return __this_cpu_read(cpu_tsc_khz);
978}
979
972static inline u64 nsec_to_cycles(u64 nsec) 980static inline u64 nsec_to_cycles(u64 nsec)
973{ 981{
974 u64 ret; 982 u64 ret;
@@ -982,20 +990,19 @@ static inline u64 nsec_to_cycles(u64 nsec)
982 return ret; 990 return ret;
983} 991}
984 992
985static void kvm_arch_set_tsc_khz(struct kvm *kvm, u32 this_tsc_khz) 993static void kvm_init_tsc_catchup(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
986{ 994{
987 /* Compute a scale to convert nanoseconds in TSC cycles */ 995 /* Compute a scale to convert nanoseconds in TSC cycles */
988 kvm_get_time_scale(this_tsc_khz, NSEC_PER_SEC / 1000, 996 kvm_get_time_scale(this_tsc_khz, NSEC_PER_SEC / 1000,
989 &kvm->arch.virtual_tsc_shift, 997 &vcpu->arch.tsc_catchup_shift,
990 &kvm->arch.virtual_tsc_mult); 998 &vcpu->arch.tsc_catchup_mult);
991 kvm->arch.virtual_tsc_khz = this_tsc_khz;
992} 999}
993 1000
994static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns) 1001static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
995{ 1002{
996 u64 tsc = pvclock_scale_delta(kernel_ns-vcpu->arch.last_tsc_nsec, 1003 u64 tsc = pvclock_scale_delta(kernel_ns-vcpu->arch.last_tsc_nsec,
997 vcpu->kvm->arch.virtual_tsc_mult, 1004 vcpu->arch.tsc_catchup_mult,
998 vcpu->kvm->arch.virtual_tsc_shift); 1005 vcpu->arch.tsc_catchup_shift);
999 tsc += vcpu->arch.last_tsc_write; 1006 tsc += vcpu->arch.last_tsc_write;
1000 return tsc; 1007 return tsc;
1001} 1008}
@@ -1062,8 +1069,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
1062 local_irq_save(flags); 1069 local_irq_save(flags);
1063 kvm_get_msr(v, MSR_IA32_TSC, &tsc_timestamp); 1070 kvm_get_msr(v, MSR_IA32_TSC, &tsc_timestamp);
1064 kernel_ns = get_kernel_ns(); 1071 kernel_ns = get_kernel_ns();
1065 this_tsc_khz = __this_cpu_read(cpu_tsc_khz); 1072 this_tsc_khz = vcpu_tsc_khz(v);
1066
1067 if (unlikely(this_tsc_khz == 0)) { 1073 if (unlikely(this_tsc_khz == 0)) {
1068 local_irq_restore(flags); 1074 local_irq_restore(flags);
1069 kvm_make_request(KVM_REQ_CLOCK_UPDATE, v); 1075 kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
@@ -6060,8 +6066,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
6060 } 6066 }
6061 vcpu->arch.pio_data = page_address(page); 6067 vcpu->arch.pio_data = page_address(page);
6062 6068
6063 if (!kvm->arch.virtual_tsc_khz) 6069 kvm_init_tsc_catchup(vcpu, max_tsc_khz);
6064 kvm_arch_set_tsc_khz(kvm, max_tsc_khz);
6065 6070
6066 r = kvm_mmu_create(vcpu); 6071 r = kvm_mmu_create(vcpu);
6067 if (r < 0) 6072 if (r < 0)