[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v4 14/30] KVM: x86: Use get_kvmclock() in kvm_get_wall_clock_epoch()



From: David Woodhouse <dwmw@xxxxxxxxxxxx>

Now that get_kvmclock() correctly handles TSC scaling and captures both
wallclock and kvmclock from the same TSC reading,
kvm_get_wall_clock_epoch()
can simply call it instead of duplicating the pvclock computation.

This eliminates the last instance of the "definition C" kvmclock
calculation that computed nanoseconds directly from the host TSC
without accounting for guest TSC scaling.

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
---
 arch/x86/kvm/x86.c | 58 +++++++---------------------------------------
 1 file changed, 8 insertions(+), 50 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 09b00906b1de..2bbc2c7ac449 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3491,60 +3491,18 @@ int kvm_guest_time_update(struct kvm_vcpu *v)
  */
 uint64_t kvm_get_wall_clock_epoch(struct kvm *kvm)
 {
-#ifdef CONFIG_X86_64
-       struct pvclock_vcpu_time_info hv_clock;
-       struct kvm_arch *ka = &kvm->arch;
-       unsigned long seq, local_tsc_khz;
-       struct timespec64 ts;
-       uint64_t host_tsc;
-
-       do {
-               seq = read_seqcount_begin(&ka->pvclock_sc);
-
-               local_tsc_khz = 0;
-               if (!ka->use_master_clock)
-                       break;
-
-               /*
-                * The TSC read and the call to get_cpu_tsc_khz() must happen
-                * on the same CPU.
-                */
-               get_cpu();
-
-               local_tsc_khz = get_cpu_tsc_khz();
-
-               if (local_tsc_khz &&
-                   !kvm_get_walltime_and_clockread(&ts, &host_tsc) &&
-                   WARN_ON_ONCE(!read_seqcount_retry(&ka->pvclock_sc, seq)))
-                       local_tsc_khz = 0; /* Fall back to old method */
-
-               put_cpu();
-
-               /*
-                * These values must be snapshotted within the seqcount loop.
-                * After that, it's just mathematics which can happen on any
-                * CPU at any time.
-                */
-               hv_clock.tsc_timestamp = ka->master_cycle_now;
-               hv_clock.system_time = ka->master_kernel_ns + 
ka->kvmclock_offset;
+       struct kvm_clock_data data;
 
-       } while (read_seqcount_retry(&ka->pvclock_sc, seq));
+       get_kvmclock(kvm, &data);
 
        /*
-        * If the conditions were right, and obtaining the wallclock+TSC was
-        * successful, calculate the KVM clock at the corresponding time and
-        * subtract one from the other to get the guest's epoch in nanoseconds
-        * since 1970-01-01.
+        * If get_kvmclock() captured both wallclock and kvmclock from the
+        * same TSC reading, use them for a precise epoch calculation.
         */
-       if (local_tsc_khz) {
-               kvm_get_time_scale(NSEC_PER_SEC, local_tsc_khz * NSEC_PER_USEC,
-                                  &hv_clock.tsc_shift,
-                                  &hv_clock.tsc_to_system_mul);
-               return ts.tv_nsec + NSEC_PER_SEC * ts.tv_sec -
-                       __pvclock_read_cycles(&hv_clock, host_tsc);
-       }
-#endif
-       return ktime_get_real_ns() - get_kvmclock_ns(kvm);
+       if (data.flags & KVM_CLOCK_REALTIME)
+               return data.realtime - data.clock;
+
+       return ktime_get_real_ns() - data.clock;
 }
 
 /*
-- 
2.51.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.