summaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2018-04-17 11:23:35 -0400
committerArnd Bergmann <arnd@arndb.de>2018-12-07 16:19:07 -0500
commitbec2f7cbb73eadf5e1cc7d54ecb0980ede244257 (patch)
tree24d06866d036f57bed35f0828f42d9fa63256eb2 /kernel/futex.c
parent04e7712f4460585e5eed5b853fd8b82a9943958f (diff)
y2038: futex: Add support for __kernel_timespec
This prepares sys_futex for y2038 safe calling: the native syscall is changed to receive a __kernel_timespec argument, which will be switched to 64-bit time_t in the future. All the internal time handling gets changed to timespec64, and the compat_sys_futex entry point is moved under the CONFIG_COMPAT_32BIT_TIME check to provide compatibility for existing 32-bit architectures. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 5cc7c3b098e9..b305beaab739 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -3558,10 +3558,10 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
3558 3558
3559 3559
3560SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, 3560SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
3561 struct timespec __user *, utime, u32 __user *, uaddr2, 3561 struct __kernel_timespec __user *, utime, u32 __user *, uaddr2,
3562 u32, val3) 3562 u32, val3)
3563{ 3563{
3564 struct timespec ts; 3564 struct timespec64 ts;
3565 ktime_t t, *tp = NULL; 3565 ktime_t t, *tp = NULL;
3566 u32 val2 = 0; 3566 u32 val2 = 0;
3567 int cmd = op & FUTEX_CMD_MASK; 3567 int cmd = op & FUTEX_CMD_MASK;
@@ -3571,12 +3571,12 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
3571 cmd == FUTEX_WAIT_REQUEUE_PI)) { 3571 cmd == FUTEX_WAIT_REQUEUE_PI)) {
3572 if (unlikely(should_fail_futex(!(op & FUTEX_PRIVATE_FLAG)))) 3572 if (unlikely(should_fail_futex(!(op & FUTEX_PRIVATE_FLAG))))
3573 return -EFAULT; 3573 return -EFAULT;
3574 if (copy_from_user(&ts, utime, sizeof(ts)) != 0) 3574 if (get_timespec64(&ts, utime))
3575 return -EFAULT; 3575 return -EFAULT;
3576 if (!timespec_valid(&ts)) 3576 if (!timespec64_valid(&ts))
3577 return -EINVAL; 3577 return -EINVAL;
3578 3578
3579 t = timespec_to_ktime(ts); 3579 t = timespec64_to_ktime(ts);
3580 if (cmd == FUTEX_WAIT) 3580 if (cmd == FUTEX_WAIT)
3581 t = ktime_add_safe(ktime_get(), t); 3581 t = ktime_add_safe(ktime_get(), t);
3582 tp = &t; 3582 tp = &t;
@@ -3747,12 +3747,14 @@ err_unlock:
3747 3747
3748 return ret; 3748 return ret;
3749} 3749}
3750#endif /* CONFIG_COMPAT */
3750 3751
3752#ifdef CONFIG_COMPAT_32BIT_TIME
3751COMPAT_SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, 3753COMPAT_SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
3752 struct old_timespec32 __user *, utime, u32 __user *, uaddr2, 3754 struct old_timespec32 __user *, utime, u32 __user *, uaddr2,
3753 u32, val3) 3755 u32, val3)
3754{ 3756{
3755 struct timespec ts; 3757 struct timespec64 ts;
3756 ktime_t t, *tp = NULL; 3758 ktime_t t, *tp = NULL;
3757 int val2 = 0; 3759 int val2 = 0;
3758 int cmd = op & FUTEX_CMD_MASK; 3760 int cmd = op & FUTEX_CMD_MASK;
@@ -3760,12 +3762,12 @@ COMPAT_SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
3760 if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || 3762 if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
3761 cmd == FUTEX_WAIT_BITSET || 3763 cmd == FUTEX_WAIT_BITSET ||
3762 cmd == FUTEX_WAIT_REQUEUE_PI)) { 3764 cmd == FUTEX_WAIT_REQUEUE_PI)) {
3763 if (compat_get_timespec(&ts, utime)) 3765 if (get_old_timespec32(&ts, utime))
3764 return -EFAULT; 3766 return -EFAULT;
3765 if (!timespec_valid(&ts)) 3767 if (!timespec64_valid(&ts))
3766 return -EINVAL; 3768 return -EINVAL;
3767 3769
3768 t = timespec_to_ktime(ts); 3770 t = timespec64_to_ktime(ts);
3769 if (cmd == FUTEX_WAIT) 3771 if (cmd == FUTEX_WAIT)
3770 t = ktime_add_safe(ktime_get(), t); 3772 t = ktime_add_safe(ktime_get(), t);
3771 tp = &t; 3773 tp = &t;
@@ -3776,7 +3778,7 @@ COMPAT_SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
3776 3778
3777 return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); 3779 return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
3778} 3780}
3779#endif /* CONFIG_COMPAT */ 3781#endif /* CONFIG_COMPAT_32BIT_TIME */
3780 3782
3781static void __init futex_detect_cmpxchg(void) 3783static void __init futex_detect_cmpxchg(void)
3782{ 3784{