From b3f59203a542001ff7485bb0be95658cbb9bb106 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 29 Jan 2026 13:37:12 +0100 Subject: [PATCH] x86/time: deal with negative deltas in get_s_time_fixed() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Callers may pass in TSC values from before the local TSC stamp was last updated (this would in particular be the case when the TSC was latched, a time rendezvous occurs, and the latched value is used only afterwards). scale_delta(), otoh, deals with unsigned values, and hence would treat negative incoming deltas as huge positive values, yielding entirely bogus return values. Fixes: 88e64cb785c1 ("x86/HVM: use fixed TSC value when saving or restoring domain") Reported-by: Антон Марков Signed-off-by: Jan Beulich Reviewed-by: Roger Pau Monné master commit: 7b3e1b4e848d34c9a5b6634009959a7b9dd42104 master date: 2026-01-20 09:03:17 +0100 --- xen/arch/x86/time.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index ece9ae0b34..3b451525a9 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -1649,8 +1649,13 @@ s_time_t get_s_time_fixed(u64 at_tsc) tsc = at_tsc; else tsc = rdtsc_ordered(); - delta = tsc - t->stamp.local_tsc; - return t->stamp.local_stime + scale_delta(delta, &t->tsc_scale); + + if ( likely(tsc >= t->stamp.local_tsc) ) + delta = scale_delta(tsc - t->stamp.local_tsc, &t->tsc_scale); + else + delta = -scale_delta(t->stamp.local_tsc - tsc, &t->tsc_scale); + + return t->stamp.local_stime + delta; } s_time_t get_s_time(void)