mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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: f64134cdb8 ("x86: Fix time_resume() to notify all domains of wallclock change")
Fixes: 0bfcf984b7 ("x86: Reintroduce clocksource=tsc")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
master commit: 54ca0aadc8
master date: 2026-05-07 16:10:52 +0200
This commit is contained in:
1 parent
3dccad5220
commit
fd2ccd79ab
1 file changed
+8
-2
+8
-2
@@ -2567,6 +2567,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);
|
||||
@@ -2584,7 +2586,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();
|
||||
@@ -2737,6 +2740,8 @@ int time_suspend(void)
|
||||
|
||||
int time_resume(void)
|
||||
{
|
||||
unsigned long wc;
|
||||
|
||||
preinit_pit();
|
||||
|
||||
resume_platform_timer();
|
||||
@@ -2748,7 +2753,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);
|
||||
|
||||
|
||||