@@ -3757,30 +3757,48 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
37573757 return - ENOSYS ;
37583758}
37593759
3760+ static __always_inline bool futex_cmd_has_timeout (u32 cmd )
3761+ {
3762+ switch (cmd ) {
3763+ case FUTEX_WAIT :
3764+ case FUTEX_LOCK_PI :
3765+ case FUTEX_WAIT_BITSET :
3766+ case FUTEX_WAIT_REQUEUE_PI :
3767+ return true;
3768+ }
3769+ return false;
3770+ }
3771+
3772+ static __always_inline int
3773+ futex_init_timeout (u32 cmd , u32 op , struct timespec64 * ts , ktime_t * t )
3774+ {
3775+ if (!timespec64_valid (ts ))
3776+ return - EINVAL ;
3777+
3778+ * t = timespec64_to_ktime (* ts );
3779+ if (cmd == FUTEX_WAIT )
3780+ * t = ktime_add_safe (ktime_get (), * t );
3781+ else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME ))
3782+ * t = timens_ktime_to_host (CLOCK_MONOTONIC , * t );
3783+ return 0 ;
3784+ }
37603785
37613786SYSCALL_DEFINE6 (futex , u32 __user * , uaddr , int , op , u32 , val ,
37623787 const struct __kernel_timespec __user * , utime ,
37633788 u32 __user * , uaddr2 , u32 , val3 )
37643789{
3765- struct timespec64 ts ;
3790+ int ret , cmd = op & FUTEX_CMD_MASK ;
37663791 ktime_t t , * tp = NULL ;
3767- int cmd = op & FUTEX_CMD_MASK ;
3792+ struct timespec64 ts ;
37683793
3769- if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
3770- cmd == FUTEX_WAIT_BITSET ||
3771- cmd == FUTEX_WAIT_REQUEUE_PI )) {
3794+ if (utime && futex_cmd_has_timeout (cmd )) {
37723795 if (unlikely (should_fail_futex (!(op & FUTEX_PRIVATE_FLAG ))))
37733796 return - EFAULT ;
37743797 if (get_timespec64 (& ts , utime ))
37753798 return - EFAULT ;
3776- if (!timespec64_valid (& ts ))
3777- return - EINVAL ;
3778-
3779- t = timespec64_to_ktime (ts );
3780- if (cmd == FUTEX_WAIT )
3781- t = ktime_add_safe (ktime_get (), t );
3782- else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME ))
3783- t = timens_ktime_to_host (CLOCK_MONOTONIC , t );
3799+ ret = futex_init_timeout (cmd , op , & ts , & t );
3800+ if (ret )
3801+ return ret ;
37843802 tp = & t ;
37853803 }
37863804
@@ -3950,23 +3968,16 @@ SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val,
39503968 const struct old_timespec32 __user * , utime , u32 __user * , uaddr2 ,
39513969 u32 , val3 )
39523970{
3953- struct timespec64 ts ;
3971+ int ret , cmd = op & FUTEX_CMD_MASK ;
39543972 ktime_t t , * tp = NULL ;
3955- int cmd = op & FUTEX_CMD_MASK ;
3973+ struct timespec64 ts ;
39563974
3957- if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
3958- cmd == FUTEX_WAIT_BITSET ||
3959- cmd == FUTEX_WAIT_REQUEUE_PI )) {
3975+ if (utime && futex_cmd_has_timeout (cmd )) {
39603976 if (get_old_timespec32 (& ts , utime ))
39613977 return - EFAULT ;
3962- if (!timespec64_valid (& ts ))
3963- return - EINVAL ;
3964-
3965- t = timespec64_to_ktime (ts );
3966- if (cmd == FUTEX_WAIT )
3967- t = ktime_add_safe (ktime_get (), t );
3968- else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME ))
3969- t = timens_ktime_to_host (CLOCK_MONOTONIC , t );
3978+ ret = futex_init_timeout (cmd , op , & ts , & t );
3979+ if (ret )
3980+ return ret ;
39703981 tp = & t ;
39713982 }
39723983
0 commit comments