Skip to content

Commit 1349401

Browse files
dcuidlezcano
authored andcommitted
clocksource/drivers/hyper-v: Suspend/resume Hyper-V clocksource for hibernation
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@microsoft.com> Reviewed-by: Michael Kelley <mikelley@microsoft.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lore.kernel.org/r/1574233946-48377-1-git-send-email-decui@microsoft.com
1 parent 5167c50 commit 1349401

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

drivers/clocksource/hyperv_timer.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,37 @@ static u64 read_hv_sched_clock_tsc(void)
330330
return read_hv_clock_tsc(NULL) - hv_sched_clock_offset;
331331
}
332332

333+
static void suspend_hv_clock_tsc(struct clocksource *arg)
334+
{
335+
u64 tsc_msr;
336+
337+
/* Disable the TSC page */
338+
hv_get_reference_tsc(tsc_msr);
339+
tsc_msr &= ~BIT_ULL(0);
340+
hv_set_reference_tsc(tsc_msr);
341+
}
342+
343+
344+
static void resume_hv_clock_tsc(struct clocksource *arg)
345+
{
346+
phys_addr_t phys_addr = virt_to_phys(&tsc_pg);
347+
u64 tsc_msr;
348+
349+
/* Re-enable the TSC page */
350+
hv_get_reference_tsc(tsc_msr);
351+
tsc_msr &= GENMASK_ULL(11, 0);
352+
tsc_msr |= BIT_ULL(0) | (u64)phys_addr;
353+
hv_set_reference_tsc(tsc_msr);
354+
}
355+
333356
static struct clocksource hyperv_cs_tsc = {
334357
.name = "hyperv_clocksource_tsc_page",
335358
.rating = 400,
336359
.read = read_hv_clock_tsc,
337360
.mask = CLOCKSOURCE_MASK(64),
338361
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
362+
.suspend= suspend_hv_clock_tsc,
363+
.resume = resume_hv_clock_tsc,
339364
};
340365

341366
static u64 notrace read_hv_clock_msr(struct clocksource *arg)

0 commit comments

Comments
 (0)