lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080605153008.GC7311@c2.user-mode-linux.org>
Date:	Thu, 5 Jun 2008 11:30:08 -0400
From:	Jeff Dike <jdike@...toit.com>
To:	Nix <nix@...eri.org.uk>, dhazelton@...er.net
Cc:	Andrew Morton <akpm@...ux-foundation.org>,
	linux-kernel@...r.kernel.org,
	user-mode-linux-devel@...ts.sourceforge.net,
	Jeremy Fitzhardinge <jeremy@...p.org>
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

On Wed, Jun 04, 2008 at 09:05:11PM +0100, Jeremy Fitzhardinge wrote:
> You can either read the monotonic clock directly, or use it as a time 
> source for a monotonic timer.  clock_gettime(CLOCK_MONOTONIC, &ts) will 
> return the time in ns, and you can just feed that directly into the guest 
> as a clocksource.

Aha, I was looking at timer_* and not getting reasonable-looking
results.  The one questionable aspect of this is that I need to pull
in a new library (librt) and I wonder how many people don't have it
installed...

Anyway, the patch below seems to make the guest behave reasonably in
the face of the host time doing funky things...

Give it a spin and let me know how it does.  If there aren't any
problems, I'll get it into mainline.

    	    	Jeff

-- 
Work email - jdike at linux dot intel dot com

Index: linux-2.6.22/arch/um/os-Linux/time.c
===================================================================
--- linux-2.6.22.orig/arch/um/os-Linux/time.c	2008-06-02 15:38:34.000000000 -0400
+++ linux-2.6.22/arch/um/os-Linux/time.c	2008-06-04 19:49:16.000000000 -0400
@@ -56,6 +56,11 @@ static inline long long timeval_to_ns(co
 		tv->tv_usec * UM_NSEC_PER_USEC;
 }
 
+static inline long long timespec_to_ns(const struct timespec *ts)
+{
+	return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) + ts->tv_nsec;
+}
+
 long long disable_timer(void)
 {
 	struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
@@ -72,12 +77,22 @@ long long disable_timer(void)
 	return remain;
 }
 
-long long os_nsecs(void)
+static inline long long nsecs(int clock)
 {
-	struct timeval tv;
+	struct timespec ts;
+
+	clock_gettime(clock, &ts);
+	return timespec_to_ns(&ts);
+}
+
+long long os_wall_nsecs(void)
+{
+	return nsecs(CLOCK_REALTIME);
+}
 
-	gettimeofday(&tv, NULL);
-	return timeval_to_ns(&tv);
+long long os_mono_nsecs(void)
+{
+	return nsecs(CLOCK_MONOTONIC);
 }
 
 extern void alarm_handler(int sig, struct sigcontext *sc);
@@ -104,13 +119,9 @@ unsigned long long skew;
 
 static void deliver_alarm(void)
 {
-	unsigned long long this_tick = os_nsecs();
+	unsigned long long this_tick = os_mono_nsecs();
 	int one_tick = UM_NSEC_PER_SEC / UM_HZ;
 
-	/* Protection against the host's time going backwards */
-	if ((last_tick != 0) && (this_tick < last_tick))
-		this_tick = last_tick;
-
 	if (last_tick == 0)
 		last_tick = this_tick - one_tick;
 
Index: linux-2.6.22/arch/um/Makefile
===================================================================
--- linux-2.6.22.orig/arch/um/Makefile	2008-05-29 11:21:25.000000000 -0400
+++ linux-2.6.22/arch/um/Makefile	2008-06-04 19:42:09.000000000 -0400
@@ -126,7 +126,7 @@ define cmd_vmlinux__
 	$(CC) $(CFLAGS_vmlinux) -o $@ \
 	-Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
 	-Wl,--start-group $(vmlinux-main) -Wl,--end-group \
-	-lutil \
+	-lutil -lrt \
 	$(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o \
 	FORCE ,$^) ; rm -f linux
 endef
Index: linux-2.6.22/arch/um/include/os.h
===================================================================
--- linux-2.6.22.orig/arch/um/include/os.h	2008-06-02 15:38:34.000000000 -0400
+++ linux-2.6.22/arch/um/include/os.h	2008-06-04 19:51:55.000000000 -0400
@@ -244,7 +244,8 @@ extern int set_interval(void);
 extern int timer_one_shot(int ticks);
 extern long long disable_timer(void);
 extern void uml_idle_timer(void);
-extern long long os_nsecs(void);
+extern long long os_wall_nsecs(void);
+extern long long os_mono_nsecs(void);
 
 /* skas/mem.c */
 extern long run_syscall_stub(struct mm_id * mm_idp,
Index: linux-2.6.22/arch/um/kernel/time.c
===================================================================
--- linux-2.6.22.orig/arch/um/kernel/time.c	2008-06-02 15:38:33.000000000 -0400
+++ linux-2.6.22/arch/um/kernel/time.c	2008-06-04 19:51:59.000000000 -0400
@@ -74,7 +74,7 @@ static irqreturn_t um_timer(int irq, voi
 
 static cycle_t itimer_read(void)
 {
-	return os_nsecs() / 1000;
+	return os_mono_nsecs() / 1000;
 }
 
 static struct clocksource itimer_clocksource = {
@@ -117,7 +117,7 @@ void __init time_init(void)
 
 	timer_init();
 
-	nsecs = os_nsecs();
+	nsecs = os_wall_nsecs();
 	set_normalized_timespec(&wall_to_monotonic, -nsecs / NSEC_PER_SEC,
 				-nsecs % NSEC_PER_SEC);
 	set_normalized_timespec(&xtime, nsecs / NSEC_PER_SEC,
Index: linux-2.6.22/arch/um/os-Linux/skas/process.c
===================================================================
--- linux-2.6.22.orig/arch/um/os-Linux/skas/process.c	2008-06-04 19:51:05.000000000 -0400
+++ linux-2.6.22/arch/um/os-Linux/skas/process.c	2008-06-04 19:51:59.000000000 -0400
@@ -359,7 +359,7 @@ void userspace(struct uml_pt_regs *regs)
 		printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno);
 	nsecs = timer.it_value.tv_sec * UM_NSEC_PER_SEC +
 		timer.it_value.tv_usec * UM_NSEC_PER_USEC;
-	nsecs += os_nsecs();
+	nsecs += os_mono_nsecs();
 
 	while (1) {
 		/*
@@ -420,7 +420,7 @@ void userspace(struct uml_pt_regs *regs)
 				relay_signal(SIGTRAP, regs);
 				break;
 			case SIGVTALRM:
-				now = os_nsecs();
+				now = os_mono_nsecs();
 				if (now < nsecs)
 					break;
 				block_signals();
@@ -430,7 +430,7 @@ void userspace(struct uml_pt_regs *regs)
 					UM_NSEC_PER_SEC +
 					timer.it_value.tv_usec *
 					UM_NSEC_PER_USEC;
-				nsecs += os_nsecs();
+				nsecs += os_mono_nsecs();
 				break;
 			case SIGIO:
 			case SIGILL:
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ