Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c499410 authored by Deepa Dinamani's avatar Deepa Dinamani Committed by Al Viro
Browse files

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: default avatarDeepa Dinamani <deepa.kernel@gmail.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 63a766a1
Loading
Loading
Loading
Loading
+45 −38
Original line number Diff line number Diff line
@@ -51,40 +51,52 @@ SYS_NI(alarm);
SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
		const struct timespec __user *, tp)
{
	struct timespec64 new_tp64;
	struct timespec new_tp;
	struct timespec64 new_tp;

	if (which_clock != CLOCK_REALTIME)
		return -EINVAL;
	if (copy_from_user(&new_tp, tp, sizeof (*tp)))
	if (get_timespec64(&new_tp, tp))
		return -EFAULT;

	new_tp64 = timespec_to_timespec64(new_tp);
	return do_sys_settimeofday64(&new_tp64, NULL);
	return do_sys_settimeofday64(&new_tp, NULL);
}

int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
{
	switch (which_clock) {
	case CLOCK_REALTIME:
		ktime_get_real_ts64(tp);
		break;
	case CLOCK_MONOTONIC:
		ktime_get_ts64(tp);
		break;
	case CLOCK_BOOTTIME:
		get_monotonic_boottime64(tp);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
		struct timespec __user *, tp)
{
	struct timespec64 kernel_tp64;
	struct timespec kernel_tp;
	int ret;
	struct timespec64 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;
	}
	ret = do_clock_gettime(which_clock, &kernel_tp);
	if (ret)
		return ret;

	kernel_tp = timespec64_to_timespec(kernel_tp64);
	if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))
	if (put_timespec64(&kernel_tp, tp))
		return -EFAULT;
	return 0;
}

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_nsec = hrtimer_resolution,
	};
@@ -93,7 +105,7 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __us
	case CLOCK_REALTIME:
	case CLOCK_MONOTONIC:
	case CLOCK_BOOTTIME:
		if (copy_to_user(tp, &rtn_tp, sizeof(rtn_tp)))
		if (put_timespec64(&rtn_tp, tp))
			return -EFAULT;
		return 0;
	default:
@@ -142,41 +154,35 @@ COMPAT_SYS_NI(setitimer);
COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
		       struct compat_timespec __user *, tp)
{
	struct timespec64 new_tp64;
	struct timespec new_tp;
	struct timespec64 new_tp;

	if (which_clock != CLOCK_REALTIME)
		return -EINVAL;
	if (compat_get_timespec(&new_tp, tp))
	if (compat_get_timespec64(&new_tp, tp))
		return -EFAULT;

	new_tp64 = timespec_to_timespec64(new_tp);
	return do_sys_settimeofday64(&new_tp64, NULL);
	return do_sys_settimeofday64(&new_tp, 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 timespec64 kernel_tp64;
	struct timespec kernel_tp;
	int ret;
	struct timespec64 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;
	}
	ret = do_clock_gettime(which_clock, &kernel_tp);
	if (ret)
		return ret;

	kernel_tp = timespec64_to_timespec(kernel_tp64);
	if (compat_put_timespec(&kernel_tp, tp))
	if (compat_put_timespec64(&kernel_tp, tp))
		return -EFAULT;
	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 timespec rtn_tp = {
	struct timespec64 rtn_tp = {
		.tv_sec = 0,
		.tv_nsec = hrtimer_resolution,
	};
@@ -185,13 +191,14 @@ COMPAT_SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
	case CLOCK_REALTIME:
	case CLOCK_MONOTONIC:
	case CLOCK_BOOTTIME:
		if (compat_put_timespec(&rtn_tp, tp))
		if (compat_put_timespec64(&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)
+25 −38
Original line number Diff line number Diff line
@@ -1049,34 +1049,30 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
		const struct timespec __user *, tp)
{
	const struct k_clock *kc = clockid_to_kclock(which_clock);
	struct timespec64 new_tp64;
	struct timespec new_tp;
	struct timespec64 new_tp;

	if (!kc || !kc->clock_set)
		return -EINVAL;

	if (copy_from_user(&new_tp, tp, sizeof (*tp)))
	if (get_timespec64(&new_tp, tp))
		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,
		struct timespec __user *,tp)
{
	const struct k_clock *kc = clockid_to_kclock(which_clock);
	struct timespec64 kernel_tp64;
	struct timespec kernel_tp;
	struct timespec64 kernel_tp;
	int error;

	if (!kc)
		return -EINVAL;

	error = kc->clock_get(which_clock, &kernel_tp64);
	kernel_tp = timespec64_to_timespec(kernel_tp64);
	error = kc->clock_get(which_clock, &kernel_tp);

	if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))
	if (!error && put_timespec64(&kernel_tp, tp))
		error = -EFAULT;

	return error;
@@ -1109,17 +1105,15 @@ 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;
	struct timespec64 rtn_tp;
	int error;

	if (!kc)
		return -EINVAL;

	error = kc->clock_getres(which_clock, &rtn_tp64);
	rtn_tp = timespec64_to_timespec(rtn_tp64);
	error = kc->clock_getres(which_clock, &rtn_tp);

	if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
	if (!error && tp && put_timespec64(&rtn_tp, tp))
		error = -EFAULT;

	return error;
@@ -1131,38 +1125,33 @@ 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;
	struct timespec64 ts;

	if (!kc || !kc->clock_set)
		return -EINVAL;

	if (compat_get_timespec(&new_tp, tp))
	if (compat_get_timespec64(&ts, tp))
		return -EFAULT;

	new_tp64 = timespec_to_timespec64(new_tp);

	return kc->clock_set(which_clock, &new_tp64);
	return kc->clock_set(which_clock, &ts);
}

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;
	struct timespec64 ts;
	int err;

	if (!kc)
		return -EINVAL;

	error = kc->clock_get(which_clock, &kernel_tp64);
	kernel_tp = timespec64_to_timespec(kernel_tp64);
	err = kc->clock_get(which_clock, &ts);

	if (!error && compat_put_timespec(&kernel_tp, tp))
		error = -EFAULT;
	if (!err && compat_put_timespec64(&ts, tp))
		err = -EFAULT;

	return error;
	return err;
}

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)
{
	const struct k_clock *kc = clockid_to_kclock(which_clock);
	struct timespec64 rtn_tp64;
	struct timespec rtn_tp;
	int error;
	struct timespec64 ts;
	int err;

	if (!kc)
		return -EINVAL;

	error = kc->clock_getres(which_clock, &rtn_tp64);
	rtn_tp = timespec64_to_timespec(rtn_tp64);

	if (!error && tp && compat_put_timespec(&rtn_tp, tp))
		error = -EFAULT;
	err = kc->clock_getres(which_clock, &ts);
	if (!err && tp && compat_put_timespec64(&ts, tp))
		return -EFAULT;

	return error;
	return err;
}

#endif

/*