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

[xen master] x86/time: make do_settime() uses more accurate



commit 54ca0aadc8219b19199703038205cd01c2611995
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu May 7 13:26:03 2026 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu May 7 16:10:52 2026 +0200

    x86/time: make do_settime() uses more accurate
    
    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. The violations aren't flagged because
    the entire file is (bogusly) excluded from scanning.
    
    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@xxxxxxxx>
    Acked-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
 xen/arch/x86/time.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index c708c80be3..98e8ef19e4 100644
--- 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();
@@ -2752,6 +2755,8 @@ int time_suspend(void)
 
 int time_resume(void)
 {
+    unsigned long wc;
+
     preinit_pit();
 
     resume_platform_timer();
@@ -2763,7 +2768,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);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

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