[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v4 15/30] KVM: x86: Fix compute_guest_tsc() to handle negative time deltas



From: David Woodhouse <dwmw@xxxxxxxxxxxx>

The compute_guest_tsc() function computes the guest TSC at a given
kernel_ns timestamp. When the master clock reference point
(master_kernel_ns) is earlier than vcpu->arch.this_tsc_nsec, the delta
is negative. Since pvclock_scale_delta() takes a u64, the negative
value wraps to a huge positive number, producing a wildly wrong result.

Change the return type to s64 and handle negative deltas explicitly by
negating the delta, scaling it, and subtracting from this_tsc_write.

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
---
 arch/x86/kvm/x86.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2bbc2c7ac449..e281c49561fa 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2586,13 +2586,23 @@ static int kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 
user_tsc_khz)
        return set_tsc_khz(vcpu, user_tsc_khz, use_scaling);
 }
 
-static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
+static s64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
 {
-       u64 tsc = pvclock_scale_delta(kernel_ns-vcpu->arch.this_tsc_nsec,
-                                     vcpu->arch.virtual_tsc_mult,
-                                     vcpu->arch.virtual_tsc_shift);
-       tsc += vcpu->arch.this_tsc_write;
-       return tsc;
+       s64 delta_ns = kernel_ns - vcpu->arch.this_tsc_nsec;
+       u64 tsc;
+
+       /* Handle negative deltas gracefully (master clock ref may be earlier) 
*/
+       if (delta_ns < 0) {
+               tsc = pvclock_scale_delta(-delta_ns,
+                                         vcpu->arch.virtual_tsc_mult,
+                                         vcpu->arch.virtual_tsc_shift);
+               return vcpu->arch.this_tsc_write - tsc;
+       }
+
+       tsc = pvclock_scale_delta(delta_ns,
+                                 vcpu->arch.virtual_tsc_mult,
+                                 vcpu->arch.virtual_tsc_shift);
+       return vcpu->arch.this_tsc_write + tsc;
 }
 
 #ifdef CONFIG_X86_64
-- 
2.51.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.