hrtimers/posix-timers: Merge nanosleep timespec copyout logics into a new helper
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: John Stultz <john.stultz@linaro.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20170607084241.28657-7-viro@ZenIV.linux.org.uk
This commit is contained in:
parent
edbeda4632
commit
ce41aaf47a
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 = ¤t->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;
|
||||
|
|
Loading…
Reference in a new issue