WARN if kvmclock is still suspended when its wallclock is read, i.e. when the kernel reads its persistent clock. The wallclock subtly depends on the BSP's kvmclock being enabled, and returns garbage if kvmclock is disabled. Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> --- arch/x86/kernel/kvmclock.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 319f8b2d0702..0ce23f862cbd 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -52,6 +52,8 @@ static struct pvclock_vsyscall_time_info *hvclock_mem; DEFINE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu); EXPORT_PER_CPU_SYMBOL_GPL(hv_clock_per_cpu); +static bool kvmclock_suspended; + /* * The wallclock is the time of day when we booted. Since then, some time may * have elapsed since the hypervisor wrote the data. So we try to account for @@ -59,6 +61,7 @@ EXPORT_PER_CPU_SYMBOL_GPL(hv_clock_per_cpu); */ static void kvm_get_wallclock(struct timespec64 *now) { + WARN_ON_ONCE(kvmclock_suspended); wrmsrl(msr_kvm_wall_clock, slow_virt_to_phys(&wall_clock)); preempt_disable(); pvclock_read_wallclock(&wall_clock, this_cpu_pvti(), now); @@ -118,6 +121,7 @@ static void kvm_save_sched_clock_state(void) * to the old address prior to reconfiguring kvmclock would clobber * random memory. */ + kvmclock_suspended = true; kvmclock_disable(); } @@ -130,16 +134,19 @@ static void kvm_setup_secondary_clock(void) static void kvm_restore_sched_clock_state(void) { + kvmclock_suspended = false; kvm_register_clock("primary cpu, sched_clock resume"); } static void kvmclock_suspend(struct clocksource *cs) { + kvmclock_suspended = true; kvmclock_disable(); } static void kvmclock_resume(struct clocksource *cs) { + kvmclock_suspended = false; kvm_register_clock("primary cpu, clocksource resume"); } -- 2.48.1.711.g2feabab25a-goog