From: Sean Christopherson <[email protected]> Sent: Wednesday, July 1, 2026 12:32 PM > > Pass in a PV clock's save/restore helpers when configuring sched_clock > instead of relying on each PV clock to manually set the save/restore hooks. > In addition to bringing sanity to the code, this will allow gracefully > "rejecting" a PV sched_clock, e.g. when running as a CoCo guest that has > access to a "secure" TSC. > > No functional change intended. > > Reviewed-by: David Woodhouse <[email protected]> > Signed-off-by: Sean Christopherson <[email protected]>
For the Hyper-V changes, Reviewed-by: Michael Kelley <[email protected]> > --- > arch/x86/include/asm/timer.h | 9 ++++++--- > arch/x86/kernel/cpu/vmware.c | 8 +++----- > arch/x86/kernel/kvmclock.c | 6 +++--- > arch/x86/kernel/tsc.c | 5 ++++- > arch/x86/xen/time.c | 5 ++--- > drivers/clocksource/hyperv_timer.c | 6 ++---- > 6 files changed, 20 insertions(+), 19 deletions(-) > > diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h > index fe41d40a9ae6..e97cd1ae03d1 100644 > --- a/arch/x86/include/asm/timer.h > +++ b/arch/x86/include/asm/timer.h > @@ -14,11 +14,14 @@ extern int no_timer_check; > extern bool using_native_sched_clock(void); > > #ifdef CONFIG_PARAVIRT > -void __paravirt_set_sched_clock(u64 (*func)(void), bool stable); > +void __paravirt_set_sched_clock(u64 (*func)(void), bool stable, > + void (*save)(void), void (*restore)(void)); > > -static inline void paravirt_set_sched_clock(u64 (*func)(void)) > +static inline void paravirt_set_sched_clock(u64 (*func)(void), > + void (*save)(void), > + void (*restore)(void)) > { > - __paravirt_set_sched_clock(func, true); > + __paravirt_set_sched_clock(func, true, save, restore); > } > #endif > > diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c > index 5c1ccaf4a25e..232255279a6e 100644 > --- a/arch/x86/kernel/cpu/vmware.c > +++ b/arch/x86/kernel/cpu/vmware.c > @@ -347,11 +347,9 @@ static void __init vmware_paravirt_ops_setup(void) > > vmware_cyc2ns_setup(); > > - if (vmw_sched_clock) { > - paravirt_set_sched_clock(vmware_sched_clock); > - x86_platform.save_sched_clock_state = x86_init_noop; > - x86_platform.restore_sched_clock_state = x86_init_noop; > - } > + if (vmw_sched_clock) > + paravirt_set_sched_clock(vmware_sched_clock, > + x86_init_noop, x86_init_noop); > > if (vmware_is_stealclock_available()) { > has_steal_clock = true; > diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c > index 07e875738c39..5b9955343199 100644 > --- a/arch/x86/kernel/kvmclock.c > +++ b/arch/x86/kernel/kvmclock.c > @@ -158,7 +158,9 @@ static void kvm_restore_sched_clock_state(void) > static inline void kvm_sched_clock_init(bool stable) > { > kvm_sched_clock_offset = kvm_clock_read(); > - __paravirt_set_sched_clock(kvm_sched_clock_read, stable); > + __paravirt_set_sched_clock(kvm_sched_clock_read, stable, > + kvm_save_sched_clock_state, > + kvm_restore_sched_clock_state); > > pr_info("kvm-clock: using sched offset of %llu cycles", > kvm_sched_clock_offset); > @@ -367,8 +369,6 @@ void __init kvmclock_init(bool prefer_tsc) > #ifdef CONFIG_SMP > x86_cpuinit.early_percpu_clock_init = kvm_setup_secondary_clock; > #endif > - x86_platform.save_sched_clock_state = kvm_save_sched_clock_state; > - x86_platform.restore_sched_clock_state = kvm_restore_sched_clock_state; > kvm_get_preset_lpj(); > > /* > diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c > index 7473dcab4775..83353d643150 100644 > --- a/arch/x86/kernel/tsc.c > +++ b/arch/x86/kernel/tsc.c > @@ -280,12 +280,15 @@ bool using_native_sched_clock(void) > return static_call_query(pv_sched_clock) == native_sched_clock; > } > > -void __paravirt_set_sched_clock(u64 (*func)(void), bool stable) > +void __paravirt_set_sched_clock(u64 (*func)(void), bool stable, > + void (*save)(void), void (*restore)(void)) > { > if (!stable) > clear_sched_clock_stable(); > > static_call_update(pv_sched_clock, func); > + x86_platform.save_sched_clock_state = save; > + x86_platform.restore_sched_clock_state = restore; > } > #else > u64 sched_clock_noinstr(void) __attribute__((alias("native_sched_clock"))); > diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c > index 477441752f40..8cd8bfaf1320 100644 > --- a/arch/x86/xen/time.c > +++ b/arch/x86/xen/time.c > @@ -566,13 +566,12 @@ static void __init xen_init_time_common(void) > { > xen_sched_clock_offset = xen_clocksource_read(); > static_call_update(pv_steal_clock, xen_steal_clock); > - paravirt_set_sched_clock(xen_sched_clock); > + > /* > * Xen has paravirtualized suspend/resume and so doesn't use the common > * x86 sched_clock save/restore hooks. > */ > - x86_platform.save_sched_clock_state = x86_init_noop; > - x86_platform.restore_sched_clock_state = x86_init_noop; > + paravirt_set_sched_clock(xen_sched_clock, x86_init_noop, x86_init_noop); > > x86_init.hyper.get_tsc_khz = xen_tsc_khz; > x86_platform.get_wallclock = xen_get_wallclock; > diff --git a/drivers/clocksource/hyperv_timer.c > b/drivers/clocksource/hyperv_timer.c > index 220668207d19..8ee7a9de0f4f 100644 > --- a/drivers/clocksource/hyperv_timer.c > +++ b/drivers/clocksource/hyperv_timer.c > @@ -570,10 +570,8 @@ static void hv_restore_sched_clock_state(void) > static __always_inline void hv_setup_sched_clock(void *sched_clock) > { > /* We're on x86/x64 *and* using PV ops */ > - paravirt_set_sched_clock(sched_clock); > - > - x86_platform.save_sched_clock_state = hv_save_sched_clock_state; > - x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state; > + paravirt_set_sched_clock(sched_clock, hv_save_sched_clock_state, > + hv_restore_sched_clock_state); > } > #else /* !CONFIG_GENERIC_SCHED_CLOCK && !CONFIG_PARAVIRT */ > static __always_inline void hv_setup_sched_clock(void *sched_clock) {} > -- > 2.55.0.rc0.799.gd6f94ed593-goog >

