|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v6 15/36] KVM: x86: Fix compute_guest_tsc() to handle negative time deltas
On Fri, Jul 03, 2026, David Woodhouse wrote:
> 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.
>
> Handle negative deltas explicitly by negating the delta, scaling it,
> and subtracting from this_tsc_write.
Does this need
Cc: stable@xxxxxxxxxxxxxxx
or is this a "technically a bug fix, but can't happen in practice" sort of
thing?
>
> Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
> ---
> arch/x86/kvm/x86.c | 20 +++++++++++++++-----
> 1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 376b8dc2ade9..55fb19fb7a88 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2588,11 +2588,21 @@ static int kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32
> user_tsc_khz)
>
> static u64 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;
To cut down on the duplicate code, and IMO to make it easier to identify the
differences, how about this?
s64 delta_ns = kernel_ns - vcpu->arch.this_tsc_nsec;
u64 tsc;
/* Handle negative deltas gracefully (master clock ref may be earlier)
*/
tsc = pvclock_scale_delta(abs(-delta_ns),
vcpu->arch.virtual_tsc_mult,
vcpu->arch.virtual_tsc_shift);
return vcpu->arch.this_tsc_write + (delta_ns >= 0 ? tsc : -tsc);
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |