posix-timers: Move compat versions of clock_gettime/settime/getres
Move them to the native implementations and get rid of the set_fs() hackery. 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-13-viro@ZenIV.linux.org.uk
This commit is contained in:
parent
54ad9c46c2
commit
d822cdcce4
|
@ -598,57 +598,6 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,
|
|||
return sys_timer_create(which_clock, event, created_timer_id);
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
long err;
|
||||
mm_segment_t oldfs;
|
||||
struct timespec ts;
|
||||
|
||||
if (compat_get_timespec(&ts, tp))
|
||||
return -EFAULT;
|
||||
oldfs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
err = sys_clock_settime(which_clock,
|
||||
(struct timespec __user *) &ts);
|
||||
set_fs(oldfs);
|
||||
return err;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
long err;
|
||||
mm_segment_t oldfs;
|
||||
struct timespec ts;
|
||||
|
||||
oldfs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
err = sys_clock_gettime(which_clock,
|
||||
(struct timespec __user *) &ts);
|
||||
set_fs(oldfs);
|
||||
if (!err && compat_put_timespec(&ts, tp))
|
||||
return -EFAULT;
|
||||
return err;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
long err;
|
||||
mm_segment_t oldfs;
|
||||
struct timespec ts;
|
||||
|
||||
oldfs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
err = sys_clock_getres(which_clock,
|
||||
(struct timespec __user *) &ts);
|
||||
set_fs(oldfs);
|
||||
if (!err && tp && compat_put_timespec(&ts, tp))
|
||||
return -EFAULT;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* We currently only need the following fields from the sigevent
|
||||
* structure: sigev_value, sigev_signo, sig_notify and (sometimes
|
||||
|
|
|
@ -137,6 +137,59 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
struct timespec64 new_tp64;
|
||||
struct timespec new_tp;
|
||||
|
||||
if (which_clock != CLOCK_REALTIME)
|
||||
return -EINVAL;
|
||||
if (compat_get_timespec(&new_tp, tp))
|
||||
return -EFAULT;
|
||||
|
||||
new_tp64 = timespec_to_timespec64(new_tp);
|
||||
return do_sys_settimeofday64(&new_tp64, NULL);
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
||||
struct compat_timespec __user *,tp)
|
||||
{
|
||||
struct timespec64 kernel_tp64;
|
||||
struct timespec kernel_tp;
|
||||
|
||||
switch (which_clock) {
|
||||
case CLOCK_REALTIME: ktime_get_real_ts64(&kernel_tp64); break;
|
||||
case CLOCK_MONOTONIC: ktime_get_ts64(&kernel_tp64); break;
|
||||
case CLOCK_BOOTTIME: get_monotonic_boottime64(&kernel_tp64); break;
|
||||
default: return -EINVAL;
|
||||
}
|
||||
|
||||
kernel_tp = timespec64_to_timespec(kernel_tp64);
|
||||
if (compat_put_timespec(&kernel_tp, tp))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
struct timespec rtn_tp = {
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = hrtimer_resolution,
|
||||
};
|
||||
|
||||
switch (which_clock) {
|
||||
case CLOCK_REALTIME:
|
||||
case CLOCK_MONOTONIC:
|
||||
case CLOCK_BOOTTIME:
|
||||
if (compat_put_timespec(&rtn_tp, tp))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
|
||||
struct compat_timespec __user *, rqtp,
|
||||
struct compat_timespec __user *, rmtp)
|
||||
|
|
|
@ -1082,8 +1082,66 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
|
|||
return err;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
||||
struct timespec __user *, tp)
|
||||
{
|
||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||
struct timespec64 rtn_tp64;
|
||||
struct timespec rtn_tp;
|
||||
int error;
|
||||
|
||||
if (!kc)
|
||||
return -EINVAL;
|
||||
|
||||
error = kc->clock_getres(which_clock, &rtn_tp64);
|
||||
rtn_tp = timespec64_to_timespec(rtn_tp64);
|
||||
|
||||
if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
|
||||
error = -EFAULT;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||
struct timespec64 new_tp64;
|
||||
struct timespec new_tp;
|
||||
|
||||
if (!kc || !kc->clock_set)
|
||||
return -EINVAL;
|
||||
|
||||
if (compat_get_timespec(&new_tp, tp))
|
||||
return -EFAULT;
|
||||
|
||||
new_tp64 = timespec_to_timespec64(new_tp);
|
||||
|
||||
return kc->clock_set(which_clock, &new_tp64);
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||
struct timespec64 kernel_tp64;
|
||||
struct timespec kernel_tp;
|
||||
int error;
|
||||
|
||||
if (!kc)
|
||||
return -EINVAL;
|
||||
|
||||
error = kc->clock_get(which_clock, &kernel_tp64);
|
||||
kernel_tp = timespec64_to_timespec(kernel_tp64);
|
||||
|
||||
if (!error && compat_put_timespec(&kernel_tp, tp))
|
||||
error = -EFAULT;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
|
||||
struct compat_timex __user *, utp)
|
||||
{
|
||||
|
@ -1107,10 +1165,9 @@ COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
|
|||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
||||
struct timespec __user *, tp)
|
||||
COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||
struct timespec64 rtn_tp64;
|
||||
|
@ -1123,11 +1180,12 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
|||
error = kc->clock_getres(which_clock, &rtn_tp64);
|
||||
rtn_tp = timespec64_to_timespec(rtn_tp64);
|
||||
|
||||
if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
|
||||
if (!error && tp && compat_put_timespec(&rtn_tp, tp))
|
||||
error = -EFAULT;
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* nanosleep for monotonic and realtime clocks
|
||||
|
|
Loading…
Reference in New Issue