
From: "La Monte H.P. Yarroll" <piggy@timesys.com>

This is a Scott Wood patch against 2.6.3.


Use gettimeofday() rather than xtime.tv_sec in sys_time(), since
sys_stime() uses settimeofday() and thus subtracts the subtick correction
from the new xtime.

stime() used settimeofday(), but time() did not use gettimeofday().  Since
settimeofday() subtracts out the current intra-tick correction, and nsec
was 0 (since stime() only allows seconds), this resulted in xtime being
slightly earlier than the time that was set.

If time() had used gettimeofday(), the correction would have been applied,
and everything would be fine.  However, instead time just reads the current
xtime.tv_sec, so if time() is called immediately after stime(), you'll
usually get a value one second earlier.


---

 25-akpm/arch/ia64/ia32/sys_ia32.c         |    7 ++++---
 25-akpm/arch/parisc/kernel/sys_parisc32.c |   14 ++++++++------
 25-akpm/arch/x86_64/ia32/sys_ia32.c       |    7 ++++---
 25-akpm/kernel/time.c                     |    7 ++++---
 4 files changed, 20 insertions(+), 15 deletions(-)

diff -puN arch/ia64/ia32/sys_ia32.c~sys_time-subtick-correction-fix arch/ia64/ia32/sys_ia32.c
--- 25/arch/ia64/ia32/sys_ia32.c~sys_time-subtick-correction-fix	2004-04-03 02:59:59.018380784 -0800
+++ 25-akpm/arch/ia64/ia32/sys_ia32.c	2004-04-03 02:59:59.026379568 -0800
@@ -1090,10 +1090,11 @@ asmlinkage long
 sys32_time (int *tloc)
 {
 	int i;
+	struct timeval tv;
+
+	do_gettimeofday(&tv);
+	i = tv.tv_sec;
 
-	/* SMP: This is fairly trivial. We grab CURRENT_TIME and
-	   stuff it to user space. No side effects */
-	i = get_seconds();
 	if (tloc) {
 		if (put_user(i, tloc))
 			i = -EFAULT;
diff -puN arch/parisc/kernel/sys_parisc32.c~sys_time-subtick-correction-fix arch/parisc/kernel/sys_parisc32.c
--- 25/arch/parisc/kernel/sys_parisc32.c~sys_time-subtick-correction-fix	2004-04-03 02:59:59.019380632 -0800
+++ 25-akpm/arch/parisc/kernel/sys_parisc32.c	2004-04-03 02:59:59.027379416 -0800
@@ -388,14 +388,16 @@ static inline long get_ts32(struct times
 
 asmlinkage long sys32_time(compat_time_t *tloc)
 {
-    time_t now = get_seconds();
-    compat_time_t now32 = now;
+    struct timeval tv;
 
-    if (tloc)
-    	if (put_user(now32, tloc))
-		now32 = -EFAULT;
+	do_gettimeofday(&tv);
+	compat_time_t now32 = tv.tv_sec;
 
-    return now32;
+	if (tloc)
+		if (put_user(now32, tloc))
+			now32 = -EFAULT;
+
+	return now32;
 }
 
 asmlinkage int
diff -puN arch/x86_64/ia32/sys_ia32.c~sys_time-subtick-correction-fix arch/x86_64/ia32/sys_ia32.c
--- 25/arch/x86_64/ia32/sys_ia32.c~sys_time-subtick-correction-fix	2004-04-03 02:59:59.020380480 -0800
+++ 25-akpm/arch/x86_64/ia32/sys_ia32.c	2004-04-03 02:59:59.028379264 -0800
@@ -832,10 +832,11 @@ sys32_writev(int fd, struct compat_iovec
 asmlinkage long sys32_time(int * tloc)
 {
 	int i;
+	struct timeval tv;
+
+	do_gettimeofday(&tv);
+	i = tv.tv_sec;
 
-	/* SMP: This is fairly trivial. We grab CURRENT_TIME and 
-	   stuff it to user space. No side effects */
-	i = get_seconds();
 	if (tloc) {
 		if (put_user(i,tloc))
 			i = -EFAULT;
diff -puN kernel/time.c~sys_time-subtick-correction-fix kernel/time.c
--- 25/kernel/time.c~sys_time-subtick-correction-fix	2004-04-03 02:59:59.022380176 -0800
+++ 25-akpm/kernel/time.c	2004-04-03 02:59:59.029379112 -0800
@@ -51,10 +51,11 @@ EXPORT_SYMBOL(sys_tz);
 asmlinkage long sys_time(int * tloc)
 {
 	int i;
+	struct timeval tv;
+
+	do_gettimeofday(&tv);
+	i = tv.tv_sec;
 
-	/* SMP: This is fairly trivial. We grab CURRENT_TIME and 
-	   stuff it to user space. No side effects */
-	i = get_seconds();
 	if (tloc) {
 		if (put_user(i,tloc))
 			i = -EFAULT;

_
