X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=kernel%2Fhrtimer.c;h=b2b2c2b0a49bc845f0ba277f96b8db2d1d2f6803;hb=762a24beed3f3ab93224bd447710e6c36fcf1968;hp=dc8a4451d79b15d64a37caf55c9dc4595c6ec5d2;hpb=ce9d3c9a6a9aef61525be07fe6ba27d937236aa2;p=powerpc.git diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index dc8a4451d7..b2b2c2b0a4 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1286,8 +1286,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod long __sched hrtimer_nanosleep_restart(struct restart_block *restart) { struct hrtimer_sleeper t; - struct timespec __user *rmtp; - struct timespec tu; + struct timespec *rmtp; ktime_t time; restart->fn = do_no_restart_syscall; @@ -1298,14 +1297,12 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) if (do_nanosleep(&t, HRTIMER_MODE_ABS)) return 0; - rmtp = (struct timespec __user *) restart->arg1; + rmtp = (struct timespec *)restart->arg1; if (rmtp) { time = ktime_sub(t.timer.expires, t.timer.base->get_time()); if (time.tv64 <= 0) return 0; - tu = ktime_to_timespec(time); - if (copy_to_user(rmtp, &tu, sizeof(tu))) - return -EFAULT; + *rmtp = ktime_to_timespec(time); } restart->fn = hrtimer_nanosleep_restart; @@ -1314,12 +1311,11 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) return -ERESTART_RESTARTBLOCK; } -long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, +long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, const enum hrtimer_mode mode, const clockid_t clockid) { struct restart_block *restart; struct hrtimer_sleeper t; - struct timespec tu; ktime_t rem; hrtimer_init(&t.timer, clockid, mode); @@ -1335,9 +1331,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, rem = ktime_sub(t.timer.expires, t.timer.base->get_time()); if (rem.tv64 <= 0) return 0; - tu = ktime_to_timespec(rem); - if (copy_to_user(rmtp, &tu, sizeof(tu))) - return -EFAULT; + *rmtp = ktime_to_timespec(rem); } restart = ¤t_thread_info()->restart_block; @@ -1353,7 +1347,8 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) { - struct timespec tu; + struct timespec tu, rmt; + int ret; if (copy_from_user(&tu, rqtp, sizeof(tu))) return -EFAULT; @@ -1361,7 +1356,15 @@ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) if (!timespec_valid(&tu)) return -EINVAL; - return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC); + ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, + CLOCK_MONOTONIC); + + if (ret && rmtp) { + if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) + return -EFAULT; + } + + return ret; } /*