]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: x86: Set PVCLOCK_GUEST_STOPPED only for kvmclock, not for Xen PV clock
authorSean Christopherson <seanjc@google.com>
Sat, 1 Feb 2025 01:38:23 +0000 (17:38 -0800)
committerSean Christopherson <seanjc@google.com>
Wed, 12 Feb 2025 18:45:55 +0000 (10:45 -0800)
Handle "guest stopped" propagation only for kvmclock, as the flag is set
if and only if kvmclock is "active", i.e. can only be set for Xen PV clock
if kvmclock *and* Xen PV clock are in-use by the guest, which creates very
bizarre behavior for the guest.

Simply restrict the flag to kvmclock, e.g. instead of trying to handle
Xen PV clock, as propagation of PVCLOCK_GUEST_STOPPED was unintentionally
added during a refactoring, and while Xen proper defines
XEN_PVCLOCK_GUEST_STOPPED, there's no evidence that Xen guests actually
support the flag.

Check and clear pvclock_set_guest_stopped_request if and only if kvmclock
is active to preserve the original behavior, i.e. keep the flag pending
if kvmclock happens to be disabled when KVM processes the initial request.

Fixes: aa096aa0a05f ("KVM: x86/xen: setup pvclock updates")
Cc: Paul Durrant <pdurrant@amazon.com>
Cc: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
Link: https://lore.kernel.org/r/20250201013827.680235-8-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/x86.c

index 906c60cc811ab8f476a3499a5a202fcc29182441..8fd5922f22a6233b95b8bfbf15a22d9e76662e8f 100644 (file)
@@ -3262,20 +3262,21 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
        if (use_master_clock)
                vcpu->hv_clock.flags |= PVCLOCK_TSC_STABLE_BIT;
 
-       if (vcpu->pv_time.active
-#ifdef CONFIG_KVM_XEN
-        || vcpu->xen.vcpu_info_cache.active
-        || vcpu->xen.vcpu_time_info_cache.active
-#endif
-           ) {
+       if (vcpu->pv_time.active) {
+               /*
+                * GUEST_STOPPED is only supported by kvmclock, and KVM's
+                * historic behavior is to only process the request if kvmclock
+                * is active/enabled.
+                */
                if (vcpu->pvclock_set_guest_stopped_request) {
                        vcpu->hv_clock.flags |= PVCLOCK_GUEST_STOPPED;
                        vcpu->pvclock_set_guest_stopped_request = false;
                }
+               kvm_setup_guest_pvclock(v, &vcpu->pv_time, 0, false);
+
+               vcpu->hv_clock.flags &= ~PVCLOCK_GUEST_STOPPED;
        }
 
-       if (vcpu->pv_time.active)
-               kvm_setup_guest_pvclock(v, &vcpu->pv_time, 0, false);
 #ifdef CONFIG_KVM_XEN
        if (vcpu->xen.vcpu_info_cache.active)
                kvm_setup_guest_pvclock(v, &vcpu->xen.vcpu_info_cache,