From 725ac7c54935bbff858092e2db302afe88062162 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Tue, 9 May 2017 12:39:18 -0700
Subject: [PATCH] x86/vmware: pv-ops clocksource

---
 arch/x86/kernel/cpu/vmware.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 1f22ed3..1eb5631 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -90,6 +90,27 @@ static int vmw_sched_clock __initdata = 1;
 static DEFINE_PER_CPU_DECRYPTED(struct vmware_steal_time, steal_time) __aligned(64);
 static int has_steal_clock = 0;
 
+static u64 vmware_clock_get_cycles(struct clocksource *cs)
+{
+	return (u64)rdtsc_ordered();
+}
+
+static struct clocksource clocksource_vmware = {
+	.name = "vmware-clock",
+	.read = vmware_clock_get_cycles,
+	.rating = 400,
+	.mask = CLOCKSOURCE_MASK(64),
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+	.archdata = { .vclock_mode = VCLOCK_TSC },
+};
+
+/* We want to use clocksource_vmware from the beginning to avoid drifting in
+   monotonic clock */
+struct clocksource * __init clocksource_default_clock(void)
+{
+	return &clocksource_vmware;
+}
+
 static __init int setup_vmw_sched_clock(char *s)
 {
 	vmw_sched_clock = 0;
@@ -313,6 +334,7 @@ static void __init vmware_paravirt_ops_setup(void)
 		vmware_guest_cpu_init();
 #endif
 	}
+	clocksource_register_khz(&clocksource_vmware, vmware_tsc_khz);
 }
 #else
 #define vmware_paravirt_ops_setup() do {} while (0)