On Wed, Sep 13, 2023, David Woodhouse wrote: > On Fri, 2023-08-11 at 15:59 -0700, Sean Christopherson wrote: > > On Tue, Aug 01, 2023, Like Xu wrote: > > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > > > index 278dbd37dab2..eeaf4ad9174d 100644 > > > --- a/arch/x86/kvm/x86.c > > > +++ b/arch/x86/kvm/x86.c > > > @@ -2713,7 +2713,7 @@ static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc, > > > kvm_track_tsc_matching(vcpu); > > > } > > > > > > -static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) > > > +static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data, bool user_initiated) > > > > Rather than pass two somewhat magic values for the KVM-internal call, what about > > making @data a pointer and passing NULL? > > Why change that at all? > > Userspace used to be able to force a sync by writing zero. You are > removing that from the ABI without any explanation about why; No, my suggestion did not remove that from the ABI. A @user_value of '0' would still force synchronization. -static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) +static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 *user_value) { + u64 data = user_value ? *user_value : 0; <=== "*user_value" is '0' struct kvm *kvm = vcpu->kvm; u64 offset, ns, elapsed; unsigned long flags; @@ -2712,14 +2713,17 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) elapsed = ns - kvm->arch.last_tsc_nsec; if (vcpu->arch.virtual_tsc_khz) { + /* + * Force synchronization when creating or hotplugging a vCPU, + * i.e. when the TSC value is '0', to help keep clocks stable. + * If this is NOT a hotplug/creation case, skip synchronization + * on the first write from userspace so as not to misconstrue + * state restoration after live migration as an attempt from + * userspace to synchronize. + */ if (data == 0) { <== "data" still '0', still forces synchronization - /* - * detection of vcpu initialization -- need to sync - * with other vCPUs. This particularly helps to keep - * kvm_clock stable after CPU hotplug - */ synchronizing = true; > it doesn't seem necessary for fixing the original issue. It's necessary for "user_set_tsc" to be an accurate name. The code in v6 yields "user_set_tsc_to_non_zero_value". And I don't think it's just a naming issue, e.g. if userspace writes '0' immediately after creating, and then later writes a small delta, the v6 code wouldn't trigger synchronization because "user_set_tsc" would be left unseft by the write of '0'.