aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 18:34:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 18:34:35 -0400
commitea3b25e1320df4e575c323b6ab22a5fc79976fbe (patch)
treeee824920b52a6458e383bc2b057cc5508e60fafe
parent89fbf5384ddf666a595eb6562dc63fcbfeb8f6a5 (diff)
parent725816e8aabb1c183baa2bc9572ab9a0d26b9ea1 (diff)
Merge branch 'timers-compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull timer-related user access updates from Al Viro: "Continuation of timers-related stuff (there had been more, but my parts of that series are already merged via timers/core). This is more of y2038 work by Deepa Dinamani, partially disrupted by the unification of native and compat timers-related syscalls" * 'timers-compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: posix_clocks: Use get_itimerspec64() and put_itimerspec64() timerfd: Use get_itimerspec64() and put_itimerspec64() nanosleep: Use get_timespec64() and put_timespec64() posix-timers: Use get_timespec64() and put_timespec64() posix-stubs: Conditionally include COMPAT_SYS_NI defines time: introduce {get,put}_itimerspec64 time: add get_timespec64 and put_timespec64
-rw-r--r--fs/timerfd.c43
-rw-r--r--include/linux/compat.h6
-rw-r--r--include/linux/hrtimer.h2
-rw-r--r--include/linux/posix-timers.h1
-rw-r--r--include/linux/time.h18
-rw-r--r--kernel/compat.c65
-rw-r--r--kernel/time/alarmtimer.c4
-rw-r--r--kernel/time/hrtimer.c30
-rw-r--r--kernel/time/posix-cpu-timers.c8
-rw-r--r--kernel/time/posix-stubs.c96
-rw-r--r--kernel/time/posix-timers.c127
-rw-r--r--kernel/time/time.c58
12 files changed, 287 insertions, 171 deletions
diff --git a/fs/timerfd.c b/fs/timerfd.c
index c543cdb5f8ed..ece0c02d7e63 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -169,7 +169,7 @@ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
169} 169}
170 170
171static int timerfd_setup(struct timerfd_ctx *ctx, int flags, 171static int timerfd_setup(struct timerfd_ctx *ctx, int flags,
172 const struct itimerspec *ktmr) 172 const struct itimerspec64 *ktmr)
173{ 173{
174 enum hrtimer_mode htmode; 174 enum hrtimer_mode htmode;
175 ktime_t texp; 175 ktime_t texp;
@@ -178,10 +178,10 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags,
178 htmode = (flags & TFD_TIMER_ABSTIME) ? 178 htmode = (flags & TFD_TIMER_ABSTIME) ?
179 HRTIMER_MODE_ABS: HRTIMER_MODE_REL; 179 HRTIMER_MODE_ABS: HRTIMER_MODE_REL;
180 180
181 texp = timespec_to_ktime(ktmr->it_value); 181 texp = timespec64_to_ktime(ktmr->it_value);
182 ctx->expired = 0; 182 ctx->expired = 0;
183 ctx->ticks = 0; 183 ctx->ticks = 0;
184 ctx->tintv = timespec_to_ktime(ktmr->it_interval); 184 ctx->tintv = timespec64_to_ktime(ktmr->it_interval);
185 185
186 if (isalarm(ctx)) { 186 if (isalarm(ctx)) {
187 alarm_init(&ctx->t.alarm, 187 alarm_init(&ctx->t.alarm,
@@ -432,16 +432,15 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
432} 432}
433 433
434static int do_timerfd_settime(int ufd, int flags, 434static int do_timerfd_settime(int ufd, int flags,
435 const struct itimerspec *new, 435 const struct itimerspec64 *new,
436 struct itimerspec *old) 436 struct itimerspec64 *old)
437{ 437{
438 struct fd f; 438 struct fd f;
439 struct timerfd_ctx *ctx; 439 struct timerfd_ctx *ctx;
440 int ret; 440 int ret;
441 441
442 if ((flags & ~TFD_SETTIME_FLAGS) || 442 if ((flags & ~TFD_SETTIME_FLAGS) ||
443 !timespec_valid(&new->it_value) || 443 !itimerspec64_valid(new))
444 !timespec_valid(&new->it_interval))
445 return -EINVAL; 444 return -EINVAL;
446 445
447 ret = timerfd_fget(ufd, &f); 446 ret = timerfd_fget(ufd, &f);
@@ -487,8 +486,8 @@ static int do_timerfd_settime(int ufd, int flags,
487 hrtimer_forward_now(&ctx->t.tmr, ctx->tintv); 486 hrtimer_forward_now(&ctx->t.tmr, ctx->tintv);
488 } 487 }
489 488
490 old->it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); 489 old->it_value = ktime_to_timespec64(timerfd_get_remaining(ctx));
491 old->it_interval = ktime_to_timespec(ctx->tintv); 490 old->it_interval = ktime_to_timespec64(ctx->tintv);
492 491
493 /* 492 /*
494 * Re-program the timer to the new value ... 493 * Re-program the timer to the new value ...
@@ -500,7 +499,7 @@ static int do_timerfd_settime(int ufd, int flags,
500 return ret; 499 return ret;
501} 500}
502 501
503static int do_timerfd_gettime(int ufd, struct itimerspec *t) 502static int do_timerfd_gettime(int ufd, struct itimerspec64 *t)
504{ 503{
505 struct fd f; 504 struct fd f;
506 struct timerfd_ctx *ctx; 505 struct timerfd_ctx *ctx;
@@ -525,8 +524,8 @@ static int do_timerfd_gettime(int ufd, struct itimerspec *t)
525 hrtimer_restart(&ctx->t.tmr); 524 hrtimer_restart(&ctx->t.tmr);
526 } 525 }
527 } 526 }
528 t->it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); 527 t->it_value = ktime_to_timespec64(timerfd_get_remaining(ctx));
529 t->it_interval = ktime_to_timespec(ctx->tintv); 528 t->it_interval = ktime_to_timespec64(ctx->tintv);
530 spin_unlock_irq(&ctx->wqh.lock); 529 spin_unlock_irq(&ctx->wqh.lock);
531 fdput(f); 530 fdput(f);
532 return 0; 531 return 0;
@@ -536,15 +535,15 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
536 const struct itimerspec __user *, utmr, 535 const struct itimerspec __user *, utmr,
537 struct itimerspec __user *, otmr) 536 struct itimerspec __user *, otmr)
538{ 537{
539 struct itimerspec new, old; 538 struct itimerspec64 new, old;
540 int ret; 539 int ret;
541 540
542 if (copy_from_user(&new, utmr, sizeof(new))) 541 if (get_itimerspec64(&new, utmr))
543 return -EFAULT; 542 return -EFAULT;
544 ret = do_timerfd_settime(ufd, flags, &new, &old); 543 ret = do_timerfd_settime(ufd, flags, &new, &old);
545 if (ret) 544 if (ret)
546 return ret; 545 return ret;
547 if (otmr && copy_to_user(otmr, &old, sizeof(old))) 546 if (otmr && put_itimerspec64(&old, otmr))
548 return -EFAULT; 547 return -EFAULT;
549 548
550 return ret; 549 return ret;
@@ -552,11 +551,11 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
552 551
553SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) 552SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr)
554{ 553{
555 struct itimerspec kotmr; 554 struct itimerspec64 kotmr;
556 int ret = do_timerfd_gettime(ufd, &kotmr); 555 int ret = do_timerfd_gettime(ufd, &kotmr);
557 if (ret) 556 if (ret)
558 return ret; 557 return ret;
559 return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; 558 return put_itimerspec64(&kotmr, otmr) ? -EFAULT : 0;
560} 559}
561 560
562#ifdef CONFIG_COMPAT 561#ifdef CONFIG_COMPAT
@@ -564,15 +563,15 @@ COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
564 const struct compat_itimerspec __user *, utmr, 563 const struct compat_itimerspec __user *, utmr,
565 struct compat_itimerspec __user *, otmr) 564 struct compat_itimerspec __user *, otmr)
566{ 565{
567 struct itimerspec new, old; 566 struct itimerspec64 new, old;
568 int ret; 567 int ret;
569 568
570 if (get_compat_itimerspec(&new, utmr)) 569 if (get_compat_itimerspec64(&new, utmr))
571 return -EFAULT; 570 return -EFAULT;
572 ret = do_timerfd_settime(ufd, flags, &new, &old); 571 ret = do_timerfd_settime(ufd, flags, &new, &old);
573 if (ret) 572 if (ret)
574 return ret; 573 return ret;
575 if (otmr && put_compat_itimerspec(otmr, &old)) 574 if (otmr && put_compat_itimerspec64(&old, otmr))
576 return -EFAULT; 575 return -EFAULT;
577 return ret; 576 return ret;
578} 577}
@@ -580,10 +579,10 @@ COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
580COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd, 579COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd,
581 struct compat_itimerspec __user *, otmr) 580 struct compat_itimerspec __user *, otmr)
582{ 581{
583 struct itimerspec kotmr; 582 struct itimerspec64 kotmr;
584 int ret = do_timerfd_gettime(ufd, &kotmr); 583 int ret = do_timerfd_gettime(ufd, &kotmr);
585 if (ret) 584 if (ret)
586 return ret; 585 return ret;
587 return put_compat_itimerspec(otmr, &kotmr) ? -EFAULT: 0; 586 return put_compat_itimerspec64(&kotmr, otmr) ? -EFAULT : 0;
588} 587}
589#endif 588#endif
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 425563c7647b..2ed54020ace0 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -164,6 +164,12 @@ extern int compat_get_timespec(struct timespec *, const void __user *);
164extern int compat_put_timespec(const struct timespec *, void __user *); 164extern int compat_put_timespec(const struct timespec *, void __user *);
165extern int compat_get_timeval(struct timeval *, const void __user *); 165extern int compat_get_timeval(struct timeval *, const void __user *);
166extern int compat_put_timeval(const struct timeval *, void __user *); 166extern int compat_put_timeval(const struct timeval *, void __user *);
167extern int compat_get_timespec64(struct timespec64 *, const void __user *);
168extern int compat_put_timespec64(const struct timespec64 *, void __user *);
169extern int get_compat_itimerspec64(struct itimerspec64 *its,
170 const struct compat_itimerspec __user *uits);
171extern int put_compat_itimerspec64(const struct itimerspec64 *its,
172 struct compat_itimerspec __user *uits);
167 173
168/* 174/*
169 * This function convert a timespec if necessary and returns a *user 175 * This function convert a timespec if necessary and returns a *user
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 255edd5e7a74..012c37fdb688 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -453,7 +453,7 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer,
453 453
454/* Precise sleep: */ 454/* Precise sleep: */
455 455
456extern int nanosleep_copyout(struct restart_block *, struct timespec *); 456extern int nanosleep_copyout(struct restart_block *, struct timespec64 *);
457extern long hrtimer_nanosleep(const struct timespec64 *rqtp, 457extern long hrtimer_nanosleep(const struct timespec64 *rqtp,
458 const enum hrtimer_mode mode, 458 const enum hrtimer_mode mode,
459 const clockid_t clockid); 459 const clockid_t clockid);
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 29f1b7f09ced..62839fd04dce 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -113,5 +113,4 @@ void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
113void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new); 113void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
114 114
115void posixtimer_rearm(struct siginfo *info); 115void posixtimer_rearm(struct siginfo *info);
116
117#endif 116#endif
diff --git a/include/linux/time.h b/include/linux/time.h
index c0543f5f25de..f9858d7e6361 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -8,6 +8,15 @@
8 8
9extern struct timezone sys_tz; 9extern struct timezone sys_tz;
10 10
11int get_timespec64(struct timespec64 *ts,
12 const struct timespec __user *uts);
13int put_timespec64(const struct timespec64 *ts,
14 struct timespec __user *uts);
15int get_itimerspec64(struct itimerspec64 *it,
16 const struct itimerspec __user *uit);
17int put_itimerspec64(const struct itimerspec64 *it,
18 struct itimerspec __user *uit);
19
11#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) 20#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
12 21
13static inline int timespec_equal(const struct timespec *a, 22static inline int timespec_equal(const struct timespec *a,
@@ -270,4 +279,13 @@ static __always_inline void timespec_add_ns(struct timespec *a, u64 ns)
270 a->tv_nsec = ns; 279 a->tv_nsec = ns;
271} 280}
272 281
282static inline bool itimerspec64_valid(const struct itimerspec64 *its)
283{
284 if (!timespec64_valid(&(its->it_interval)) ||
285 !timespec64_valid(&(its->it_value)))
286 return false;
287
288 return true;
289}
290
273#endif 291#endif
diff --git a/kernel/compat.c b/kernel/compat.c
index 9ce1d4876e60..0621c8e1ab72 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -120,6 +120,50 @@ static int __compat_put_timespec(const struct timespec *ts, struct compat_timesp
120 __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0; 120 __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
121} 121}
122 122
123static int __compat_get_timespec64(struct timespec64 *ts64,
124 const struct compat_timespec __user *cts)
125{
126 struct compat_timespec ts;
127 int ret;
128
129 ret = copy_from_user(&ts, cts, sizeof(ts));
130 if (ret)
131 return -EFAULT;
132
133 ts64->tv_sec = ts.tv_sec;
134 ts64->tv_nsec = ts.tv_nsec;
135
136 return 0;
137}
138
139static int __compat_put_timespec64(const struct timespec64 *ts64,
140 struct compat_timespec __user *cts)
141{
142 struct compat_timespec ts = {
143 .tv_sec = ts64->tv_sec,
144 .tv_nsec = ts64->tv_nsec
145 };
146 return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0;
147}
148
149int compat_get_timespec64(struct timespec64 *ts, const void __user *uts)
150{
151 if (COMPAT_USE_64BIT_TIME)
152 return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0;
153 else
154 return __compat_get_timespec64(ts, uts);
155}
156EXPORT_SYMBOL_GPL(compat_get_timespec64);
157
158int compat_put_timespec64(const struct timespec64 *ts, void __user *uts)
159{
160 if (COMPAT_USE_64BIT_TIME)
161 return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0;
162 else
163 return __compat_put_timespec64(ts, uts);
164}
165EXPORT_SYMBOL_GPL(compat_put_timespec64);
166
123int compat_get_timeval(struct timeval *tv, const void __user *utv) 167int compat_get_timeval(struct timeval *tv, const void __user *utv)
124{ 168{
125 if (COMPAT_USE_64BIT_TIME) 169 if (COMPAT_USE_64BIT_TIME)
@@ -476,6 +520,27 @@ int put_compat_itimerspec(struct compat_itimerspec __user *dst,
476 return 0; 520 return 0;
477} 521}
478 522
523int get_compat_itimerspec64(struct itimerspec64 *its,
524 const struct compat_itimerspec __user *uits)
525{
526
527 if (__compat_get_timespec64(&its->it_interval, &uits->it_interval) ||
528 __compat_get_timespec64(&its->it_value, &uits->it_value))
529 return -EFAULT;
530 return 0;
531}
532EXPORT_SYMBOL_GPL(get_compat_itimerspec64);
533
534int put_compat_itimerspec64(const struct itimerspec64 *its,
535 struct compat_itimerspec __user *uits)
536{
537 if (__compat_put_timespec64(&its->it_interval, &uits->it_interval) ||
538 __compat_put_timespec64(&its->it_value, &uits->it_value))
539 return -EFAULT;
540 return 0;
541}
542EXPORT_SYMBOL_GPL(put_compat_itimerspec64);
543
479/* 544/*
480 * We currently only need the following fields from the sigevent 545 * We currently only need the following fields from the sigevent
481 * structure: sigev_value, sigev_signo, sig_notify and (sometimes 546 * structure: sigev_value, sigev_signo, sig_notify and (sometimes
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 = &current->restart_block; 713 restart = &current->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}
1441EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); 1441EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
1442 1442
1443int nanosleep_copyout(struct restart_block *restart, struct timespec *ts) 1443int 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 = &current->restart_block; 1485 restart = &current->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:
1546SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, 1546SYSCALL_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,
1566COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, 1564COMPAT_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 60cb24ac9ebc..a3bd5dbe0dc4 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -1318,12 +1318,8 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
1318 */ 1318 */
1319 restart = &current->restart_block; 1319 restart = &current->restart_block;
1320 restart->nanosleep.expires = expires; 1320 restart->nanosleep.expires = expires;
1321 if (restart->nanosleep.type != TT_NONE) { 1321 if (restart->nanosleep.type != TT_NONE)
1322 struct timespec ts; 1322 error = nanosleep_copyout(restart, &it.it_value);
1323
1324 ts = timespec64_to_timespec(it.it_value);
1325 error = nanosleep_copyout(restart, &ts);
1326 }
1327 } 1323 }
1328 1324
1329 return error; 1325 return error;
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c
index 38f3b20efa29..06f34feb635e 100644
--- a/kernel/time/posix-stubs.c
+++ b/kernel/time/posix-stubs.c
@@ -41,12 +41,6 @@ SYS_NI(setitimer);
41#ifdef __ARCH_WANT_SYS_ALARM 41#ifdef __ARCH_WANT_SYS_ALARM
42SYS_NI(alarm); 42SYS_NI(alarm);
43#endif 43#endif
44COMPAT_SYS_NI(timer_create);
45COMPAT_SYS_NI(clock_adjtime);
46COMPAT_SYS_NI(timer_settime);
47COMPAT_SYS_NI(timer_gettime);
48COMPAT_SYS_NI(getitimer);
49COMPAT_SYS_NI(setitimer);
50 44
51/* 45/*
52 * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC 46 * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
@@ -57,40 +51,52 @@ COMPAT_SYS_NI(setitimer);
57SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 51SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
58 const struct timespec __user *, tp) 52 const struct timespec __user *, tp)
59{ 53{
60 struct timespec64 new_tp64; 54 struct timespec64 new_tp;
61 struct timespec new_tp;
62 55
63 if (which_clock != CLOCK_REALTIME) 56 if (which_clock != CLOCK_REALTIME)
64 return -EINVAL; 57 return -EINVAL;
65 if (copy_from_user(&new_tp, tp, sizeof (*tp))) 58 if (get_timespec64(&new_tp, tp))
66 return -EFAULT; 59 return -EFAULT;
67 60
68 new_tp64 = timespec_to_timespec64(new_tp); 61 return do_sys_settimeofday64(&new_tp, NULL);
69 return do_sys_settimeofday64(&new_tp64, NULL);
70} 62}
71 63
72SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 64int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
73 struct timespec __user *,tp)
74{ 65{
75 struct timespec64 kernel_tp64;
76 struct timespec kernel_tp;
77
78 switch (which_clock) { 66 switch (which_clock) {
79 case CLOCK_REALTIME: ktime_get_real_ts64(&kernel_tp64); break; 67 case CLOCK_REALTIME:
80 case CLOCK_MONOTONIC: ktime_get_ts64(&kernel_tp64); break; 68 ktime_get_real_ts64(tp);
81 case CLOCK_BOOTTIME: get_monotonic_boottime64(&kernel_tp64); break; 69 break;
82 default: return -EINVAL; 70 case CLOCK_MONOTONIC:
71 ktime_get_ts64(tp);
72 break;
73 case CLOCK_BOOTTIME:
74 get_monotonic_boottime64(tp);
75 break;
76 default:
77 return -EINVAL;
83 } 78 }
84 79
85 kernel_tp = timespec64_to_timespec(kernel_tp64); 80 return 0;
86 if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) 81}
82SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
83 struct timespec __user *, tp)
84{
85 int ret;
86 struct timespec64 kernel_tp;
87
88 ret = do_clock_gettime(which_clock, &kernel_tp);
89 if (ret)
90 return ret;
91
92 if (put_timespec64(&kernel_tp, tp))
87 return -EFAULT; 93 return -EFAULT;
88 return 0; 94 return 0;
89} 95}
90 96
91SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) 97SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
92{ 98{
93 struct timespec rtn_tp = { 99 struct timespec64 rtn_tp = {
94 .tv_sec = 0, 100 .tv_sec = 0,
95 .tv_nsec = hrtimer_resolution, 101 .tv_nsec = hrtimer_resolution,
96 }; 102 };
@@ -99,7 +105,7 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __us
99 case CLOCK_REALTIME: 105 case CLOCK_REALTIME:
100 case CLOCK_MONOTONIC: 106 case CLOCK_MONOTONIC:
101 case CLOCK_BOOTTIME: 107 case CLOCK_BOOTTIME:
102 if (copy_to_user(tp, &rtn_tp, sizeof(rtn_tp))) 108 if (put_timespec64(&rtn_tp, tp))
103 return -EFAULT; 109 return -EFAULT;
104 return 0; 110 return 0;
105 default: 111 default:
@@ -138,44 +144,45 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
138} 144}
139 145
140#ifdef CONFIG_COMPAT 146#ifdef CONFIG_COMPAT
147COMPAT_SYS_NI(timer_create);
148COMPAT_SYS_NI(clock_adjtime);
149COMPAT_SYS_NI(timer_settime);
150COMPAT_SYS_NI(timer_gettime);
151COMPAT_SYS_NI(getitimer);
152COMPAT_SYS_NI(setitimer);
153
141COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 154COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
142 struct compat_timespec __user *, tp) 155 struct compat_timespec __user *, tp)
143{ 156{
144 struct timespec64 new_tp64; 157 struct timespec64 new_tp;
145 struct timespec new_tp;
146 158
147 if (which_clock != CLOCK_REALTIME) 159 if (which_clock != CLOCK_REALTIME)
148 return -EINVAL; 160 return -EINVAL;
149 if (compat_get_timespec(&new_tp, tp)) 161 if (compat_get_timespec64(&new_tp, tp))
150 return -EFAULT; 162 return -EFAULT;
151 163
152 new_tp64 = timespec_to_timespec64(new_tp); 164 return do_sys_settimeofday64(&new_tp, NULL);
153 return do_sys_settimeofday64(&new_tp64, NULL);
154} 165}
155 166
156COMPAT_SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 167COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
157 struct compat_timespec __user *,tp) 168 struct compat_timespec __user *, tp)
158{ 169{
159 struct timespec64 kernel_tp64; 170 int ret;
160 struct timespec kernel_tp; 171 struct timespec64 kernel_tp;
161 172
162 switch (which_clock) { 173 ret = do_clock_gettime(which_clock, &kernel_tp);
163 case CLOCK_REALTIME: ktime_get_real_ts64(&kernel_tp64); break; 174 if (ret)
164 case CLOCK_MONOTONIC: ktime_get_ts64(&kernel_tp64); break; 175 return ret;
165 case CLOCK_BOOTTIME: get_monotonic_boottime64(&kernel_tp64); break;
166 default: return -EINVAL;
167 }
168 176
169 kernel_tp = timespec64_to_timespec(kernel_tp64); 177 if (compat_put_timespec64(&kernel_tp, tp))
170 if (compat_put_timespec(&kernel_tp, tp))
171 return -EFAULT; 178 return -EFAULT;
172 return 0; 179 return 0;
173} 180}
174 181
175COMPAT_SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, 182COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
176 struct compat_timespec __user *, tp) 183 struct compat_timespec __user *, tp)
177{ 184{
178 struct timespec rtn_tp = { 185 struct timespec64 rtn_tp = {
179 .tv_sec = 0, 186 .tv_sec = 0,
180 .tv_nsec = hrtimer_resolution, 187 .tv_nsec = hrtimer_resolution,
181 }; 188 };
@@ -184,13 +191,14 @@ COMPAT_SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
184 case CLOCK_REALTIME: 191 case CLOCK_REALTIME:
185 case CLOCK_MONOTONIC: 192 case CLOCK_MONOTONIC:
186 case CLOCK_BOOTTIME: 193 case CLOCK_BOOTTIME:
187 if (compat_put_timespec(&rtn_tp, tp)) 194 if (compat_put_timespec64(&rtn_tp, tp))
188 return -EFAULT; 195 return -EFAULT;
189 return 0; 196 return 0;
190 default: 197 default:
191 return -EINVAL; 198 return -EINVAL;
192 } 199 }
193} 200}
201
194COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, 202COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
195 struct compat_timespec __user *, rqtp, 203 struct compat_timespec __user *, rqtp,
196 struct compat_timespec __user *, rmtp) 204 struct compat_timespec __user *, rmtp)
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 82d67be7d9d1..13d6881f908b 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -739,13 +739,11 @@ static int do_timer_gettime(timer_t timer_id, struct itimerspec64 *setting)
739SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, 739SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
740 struct itimerspec __user *, setting) 740 struct itimerspec __user *, setting)
741{ 741{
742 struct itimerspec64 cur_setting64; 742 struct itimerspec64 cur_setting;
743 743
744 int ret = do_timer_gettime(timer_id, &cur_setting64); 744 int ret = do_timer_gettime(timer_id, &cur_setting);
745 if (!ret) { 745 if (!ret) {
746 struct itimerspec cur_setting; 746 if (put_itimerspec64(&cur_setting, setting))
747 cur_setting = itimerspec64_to_itimerspec(&cur_setting64);
748 if (copy_to_user(setting, &cur_setting, sizeof (cur_setting)))
749 ret = -EFAULT; 747 ret = -EFAULT;
750 } 748 }
751 return ret; 749 return ret;
@@ -755,13 +753,11 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
755COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, 753COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
756 struct compat_itimerspec __user *, setting) 754 struct compat_itimerspec __user *, setting)
757{ 755{
758 struct itimerspec64 cur_setting64; 756 struct itimerspec64 cur_setting;
759 757
760 int ret = do_timer_gettime(timer_id, &cur_setting64); 758 int ret = do_timer_gettime(timer_id, &cur_setting);
761 if (!ret) { 759 if (!ret) {
762 struct itimerspec cur_setting; 760 if (put_compat_itimerspec64(&cur_setting, setting))
763 cur_setting = itimerspec64_to_itimerspec(&cur_setting64);
764 if (put_compat_itimerspec(setting, &cur_setting))
765 ret = -EFAULT; 761 ret = -EFAULT;
766 } 762 }
767 return ret; 763 return ret;
@@ -907,23 +903,19 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
907 const struct itimerspec __user *, new_setting, 903 const struct itimerspec __user *, new_setting,
908 struct itimerspec __user *, old_setting) 904 struct itimerspec __user *, old_setting)
909{ 905{
910 struct itimerspec64 new_spec64, old_spec64; 906 struct itimerspec64 new_spec, old_spec;
911 struct itimerspec64 *rtn = old_setting ? &old_spec64 : NULL; 907 struct itimerspec64 *rtn = old_setting ? &old_spec : NULL;
912 struct itimerspec new_spec;
913 int error = 0; 908 int error = 0;
914 909
915 if (!new_setting) 910 if (!new_setting)
916 return -EINVAL; 911 return -EINVAL;
917 912
918 if (copy_from_user(&new_spec, new_setting, sizeof (new_spec))) 913 if (get_itimerspec64(&new_spec, new_setting))
919 return -EFAULT; 914 return -EFAULT;
920 new_spec64 = itimerspec_to_itimerspec64(&new_spec);
921 915
922 error = do_timer_settime(timer_id, flags, &new_spec64, rtn); 916 error = do_timer_settime(timer_id, flags, &new_spec, rtn);
923 if (!error && old_setting) { 917 if (!error && old_setting) {
924 struct itimerspec old_spec; 918 if (put_itimerspec64(&old_spec, old_setting))
925 old_spec = itimerspec64_to_itimerspec(&old_spec64);
926 if (copy_to_user(old_setting, &old_spec, sizeof (old_spec)))
927 error = -EFAULT; 919 error = -EFAULT;
928 } 920 }
929 return error; 921 return error;
@@ -934,22 +926,18 @@ COMPAT_SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
934 struct compat_itimerspec __user *, new, 926 struct compat_itimerspec __user *, new,
935 struct compat_itimerspec __user *, old) 927 struct compat_itimerspec __user *, old)
936{ 928{
937 struct itimerspec64 new_spec64, old_spec64; 929 struct itimerspec64 new_spec, old_spec;
938 struct itimerspec64 *rtn = old ? &old_spec64 : NULL; 930 struct itimerspec64 *rtn = old ? &old_spec : NULL;
939 struct itimerspec new_spec;
940 int error = 0; 931 int error = 0;
941 932
942 if (!new) 933 if (!new)
943 return -EINVAL; 934 return -EINVAL;
944 if (get_compat_itimerspec(&new_spec, new)) 935 if (get_compat_itimerspec64(&new_spec, new))
945 return -EFAULT; 936 return -EFAULT;
946 937
947 new_spec64 = itimerspec_to_itimerspec64(&new_spec); 938 error = do_timer_settime(timer_id, flags, &new_spec, rtn);
948 error = do_timer_settime(timer_id, flags, &new_spec64, rtn);
949 if (!error && old) { 939 if (!error && old) {
950 struct itimerspec old_spec; 940 if (put_compat_itimerspec64(&old_spec, old))
951 old_spec = itimerspec64_to_itimerspec(&old_spec64);
952 if (put_compat_itimerspec(old, &old_spec))
953 error = -EFAULT; 941 error = -EFAULT;
954 } 942 }
955 return error; 943 return error;
@@ -1049,34 +1037,30 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
1049 const struct timespec __user *, tp) 1037 const struct timespec __user *, tp)
1050{ 1038{
1051 const struct k_clock *kc = clockid_to_kclock(which_clock); 1039 const struct k_clock *kc = clockid_to_kclock(which_clock);
1052 struct timespec64 new_tp64; 1040 struct timespec64 new_tp;
1053 struct timespec new_tp;
1054 1041
1055 if (!kc || !kc->clock_set) 1042 if (!kc || !kc->clock_set)
1056 return -EINVAL; 1043 return -EINVAL;
1057 1044
1058 if (copy_from_user(&new_tp, tp, sizeof (*tp))) 1045 if (get_timespec64(&new_tp, tp))
1059 return -EFAULT; 1046 return -EFAULT;
1060 new_tp64 = timespec_to_timespec64(new_tp);
1061 1047
1062 return kc->clock_set(which_clock, &new_tp64); 1048 return kc->clock_set(which_clock, &new_tp);
1063} 1049}
1064 1050
1065SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 1051SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
1066 struct timespec __user *,tp) 1052 struct timespec __user *,tp)
1067{ 1053{
1068 const struct k_clock *kc = clockid_to_kclock(which_clock); 1054 const struct k_clock *kc = clockid_to_kclock(which_clock);
1069 struct timespec64 kernel_tp64; 1055 struct timespec64 kernel_tp;
1070 struct timespec kernel_tp;
1071 int error; 1056 int error;
1072 1057
1073 if (!kc) 1058 if (!kc)
1074 return -EINVAL; 1059 return -EINVAL;
1075 1060
1076 error = kc->clock_get(which_clock, &kernel_tp64); 1061 error = kc->clock_get(which_clock, &kernel_tp);
1077 kernel_tp = timespec64_to_timespec(kernel_tp64);
1078 1062
1079 if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) 1063 if (!error && put_timespec64(&kernel_tp, tp))
1080 error = -EFAULT; 1064 error = -EFAULT;
1081 1065
1082 return error; 1066 return error;
@@ -1109,17 +1093,15 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
1109 struct timespec __user *, tp) 1093 struct timespec __user *, tp)
1110{ 1094{
1111 const struct k_clock *kc = clockid_to_kclock(which_clock); 1095 const struct k_clock *kc = clockid_to_kclock(which_clock);
1112 struct timespec64 rtn_tp64; 1096 struct timespec64 rtn_tp;
1113 struct timespec rtn_tp;
1114 int error; 1097 int error;
1115 1098
1116 if (!kc) 1099 if (!kc)
1117 return -EINVAL; 1100 return -EINVAL;
1118 1101
1119 error = kc->clock_getres(which_clock, &rtn_tp64); 1102 error = kc->clock_getres(which_clock, &rtn_tp);
1120 rtn_tp = timespec64_to_timespec(rtn_tp64);
1121 1103
1122 if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) 1104 if (!error && tp && put_timespec64(&rtn_tp, tp))
1123 error = -EFAULT; 1105 error = -EFAULT;
1124 1106
1125 return error; 1107 return error;
@@ -1131,38 +1113,33 @@ COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
1131 struct compat_timespec __user *, tp) 1113 struct compat_timespec __user *, tp)
1132{ 1114{
1133 const struct k_clock *kc = clockid_to_kclock(which_clock); 1115 const struct k_clock *kc = clockid_to_kclock(which_clock);
1134 struct timespec64 new_tp64; 1116 struct timespec64 ts;
1135 struct timespec new_tp;
1136 1117
1137 if (!kc || !kc->clock_set) 1118 if (!kc || !kc->clock_set)
1138 return -EINVAL; 1119 return -EINVAL;
1139 1120
1140 if (compat_get_timespec(&new_tp, tp)) 1121 if (compat_get_timespec64(&ts, tp))
1141 return -EFAULT; 1122 return -EFAULT;
1142 1123
1143 new_tp64 = timespec_to_timespec64(new_tp); 1124 return kc->clock_set(which_clock, &ts);
1144
1145 return kc->clock_set(which_clock, &new_tp64);
1146} 1125}
1147 1126
1148COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock, 1127COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
1149 struct compat_timespec __user *, tp) 1128 struct compat_timespec __user *, tp)
1150{ 1129{
1151 const struct k_clock *kc = clockid_to_kclock(which_clock); 1130 const struct k_clock *kc = clockid_to_kclock(which_clock);
1152 struct timespec64 kernel_tp64; 1131 struct timespec64 ts;
1153 struct timespec kernel_tp; 1132 int err;
1154 int error;
1155 1133
1156 if (!kc) 1134 if (!kc)
1157 return -EINVAL; 1135 return -EINVAL;
1158 1136
1159 error = kc->clock_get(which_clock, &kernel_tp64); 1137 err = kc->clock_get(which_clock, &ts);
1160 kernel_tp = timespec64_to_timespec(kernel_tp64);
1161 1138
1162 if (!error && compat_put_timespec(&kernel_tp, tp)) 1139 if (!err && compat_put_timespec64(&ts, tp))
1163 error = -EFAULT; 1140 err = -EFAULT;
1164 1141
1165 return error; 1142 return err;
1166} 1143}
1167 1144
1168COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock, 1145COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
@@ -1193,21 +1170,19 @@ COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
1193 struct compat_timespec __user *, tp) 1170 struct compat_timespec __user *, tp)
1194{ 1171{
1195 const struct k_clock *kc = clockid_to_kclock(which_clock); 1172 const struct k_clock *kc = clockid_to_kclock(which_clock);
1196 struct timespec64 rtn_tp64; 1173 struct timespec64 ts;
1197 struct timespec rtn_tp; 1174 int err;
1198 int error;
1199 1175
1200 if (!kc) 1176 if (!kc)
1201 return -EINVAL; 1177 return -EINVAL;
1202 1178
1203 error = kc->clock_getres(which_clock, &rtn_tp64); 1179 err = kc->clock_getres(which_clock, &ts);
1204 rtn_tp = timespec64_to_timespec(rtn_tp64); 1180 if (!err && tp && compat_put_timespec64(&ts, tp))
1205 1181 return -EFAULT;
1206 if (!error && tp && compat_put_timespec(&rtn_tp, tp))
1207 error = -EFAULT;
1208 1182
1209 return error; 1183 return err;
1210} 1184}
1185
1211#endif 1186#endif
1212 1187
1213/* 1188/*
@@ -1226,26 +1201,24 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
1226 struct timespec __user *, rmtp) 1201 struct timespec __user *, rmtp)
1227{ 1202{
1228 const struct k_clock *kc = clockid_to_kclock(which_clock); 1203 const struct k_clock *kc = clockid_to_kclock(which_clock);
1229 struct timespec64 t64; 1204 struct timespec64 t;
1230 struct timespec t;
1231 1205
1232 if (!kc) 1206 if (!kc)
1233 return -EINVAL; 1207 return -EINVAL;
1234 if (!kc->nsleep) 1208 if (!kc->nsleep)
1235 return -ENANOSLEEP_NOTSUP; 1209 return -ENANOSLEEP_NOTSUP;
1236 1210
1237 if (copy_from_user(&t, rqtp, sizeof (struct timespec))) 1211 if (get_timespec64(&t, rqtp))
1238 return -EFAULT; 1212 return -EFAULT;
1239 1213
1240 t64 = timespec_to_timespec64(t); 1214 if (!timespec64_valid(&t))
1241 if (!timespec64_valid(&t64))
1242 return -EINVAL; 1215 return -EINVAL;
1243 if (flags & TIMER_ABSTIME) 1216 if (flags & TIMER_ABSTIME)
1244 rmtp = NULL; 1217 rmtp = NULL;
1245 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 1218 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
1246 current->restart_block.nanosleep.rmtp = rmtp; 1219 current->restart_block.nanosleep.rmtp = rmtp;
1247 1220
1248 return kc->nsleep(which_clock, flags, &t64); 1221 return kc->nsleep(which_clock, flags, &t);
1249} 1222}
1250 1223
1251#ifdef CONFIG_COMPAT 1224#ifdef CONFIG_COMPAT
@@ -1254,26 +1227,24 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
1254 struct compat_timespec __user *, rmtp) 1227 struct compat_timespec __user *, rmtp)
1255{ 1228{
1256 const struct k_clock *kc = clockid_to_kclock(which_clock); 1229 const struct k_clock *kc = clockid_to_kclock(which_clock);
1257 struct timespec64 t64; 1230 struct timespec64 t;
1258 struct timespec t;
1259 1231
1260 if (!kc) 1232 if (!kc)
1261 return -EINVAL; 1233 return -EINVAL;
1262 if (!kc->nsleep) 1234 if (!kc->nsleep)
1263 return -ENANOSLEEP_NOTSUP; 1235 return -ENANOSLEEP_NOTSUP;
1264 1236
1265 if (compat_get_timespec(&t, rqtp)) 1237 if (compat_get_timespec64(&t, rqtp))
1266 return -EFAULT; 1238 return -EFAULT;
1267 1239
1268 t64 = timespec_to_timespec64(t); 1240 if (!timespec64_valid(&t))
1269 if (!timespec64_valid(&t64))
1270 return -EINVAL; 1241 return -EINVAL;
1271 if (flags & TIMER_ABSTIME) 1242 if (flags & TIMER_ABSTIME)
1272 rmtp = NULL; 1243 rmtp = NULL;
1273 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 1244 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
1274 current->restart_block.nanosleep.compat_rmtp = rmtp; 1245 current->restart_block.nanosleep.compat_rmtp = rmtp;
1275 1246
1276 return kc->nsleep(which_clock, flags, &t64); 1247 return kc->nsleep(which_clock, flags, &t);
1277} 1248}
1278#endif 1249#endif
1279 1250
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 7c89e437c4d7..44a8c1402133 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -890,3 +890,61 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
890 890
891 return res; 891 return res;
892} 892}
893
894int get_timespec64(struct timespec64 *ts,
895 const struct timespec __user *uts)
896{
897 struct timespec kts;
898 int ret;
899
900 ret = copy_from_user(&kts, uts, sizeof(kts));
901 if (ret)
902 return -EFAULT;
903
904 ts->tv_sec = kts.tv_sec;
905 ts->tv_nsec = kts.tv_nsec;
906
907 return 0;
908}
909EXPORT_SYMBOL_GPL(get_timespec64);
910
911int put_timespec64(const struct timespec64 *ts,
912 struct timespec __user *uts)
913{
914 struct timespec kts = {
915 .tv_sec = ts->tv_sec,
916 .tv_nsec = ts->tv_nsec
917 };
918 return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0;
919}
920EXPORT_SYMBOL_GPL(put_timespec64);
921
922int get_itimerspec64(struct itimerspec64 *it,
923 const struct itimerspec __user *uit)
924{
925 int ret;
926
927 ret = get_timespec64(&it->it_interval, &uit->it_interval);
928 if (ret)
929 return ret;
930
931 ret = get_timespec64(&it->it_value, &uit->it_value);
932
933 return ret;
934}
935EXPORT_SYMBOL_GPL(get_itimerspec64);
936
937int put_itimerspec64(const struct itimerspec64 *it,
938 struct itimerspec __user *uit)
939{
940 int ret;
941
942 ret = put_timespec64(&it->it_interval, &uit->it_interval);
943 if (ret)
944 return ret;
945
946 ret = put_timespec64(&it->it_value, &uit->it_value);
947
948 return ret;
949}
950EXPORT_SYMBOL_GPL(put_itimerspec64);