xref: /openbmc/linux/kernel/time/time.c (revision 3876ced4)
135728b82SThomas Gleixner // SPDX-License-Identifier: GPL-2.0
25cee9645SThomas Gleixner /*
35cee9645SThomas Gleixner  *  Copyright (C) 1991, 1992  Linus Torvalds
45cee9645SThomas Gleixner  *
558c5fc2bSThomas Gleixner  *  This file contains the interface functions for the various time related
658c5fc2bSThomas Gleixner  *  system calls: time, stime, gettimeofday, settimeofday, adjtime
758c5fc2bSThomas Gleixner  *
858c5fc2bSThomas Gleixner  * Modification history:
95cee9645SThomas Gleixner  *
105cee9645SThomas Gleixner  * 1993-09-02    Philip Gladstone
115cee9645SThomas Gleixner  *      Created file with time related functions from sched/core.c and adjtimex()
125cee9645SThomas Gleixner  * 1993-10-08    Torsten Duwe
135cee9645SThomas Gleixner  *      adjtime interface update and CMOS clock write code
145cee9645SThomas Gleixner  * 1995-08-13    Torsten Duwe
155cee9645SThomas Gleixner  *      kernel PLL updated to 1994-12-13 specs (rfc-1589)
165cee9645SThomas Gleixner  * 1999-01-16    Ulrich Windl
175cee9645SThomas Gleixner  *	Introduced error checking for many cases in adjtimex().
185cee9645SThomas Gleixner  *	Updated NTP code according to technical memorandum Jan '96
195cee9645SThomas Gleixner  *	"A Kernel Model for Precision Timekeeping" by Dave Mills
205cee9645SThomas Gleixner  *	Allow time_constant larger than MAXTC(6) for NTP v4 (MAXTC == 10)
215cee9645SThomas Gleixner  *	(Even though the technical memorandum forbids it)
225cee9645SThomas Gleixner  * 2004-07-14	 Christoph Lameter
235cee9645SThomas Gleixner  *	Added getnstimeofday to allow the posix timer functions to return
245cee9645SThomas Gleixner  *	with nanosecond accuracy
255cee9645SThomas Gleixner  */
265cee9645SThomas Gleixner 
275cee9645SThomas Gleixner #include <linux/export.h>
28abcbcb80SGeert Uytterhoeven #include <linux/kernel.h>
295cee9645SThomas Gleixner #include <linux/timex.h>
305cee9645SThomas Gleixner #include <linux/capability.h>
315cee9645SThomas Gleixner #include <linux/timekeeper_internal.h>
325cee9645SThomas Gleixner #include <linux/errno.h>
335cee9645SThomas Gleixner #include <linux/syscalls.h>
345cee9645SThomas Gleixner #include <linux/security.h>
355cee9645SThomas Gleixner #include <linux/fs.h>
365cee9645SThomas Gleixner #include <linux/math64.h>
375cee9645SThomas Gleixner #include <linux/ptrace.h>
385cee9645SThomas Gleixner 
397c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
403a4d44b6SAl Viro #include <linux/compat.h>
415cee9645SThomas Gleixner #include <asm/unistd.h>
425cee9645SThomas Gleixner 
430a227985SNicholas Mc Guire #include <generated/timeconst.h>
448b094cd0SThomas Gleixner #include "timekeeping.h"
455cee9645SThomas Gleixner 
465cee9645SThomas Gleixner /*
475cee9645SThomas Gleixner  * The timezone where the local system is located.  Used as a default by some
485cee9645SThomas Gleixner  * programs who obtain this value by using gettimeofday.
495cee9645SThomas Gleixner  */
505cee9645SThomas Gleixner struct timezone sys_tz;
515cee9645SThomas Gleixner 
525cee9645SThomas Gleixner EXPORT_SYMBOL(sys_tz);
535cee9645SThomas Gleixner 
545cee9645SThomas Gleixner #ifdef __ARCH_WANT_SYS_TIME
555cee9645SThomas Gleixner 
565cee9645SThomas Gleixner /*
575cee9645SThomas Gleixner  * sys_time() can be implemented in user-level using
585cee9645SThomas Gleixner  * sys_gettimeofday().  Is this for backwards compatibility?  If so,
595cee9645SThomas Gleixner  * why not move it into the appropriate arch directory (for those
605cee9645SThomas Gleixner  * architectures that need it).
615cee9645SThomas Gleixner  */
625cee9645SThomas Gleixner SYSCALL_DEFINE1(time, time_t __user *, tloc)
635cee9645SThomas Gleixner {
64f5a89295SArnd Bergmann 	time_t i = (time_t)ktime_get_real_seconds();
655cee9645SThomas Gleixner 
665cee9645SThomas Gleixner 	if (tloc) {
675cee9645SThomas Gleixner 		if (put_user(i,tloc))
685cee9645SThomas Gleixner 			return -EFAULT;
695cee9645SThomas Gleixner 	}
705cee9645SThomas Gleixner 	force_successful_syscall_return();
715cee9645SThomas Gleixner 	return i;
725cee9645SThomas Gleixner }
735cee9645SThomas Gleixner 
745cee9645SThomas Gleixner /*
755cee9645SThomas Gleixner  * sys_stime() can be implemented in user-level using
765cee9645SThomas Gleixner  * sys_settimeofday().  Is this for backwards compatibility?  If so,
775cee9645SThomas Gleixner  * why not move it into the appropriate arch directory (for those
785cee9645SThomas Gleixner  * architectures that need it).
795cee9645SThomas Gleixner  */
805cee9645SThomas Gleixner 
815cee9645SThomas Gleixner SYSCALL_DEFINE1(stime, time_t __user *, tptr)
825cee9645SThomas Gleixner {
834eb1bca1SArnd Bergmann 	struct timespec64 tv;
845cee9645SThomas Gleixner 	int err;
855cee9645SThomas Gleixner 
865cee9645SThomas Gleixner 	if (get_user(tv.tv_sec, tptr))
875cee9645SThomas Gleixner 		return -EFAULT;
885cee9645SThomas Gleixner 
895cee9645SThomas Gleixner 	tv.tv_nsec = 0;
905cee9645SThomas Gleixner 
914eb1bca1SArnd Bergmann 	err = security_settime64(&tv, NULL);
925cee9645SThomas Gleixner 	if (err)
935cee9645SThomas Gleixner 		return err;
945cee9645SThomas Gleixner 
954eb1bca1SArnd Bergmann 	do_settimeofday64(&tv);
965cee9645SThomas Gleixner 	return 0;
975cee9645SThomas Gleixner }
985cee9645SThomas Gleixner 
995cee9645SThomas Gleixner #endif /* __ARCH_WANT_SYS_TIME */
1005cee9645SThomas Gleixner 
101b180db2cSAl Viro #ifdef CONFIG_COMPAT
102b180db2cSAl Viro #ifdef __ARCH_WANT_COMPAT_SYS_TIME
103b180db2cSAl Viro 
1049afc5eeeSArnd Bergmann /* old_time32_t is a 32 bit "long" and needs to get converted. */
1059afc5eeeSArnd Bergmann COMPAT_SYSCALL_DEFINE1(time, old_time32_t __user *, tloc)
106b180db2cSAl Viro {
1079afc5eeeSArnd Bergmann 	old_time32_t i;
108b180db2cSAl Viro 
1099afc5eeeSArnd Bergmann 	i = (old_time32_t)ktime_get_real_seconds();
110b180db2cSAl Viro 
111b180db2cSAl Viro 	if (tloc) {
112b180db2cSAl Viro 		if (put_user(i,tloc))
113b180db2cSAl Viro 			return -EFAULT;
114b180db2cSAl Viro 	}
115b180db2cSAl Viro 	force_successful_syscall_return();
116b180db2cSAl Viro 	return i;
117b180db2cSAl Viro }
118b180db2cSAl Viro 
1199afc5eeeSArnd Bergmann COMPAT_SYSCALL_DEFINE1(stime, old_time32_t __user *, tptr)
120b180db2cSAl Viro {
1214eb1bca1SArnd Bergmann 	struct timespec64 tv;
122b180db2cSAl Viro 	int err;
123b180db2cSAl Viro 
124b180db2cSAl Viro 	if (get_user(tv.tv_sec, tptr))
125b180db2cSAl Viro 		return -EFAULT;
126b180db2cSAl Viro 
127b180db2cSAl Viro 	tv.tv_nsec = 0;
128b180db2cSAl Viro 
1294eb1bca1SArnd Bergmann 	err = security_settime64(&tv, NULL);
130b180db2cSAl Viro 	if (err)
131b180db2cSAl Viro 		return err;
132b180db2cSAl Viro 
1334eb1bca1SArnd Bergmann 	do_settimeofday64(&tv);
134b180db2cSAl Viro 	return 0;
135b180db2cSAl Viro }
136b180db2cSAl Viro 
137b180db2cSAl Viro #endif /* __ARCH_WANT_COMPAT_SYS_TIME */
138b180db2cSAl Viro #endif
139b180db2cSAl Viro 
1405cee9645SThomas Gleixner SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
1415cee9645SThomas Gleixner 		struct timezone __user *, tz)
1425cee9645SThomas Gleixner {
1435cee9645SThomas Gleixner 	if (likely(tv != NULL)) {
14433e26418SArnd Bergmann 		struct timespec64 ts;
14533e26418SArnd Bergmann 
14633e26418SArnd Bergmann 		ktime_get_real_ts64(&ts);
14733e26418SArnd Bergmann 		if (put_user(ts.tv_sec, &tv->tv_sec) ||
14833e26418SArnd Bergmann 		    put_user(ts.tv_nsec / 1000, &tv->tv_usec))
1495cee9645SThomas Gleixner 			return -EFAULT;
1505cee9645SThomas Gleixner 	}
1515cee9645SThomas Gleixner 	if (unlikely(tz != NULL)) {
1525cee9645SThomas Gleixner 		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
1535cee9645SThomas Gleixner 			return -EFAULT;
1545cee9645SThomas Gleixner 	}
1555cee9645SThomas Gleixner 	return 0;
1565cee9645SThomas Gleixner }
1575cee9645SThomas Gleixner 
1585cee9645SThomas Gleixner /*
1595cee9645SThomas Gleixner  * In case for some reason the CMOS clock has not already been running
1605cee9645SThomas Gleixner  * in UTC, but in some local time: The first time we set the timezone,
1615cee9645SThomas Gleixner  * we will warp the clock so that it is ticking UTC time instead of
1625cee9645SThomas Gleixner  * local time. Presumably, if someone is setting the timezone then we
1635cee9645SThomas Gleixner  * are running in an environment where the programs understand about
1645cee9645SThomas Gleixner  * timezones. This should be done at boot time in the /etc/rc script,
1655cee9645SThomas Gleixner  * as soon as possible, so that the clock can be set right. Otherwise,
1665cee9645SThomas Gleixner  * various programs will get confused when the clock gets warped.
1675cee9645SThomas Gleixner  */
1685cee9645SThomas Gleixner 
16986d34732SBaolin Wang int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz)
1705cee9645SThomas Gleixner {
1715cee9645SThomas Gleixner 	static int firsttime = 1;
1725cee9645SThomas Gleixner 	int error = 0;
1735cee9645SThomas Gleixner 
17486d34732SBaolin Wang 	if (tv && !timespec64_valid(tv))
1755cee9645SThomas Gleixner 		return -EINVAL;
1765cee9645SThomas Gleixner 
17786d34732SBaolin Wang 	error = security_settime64(tv, tz);
1785cee9645SThomas Gleixner 	if (error)
1795cee9645SThomas Gleixner 		return error;
1805cee9645SThomas Gleixner 
1815cee9645SThomas Gleixner 	if (tz) {
1826f7d7984SSasha Levin 		/* Verify we're witin the +-15 hrs range */
1836f7d7984SSasha Levin 		if (tz->tz_minuteswest > 15*60 || tz->tz_minuteswest < -15*60)
1846f7d7984SSasha Levin 			return -EINVAL;
1856f7d7984SSasha Levin 
1865cee9645SThomas Gleixner 		sys_tz = *tz;
1875cee9645SThomas Gleixner 		update_vsyscall_tz();
1885cee9645SThomas Gleixner 		if (firsttime) {
1895cee9645SThomas Gleixner 			firsttime = 0;
1905cee9645SThomas Gleixner 			if (!tv)
191e0956dccSArnd Bergmann 				timekeeping_warp_clock();
1925cee9645SThomas Gleixner 		}
1935cee9645SThomas Gleixner 	}
1945cee9645SThomas Gleixner 	if (tv)
19586d34732SBaolin Wang 		return do_settimeofday64(tv);
1965cee9645SThomas Gleixner 	return 0;
1975cee9645SThomas Gleixner }
1985cee9645SThomas Gleixner 
1995cee9645SThomas Gleixner SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv,
2005cee9645SThomas Gleixner 		struct timezone __user *, tz)
2015cee9645SThomas Gleixner {
2022ac00f17SDeepa Dinamani 	struct timespec64 new_ts;
2035cee9645SThomas Gleixner 	struct timeval user_tv;
2045cee9645SThomas Gleixner 	struct timezone new_tz;
2055cee9645SThomas Gleixner 
2065cee9645SThomas Gleixner 	if (tv) {
2075cee9645SThomas Gleixner 		if (copy_from_user(&user_tv, tv, sizeof(*tv)))
2085cee9645SThomas Gleixner 			return -EFAULT;
2096ada1fc0SSasha Levin 
2106ada1fc0SSasha Levin 		if (!timeval_valid(&user_tv))
2116ada1fc0SSasha Levin 			return -EINVAL;
2126ada1fc0SSasha Levin 
2135cee9645SThomas Gleixner 		new_ts.tv_sec = user_tv.tv_sec;
2145cee9645SThomas Gleixner 		new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
2155cee9645SThomas Gleixner 	}
2165cee9645SThomas Gleixner 	if (tz) {
2175cee9645SThomas Gleixner 		if (copy_from_user(&new_tz, tz, sizeof(*tz)))
2185cee9645SThomas Gleixner 			return -EFAULT;
2195cee9645SThomas Gleixner 	}
2205cee9645SThomas Gleixner 
2212ac00f17SDeepa Dinamani 	return do_sys_settimeofday64(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
2225cee9645SThomas Gleixner }
2235cee9645SThomas Gleixner 
2242b2d0285SAl Viro #ifdef CONFIG_COMPAT
2259afc5eeeSArnd Bergmann COMPAT_SYSCALL_DEFINE2(gettimeofday, struct old_timeval32 __user *, tv,
2262b2d0285SAl Viro 		       struct timezone __user *, tz)
2272b2d0285SAl Viro {
2282b2d0285SAl Viro 	if (tv) {
22933e26418SArnd Bergmann 		struct timespec64 ts;
2302b2d0285SAl Viro 
23133e26418SArnd Bergmann 		ktime_get_real_ts64(&ts);
23233e26418SArnd Bergmann 		if (put_user(ts.tv_sec, &tv->tv_sec) ||
23333e26418SArnd Bergmann 		    put_user(ts.tv_nsec / 1000, &tv->tv_usec))
2342b2d0285SAl Viro 			return -EFAULT;
2352b2d0285SAl Viro 	}
2362b2d0285SAl Viro 	if (tz) {
2372b2d0285SAl Viro 		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
2382b2d0285SAl Viro 			return -EFAULT;
2392b2d0285SAl Viro 	}
2402b2d0285SAl Viro 
2412b2d0285SAl Viro 	return 0;
2422b2d0285SAl Viro }
2432b2d0285SAl Viro 
2449afc5eeeSArnd Bergmann COMPAT_SYSCALL_DEFINE2(settimeofday, struct old_timeval32 __user *, tv,
2452b2d0285SAl Viro 		       struct timezone __user *, tz)
2462b2d0285SAl Viro {
2472b2d0285SAl Viro 	struct timespec64 new_ts;
2482b2d0285SAl Viro 	struct timeval user_tv;
2492b2d0285SAl Viro 	struct timezone new_tz;
2502b2d0285SAl Viro 
2512b2d0285SAl Viro 	if (tv) {
2522b2d0285SAl Viro 		if (compat_get_timeval(&user_tv, tv))
2532b2d0285SAl Viro 			return -EFAULT;
2542b2d0285SAl Viro 		new_ts.tv_sec = user_tv.tv_sec;
2552b2d0285SAl Viro 		new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
2562b2d0285SAl Viro 	}
2572b2d0285SAl Viro 	if (tz) {
2582b2d0285SAl Viro 		if (copy_from_user(&new_tz, tz, sizeof(*tz)))
2592b2d0285SAl Viro 			return -EFAULT;
2602b2d0285SAl Viro 	}
2612b2d0285SAl Viro 
2622b2d0285SAl Viro 	return do_sys_settimeofday64(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
2632b2d0285SAl Viro }
2642b2d0285SAl Viro #endif
2652b2d0285SAl Viro 
2663876ced4SDeepa Dinamani #if !defined(CONFIG_64BIT_TIME) || defined(CONFIG_64BIT)
2673876ced4SDeepa Dinamani SYSCALL_DEFINE1(adjtimex, struct __kernel_timex __user *, txc_p)
2685cee9645SThomas Gleixner {
269ead25417SDeepa Dinamani 	struct __kernel_timex txc;		/* Local copy of parameter */
2705cee9645SThomas Gleixner 	int ret;
2715cee9645SThomas Gleixner 
2725cee9645SThomas Gleixner 	/* Copy the user data space into the kernel copy
2735cee9645SThomas Gleixner 	 * structure. But bear in mind that the structures
2745cee9645SThomas Gleixner 	 * may change
2755cee9645SThomas Gleixner 	 */
276ead25417SDeepa Dinamani 	if (copy_from_user(&txc, txc_p, sizeof(struct __kernel_timex)))
2775cee9645SThomas Gleixner 		return -EFAULT;
2785cee9645SThomas Gleixner 	ret = do_adjtimex(&txc);
279ead25417SDeepa Dinamani 	return copy_to_user(txc_p, &txc, sizeof(struct __kernel_timex)) ? -EFAULT : ret;
2805cee9645SThomas Gleixner }
2813876ced4SDeepa Dinamani #endif
2825cee9645SThomas Gleixner 
2834d5f007eSArnd Bergmann #ifdef CONFIG_COMPAT_32BIT_TIME
284ead25417SDeepa Dinamani int get_old_timex32(struct __kernel_timex *txc, const struct old_timex32 __user *utp)
2854d5f007eSArnd Bergmann {
2864d5f007eSArnd Bergmann 	struct old_timex32 tx32;
2873a4d44b6SAl Viro 
288ead25417SDeepa Dinamani 	memset(txc, 0, sizeof(struct __kernel_timex));
2894d5f007eSArnd Bergmann 	if (copy_from_user(&tx32, utp, sizeof(struct old_timex32)))
2904d5f007eSArnd Bergmann 		return -EFAULT;
2914d5f007eSArnd Bergmann 
2924d5f007eSArnd Bergmann 	txc->modes = tx32.modes;
2934d5f007eSArnd Bergmann 	txc->offset = tx32.offset;
2944d5f007eSArnd Bergmann 	txc->freq = tx32.freq;
2954d5f007eSArnd Bergmann 	txc->maxerror = tx32.maxerror;
2964d5f007eSArnd Bergmann 	txc->esterror = tx32.esterror;
2974d5f007eSArnd Bergmann 	txc->status = tx32.status;
2984d5f007eSArnd Bergmann 	txc->constant = tx32.constant;
2994d5f007eSArnd Bergmann 	txc->precision = tx32.precision;
3004d5f007eSArnd Bergmann 	txc->tolerance = tx32.tolerance;
3014d5f007eSArnd Bergmann 	txc->time.tv_sec = tx32.time.tv_sec;
3024d5f007eSArnd Bergmann 	txc->time.tv_usec = tx32.time.tv_usec;
3034d5f007eSArnd Bergmann 	txc->tick = tx32.tick;
3044d5f007eSArnd Bergmann 	txc->ppsfreq = tx32.ppsfreq;
3054d5f007eSArnd Bergmann 	txc->jitter = tx32.jitter;
3064d5f007eSArnd Bergmann 	txc->shift = tx32.shift;
3074d5f007eSArnd Bergmann 	txc->stabil = tx32.stabil;
3084d5f007eSArnd Bergmann 	txc->jitcnt = tx32.jitcnt;
3094d5f007eSArnd Bergmann 	txc->calcnt = tx32.calcnt;
3104d5f007eSArnd Bergmann 	txc->errcnt = tx32.errcnt;
3114d5f007eSArnd Bergmann 	txc->stbcnt = tx32.stbcnt;
3124d5f007eSArnd Bergmann 
3134d5f007eSArnd Bergmann 	return 0;
3144d5f007eSArnd Bergmann }
3154d5f007eSArnd Bergmann 
316ead25417SDeepa Dinamani int put_old_timex32(struct old_timex32 __user *utp, const struct __kernel_timex *txc)
3174d5f007eSArnd Bergmann {
3184d5f007eSArnd Bergmann 	struct old_timex32 tx32;
3194d5f007eSArnd Bergmann 
3204d5f007eSArnd Bergmann 	memset(&tx32, 0, sizeof(struct old_timex32));
3214d5f007eSArnd Bergmann 	tx32.modes = txc->modes;
3224d5f007eSArnd Bergmann 	tx32.offset = txc->offset;
3234d5f007eSArnd Bergmann 	tx32.freq = txc->freq;
3244d5f007eSArnd Bergmann 	tx32.maxerror = txc->maxerror;
3254d5f007eSArnd Bergmann 	tx32.esterror = txc->esterror;
3264d5f007eSArnd Bergmann 	tx32.status = txc->status;
3274d5f007eSArnd Bergmann 	tx32.constant = txc->constant;
3284d5f007eSArnd Bergmann 	tx32.precision = txc->precision;
3294d5f007eSArnd Bergmann 	tx32.tolerance = txc->tolerance;
3304d5f007eSArnd Bergmann 	tx32.time.tv_sec = txc->time.tv_sec;
3314d5f007eSArnd Bergmann 	tx32.time.tv_usec = txc->time.tv_usec;
3324d5f007eSArnd Bergmann 	tx32.tick = txc->tick;
3334d5f007eSArnd Bergmann 	tx32.ppsfreq = txc->ppsfreq;
3344d5f007eSArnd Bergmann 	tx32.jitter = txc->jitter;
3354d5f007eSArnd Bergmann 	tx32.shift = txc->shift;
3364d5f007eSArnd Bergmann 	tx32.stabil = txc->stabil;
3374d5f007eSArnd Bergmann 	tx32.jitcnt = txc->jitcnt;
3384d5f007eSArnd Bergmann 	tx32.calcnt = txc->calcnt;
3394d5f007eSArnd Bergmann 	tx32.errcnt = txc->errcnt;
3404d5f007eSArnd Bergmann 	tx32.stbcnt = txc->stbcnt;
3414d5f007eSArnd Bergmann 	tx32.tai = txc->tai;
3424d5f007eSArnd Bergmann 	if (copy_to_user(utp, &tx32, sizeof(struct old_timex32)))
3434d5f007eSArnd Bergmann 		return -EFAULT;
3444d5f007eSArnd Bergmann 	return 0;
3454d5f007eSArnd Bergmann }
3464d5f007eSArnd Bergmann 
3474d5f007eSArnd Bergmann COMPAT_SYSCALL_DEFINE1(adjtimex, struct old_timex32 __user *, utp)
3483a4d44b6SAl Viro {
349ead25417SDeepa Dinamani 	struct __kernel_timex txc;
3503a4d44b6SAl Viro 	int err, ret;
3513a4d44b6SAl Viro 
3524d5f007eSArnd Bergmann 	err = get_old_timex32(&txc, utp);
3533a4d44b6SAl Viro 	if (err)
3543a4d44b6SAl Viro 		return err;
3553a4d44b6SAl Viro 
3563a4d44b6SAl Viro 	ret = do_adjtimex(&txc);
3573a4d44b6SAl Viro 
3584d5f007eSArnd Bergmann 	err = put_old_timex32(utp, &txc);
3593a4d44b6SAl Viro 	if (err)
3603a4d44b6SAl Viro 		return err;
3613a4d44b6SAl Viro 
3623a4d44b6SAl Viro 	return ret;
3633a4d44b6SAl Viro }
3643a4d44b6SAl Viro #endif
3653a4d44b6SAl Viro 
3665cee9645SThomas Gleixner /*
3675cee9645SThomas Gleixner  * Convert jiffies to milliseconds and back.
3685cee9645SThomas Gleixner  *
3695cee9645SThomas Gleixner  * Avoid unnecessary multiplications/divisions in the
3705cee9645SThomas Gleixner  * two most common HZ cases:
3715cee9645SThomas Gleixner  */
3725cee9645SThomas Gleixner unsigned int jiffies_to_msecs(const unsigned long j)
3735cee9645SThomas Gleixner {
3745cee9645SThomas Gleixner #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
3755cee9645SThomas Gleixner 	return (MSEC_PER_SEC / HZ) * j;
3765cee9645SThomas Gleixner #elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
3775cee9645SThomas Gleixner 	return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
3785cee9645SThomas Gleixner #else
3795cee9645SThomas Gleixner # if BITS_PER_LONG == 32
380abcbcb80SGeert Uytterhoeven 	return (HZ_TO_MSEC_MUL32 * j + (1ULL << HZ_TO_MSEC_SHR32) - 1) >>
381abcbcb80SGeert Uytterhoeven 	       HZ_TO_MSEC_SHR32;
3825cee9645SThomas Gleixner # else
383abcbcb80SGeert Uytterhoeven 	return DIV_ROUND_UP(j * HZ_TO_MSEC_NUM, HZ_TO_MSEC_DEN);
3845cee9645SThomas Gleixner # endif
3855cee9645SThomas Gleixner #endif
3865cee9645SThomas Gleixner }
3875cee9645SThomas Gleixner EXPORT_SYMBOL(jiffies_to_msecs);
3885cee9645SThomas Gleixner 
3895cee9645SThomas Gleixner unsigned int jiffies_to_usecs(const unsigned long j)
3905cee9645SThomas Gleixner {
391e0758676SFrederic Weisbecker 	/*
392e0758676SFrederic Weisbecker 	 * Hz usually doesn't go much further MSEC_PER_SEC.
393e0758676SFrederic Weisbecker 	 * jiffies_to_usecs() and usecs_to_jiffies() depend on that.
394e0758676SFrederic Weisbecker 	 */
395e0758676SFrederic Weisbecker 	BUILD_BUG_ON(HZ > USEC_PER_SEC);
396e0758676SFrederic Weisbecker 
397e0758676SFrederic Weisbecker #if !(USEC_PER_SEC % HZ)
3985cee9645SThomas Gleixner 	return (USEC_PER_SEC / HZ) * j;
3995cee9645SThomas Gleixner #else
4005cee9645SThomas Gleixner # if BITS_PER_LONG == 32
4015cee9645SThomas Gleixner 	return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
4025cee9645SThomas Gleixner # else
4035cee9645SThomas Gleixner 	return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN;
4045cee9645SThomas Gleixner # endif
4055cee9645SThomas Gleixner #endif
4065cee9645SThomas Gleixner }
4075cee9645SThomas Gleixner EXPORT_SYMBOL(jiffies_to_usecs);
4085cee9645SThomas Gleixner 
40990b6ce9cSpang.xunlei /*
41090b6ce9cSpang.xunlei  * mktime64 - Converts date to seconds.
41190b6ce9cSpang.xunlei  * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
4125cee9645SThomas Gleixner  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
4135cee9645SThomas Gleixner  * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
4145cee9645SThomas Gleixner  *
4155cee9645SThomas Gleixner  * [For the Julian calendar (which was used in Russia before 1917,
4165cee9645SThomas Gleixner  * Britain & colonies before 1752, anywhere else before 1582,
4175cee9645SThomas Gleixner  * and is still in use by some communities) leave out the
4185cee9645SThomas Gleixner  * -year/100+year/400 terms, and add 10.]
4195cee9645SThomas Gleixner  *
4205cee9645SThomas Gleixner  * This algorithm was first published by Gauss (I think).
421ede5147dSDavid Howells  *
422ede5147dSDavid Howells  * A leap second can be indicated by calling this function with sec as
423ede5147dSDavid Howells  * 60 (allowable under ISO 8601).  The leap second is treated the same
424ede5147dSDavid Howells  * as the following second since they don't exist in UNIX time.
425ede5147dSDavid Howells  *
426ede5147dSDavid Howells  * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight
427ede5147dSDavid Howells  * tomorrow - (allowable under ISO 8601) is supported.
4285cee9645SThomas Gleixner  */
42990b6ce9cSpang.xunlei time64_t mktime64(const unsigned int year0, const unsigned int mon0,
4305cee9645SThomas Gleixner 		const unsigned int day, const unsigned int hour,
4315cee9645SThomas Gleixner 		const unsigned int min, const unsigned int sec)
4325cee9645SThomas Gleixner {
4335cee9645SThomas Gleixner 	unsigned int mon = mon0, year = year0;
4345cee9645SThomas Gleixner 
4355cee9645SThomas Gleixner 	/* 1..12 -> 11,12,1..10 */
4365cee9645SThomas Gleixner 	if (0 >= (int) (mon -= 2)) {
4375cee9645SThomas Gleixner 		mon += 12;	/* Puts Feb last since it has leap day */
4385cee9645SThomas Gleixner 		year -= 1;
4395cee9645SThomas Gleixner 	}
4405cee9645SThomas Gleixner 
44190b6ce9cSpang.xunlei 	return ((((time64_t)
4425cee9645SThomas Gleixner 		  (year/4 - year/100 + year/400 + 367*mon/12 + day) +
4435cee9645SThomas Gleixner 		  year*365 - 719499
444ede5147dSDavid Howells 	    )*24 + hour /* now have hours - midnight tomorrow handled here */
4455cee9645SThomas Gleixner 	  )*60 + min /* now have minutes */
4465cee9645SThomas Gleixner 	)*60 + sec; /* finally seconds */
4475cee9645SThomas Gleixner }
44890b6ce9cSpang.xunlei EXPORT_SYMBOL(mktime64);
4495cee9645SThomas Gleixner 
4505cee9645SThomas Gleixner /**
4515cee9645SThomas Gleixner  * ns_to_timespec - Convert nanoseconds to timespec
4525cee9645SThomas Gleixner  * @nsec:       the nanoseconds value to be converted
4535cee9645SThomas Gleixner  *
4545cee9645SThomas Gleixner  * Returns the timespec representation of the nsec parameter.
4555cee9645SThomas Gleixner  */
4565cee9645SThomas Gleixner struct timespec ns_to_timespec(const s64 nsec)
4575cee9645SThomas Gleixner {
4585cee9645SThomas Gleixner 	struct timespec ts;
4595cee9645SThomas Gleixner 	s32 rem;
4605cee9645SThomas Gleixner 
4615cee9645SThomas Gleixner 	if (!nsec)
4625cee9645SThomas Gleixner 		return (struct timespec) {0, 0};
4635cee9645SThomas Gleixner 
4645cee9645SThomas Gleixner 	ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
4655cee9645SThomas Gleixner 	if (unlikely(rem < 0)) {
4665cee9645SThomas Gleixner 		ts.tv_sec--;
4675cee9645SThomas Gleixner 		rem += NSEC_PER_SEC;
4685cee9645SThomas Gleixner 	}
4695cee9645SThomas Gleixner 	ts.tv_nsec = rem;
4705cee9645SThomas Gleixner 
4715cee9645SThomas Gleixner 	return ts;
4725cee9645SThomas Gleixner }
4735cee9645SThomas Gleixner EXPORT_SYMBOL(ns_to_timespec);
4745cee9645SThomas Gleixner 
4755cee9645SThomas Gleixner /**
4765cee9645SThomas Gleixner  * ns_to_timeval - Convert nanoseconds to timeval
4775cee9645SThomas Gleixner  * @nsec:       the nanoseconds value to be converted
4785cee9645SThomas Gleixner  *
4795cee9645SThomas Gleixner  * Returns the timeval representation of the nsec parameter.
4805cee9645SThomas Gleixner  */
4815cee9645SThomas Gleixner struct timeval ns_to_timeval(const s64 nsec)
4825cee9645SThomas Gleixner {
4835cee9645SThomas Gleixner 	struct timespec ts = ns_to_timespec(nsec);
4845cee9645SThomas Gleixner 	struct timeval tv;
4855cee9645SThomas Gleixner 
4865cee9645SThomas Gleixner 	tv.tv_sec = ts.tv_sec;
4875cee9645SThomas Gleixner 	tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;
4885cee9645SThomas Gleixner 
4895cee9645SThomas Gleixner 	return tv;
4905cee9645SThomas Gleixner }
4915cee9645SThomas Gleixner EXPORT_SYMBOL(ns_to_timeval);
4925cee9645SThomas Gleixner 
493a84d1169SArnd Bergmann struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec)
494a84d1169SArnd Bergmann {
495a84d1169SArnd Bergmann 	struct timespec64 ts = ns_to_timespec64(nsec);
496a84d1169SArnd Bergmann 	struct __kernel_old_timeval tv;
497a84d1169SArnd Bergmann 
498a84d1169SArnd Bergmann 	tv.tv_sec = ts.tv_sec;
499a84d1169SArnd Bergmann 	tv.tv_usec = (suseconds_t)ts.tv_nsec / 1000;
500a84d1169SArnd Bergmann 
501a84d1169SArnd Bergmann 	return tv;
502a84d1169SArnd Bergmann }
503a84d1169SArnd Bergmann EXPORT_SYMBOL(ns_to_kernel_old_timeval);
504a84d1169SArnd Bergmann 
50549cd6f86SJohn Stultz /**
50649cd6f86SJohn Stultz  * set_normalized_timespec - set timespec sec and nsec parts and normalize
50749cd6f86SJohn Stultz  *
50849cd6f86SJohn Stultz  * @ts:		pointer to timespec variable to be set
50949cd6f86SJohn Stultz  * @sec:	seconds to set
51049cd6f86SJohn Stultz  * @nsec:	nanoseconds to set
51149cd6f86SJohn Stultz  *
51249cd6f86SJohn Stultz  * Set seconds and nanoseconds field of a timespec variable and
51349cd6f86SJohn Stultz  * normalize to the timespec storage format
51449cd6f86SJohn Stultz  *
51549cd6f86SJohn Stultz  * Note: The tv_nsec part is always in the range of
51649cd6f86SJohn Stultz  *	0 <= tv_nsec < NSEC_PER_SEC
51749cd6f86SJohn Stultz  * For negative values only the tv_sec field is negative !
51849cd6f86SJohn Stultz  */
51949cd6f86SJohn Stultz void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec)
52049cd6f86SJohn Stultz {
52149cd6f86SJohn Stultz 	while (nsec >= NSEC_PER_SEC) {
52249cd6f86SJohn Stultz 		/*
52349cd6f86SJohn Stultz 		 * The following asm() prevents the compiler from
52449cd6f86SJohn Stultz 		 * optimising this loop into a modulo operation. See
52549cd6f86SJohn Stultz 		 * also __iter_div_u64_rem() in include/linux/time.h
52649cd6f86SJohn Stultz 		 */
52749cd6f86SJohn Stultz 		asm("" : "+rm"(nsec));
52849cd6f86SJohn Stultz 		nsec -= NSEC_PER_SEC;
52949cd6f86SJohn Stultz 		++sec;
53049cd6f86SJohn Stultz 	}
53149cd6f86SJohn Stultz 	while (nsec < 0) {
53249cd6f86SJohn Stultz 		asm("" : "+rm"(nsec));
53349cd6f86SJohn Stultz 		nsec += NSEC_PER_SEC;
53449cd6f86SJohn Stultz 		--sec;
53549cd6f86SJohn Stultz 	}
53649cd6f86SJohn Stultz 	ts->tv_sec = sec;
53749cd6f86SJohn Stultz 	ts->tv_nsec = nsec;
53849cd6f86SJohn Stultz }
53949cd6f86SJohn Stultz EXPORT_SYMBOL(set_normalized_timespec64);
54049cd6f86SJohn Stultz 
54149cd6f86SJohn Stultz /**
54249cd6f86SJohn Stultz  * ns_to_timespec64 - Convert nanoseconds to timespec64
54349cd6f86SJohn Stultz  * @nsec:       the nanoseconds value to be converted
54449cd6f86SJohn Stultz  *
54549cd6f86SJohn Stultz  * Returns the timespec64 representation of the nsec parameter.
54649cd6f86SJohn Stultz  */
54749cd6f86SJohn Stultz struct timespec64 ns_to_timespec64(const s64 nsec)
54849cd6f86SJohn Stultz {
54949cd6f86SJohn Stultz 	struct timespec64 ts;
55049cd6f86SJohn Stultz 	s32 rem;
55149cd6f86SJohn Stultz 
55249cd6f86SJohn Stultz 	if (!nsec)
55349cd6f86SJohn Stultz 		return (struct timespec64) {0, 0};
55449cd6f86SJohn Stultz 
55549cd6f86SJohn Stultz 	ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
55649cd6f86SJohn Stultz 	if (unlikely(rem < 0)) {
55749cd6f86SJohn Stultz 		ts.tv_sec--;
55849cd6f86SJohn Stultz 		rem += NSEC_PER_SEC;
55949cd6f86SJohn Stultz 	}
56049cd6f86SJohn Stultz 	ts.tv_nsec = rem;
56149cd6f86SJohn Stultz 
56249cd6f86SJohn Stultz 	return ts;
56349cd6f86SJohn Stultz }
56449cd6f86SJohn Stultz EXPORT_SYMBOL(ns_to_timespec64);
565abc8f96eSArnd Bergmann 
566ca42aaf0SNicholas Mc Guire /**
567ca42aaf0SNicholas Mc Guire  * msecs_to_jiffies: - convert milliseconds to jiffies
568ca42aaf0SNicholas Mc Guire  * @m:	time in milliseconds
569ca42aaf0SNicholas Mc Guire  *
570ca42aaf0SNicholas Mc Guire  * conversion is done as follows:
5715cee9645SThomas Gleixner  *
5725cee9645SThomas Gleixner  * - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
5735cee9645SThomas Gleixner  *
5745cee9645SThomas Gleixner  * - 'too large' values [that would result in larger than
5755cee9645SThomas Gleixner  *   MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
5765cee9645SThomas Gleixner  *
5775cee9645SThomas Gleixner  * - all other values are converted to jiffies by either multiplying
578ca42aaf0SNicholas Mc Guire  *   the input value by a factor or dividing it with a factor and
579ca42aaf0SNicholas Mc Guire  *   handling any 32-bit overflows.
580ca42aaf0SNicholas Mc Guire  *   for the details see __msecs_to_jiffies()
5815cee9645SThomas Gleixner  *
582ca42aaf0SNicholas Mc Guire  * msecs_to_jiffies() checks for the passed in value being a constant
583ca42aaf0SNicholas Mc Guire  * via __builtin_constant_p() allowing gcc to eliminate most of the
584ca42aaf0SNicholas Mc Guire  * code, __msecs_to_jiffies() is called if the value passed does not
585ca42aaf0SNicholas Mc Guire  * allow constant folding and the actual conversion must be done at
586ca42aaf0SNicholas Mc Guire  * runtime.
587ca42aaf0SNicholas Mc Guire  * the _msecs_to_jiffies helpers are the HZ dependent conversion
588ca42aaf0SNicholas Mc Guire  * routines found in include/linux/jiffies.h
5895cee9645SThomas Gleixner  */
590ca42aaf0SNicholas Mc Guire unsigned long __msecs_to_jiffies(const unsigned int m)
5915cee9645SThomas Gleixner {
5925cee9645SThomas Gleixner 	/*
5935cee9645SThomas Gleixner 	 * Negative value, means infinite timeout:
5945cee9645SThomas Gleixner 	 */
5955cee9645SThomas Gleixner 	if ((int)m < 0)
5965cee9645SThomas Gleixner 		return MAX_JIFFY_OFFSET;
597ca42aaf0SNicholas Mc Guire 	return _msecs_to_jiffies(m);
5985cee9645SThomas Gleixner }
599ca42aaf0SNicholas Mc Guire EXPORT_SYMBOL(__msecs_to_jiffies);
6005cee9645SThomas Gleixner 
601ae60d6a0SNicholas Mc Guire unsigned long __usecs_to_jiffies(const unsigned int u)
6025cee9645SThomas Gleixner {
6035cee9645SThomas Gleixner 	if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
6045cee9645SThomas Gleixner 		return MAX_JIFFY_OFFSET;
605ae60d6a0SNicholas Mc Guire 	return _usecs_to_jiffies(u);
6065cee9645SThomas Gleixner }
607ae60d6a0SNicholas Mc Guire EXPORT_SYMBOL(__usecs_to_jiffies);
6085cee9645SThomas Gleixner 
6095cee9645SThomas Gleixner /*
6105cee9645SThomas Gleixner  * The TICK_NSEC - 1 rounds up the value to the next resolution.  Note
6115cee9645SThomas Gleixner  * that a remainder subtract here would not do the right thing as the
6125cee9645SThomas Gleixner  * resolution values don't fall on second boundries.  I.e. the line:
6135cee9645SThomas Gleixner  * nsec -= nsec % TICK_NSEC; is NOT a correct resolution rounding.
614d78c9300SAndrew Hunter  * Note that due to the small error in the multiplier here, this
615d78c9300SAndrew Hunter  * rounding is incorrect for sufficiently large values of tv_nsec, but
616d78c9300SAndrew Hunter  * well formed timespecs should have tv_nsec < NSEC_PER_SEC, so we're
617d78c9300SAndrew Hunter  * OK.
6185cee9645SThomas Gleixner  *
6195cee9645SThomas Gleixner  * Rather, we just shift the bits off the right.
6205cee9645SThomas Gleixner  *
6215cee9645SThomas Gleixner  * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
6225cee9645SThomas Gleixner  * value to a scaled second value.
6235cee9645SThomas Gleixner  */
624d78c9300SAndrew Hunter static unsigned long
6259ca30850SBaolin Wang __timespec64_to_jiffies(u64 sec, long nsec)
6265cee9645SThomas Gleixner {
627d78c9300SAndrew Hunter 	nsec = nsec + TICK_NSEC - 1;
6285cee9645SThomas Gleixner 
6295cee9645SThomas Gleixner 	if (sec >= MAX_SEC_IN_JIFFIES){
6305cee9645SThomas Gleixner 		sec = MAX_SEC_IN_JIFFIES;
6315cee9645SThomas Gleixner 		nsec = 0;
6325cee9645SThomas Gleixner 	}
6339ca30850SBaolin Wang 	return ((sec * SEC_CONVERSION) +
6345cee9645SThomas Gleixner 		(((u64)nsec * NSEC_CONVERSION) >>
6355cee9645SThomas Gleixner 		 (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
6365cee9645SThomas Gleixner 
6375cee9645SThomas Gleixner }
638d78c9300SAndrew Hunter 
6399ca30850SBaolin Wang static unsigned long
6409ca30850SBaolin Wang __timespec_to_jiffies(unsigned long sec, long nsec)
641d78c9300SAndrew Hunter {
6429ca30850SBaolin Wang 	return __timespec64_to_jiffies((u64)sec, nsec);
643d78c9300SAndrew Hunter }
644d78c9300SAndrew Hunter 
6459ca30850SBaolin Wang unsigned long
6469ca30850SBaolin Wang timespec64_to_jiffies(const struct timespec64 *value)
6479ca30850SBaolin Wang {
6489ca30850SBaolin Wang 	return __timespec64_to_jiffies(value->tv_sec, value->tv_nsec);
6499ca30850SBaolin Wang }
6509ca30850SBaolin Wang EXPORT_SYMBOL(timespec64_to_jiffies);
6515cee9645SThomas Gleixner 
6525cee9645SThomas Gleixner void
6539ca30850SBaolin Wang jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value)
6545cee9645SThomas Gleixner {
6555cee9645SThomas Gleixner 	/*
6565cee9645SThomas Gleixner 	 * Convert jiffies to nanoseconds and separate with
6575cee9645SThomas Gleixner 	 * one divide.
6585cee9645SThomas Gleixner 	 */
6595cee9645SThomas Gleixner 	u32 rem;
6605cee9645SThomas Gleixner 	value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
6615cee9645SThomas Gleixner 				    NSEC_PER_SEC, &rem);
6625cee9645SThomas Gleixner 	value->tv_nsec = rem;
6635cee9645SThomas Gleixner }
6649ca30850SBaolin Wang EXPORT_SYMBOL(jiffies_to_timespec64);
6655cee9645SThomas Gleixner 
666d78c9300SAndrew Hunter /*
667d78c9300SAndrew Hunter  * We could use a similar algorithm to timespec_to_jiffies (with a
668d78c9300SAndrew Hunter  * different multiplier for usec instead of nsec). But this has a
669d78c9300SAndrew Hunter  * problem with rounding: we can't exactly add TICK_NSEC - 1 to the
670d78c9300SAndrew Hunter  * usec value, since it's not necessarily integral.
6715cee9645SThomas Gleixner  *
672d78c9300SAndrew Hunter  * We could instead round in the intermediate scaled representation
673d78c9300SAndrew Hunter  * (i.e. in units of 1/2^(large scale) jiffies) but that's also
674d78c9300SAndrew Hunter  * perilous: the scaling introduces a small positive error, which
675d78c9300SAndrew Hunter  * combined with a division-rounding-upward (i.e. adding 2^(scale) - 1
676d78c9300SAndrew Hunter  * units to the intermediate before shifting) leads to accidental
677d78c9300SAndrew Hunter  * overflow and overestimates.
678d78c9300SAndrew Hunter  *
679d78c9300SAndrew Hunter  * At the cost of one additional multiplication by a constant, just
680d78c9300SAndrew Hunter  * use the timespec implementation.
6815cee9645SThomas Gleixner  */
6825cee9645SThomas Gleixner unsigned long
6835cee9645SThomas Gleixner timeval_to_jiffies(const struct timeval *value)
6845cee9645SThomas Gleixner {
685d78c9300SAndrew Hunter 	return __timespec_to_jiffies(value->tv_sec,
686d78c9300SAndrew Hunter 				     value->tv_usec * NSEC_PER_USEC);
6875cee9645SThomas Gleixner }
6885cee9645SThomas Gleixner EXPORT_SYMBOL(timeval_to_jiffies);
6895cee9645SThomas Gleixner 
6905cee9645SThomas Gleixner void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)
6915cee9645SThomas Gleixner {
6925cee9645SThomas Gleixner 	/*
6935cee9645SThomas Gleixner 	 * Convert jiffies to nanoseconds and separate with
6945cee9645SThomas Gleixner 	 * one divide.
6955cee9645SThomas Gleixner 	 */
6965cee9645SThomas Gleixner 	u32 rem;
6975cee9645SThomas Gleixner 
6985cee9645SThomas Gleixner 	value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
6995cee9645SThomas Gleixner 				    NSEC_PER_SEC, &rem);
7005cee9645SThomas Gleixner 	value->tv_usec = rem / NSEC_PER_USEC;
7015cee9645SThomas Gleixner }
7025cee9645SThomas Gleixner EXPORT_SYMBOL(jiffies_to_timeval);
7035cee9645SThomas Gleixner 
7045cee9645SThomas Gleixner /*
7055cee9645SThomas Gleixner  * Convert jiffies/jiffies_64 to clock_t and back.
7065cee9645SThomas Gleixner  */
7075cee9645SThomas Gleixner clock_t jiffies_to_clock_t(unsigned long x)
7085cee9645SThomas Gleixner {
7095cee9645SThomas Gleixner #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
7105cee9645SThomas Gleixner # if HZ < USER_HZ
7115cee9645SThomas Gleixner 	return x * (USER_HZ / HZ);
7125cee9645SThomas Gleixner # else
7135cee9645SThomas Gleixner 	return x / (HZ / USER_HZ);
7145cee9645SThomas Gleixner # endif
7155cee9645SThomas Gleixner #else
7165cee9645SThomas Gleixner 	return div_u64((u64)x * TICK_NSEC, NSEC_PER_SEC / USER_HZ);
7175cee9645SThomas Gleixner #endif
7185cee9645SThomas Gleixner }
7195cee9645SThomas Gleixner EXPORT_SYMBOL(jiffies_to_clock_t);
7205cee9645SThomas Gleixner 
7215cee9645SThomas Gleixner unsigned long clock_t_to_jiffies(unsigned long x)
7225cee9645SThomas Gleixner {
7235cee9645SThomas Gleixner #if (HZ % USER_HZ)==0
7245cee9645SThomas Gleixner 	if (x >= ~0UL / (HZ / USER_HZ))
7255cee9645SThomas Gleixner 		return ~0UL;
7265cee9645SThomas Gleixner 	return x * (HZ / USER_HZ);
7275cee9645SThomas Gleixner #else
7285cee9645SThomas Gleixner 	/* Don't worry about loss of precision here .. */
7295cee9645SThomas Gleixner 	if (x >= ~0UL / HZ * USER_HZ)
7305cee9645SThomas Gleixner 		return ~0UL;
7315cee9645SThomas Gleixner 
7325cee9645SThomas Gleixner 	/* .. but do try to contain it here */
7335cee9645SThomas Gleixner 	return div_u64((u64)x * HZ, USER_HZ);
7345cee9645SThomas Gleixner #endif
7355cee9645SThomas Gleixner }
7365cee9645SThomas Gleixner EXPORT_SYMBOL(clock_t_to_jiffies);
7375cee9645SThomas Gleixner 
7385cee9645SThomas Gleixner u64 jiffies_64_to_clock_t(u64 x)
7395cee9645SThomas Gleixner {
7405cee9645SThomas Gleixner #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
7415cee9645SThomas Gleixner # if HZ < USER_HZ
7425cee9645SThomas Gleixner 	x = div_u64(x * USER_HZ, HZ);
7435cee9645SThomas Gleixner # elif HZ > USER_HZ
7445cee9645SThomas Gleixner 	x = div_u64(x, HZ / USER_HZ);
7455cee9645SThomas Gleixner # else
7465cee9645SThomas Gleixner 	/* Nothing to do */
7475cee9645SThomas Gleixner # endif
7485cee9645SThomas Gleixner #else
7495cee9645SThomas Gleixner 	/*
7505cee9645SThomas Gleixner 	 * There are better ways that don't overflow early,
7515cee9645SThomas Gleixner 	 * but even this doesn't overflow in hundreds of years
7525cee9645SThomas Gleixner 	 * in 64 bits, so..
7535cee9645SThomas Gleixner 	 */
7545cee9645SThomas Gleixner 	x = div_u64(x * TICK_NSEC, (NSEC_PER_SEC / USER_HZ));
7555cee9645SThomas Gleixner #endif
7565cee9645SThomas Gleixner 	return x;
7575cee9645SThomas Gleixner }
7585cee9645SThomas Gleixner EXPORT_SYMBOL(jiffies_64_to_clock_t);
7595cee9645SThomas Gleixner 
7605cee9645SThomas Gleixner u64 nsec_to_clock_t(u64 x)
7615cee9645SThomas Gleixner {
7625cee9645SThomas Gleixner #if (NSEC_PER_SEC % USER_HZ) == 0
7635cee9645SThomas Gleixner 	return div_u64(x, NSEC_PER_SEC / USER_HZ);
7645cee9645SThomas Gleixner #elif (USER_HZ % 512) == 0
7655cee9645SThomas Gleixner 	return div_u64(x * USER_HZ / 512, NSEC_PER_SEC / 512);
7665cee9645SThomas Gleixner #else
7675cee9645SThomas Gleixner 	/*
7685cee9645SThomas Gleixner          * max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024,
7695cee9645SThomas Gleixner          * overflow after 64.99 years.
7705cee9645SThomas Gleixner          * exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ...
7715cee9645SThomas Gleixner          */
7725cee9645SThomas Gleixner 	return div_u64(x * 9, (9ull * NSEC_PER_SEC + (USER_HZ / 2)) / USER_HZ);
7735cee9645SThomas Gleixner #endif
7745cee9645SThomas Gleixner }
7755cee9645SThomas Gleixner 
77607e5f5e3SFrederic Weisbecker u64 jiffies64_to_nsecs(u64 j)
77707e5f5e3SFrederic Weisbecker {
77807e5f5e3SFrederic Weisbecker #if !(NSEC_PER_SEC % HZ)
77907e5f5e3SFrederic Weisbecker 	return (NSEC_PER_SEC / HZ) * j;
78007e5f5e3SFrederic Weisbecker # else
78107e5f5e3SFrederic Weisbecker 	return div_u64(j * HZ_TO_NSEC_NUM, HZ_TO_NSEC_DEN);
78207e5f5e3SFrederic Weisbecker #endif
78307e5f5e3SFrederic Weisbecker }
78407e5f5e3SFrederic Weisbecker EXPORT_SYMBOL(jiffies64_to_nsecs);
78507e5f5e3SFrederic Weisbecker 
7865cee9645SThomas Gleixner /**
7875cee9645SThomas Gleixner  * nsecs_to_jiffies64 - Convert nsecs in u64 to jiffies64
7885cee9645SThomas Gleixner  *
7895cee9645SThomas Gleixner  * @n:	nsecs in u64
7905cee9645SThomas Gleixner  *
7915cee9645SThomas Gleixner  * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64.
7925cee9645SThomas Gleixner  * And this doesn't return MAX_JIFFY_OFFSET since this function is designed
7935cee9645SThomas Gleixner  * for scheduler, not for use in device drivers to calculate timeout value.
7945cee9645SThomas Gleixner  *
7955cee9645SThomas Gleixner  * note:
7965cee9645SThomas Gleixner  *   NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
7975cee9645SThomas Gleixner  *   ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
7985cee9645SThomas Gleixner  */
7995cee9645SThomas Gleixner u64 nsecs_to_jiffies64(u64 n)
8005cee9645SThomas Gleixner {
8015cee9645SThomas Gleixner #if (NSEC_PER_SEC % HZ) == 0
8025cee9645SThomas Gleixner 	/* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */
8035cee9645SThomas Gleixner 	return div_u64(n, NSEC_PER_SEC / HZ);
8045cee9645SThomas Gleixner #elif (HZ % 512) == 0
8055cee9645SThomas Gleixner 	/* overflow after 292 years if HZ = 1024 */
8065cee9645SThomas Gleixner 	return div_u64(n * HZ / 512, NSEC_PER_SEC / 512);
8075cee9645SThomas Gleixner #else
8085cee9645SThomas Gleixner 	/*
8095cee9645SThomas Gleixner 	 * Generic case - optimized for cases where HZ is a multiple of 3.
8105cee9645SThomas Gleixner 	 * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc.
8115cee9645SThomas Gleixner 	 */
8125cee9645SThomas Gleixner 	return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ);
8135cee9645SThomas Gleixner #endif
8145cee9645SThomas Gleixner }
8157bd0e226SDaniel Vetter EXPORT_SYMBOL(nsecs_to_jiffies64);
8165cee9645SThomas Gleixner 
8175cee9645SThomas Gleixner /**
8185cee9645SThomas Gleixner  * nsecs_to_jiffies - Convert nsecs in u64 to jiffies
8195cee9645SThomas Gleixner  *
8205cee9645SThomas Gleixner  * @n:	nsecs in u64
8215cee9645SThomas Gleixner  *
8225cee9645SThomas Gleixner  * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64.
8235cee9645SThomas Gleixner  * And this doesn't return MAX_JIFFY_OFFSET since this function is designed
8245cee9645SThomas Gleixner  * for scheduler, not for use in device drivers to calculate timeout value.
8255cee9645SThomas Gleixner  *
8265cee9645SThomas Gleixner  * note:
8275cee9645SThomas Gleixner  *   NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
8285cee9645SThomas Gleixner  *   ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
8295cee9645SThomas Gleixner  */
8305cee9645SThomas Gleixner unsigned long nsecs_to_jiffies(u64 n)
8315cee9645SThomas Gleixner {
8325cee9645SThomas Gleixner 	return (unsigned long)nsecs_to_jiffies64(n);
8335cee9645SThomas Gleixner }
834d560fed6SThomas Gleixner EXPORT_SYMBOL_GPL(nsecs_to_jiffies);
8355cee9645SThomas Gleixner 
8365cee9645SThomas Gleixner /*
837bc2c53e5SDeepa Dinamani  * Add two timespec64 values and do a safety check for overflow.
838bc2c53e5SDeepa Dinamani  * It's assumed that both values are valid (>= 0).
839bc2c53e5SDeepa Dinamani  * And, each timespec64 is in normalized form.
840bc2c53e5SDeepa Dinamani  */
841bc2c53e5SDeepa Dinamani struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
842bc2c53e5SDeepa Dinamani 				const struct timespec64 rhs)
843bc2c53e5SDeepa Dinamani {
844bc2c53e5SDeepa Dinamani 	struct timespec64 res;
845bc2c53e5SDeepa Dinamani 
846469e857fSVegard Nossum 	set_normalized_timespec64(&res, (timeu64_t) lhs.tv_sec + rhs.tv_sec,
847bc2c53e5SDeepa Dinamani 			lhs.tv_nsec + rhs.tv_nsec);
848bc2c53e5SDeepa Dinamani 
849bc2c53e5SDeepa Dinamani 	if (unlikely(res.tv_sec < lhs.tv_sec || res.tv_sec < rhs.tv_sec)) {
850bc2c53e5SDeepa Dinamani 		res.tv_sec = TIME64_MAX;
851bc2c53e5SDeepa Dinamani 		res.tv_nsec = 0;
852bc2c53e5SDeepa Dinamani 	}
853bc2c53e5SDeepa Dinamani 
854bc2c53e5SDeepa Dinamani 	return res;
855bc2c53e5SDeepa Dinamani }
856f59dd9c8SDeepa Dinamani 
857f59dd9c8SDeepa Dinamani int get_timespec64(struct timespec64 *ts,
858ea2ce8f3SDeepa Dinamani 		   const struct __kernel_timespec __user *uts)
859f59dd9c8SDeepa Dinamani {
860ea2ce8f3SDeepa Dinamani 	struct __kernel_timespec kts;
861f59dd9c8SDeepa Dinamani 	int ret;
862f59dd9c8SDeepa Dinamani 
863f59dd9c8SDeepa Dinamani 	ret = copy_from_user(&kts, uts, sizeof(kts));
864f59dd9c8SDeepa Dinamani 	if (ret)
865f59dd9c8SDeepa Dinamani 		return -EFAULT;
866f59dd9c8SDeepa Dinamani 
867f59dd9c8SDeepa Dinamani 	ts->tv_sec = kts.tv_sec;
868ea2ce8f3SDeepa Dinamani 
869ea2ce8f3SDeepa Dinamani 	/* Zero out the padding for 32 bit systems or in compat mode */
87098f76206SDmitry Safonov 	if (IS_ENABLED(CONFIG_64BIT_TIME) && in_compat_syscall())
871ea2ce8f3SDeepa Dinamani 		kts.tv_nsec &= 0xFFFFFFFFUL;
872ea2ce8f3SDeepa Dinamani 
873f59dd9c8SDeepa Dinamani 	ts->tv_nsec = kts.tv_nsec;
874f59dd9c8SDeepa Dinamani 
875f59dd9c8SDeepa Dinamani 	return 0;
876f59dd9c8SDeepa Dinamani }
877f59dd9c8SDeepa Dinamani EXPORT_SYMBOL_GPL(get_timespec64);
878f59dd9c8SDeepa Dinamani 
879f59dd9c8SDeepa Dinamani int put_timespec64(const struct timespec64 *ts,
880ea2ce8f3SDeepa Dinamani 		   struct __kernel_timespec __user *uts)
881f59dd9c8SDeepa Dinamani {
882ea2ce8f3SDeepa Dinamani 	struct __kernel_timespec kts = {
883f59dd9c8SDeepa Dinamani 		.tv_sec = ts->tv_sec,
884f59dd9c8SDeepa Dinamani 		.tv_nsec = ts->tv_nsec
885f59dd9c8SDeepa Dinamani 	};
886ea2ce8f3SDeepa Dinamani 
887f59dd9c8SDeepa Dinamani 	return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0;
888f59dd9c8SDeepa Dinamani }
889f59dd9c8SDeepa Dinamani EXPORT_SYMBOL_GPL(put_timespec64);
890d5b7ffbfSDeepa Dinamani 
891743f5cdbSkbuild test robot static int __get_old_timespec32(struct timespec64 *ts64,
8929afc5eeeSArnd Bergmann 				   const struct old_timespec32 __user *cts)
8931c68adf6SDeepa Dinamani {
8949afc5eeeSArnd Bergmann 	struct old_timespec32 ts;
8951c68adf6SDeepa Dinamani 	int ret;
8961c68adf6SDeepa Dinamani 
8971c68adf6SDeepa Dinamani 	ret = copy_from_user(&ts, cts, sizeof(ts));
8981c68adf6SDeepa Dinamani 	if (ret)
8991c68adf6SDeepa Dinamani 		return -EFAULT;
9001c68adf6SDeepa Dinamani 
9011c68adf6SDeepa Dinamani 	ts64->tv_sec = ts.tv_sec;
9021c68adf6SDeepa Dinamani 	ts64->tv_nsec = ts.tv_nsec;
9031c68adf6SDeepa Dinamani 
9041c68adf6SDeepa Dinamani 	return 0;
9051c68adf6SDeepa Dinamani }
9061c68adf6SDeepa Dinamani 
907743f5cdbSkbuild test robot static int __put_old_timespec32(const struct timespec64 *ts64,
9089afc5eeeSArnd Bergmann 				   struct old_timespec32 __user *cts)
9091c68adf6SDeepa Dinamani {
9109afc5eeeSArnd Bergmann 	struct old_timespec32 ts = {
9111c68adf6SDeepa Dinamani 		.tv_sec = ts64->tv_sec,
9121c68adf6SDeepa Dinamani 		.tv_nsec = ts64->tv_nsec
9131c68adf6SDeepa Dinamani 	};
9141c68adf6SDeepa Dinamani 	return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0;
9151c68adf6SDeepa Dinamani }
9161c68adf6SDeepa Dinamani 
9179afc5eeeSArnd Bergmann int get_old_timespec32(struct timespec64 *ts, const void __user *uts)
9181c68adf6SDeepa Dinamani {
9191c68adf6SDeepa Dinamani 	if (COMPAT_USE_64BIT_TIME)
9201c68adf6SDeepa Dinamani 		return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0;
9211c68adf6SDeepa Dinamani 	else
9229afc5eeeSArnd Bergmann 		return __get_old_timespec32(ts, uts);
9231c68adf6SDeepa Dinamani }
9249afc5eeeSArnd Bergmann EXPORT_SYMBOL_GPL(get_old_timespec32);
9251c68adf6SDeepa Dinamani 
9269afc5eeeSArnd Bergmann int put_old_timespec32(const struct timespec64 *ts, void __user *uts)
9271c68adf6SDeepa Dinamani {
9281c68adf6SDeepa Dinamani 	if (COMPAT_USE_64BIT_TIME)
9291c68adf6SDeepa Dinamani 		return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0;
9301c68adf6SDeepa Dinamani 	else
9319afc5eeeSArnd Bergmann 		return __put_old_timespec32(ts, uts);
9321c68adf6SDeepa Dinamani }
9339afc5eeeSArnd Bergmann EXPORT_SYMBOL_GPL(put_old_timespec32);
9341c68adf6SDeepa Dinamani 
935d5b7ffbfSDeepa Dinamani int get_itimerspec64(struct itimerspec64 *it,
936d0dd63a8SDeepa Dinamani 			const struct __kernel_itimerspec __user *uit)
937d5b7ffbfSDeepa Dinamani {
938d5b7ffbfSDeepa Dinamani 	int ret;
939d5b7ffbfSDeepa Dinamani 
940d5b7ffbfSDeepa Dinamani 	ret = get_timespec64(&it->it_interval, &uit->it_interval);
941d5b7ffbfSDeepa Dinamani 	if (ret)
942d5b7ffbfSDeepa Dinamani 		return ret;
943d5b7ffbfSDeepa Dinamani 
944d5b7ffbfSDeepa Dinamani 	ret = get_timespec64(&it->it_value, &uit->it_value);
945d5b7ffbfSDeepa Dinamani 
946d5b7ffbfSDeepa Dinamani 	return ret;
947d5b7ffbfSDeepa Dinamani }
948d5b7ffbfSDeepa Dinamani EXPORT_SYMBOL_GPL(get_itimerspec64);
949d5b7ffbfSDeepa Dinamani 
950d5b7ffbfSDeepa Dinamani int put_itimerspec64(const struct itimerspec64 *it,
951d0dd63a8SDeepa Dinamani 			struct __kernel_itimerspec __user *uit)
952d5b7ffbfSDeepa Dinamani {
953d5b7ffbfSDeepa Dinamani 	int ret;
954d5b7ffbfSDeepa Dinamani 
955d5b7ffbfSDeepa Dinamani 	ret = put_timespec64(&it->it_interval, &uit->it_interval);
956d5b7ffbfSDeepa Dinamani 	if (ret)
957d5b7ffbfSDeepa Dinamani 		return ret;
958d5b7ffbfSDeepa Dinamani 
959d5b7ffbfSDeepa Dinamani 	ret = put_timespec64(&it->it_value, &uit->it_value);
960d5b7ffbfSDeepa Dinamani 
961d5b7ffbfSDeepa Dinamani 	return ret;
962d5b7ffbfSDeepa Dinamani }
963d5b7ffbfSDeepa Dinamani EXPORT_SYMBOL_GPL(put_itimerspec64);
964afef05cfSDeepa Dinamani 
9659afc5eeeSArnd Bergmann int get_old_itimerspec32(struct itimerspec64 *its,
9669afc5eeeSArnd Bergmann 			const struct old_itimerspec32 __user *uits)
967afef05cfSDeepa Dinamani {
968afef05cfSDeepa Dinamani 
9699afc5eeeSArnd Bergmann 	if (__get_old_timespec32(&its->it_interval, &uits->it_interval) ||
9709afc5eeeSArnd Bergmann 	    __get_old_timespec32(&its->it_value, &uits->it_value))
971afef05cfSDeepa Dinamani 		return -EFAULT;
972afef05cfSDeepa Dinamani 	return 0;
973afef05cfSDeepa Dinamani }
9749afc5eeeSArnd Bergmann EXPORT_SYMBOL_GPL(get_old_itimerspec32);
975afef05cfSDeepa Dinamani 
9769afc5eeeSArnd Bergmann int put_old_itimerspec32(const struct itimerspec64 *its,
9779afc5eeeSArnd Bergmann 			struct old_itimerspec32 __user *uits)
978afef05cfSDeepa Dinamani {
9799afc5eeeSArnd Bergmann 	if (__put_old_timespec32(&its->it_interval, &uits->it_interval) ||
9809afc5eeeSArnd Bergmann 	    __put_old_timespec32(&its->it_value, &uits->it_value))
981afef05cfSDeepa Dinamani 		return -EFAULT;
982afef05cfSDeepa Dinamani 	return 0;
983afef05cfSDeepa Dinamani }
9849afc5eeeSArnd Bergmann EXPORT_SYMBOL_GPL(put_old_itimerspec32);
985