diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2011-03-25 04:44:47 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-11 07:57:04 -0400 |
commit | 1e993611d0dc879fde25515dc9867d1cfd4c5137 (patch) | |
tree | 39bb576e536d5d3a1194118935c87b5257b04369 /arch/x86/kvm/x86.c | |
parent | fbc0db76b77125e0a5131fb886cbaafa1ec5c525 (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.c | 25 |
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 | ||
972 | static 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 | |||
972 | static inline u64 nsec_to_cycles(u64 nsec) | 980 | static 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 | ||
985 | static void kvm_arch_set_tsc_khz(struct kvm *kvm, u32 this_tsc_khz) | 993 | static 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 | ||
994 | static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns) | 1001 | static 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) |