]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/compat.c
[SCSI] aic79xx: user visible misuse wrong SI units (not disk size!)
[linux-2.6-omap-h63xx.git] / kernel / compat.c
index 5f0e201bcfd3b883418b16f04c32da51cf2353be..143990e48cb9aab2af2f04d93a372d63dc570882 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)) ||
@@ -47,15 +105,14 @@ static long compat_nanosleep_restart(struct restart_block *restart)
        mm_segment_t oldfs;
        long ret;
 
-       rmtp = (struct compat_timespec __user *)(restart->arg1);
-       restart->arg1 = (unsigned long)&rmt;
+       restart->nanosleep.rmtp = (struct timespec __user *) &rmt;
        oldfs = get_fs();
        set_fs(KERNEL_DS);
        ret = hrtimer_nanosleep_restart(restart);
        set_fs(oldfs);
 
        if (ret) {
-               restart->arg1 = (unsigned long)rmtp;
+               rmtp = restart->nanosleep.compat_rmtp;
 
                if (rmtp && put_compat_timespec(&rmt, rmtp))
                        return -EFAULT;
@@ -89,7 +146,7 @@ asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
                        = &current_thread_info()->restart_block;
 
                restart->fn = compat_nanosleep_restart;
-               restart->arg1 = (unsigned long)rmtp;
+               restart->nanosleep.compat_rmtp = rmtp;
 
                if (rmtp && put_compat_timespec(&rmt, rmtp))
                        return -EFAULT;
@@ -446,7 +503,7 @@ asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
        if (retval)
                return retval;
 
-       return sched_setaffinity(pid, new_mask);
+       return sched_setaffinity(pid, &new_mask);
 }
 
 asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
@@ -607,9 +664,9 @@ static long compat_clock_nanosleep_restart(struct restart_block *restart)
        long err;
        mm_segment_t oldfs;
        struct timespec tu;
-       struct compat_timespec *rmtp = (struct compat_timespec *)(restart->arg1);
+       struct compat_timespec *rmtp = restart->nanosleep.compat_rmtp;
 
-       restart->arg1 = (unsigned long) &tu;
+       restart->nanosleep.rmtp = (struct timespec __user *) &tu;
        oldfs = get_fs();
        set_fs(KERNEL_DS);
        err = clock_nanosleep_restart(restart);
@@ -621,7 +678,7 @@ static long compat_clock_nanosleep_restart(struct restart_block *restart)
 
        if (err == -ERESTART_RESTARTBLOCK) {
                restart->fn = compat_clock_nanosleep_restart;
-               restart->arg1 = (unsigned long) rmtp;
+               restart->nanosleep.compat_rmtp = rmtp;
        }
        return err;
 }
@@ -652,7 +709,7 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
        if (err == -ERESTART_RESTARTBLOCK) {
                restart = &current_thread_info()->restart_block;
                restart->fn = compat_clock_nanosleep_restart;
-               restart->arg1 = (unsigned long) rmtp;
+               restart->nanosleep.compat_rmtp = rmtp;
        }
        return err;
 }
@@ -899,7 +956,7 @@ asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
-       set_thread_flag(TIF_RESTORE_SIGMASK);
+       set_restore_sigmask();
        return -ERESTARTNOHAND;
 }
 #endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */
@@ -956,7 +1013,8 @@ asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp)
                        __put_user(txc.jitcnt, &utp->jitcnt) ||
                        __put_user(txc.calcnt, &utp->calcnt) ||
                        __put_user(txc.errcnt, &utp->errcnt) ||
-                       __put_user(txc.stbcnt, &utp->stbcnt))
+                       __put_user(txc.stbcnt, &utp->stbcnt) ||
+                       __put_user(txc.tai, &utp->tai))
                ret = -EFAULT;
 
        return ret;
@@ -1081,4 +1139,3 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
 
        return 0;
 }
-