Commit b7ec15bd004f4524bf091f851348da2ccb519e4f

Authored by Jeff Dike
Committed by Linus Torvalds
1 parent 83ff7df5f1

uml: virtualized time fix

With the current timekeeping, !CONFIG_UML_REAL_TIME_CLOCK has
inconsistent behavior.  Previously, gettimeofday could be (and was)
isolated from the clock ticking.  Now, it's not, so when
CONFIG_UML_REAL_TIME_CLOCK is disabled, gettimeofday must progress in
lockstep with the clock, making it fully virtual.

Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 12 additions and 2 deletions Side-by-side Diff

arch/um/kernel/time.c
... ... @@ -34,8 +34,8 @@
34 34 return (unsigned long long)jiffies_64 * (1000000000 / HZ);
35 35 }
36 36  
37   -static unsigned long long prev_nsecs[NR_CPUS];
38 37 #ifdef CONFIG_UML_REAL_TIME_CLOCK
  38 +static unsigned long long prev_nsecs[NR_CPUS];
39 39 static long long delta[NR_CPUS]; /* Deviation per interval */
40 40 #endif
41 41  
42 42  
... ... @@ -94,7 +94,12 @@
94 94  
95 95 do_timer(1);
96 96  
  97 +#ifdef CONFIG_UML_REAL_TIME_CLOCK
97 98 nsecs = get_time();
  99 +#else
  100 + nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec +
  101 + BILLION / HZ;
  102 +#endif
98 103 xtime.tv_sec = nsecs / NSEC_PER_SEC;
99 104 xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
100 105  
101 106  
102 107  
... ... @@ -127,13 +132,18 @@
127 132 nsecs = os_nsecs();
128 133 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
129 134 -nsecs % BILLION);
  135 + set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION);
130 136 late_time_init = register_timer;
131 137 }
132 138  
133 139 void do_gettimeofday(struct timeval *tv)
134 140 {
  141 +#ifdef CONFIG_UML_REAL_TIME_CLOCK
135 142 unsigned long long nsecs = get_time();
136   -
  143 +#else
  144 + unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION +
  145 + xtime.tv_nsec;
  146 +#endif
137 147 tv->tv_sec = nsecs / NSEC_PER_SEC;
138 148 /* Careful about calculations here - this was originally done as
139 149 * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC