All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/time: make do_settime() uses more accurate
@ 2026-05-06  9:35 Jan Beulich
  2026-05-06  9:47 ` Andrew Cooper
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Jan Beulich @ 2026-05-06  9:35 UTC (permalink / raw)
  To: xen-devel@lists.xenproject.org
  Cc: Andrew Cooper, Roger Pau Monné, Teddy Astie, Nicola Vetrini

As a comment next to one of the invocations states, get_wallclock_time()
can take over a second. The order of evaluation of function arguments is
in principle unspecified; in practice at least gcc looks to be evaluating
them from last to first. Hence with NOW() invoked first, the respective
value passed to do_settime() can be off by over a second (which is in
contrast to __get_cmos_time() attempting to get the time exactly after an
update, i.e. [pretty] precisely at a seconds boundary).

This also addresses a Misra C:2012 rule 13.2 ("The value of an expression
and its persistent side-effects shall be the same under all permitted
evaluation orders") violation each.

Fixes: f64134cdb81c ("x86: Fix time_resume() to notify all domains of wallclock change")
Fixes: 0bfcf984b727 ("x86: Reintroduce clocksource=tsc")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
Of course the time it takes to do all the CMOS reads (or whichever else
wallclock time source is in use) also results in an inaccuracy. For
__get_cmos_time() this might be solvable by having it latch NOW() before
doing the 6 reads, but in particular for efi_get_time() there's hardly
anything we can do.

As to Misra rule 13.2: tagging.ecl lists the rule as clean. I also can't
find any deviation for the two instances fixed here. What am I missing?

For __get_cmos_time(), tangentially: Wouldn't we better use the
century byte if available? As it stands, things will break in 2070. Which
is a long way out, yes, but still. (Of course this would mean a 7th slow
I/O port write/read pair.)

--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -2575,6 +2575,8 @@ __initcall(verify_tsc_reliability);
 /* Late init function (after interrupts are enabled). */
 int __init init_xen_time(void)
 {
+    unsigned long wc;
+
     tsc_check_writability();
 
     open_softirq(TIME_CALIBRATE_SOFTIRQ, local_time_calibration);
@@ -2592,7 +2594,8 @@ int __init init_xen_time(void)
     printk(XENLOG_INFO "Wallclock source: %s\n", wallclock_type_to_string());
 
     /* NB. get_wallclock_time() can take over one second to execute. */
-    do_settime(get_wallclock_time(), 0, NOW());
+    wc = get_wallclock_time();
+    do_settime(wc, 0,  NOW());
 
     /* Finish platform timer initialization. */
     try_platform_timer_tail();
@@ -2745,6 +2748,8 @@ int time_suspend(void)
 
 int time_resume(void)
 {
+    unsigned long wc;
+
     preinit_pit();
 
     resume_platform_timer();
@@ -2756,7 +2761,8 @@ int time_resume(void)
 
     set_timer(&calibration_timer, NOW() + EPOCH);
 
-    do_settime(get_wallclock_time() + cmos_utc_offset, 0, NOW());
+    wc = get_wallclock_time();
+    do_settime(wc + cmos_utc_offset, 0, NOW());
 
     update_vcpu_system_time(current);
 


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-05-07 10:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-06  9:35 [PATCH] x86/time: make do_settime() uses more accurate Jan Beulich
2026-05-06  9:47 ` Andrew Cooper
2026-05-06  9:48   ` Andrew Cooper
2026-05-06  9:53     ` Nicola Vetrini
2026-05-06 11:15 ` Roger Pau Monné
2026-05-06 11:45   ` Jan Beulich
2026-05-06 12:49     ` Roger Pau Monné
2026-05-07 10:26 ` Roger Pau Monné

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.