diff mbox series

[v7,2/5] um: time: fix read_persistent_clock64() in time-travel

Message ID 20201202205659.03331ec9616f.I3f5effe88fe040ff9262de115dd71bfd65d2b0a2@changeid
State Accepted
Headers show
Series um: suspend/resume support | expand

Commit Message

Johannes Berg Dec. 2, 2020, 7:58 p.m. UTC
From: Johannes Berg <johannes.berg@intel.com>

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>
---
 arch/um/kernel/time.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

Comments

Anton Ivanov Dec. 3, 2020, 11:33 a.m. UTC | #1
On 02/12/2020 19:58, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> 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>
> ---
>   arch/um/kernel/time.c | 23 ++++++++++++++++++++---
>   1 file changed, 20 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
> index 8e8eb8ba04a4..80d33735cfd2 100644
> --- a/arch/um/kernel/time.c
> +++ b/arch/um/kernel/time.c
> @@ -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;
>   }
> 

Acked-By: Anton Ivanov <anton.ivanov@cambridgegreys.com>
diff mbox series

Patch

diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 8e8eb8ba04a4..80d33735cfd2 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -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;
 }