drivers: hv: Decouple Hyper-V clock/timer code from VMbus drivers
authorMichael Kelley <mikelley@microsoft.com>
Wed, 14 Jul 2021 00:01:46 +0000 (17:01 -0700)
committerWei Liu <wei.liu@kernel.org>
Mon, 19 Jul 2021 09:24:28 +0000 (09:24 +0000)
Hyper-V clock/timer code in hyperv_timer.c is mostly independent from
other VMbus drivers, but building for ARM64 without hyperv_timer.c
shows some remaining entanglements.  A default implementation of
hv_read_reference_counter can just read a Hyper-V synthetic register
and be independent of hyperv_timer.c, so move this code out and into
hv_common.c. Then it can be used by the timesync driver even if
hyperv_timer.c isn't built on a particular architecture.  If
hyperv_timer.c *is* built, it can override with a faster implementation.

Also provide stubs for stimer functions called by the VMbus driver when
hyperv_timer.c isn't built.

No functional changes.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/1626220906-22629-1-git-send-email-mikelley@microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
drivers/clocksource/hyperv_timer.c
drivers/hv/hv_common.c
drivers/hv/hv_util.c
include/asm-generic/mshyperv.h
include/clocksource/hyperv_timer.h

index d6ece7bbce894b0f9d42da6922178f9341bbb658..ff188ab68496e0d646f5e15ea8c5b0ef2e321c83 100644 (file)
@@ -361,9 +361,6 @@ EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup);
  * Hyper-V and 32-bit x86.  The TSC reference page version is preferred.
  */
 
-u64 (*hv_read_reference_counter)(void);
-EXPORT_SYMBOL_GPL(hv_read_reference_counter);
-
 static union {
        struct ms_hyperv_tsc_page page;
        u8 reserved[PAGE_SIZE];
index 46658de78050e5140f38c1b5856023b65c8a36ae..c0d9048a411236cc3fae0f403a1a4b61e879811e 100644 (file)
@@ -222,6 +222,20 @@ bool hv_is_hibernation_supported(void)
 }
 EXPORT_SYMBOL_GPL(hv_is_hibernation_supported);
 
+/*
+ * Default function to read the Hyper-V reference counter, independent
+ * of whether Hyper-V enlightened clocks/timers are being used. But on
+ * architectures where it is used, Hyper-V enlightenment code in
+ * hyperv_timer.c may override this function.
+ */
+static u64 __hv_read_ref_counter(void)
+{
+       return hv_get_register(HV_REGISTER_TIME_REF_COUNT);
+}
+
+u64 (*hv_read_reference_counter)(void) = __hv_read_ref_counter;
+EXPORT_SYMBOL_GPL(hv_read_reference_counter);
+
 /* These __weak functions provide default "no-op" behavior and
  * may be overridden by architecture specific versions. Architectures
  * for which the default "no-op" behavior is sufficient can leave
index 136576cba26f5687272ea18e6c969d6bbd411238..835e6039c186789433f54562378f43df8851fabb 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/hyperv.h>
 #include <linux/clockchips.h>
 #include <linux/ptp_clock_kernel.h>
-#include <clocksource/hyperv_timer.h>
 #include <asm/mshyperv.h>
 
 #include "hyperv_vmbus.h"
@@ -735,10 +734,6 @@ static struct ptp_clock *hv_ptp_clock;
 
 static int hv_timesync_init(struct hv_util_service *srv)
 {
-       /* TimeSync requires Hyper-V clocksource. */
-       if (!hv_read_reference_counter)
-               return -ENODEV;
-
        spin_lock_init(&host_ts.lock);
 
        INIT_WORK(&adj_time_work, hv_set_host_time);
index 60cdff3e22520a98f0dcdff8759b646ba6d5da56..c1ab6a6e72b535a0cecdc29a1a55dd6e65650f78 100644 (file)
@@ -167,6 +167,8 @@ extern bool hv_root_partition;
 extern u32 *hv_vp_index;
 extern u32 hv_max_vp_index;
 
+extern u64 (*hv_read_reference_counter)(void);
+
 /* Sentinel value for an uninitialized entry in hv_vp_index array */
 #define VP_INVAL       U32_MAX
 
index b6774aa5a4b865fa4b0b32c20d7315bf3cf96ea4..b3f5d73ae1d6db1977d7bcfb36c90ad147ec488f 100644 (file)
@@ -20,6 +20,8 @@
 #define HV_MAX_MAX_DELTA_TICKS 0xffffffff
 #define HV_MIN_DELTA_TICKS 1
 
+#ifdef CONFIG_HYPERV_TIMER
+
 /* Routines called by the VMbus driver */
 extern int hv_stimer_alloc(bool have_percpu_irqs);
 extern int hv_stimer_cleanup(unsigned int cpu);
@@ -28,8 +30,6 @@ extern void hv_stimer_legacy_cleanup(unsigned int cpu);
 extern void hv_stimer_global_cleanup(void);
 extern void hv_stimer0_isr(void);
 
-#ifdef CONFIG_HYPERV_TIMER
-extern u64 (*hv_read_reference_counter)(void);
 extern void hv_init_clocksource(void);
 
 extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
@@ -100,6 +100,13 @@ static inline u64 hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg,
 {
        return U64_MAX;
 }
+
+static inline int hv_stimer_cleanup(unsigned int cpu) { return 0; }
+static inline void hv_stimer_legacy_init(unsigned int cpu, int sint) {}
+static inline void hv_stimer_legacy_cleanup(unsigned int cpu) {}
+static inline void hv_stimer_global_cleanup(void) {}
+static inline void hv_stimer0_isr(void) {}
+
 #endif /* CONFIG_HYPERV_TIMER */
 
 #endif