From b7ec15bd004f4524bf091f851348da2ccb519e4f Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 6 May 2007 14:51:51 -0700 Subject: 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 Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/time.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 9fd80ee3eef6..cd7349de8ca6 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -34,8 +34,8 @@ unsigned long long sched_clock(void) return (unsigned long long)jiffies_64 * (1000000000 / HZ); } -static unsigned long long prev_nsecs[NR_CPUS]; #ifdef CONFIG_UML_REAL_TIME_CLOCK +static unsigned long long prev_nsecs[NR_CPUS]; static long long delta[NR_CPUS]; /* Deviation per interval */ #endif @@ -94,7 +94,12 @@ irqreturn_t um_timer(int irq, void *dev) do_timer(1); +#ifdef CONFIG_UML_REAL_TIME_CLOCK nsecs = get_time(); +#else + nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec + + BILLION / HZ; +#endif xtime.tv_sec = nsecs / NSEC_PER_SEC; xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; @@ -127,13 +132,18 @@ void time_init(void) nsecs = os_nsecs(); set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, -nsecs % BILLION); + set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION); late_time_init = register_timer; } void do_gettimeofday(struct timeval *tv) { +#ifdef CONFIG_UML_REAL_TIME_CLOCK unsigned long long nsecs = get_time(); - +#else + unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION + + xtime.tv_nsec; +#endif tv->tv_sec = nsecs / NSEC_PER_SEC; /* Careful about calculations here - this was originally done as * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC -- cgit v1.2.3-59-g8ed1b