Update Linux to v5.4.2

Change-Id: Idf6911045d9d382da2cfe01b1edff026404ac8fd
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 052de4c..94ea87b 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
  * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
  * Copyright (C) 2012-2014 Cisco Systems
  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
  */
 
 #include <linux/clockchips.h>
@@ -19,11 +19,37 @@
 #include <kern_util.h>
 #include <os.h>
 #include <timer-internal.h>
+#include <shared/init.h>
+
+#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
+enum time_travel_mode time_travel_mode;
+unsigned long long time_travel_time;
+enum time_travel_timer_mode time_travel_timer_mode;
+unsigned long long time_travel_timer_expiry;
+unsigned long long time_travel_timer_interval;
+
+static bool time_travel_start_set;
+static unsigned long long time_travel_start;
+#else
+#define time_travel_start_set 0
+#define time_travel_start 0
+#endif
 
 void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
 {
 	unsigned long flags;
 
+	/*
+	 * In basic time-travel mode we still get real interrupts
+	 * (signals) but since we don't read time from the OS, we
+	 * must update the simulated time here to the expiry when
+	 * we get a signal.
+	 * This is not the case in inf-cpu mode, since there we
+	 * never get any real signals from the OS.
+	 */
+	if (time_travel_mode == TT_MODE_BASIC)
+		time_travel_set_time(time_travel_timer_expiry);
+
 	local_irq_save(flags);
 	do_IRQ(TIMER_IRQ, regs);
 	local_irq_restore(flags);
@@ -31,32 +57,56 @@
 
 static int itimer_shutdown(struct clock_event_device *evt)
 {
-	os_timer_disable();
+	if (time_travel_mode != TT_MODE_OFF)
+		time_travel_set_timer_mode(TT_TMR_DISABLED);
+
+	if (time_travel_mode != TT_MODE_INFCPU)
+		os_timer_disable();
+
 	return 0;
 }
 
 static int itimer_set_periodic(struct clock_event_device *evt)
 {
-	os_timer_set_interval(NULL, NULL);
+	unsigned long long interval = NSEC_PER_SEC / HZ;
+
+	if (time_travel_mode != TT_MODE_OFF) {
+		time_travel_set_timer_mode(TT_TMR_PERIODIC);
+		time_travel_set_timer_expiry(time_travel_time + interval);
+		time_travel_set_timer_interval(interval);
+	}
+
+	if (time_travel_mode != TT_MODE_INFCPU)
+		os_timer_set_interval(interval);
+
 	return 0;
 }
 
 static int itimer_next_event(unsigned long delta,
 			     struct clock_event_device *evt)
 {
-	return os_timer_one_shot(delta);
+	delta += 1;
+
+	if (time_travel_mode != TT_MODE_OFF) {
+		time_travel_set_timer_mode(TT_TMR_ONESHOT);
+		time_travel_set_timer_expiry(time_travel_time + delta);
+	}
+
+	if (time_travel_mode != TT_MODE_INFCPU)
+		return os_timer_one_shot(delta);
+
+	return 0;
 }
 
 static int itimer_one_shot(struct clock_event_device *evt)
 {
-	os_timer_one_shot(1);
-	return 0;
+	return itimer_next_event(0, evt);
 }
 
 static struct clock_event_device timer_clockevent = {
 	.name			= "posix-timer",
 	.rating			= 250,
-	.cpumask		= cpu_all_mask,
+	.cpumask		= cpu_possible_mask,
 	.features		= CLOCK_EVT_FEAT_PERIODIC |
 				  CLOCK_EVT_FEAT_ONESHOT,
 	.set_state_shutdown	= itimer_shutdown,
@@ -87,6 +137,17 @@
 
 static u64 timer_read(struct clocksource *cs)
 {
+	if (time_travel_mode != TT_MODE_OFF) {
+		/*
+		 * We make reading the timer cost a bit so that we don't get
+		 * stuck in loops that expect time to move more than the
+		 * exact requested sleep amount, e.g. python's socket server,
+		 * see https://bugs.python.org/issue37026.
+		 */
+		time_travel_set_time(time_travel_time + TIMER_MULTIPLIER);
+		return time_travel_time / TIMER_MULTIPLIER;
+	}
+
 	return os_nsecs() / TIMER_MULTIPLIER;
 }
 
@@ -107,7 +168,7 @@
 		printk(KERN_ERR "register_timer : request_irq failed - "
 		       "errno = %d\n", -err);
 
-	err = os_timer_create(NULL);
+	err = os_timer_create();
 	if (err != 0) {
 		printk(KERN_ERR "creation of timer failed - errno = %d\n", -err);
 		return;
@@ -123,7 +184,12 @@
 
 void read_persistent_clock64(struct timespec64 *ts)
 {
-	long long nsecs = os_persistent_clock_emulation();
+	long long nsecs;
+
+	if (time_travel_start_set)
+		nsecs = time_travel_start + time_travel_time;
+	else
+		nsecs = os_persistent_clock_emulation();
 
 	set_normalized_timespec64(ts, nsecs / NSEC_PER_SEC,
 				  nsecs % NSEC_PER_SEC);
@@ -134,3 +200,65 @@
 	timer_set_signal_handler();
 	late_time_init = um_timer_setup;
 }
+
+#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
+unsigned long calibrate_delay_is_known(void)
+{
+	if (time_travel_mode == TT_MODE_INFCPU)
+		return 1;
+	return 0;
+}
+
+int setup_time_travel(char *str)
+{
+	if (strcmp(str, "=inf-cpu") == 0) {
+		time_travel_mode = TT_MODE_INFCPU;
+		timer_clockevent.name = "time-travel-timer-infcpu";
+		timer_clocksource.name = "time-travel-clock";
+		return 1;
+	}
+
+	if (!*str) {
+		time_travel_mode = TT_MODE_BASIC;
+		timer_clockevent.name = "time-travel-timer";
+		timer_clocksource.name = "time-travel-clock";
+		return 1;
+	}
+
+	return -EINVAL;
+}
+
+__setup("time-travel", setup_time_travel);
+__uml_help(setup_time_travel,
+"time-travel\n"
+"This option just enables basic time travel mode, in which the clock/timers\n"
+"inside the UML instance skip forward when there's nothing to do, rather than\n"
+"waiting for real time to elapse. However, instance CPU speed is limited by\n"
+"the real CPU speed, so e.g. a 10ms timer will always fire after ~10ms wall\n"
+"clock (but quicker when there's nothing to do).\n"
+"\n"
+"time-travel=inf-cpu\n"
+"This enables time travel mode with infinite processing power, in which there\n"
+"are no wall clock timers, and any CPU processing happens - as seen from the\n"
+"guest - instantly. This can be useful for accurate simulation regardless of\n"
+"debug overhead, physical CPU speed, etc. but is somewhat dangerous as it can\n"
+"easily lead to getting stuck (e.g. if anything in the system busy loops).\n");
+
+int setup_time_travel_start(char *str)
+{
+	int err;
+
+	err = kstrtoull(str, 0, &time_travel_start);
+	if (err)
+		return err;
+
+	time_travel_start_set = 1;
+	return 1;
+}
+
+__setup("time-travel-start", setup_time_travel_start);
+__uml_help(setup_time_travel_start,
+"time-travel-start=<seconds>\n"
+"Configure the UML instance's wall clock to start at this value rather than\n"
+"the host's wall clock at the time of UML boot.\n");
+#endif