diff options
Diffstat (limited to 'drivers/clocksource/hyperv_timer.c')
| -rw-r--r-- | drivers/clocksource/hyperv_timer.c | 45 | 
1 files changed, 16 insertions, 29 deletions
diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c index ba2c79e6a0ee..2317d4e3daaf 100644 --- a/drivers/clocksource/hyperv_timer.c +++ b/drivers/clocksource/hyperv_timer.c @@ -22,6 +22,7 @@  #include <asm/mshyperv.h>  static struct clock_event_device __percpu *hv_clock_event; +static u64 hv_sched_clock_offset __ro_after_init;  /*   * If false, we're using the old mechanism for stimer0 interrupts @@ -212,19 +213,17 @@ EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup);  struct clocksource *hyperv_cs;  EXPORT_SYMBOL_GPL(hyperv_cs); -#ifdef CONFIG_HYPERV_TSCPAGE - -static struct ms_hyperv_tsc_page *tsc_pg; +static struct ms_hyperv_tsc_page tsc_pg __aligned(PAGE_SIZE);  struct ms_hyperv_tsc_page *hv_get_tsc_page(void)  { -	return tsc_pg; +	return &tsc_pg;  }  EXPORT_SYMBOL_GPL(hv_get_tsc_page); -static u64 notrace read_hv_sched_clock_tsc(void) +static u64 notrace read_hv_clock_tsc(struct clocksource *arg)  { -	u64 current_tick = hv_read_tsc_page(tsc_pg); +	u64 current_tick = hv_read_tsc_page(&tsc_pg);  	if (current_tick == U64_MAX)  		hv_get_time_ref_count(current_tick); @@ -232,9 +231,9 @@ static u64 notrace read_hv_sched_clock_tsc(void)  	return current_tick;  } -static u64 read_hv_clock_tsc(struct clocksource *arg) +static u64 read_hv_sched_clock_tsc(void)  { -	return read_hv_sched_clock_tsc(); +	return read_hv_clock_tsc(NULL) - hv_sched_clock_offset;  }  static struct clocksource hyperv_cs_tsc = { @@ -244,9 +243,8 @@ static struct clocksource hyperv_cs_tsc = {  	.mask	= CLOCKSOURCE_MASK(64),  	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,  }; -#endif -static u64 notrace read_hv_sched_clock_msr(void) +static u64 notrace read_hv_clock_msr(struct clocksource *arg)  {  	u64 current_tick;  	/* @@ -258,9 +256,9 @@ static u64 notrace read_hv_sched_clock_msr(void)  	return current_tick;  } -static u64 read_hv_clock_msr(struct clocksource *arg) +static u64 read_hv_sched_clock_msr(void)  { -	return read_hv_sched_clock_msr(); +	return read_hv_clock_msr(NULL) - hv_sched_clock_offset;  }  static struct clocksource hyperv_cs_msr = { @@ -271,7 +269,6 @@ static struct clocksource hyperv_cs_msr = {  	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,  }; -#ifdef CONFIG_HYPERV_TSCPAGE  static bool __init hv_init_tsc_clocksource(void)  {  	u64		tsc_msr; @@ -280,12 +277,8 @@ static bool __init hv_init_tsc_clocksource(void)  	if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))  		return false; -	tsc_pg = vmalloc(PAGE_SIZE); -	if (!tsc_pg) -		return false; -  	hyperv_cs = &hyperv_cs_tsc; -	phys_addr = page_to_phys(vmalloc_to_page(tsc_pg)); +	phys_addr = virt_to_phys(&tsc_pg);  	/*  	 * The Hyper-V TLFS specifies to preserve the value of reserved @@ -302,17 +295,11 @@ static bool __init hv_init_tsc_clocksource(void)  	hv_set_clocksource_vdso(hyperv_cs_tsc);  	clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100); -	/* sched_clock_register is needed on ARM64 but is a no-op on x86 */ -	sched_clock_register(read_hv_sched_clock_tsc, 64, HV_CLOCK_HZ); +	hv_sched_clock_offset = hyperv_cs->read(hyperv_cs); +	hv_setup_sched_clock(read_hv_sched_clock_tsc); +  	return true;  } -#else -static bool __init hv_init_tsc_clocksource(void) -{ -	return false; -} -#endif -  void __init hv_init_clocksource(void)  { @@ -333,7 +320,7 @@ void __init hv_init_clocksource(void)  	hyperv_cs = &hyperv_cs_msr;  	clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100); -	/* sched_clock_register is needed on ARM64 but is a no-op on x86 */ -	sched_clock_register(read_hv_sched_clock_msr, 64, HV_CLOCK_HZ); +	hv_sched_clock_offset = hyperv_cs->read(hyperv_cs); +	hv_setup_sched_clock(read_hv_sched_clock_msr);  }  EXPORT_SYMBOL_GPL(hv_init_clocksource);  |