diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c index 6955b2788f..be54b87438 100644 --- a/xen/arch/arm/time.c +++ b/xen/arch/arm/time.c @@ -145,6 +145,8 @@ void __init preinit_xen_time(void) panic("Timer: Cannot initialize platform timer\n"); boot_count = get_cycles(); + smp_wmb(); + NOW_good = true; } static void __init init_dt_xen_time(void) diff --git a/xen/arch/riscv/time.c b/xen/arch/riscv/time.c index 10b7e35f13..602c029641 100644 --- a/xen/arch/riscv/time.c +++ b/xen/arch/riscv/time.c @@ -87,6 +87,8 @@ void __init preinit_xen_time(void) panic("%s: ACPI isn't supported\n", __func__); boot_clock_cycles = get_cycles(); + smp_wmb(); + NOW_good = true; /* set_xen_timer must have been set by sbi_init() already */ ASSERT(set_xen_timer); diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index bc76e20777..bc0161f7c2 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -2660,6 +2660,8 @@ void __init early_time_init(void) set_time_scale(&t->tsc_scale, tmp); t->stamp.local_tsc = boot_tsc_stamp; + barrier(); + NOW_good = true; init_percpu_time(); diff --git a/xen/common/time.c b/xen/common/time.c index 04a65f00b3..2b8c98e2de 100644 --- a/xen/common/time.c +++ b/xen/common/time.c @@ -22,6 +22,8 @@ #include #include +bool __ro_after_init NOW_good; + /* Nonzero if YEAR is a leap year (every 4 years, except every 100th isn't, and every 400th is). */ #define __isleap(year) \ diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 40355c1d14..fcacf37c52 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -987,11 +987,11 @@ static void printk_start_of_line(const char *prefix) } /* fall through */ case TSM_BOOT: - sec = NOW(); - nsec = do_div(sec, 1000000000); - - if ( sec | nsec ) + if ( NOW_good ) { + smp_rmb(); + sec = NOW(); + nsec = do_div(sec, 1000000000); snprintf(tstr, sizeof(tstr), "[%5"PRIu64".%06"PRIu64"] ", sec, nsec / 1000); break; diff --git a/xen/include/xen/time.h b/xen/include/xen/time.h index e9c0822e6f..4db24617a9 100644 --- a/xen/include/xen/time.h +++ b/xen/include/xen/time.h @@ -62,6 +62,12 @@ struct tm wallclock_time(uint64_t *ns); /* Chosen so (NOW() + delta) wont overflow without an uptime of 200 years */ #define STIME_DELTA_MAX ((s_time_t)((uint64_t)~0ULL>>2)) +/* + * Indicator that the value returned by NOW() is good (earlier invocations may + * return zero or very small, merely monotonically increasing values). + */ +extern bool NOW_good; + /* Explicitly OR with 1 just in case version number gets out of sync. */ #define version_update_begin(v) (((v) + 1) | 1) #define version_update_end(v) ((v) + 1)