[RFC PATCH 2/8] clocksource/hyperv: Implement read_raw() for TSC page clocksource
From: David Woodhouse
Date: Tue May 26 2026 - 19:07:43 EST
From: David Woodhouse <dwmw@xxxxxxxxxxxx>
Implement the read_raw() callback for the Hyper-V TSC page
clocksource. This returns the derived 10MHz reference time (for
timekeeping) while also providing the raw TSC value that was used
to compute it.
When the TSC page is valid, hv_read_tsc_page_tsc() atomically
captures both values from a single RDTSC inside the sequence-counter
protected read. When the TSC page is invalid (sequence == 0), raw is
set to zero indicating no value is available.
This enables ktime_get_snapshot_id() to provide the raw TSC to
consumers like KVM's master clock when running nested on Hyper-V.
Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
Assisted-by: Kiro:claude-opus-4.6-1m
---
drivers/clocksource/hyperv_timer.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index e9f5034a1bc8..c5ae01fdbd8e 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -444,6 +444,18 @@ static u64 notrace read_hv_clock_tsc_cs(struct clocksource *arg)
return read_hv_clock_tsc();
}
+static u64 notrace read_hv_clock_tsc_cs_raw(struct clocksource *arg, u64 *raw)
+{
+ u64 time;
+
+ if (!hv_read_tsc_page_tsc(tsc_page, raw, &time)) {
+ time = read_hv_clock_msr();
+ *raw = 0;
+ }
+
+ return time;
+}
+
static u64 noinstr read_hv_sched_clock_tsc(void)
{
return (read_hv_clock_tsc() - hv_sched_clock_offset) *
@@ -495,6 +507,8 @@ static struct clocksource hyperv_cs_tsc = {
.name = "hyperv_clocksource_tsc_page",
.rating = 500,
.read = read_hv_clock_tsc_cs,
+ .read_raw = read_hv_clock_tsc_cs_raw,
+ .raw_csid = CSID_X86_TSC,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
.suspend= suspend_hv_clock_tsc,
--
2.54.0