um: time: Fix read_persistent_clock64() in time-travel
authorJohannes Berg <johannes.berg@intel.com>
Wed, 2 Dec 2020 19:58:05 +0000 (20:58 +0100)
committerRichard Weinberger <richard@nod.at>
Sun, 13 Dec 2020 21:22:41 +0000 (22:22 +0100)
In time-travel mode, we've relied on read_persistent_clock64()
being called only once at system startup, but this is both the
right thing to call from the pseudo-RTC, and also gets called
by the timekeeping core during suspend/resume.

Thus, fix this to always fall make use of the time_travel_time
in any time-travel mode, initializing time_travel_start at boot
to the right value depending on the time-travel mode.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Acked-By: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
arch/um/kernel/time.c

index 8e8eb8b..80d3373 100644 (file)
@@ -676,10 +676,8 @@ void read_persistent_clock64(struct timespec64 *ts)
 {
        long long nsecs;
 
-       if (time_travel_start_set)
+       if (time_travel_mode != TT_MODE_OFF)
                nsecs = time_travel_start + time_travel_time;
-       else if (time_travel_mode == TT_MODE_EXTERNAL)
-               nsecs = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1);
        else
                nsecs = os_persistent_clock_emulation();
 
@@ -689,6 +687,25 @@ void read_persistent_clock64(struct timespec64 *ts)
 
 void __init time_init(void)
 {
+#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
+       switch (time_travel_mode) {
+       case TT_MODE_EXTERNAL:
+               time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1);
+               /* controller gave us the *current* time, so adjust by that */
+               time_travel_ext_get_time();
+               time_travel_start -= time_travel_time;
+               break;
+       case TT_MODE_INFCPU:
+       case TT_MODE_BASIC:
+               if (!time_travel_start_set)
+                       time_travel_start = os_persistent_clock_emulation();
+               break;
+       case TT_MODE_OFF:
+               /* we just read the host clock with os_persistent_clock_emulation() */
+               break;
+       }
+#endif
+
        timer_set_signal_handler();
        late_time_init = um_timer_setup;
 }