
From: Martin Schwidefsky <schwidefsky@de.ibm.com>

I realized that the best way to get the sys_time/sys_stime problem fixed is
to make sys_time 64 bit safe by using "time_t *" instead of "int *" and to
introduce two proper compat functions compat_sys_time and compat_sys_stime.

The prototype change of sys_time is transparent for 32 bit architectures
because both "int" and "time_t" are 32 bit.  For 64 bit the type change
would be wrong but luckily no 64 bit architecture uses sys_time/sys_stime
in 64 bit mode.  The patch makes the following change:

ia64     : Remove sys32_time, use compat_sys_time and
           add (!!) compat_sys_stime to compat syscall table.
mips     : Use compat_sys_time/compat_sys_stime in 32 bit syscall table.
           Add #ifdef magic to compile sys_time/sys_stime and
           compat_sys_time/compat_sys_stime only if needed.
parisc   : Remove sys32_time, use compat_sys_time and compat_sys_stime.
ppc64    : remove sys32_time, ppc64_sys32_stime and ppc64_sys_stime.
           Use common compat_sys_time, compat_sys_stime and sys_stime.
s390     : Use compat_sys_stime. Add #ifdef magic to compile
           sys_time/sys_stime and compat_sys_time/compat_sys_stime only
           if needed.
sparc64  : Use compat_sys_time/compat_Sys_stime in 32 bit syscall table.
um       : Remove um_time and um_stime. Use common functions sys_time and
           sys_stime. This adds a CAP_SYS_TIME check to UMs stime call.
x86_64   : Remove sys32_time. Use compat_sys_time and compat_sys_stime
           in 32 bit syscall table.

The original stime bug is fixed for mips, parisc, s390, sparc64 and
x86_64. Can the arch-maintainers please take a look at this?

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

Convert compat_time_t to time_t in 32 bit emulation for sys_stime and
consolidate all the different implementation of sys_time, sys_stime and
their 32-bit emulation parts.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/ia64/ia32/ia32_entry.S        |    4 +-
 25-akpm/arch/ia64/ia32/sys_ia32.c          |   21 -----------
 25-akpm/arch/mips/kernel/scall64-o32.S     |    4 +-
 25-akpm/arch/parisc/kernel/sys_parisc32.c  |   15 --------
 25-akpm/arch/parisc/kernel/syscall_table.S |    4 +-
 25-akpm/arch/ppc64/kernel/misc.S           |    6 +--
 25-akpm/arch/ppc64/kernel/sys_ppc32.c      |   17 ---------
 25-akpm/arch/ppc64/kernel/time.c           |   54 -----------------------------
 25-akpm/arch/s390/kernel/compat_wrapper.S  |    4 +-
 25-akpm/arch/sparc64/kernel/systbls.S      |    4 +-
 25-akpm/arch/x86_64/ia32/ia32entry.S       |    4 +-
 25-akpm/arch/x86_64/ia32/sys_ia32.c        |   20 ----------
 25-akpm/include/asm-mips/unistd.h          |    7 +++
 25-akpm/include/asm-parisc/unistd.h        |    1 
 25-akpm/include/asm-ppc64/unistd.h         |    1 
 25-akpm/include/asm-s390/unistd.h          |    5 +-
 25-akpm/include/asm-sparc64/unistd.h       |    1 
 25-akpm/include/asm-x86_64/unistd.h        |    2 -
 25-akpm/kernel/compat.c                    |   39 ++++++++++++++++++++
 25-akpm/kernel/time.c                      |    6 +--
 20 files changed, 69 insertions(+), 150 deletions(-)

diff -puN arch/ia64/ia32/ia32_entry.S~sys_stime-needs-a-compat-function arch/ia64/ia32/ia32_entry.S
--- 25/arch/ia64/ia32/ia32_entry.S~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.818091888 -0800
+++ 25-akpm/arch/ia64/ia32/ia32_entry.S	2004-12-03 20:55:57.851086872 -0800
@@ -223,7 +223,7 @@ ia32_syscall_table:
 	data8 sys_unlink	  /* 10 */
 	data8 ia32_execve
 	data8 sys_chdir
-	data8 sys32_time
+	data8 compat_sys_time
 	data8 sys_mknod
 	data8 sys_chmod		  /* 15 */
 	data8 sys_lchown	/* 16-bit version */
@@ -235,7 +235,7 @@ ia32_syscall_table:
 	data8 sys_oldumount
 	data8 sys_setuid	/* 16-bit version */
 	data8 sys_getuid	/* 16-bit version */
-	data8 sys_ni_syscall	/* sys_stime is not supported on IA64 */  /* 25 */
+	data8 compat_sys_stime    /* 25 */
 	data8 sys32_ptrace
 	data8 sys32_alarm
 	data8 sys_ni_syscall
diff -puN arch/ia64/ia32/sys_ia32.c~sys_stime-needs-a-compat-function arch/ia64/ia32/sys_ia32.c
--- 25/arch/ia64/ia32/sys_ia32.c~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.820091584 -0800
+++ 25-akpm/arch/ia64/ia32/sys_ia32.c	2004-12-03 20:55:57.853086568 -0800
@@ -1425,27 +1425,6 @@ sys32_ipc(u32 call, int first, int secon
 	return -EINVAL;
 }
 
-/*
- * sys_time() can be implemented in user-level using
- * sys_gettimeofday().  IA64 did this but i386 Linux did not
- * so we have to implement this system call here.
- */
-asmlinkage long
-sys32_time (int __user *tloc)
-{
-	int i;
-	struct timeval tv;
-
-	do_gettimeofday(&tv);
-	i = tv.tv_sec;
-
-	if (tloc) {
-		if (put_user(i, tloc))
-			i = -EFAULT;
-	}
-	return i;
-}
-
 asmlinkage long
 compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options,
 		 struct compat_rusage *ru);
diff -puN arch/mips/kernel/scall64-o32.S~sys_stime-needs-a-compat-function arch/mips/kernel/scall64-o32.S
--- 25/arch/mips/kernel/scall64-o32.S~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.822091280 -0800
+++ 25-akpm/arch/mips/kernel/scall64-o32.S	2004-12-03 20:55:57.853086568 -0800
@@ -236,7 +236,7 @@ sys_call_table:
 	PTR	sys_unlink			/* 4010 */
 	PTR	sys32_execve
 	PTR	sys_chdir
-	PTR	sys_time
+	PTR	compat_sys_time
 	PTR	sys_mknod
 	PTR	sys_chmod			/* 4015 */
 	PTR	sys_lchown
@@ -248,7 +248,7 @@ sys_call_table:
 	PTR	sys_oldumount
 	PTR	sys_setuid
 	PTR	sys_getuid
-	PTR	sys_stime			/* 4025 */
+	PTR	compat_sys_stime		/* 4025 */
 	PTR	sys32_ptrace
 	PTR	sys_alarm
 	PTR	sys_ni_syscall			/* was sys_fstat */
diff -puN arch/parisc/kernel/syscall_table.S~sys_stime-needs-a-compat-function arch/parisc/kernel/syscall_table.S
--- 25/arch/parisc/kernel/syscall_table.S~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.823091128 -0800
+++ 25-akpm/arch/parisc/kernel/syscall_table.S	2004-12-03 20:55:57.854086416 -0800
@@ -74,7 +74,7 @@
 	ENTRY_DIFF(execve_wrapper)
 	ENTRY_SAME(chdir)
 	/* See comments in kernel/time.c!!! Maybe we don't need this? */
-	ENTRY_DIFF(time)
+	ENTRY_COMP(time)
 	ENTRY_SAME(mknod)
 	ENTRY_SAME(chmod)		/* 15 */
 	ENTRY_SAME(lchown)
@@ -91,7 +91,7 @@
 	ENTRY_SAME(bind)
 	ENTRY_SAME(setuid)
 	ENTRY_SAME(getuid)
-	ENTRY_SAME(stime)		/* 25 */
+	ENTRY_COMP(stime)		/* 25 */
 	ENTRY_SAME(ptrace)
 	ENTRY_SAME(alarm)
 	/* see stat comment */
diff -puN arch/parisc/kernel/sys_parisc32.c~sys_stime-needs-a-compat-function arch/parisc/kernel/sys_parisc32.c
--- 25/arch/parisc/kernel/sys_parisc32.c~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.825090824 -0800
+++ 25-akpm/arch/parisc/kernel/sys_parisc32.c	2004-12-03 20:55:57.855086264 -0800
@@ -206,21 +206,6 @@ static inline long get_ts32(struct times
 	return 0;
 }
 
-asmlinkage long sys32_time(compat_time_t *tloc)
-{
-	struct timeval tv;
-	compat_time_t now32;
-
-	do_gettimeofday(&tv);
-	now32 = tv.tv_sec;
-
-	if (tloc)
-		if (put_user(now32, tloc))
-			now32 = -EFAULT;
-
-	return now32;
-}
-
 asmlinkage int
 sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
diff -puN arch/ppc64/kernel/misc.S~sys_stime-needs-a-compat-function arch/ppc64/kernel/misc.S
--- 25/arch/ppc64/kernel/misc.S~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.827090520 -0800
+++ 25-akpm/arch/ppc64/kernel/misc.S	2004-12-03 20:55:57.856086112 -0800
@@ -707,7 +707,7 @@ _GLOBAL(sys_call_table32)
 	.llong .sys_unlink      	/* 10 */
 	.llong .sys32_execve
 	.llong .sys_chdir
-	.llong .sys32_time
+	.llong .compat_sys_time
 	.llong .sys_mknod
 	.llong .sys_chmod		/* 15 */
 	.llong .sys_lchown
@@ -719,7 +719,7 @@ _GLOBAL(sys_call_table32)
 	.llong .sys_oldumount
 	.llong .sys_setuid
 	.llong .sys_getuid
-	.llong .ppc64_sys32_stime       /* 25 */
+	.llong .compat_sys_stime	/* 25 */
 	.llong .sys32_ptrace
 	.llong .sys_alarm
 	.llong .sys_ni_syscall		/* old fstat syscall */
@@ -994,7 +994,7 @@ _GLOBAL(sys_call_table)
 	.llong .sys_ni_syscall		/* old umount syscall */
 	.llong .sys_setuid
 	.llong .sys_getuid
-	.llong .ppc64_sys_stime		/* 25 */
+	.llong .sys_stime		/* 25 */
 	.llong .sys_ptrace
 	.llong .sys_alarm
 	.llong .sys_ni_syscall		/* old fstat syscall */
diff -puN arch/ppc64/kernel/sys_ppc32.c~sys_stime-needs-a-compat-function arch/ppc64/kernel/sys_ppc32.c
--- 25/arch/ppc64/kernel/sys_ppc32.c~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.828090368 -0800
+++ 25-akpm/arch/ppc64/kernel/sys_ppc32.c	2004-12-03 20:55:57.857085960 -0800
@@ -1153,23 +1153,6 @@ asmlinkage long sys32_sysctl(struct __sy
 	return error;
 }
 
-asmlinkage long sys32_time(compat_time_t __user * tloc)
-{
-	compat_time_t secs;
-
-	struct timeval tv;
-
-	do_gettimeofday( &tv );
-	secs = tv.tv_sec;
-
-	if (tloc) {
-		if (put_user(secs,tloc))
-			secs = -EFAULT;
-	}
-
-	return secs;
-}
-
 asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
 {
 	int error;
diff -puN arch/ppc64/kernel/time.c~sys_stime-needs-a-compat-function arch/ppc64/kernel/time.c
--- 25/arch/ppc64/kernel/time.c~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.830090064 -0800
+++ 25-akpm/arch/ppc64/kernel/time.c	2004-12-03 20:55:57.858085808 -0800
@@ -425,60 +425,6 @@ int do_settimeofday(struct timespec *tv)
 
 EXPORT_SYMBOL(do_settimeofday);
 
-/*
- * This function is a copy of the architecture independent function
- * but which calls do_settimeofday rather than setting the xtime
- * fields itself.  This way, the fields which are used for 
- * do_settimeofday get updated too.
- */
-long ppc64_sys32_stime(int __user * tptr)
-{
-	int value;
-	struct timespec myTimeval;
-	int err;
-
-	if (get_user(value, tptr))
-		return -EFAULT;
-
-	myTimeval.tv_sec = value;
-	myTimeval.tv_nsec = 0;
-
-	err = security_settime(&myTimeval, NULL);
-	if (err)
-		return err;
-
-	do_settimeofday(&myTimeval);
-
-	return 0;
-}
-
-/*
- * This function is a copy of the architecture independent function
- * but which calls do_settimeofday rather than setting the xtime
- * fields itself.  This way, the fields which are used for 
- * do_settimeofday get updated too.
- */
-long ppc64_sys_stime(long __user * tptr)
-{
-	long value;
-	struct timespec myTimeval;
-	int err;
-
-	if (get_user(value, tptr))
-		return -EFAULT;
-
-	myTimeval.tv_sec = value;
-	myTimeval.tv_nsec = 0;
-
-	err = security_settime(&myTimeval, NULL);
-	if (err)
-		return err;
-
-	do_settimeofday(&myTimeval);
-
-	return 0;
-}
-
 void __init time_init(void)
 {
 	/* This function is only called on the boot processor */
diff -puN arch/s390/kernel/compat_wrapper.S~sys_stime-needs-a-compat-function arch/s390/kernel/compat_wrapper.S
--- 25/arch/s390/kernel/compat_wrapper.S~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.831089912 -0800
+++ 25-akpm/arch/s390/kernel/compat_wrapper.S	2004-12-03 20:55:57.859085656 -0800
@@ -1076,8 +1076,8 @@ sys32_lstat64_wrapper:
 
 	.globl	sys32_stime_wrapper
 sys32_stime_wrapper:
-	llgtr	%r2,%r2			# int *
-	jg	sys_stime		# branch to system call
+	llgtr	%r2,%r2			# long *
+	jg	compat_sys_stime	# branch to system call
 
 	.globl  sys32_sysctl_wrapper
 sys32_sysctl_wrapper:
diff -puN arch/sparc64/kernel/systbls.S~sys_stime-needs-a-compat-function arch/sparc64/kernel/systbls.S
--- 25/arch/sparc64/kernel/systbls.S~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.833089608 -0800
+++ 25-akpm/arch/sparc64/kernel/systbls.S	2004-12-03 20:55:57.860085504 -0800
@@ -25,7 +25,7 @@ sys_call_table32:
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod
 /*15*/	.word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16
-/*25*/	.word sys_time, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
+/*25*/	.word compat_sys_time, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
 /*30*/	.word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
 	.word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile
 /*40*/	.word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid
@@ -66,7 +66,7 @@ sys_call_table32:
 	.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
 /*220*/	.word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid
 	.word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16
-/*230*/	.word sys32_select, sys_time, sys_nis_syscall, sys_stime, compat_sys_statfs64
+/*230*/	.word sys32_select, compat_sys_time, sys_nis_syscall, compat_sys_stime, compat_sys_statfs64
 	.word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall
 /*240*/	.word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler
 	.word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
diff -puN arch/x86_64/ia32/ia32entry.S~sys_stime-needs-a-compat-function arch/x86_64/ia32/ia32entry.S
--- 25/arch/x86_64/ia32/ia32entry.S~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.834089456 -0800
+++ 25-akpm/arch/x86_64/ia32/ia32entry.S	2004-12-03 20:55:57.860085504 -0800
@@ -315,7 +315,7 @@ ia32_sys_call_table:
 	.quad sys_unlink		/* 10 */
 	.quad stub32_execve
 	.quad sys_chdir
-	.quad sys32_time
+	.quad compat_sys_time
 	.quad sys_mknod
 	.quad sys_chmod		/* 15 */
 	.quad sys_lchown16
@@ -327,7 +327,7 @@ ia32_sys_call_table:
 	.quad sys_oldumount	/* old_umount  */
 	.quad sys_setuid16
 	.quad sys_getuid16
-	.quad sys_stime		/* stime */		/* 25 */
+	.quad compat_sys_stime	/* stime */		/* 25 */
 	.quad sys32_ptrace	/* ptrace */
 	.quad sys_alarm
 	.quad sys_fstat	/* (old)fstat */
diff -puN arch/x86_64/ia32/sys_ia32.c~sys_stime-needs-a-compat-function arch/x86_64/ia32/sys_ia32.c
--- 25/arch/x86_64/ia32/sys_ia32.c~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.836089152 -0800
+++ 25-akpm/arch/x86_64/ia32/sys_ia32.c	2004-12-03 20:55:57.861085352 -0800
@@ -492,26 +492,6 @@ sys32_old_select(struct sel_arg_struct _
 				 compat_ptr(a.exp), compat_ptr(a.tvp));
 }
 
-/*
- * sys_time() can be implemented in user-level using
- * sys_gettimeofday().  x86-64 did this but i386 Linux did not
- * so we have to implement this system call here.
- */
-asmlinkage long sys32_time(int __user * tloc)
-{
-	int i;
-	struct timeval tv;
-
-	do_gettimeofday(&tv);
-	i = tv.tv_sec;
-
-	if (tloc) {
-		if (put_user(i,tloc))
-			i = -EFAULT;
-	}
-	return i;
-}
-
 extern asmlinkage long
 compat_sys_wait4(compat_pid_t pid, compat_uint_t * stat_addr, int options,
 		 struct compat_rusage *ru);
diff -puN include/asm-mips/unistd.h~sys_stime-needs-a-compat-function include/asm-mips/unistd.h
--- 25/include/asm-mips/unistd.h~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.837089000 -0800
+++ 25-akpm/include/asm-mips/unistd.h	2004-12-03 20:55:57.863085048 -0800
@@ -1106,7 +1106,6 @@ type name (atype a,btype b,ctype c,dtype
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
@@ -1122,6 +1121,12 @@ type name (atype a,btype b,ctype c,dtype
 # ifndef __mips64
 #  define __ARCH_WANT_STAT64
 # endif
+# ifdef CONFIG_MIPS32
+#  define __ARCH_WANT_SYS_TIME
+# endif
+# ifdef CONFIG_MIPS32_O32
+#  define __ARCH_WANT_COMPAT_SYS_TIME
+# endif
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
diff -puN include/asm-parisc/unistd.h~sys_stime-needs-a-compat-function include/asm-parisc/unistd.h
--- 25/include/asm-parisc/unistd.h~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.839088696 -0800
+++ 25-akpm/include/asm-parisc/unistd.h	2004-12-03 20:55:57.864084896 -0800
@@ -912,6 +912,7 @@ type name(type1 arg1, type2 arg2, type3 
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
diff -puN include/asm-ppc64/unistd.h~sys_stime-needs-a-compat-function include/asm-ppc64/unistd.h
--- 25/include/asm-ppc64/unistd.h~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.840088544 -0800
+++ 25-akpm/include/asm-ppc64/unistd.h	2004-12-03 20:55:57.864084896 -0800
@@ -431,6 +431,7 @@ static inline _syscall3(int, execve, __c
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
diff -puN include/asm-s390/unistd.h~sys_stime-needs-a-compat-function include/asm-s390/unistd.h
--- 25/include/asm-s390/unistd.h~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.841088392 -0800
+++ 25-akpm/include/asm-s390/unistd.h	2004-12-03 20:55:57.865084744 -0800
@@ -520,7 +520,6 @@ type name(type1 arg1, type2 arg2, type3 
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
@@ -532,9 +531,11 @@ type name(type1 arg1, type2 arg2, type3 
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
-# ifndef CONFIG_ARCH_S390X
+# ifdef CONFIG_ARCH_S390_31
 #   define __ARCH_WANT_STAT64
+#   define __ARCH_WANT_SYS_TIME
 # endif
+# define __ARCH_WANT_COMPAT_SYS_TIME
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
diff -puN include/asm-sparc64/unistd.h~sys_stime-needs-a-compat-function include/asm-sparc64/unistd.h
--- 25/include/asm-sparc64/unistd.h~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.843088088 -0800
+++ 25-akpm/include/asm-sparc64/unistd.h	2004-12-03 20:55:57.866084592 -0800
@@ -489,6 +489,7 @@ asmlinkage long sys_rt_sigaction(int sig
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
diff -puN include/asm-x86_64/unistd.h~sys_stime-needs-a-compat-function include/asm-x86_64/unistd.h
--- 25/include/asm-x86_64/unistd.h~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.844087936 -0800
+++ 25-akpm/include/asm-x86_64/unistd.h	2004-12-03 20:55:57.867084440 -0800
@@ -581,7 +581,6 @@ do { \
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
@@ -594,6 +593,7 @@ do { \
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_COMPAT_SYS_TIME
 #endif
 
 #ifndef __KERNEL_SYSCALLS__
diff -puN kernel/compat.c~sys_stime-needs-a-compat-function kernel/compat.c
--- 25/kernel/compat.c~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.846087632 -0800
+++ 25-akpm/kernel/compat.c	2004-12-03 20:55:57.867084440 -0800
@@ -680,3 +680,42 @@ long compat_put_bitmap(compat_ulong_t __
 
 	return 0;
 }
+
+#ifdef __ARCH_WANT_COMPAT_SYS_TIME
+
+/* compat_time_t is a 32 bit "long" and needs to get converted. */
+
+asmlinkage long compat_sys_time(compat_time_t __user * tloc)
+{
+	compat_time_t i;
+	struct timeval tv;
+
+	do_gettimeofday(&tv);
+	i = tv.tv_sec;
+
+	if (tloc) {
+		if (put_user(i,tloc))
+			i = -EFAULT;
+	}
+	return i;
+}
+
+asmlinkage long compat_sys_stime(compat_time_t __user *tptr)
+{
+	struct timespec tv;
+	int err;
+
+	if (get_user(tv.tv_sec, tptr))
+		return -EFAULT;
+
+	tv.tv_nsec = 0;
+
+	err = security_settime(&tv, NULL);
+	if (err)
+		return err;
+
+	do_settimeofday(&tv);
+	return 0;
+}
+
+#endif /* __ARCH_WANT_COMPAT_SYS_TIME */
diff -puN kernel/time.c~sys_stime-needs-a-compat-function kernel/time.c
--- 25/kernel/time.c~sys_stime-needs-a-compat-function	2004-12-03 20:55:57.847087480 -0800
+++ 25-akpm/kernel/time.c	2004-12-03 20:55:57.868084288 -0800
@@ -52,12 +52,10 @@ EXPORT_SYMBOL(sys_tz);
  * sys_gettimeofday().  Is this for backwards compatibility?  If so,
  * why not move it into the appropriate arch directory (for those
  * architectures that need it).
- *
- * XXX This function is NOT 64-bit clean!
  */
-asmlinkage long sys_time(int __user * tloc)
+asmlinkage long sys_time(time_t __user * tloc)
 {
-	int i;
+	time_t i;
 	struct timeval tv;
 
 	do_gettimeofday(&tv);
_
