diff options
| author | Deepa Dinamani <deepa.kernel@gmail.com> | 2017-06-24 14:45:06 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-30 04:14:14 -0400 |
| commit | c0edd7c9acd0eaee149ab6cb4441cc71a1af87f0 (patch) | |
| tree | 9c670f99b106a03963fa9a2bc606617cd0958497 /kernel/time | |
| parent | 5c4994102fb508d4a0f7a8afa46560c314c1ebd4 (diff) | |
nanosleep: Use get_timespec64() and put_timespec64()
Usage of these apis and their compat versions makes
the syscalls: clock_nanosleep and nanosleep and
their compat implementations simpler.
This is a preparatory patch to isolate data conversions to
struct timespec64 at userspace boundaries. This helps contain
the changes needed to transition to new y2038 safe types.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/time')
| -rw-r--r-- | kernel/time/alarmtimer.c | 4 | ||||
| -rw-r--r-- | kernel/time/hrtimer.c | 30 | ||||
| -rw-r--r-- | kernel/time/posix-cpu-timers.c | 8 | ||||
| -rw-r--r-- | kernel/time/posix-timers.c | 20 |
4 files changed, 25 insertions, 37 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index c991cf212c6d..0b8ff7d257ea 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c | |||
| @@ -712,14 +712,14 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp, | |||
| 712 | alarmtimer_freezerset(absexp, type); | 712 | alarmtimer_freezerset(absexp, type); |
| 713 | restart = ¤t->restart_block; | 713 | restart = ¤t->restart_block; |
| 714 | if (restart->nanosleep.type != TT_NONE) { | 714 | if (restart->nanosleep.type != TT_NONE) { |
| 715 | struct timespec rmt; | 715 | struct timespec64 rmt; |
| 716 | ktime_t rem; | 716 | ktime_t rem; |
| 717 | 717 | ||
| 718 | rem = ktime_sub(absexp, alarm_bases[type].gettime()); | 718 | rem = ktime_sub(absexp, alarm_bases[type].gettime()); |
| 719 | 719 | ||
| 720 | if (rem <= 0) | 720 | if (rem <= 0) |
| 721 | return 0; | 721 | return 0; |
| 722 | rmt = ktime_to_timespec(rem); | 722 | rmt = ktime_to_timespec64(rem); |
| 723 | 723 | ||
| 724 | return nanosleep_copyout(restart, &rmt); | 724 | return nanosleep_copyout(restart, &rmt); |
| 725 | } | 725 | } |
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 81da124f1115..88f75f92ef36 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c | |||
| @@ -1440,17 +1440,17 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task) | |||
| 1440 | } | 1440 | } |
| 1441 | EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); | 1441 | EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); |
| 1442 | 1442 | ||
| 1443 | int nanosleep_copyout(struct restart_block *restart, struct timespec *ts) | 1443 | int nanosleep_copyout(struct restart_block *restart, struct timespec64 *ts) |
| 1444 | { | 1444 | { |
| 1445 | switch(restart->nanosleep.type) { | 1445 | switch(restart->nanosleep.type) { |
| 1446 | #ifdef CONFIG_COMPAT | 1446 | #ifdef CONFIG_COMPAT |
| 1447 | case TT_COMPAT: | 1447 | case TT_COMPAT: |
| 1448 | if (compat_put_timespec(ts, restart->nanosleep.compat_rmtp)) | 1448 | if (compat_put_timespec64(ts, restart->nanosleep.compat_rmtp)) |
| 1449 | return -EFAULT; | 1449 | return -EFAULT; |
| 1450 | break; | 1450 | break; |
| 1451 | #endif | 1451 | #endif |
| 1452 | case TT_NATIVE: | 1452 | case TT_NATIVE: |
| 1453 | if (copy_to_user(restart->nanosleep.rmtp, ts, sizeof(struct timespec))) | 1453 | if (put_timespec64(ts, restart->nanosleep.rmtp)) |
| 1454 | return -EFAULT; | 1454 | return -EFAULT; |
| 1455 | break; | 1455 | break; |
| 1456 | default: | 1456 | default: |
| @@ -1485,11 +1485,11 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod | |||
| 1485 | restart = ¤t->restart_block; | 1485 | restart = ¤t->restart_block; |
| 1486 | if (restart->nanosleep.type != TT_NONE) { | 1486 | if (restart->nanosleep.type != TT_NONE) { |
| 1487 | ktime_t rem = hrtimer_expires_remaining(&t->timer); | 1487 | ktime_t rem = hrtimer_expires_remaining(&t->timer); |
| 1488 | struct timespec rmt; | 1488 | struct timespec64 rmt; |
| 1489 | 1489 | ||
| 1490 | if (rem <= 0) | 1490 | if (rem <= 0) |
| 1491 | return 0; | 1491 | return 0; |
| 1492 | rmt = ktime_to_timespec(rem); | 1492 | rmt = ktime_to_timespec64(rem); |
| 1493 | 1493 | ||
| 1494 | return nanosleep_copyout(restart, &rmt); | 1494 | return nanosleep_copyout(restart, &rmt); |
| 1495 | } | 1495 | } |
| @@ -1546,19 +1546,17 @@ out: | |||
| 1546 | SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, | 1546 | SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, |
| 1547 | struct timespec __user *, rmtp) | 1547 | struct timespec __user *, rmtp) |
| 1548 | { | 1548 | { |
| 1549 | struct timespec64 tu64; | 1549 | struct timespec64 tu; |
| 1550 | struct timespec tu; | ||
| 1551 | 1550 | ||
| 1552 | if (copy_from_user(&tu, rqtp, sizeof(tu))) | 1551 | if (get_timespec64(&tu, rqtp)) |
| 1553 | return -EFAULT; | 1552 | return -EFAULT; |
| 1554 | 1553 | ||
| 1555 | tu64 = timespec_to_timespec64(tu); | 1554 | if (!timespec64_valid(&tu)) |
| 1556 | if (!timespec64_valid(&tu64)) | ||
| 1557 | return -EINVAL; | 1555 | return -EINVAL; |
| 1558 | 1556 | ||
| 1559 | current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; | 1557 | current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; |
| 1560 | current->restart_block.nanosleep.rmtp = rmtp; | 1558 | current->restart_block.nanosleep.rmtp = rmtp; |
| 1561 | return hrtimer_nanosleep(&tu64, HRTIMER_MODE_REL, CLOCK_MONOTONIC); | 1559 | return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC); |
| 1562 | } | 1560 | } |
| 1563 | 1561 | ||
| 1564 | #ifdef CONFIG_COMPAT | 1562 | #ifdef CONFIG_COMPAT |
| @@ -1566,19 +1564,17 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, | |||
| 1566 | COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, | 1564 | COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, |
| 1567 | struct compat_timespec __user *, rmtp) | 1565 | struct compat_timespec __user *, rmtp) |
| 1568 | { | 1566 | { |
| 1569 | struct timespec64 tu64; | 1567 | struct timespec64 tu; |
| 1570 | struct timespec tu; | ||
| 1571 | 1568 | ||
| 1572 | if (compat_get_timespec(&tu, rqtp)) | 1569 | if (compat_get_timespec64(&tu, rqtp)) |
| 1573 | return -EFAULT; | 1570 | return -EFAULT; |
| 1574 | 1571 | ||
| 1575 | tu64 = timespec_to_timespec64(tu); | 1572 | if (!timespec64_valid(&tu)) |
| 1576 | if (!timespec64_valid(&tu64)) | ||
| 1577 | return -EINVAL; | 1573 | return -EINVAL; |
| 1578 | 1574 | ||
| 1579 | current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; | 1575 | current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; |
| 1580 | current->restart_block.nanosleep.compat_rmtp = rmtp; | 1576 | current->restart_block.nanosleep.compat_rmtp = rmtp; |
| 1581 | return hrtimer_nanosleep(&tu64, HRTIMER_MODE_REL, CLOCK_MONOTONIC); | 1577 | return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC); |
| 1582 | } | 1578 | } |
| 1583 | #endif | 1579 | #endif |
| 1584 | 1580 | ||
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 9df618ee64cf..7323da5950cc 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c | |||
| @@ -1314,12 +1314,8 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, | |||
| 1314 | */ | 1314 | */ |
| 1315 | restart = ¤t->restart_block; | 1315 | restart = ¤t->restart_block; |
| 1316 | restart->nanosleep.expires = expires; | 1316 | restart->nanosleep.expires = expires; |
| 1317 | if (restart->nanosleep.type != TT_NONE) { | 1317 | if (restart->nanosleep.type != TT_NONE) |
| 1318 | struct timespec ts; | 1318 | error = nanosleep_copyout(restart, &it.it_value); |
| 1319 | |||
| 1320 | ts = timespec64_to_timespec(it.it_value); | ||
| 1321 | error = nanosleep_copyout(restart, &ts); | ||
| 1322 | } | ||
| 1323 | } | 1319 | } |
| 1324 | 1320 | ||
| 1325 | return error; | 1321 | return error; |
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 39322ae5dd87..4b0fc3b0a1c4 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c | |||
| @@ -1213,26 +1213,24 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, | |||
| 1213 | struct timespec __user *, rmtp) | 1213 | struct timespec __user *, rmtp) |
| 1214 | { | 1214 | { |
| 1215 | const struct k_clock *kc = clockid_to_kclock(which_clock); | 1215 | const struct k_clock *kc = clockid_to_kclock(which_clock); |
| 1216 | struct timespec64 t64; | 1216 | struct timespec64 t; |
| 1217 | struct timespec t; | ||
| 1218 | 1217 | ||
| 1219 | if (!kc) | 1218 | if (!kc) |
| 1220 | return -EINVAL; | 1219 | return -EINVAL; |
| 1221 | if (!kc->nsleep) | 1220 | if (!kc->nsleep) |
| 1222 | return -ENANOSLEEP_NOTSUP; | 1221 | return -ENANOSLEEP_NOTSUP; |
| 1223 | 1222 | ||
| 1224 | if (copy_from_user(&t, rqtp, sizeof (struct timespec))) | 1223 | if (get_timespec64(&t, rqtp)) |
| 1225 | return -EFAULT; | 1224 | return -EFAULT; |
| 1226 | 1225 | ||
| 1227 | t64 = timespec_to_timespec64(t); | 1226 | if (!timespec64_valid(&t)) |
| 1228 | if (!timespec64_valid(&t64)) | ||
| 1229 | return -EINVAL; | 1227 | return -EINVAL; |
| 1230 | if (flags & TIMER_ABSTIME) | 1228 | if (flags & TIMER_ABSTIME) |
| 1231 | rmtp = NULL; | 1229 | rmtp = NULL; |
| 1232 | current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; | 1230 | current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; |
| 1233 | current->restart_block.nanosleep.rmtp = rmtp; | 1231 | current->restart_block.nanosleep.rmtp = rmtp; |
| 1234 | 1232 | ||
| 1235 | return kc->nsleep(which_clock, flags, &t64); | 1233 | return kc->nsleep(which_clock, flags, &t); |
| 1236 | } | 1234 | } |
| 1237 | 1235 | ||
| 1238 | #ifdef CONFIG_COMPAT | 1236 | #ifdef CONFIG_COMPAT |
| @@ -1241,26 +1239,24 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, | |||
| 1241 | struct compat_timespec __user *, rmtp) | 1239 | struct compat_timespec __user *, rmtp) |
| 1242 | { | 1240 | { |
| 1243 | const struct k_clock *kc = clockid_to_kclock(which_clock); | 1241 | const struct k_clock *kc = clockid_to_kclock(which_clock); |
| 1244 | struct timespec64 t64; | 1242 | struct timespec64 t; |
| 1245 | struct timespec t; | ||
| 1246 | 1243 | ||
| 1247 | if (!kc) | 1244 | if (!kc) |
| 1248 | return -EINVAL; | 1245 | return -EINVAL; |
| 1249 | if (!kc->nsleep) | 1246 | if (!kc->nsleep) |
| 1250 | return -ENANOSLEEP_NOTSUP; | 1247 | return -ENANOSLEEP_NOTSUP; |
| 1251 | 1248 | ||
| 1252 | if (compat_get_timespec(&t, rqtp)) | 1249 | if (compat_get_timespec64(&t, rqtp)) |
| 1253 | return -EFAULT; | 1250 | return -EFAULT; |
| 1254 | 1251 | ||
| 1255 | t64 = timespec_to_timespec64(t); | 1252 | if (!timespec64_valid(&t)) |
| 1256 | if (!timespec64_valid(&t64)) | ||
| 1257 | return -EINVAL; | 1253 | return -EINVAL; |
| 1258 | if (flags & TIMER_ABSTIME) | 1254 | if (flags & TIMER_ABSTIME) |
| 1259 | rmtp = NULL; | 1255 | rmtp = NULL; |
| 1260 | current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; | 1256 | current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; |
| 1261 | current->restart_block.nanosleep.compat_rmtp = rmtp; | 1257 | current->restart_block.nanosleep.compat_rmtp = rmtp; |
| 1262 | 1258 | ||
| 1263 | return kc->nsleep(which_clock, flags, &t64); | 1259 | return kc->nsleep(which_clock, flags, &t); |
| 1264 | } | 1260 | } |
| 1265 | #endif | 1261 | #endif |
| 1266 | 1262 | ||
