X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fcompat.c;h=32c254a8ab9af07ae3ac102972063956592e0b3b;hb=13b3c3fa27f8f4ed306ce624f446fab000dd8ee4;hp=3bae3742c2aa567e18f7b1558f7fa72b1c9155a0;hpb=5e16e3f0e24dadb79b96b6134cd3303f0d42f0c5;p=linux-2.6-omap-h63xx.git diff --git a/kernel/compat.c b/kernel/compat.c index 3bae3742c2a..32c254a8ab9 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -42,60 +42,59 @@ int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user static long compat_nanosleep_restart(struct restart_block *restart) { - unsigned long expire = restart->arg0, now = jiffies; struct compat_timespec __user *rmtp; + struct timespec rmt; + mm_segment_t oldfs; + long ret; - /* Did it expire while we handled signals? */ - if (!time_after(expire, now)) - return 0; - - expire = schedule_timeout_interruptible(expire - now); - if (expire == 0) - return 0; + restart->nanosleep.rmtp = (struct timespec __user *) &rmt; + oldfs = get_fs(); + set_fs(KERNEL_DS); + ret = hrtimer_nanosleep_restart(restart); + set_fs(oldfs); - rmtp = (struct compat_timespec __user *)restart->arg1; - if (rmtp) { - struct compat_timespec ct; - struct timespec t; + if (ret) { + rmtp = restart->nanosleep.compat_rmtp; - jiffies_to_timespec(expire, &t); - ct.tv_sec = t.tv_sec; - ct.tv_nsec = t.tv_nsec; - if (copy_to_user(rmtp, &ct, sizeof(ct))) + if (rmtp && put_compat_timespec(&rmt, rmtp)) return -EFAULT; } - /* The 'restart' block is already filled in */ - return -ERESTART_RESTARTBLOCK; + + return ret; } asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, - struct compat_timespec __user *rmtp) + struct compat_timespec __user *rmtp) { - struct timespec t; - struct restart_block *restart; - unsigned long expire; + struct timespec tu, rmt; + mm_segment_t oldfs; + long ret; - if (get_compat_timespec(&t, rqtp)) + if (get_compat_timespec(&tu, rqtp)) return -EFAULT; - if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0)) + if (!timespec_valid(&tu)) return -EINVAL; - expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec); - expire = schedule_timeout_interruptible(expire); - if (expire == 0) - return 0; + oldfs = get_fs(); + set_fs(KERNEL_DS); + ret = hrtimer_nanosleep(&tu, + rmtp ? (struct timespec __user *)&rmt : NULL, + HRTIMER_MODE_REL, CLOCK_MONOTONIC); + set_fs(oldfs); + + if (ret) { + struct restart_block *restart + = ¤t_thread_info()->restart_block; - if (rmtp) { - jiffies_to_timespec(expire, &t); - if (put_compat_timespec(&t, rmtp)) + restart->fn = compat_nanosleep_restart; + restart->nanosleep.compat_rmtp = rmtp; + + if (rmtp && put_compat_timespec(&rmt, rmtp)) return -EFAULT; } - restart = ¤t_thread_info()->restart_block; - restart->fn = compat_nanosleep_restart; - restart->arg0 = jiffies + expire; - restart->arg1 = (unsigned long) rmtp; - return -ERESTART_RESTARTBLOCK; + + return ret; } static inline long get_compat_itimerval(struct itimerval *o, @@ -247,8 +246,8 @@ asmlinkage long compat_sys_setrlimit(unsigned int resource, int ret; mm_segment_t old_fs = get_fs (); - if (resource >= RLIM_NLIMITS) - return -EINVAL; + if (resource >= RLIM_NLIMITS) + return -EINVAL; if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) || __get_user(r.rlim_cur, &rlim->rlim_cur) || @@ -446,7 +445,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, @@ -477,21 +476,21 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, int get_compat_itimerspec(struct itimerspec *dst, const struct compat_itimerspec __user *src) -{ +{ if (get_compat_timespec(&dst->it_interval, &src->it_interval) || get_compat_timespec(&dst->it_value, &src->it_value)) return -EFAULT; return 0; -} +} int put_compat_itimerspec(struct compat_itimerspec __user *dst, const struct itimerspec *src) -{ +{ if (put_compat_timespec(&src->it_interval, &dst->it_interval) || put_compat_timespec(&src->it_value, &dst->it_value)) return -EFAULT; return 0; -} +} long compat_sys_timer_create(clockid_t which_clock, struct compat_sigevent __user *timer_event_spec, @@ -512,9 +511,9 @@ long compat_sys_timer_create(clockid_t which_clock, } long compat_sys_timer_settime(timer_t timer_id, int flags, - struct compat_itimerspec __user *new, + struct compat_itimerspec __user *new, struct compat_itimerspec __user *old) -{ +{ long err; mm_segment_t oldfs; struct itimerspec newts, oldts; @@ -522,58 +521,58 @@ long compat_sys_timer_settime(timer_t timer_id, int flags, if (!new) return -EINVAL; if (get_compat_itimerspec(&newts, new)) - return -EFAULT; + return -EFAULT; oldfs = get_fs(); set_fs(KERNEL_DS); err = sys_timer_settime(timer_id, flags, (struct itimerspec __user *) &newts, (struct itimerspec __user *) &oldts); - set_fs(oldfs); + set_fs(oldfs); if (!err && old && put_compat_itimerspec(old, &oldts)) return -EFAULT; return err; -} +} long compat_sys_timer_gettime(timer_t timer_id, struct compat_itimerspec __user *setting) -{ +{ long err; mm_segment_t oldfs; - struct itimerspec ts; + struct itimerspec ts; oldfs = get_fs(); set_fs(KERNEL_DS); err = sys_timer_gettime(timer_id, - (struct itimerspec __user *) &ts); - set_fs(oldfs); + (struct itimerspec __user *) &ts); + set_fs(oldfs); if (!err && put_compat_itimerspec(setting, &ts)) return -EFAULT; return err; -} +} long compat_sys_clock_settime(clockid_t which_clock, struct compat_timespec __user *tp) { long err; mm_segment_t oldfs; - struct timespec ts; + struct timespec ts; if (get_compat_timespec(&ts, tp)) - return -EFAULT; + return -EFAULT; oldfs = get_fs(); - set_fs(KERNEL_DS); + set_fs(KERNEL_DS); err = sys_clock_settime(which_clock, (struct timespec __user *) &ts); set_fs(oldfs); return err; -} +} long compat_sys_clock_gettime(clockid_t which_clock, struct compat_timespec __user *tp) { long err; mm_segment_t oldfs; - struct timespec ts; + struct timespec ts; oldfs = get_fs(); set_fs(KERNEL_DS); @@ -581,16 +580,16 @@ long compat_sys_clock_gettime(clockid_t which_clock, (struct timespec __user *) &ts); set_fs(oldfs); if (!err && put_compat_timespec(&ts, tp)) - return -EFAULT; + return -EFAULT; return err; -} +} long compat_sys_clock_getres(clockid_t which_clock, struct compat_timespec __user *tp) { long err; mm_segment_t oldfs; - struct timespec ts; + struct timespec ts; oldfs = get_fs(); set_fs(KERNEL_DS); @@ -598,18 +597,18 @@ long compat_sys_clock_getres(clockid_t which_clock, (struct timespec __user *) &ts); set_fs(oldfs); if (!err && tp && put_compat_timespec(&ts, tp)) - return -EFAULT; + return -EFAULT; return err; -} +} 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 +620,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; } @@ -632,10 +631,10 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, { long err; mm_segment_t oldfs; - struct timespec in, out; + struct timespec in, out; struct restart_block *restart; - if (get_compat_timespec(&in, rqtp)) + if (get_compat_timespec(&in, rqtp)) return -EFAULT; oldfs = get_fs(); @@ -652,10 +651,10 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, if (err == -ERESTART_RESTARTBLOCK) { restart = ¤t_thread_info()->restart_block; restart->fn = compat_clock_nanosleep_restart; - restart->arg1 = (unsigned long) rmtp; + restart->nanosleep.compat_rmtp = rmtp; } - return err; -} + return err; +} /* * We currently only need the following fields from the sigevent @@ -899,7 +898,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 +955,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 +1081,3 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info) return 0; } -