mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-30 19:07:15 +00:00
posix-timers: Use get_timespec64() and put_timespec64()
Usage of these apis and their compat versions makes the syscalls: clock_gettime, clock_settime, clock_getres and their compat implementations simpler. This is a preparatory patch to isolate data conversions to struct timespec64 at userspace boundaries. This helps contain the changes needed to transition to new y2038 safe types. Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
63a766a178
commit
5c4994102f
2 changed files with 70 additions and 76 deletions
|
@ -51,40 +51,52 @@ SYS_NI(alarm);
|
||||||
SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
||||||
const struct timespec __user *, tp)
|
const struct timespec __user *, tp)
|
||||||
{
|
{
|
||||||
struct timespec64 new_tp64;
|
struct timespec64 new_tp;
|
||||||
struct timespec new_tp;
|
|
||||||
|
|
||||||
if (which_clock != CLOCK_REALTIME)
|
if (which_clock != CLOCK_REALTIME)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&new_tp, tp, sizeof (*tp)))
|
if (get_timespec64(&new_tp, tp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
new_tp64 = timespec_to_timespec64(new_tp);
|
return do_sys_settimeofday64(&new_tp, NULL);
|
||||||
return do_sys_settimeofday64(&new_tp64, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
|
||||||
struct timespec __user *,tp)
|
|
||||||
{
|
{
|
||||||
struct timespec64 kernel_tp64;
|
|
||||||
struct timespec kernel_tp;
|
|
||||||
|
|
||||||
switch (which_clock) {
|
switch (which_clock) {
|
||||||
case CLOCK_REALTIME: ktime_get_real_ts64(&kernel_tp64); break;
|
case CLOCK_REALTIME:
|
||||||
case CLOCK_MONOTONIC: ktime_get_ts64(&kernel_tp64); break;
|
ktime_get_real_ts64(tp);
|
||||||
case CLOCK_BOOTTIME: get_monotonic_boottime64(&kernel_tp64); break;
|
break;
|
||||||
default: return -EINVAL;
|
case CLOCK_MONOTONIC:
|
||||||
|
ktime_get_ts64(tp);
|
||||||
|
break;
|
||||||
|
case CLOCK_BOOTTIME:
|
||||||
|
get_monotonic_boottime64(tp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
kernel_tp = timespec64_to_timespec(kernel_tp64);
|
return 0;
|
||||||
if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))
|
}
|
||||||
|
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
||||||
|
struct timespec __user *, tp)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct timespec64 kernel_tp;
|
||||||
|
|
||||||
|
ret = do_clock_gettime(which_clock, &kernel_tp);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (put_timespec64(&kernel_tp, tp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
|
SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
|
||||||
{
|
{
|
||||||
struct timespec rtn_tp = {
|
struct timespec64 rtn_tp = {
|
||||||
.tv_sec = 0,
|
.tv_sec = 0,
|
||||||
.tv_nsec = hrtimer_resolution,
|
.tv_nsec = hrtimer_resolution,
|
||||||
};
|
};
|
||||||
|
@ -93,7 +105,7 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __us
|
||||||
case CLOCK_REALTIME:
|
case CLOCK_REALTIME:
|
||||||
case CLOCK_MONOTONIC:
|
case CLOCK_MONOTONIC:
|
||||||
case CLOCK_BOOTTIME:
|
case CLOCK_BOOTTIME:
|
||||||
if (copy_to_user(tp, &rtn_tp, sizeof(rtn_tp)))
|
if (put_timespec64(&rtn_tp, tp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
|
@ -142,41 +154,35 @@ COMPAT_SYS_NI(setitimer);
|
||||||
COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
||||||
struct compat_timespec __user *, tp)
|
struct compat_timespec __user *, tp)
|
||||||
{
|
{
|
||||||
struct timespec64 new_tp64;
|
struct timespec64 new_tp;
|
||||||
struct timespec new_tp;
|
|
||||||
|
|
||||||
if (which_clock != CLOCK_REALTIME)
|
if (which_clock != CLOCK_REALTIME)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (compat_get_timespec(&new_tp, tp))
|
if (compat_get_timespec64(&new_tp, tp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
new_tp64 = timespec_to_timespec64(new_tp);
|
return do_sys_settimeofday64(&new_tp, NULL);
|
||||||
return do_sys_settimeofday64(&new_tp64, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
|
||||||
struct compat_timespec __user *,tp)
|
struct compat_timespec __user *, tp)
|
||||||
{
|
{
|
||||||
struct timespec64 kernel_tp64;
|
int ret;
|
||||||
struct timespec kernel_tp;
|
struct timespec64 kernel_tp;
|
||||||
|
|
||||||
switch (which_clock) {
|
ret = do_clock_gettime(which_clock, &kernel_tp);
|
||||||
case CLOCK_REALTIME: ktime_get_real_ts64(&kernel_tp64); break;
|
if (ret)
|
||||||
case CLOCK_MONOTONIC: ktime_get_ts64(&kernel_tp64); break;
|
return ret;
|
||||||
case CLOCK_BOOTTIME: get_monotonic_boottime64(&kernel_tp64); break;
|
|
||||||
default: return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel_tp = timespec64_to_timespec(kernel_tp64);
|
if (compat_put_timespec64(&kernel_tp, tp))
|
||||||
if (compat_put_timespec(&kernel_tp, tp))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
|
||||||
struct compat_timespec __user *, tp)
|
struct compat_timespec __user *, tp)
|
||||||
{
|
{
|
||||||
struct timespec rtn_tp = {
|
struct timespec64 rtn_tp = {
|
||||||
.tv_sec = 0,
|
.tv_sec = 0,
|
||||||
.tv_nsec = hrtimer_resolution,
|
.tv_nsec = hrtimer_resolution,
|
||||||
};
|
};
|
||||||
|
@ -185,13 +191,14 @@ COMPAT_SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
||||||
case CLOCK_REALTIME:
|
case CLOCK_REALTIME:
|
||||||
case CLOCK_MONOTONIC:
|
case CLOCK_MONOTONIC:
|
||||||
case CLOCK_BOOTTIME:
|
case CLOCK_BOOTTIME:
|
||||||
if (compat_put_timespec(&rtn_tp, tp))
|
if (compat_put_timespec64(&rtn_tp, tp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
|
COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
|
||||||
struct compat_timespec __user *, rqtp,
|
struct compat_timespec __user *, rqtp,
|
||||||
struct compat_timespec __user *, rmtp)
|
struct compat_timespec __user *, rmtp)
|
||||||
|
|
|
@ -1049,34 +1049,30 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
||||||
const struct timespec __user *, tp)
|
const struct timespec __user *, tp)
|
||||||
{
|
{
|
||||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||||
struct timespec64 new_tp64;
|
struct timespec64 new_tp;
|
||||||
struct timespec new_tp;
|
|
||||||
|
|
||||||
if (!kc || !kc->clock_set)
|
if (!kc || !kc->clock_set)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&new_tp, tp, sizeof (*tp)))
|
if (get_timespec64(&new_tp, tp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
new_tp64 = timespec_to_timespec64(new_tp);
|
|
||||||
|
|
||||||
return kc->clock_set(which_clock, &new_tp64);
|
return kc->clock_set(which_clock, &new_tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
||||||
struct timespec __user *,tp)
|
struct timespec __user *,tp)
|
||||||
{
|
{
|
||||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||||
struct timespec64 kernel_tp64;
|
struct timespec64 kernel_tp;
|
||||||
struct timespec kernel_tp;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (!kc)
|
if (!kc)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
error = kc->clock_get(which_clock, &kernel_tp64);
|
error = kc->clock_get(which_clock, &kernel_tp);
|
||||||
kernel_tp = timespec64_to_timespec(kernel_tp64);
|
|
||||||
|
|
||||||
if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))
|
if (!error && put_timespec64(&kernel_tp, tp))
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -1109,17 +1105,15 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
||||||
struct timespec __user *, tp)
|
struct timespec __user *, tp)
|
||||||
{
|
{
|
||||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||||
struct timespec64 rtn_tp64;
|
struct timespec64 rtn_tp;
|
||||||
struct timespec rtn_tp;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (!kc)
|
if (!kc)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
error = kc->clock_getres(which_clock, &rtn_tp64);
|
error = kc->clock_getres(which_clock, &rtn_tp);
|
||||||
rtn_tp = timespec64_to_timespec(rtn_tp64);
|
|
||||||
|
|
||||||
if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
|
if (!error && tp && put_timespec64(&rtn_tp, tp))
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -1131,38 +1125,33 @@ COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
|
||||||
struct compat_timespec __user *, tp)
|
struct compat_timespec __user *, tp)
|
||||||
{
|
{
|
||||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||||
struct timespec64 new_tp64;
|
struct timespec64 ts;
|
||||||
struct timespec new_tp;
|
|
||||||
|
|
||||||
if (!kc || !kc->clock_set)
|
if (!kc || !kc->clock_set)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (compat_get_timespec(&new_tp, tp))
|
if (compat_get_timespec64(&ts, tp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
new_tp64 = timespec_to_timespec64(new_tp);
|
return kc->clock_set(which_clock, &ts);
|
||||||
|
|
||||||
return kc->clock_set(which_clock, &new_tp64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
|
COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
|
||||||
struct compat_timespec __user *, tp)
|
struct compat_timespec __user *, tp)
|
||||||
{
|
{
|
||||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||||
struct timespec64 kernel_tp64;
|
struct timespec64 ts;
|
||||||
struct timespec kernel_tp;
|
int err;
|
||||||
int error;
|
|
||||||
|
|
||||||
if (!kc)
|
if (!kc)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
error = kc->clock_get(which_clock, &kernel_tp64);
|
err = kc->clock_get(which_clock, &ts);
|
||||||
kernel_tp = timespec64_to_timespec(kernel_tp64);
|
|
||||||
|
|
||||||
if (!error && compat_put_timespec(&kernel_tp, tp))
|
if (!err && compat_put_timespec64(&ts, tp))
|
||||||
error = -EFAULT;
|
err = -EFAULT;
|
||||||
|
|
||||||
return error;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
|
COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
|
||||||
|
@ -1193,21 +1182,19 @@ COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
|
||||||
struct compat_timespec __user *, tp)
|
struct compat_timespec __user *, tp)
|
||||||
{
|
{
|
||||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||||
struct timespec64 rtn_tp64;
|
struct timespec64 ts;
|
||||||
struct timespec rtn_tp;
|
int err;
|
||||||
int error;
|
|
||||||
|
|
||||||
if (!kc)
|
if (!kc)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
error = kc->clock_getres(which_clock, &rtn_tp64);
|
err = kc->clock_getres(which_clock, &ts);
|
||||||
rtn_tp = timespec64_to_timespec(rtn_tp64);
|
if (!err && tp && compat_put_timespec64(&ts, tp))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
if (!error && tp && compat_put_timespec(&rtn_tp, tp))
|
return err;
|
||||||
error = -EFAULT;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue