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

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

timerfd: Use get_itimerspec64() and put_itimerspec64()



Usage of these apis and their compat versions makes
the syscalls: timerfd_settime and timerfd_gettime and
their compat implementations simpler.

This patch also serves as a preparatory patch for changing
syscalls to use new time_t data types to support the
y2038 effort by isolating the processing of user pointers
through these apis.

Signed-off-by: default avatarDeepa Dinamani <deepa.kernel@gmail.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent c0edd7c9
Loading
Loading
Loading
Loading
+21 −22
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
}

static int timerfd_setup(struct timerfd_ctx *ctx, int flags,
			 const struct itimerspec *ktmr)
			 const struct itimerspec64 *ktmr)
{
	enum hrtimer_mode htmode;
	ktime_t texp;
@@ -178,10 +178,10 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags,
	htmode = (flags & TFD_TIMER_ABSTIME) ?
		HRTIMER_MODE_ABS: HRTIMER_MODE_REL;

	texp = timespec_to_ktime(ktmr->it_value);
	texp = timespec64_to_ktime(ktmr->it_value);
	ctx->expired = 0;
	ctx->ticks = 0;
	ctx->tintv = timespec_to_ktime(ktmr->it_interval);
	ctx->tintv = timespec64_to_ktime(ktmr->it_interval);

	if (isalarm(ctx)) {
		alarm_init(&ctx->t.alarm,
@@ -432,16 +432,15 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
}

static int do_timerfd_settime(int ufd, int flags, 
		const struct itimerspec *new,
		struct itimerspec *old)
		const struct itimerspec64 *new,
		struct itimerspec64 *old)
{
	struct fd f;
	struct timerfd_ctx *ctx;
	int ret;

	if ((flags & ~TFD_SETTIME_FLAGS) ||
	    !timespec_valid(&new->it_value) ||
	    !timespec_valid(&new->it_interval))
		 !itimerspec64_valid(new))
		return -EINVAL;

	ret = timerfd_fget(ufd, &f);
@@ -487,8 +486,8 @@ static int do_timerfd_settime(int ufd, int flags,
			hrtimer_forward_now(&ctx->t.tmr, ctx->tintv);
	}

	old->it_value = ktime_to_timespec(timerfd_get_remaining(ctx));
	old->it_interval = ktime_to_timespec(ctx->tintv);
	old->it_value = ktime_to_timespec64(timerfd_get_remaining(ctx));
	old->it_interval = ktime_to_timespec64(ctx->tintv);

	/*
	 * Re-program the timer to the new value ...
@@ -500,7 +499,7 @@ static int do_timerfd_settime(int ufd, int flags,
	return ret;
}

static int do_timerfd_gettime(int ufd, struct itimerspec *t)
static int do_timerfd_gettime(int ufd, struct itimerspec64 *t)
{
	struct fd f;
	struct timerfd_ctx *ctx;
@@ -525,8 +524,8 @@ static int do_timerfd_gettime(int ufd, struct itimerspec *t)
			hrtimer_restart(&ctx->t.tmr);
		}
	}
	t->it_value = ktime_to_timespec(timerfd_get_remaining(ctx));
	t->it_interval = ktime_to_timespec(ctx->tintv);
	t->it_value = ktime_to_timespec64(timerfd_get_remaining(ctx));
	t->it_interval = ktime_to_timespec64(ctx->tintv);
	spin_unlock_irq(&ctx->wqh.lock);
	fdput(f);
	return 0;
@@ -536,15 +535,15 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
		const struct itimerspec __user *, utmr,
		struct itimerspec __user *, otmr)
{
	struct itimerspec new, old;
	struct itimerspec64 new, old;
	int ret;

	if (copy_from_user(&new, utmr, sizeof(new)))
	if (get_itimerspec64(&new, utmr))
		return -EFAULT;
	ret = do_timerfd_settime(ufd, flags, &new, &old);
	if (ret)
		return ret;
	if (otmr && copy_to_user(otmr, &old, sizeof(old)))
	if (otmr && put_itimerspec64(&old, otmr))
		return -EFAULT;

	return ret;
@@ -552,11 +551,11 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,

SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr)
{
	struct itimerspec kotmr;
	struct itimerspec64 kotmr;
	int ret = do_timerfd_gettime(ufd, &kotmr);
	if (ret)
		return ret;
	return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0;
	return put_itimerspec64(&kotmr, otmr) ? -EFAULT : 0;
}

#ifdef CONFIG_COMPAT
@@ -564,15 +563,15 @@ COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
		const struct compat_itimerspec __user *, utmr,
		struct compat_itimerspec __user *, otmr)
{
	struct itimerspec new, old;
	struct itimerspec64 new, old;
	int ret;

	if (get_compat_itimerspec(&new, utmr))
	if (get_compat_itimerspec64(&new, utmr))
		return -EFAULT;
	ret = do_timerfd_settime(ufd, flags, &new, &old);
	if (ret)
		return ret;
	if (otmr && put_compat_itimerspec(otmr, &old))
	if (otmr && put_compat_itimerspec64(&old, otmr))
		return -EFAULT;
	return ret;
}
@@ -580,10 +579,10 @@ COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd,
		struct compat_itimerspec __user *, otmr)
{
	struct itimerspec kotmr;
	struct itimerspec64 kotmr;
	int ret = do_timerfd_gettime(ufd, &kotmr);
	if (ret)
		return ret;
	return put_compat_itimerspec(otmr, &kotmr) ? -EFAULT: 0;
	return put_compat_itimerspec64(&kotmr, otmr) ? -EFAULT : 0;
}
#endif