mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
clocksource/hyperv: Implement read_snapshot() for TSC page clocksource
Implement the read_snapshot() callback for the Hyper-V TSC page clock- source. 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), the hw_csid and hw_cycles are 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 guests under Hyper-V. Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Assisted-by: Kiro:claude-opus-4.6-1m Reviewed-by: Michael Kelley <mhklinux@outlook.com> Link: https://patch.msgid.link/20260604095755.64849-2-dwmw2@infradead.org
This commit is contained in:
parent
ca1ec8bfac
commit
c51100f9e2
|
|
@ -444,6 +444,22 @@ static u64 notrace read_hv_clock_tsc_cs(struct clocksource *arg)
|
|||
return read_hv_clock_tsc();
|
||||
}
|
||||
|
||||
static u64 notrace read_hv_clock_tsc_cs_snapshot(struct clocksource *arg,
|
||||
struct clocksource_hw_snapshot *chs)
|
||||
{
|
||||
u64 time;
|
||||
|
||||
if (hv_read_tsc_page_tsc(tsc_page, &chs->hw_cycles, &time)) {
|
||||
chs->hw_csid = CSID_X86_TSC;
|
||||
} else {
|
||||
chs->hw_cycles = 0;
|
||||
chs->hw_csid = CSID_GENERIC;
|
||||
time = read_hv_clock_msr();
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
static u64 noinstr read_hv_sched_clock_tsc(void)
|
||||
{
|
||||
return (read_hv_clock_tsc() - hv_sched_clock_offset) *
|
||||
|
|
@ -492,18 +508,19 @@ static int hv_cs_enable(struct clocksource *cs)
|
|||
#endif
|
||||
|
||||
static struct clocksource hyperv_cs_tsc = {
|
||||
.name = "hyperv_clocksource_tsc_page",
|
||||
.rating = 500,
|
||||
.read = read_hv_clock_tsc_cs,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
.suspend= suspend_hv_clock_tsc,
|
||||
.resume = resume_hv_clock_tsc,
|
||||
.name = "hyperv_clocksource_tsc_page",
|
||||
.rating = 500,
|
||||
.read = read_hv_clock_tsc_cs,
|
||||
.read_snapshot = read_hv_clock_tsc_cs_snapshot,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
.suspend = suspend_hv_clock_tsc,
|
||||
.resume = resume_hv_clock_tsc,
|
||||
#ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
|
||||
.enable = hv_cs_enable,
|
||||
.vdso_clock_mode = VDSO_CLOCKMODE_HVCLOCK,
|
||||
.enable = hv_cs_enable,
|
||||
.vdso_clock_mode = VDSO_CLOCKMODE_HVCLOCK,
|
||||
#else
|
||||
.vdso_clock_mode = VDSO_CLOCKMODE_NONE,
|
||||
.vdso_clock_mode = VDSO_CLOCKMODE_NONE,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user