compat: generic compat get/settimeofday
Christoph Hellwig [Thu, 16 Oct 2008 05:02:06 +0000 (22:02 -0700)]
Nothing arch specific in get/settimeofday.  The details of the timeval
conversion varied a little from arch to arch, but all with the same
results.

Also add an extern declaration for sys_tz to linux/time.h because externs
in .c files are fowned upon.  I'll kill the externs in various other files
in a sparate patch.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: David S. Miller <davem@davemloft.net> [ sparc bits ]
Cc: "Luck, Tony" <tony.luck@intel.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Kyle McMartin <kyle@mcmartin.ca>
Cc: Matthew Wilcox <matthew@wil.cx>
Cc: Grant Grundler <grundler@parisc-linux.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

19 files changed:
arch/ia64/ia32/ia32_entry.S
arch/ia64/ia32/sys_ia32.c
arch/mips/kernel/linux32.c
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/parisc/kernel/sys_parisc32.c
arch/parisc/kernel/syscall_table.S
arch/powerpc/kernel/sys_ppc32.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_linux.h
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/syscalls.S
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/systbls.S
arch/x86/ia32/ia32entry.S
arch/x86/ia32/sys_ia32.c
include/linux/compat.h
include/linux/time.h
kernel/compat.c

index ff88c48..53505bb 100644 (file)
@@ -251,8 +251,8 @@ ia32_syscall_table:
        data8 compat_sys_setrlimit        /* 75 */
        data8 compat_sys_old_getrlimit
        data8 compat_sys_getrusage
-       data8 sys32_gettimeofday
-       data8 sys32_settimeofday
+       data8 compat_sys_gettimeofday
+       data8 compat_sys_settimeofday
        data8 sys32_getgroups16   /* 80 */
        data8 sys32_setgroups16
        data8 sys32_old_select
index 2362a8e..f4430bb 100644 (file)
@@ -1113,68 +1113,12 @@ sys32_pipe (int __user *fd)
        return retval;
 }
 
-static inline long
-get_tv32 (struct timeval *o, struct compat_timeval __user *i)
-{
-       return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
-               (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec)));
-}
-
-static inline long
-put_tv32 (struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec)));
-}
-
 asmlinkage unsigned long
 sys32_alarm (unsigned int seconds)
 {
        return alarm_setitimer(seconds);
 }
 
-/* Translations due to time_t size differences.  Which affects all
-   sorts of things, like timeval and itimerval.  */
-
-extern struct timezone sys_tz;
-
-asmlinkage long
-sys32_gettimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-asmlinkage long
-sys32_settimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timeval ktv;
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_tv32(&ktv, tv))
-                       return -EFAULT;
-               kts.tv_sec = ktv.tv_sec;
-               kts.tv_nsec = ktv.tv_usec * 1000;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 struct sel_arg_struct {
        unsigned int n;
        unsigned int inp;
index 89223a9..aa2c55e 100644 (file)
@@ -133,72 +133,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
        return sys_ftruncate(fd, merge_64(a2, a3));
 }
 
-static inline long
-get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
-       return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
-               (__get_user(o->tv_sec, &i->tv_sec) |
-                __get_user(o->tv_usec, &i->tv_usec)));
-}
-
-static inline long
-put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) |
-                __put_user(i->tv_usec, &o->tv_usec)));
-}
-
-extern struct timezone sys_tz;
-
-asmlinkage int
-sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (!access_ok(VERIFY_READ, i, sizeof(*i)))
-               return -EFAULT;
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-               return 0;
-}
-
-asmlinkage int
-sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
                            unsigned int offset_low, loff_t __user * result,
                            unsigned int origin)
index 324c549..e266b3a 100644 (file)
@@ -214,7 +214,7 @@ EXPORT(sysn32_call_table)
        PTR     sys_fchown
        PTR     sys_lchown
        PTR     sys_umask
-       PTR     sys32_gettimeofday
+       PTR     compat_sys_gettimeofday
        PTR     compat_sys_getrlimit            /* 6095 */
        PTR     compat_sys_getrusage
        PTR     compat_sys_sysinfo
@@ -279,7 +279,7 @@ EXPORT(sysn32_call_table)
        PTR     sys_chroot
        PTR     sys_sync
        PTR     sys_acct
-       PTR     sys32_settimeofday
+       PTR     compat_sys_settimeofday
        PTR     compat_sys_mount                /* 6160 */
        PTR     sys_umount
        PTR     sys_swapon
index 85fedac..6c7ef83 100644 (file)
@@ -283,8 +283,8 @@ sys_call_table:
        PTR     compat_sys_setrlimit            /* 4075 */
        PTR     compat_sys_getrlimit
        PTR     compat_sys_getrusage
-       PTR     sys32_gettimeofday
-       PTR     sys32_settimeofday
+       PTR     compat_sys_gettimeofday
+       PTR     compat_sys_settimeofday
        PTR     sys_getgroups                   /* 4080 */
        PTR     sys_setgroups
        PTR     sys_ni_syscall                  /* old_select */
index 2c3af17..0838155 100644 (file)
@@ -179,64 +179,6 @@ asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
        return ret;
 }
 
-static int
-put_compat_timeval(struct compat_timeval __user *u, struct timeval *t)
-{
-       struct compat_timeval t32;
-       t32.tv_sec = t->tv_sec;
-       t32.tv_usec = t->tv_usec;
-       return copy_to_user(u, &t32, sizeof t32);
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-       return 0;
-}
-
-asmlinkage int
-sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-    extern void do_gettimeofday(struct timeval *tv);
-
-    if (tv) {
-           struct timeval ktv;
-           do_gettimeofday(&ktv);
-           if (put_compat_timeval(tv, &ktv))
-                   return -EFAULT;
-    }
-    if (tz) {
-           extern struct timezone sys_tz;
-           if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                   return -EFAULT;
-    }
-    return 0;
-}
-
-asmlinkage 
-int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 /*** copied from mips64 ***/
 /*
  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
index 6b5ac38..c7e59f5 100644 (file)
        ENTRY_COMP(getrlimit)
        ENTRY_COMP(getrusage)
        /* struct timeval and timezone are maybe?? consistent wide and narrow */
-       ENTRY_DIFF(gettimeofday)
-       ENTRY_DIFF(settimeofday)
+       ENTRY_COMP(gettimeofday)
+       ENTRY_COMP(settimeofday)
        ENTRY_SAME(getgroups)           /* 80 */
        ENTRY_SAME(setgroups)
        /* struct socketaddr... */
index d00599b..bb1cfcf 100644 (file)
@@ -71,69 +71,6 @@ asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2)
        return sys_sysfs((int)option, arg1, arg2);
 }
 
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (!access_ok(VERIFY_READ, i, sizeof(*i)))
-               return -EFAULT;
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-       return 0;
-}
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) |
-                __put_user(i->tv_usec, &o->tv_usec)));
-}
-
-
-
-
-/* Translations due to time_t size differences.  Which affects all
-   sorts of things, like timeval and itimerval.  */
-extern struct timezone sys_tz;
-
-asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       
-       return 0;
-}
-
-
-
-asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-       
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 #ifdef CONFIG_SYSVIPC
 long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
               u32 fifth)
index 9b471d7..4646382 100644 (file)
@@ -279,22 +279,6 @@ asmlinkage long sys32_getegid16(void)
        return high2lowgid(current->egid);
 }
 
-/* 32-bit timeval and related flotsam.  */
-
-static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
-       return (!access_ok(VERIFY_READ, o, sizeof(*o)) ||
-               (__get_user(o->tv_sec, &i->tv_sec) ||
-                __get_user(o->tv_usec, &i->tv_usec)));
-}
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) ||
-                __put_user(i->tv_usec, &o->tv_usec)));
-}
-
 /*
  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation.
  *
@@ -522,57 +506,6 @@ sys32_delete_module(const char __user *name_user, unsigned int flags)
 
 #endif  /* CONFIG_MODULES */
 
-/* Translations due to time_t size differences.  Which affects all
-   sorts of things, like timeval and itimerval.  */
-
-extern struct timezone sys_tz;
-
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (!access_ok(VERIFY_READ, i, sizeof(*i)))
-               return -EFAULT;
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-       return 0;
-}
-
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
                                size_t count, u32 poshi, u32 poslo)
 {
index 05f8516..836a288 100644 (file)
@@ -202,10 +202,6 @@ long sys32_execve(void);
 long sys32_init_module(void __user *umod, unsigned long len,
                       const char __user *uargs);
 long sys32_delete_module(const char __user *name_user, unsigned int flags);
-long sys32_gettimeofday(struct compat_timeval __user *tv,
-                       struct timezone __user *tz);
-long sys32_settimeofday(struct compat_timeval __user *tv,
-                       struct timezone __user *tz);
 long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count,
                   u32 poshi, u32 poslo);
 long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
index ee51ca9..fc2c971 100644 (file)
@@ -332,17 +332,17 @@ compat_sys_getrusage_wrapper:
        llgtr   %r3,%r3                 # struct rusage_emu31 *
        jg      compat_sys_getrusage    # branch to system call
 
-       .globl  sys32_gettimeofday_wrapper
-sys32_gettimeofday_wrapper:
+       .globl  compat_sys_gettimeofday_wrapper
+compat_sys_gettimeofday_wrapper:
        llgtr   %r2,%r2                 # struct timeval_emu31 *
        llgtr   %r3,%r3                 # struct timezone *
-       jg      sys32_gettimeofday      # branch to system call
+       jg      compat_sys_gettimeofday # branch to system call
 
-       .globl  sys32_settimeofday_wrapper
-sys32_settimeofday_wrapper:
+       .globl  compat_sys_settimeofday_wrapper
+compat_sys_settimeofday_wrapper:
        llgtr   %r2,%r2                 # struct timeval_emu31 *
        llgtr   %r3,%r3                 # struct timezone *
-       jg      sys32_settimeofday      # branch to system call
+       jg      compat_sys_settimeofday # branch to system call
 
        .globl  sys32_getgroups16_wrapper
 sys32_getgroups16_wrapper:
index 3ae3039..2d61787 100644 (file)
@@ -86,8 +86,8 @@ SYSCALL(sys_sethostname,sys_sethostname,sys32_sethostname_wrapper)
 SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit_wrapper)      /* 75 */
 SYSCALL(sys_old_getrlimit,sys_getrlimit,compat_sys_old_getrlimit_wrapper)
 SYSCALL(sys_getrusage,sys_getrusage,compat_sys_getrusage_wrapper)
-SYSCALL(sys_gettimeofday,sys_gettimeofday,sys32_gettimeofday_wrapper)
-SYSCALL(sys_settimeofday,sys_settimeofday,sys32_settimeofday_wrapper)
+SYSCALL(sys_gettimeofday,sys_gettimeofday,compat_sys_gettimeofday_wrapper)
+SYSCALL(sys_settimeofday,sys_settimeofday,compat_sys_settimeofday_wrapper)
 SYSCALL(sys_getgroups16,sys_ni_syscall,sys32_getgroups16_wrapper)      /* 80 old getgroups16 syscall */
 SYSCALL(sys_setgroups16,sys_ni_syscall,sys32_setgroups16_wrapper)      /* old setgroups16 syscall */
 NI_SYSCALL                                                     /* old select syscall */
index 73a33dc..e800503 100644 (file)
 #include <asm/mmu_context.h>
 #include <asm/compat_signal.h>
 
-/* 32-bit timeval and related flotsam.  */
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) |
-                __put_user(i->tv_usec, &o->tv_usec)));
-}
-
 #ifdef CONFIG_SYSVIPC                                                        
 asmlinkage long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth)
 {
@@ -487,59 +478,6 @@ asmlinkage long sys32_delete_module(const char __user *name_user)
 
 #endif  /* CONFIG_MODULES */
 
-/* Translations due to time_t size differences.  Which affects all
-   sorts of things, like timeval and itimerval.  */
-
-extern struct timezone sys_tz;
-
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv,
-                                  struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (!access_ok(VERIFY_READ, i, sizeof(*i)))
-               return -EFAULT;
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-       return 0;
-}
-
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
-                                  struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 asmlinkage compat_ssize_t sys32_pread64(unsigned int fd,
                                        char __user *ubuf,
                                        compat_size_t count,
index 5daee4b..b2fa4c1 100644 (file)
@@ -41,8 +41,8 @@ sys_call_table32:
 /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
        .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid
 /*110*/        .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
-       .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
-/*120*/        .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys_fchown16, sys_fchmod
+       .word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
+/*120*/        .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod
        .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
 /*130*/        .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
        .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
index eb43147..256b00b 100644 (file)
@@ -571,8 +571,8 @@ ia32_sys_call_table:
        .quad compat_sys_setrlimit      /* 75 */
        .quad compat_sys_old_getrlimit  /* old_getrlimit */
        .quad compat_sys_getrusage
-       .quad sys32_gettimeofday
-       .quad sys32_settimeofday
+       .quad compat_sys_gettimeofday
+       .quad compat_sys_settimeofday
        .quad sys_getgroups16   /* 80 */
        .quad sys_setgroups16
        .quad sys32_old_select
index 4d3ad8d..2e09dcd 100644 (file)
@@ -367,75 +367,11 @@ asmlinkage long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
        return 0;
 }
 
-static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
-       int err = -EFAULT;
-
-       if (access_ok(VERIFY_READ, i, sizeof(*i))) {
-               err = __get_user(o->tv_sec, &i->tv_sec);
-               err |= __get_user(o->tv_usec, &i->tv_usec);
-       }
-       return err;
-}
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       int err = -EFAULT;
-
-       if (access_ok(VERIFY_WRITE, o, sizeof(*o))) {
-               err = __put_user(i->tv_sec, &o->tv_sec);
-               err |= __put_user(i->tv_usec, &o->tv_usec);
-       }
-       return err;
-}
-
 asmlinkage long sys32_alarm(unsigned int seconds)
 {
        return alarm_setitimer(seconds);
 }
 
-/*
- * Translations due to time_t size differences. Which affects all
- * sorts of things, like timeval and itimerval.
- */
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv,
-                                  struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
-                                  struct timezone __user *tz)
-{
-       struct timeval ktv;
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_tv32(&ktv, tv))
-                       return -EFAULT;
-               kts.tv_sec = ktv.tv_sec;
-               kts.tv_nsec = ktv.tv_usec * NSEC_PER_USEC;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 struct sel_arg_struct {
        unsigned int n;
        unsigned int inp;
index 999dddd..f061a1e 100644 (file)
@@ -234,6 +234,11 @@ extern int get_compat_itimerspec(struct itimerspec *dst,
 extern int put_compat_itimerspec(struct compat_itimerspec __user *dst,
                                 const struct itimerspec *src);
 
+asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
+               struct timezone __user *tz);
+asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
+               struct timezone __user *tz);
+
 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
 
 extern int compat_printk(const char *fmt, ...);
index e15206a..51e883d 100644 (file)
@@ -29,6 +29,8 @@ struct timezone {
 
 #ifdef __KERNEL__
 
+extern struct timezone sys_tz;
+
 /* Parameters used to convert the timespec values: */
 #define MSEC_PER_SEC   1000L
 #define USEC_PER_MSEC  1000L
index 32c254a..143990e 100644 (file)
 
 #include <asm/uaccess.h>
 
+/*
+ * Note that the native side is already converted to a timespec, because
+ * that's what we want anyway.
+ */
+static int compat_get_timeval(struct timespec *o,
+               struct compat_timeval __user *i)
+{
+       long usec;
+
+       if (get_user(o->tv_sec, &i->tv_sec) ||
+           get_user(usec, &i->tv_usec))
+               return -EFAULT;
+       o->tv_nsec = usec * 1000;
+       return 0;
+}
+
+static int compat_put_timeval(struct compat_timeval __user *o,
+               struct timeval *i)
+{
+       return (put_user(i->tv_sec, &o->tv_sec) ||
+               put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0;
+}
+
+asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
+               struct timezone __user *tz)
+{
+       if (tv) {
+               struct timeval ktv;
+               do_gettimeofday(&ktv);
+               if (compat_put_timeval(tv, &ktv))
+                       return -EFAULT;
+       }
+       if (tz) {
+               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
+                       return -EFAULT;
+       }
+
+       return 0;
+}
+
+asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
+               struct timezone __user *tz)
+{
+       struct timespec kts;
+       struct timezone ktz;
+
+       if (tv) {
+               if (compat_get_timeval(&kts, tv))
+                       return -EFAULT;
+       }
+       if (tz) {
+               if (copy_from_user(&ktz, tz, sizeof(ktz)))
+                       return -EFAULT;
+       }
+
+       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
+}
+
 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
 {
        return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||