|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v13 00/26] KVM: x86: Cleaning up the KVM clock mess, part 2
From: David Woodhouse <dwmw@xxxxxxxxxxxx> This is the second half of the KVM clock series which has been churning since about 2024. The first half¹ is upstream as of 7.4-rc1 (yay!). This is the remainder — the masterclock overhaul, and new API for fixing migration. Sashiko is helping by finding lots of things which have been fairly hosed in kvmclock since its inception, as well as things I've managed to screw up for myself along the way. As of v12, a guest can no longer force the KVM clock out of masterclock mode at all. Even the old SYSTEM_TIME MSR (and that SUSE kernel from 2006) is satisfied by updating the master clock when the MSR is rewritten. Tree: https://git.infradead.org/users/dwmw2/linux.git/shortlog/refs/heads/kvmclock13 v13 follows one more on-list sashiko round, a second 0day report⁴, and eleven rounds of review-and-fixup with sashiko locally. Two pre-existing bugs the review flushed out are split out as standalone fixes with Fixes: tags (new patches 7 and 9), so the series is now 26 patches. In detail: KVM_SET_TSC_KHZ: • The {guest TSC, host clock} tuple could be sampled just before a sibling opened a newer generation, wrapping the elapsed time — and the first fix, clamping it to zero, inflated the matching error from |F1-F2|·Δt to F1·Δt, spuriously splitting the generation when two vCPUs raced through the ioctl. • The 1ms matching window for exact kernel-internal samples was unreachable unless userspace had already written a TSC. • preempt_disable() did not actually make the fallback {TSC, ns} read pair coherent; interrupts could still land between the two reads. • A creation-time frequency the hardware cannot scale to left the vCPU with virtual_tsc_khz == 0 for its whole life. • An internal preserved sample of exactly zero took the userspace zero-write path and was snapped onto the generation line. • A forced synchronization of an unrun vCPU racing a sibling through the ioctl could wrap its extrapolated TSC below zero, which an unstable-TSC host then re-anchored the guest TSC to at vcpu_load. • The 1ms window computation needed libgcc's __udivdi3 on i386 (kernel test robot⁴). • The fix for stale always-catchup state is now its own patch with a Fixes: tag, since the bug predates this series (new patch 9), as is the fix for the Hyper-V TSC page latching stale parameters from a superseded snapshot (new patch 7). The master clock: • A scaled protected guest TSC (TDX, SNP Secure TSC) left the master clock computing with the host's unscaled frequency. • The first protected-TSC synchronization cleared the frequency match for the life of the VM, since such vCPUs never reach kvm_track_tsc_matching() to re-latch it — and the re-latch then had to raise the masterclock update itself, or a refresh racing a second vCPU's creation latched the master clock off forever. • An aborted vCPU creation could clear matched state which a racing host-initiated TSC write on the already-live fd had made correct, and for a protected-TSC first vCPU it skipped the snapshot refresh forever. • KVM_GET_CLOCK's no-vCPU staleness check compared two reads nothing kept coherent, so a reader preempted for a second mid-ioctl served the flag-less fallback from a healthy snapshot. • Deduplicated masterclock updates removed the accidental heal for a Hyper-V TSC page rewritten from a stale snapshot: a vCPU preempted between its pvclock read and the page write consumed the HOST_CHANGED mark against the old snapshot and set HV_TSC_PAGE_SET, permanently. kvm_hv_setup_tsc_page() now revalidates the pvclock seqcount under its own lock, and the updater re-marks the page once the new snapshot is published. • The CLOCK_UPDATE broadcast sat inside the pvclock seqcount write section, growing the interrupts-off window with the vCPU count. • A CPU hotplug runs the backwards-TSC compensation while vCPU threads are live, and the unlocked consume of tsc_offset_adjustment in vcpu_load could discard a delta the generation reference kept. • kvm_vm_ioctl_set_clock()'s epoch-wrap guard left the anchor off master_kernel_ns, wrapping system_time for a near-zero clock instead. • Patch 12's subject and opening described an earlier patch's work; it is now "Keep the master clock trustworthy while the VM has no vCPUs". KVM_[GS]ET_CLOCK_GUEST: • GET after a host suspend with the VM paused combined the post-resume offset with the pre-suspend snapshot — frequencies still matched, so the destination accepted garbage. GET now services the vCPU's pending masterclock update first, and fails with -ENODATA. Elsewhere: • The TSC migration documentation's step 7b multiplication wraps a signed 64-bit value after ~51 minutes of pause at 3GHz; it now carries the same 128-bit note as step 2d, and the exemplar selftest does the arithmetic in 128 bits. • Selftests reported a loaded host as a kernel regression instead of a TAP skip, printed no TAP output at all, carried a fourth private copy of the pvclock arithmetic, and the divergent-offset correction check could not fail against a silently ignored KVM_SET_CLOCK_GUEST. • The CPUID timing test's ratio cross-check skip keyed off the very ratio it exists to verify, and the first-write test's frequency-change arm could pass on a buggy kernel under adverse scheduling. • The clock library helpers now also convert the pre-existing open-coded call sites. • Various comments and commit messages overclaimed ("invisible to any correct guest", "definitely identical", "the only synchronization a protected vCPU ever performs") and have been made honest. ¹ https://lore.kernel.org/all/20260826213303.914988-1-seanjc@xxxxxxxxxx ² https://lore.kernel.org/all/20261105154955.2525419-1-dwmw2@xxxxxxxxxxxxx ³ https://lore.kernel.org/all/20261109012112.3415328-1-dwmw2@xxxxxxxxxxxxx ⁴ https://lore.kernel.org/all/202611091411.tSxUx2Bj-lkp@xxxxxxxxx David Woodhouse (23): KVM: x86: Improve synchronization in kvm_synchronize_tsc() KVM: x86: Kill last_tsc_{nsec,write,offset} fields KVM: x86: Replace nr_vcpus_matched_tsc count with all_vcpus_matched_tsc bool KVM: x86: Allow KVM master clock mode when TSCs are offset from each other KVM: x86: Factor out kvm_use_master_clock() KVM: x86: Avoid gratuitous global clock updates KVM: x86: Don't latch the Hyper-V TSC page from a superseded snapshot KVM: x86: Avoid redundant masterclock updates from multiple vCPUs KVM: x86: Stop TSC catchup when a frequency change no longer needs it KVM: x86: Re-synchronize TSC after KVM_SET_TSC_KHZ KVM: x86: Cache host vclock_mode for masterclock eligibility checks KVM: x86: Remove pvclock_gtod_data and private timekeeping code KVM: x86: Keep the master clock trustworthy while the VM has no vCPUs KVM: selftests: Use UAPI pvclock-abi.h in xen_shinfo_test KVM: selftests: Add library helpers for clock and TSC-offset ioctls KVM: x86: Add KVM_VCPU_TSC_SCALE and fix the documentation on TSC migration KVM: selftests: Add master clock offset test KVM: selftests: Add Xen/generic CPUID timing leaf test KVM: selftests: Add Xen runstate migration test KVM: selftests: Test that the first user TSC write is honoured exactly KVM: x86/xen: Drop open-coded fallback clock read in kvm_xen_start_timer() KVM: x86: Use a single time snapshot in kvm_vm_ioctl_set_clock() KVM: x86: Keep master clock for guests using legacy MSR_KVM_SYSTEM_TIME Jack Allister (3): UAPI: x86: Move pvclock-abi to UAPI for x86 platforms KVM: x86: Add KVM_[GS]ET_CLOCK_GUEST for accurate KVM clock migration KVM: selftests: Add KVM/PV clock selftest to prove timer correction Documentation/virt/kvm/api.rst | 64 + Documentation/virt/kvm/devices/vcpu.rst | 144 +- Documentation/virt/kvm/locking.rst | 3 +- MAINTAINERS | 4 +- arch/x86/include/asm/kvm_host.h | 21 +- arch/x86/include/uapi/asm/kvm.h | 7 + arch/x86/include/{ => uapi}/asm/pvclock-abi.h | 27 +- arch/x86/kvm/hyperv.c | 20 +- arch/x86/kvm/hyperv.h | 10 +- arch/x86/kvm/msrs.c | 30 +- arch/x86/kvm/trace.h | 12 +- arch/x86/kvm/x86.c | 1275 ++++++++++++++--- arch/x86/kvm/x86.h | 2 +- arch/x86/kvm/xen.c | 50 +- include/uapi/linux/kvm.h | 4 + scripts/xen-hypercalls.sh | 2 +- tools/arch/x86/include/asm/pvclock-abi.h | 48 - tools/arch/x86/include/uapi/asm/kvm.h | 6 + tools/testing/selftests/kvm/Makefile.kvm | 6 + .../selftests/kvm/include/x86/processor.h | 50 + .../kvm/system_counter_offset_test.c | 3 +- .../testing/selftests/kvm/x86/hyperv_clock.c | 2 +- .../selftests/kvm/x86/kvm_clock_test.c | 6 +- .../kvm/x86/masterclock_offset_test.c | 249 ++++ .../kvm/x86/pvclock_migration_test.c | 503 +++++++ .../testing/selftests/kvm/x86/pvclock_test.c | 525 +++++++ .../selftests/kvm/x86/tsc_user_set_test.c | 193 +++ .../selftests/kvm/x86/xen_cpuid_timing_test.c | 293 ++++ .../selftests/kvm/x86/xen_migration_test.c | 227 +++ .../selftests/kvm/x86/xen_shinfo_test.c | 35 +- 30 files changed, 3454 insertions(+), 367 deletions(-) rename arch/x86/include/{ => uapi}/asm/pvclock-abi.h (82%) delete mode 100644 tools/arch/x86/include/asm/pvclock-abi.h create mode 100644 tools/testing/selftests/kvm/x86/masterclock_offset_test.c create mode 100644 tools/testing/selftests/kvm/x86/pvclock_migration_test.c create mode 100644 tools/testing/selftests/kvm/x86/pvclock_test.c create mode 100644 tools/testing/selftests/kvm/x86/tsc_user_set_test.c create mode 100644 tools/testing/selftests/kvm/x86/xen_cpuid_timing_test.c create mode 100644 tools/testing/selftests/kvm/x86/xen_migration_test.c -- 2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |