On 06/09/2019 00:47, Dexuan Cui wrote: > This is needed for hibernation, e.g. when we resume the old kernel, we need > to disable the "current" kernel's TSC page and then resume the old kernel's. > > Signed-off-by: Dexuan Cui <decui@xxxxxxxxxxxxx> > Reviewed-by: Michael Kelley <mikelley@xxxxxxxxxxxxx> I can take this patch if needed. > --- > drivers/clocksource/hyperv_timer.c | 25 +++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > > diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c > index 726a65e..07f4747 100644 > --- a/drivers/clocksource/hyperv_timer.c > +++ b/drivers/clocksource/hyperv_timer.c > @@ -237,12 +237,37 @@ static u64 read_hv_sched_clock_tsc(void) > return read_hv_clock_tsc(NULL) - hv_sched_clock_offset; > } > > +static void suspend_hv_clock_tsc(struct clocksource *arg) > +{ > + u64 tsc_msr; > + > + /* Disable the TSC page */ > + hv_get_reference_tsc(tsc_msr); > + tsc_msr &= ~BIT_ULL(0); > + hv_set_reference_tsc(tsc_msr); > +} > + > + > +static void resume_hv_clock_tsc(struct clocksource *arg) > +{ > + phys_addr_t phys_addr = virt_to_phys(&tsc_pg); > + u64 tsc_msr; > + > + /* Re-enable the TSC page */ > + hv_get_reference_tsc(tsc_msr); > + tsc_msr &= GENMASK_ULL(11, 0); > + tsc_msr |= BIT_ULL(0) | (u64)phys_addr; > + hv_set_reference_tsc(tsc_msr); > +} > + > static struct clocksource hyperv_cs_tsc = { > .name = "hyperv_clocksource_tsc_page", > .rating = 400, > .read = read_hv_clock_tsc, > .mask = CLOCKSOURCE_MASK(64), > .flags = CLOCK_SOURCE_IS_CONTINUOUS, > + .suspend= suspend_hv_clock_tsc, > + .resume = resume_hv_clock_ts,> }; > > static u64 notrace read_hv_clock_msr(struct clocksource *arg) > -- <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | <http://twitter.com/#!/linaroorg> Twitter | <http://www.linaro.org/linaro-blog/> Blog