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

Commit d822cdcc authored by Al Viro's avatar Al Viro Committed by Thomas Gleixner
Browse files

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarThomas 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
parent 54ad9c46
Loading
Loading
Loading
Loading
+0 −51
Original line number Diff line number Diff line
@@ -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
+53 −0
Original line number Diff line number Diff line
@@ -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)
+62 −4
Original line number Diff line number Diff line
@@ -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