diff options
-rw-r--r-- | include/linux/hrtimer.h | 2 | ||||
-rw-r--r-- | kernel/hrtimer.c | 29 | ||||
-rw-r--r-- | kernel/posix-timers.c | 17 |
3 files changed, 31 insertions, 17 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 540799bc85f8..7a9398e19704 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -300,7 +300,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); | |||
300 | 300 | ||
301 | /* Precise sleep: */ | 301 | /* Precise sleep: */ |
302 | extern long hrtimer_nanosleep(struct timespec *rqtp, | 302 | extern long hrtimer_nanosleep(struct timespec *rqtp, |
303 | struct timespec __user *rmtp, | 303 | struct timespec *rmtp, |
304 | const enum hrtimer_mode mode, | 304 | const enum hrtimer_mode mode, |
305 | const clockid_t clockid); | 305 | const clockid_t clockid); |
306 | extern long hrtimer_nanosleep_restart(struct restart_block *restart_block); | 306 | extern long hrtimer_nanosleep_restart(struct restart_block *restart_block); |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index dc8a4451d79b..b2b2c2b0a49b 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 | |||
1286 | long __sched hrtimer_nanosleep_restart(struct restart_block *restart) | 1286 | long __sched hrtimer_nanosleep_restart(struct restart_block *restart) |
1287 | { | 1287 | { |
1288 | struct hrtimer_sleeper t; | 1288 | struct hrtimer_sleeper t; |
1289 | struct timespec __user *rmtp; | 1289 | struct timespec *rmtp; |
1290 | struct timespec tu; | ||
1291 | ktime_t time; | 1290 | ktime_t time; |
1292 | 1291 | ||
1293 | restart->fn = do_no_restart_syscall; | 1292 | restart->fn = do_no_restart_syscall; |
@@ -1298,14 +1297,12 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) | |||
1298 | if (do_nanosleep(&t, HRTIMER_MODE_ABS)) | 1297 | if (do_nanosleep(&t, HRTIMER_MODE_ABS)) |
1299 | return 0; | 1298 | return 0; |
1300 | 1299 | ||
1301 | rmtp = (struct timespec __user *) restart->arg1; | 1300 | rmtp = (struct timespec *)restart->arg1; |
1302 | if (rmtp) { | 1301 | if (rmtp) { |
1303 | time = ktime_sub(t.timer.expires, t.timer.base->get_time()); | 1302 | time = ktime_sub(t.timer.expires, t.timer.base->get_time()); |
1304 | if (time.tv64 <= 0) | 1303 | if (time.tv64 <= 0) |
1305 | return 0; | 1304 | return 0; |
1306 | tu = ktime_to_timespec(time); | 1305 | *rmtp = ktime_to_timespec(time); |
1307 | if (copy_to_user(rmtp, &tu, sizeof(tu))) | ||
1308 | return -EFAULT; | ||
1309 | } | 1306 | } |
1310 | 1307 | ||
1311 | restart->fn = hrtimer_nanosleep_restart; | 1308 | restart->fn = hrtimer_nanosleep_restart; |
@@ -1314,12 +1311,11 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) | |||
1314 | return -ERESTART_RESTARTBLOCK; | 1311 | return -ERESTART_RESTARTBLOCK; |
1315 | } | 1312 | } |
1316 | 1313 | ||
1317 | long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, | 1314 | long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, |
1318 | const enum hrtimer_mode mode, const clockid_t clockid) | 1315 | const enum hrtimer_mode mode, const clockid_t clockid) |
1319 | { | 1316 | { |
1320 | struct restart_block *restart; | 1317 | struct restart_block *restart; |
1321 | struct hrtimer_sleeper t; | 1318 | struct hrtimer_sleeper t; |
1322 | struct timespec tu; | ||
1323 | ktime_t rem; | 1319 | ktime_t rem; |
1324 | 1320 | ||
1325 | hrtimer_init(&t.timer, clockid, mode); | 1321 | hrtimer_init(&t.timer, clockid, mode); |
@@ -1335,9 +1331,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, | |||
1335 | rem = ktime_sub(t.timer.expires, t.timer.base->get_time()); | 1331 | rem = ktime_sub(t.timer.expires, t.timer.base->get_time()); |
1336 | if (rem.tv64 <= 0) | 1332 | if (rem.tv64 <= 0) |
1337 | return 0; | 1333 | return 0; |
1338 | tu = ktime_to_timespec(rem); | 1334 | *rmtp = ktime_to_timespec(rem); |
1339 | if (copy_to_user(rmtp, &tu, sizeof(tu))) | ||
1340 | return -EFAULT; | ||
1341 | } | 1335 | } |
1342 | 1336 | ||
1343 | restart = ¤t_thread_info()->restart_block; | 1337 | restart = ¤t_thread_info()->restart_block; |
@@ -1353,7 +1347,8 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, | |||
1353 | asmlinkage long | 1347 | asmlinkage long |
1354 | sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) | 1348 | sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) |
1355 | { | 1349 | { |
1356 | struct timespec tu; | 1350 | struct timespec tu, rmt; |
1351 | int ret; | ||
1357 | 1352 | ||
1358 | if (copy_from_user(&tu, rqtp, sizeof(tu))) | 1353 | if (copy_from_user(&tu, rqtp, sizeof(tu))) |
1359 | return -EFAULT; | 1354 | return -EFAULT; |
@@ -1361,7 +1356,15 @@ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) | |||
1361 | if (!timespec_valid(&tu)) | 1356 | if (!timespec_valid(&tu)) |
1362 | return -EINVAL; | 1357 | return -EINVAL; |
1363 | 1358 | ||
1364 | return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC); | 1359 | ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, |
1360 | CLOCK_MONOTONIC); | ||
1361 | |||
1362 | if (ret && rmtp) { | ||
1363 | if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) | ||
1364 | return -EFAULT; | ||
1365 | } | ||
1366 | |||
1367 | return ret; | ||
1365 | } | 1368 | } |
1366 | 1369 | ||
1367 | /* | 1370 | /* |
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index d71ed09fe1dd..d11f579d189a 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
@@ -981,9 +981,20 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp) | |||
981 | static int common_nsleep(const clockid_t which_clock, int flags, | 981 | static int common_nsleep(const clockid_t which_clock, int flags, |
982 | struct timespec *tsave, struct timespec __user *rmtp) | 982 | struct timespec *tsave, struct timespec __user *rmtp) |
983 | { | 983 | { |
984 | return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ? | 984 | struct timespec rmt; |
985 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, | 985 | int ret; |
986 | which_clock); | 986 | |
987 | ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL, | ||
988 | flags & TIMER_ABSTIME ? | ||
989 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, | ||
990 | which_clock); | ||
991 | |||
992 | if (ret && rmtp) { | ||
993 | if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) | ||
994 | return -EFAULT; | ||
995 | } | ||
996 | |||
997 | return ret; | ||
987 | } | 998 | } |
988 | 999 | ||
989 | asmlinkage long | 1000 | asmlinkage long |