On Thu, Oct 10, 2019 at 7:55 PM Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote: > > On 10/10/19 09:30, Suleiman Souhlal wrote: > > +kvm_hostclock_enable(struct clocksource *cs) > > +{ > > + pv_timekeeper_enabled = 1; > > + > > + old_vclock_mode = kvm_clock.archdata.vclock_mode; > > + kvm_clock.archdata.vclock_mode = VCLOCK_TSC; > > + return 0; > > +} > > + > > +static void > > +kvm_hostclock_disable(struct clocksource *cs) > > +{ > > + pv_timekeeper_enabled = 0; > > + kvm_clock.archdata.vclock_mode = old_vclock_mode; > > +} > > + > > Why do you poke at kvm_clock? Instead you should add > > .archdata = { .vclock_mode = VCLOCK_TSC }, > > to the kvm_hostclock declaration. Yeah, what I was doing does not make sense. > Please also check that the invariant TSC CPUID bit > CPUID[0x80000007].EDX[8] is set before enabling this feature. Will do. > > Paolo > > > + pvtk = &pv_timekeeper; > > + do { > > + gen = pvtk_read_begin(pvtk); > > + if (!(pv_timekeeper.flags & PVCLOCK_TIMEKEEPER_ENABLED)) > > + return; > > + > > + pvclock_copy_into_read_base(pvtk, &tk->tkr_mono, > > + &pvtk->tkr_mono); > > + pvclock_copy_into_read_base(pvtk, &tk->tkr_raw, &pvtk->tkr_raw); > > + > > + tk->xtime_sec = pvtk->xtime_sec; > > + tk->ktime_sec = pvtk->ktime_sec; > > + tk->wall_to_monotonic.tv_sec = pvtk->wall_to_monotonic_sec; > > + tk->wall_to_monotonic.tv_nsec = pvtk->wall_to_monotonic_nsec; > > + tk->offs_real = pvtk->offs_real; > > + tk->offs_boot = pvtk->offs_boot; > > + tk->offs_tai = pvtk->offs_tai; > > + tk->raw_sec = pvtk->raw_sec; > > + } while (pvtk_read_retry(pvtk, gen)); > > +} > > + > > Should you write an "enabled value" (basically the flags) into pvtk as well? I think we have that already (pvtk->flags). I'll change the if statement above to use pvtk instead of pv_timekeeper. > > +kvm_hostclock_init(void) > > +{ > > + unsigned long pa; > > + > > + pa = __pa(&pv_timekeeper); > > + wrmsrl(MSR_KVM_TIMEKEEPER_EN, pa); > > > As Vitaly said, a new CPUID bit must be defined in > Documentation/virt/kvm/cpuid.txt, and used here. Also please make bit 0 > an enable bit. I think I might not be able to move the enable bit to 0 because we need the generation count (pvclock_timekeeper.gen) to be the first word of the struct due to the way we copy the data to userspace, similarly to how kvm_setup_pvclock_page() does it. I also noticed the comment in kvm_copy_into_pvtk() references the wrong function, which I will fix in the next revision. Thanks for the feedback. -- Suleiman