Skip to content

Commit

Permalink
hrtimers/posix-timers: Merge nanosleep timespec copyout logics into a…
Browse files Browse the repository at this point in the history
… new helper

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: John Stultz <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
  • Loading branch information
Al Viro authored and KAGA-KOKO committed Jun 13, 2017
1 parent edbeda4 commit ce41aaf
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 29 deletions.
2 changes: 2 additions & 0 deletions include/linux/hrtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer,
}

/* Precise sleep: */

extern int nanosleep_copyout(struct restart_block *, struct timespec *);
extern long hrtimer_nanosleep(struct timespec64 *rqtp,
const enum hrtimer_mode mode,
const clockid_t clockid);
Expand Down
10 changes: 1 addition & 9 deletions kernel/time/alarmtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,15 +721,7 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp,
return 0;
rmt = ktime_to_timespec(rem);

#ifdef CONFIG_COMPAT
if (restart->nanosleep.type == TT_COMPAT) {
if (compat_put_timespec(&rmt,
restart->nanosleep.compat_rmtp))
return -EFAULT;
} else
#endif
if (copy_to_user(restart->nanosleep.rmtp, &rmt, sizeof(rmt)))
return -EFAULT;
return nanosleep_copyout(restart, &rmt);
}
return -ERESTART_RESTARTBLOCK;
}
Expand Down
29 changes: 20 additions & 9 deletions kernel/time/hrtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1440,6 +1440,25 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
}
EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);

int nanosleep_copyout(struct restart_block *restart, struct timespec *ts)
{
switch(restart->nanosleep.type) {
#ifdef CONFIG_COMPAT
case TT_COMPAT:
if (compat_put_timespec(ts, restart->nanosleep.compat_rmtp))
return -EFAULT;
break;
#endif
case TT_NATIVE:
if (copy_to_user(restart->nanosleep.rmtp, ts, sizeof(struct timespec)))
return -EFAULT;
break;
default:
BUG();
}
return -ERESTART_RESTARTBLOCK;
}

static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
{
struct restart_block *restart;
Expand Down Expand Up @@ -1472,15 +1491,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
return 0;
rmt = ktime_to_timespec(rem);

#ifdef CONFIG_COMPAT
if (restart->nanosleep.type == TT_COMPAT) {
if (compat_put_timespec(&rmt,
restart->nanosleep.compat_rmtp))
return -EFAULT;
} else
#endif
if (copy_to_user(restart->nanosleep.rmtp, &rmt, sizeof(rmt)))
return -EFAULT;
return nanosleep_copyout(restart, &rmt);
}
return -ERESTART_RESTARTBLOCK;
}
Expand Down
13 changes: 2 additions & 11 deletions kernel/time/posix-cpu-timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1312,22 +1312,13 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
* Report back to the user the time still remaining.
*/
restart = &current->restart_block;
restart->nanosleep.expires = timespec64_to_ns(rqtp);
if (restart->nanosleep.type != TT_NONE) {
struct timespec ts;

ts = timespec64_to_timespec(it.it_value);
#ifdef CONFIG_COMPAT
if (restart->nanosleep.type == TT_COMPAT) {
if (compat_put_timespec(&ts,
restart->nanosleep.compat_rmtp))
return -EFAULT;
} else
#endif
if (copy_to_user(restart->nanosleep.rmtp, &ts,
sizeof(ts)))
return -EFAULT;
error = nanosleep_copyout(restart, &ts);
}
restart->nanosleep.expires = timespec64_to_ns(rqtp);
}

return error;
Expand Down

0 comments on commit ce41aaf

Please sign in to comment.