From nobody Tue Aug 25 00:12:48 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=infradead.org ARC-Seal: i=1; a=rsa-sha256; t=1783113764; cv=none; d=zohomail.com; s=zohoarc; b=LRC3DmxIcQwUhuc1LD304U5m8KJ8xH359l3hDh6HoR8KfDV8bhy82IS78mTvQmP79m/zxZZuH+iOfmC5vdbdLFShD2j6NL+HuN+1o/PKAuIERG6eoy4G915ROAhv/j+SDbCorZ6DHfH18vB/UJuPL7th/OkBR2prsGFQJamjJYI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783113764; h=Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To:Cc; bh=aJbyYvbMlra4ob/lrPKW+13k0D2GomXNtoUlefAARyI=; b=bRY00brpw3iXz98ejBhBXWTQtoNapz8tic8GIMvleQF9laC03rQe6ith02+x9L2CmANhu496cSAdDx1AAfS8ftcP6SFFhfZa6jeq1tP4Y3HiaOSEvz+y5o/oKhPRQfXtJm+Z4cTDmDxwIuD9if4U1w/NcLQdefr7FA1bB57SjQk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1783113764528105.40865435763897; Fri, 3 Jul 2026 14:22:44 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1353759.1609520 (Exim 4.92) (envelope-from ) id 1wflKs-0006jt-2G; Fri, 03 Jul 2026 21:22:10 +0000 Received: by outflank-mailman (output) from mailman id 1353759.1609520; Fri, 03 Jul 2026 21:22:09 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wflKr-0006gm-MO; Fri, 03 Jul 2026 21:22:09 +0000 Received: by outflank-mailman (input) for mailman id 1353759; Fri, 03 Jul 2026 21:22:07 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wflKo-0005nZ-RA for xen-devel@lists.xenproject.org; Fri, 03 Jul 2026 21:22:06 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wflKo-00BXCb-80; Fri, 03 Jul 2026 23:22:06 +0200 Received: from [10.42.69.4] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a4827c7-2eae-0a2a0a5409dd-0a2a4504c5b0-30 for ; Fri, 03 Jul 2026 23:22:06 +0200 Received: from [90.155.50.34] (helo=casper.infradead.org) by tlsNG-ebf023.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a4827f8-a01d-0a2a45040019-5a9b322291dc-3 for ; Fri, 03 Jul 2026 23:22:00 +0200 Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by casper.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1wflKW-0000000AsYA-412E; Fri, 03 Jul 2026 21:21:49 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.99.2 #2 (Red Hat Linux)) id 1wflKW-00000001RP5-3Puq; Fri, 03 Jul 2026 22:21:48 +0100 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=casper.20170209 header.d=infradead.org header.i="@infradead.org" header.h="Sender:Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:To:From" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:To:From:Reply-To: Cc:Content-Type:Content-ID:Content-Description; bh=aJbyYvbMlra4ob/lrPKW+13k0D2GomXNtoUlefAARyI=; b=RUX0gU2BmZAS8Mc7MvtqcjpKaA 4X2GDo7Scxh/FJ1zfZj/ZZUyMDJLZdQtdY/yzpdVZO3bM/BQQLjwYOuR7nQJiiOLfJN8o9bXd0KEm l746azezEjoQE2RTg+hpkWKNpt6Vb5ogWz+nAFg5mQQ0InOMCWqd7vLGDc76I66RSvfzFQY+yfOne tJbmYqYf4y8NcSnh+ymr0gQ0qUnSjLlbP7a9/JcR68N/4qX/IVF7uUKlxqNM4lp3vkFKExekknJt9 4Ipax9FNfOZuryGMT0mvzgT9ncQ6Of+VmYZ1R2nRjr/PYhl4mTt99MskS2b0Erewa9tJ3yQ+Kw6dt ciUtLalA==; From: David Woodhouse To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Vitaly Kuznetsov , Juergen Gross , Boris Ostrovsky , David Woodhouse , Paul Durrant , Jonathan Cameron , Sascha Bischoff , Marc Zyngier , Joey Gouly , Jack Allister , Dongli Zhang , joe.jin@oracle.com, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, xen-devel@lists.xenproject.org, linux-kselftest@vger.kernel.org Subject: [PATCH v6 19/36] KVM: x86: Improve synchronization in kvm_synchronize_tsc() Date: Fri, 3 Jul 2026 22:17:58 +0100 Message-ID: <20260703212145.343527-20-dwmw2@infradead.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260703212145.343527-1-dwmw2@infradead.org> References: <20260703212145.343527-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html X-purgate-ID: tlsNG-ebf023/1783113720-ACB3B1CC-02C39D49/0/0 X-purgate-type: clean X-purgate-size: 3475 X-ZohoMail-DKIM: pass (identity @infradead.org) X-ZM-MESSAGEID: 1783113766529158500 Content-Type: text/plain; charset="utf-8" From: David Woodhouse When synchronizing to an existing TSC (either by explicitly writing zero, or the legacy hack where the TSC is written within one second's worth of the previously written TSC), the last_tsc_write and last_tsc_nsec values were being misrecorded by __kvm_synchronize_tsc(). The *unsynchronized* value of the TSC (perhaps even zero) was being recorded, along with the current time at which kvm_synchronize_tsc() was called. This could cause *subsequent* writes to fail to synchronize correctly. Fix that by resetting {data, ns} to the previous values before passing them to __kvm_synchronize_tsc() when synchronization is detected. Except in the case where the TSC is unstable and *has* to be synthesised from the host clock, in which case attempt to create a nsec/tsc pair which is on the correct line. Furthermore, there were *three* different TSC reads used for calculating the "current" time, all slightly different from each other. Fix that by using kvm_get_time_and_clockread() where possible and using the same host_tsc value in all cases. Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- arch/x86/kvm/x86.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0fa2050f4bd4..ffe5f98a5688 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -203,6 +203,9 @@ module_param(mitigate_smt_rsb, bool, 0444); * usermode, e.g. SYSCALL MSRs and TSC_AUX, can be deferred until the CPU * returns to userspace, i.e. the kernel can run with the guest's value. */ +#ifdef CONFIG_X86_64 +static bool kvm_get_time_and_clockread(s64 *kernel_ns, u64 *tsc_timestamp); +#endif #define KVM_MAX_NR_USER_RETURN_MSRS 16 =20 struct kvm_user_return_msrs { @@ -2854,14 +2857,23 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vc= pu, u64 *user_value) { u64 data =3D user_value ? *user_value : 0; struct kvm *kvm =3D vcpu->kvm; - u64 offset, ns, elapsed; + u64 offset, host_tsc, elapsed; + s64 ns; unsigned long flags; bool matched =3D false; bool synchronizing =3D false; =20 raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags); - offset =3D kvm_compute_l1_tsc_offset(vcpu, rdtsc(), data); - ns =3D get_kvmclock_base_ns(); + +#ifdef CONFIG_X86_64 + if (!kvm_get_time_and_clockread(&ns, &host_tsc)) +#endif + { + host_tsc =3D rdtsc(); + ns =3D get_kvmclock_base_ns(); + } + + offset =3D kvm_compute_l1_tsc_offset(vcpu, host_tsc, data); elapsed =3D ns - kvm->arch.last_tsc_nsec; =20 if (vcpu->arch.virtual_tsc_khz) { @@ -2904,13 +2916,18 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vc= pu, u64 *user_value) */ if (synchronizing && vcpu->arch.virtual_tsc_khz =3D=3D kvm->arch.last_tsc_khz) { - if (!kvm_check_tsc_unstable()) { + /* + * If synchronizing, advance the reference point to "now" + * so the matching window slides forward with each vCPU. + */ + u64 delta =3D nsec_to_cycles(vcpu, elapsed); + + data =3D kvm->arch.cur_tsc_write + delta; + + if (!kvm_check_tsc_unstable()) offset =3D kvm->arch.cur_tsc_offset; - } else { - u64 delta =3D nsec_to_cycles(vcpu, elapsed); - data +=3D delta; - offset =3D kvm_compute_l1_tsc_offset(vcpu, rdtsc(), data); - } + else + offset =3D kvm_compute_l1_tsc_offset(vcpu, host_tsc, data); matched =3D true; } =20 --=20 2.54.0