From: sashiko-bot@kernel.org
To: "David Woodhouse" <dwmw2@infradead.org>, kvm@vger.kernel.org
Subject: Re: [PATCH v12 07/24] KVM: x86: Avoid redundant masterclock updates from multiple vCPUs
Date: Mon, 09 Nov 2026 01:53:17 +0000 [thread overview]
Message-ID: <sashiko-outbox-204330@kernel.org> (raw)
In-Reply-To: <20261109012112.3415328-8-dwmw2@infradead.org>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] KVM: x86: premature kvm_guest_time_update() in
__kvm_start_pvclock_update()
- [Medium] KVM: x86: race in __kvm_start_pvclock_update() lets vCPUs
skip clock update
--
commit 562c60eff9324c1010b59724e91ff05f45041197
Author: David Woodhouse <dwmw@amazon.co.uk>
KVM: x86: Avoid redundant masterclock updates from multiple vCPUs
This commit deduplicates VM-wide masterclock updates by clearing pending
KVM_REQ_MASTERCLOCK_UPDATE bits across all vCPUs inside
__kvm_start_pvclock_update() under tsc_write_lock and bailing out if
another vCPU already serviced the request.
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 0348f24cfd1d3..290a3c3bb44fc 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -1733,10 +1733,51 @@ static void kvm_make_mclock_inprogress_request(struct kvm *kvm)
> kvm_make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS);
> }
>
> -static void __kvm_start_pvclock_update(struct kvm *kvm)
> +static void kvm_clear_mclock_inprogress_request(struct kvm *kvm)
> {
> + struct kvm_vcpu *vcpu;
> + unsigned long i;
> +
> + kvm_for_each_vcpu(i, vcpu, kvm)
> + kvm_clear_request(KVM_REQ_MCLOCK_INPROGRESS, vcpu);
> +}
> +
> +static bool __kvm_start_pvclock_update(struct kvm *kvm, struct kvm_vcpu *requesting_vcpu)
> +{
> + struct kvm_vcpu *vcpu;
> + unsigned long i;
> +
> raw_spin_lock_irq(&kvm->arch.tsc_write_lock);
> +
> + /*
> + * If another vCPU already did the update while we were waiting
> + * for the lock, our request will have been cleared. Bail out,
> + * clearing the KVM_REQ_MCLOCK_INPROGRESS kicks made on entry to
> + * kvm_update_masterclock() so vCPUs can enter the guest again.
> + *
> + * Clearing them VM-wide can also clear kicks just made by yet
> + * another updater still waiting for tsc_write_lock, letting
> + * vCPUs run while that update is in flight. That is not new:
> + * kvm_end_pvclock_update() has always cleared the request on
> + * every vCPU regardless of which updater made it. The window is
> + * harmless to readers (the pvclock seqcount covers the master
> + * state); a vCPU which slips in runs on the old snapshot until
> + * its KVM_REQ_CLOCK_UPDATE is serviced, exactly as if it had
> + * entered just before the update began.
> + */
> + if (requesting_vcpu &&
> + !kvm_test_request(KVM_REQ_MASTERCLOCK_UPDATE, requesting_vcpu)) {
> + kvm_clear_mclock_inprogress_request(kvm);
> + raw_spin_unlock_irq(&kvm->arch.tsc_write_lock);
> + return false;
> + }
[Severity: Medium]
Can clearing KVM_REQ_MCLOCK_INPROGRESS while another updater is waiting on
tsc_write_lock allow a third vCPU whose KVM_REQ_MASTERCLOCK_UPDATE was
consumed to enter the guest before the update finishes, and stay in guest
mode without servicing KVM_REQ_CLOCK_UPDATE?
Because kvm_make_mclock_inprogress_request() runs before acquiring
tsc_write_lock, an updater bailing out (or finishing in
kvm_end_pvclock_update()) can clear the KVM_REQ_MCLOCK_INPROGRESS bits just
set by a second updater waiting on the lock. When that second updater
acquires tsc_write_lock, it clears KVM_REQ_MASTERCLOCK_UPDATE on all vCPUs
before setting KVM_REQ_CLOCK_UPDATE in kvm_end_pvclock_update():
CPU0 (vcpu0) CPU1 (vcpu1) CPU2 (vcpu2)
------------ ------------ ------------
kvm_update_masterclock()
/* cleared by prior
updater */
kvm_update_masterclock()
kvm_make_mclock_inprogress_request()
__kvm_start_pvclock_update()
kvm_clear_mclock_inprogress_request()
unlock(tsc_write_lock)
__kvm_start_pvclock_update()
lock(tsc_write_lock)
kvm_clear_request(MASTERCLOCK, vcpu2)
vcpu_enter_guest()
test(MASTERCLOCK) -> 0
check(CLOCK_UPDATE) -> 0
exit_request() -> 0
/* enters guest */
write_seqcount_begin(&pvclock_sc)
pvclock_update_vm_gtod_copy()
kvm_end_pvclock_update()
kvm_make_request(CLOCK_UPDATE, vcpu2)
/* no kick */
vcpu_enter_guest() only reads pvclock_sc inside kvm_guest_time_update()
when KVM_REQ_CLOCK_UPDATE is set. If vcpu2 only had
KVM_REQ_MASTERCLOCK_UPDATE pending (for example, after enabling
HV_X64_MSR_REFERENCE_TSC in kvm_hv_set_msr_pw()), it skips both
kvm_update_masterclock() and kvm_guest_time_update(), sees
KVM_REQ_MCLOCK_INPROGRESS cleared, and enters the guest before
kvm_hv_setup_tsc_page() or pvclock_update_vm_gtod_copy() has run.
Unlike a vCPU that entered before the update began and was kicked by
kvm_make_mclock_inprogress_request(), kvm_end_pvclock_update() calls
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu) without kicking, so vcpu2
remains in guest mode with stale clock state until an unrelated VM-exit.
> +
> + /* The update is VM-wide; prevent other vCPUs from redoing it. */
> + kvm_for_each_vcpu(i, vcpu, kvm)
> + kvm_clear_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu);
> +
> write_seqcount_begin(&kvm->arch.pvclock_sc);
> + return true;
> }
[Severity: Medium]
Does clearing KVM_REQ_MASTERCLOCK_UPDATE on all vCPUs before
write_seqcount_begin(&kvm->arch.pvclock_sc) allow another vCPU to run
kvm_guest_time_update() against the stale masterclock snapshot?
When both KVM_REQ_MASTERCLOCK_UPDATE and KVM_REQ_CLOCK_UPDATE are pending
on vcpu1 (such as after kvm_write_system_time() or __kvm_synchronize_tsc()),
clearing KVM_REQ_MASTERCLOCK_UPDATE before opening pvclock_sc lets vcpu1
skip kvm_update_masterclock() without waiting on tsc_write_lock and read
pvclock_sc before the write section begins:
CPU0 (vcpu0) CPU1 (vcpu1)
------------ ------------
__kvm_start_pvclock_update()
kvm_clear_request(MASTERCLOCK, vcpu1)
vcpu_enter_guest()
test(MASTERCLOCK) -> false
check(CLOCK_UPDATE) -> true
kvm_guest_time_update()
read_seqcount_begin(&pvclock_sc)
/* reads stale masterclock */
kvm_hv_setup_tsc_page()
write_seqcount_begin(&pvclock_sc)
pvclock_update_vm_gtod_copy()
kvm_end_pvclock_update()
In addition to writing stale pvclock data to guest memory, the premature
kvm_hv_setup_tsc_page() call consumes HV_TSC_PAGE_HOST_CHANGED or
HV_TSC_PAGE_GUEST_CHANGED using the pre-update state and transitions
hv_tsc_page_status to HV_TSC_PAGE_SET or HV_TSC_PAGE_BROKEN:
arch/x86/kvm/hyperv.c:kvm_hv_setup_tsc_page() {
...
if (hv->hv_tsc_page_status == HV_TSC_PAGE_BROKEN ||
hv->hv_tsc_page_status == HV_TSC_PAGE_SET ||
hv->hv_tsc_page_status == HV_TSC_PAGE_UNSET)
return;
...
}
When kvm_end_pvclock_update() subsequently requests KVM_REQ_CLOCK_UPDATE,
kvm_hv_setup_tsc_page() returns early and leaves the Hyper-V reference TSC
page stuck with stale parameters or permanently disabled. Opening
pvclock_sc with write_seqcount_begin() before the kvm_for_each_vcpu() loop
that clears KVM_REQ_MASTERCLOCK_UPDATE would ensure any vCPU that sees its
request cleared already observes the open seqcount.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109012112.3415328-1-dwmw2@infradead.org?part=7
next prev parent reply other threads:[~2026-11-09 1:53 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 1:20 [PATCH v12 00/24] KVM: x86: Cleaning up the KVM clock mess, part 2 David Woodhouse
2026-11-09 1:20 ` [PATCH v12 01/24] KVM: x86: Improve synchronization in kvm_synchronize_tsc() David Woodhouse
2026-11-09 1:20 ` [PATCH v12 02/24] KVM: x86: Kill last_tsc_{nsec,write,offset} fields David Woodhouse
2026-11-09 1:20 ` [PATCH v12 03/24] KVM: x86: Replace nr_vcpus_matched_tsc count with all_vcpus_matched_tsc bool David Woodhouse
2026-11-09 1:53 ` sashiko-bot
2026-11-09 1:20 ` [PATCH v12 04/24] KVM: x86: Allow KVM master clock mode when TSCs are offset from each other David Woodhouse
2026-11-09 1:45 ` sashiko-bot
2026-11-09 1:20 ` [PATCH v12 05/24] KVM: x86: Factor out kvm_use_master_clock() David Woodhouse
2026-11-09 1:20 ` [PATCH v12 06/24] KVM: x86: Avoid gratuitous global clock updates David Woodhouse
2026-11-09 1:20 ` [PATCH v12 07/24] KVM: x86: Avoid redundant masterclock updates from multiple vCPUs David Woodhouse
2026-11-09 1:53 ` sashiko-bot [this message]
2026-11-09 1:20 ` [PATCH v12 08/24] KVM: x86: Re-synchronize TSC after KVM_SET_TSC_KHZ David Woodhouse
2026-11-09 1:53 ` sashiko-bot
2026-11-09 6:24 ` kernel test robot
2026-11-10 5:21 ` kernel test robot
2026-11-09 1:20 ` [PATCH v12 09/24] KVM: x86: Cache host vclock_mode for masterclock eligibility checks David Woodhouse
2026-11-09 1:20 ` [PATCH v12 10/24] KVM: x86: Remove pvclock_gtod_data and private timekeeping code David Woodhouse
2026-11-09 1:20 ` [PATCH v12 11/24] KVM: x86: Activate master clock from kvm_arch_init_vm() David Woodhouse
2026-11-09 1:56 ` sashiko-bot
2026-11-09 1:20 ` [PATCH v12 12/24] UAPI: x86: Move pvclock-abi to UAPI for x86 platforms David Woodhouse
2026-11-09 1:20 ` [PATCH v12 13/24] KVM: selftests: Use UAPI pvclock-abi.h in xen_shinfo_test David Woodhouse
2026-11-09 1:21 ` [PATCH v12 14/24] KVM: x86: Add KVM_[GS]ET_CLOCK_GUEST for accurate KVM clock migration David Woodhouse
2026-11-09 1:53 ` sashiko-bot
2026-11-09 1:21 ` [PATCH v12 15/24] KVM: selftests: Add library helpers for clock and TSC-offset ioctls David Woodhouse
2026-11-09 1:21 ` [PATCH v12 16/24] KVM: x86: Add KVM_VCPU_TSC_SCALE and fix the documentation on TSC migration David Woodhouse
2026-11-09 1:44 ` sashiko-bot
2026-11-09 1:21 ` [PATCH v12 17/24] KVM: selftests: Add KVM/PV clock selftest to prove timer correction David Woodhouse
2026-11-09 1:21 ` [PATCH v12 18/24] KVM: selftests: Add master clock offset test David Woodhouse
2026-11-09 1:47 ` sashiko-bot
2026-11-09 1:21 ` [PATCH v12 19/24] KVM: selftests: Add Xen/generic CPUID timing leaf test David Woodhouse
2026-11-09 1:21 ` [PATCH v12 20/24] KVM: selftests: Add Xen runstate migration test David Woodhouse
2026-11-09 1:21 ` [PATCH v12 21/24] KVM: selftests: Test that the first user TSC write is honoured exactly David Woodhouse
2026-11-09 1:21 ` [PATCH v12 22/24] KVM: x86/xen: Drop open-coded fallback clock read in kvm_xen_start_timer() David Woodhouse
2026-11-09 1:21 ` [PATCH v12 23/24] KVM: x86: Use a single time snapshot in kvm_vm_ioctl_set_clock() David Woodhouse
2026-11-09 1:21 ` [PATCH v12 24/24] KVM: x86: Keep master clock for guests using legacy MSR_KVM_SYSTEM_TIME David Woodhouse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-204330@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dwmw2@infradead.org \
--cc=kvm@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.