diff mbox

[xenial,v2,1/8] UBUNTU: SAUCE: hv: make clocksource available for PTP device supporting

Message ID 1498850494-31277-2-git-send-email-marcelo.cerri@canonical.com
State New
Headers show

Commit Message

Marcelo Henrique Cerri June 30, 2017, 7:21 p.m. UTC
BugLink: http://bugs.launchpad.net/bugs/1676635

Make the MSR and TSC clock sources available during the hv_init() and
export them via hyperv_cs in a similar way as the following upstream
commit does:

commit dee863b571b0 ("hv: export current Hyper-V clocksource")

Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
---
 arch/x86/kernel/cpu/mshyperv.c | 23 -----------------------
 drivers/hv/hv.c                | 36 +++++++++++++++++++++++++++++++++++-
 drivers/hv/hyperv_vmbus.h      |  3 +++
 3 files changed, 38 insertions(+), 24 deletions(-)

Comments

Kleber Sacilotto de Souza July 3, 2017, 10:29 a.m. UTC | #1
On 06/30/17 21:21, Marcelo Henrique Cerri wrote:
> BugLink: http://bugs.launchpad.net/bugs/1676635
> 
> Make the MSR and TSC clock sources available during the hv_init() and
> export them via hyperv_cs in a similar way as the following upstream
> commit does:
> 
> commit dee863b571b0 ("hv: export current Hyper-V clocksource")
> 
> Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
> ---
>  arch/x86/kernel/cpu/mshyperv.c | 23 -----------------------
>  drivers/hv/hv.c                | 36 +++++++++++++++++++++++++++++++++++-
>  drivers/hv/hyperv_vmbus.h      |  3 +++
>  3 files changed, 38 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
> index 668df428f8ad..8ffd894d4b8e 100644
> --- a/arch/x86/kernel/cpu/mshyperv.c
> +++ b/arch/x86/kernel/cpu/mshyperv.c
> @@ -134,26 +134,6 @@ static uint32_t  __init ms_hyperv_platform(void)
>  	return 0;
>  }
>  
> -static cycle_t read_hv_clock(struct clocksource *arg)
> -{
> -	cycle_t current_tick;
> -	/*
> -	 * Read the partition counter to get the current tick count. This count
> -	 * is set to 0 when the partition is created and is incremented in
> -	 * 100 nanosecond units.
> -	 */
> -	rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
> -	return current_tick;
> -}
> -
> -static struct clocksource hyperv_cs = {
> -	.name		= "hyperv_clocksource",
> -	.rating		= 400, /* use this when running on Hyperv*/
> -	.read		= read_hv_clock,
> -	.mask		= CLOCKSOURCE_MASK(64),
> -	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
> -};
> -
>  static unsigned char hv_get_nmi_reason(void)
>  {
>  	return 0;
> @@ -209,9 +189,6 @@ static void __init ms_hyperv_init_platform(void)
>  			     "hv_nmi_unknown");
>  #endif
>  
> -	if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
> -		clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100);
> -
>  #ifdef CONFIG_X86_IO_APIC
>  	no_timer_check = 1;
>  #endif
> diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
> index 176ee7d4c243..92fb168a6633 100644
> --- a/drivers/hv/hv.c
> +++ b/drivers/hv/hv.c
> @@ -191,6 +191,28 @@ static struct clocksource hyperv_cs_tsc = {
>  };
>  #endif
>  
> +static cycle_t read_hv_clock_msr(struct clocksource *arg)
> +{
> +	cycle_t current_tick;
> +	/*
> +	 * Read the partition counter to get the current tick count. This count
> +	 * is set to 0 when the partition is created and is incremented in
> +	 * 100 nanosecond units.
> +	 */
> +	rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
> +	return current_tick;
> +}
> +
> +static struct clocksource hyperv_cs_msr = {
> +	.name		= "hyperv_clocksource_msr",
> +	.rating		= 400, /* use this when running on Hyperv*/
> +	.read		= read_hv_clock_msr,
> +	.mask		= CLOCKSOURCE_MASK(64),
> +	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +struct clocksource *hyperv_cs;
> +EXPORT_SYMBOL_GPL(hyperv_cs);
>  
>  /*
>   * hv_init - Main initialization routine.
> @@ -254,9 +276,11 @@ int hv_init(void)
>  
>  		va_tsc = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL);
>  		if (!va_tsc)
> -			goto cleanup;
> +			goto register_msr_cs;
>  		hv_context.tsc_page = va_tsc;
>  
> +		hyperv_cs = &hyperv_cs_tsc;
> +
>  		rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
>  
>  		tsc_msr.enable = 1;
> @@ -266,6 +290,16 @@ int hv_init(void)
>  		clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
>  	}
>  #endif
> +	/*
> +	 * For 32 bit guests just use the MSR based mechanism for reading
> +	 * the partition counter.
> +	 */
> +
> +register_msr_cs:
> +	hyperv_cs = &hyperv_cs_msr;
> +	if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
> +		clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100);
> +
>  	return 0;

As in commit dee863b571b0 ("hv: export current Hyper-V clocksource")
upstream, the label could be placed inside the ifdef to void the
following warning on archs other than X86_64:

/tmp/kernel-kleber-3902cd9-oxu2/build/drivers/hv/hv.c: In function
'hv_init':
/tmp/kernel-kleber-3902cd9-oxu2/build/drivers/hv/hv.c:298:1: warning:
label 'register_msr_cs' defined but not used [-Wunused-label]
 register_msr_cs:
 ^

>  
>  cleanup:
> diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
> index 8d7f865c1133..f75729b5aed6 100644
> --- a/drivers/hv/hyperv_vmbus.h
> +++ b/drivers/hv/hyperv_vmbus.h
> @@ -29,6 +29,7 @@
>  #include <asm/sync_bitops.h>
>  #include <linux/atomic.h>
>  #include <linux/hyperv.h>
> +#include <linux/clocksource.h>
>  
>  /*
>   * Timeout for services such as KVP and fcopy.
> @@ -719,4 +720,6 @@ enum hvutil_device_state {
>  	HVUTIL_DEVICE_DYING,     /* driver unload is in progress */
>  };
>  
> +extern struct clocksource *hyperv_cs;
> +
>  #endif /* _HYPERV_VMBUS_H */
>
Marcelo Henrique Cerri July 3, 2017, 12:32 p.m. UTC | #2
Good catch. I will prepare a v3 with that fixed.
diff mbox

Patch

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 668df428f8ad..8ffd894d4b8e 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -134,26 +134,6 @@  static uint32_t  __init ms_hyperv_platform(void)
 	return 0;
 }
 
-static cycle_t read_hv_clock(struct clocksource *arg)
-{
-	cycle_t current_tick;
-	/*
-	 * Read the partition counter to get the current tick count. This count
-	 * is set to 0 when the partition is created and is incremented in
-	 * 100 nanosecond units.
-	 */
-	rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
-	return current_tick;
-}
-
-static struct clocksource hyperv_cs = {
-	.name		= "hyperv_clocksource",
-	.rating		= 400, /* use this when running on Hyperv*/
-	.read		= read_hv_clock,
-	.mask		= CLOCKSOURCE_MASK(64),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static unsigned char hv_get_nmi_reason(void)
 {
 	return 0;
@@ -209,9 +189,6 @@  static void __init ms_hyperv_init_platform(void)
 			     "hv_nmi_unknown");
 #endif
 
-	if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
-		clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100);
-
 #ifdef CONFIG_X86_IO_APIC
 	no_timer_check = 1;
 #endif
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 176ee7d4c243..92fb168a6633 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -191,6 +191,28 @@  static struct clocksource hyperv_cs_tsc = {
 };
 #endif
 
+static cycle_t read_hv_clock_msr(struct clocksource *arg)
+{
+	cycle_t current_tick;
+	/*
+	 * Read the partition counter to get the current tick count. This count
+	 * is set to 0 when the partition is created and is incremented in
+	 * 100 nanosecond units.
+	 */
+	rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
+	return current_tick;
+}
+
+static struct clocksource hyperv_cs_msr = {
+	.name		= "hyperv_clocksource_msr",
+	.rating		= 400, /* use this when running on Hyperv*/
+	.read		= read_hv_clock_msr,
+	.mask		= CLOCKSOURCE_MASK(64),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+struct clocksource *hyperv_cs;
+EXPORT_SYMBOL_GPL(hyperv_cs);
 
 /*
  * hv_init - Main initialization routine.
@@ -254,9 +276,11 @@  int hv_init(void)
 
 		va_tsc = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL);
 		if (!va_tsc)
-			goto cleanup;
+			goto register_msr_cs;
 		hv_context.tsc_page = va_tsc;
 
+		hyperv_cs = &hyperv_cs_tsc;
+
 		rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
 
 		tsc_msr.enable = 1;
@@ -266,6 +290,16 @@  int hv_init(void)
 		clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
 	}
 #endif
+	/*
+	 * For 32 bit guests just use the MSR based mechanism for reading
+	 * the partition counter.
+	 */
+
+register_msr_cs:
+	hyperv_cs = &hyperv_cs_msr;
+	if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
+		clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100);
+
 	return 0;
 
 cleanup:
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 8d7f865c1133..f75729b5aed6 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -29,6 +29,7 @@ 
 #include <asm/sync_bitops.h>
 #include <linux/atomic.h>
 #include <linux/hyperv.h>
+#include <linux/clocksource.h>
 
 /*
  * Timeout for services such as KVP and fcopy.
@@ -719,4 +720,6 @@  enum hvutil_device_state {
 	HVUTIL_DEVICE_DYING,     /* driver unload is in progress */
 };
 
+extern struct clocksource *hyperv_cs;
+
 #endif /* _HYPERV_VMBUS_H */