2018-11-01 02:21:09 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2005-04-17 06:20:36 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
|
*
|
2018-11-01 02:21:08 +08:00
|
|
|
* This file contains the interface functions for the various time related
|
|
|
|
* system calls: time, stime, gettimeofday, settimeofday, adjtime
|
|
|
|
*
|
|
|
|
* Modification history:
|
2007-10-18 18:06:03 +08:00
|
|
|
*
|
2005-04-17 06:20:36 +08:00
|
|
|
* 1993-09-02 Philip Gladstone
|
2013-06-04 15:40:24 +08:00
|
|
|
* Created file with time related functions from sched/core.c and adjtimex()
|
2005-04-17 06:20:36 +08:00
|
|
|
* 1993-10-08 Torsten Duwe
|
|
|
|
* adjtime interface update and CMOS clock write code
|
|
|
|
* 1995-08-13 Torsten Duwe
|
|
|
|
* kernel PLL updated to 1994-12-13 specs (rfc-1589)
|
|
|
|
* 1999-01-16 Ulrich Windl
|
|
|
|
* Introduced error checking for many cases in adjtimex().
|
|
|
|
* Updated NTP code according to technical memorandum Jan '96
|
|
|
|
* "A Kernel Model for Precision Timekeeping" by Dave Mills
|
|
|
|
* Allow time_constant larger than MAXTC(6) for NTP v4 (MAXTC == 10)
|
|
|
|
* (Even though the technical memorandum forbids it)
|
|
|
|
* 2004-07-14 Christoph Lameter
|
|
|
|
* Added getnstimeofday to allow the posix timer functions to return
|
|
|
|
* with nanosecond accuracy
|
|
|
|
*/
|
|
|
|
|
2011-05-24 02:51:41 +08:00
|
|
|
#include <linux/export.h>
|
2018-06-22 22:33:57 +08:00
|
|
|
#include <linux/kernel.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <linux/timex.h>
|
2006-01-12 04:17:46 +08:00
|
|
|
#include <linux/capability.h>
|
2012-09-05 03:27:48 +08:00
|
|
|
#include <linux/timekeeper_internal.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <linux/errno.h>
|
|
|
|
#include <linux/syscalls.h>
|
|
|
|
#include <linux/security.h>
|
|
|
|
#include <linux/fs.h>
|
2008-05-01 19:34:26 +08:00
|
|
|
#include <linux/math64.h>
|
2009-01-07 06:41:02 +08:00
|
|
|
#include <linux/ptrace.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2016-12-25 03:46:01 +08:00
|
|
|
#include <linux/uaccess.h>
|
2017-06-07 16:42:34 +08:00
|
|
|
#include <linux/compat.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <asm/unistd.h>
|
|
|
|
|
2015-05-18 20:19:12 +08:00
|
|
|
#include <generated/timeconst.h>
|
2014-07-17 05:04:02 +08:00
|
|
|
#include "timekeeping.h"
|
avoid overflows in kernel/time.c
When the conversion factor between jiffies and milli- or microseconds is
not a single multiply or divide, as for the case of HZ == 300, we currently
do a multiply followed by a divide. The intervening result, however, is
subject to overflows, especially since the fraction is not simplified (for
HZ == 300, we multiply by 300 and divide by 1000).
This is exposed to the user when passing a large timeout to poll(), for
example.
This patch replaces the multiply-divide with a reciprocal multiplication on
32-bit platforms. When the input is an unsigned long, there is no portable
way to do this on 64-bit platforms there is no portable way to do this
since it requires a 128-bit intermediate result (which gcc does support on
64-bit platforms but may generate libgcc calls, e.g. on 64-bit s390), but
since the output is a 32-bit integer in the cases affected, just simplify
the multiply-divide (*3/10 instead of *300/1000).
The reciprocal multiply used can have off-by-one errors in the upper half
of the valid output range. This could be avoided at the expense of having
to deal with a potential 65-bit intermediate result. Since the intent is
to avoid overflow problems and most of the other time conversions are only
semiexact, the off-by-one errors were considered an acceptable tradeoff.
At Ralf Baechle's suggestion, this version uses a Perl script to compute
the necessary constants. We already have dependencies on Perl for kernel
compiles. This does, however, require the Perl module Math::BigInt, which
is included in the standard Perl distribution starting with version 5.8.0.
In order to support older versions of Perl, include a table of canned
constants in the script itself, and structure the script so that
Math::BigInt isn't required if pulling values from said table.
Running the script requires that the HZ value is available from the
Makefile. Thus, this patch also adds the Kconfig variable CONFIG_HZ to the
architectures which didn't already have it (alpha, cris, frv, h8300, m32r,
m68k, m68knommu, sparc, v850, and xtensa.) It does *not* touch the sh or
sh64 architectures, since Paul Mundt has dealt with those separately in the
sh tree.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Ralf Baechle <ralf@linux-mips.org>,
Cc: Sam Ravnborg <sam@ravnborg.org>,
Cc: Paul Mundt <lethal@linux-sh.org>,
Cc: Richard Henderson <rth@twiddle.net>,
Cc: Michael Starvik <starvik@axis.com>,
Cc: David Howells <dhowells@redhat.com>,
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>,
Cc: Hirokazu Takata <takata@linux-m32r.org>,
Cc: Geert Uytterhoeven <geert@linux-m68k.org>,
Cc: Roman Zippel <zippel@linux-m68k.org>,
Cc: William L. Irwin <sparclinux@vger.kernel.org>,
Cc: Chris Zankel <chris@zankel.net>,
Cc: H. Peter Anvin <hpa@zytor.com>,
Cc: Jan Engelhardt <jengelh@computergmbh.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-08 20:21:26 +08:00
|
|
|
|
2007-10-18 18:06:03 +08:00
|
|
|
/*
|
2005-04-17 06:20:36 +08:00
|
|
|
* The timezone where the local system is located. Used as a default by some
|
|
|
|
* programs who obtain this value by using gettimeofday.
|
|
|
|
*/
|
|
|
|
struct timezone sys_tz;
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(sys_tz);
|
|
|
|
|
|
|
|
#ifdef __ARCH_WANT_SYS_TIME
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sys_time() can be implemented in user-level using
|
|
|
|
* sys_gettimeofday(). Is this for backwards compatibility? If so,
|
|
|
|
* why not move it into the appropriate arch directory (for those
|
|
|
|
* architectures that need it).
|
|
|
|
*/
|
2019-11-05 18:10:01 +08:00
|
|
|
SYSCALL_DEFINE1(time, __kernel_old_time_t __user *, tloc)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2019-11-05 18:10:01 +08:00
|
|
|
__kernel_old_time_t i = (__kernel_old_time_t)ktime_get_real_seconds();
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
if (tloc) {
|
2007-07-21 04:28:54 +08:00
|
|
|
if (put_user(i,tloc))
|
2009-01-07 06:41:02 +08:00
|
|
|
return -EFAULT;
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
2009-01-07 06:41:02 +08:00
|
|
|
force_successful_syscall_return();
|
2005-04-17 06:20:36 +08:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sys_stime() can be implemented in user-level using
|
|
|
|
* sys_settimeofday(). Is this for backwards compatibility? If so,
|
|
|
|
* why not move it into the appropriate arch directory (for those
|
|
|
|
* architectures that need it).
|
|
|
|
*/
|
2007-10-18 18:06:03 +08:00
|
|
|
|
2019-11-05 18:10:01 +08:00
|
|
|
SYSCALL_DEFINE1(stime, __kernel_old_time_t __user *, tptr)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2017-10-14 02:34:35 +08:00
|
|
|
struct timespec64 tv;
|
2005-04-17 06:20:36 +08:00
|
|
|
int err;
|
|
|
|
|
|
|
|
if (get_user(tv.tv_sec, tptr))
|
|
|
|
return -EFAULT;
|
|
|
|
|
|
|
|
tv.tv_nsec = 0;
|
|
|
|
|
2017-10-14 02:34:35 +08:00
|
|
|
err = security_settime64(&tv, NULL);
|
2005-04-17 06:20:36 +08:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
2017-10-14 02:34:35 +08:00
|
|
|
do_settimeofday64(&tv);
|
2005-04-17 06:20:36 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* __ARCH_WANT_SYS_TIME */
|
|
|
|
|
2019-01-07 07:33:08 +08:00
|
|
|
#ifdef CONFIG_COMPAT_32BIT_TIME
|
y2038: rename old time and utime syscalls
The time, stime, utime, utimes, and futimesat system calls are only
used on older architectures, and we do not provide y2038 safe variants
of them, as they are replaced by clock_gettime64, clock_settime64,
and utimensat_time64.
However, for consistency it seems better to have the 32-bit architectures
that still use them call the "time32" entry points (leaving the
traditional handlers for the 64-bit architectures), like we do for system
calls that now require two versions.
Note: We used to always define __ARCH_WANT_SYS_TIME and
__ARCH_WANT_SYS_UTIME and only set __ARCH_WANT_COMPAT_SYS_TIME and
__ARCH_WANT_SYS_UTIME32 for compat mode on 64-bit kernels. Now this is
reversed: only 64-bit architectures set __ARCH_WANT_SYS_TIME/UTIME, while
we need __ARCH_WANT_SYS_TIME32/UTIME32 for 32-bit architectures and compat
mode. The resulting asm/unistd.h changes look a bit counterintuitive.
This is only a cleanup patch and it should not change any behavior.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
2019-01-07 06:45:29 +08:00
|
|
|
#ifdef __ARCH_WANT_SYS_TIME32
|
2017-06-07 16:42:40 +08:00
|
|
|
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
/* old_time32_t is a 32 bit "long" and needs to get converted. */
|
2019-01-07 07:33:08 +08:00
|
|
|
SYSCALL_DEFINE1(time32, old_time32_t __user *, tloc)
|
2017-06-07 16:42:40 +08:00
|
|
|
{
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
old_time32_t i;
|
2017-06-07 16:42:40 +08:00
|
|
|
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
i = (old_time32_t)ktime_get_real_seconds();
|
2017-06-07 16:42:40 +08:00
|
|
|
|
|
|
|
if (tloc) {
|
|
|
|
if (put_user(i,tloc))
|
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
force_successful_syscall_return();
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2019-01-07 07:33:08 +08:00
|
|
|
SYSCALL_DEFINE1(stime32, old_time32_t __user *, tptr)
|
2017-06-07 16:42:40 +08:00
|
|
|
{
|
2017-10-14 02:34:35 +08:00
|
|
|
struct timespec64 tv;
|
2017-06-07 16:42:40 +08:00
|
|
|
int err;
|
|
|
|
|
|
|
|
if (get_user(tv.tv_sec, tptr))
|
|
|
|
return -EFAULT;
|
|
|
|
|
|
|
|
tv.tv_nsec = 0;
|
|
|
|
|
2017-10-14 02:34:35 +08:00
|
|
|
err = security_settime64(&tv, NULL);
|
2017-06-07 16:42:40 +08:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
2017-10-14 02:34:35 +08:00
|
|
|
do_settimeofday64(&tv);
|
2017-06-07 16:42:40 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
y2038: rename old time and utime syscalls
The time, stime, utime, utimes, and futimesat system calls are only
used on older architectures, and we do not provide y2038 safe variants
of them, as they are replaced by clock_gettime64, clock_settime64,
and utimensat_time64.
However, for consistency it seems better to have the 32-bit architectures
that still use them call the "time32" entry points (leaving the
traditional handlers for the 64-bit architectures), like we do for system
calls that now require two versions.
Note: We used to always define __ARCH_WANT_SYS_TIME and
__ARCH_WANT_SYS_UTIME and only set __ARCH_WANT_COMPAT_SYS_TIME and
__ARCH_WANT_SYS_UTIME32 for compat mode on 64-bit kernels. Now this is
reversed: only 64-bit architectures set __ARCH_WANT_SYS_TIME/UTIME, while
we need __ARCH_WANT_SYS_TIME32/UTIME32 for 32-bit architectures and compat
mode. The resulting asm/unistd.h changes look a bit counterintuitive.
This is only a cleanup patch and it should not change any behavior.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
2019-01-07 06:45:29 +08:00
|
|
|
#endif /* __ARCH_WANT_SYS_TIME32 */
|
2017-06-07 16:42:40 +08:00
|
|
|
#endif
|
|
|
|
|
2019-10-26 04:56:17 +08:00
|
|
|
SYSCALL_DEFINE2(gettimeofday, struct __kernel_old_timeval __user *, tv,
|
2009-01-14 21:14:03 +08:00
|
|
|
struct timezone __user *, tz)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
|
|
|
if (likely(tv != NULL)) {
|
2018-08-14 21:18:20 +08:00
|
|
|
struct timespec64 ts;
|
|
|
|
|
|
|
|
ktime_get_real_ts64(&ts);
|
|
|
|
if (put_user(ts.tv_sec, &tv->tv_sec) ||
|
|
|
|
put_user(ts.tv_nsec / 1000, &tv->tv_usec))
|
2005-04-17 06:20:36 +08:00
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
if (unlikely(tz != NULL)) {
|
|
|
|
if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
|
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In case for some reason the CMOS clock has not already been running
|
|
|
|
* in UTC, but in some local time: The first time we set the timezone,
|
|
|
|
* we will warp the clock so that it is ticking UTC time instead of
|
|
|
|
* local time. Presumably, if someone is setting the timezone then we
|
|
|
|
* are running in an environment where the programs understand about
|
|
|
|
* timezones. This should be done at boot time in the /etc/rc script,
|
|
|
|
* as soon as possible, so that the clock can be set right. Otherwise,
|
|
|
|
* various programs will get confused when the clock gets warped.
|
|
|
|
*/
|
|
|
|
|
2016-04-08 14:02:12 +08:00
|
|
|
int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
|
|
|
static int firsttime = 1;
|
|
|
|
int error = 0;
|
|
|
|
|
2019-03-23 18:36:19 +08:00
|
|
|
if (tv && !timespec64_valid_settod(tv))
|
2006-01-10 12:52:29 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
2016-04-08 14:02:12 +08:00
|
|
|
error = security_settime64(tv, tz);
|
2005-04-17 06:20:36 +08:00
|
|
|
if (error)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
if (tz) {
|
2019-10-15 15:33:39 +08:00
|
|
|
/* Verify we're within the +-15 hrs range */
|
2014-12-02 12:04:06 +08:00
|
|
|
if (tz->tz_minuteswest > 15*60 || tz->tz_minuteswest < -15*60)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
sys_tz = *tz;
|
2007-10-18 18:04:57 +08:00
|
|
|
update_vsyscall_tz();
|
2005-04-17 06:20:36 +08:00
|
|
|
if (firsttime) {
|
|
|
|
firsttime = 0;
|
|
|
|
if (!tv)
|
2017-10-19 19:14:44 +08:00
|
|
|
timekeeping_warp_clock();
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tv)
|
2016-04-08 14:02:12 +08:00
|
|
|
return do_settimeofday64(tv);
|
2005-04-17 06:20:36 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-08-16 02:04:11 +08:00
|
|
|
SYSCALL_DEFINE2(settimeofday, struct __kernel_old_timeval __user *, tv,
|
2009-01-14 21:14:03 +08:00
|
|
|
struct timezone __user *, tz)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2017-03-27 03:04:12 +08:00
|
|
|
struct timespec64 new_ts;
|
2005-04-17 06:20:36 +08:00
|
|
|
struct timezone new_tz;
|
|
|
|
|
|
|
|
if (tv) {
|
2018-08-16 02:04:11 +08:00
|
|
|
if (get_user(new_ts.tv_sec, &tv->tv_sec) ||
|
|
|
|
get_user(new_ts.tv_nsec, &tv->tv_usec))
|
2005-04-17 06:20:36 +08:00
|
|
|
return -EFAULT;
|
2014-12-04 08:22:48 +08:00
|
|
|
|
2018-08-16 02:04:11 +08:00
|
|
|
if (new_ts.tv_nsec > USEC_PER_SEC || new_ts.tv_nsec < 0)
|
2014-12-04 08:22:48 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
2018-08-16 02:04:11 +08:00
|
|
|
new_ts.tv_nsec *= NSEC_PER_USEC;
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
if (tz) {
|
|
|
|
if (copy_from_user(&new_tz, tz, sizeof(*tz)))
|
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
|
2017-03-27 03:04:12 +08:00
|
|
|
return do_sys_settimeofday64(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
2017-06-07 16:42:41 +08:00
|
|
|
#ifdef CONFIG_COMPAT
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
COMPAT_SYSCALL_DEFINE2(gettimeofday, struct old_timeval32 __user *, tv,
|
2017-06-07 16:42:41 +08:00
|
|
|
struct timezone __user *, tz)
|
|
|
|
{
|
|
|
|
if (tv) {
|
2018-08-14 21:18:20 +08:00
|
|
|
struct timespec64 ts;
|
2017-06-07 16:42:41 +08:00
|
|
|
|
2018-08-14 21:18:20 +08:00
|
|
|
ktime_get_real_ts64(&ts);
|
|
|
|
if (put_user(ts.tv_sec, &tv->tv_sec) ||
|
|
|
|
put_user(ts.tv_nsec / 1000, &tv->tv_usec))
|
2017-06-07 16:42:41 +08:00
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
if (tz) {
|
|
|
|
if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
|
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
COMPAT_SYSCALL_DEFINE2(settimeofday, struct old_timeval32 __user *, tv,
|
2017-06-07 16:42:41 +08:00
|
|
|
struct timezone __user *, tz)
|
|
|
|
{
|
|
|
|
struct timespec64 new_ts;
|
|
|
|
struct timezone new_tz;
|
|
|
|
|
|
|
|
if (tv) {
|
2018-08-16 02:04:11 +08:00
|
|
|
if (get_user(new_ts.tv_sec, &tv->tv_sec) ||
|
|
|
|
get_user(new_ts.tv_nsec, &tv->tv_usec))
|
2017-06-07 16:42:41 +08:00
|
|
|
return -EFAULT;
|
2019-07-07 08:51:41 +08:00
|
|
|
|
2018-08-16 02:04:11 +08:00
|
|
|
if (new_ts.tv_nsec > USEC_PER_SEC || new_ts.tv_nsec < 0)
|
2019-07-07 08:51:41 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
2018-08-16 02:04:11 +08:00
|
|
|
new_ts.tv_nsec *= NSEC_PER_USEC;
|
2017-06-07 16:42:41 +08:00
|
|
|
}
|
|
|
|
if (tz) {
|
|
|
|
if (copy_from_user(&new_tz, tz, sizeof(*tz)))
|
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return do_sys_settimeofday64(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-04-23 23:43:50 +08:00
|
|
|
#ifdef CONFIG_64BIT
|
2018-07-03 13:44:22 +08:00
|
|
|
SYSCALL_DEFINE1(adjtimex, struct __kernel_timex __user *, txc_p)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2018-07-03 13:44:21 +08:00
|
|
|
struct __kernel_timex txc; /* Local copy of parameter */
|
2005-04-17 06:20:36 +08:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* Copy the user data space into the kernel copy
|
|
|
|
* structure. But bear in mind that the structures
|
|
|
|
* may change
|
|
|
|
*/
|
2018-07-03 13:44:21 +08:00
|
|
|
if (copy_from_user(&txc, txc_p, sizeof(struct __kernel_timex)))
|
2005-04-17 06:20:36 +08:00
|
|
|
return -EFAULT;
|
|
|
|
ret = do_adjtimex(&txc);
|
2018-07-03 13:44:21 +08:00
|
|
|
return copy_to_user(txc_p, &txc, sizeof(struct __kernel_timex)) ? -EFAULT : ret;
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
2018-07-03 13:44:22 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2019-01-02 20:28:47 +08:00
|
|
|
#ifdef CONFIG_COMPAT_32BIT_TIME
|
2018-07-03 13:44:21 +08:00
|
|
|
int get_old_timex32(struct __kernel_timex *txc, const struct old_timex32 __user *utp)
|
2019-01-02 20:28:47 +08:00
|
|
|
{
|
|
|
|
struct old_timex32 tx32;
|
|
|
|
|
2018-07-03 13:44:21 +08:00
|
|
|
memset(txc, 0, sizeof(struct __kernel_timex));
|
2019-01-02 20:28:47 +08:00
|
|
|
if (copy_from_user(&tx32, utp, sizeof(struct old_timex32)))
|
|
|
|
return -EFAULT;
|
|
|
|
|
|
|
|
txc->modes = tx32.modes;
|
|
|
|
txc->offset = tx32.offset;
|
|
|
|
txc->freq = tx32.freq;
|
|
|
|
txc->maxerror = tx32.maxerror;
|
|
|
|
txc->esterror = tx32.esterror;
|
|
|
|
txc->status = tx32.status;
|
|
|
|
txc->constant = tx32.constant;
|
|
|
|
txc->precision = tx32.precision;
|
|
|
|
txc->tolerance = tx32.tolerance;
|
|
|
|
txc->time.tv_sec = tx32.time.tv_sec;
|
|
|
|
txc->time.tv_usec = tx32.time.tv_usec;
|
|
|
|
txc->tick = tx32.tick;
|
|
|
|
txc->ppsfreq = tx32.ppsfreq;
|
|
|
|
txc->jitter = tx32.jitter;
|
|
|
|
txc->shift = tx32.shift;
|
|
|
|
txc->stabil = tx32.stabil;
|
|
|
|
txc->jitcnt = tx32.jitcnt;
|
|
|
|
txc->calcnt = tx32.calcnt;
|
|
|
|
txc->errcnt = tx32.errcnt;
|
|
|
|
txc->stbcnt = tx32.stbcnt;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-07-03 13:44:21 +08:00
|
|
|
int put_old_timex32(struct old_timex32 __user *utp, const struct __kernel_timex *txc)
|
2019-01-02 20:28:47 +08:00
|
|
|
{
|
|
|
|
struct old_timex32 tx32;
|
|
|
|
|
|
|
|
memset(&tx32, 0, sizeof(struct old_timex32));
|
|
|
|
tx32.modes = txc->modes;
|
|
|
|
tx32.offset = txc->offset;
|
|
|
|
tx32.freq = txc->freq;
|
|
|
|
tx32.maxerror = txc->maxerror;
|
|
|
|
tx32.esterror = txc->esterror;
|
|
|
|
tx32.status = txc->status;
|
|
|
|
tx32.constant = txc->constant;
|
|
|
|
tx32.precision = txc->precision;
|
|
|
|
tx32.tolerance = txc->tolerance;
|
|
|
|
tx32.time.tv_sec = txc->time.tv_sec;
|
|
|
|
tx32.time.tv_usec = txc->time.tv_usec;
|
|
|
|
tx32.tick = txc->tick;
|
|
|
|
tx32.ppsfreq = txc->ppsfreq;
|
|
|
|
tx32.jitter = txc->jitter;
|
|
|
|
tx32.shift = txc->shift;
|
|
|
|
tx32.stabil = txc->stabil;
|
|
|
|
tx32.jitcnt = txc->jitcnt;
|
|
|
|
tx32.calcnt = txc->calcnt;
|
|
|
|
tx32.errcnt = txc->errcnt;
|
|
|
|
tx32.stbcnt = txc->stbcnt;
|
|
|
|
tx32.tai = txc->tai;
|
|
|
|
if (copy_to_user(utp, &tx32, sizeof(struct old_timex32)))
|
|
|
|
return -EFAULT;
|
|
|
|
return 0;
|
|
|
|
}
|
2017-06-07 16:42:34 +08:00
|
|
|
|
2019-01-07 07:33:08 +08:00
|
|
|
SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp)
|
2017-06-07 16:42:34 +08:00
|
|
|
{
|
2018-07-03 13:44:21 +08:00
|
|
|
struct __kernel_timex txc;
|
2017-06-07 16:42:34 +08:00
|
|
|
int err, ret;
|
|
|
|
|
2019-01-02 20:28:47 +08:00
|
|
|
err = get_old_timex32(&txc, utp);
|
2017-06-07 16:42:34 +08:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
ret = do_adjtimex(&txc);
|
|
|
|
|
2019-01-02 20:28:47 +08:00
|
|
|
err = put_old_timex32(utp, &txc);
|
2017-06-07 16:42:34 +08:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* jiffies_to_msecs - Convert jiffies to milliseconds
|
|
|
|
* @j: jiffies value
|
Optimize timespec_trunc()
The first thing done by timespec_trunc() is :
if (gran <= jiffies_to_usecs(1) * 1000)
This should really be a test against a constant known at compile time.
Alas, it isnt. jiffies_to_usec() was unilined so C compiler emits a function
call and a multiply to compute : a CONSTANT.
mov $0x1,%edi
mov %rbx,0xffffffffffffffe8(%rbp)
mov %r12,0xfffffffffffffff0(%rbp)
mov %edx,%ebx
mov %rsi,0xffffffffffffffc8(%rbp)
mov %rsi,%r12
callq ffffffff80232010 <jiffies_to_usecs>
imul $0x3e8,%eax,%eax
cmp %ebx,%eax
This patch reorders kernel/time.c a bit so that jiffies_to_usecs() is defined
before timespec_trunc() so that compiler now generates :
cmp $0x3d0900,%edx (HZ=250 on my machine)
This gives a better code (timespec_trunc() becoming a leaf function), and
shorter kernel size as well.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-08 15:25:32 +08:00
|
|
|
*
|
|
|
|
* Avoid unnecessary multiplications/divisions in the
|
2023-07-04 13:24:05 +08:00
|
|
|
* two most common HZ cases.
|
|
|
|
*
|
|
|
|
* Return: milliseconds value
|
Optimize timespec_trunc()
The first thing done by timespec_trunc() is :
if (gran <= jiffies_to_usecs(1) * 1000)
This should really be a test against a constant known at compile time.
Alas, it isnt. jiffies_to_usec() was unilined so C compiler emits a function
call and a multiply to compute : a CONSTANT.
mov $0x1,%edi
mov %rbx,0xffffffffffffffe8(%rbp)
mov %r12,0xfffffffffffffff0(%rbp)
mov %edx,%ebx
mov %rsi,0xffffffffffffffc8(%rbp)
mov %rsi,%r12
callq ffffffff80232010 <jiffies_to_usecs>
imul $0x3e8,%eax,%eax
cmp %ebx,%eax
This patch reorders kernel/time.c a bit so that jiffies_to_usecs() is defined
before timespec_trunc() so that compiler now generates :
cmp $0x3d0900,%edx (HZ=250 on my machine)
This gives a better code (timespec_trunc() becoming a leaf function), and
shorter kernel size as well.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-08 15:25:32 +08:00
|
|
|
*/
|
2013-02-22 08:42:40 +08:00
|
|
|
unsigned int jiffies_to_msecs(const unsigned long j)
|
Optimize timespec_trunc()
The first thing done by timespec_trunc() is :
if (gran <= jiffies_to_usecs(1) * 1000)
This should really be a test against a constant known at compile time.
Alas, it isnt. jiffies_to_usec() was unilined so C compiler emits a function
call and a multiply to compute : a CONSTANT.
mov $0x1,%edi
mov %rbx,0xffffffffffffffe8(%rbp)
mov %r12,0xfffffffffffffff0(%rbp)
mov %edx,%ebx
mov %rsi,0xffffffffffffffc8(%rbp)
mov %rsi,%r12
callq ffffffff80232010 <jiffies_to_usecs>
imul $0x3e8,%eax,%eax
cmp %ebx,%eax
This patch reorders kernel/time.c a bit so that jiffies_to_usecs() is defined
before timespec_trunc() so that compiler now generates :
cmp $0x3d0900,%edx (HZ=250 on my machine)
This gives a better code (timespec_trunc() becoming a leaf function), and
shorter kernel size as well.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-08 15:25:32 +08:00
|
|
|
{
|
|
|
|
#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
|
|
|
|
return (MSEC_PER_SEC / HZ) * j;
|
|
|
|
#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
|
|
|
|
return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
|
|
|
|
#else
|
avoid overflows in kernel/time.c
When the conversion factor between jiffies and milli- or microseconds is
not a single multiply or divide, as for the case of HZ == 300, we currently
do a multiply followed by a divide. The intervening result, however, is
subject to overflows, especially since the fraction is not simplified (for
HZ == 300, we multiply by 300 and divide by 1000).
This is exposed to the user when passing a large timeout to poll(), for
example.
This patch replaces the multiply-divide with a reciprocal multiplication on
32-bit platforms. When the input is an unsigned long, there is no portable
way to do this on 64-bit platforms there is no portable way to do this
since it requires a 128-bit intermediate result (which gcc does support on
64-bit platforms but may generate libgcc calls, e.g. on 64-bit s390), but
since the output is a 32-bit integer in the cases affected, just simplify
the multiply-divide (*3/10 instead of *300/1000).
The reciprocal multiply used can have off-by-one errors in the upper half
of the valid output range. This could be avoided at the expense of having
to deal with a potential 65-bit intermediate result. Since the intent is
to avoid overflow problems and most of the other time conversions are only
semiexact, the off-by-one errors were considered an acceptable tradeoff.
At Ralf Baechle's suggestion, this version uses a Perl script to compute
the necessary constants. We already have dependencies on Perl for kernel
compiles. This does, however, require the Perl module Math::BigInt, which
is included in the standard Perl distribution starting with version 5.8.0.
In order to support older versions of Perl, include a table of canned
constants in the script itself, and structure the script so that
Math::BigInt isn't required if pulling values from said table.
Running the script requires that the HZ value is available from the
Makefile. Thus, this patch also adds the Kconfig variable CONFIG_HZ to the
architectures which didn't already have it (alpha, cris, frv, h8300, m32r,
m68k, m68knommu, sparc, v850, and xtensa.) It does *not* touch the sh or
sh64 architectures, since Paul Mundt has dealt with those separately in the
sh tree.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Ralf Baechle <ralf@linux-mips.org>,
Cc: Sam Ravnborg <sam@ravnborg.org>,
Cc: Paul Mundt <lethal@linux-sh.org>,
Cc: Richard Henderson <rth@twiddle.net>,
Cc: Michael Starvik <starvik@axis.com>,
Cc: David Howells <dhowells@redhat.com>,
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>,
Cc: Hirokazu Takata <takata@linux-m32r.org>,
Cc: Geert Uytterhoeven <geert@linux-m68k.org>,
Cc: Roman Zippel <zippel@linux-m68k.org>,
Cc: William L. Irwin <sparclinux@vger.kernel.org>,
Cc: Chris Zankel <chris@zankel.net>,
Cc: H. Peter Anvin <hpa@zytor.com>,
Cc: Jan Engelhardt <jengelh@computergmbh.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-08 20:21:26 +08:00
|
|
|
# if BITS_PER_LONG == 32
|
2018-06-22 22:33:57 +08:00
|
|
|
return (HZ_TO_MSEC_MUL32 * j + (1ULL << HZ_TO_MSEC_SHR32) - 1) >>
|
|
|
|
HZ_TO_MSEC_SHR32;
|
avoid overflows in kernel/time.c
When the conversion factor between jiffies and milli- or microseconds is
not a single multiply or divide, as for the case of HZ == 300, we currently
do a multiply followed by a divide. The intervening result, however, is
subject to overflows, especially since the fraction is not simplified (for
HZ == 300, we multiply by 300 and divide by 1000).
This is exposed to the user when passing a large timeout to poll(), for
example.
This patch replaces the multiply-divide with a reciprocal multiplication on
32-bit platforms. When the input is an unsigned long, there is no portable
way to do this on 64-bit platforms there is no portable way to do this
since it requires a 128-bit intermediate result (which gcc does support on
64-bit platforms but may generate libgcc calls, e.g. on 64-bit s390), but
since the output is a 32-bit integer in the cases affected, just simplify
the multiply-divide (*3/10 instead of *300/1000).
The reciprocal multiply used can have off-by-one errors in the upper half
of the valid output range. This could be avoided at the expense of having
to deal with a potential 65-bit intermediate result. Since the intent is
to avoid overflow problems and most of the other time conversions are only
semiexact, the off-by-one errors were considered an acceptable tradeoff.
At Ralf Baechle's suggestion, this version uses a Perl script to compute
the necessary constants. We already have dependencies on Perl for kernel
compiles. This does, however, require the Perl module Math::BigInt, which
is included in the standard Perl distribution starting with version 5.8.0.
In order to support older versions of Perl, include a table of canned
constants in the script itself, and structure the script so that
Math::BigInt isn't required if pulling values from said table.
Running the script requires that the HZ value is available from the
Makefile. Thus, this patch also adds the Kconfig variable CONFIG_HZ to the
architectures which didn't already have it (alpha, cris, frv, h8300, m32r,
m68k, m68knommu, sparc, v850, and xtensa.) It does *not* touch the sh or
sh64 architectures, since Paul Mundt has dealt with those separately in the
sh tree.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Ralf Baechle <ralf@linux-mips.org>,
Cc: Sam Ravnborg <sam@ravnborg.org>,
Cc: Paul Mundt <lethal@linux-sh.org>,
Cc: Richard Henderson <rth@twiddle.net>,
Cc: Michael Starvik <starvik@axis.com>,
Cc: David Howells <dhowells@redhat.com>,
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>,
Cc: Hirokazu Takata <takata@linux-m32r.org>,
Cc: Geert Uytterhoeven <geert@linux-m68k.org>,
Cc: Roman Zippel <zippel@linux-m68k.org>,
Cc: William L. Irwin <sparclinux@vger.kernel.org>,
Cc: Chris Zankel <chris@zankel.net>,
Cc: H. Peter Anvin <hpa@zytor.com>,
Cc: Jan Engelhardt <jengelh@computergmbh.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-08 20:21:26 +08:00
|
|
|
# else
|
2018-06-22 22:33:57 +08:00
|
|
|
return DIV_ROUND_UP(j * HZ_TO_MSEC_NUM, HZ_TO_MSEC_DEN);
|
avoid overflows in kernel/time.c
When the conversion factor between jiffies and milli- or microseconds is
not a single multiply or divide, as for the case of HZ == 300, we currently
do a multiply followed by a divide. The intervening result, however, is
subject to overflows, especially since the fraction is not simplified (for
HZ == 300, we multiply by 300 and divide by 1000).
This is exposed to the user when passing a large timeout to poll(), for
example.
This patch replaces the multiply-divide with a reciprocal multiplication on
32-bit platforms. When the input is an unsigned long, there is no portable
way to do this on 64-bit platforms there is no portable way to do this
since it requires a 128-bit intermediate result (which gcc does support on
64-bit platforms but may generate libgcc calls, e.g. on 64-bit s390), but
since the output is a 32-bit integer in the cases affected, just simplify
the multiply-divide (*3/10 instead of *300/1000).
The reciprocal multiply used can have off-by-one errors in the upper half
of the valid output range. This could be avoided at the expense of having
to deal with a potential 65-bit intermediate result. Since the intent is
to avoid overflow problems and most of the other time conversions are only
semiexact, the off-by-one errors were considered an acceptable tradeoff.
At Ralf Baechle's suggestion, this version uses a Perl script to compute
the necessary constants. We already have dependencies on Perl for kernel
compiles. This does, however, require the Perl module Math::BigInt, which
is included in the standard Perl distribution starting with version 5.8.0.
In order to support older versions of Perl, include a table of canned
constants in the script itself, and structure the script so that
Math::BigInt isn't required if pulling values from said table.
Running the script requires that the HZ value is available from the
Makefile. Thus, this patch also adds the Kconfig variable CONFIG_HZ to the
architectures which didn't already have it (alpha, cris, frv, h8300, m32r,
m68k, m68knommu, sparc, v850, and xtensa.) It does *not* touch the sh or
sh64 architectures, since Paul Mundt has dealt with those separately in the
sh tree.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Ralf Baechle <ralf@linux-mips.org>,
Cc: Sam Ravnborg <sam@ravnborg.org>,
Cc: Paul Mundt <lethal@linux-sh.org>,
Cc: Richard Henderson <rth@twiddle.net>,
Cc: Michael Starvik <starvik@axis.com>,
Cc: David Howells <dhowells@redhat.com>,
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>,
Cc: Hirokazu Takata <takata@linux-m32r.org>,
Cc: Geert Uytterhoeven <geert@linux-m68k.org>,
Cc: Roman Zippel <zippel@linux-m68k.org>,
Cc: William L. Irwin <sparclinux@vger.kernel.org>,
Cc: Chris Zankel <chris@zankel.net>,
Cc: H. Peter Anvin <hpa@zytor.com>,
Cc: Jan Engelhardt <jengelh@computergmbh.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-08 20:21:26 +08:00
|
|
|
# endif
|
Optimize timespec_trunc()
The first thing done by timespec_trunc() is :
if (gran <= jiffies_to_usecs(1) * 1000)
This should really be a test against a constant known at compile time.
Alas, it isnt. jiffies_to_usec() was unilined so C compiler emits a function
call and a multiply to compute : a CONSTANT.
mov $0x1,%edi
mov %rbx,0xffffffffffffffe8(%rbp)
mov %r12,0xfffffffffffffff0(%rbp)
mov %edx,%ebx
mov %rsi,0xffffffffffffffc8(%rbp)
mov %rsi,%r12
callq ffffffff80232010 <jiffies_to_usecs>
imul $0x3e8,%eax,%eax
cmp %ebx,%eax
This patch reorders kernel/time.c a bit so that jiffies_to_usecs() is defined
before timespec_trunc() so that compiler now generates :
cmp $0x3d0900,%edx (HZ=250 on my machine)
This gives a better code (timespec_trunc() becoming a leaf function), and
shorter kernel size as well.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-08 15:25:32 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(jiffies_to_msecs);
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* jiffies_to_usecs - Convert jiffies to microseconds
|
|
|
|
* @j: jiffies value
|
|
|
|
*
|
|
|
|
* Return: microseconds value
|
|
|
|
*/
|
2013-02-22 08:42:40 +08:00
|
|
|
unsigned int jiffies_to_usecs(const unsigned long j)
|
Optimize timespec_trunc()
The first thing done by timespec_trunc() is :
if (gran <= jiffies_to_usecs(1) * 1000)
This should really be a test against a constant known at compile time.
Alas, it isnt. jiffies_to_usec() was unilined so C compiler emits a function
call and a multiply to compute : a CONSTANT.
mov $0x1,%edi
mov %rbx,0xffffffffffffffe8(%rbp)
mov %r12,0xfffffffffffffff0(%rbp)
mov %edx,%ebx
mov %rsi,0xffffffffffffffc8(%rbp)
mov %rsi,%r12
callq ffffffff80232010 <jiffies_to_usecs>
imul $0x3e8,%eax,%eax
cmp %ebx,%eax
This patch reorders kernel/time.c a bit so that jiffies_to_usecs() is defined
before timespec_trunc() so that compiler now generates :
cmp $0x3d0900,%edx (HZ=250 on my machine)
This gives a better code (timespec_trunc() becoming a leaf function), and
shorter kernel size as well.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-08 15:25:32 +08:00
|
|
|
{
|
2014-10-10 08:44:01 +08:00
|
|
|
/*
|
|
|
|
* Hz usually doesn't go much further MSEC_PER_SEC.
|
|
|
|
* jiffies_to_usecs() and usecs_to_jiffies() depend on that.
|
|
|
|
*/
|
|
|
|
BUILD_BUG_ON(HZ > USEC_PER_SEC);
|
|
|
|
|
|
|
|
#if !(USEC_PER_SEC % HZ)
|
Optimize timespec_trunc()
The first thing done by timespec_trunc() is :
if (gran <= jiffies_to_usecs(1) * 1000)
This should really be a test against a constant known at compile time.
Alas, it isnt. jiffies_to_usec() was unilined so C compiler emits a function
call and a multiply to compute : a CONSTANT.
mov $0x1,%edi
mov %rbx,0xffffffffffffffe8(%rbp)
mov %r12,0xfffffffffffffff0(%rbp)
mov %edx,%ebx
mov %rsi,0xffffffffffffffc8(%rbp)
mov %rsi,%r12
callq ffffffff80232010 <jiffies_to_usecs>
imul $0x3e8,%eax,%eax
cmp %ebx,%eax
This patch reorders kernel/time.c a bit so that jiffies_to_usecs() is defined
before timespec_trunc() so that compiler now generates :
cmp $0x3d0900,%edx (HZ=250 on my machine)
This gives a better code (timespec_trunc() becoming a leaf function), and
shorter kernel size as well.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-08 15:25:32 +08:00
|
|
|
return (USEC_PER_SEC / HZ) * j;
|
|
|
|
#else
|
avoid overflows in kernel/time.c
When the conversion factor between jiffies and milli- or microseconds is
not a single multiply or divide, as for the case of HZ == 300, we currently
do a multiply followed by a divide. The intervening result, however, is
subject to overflows, especially since the fraction is not simplified (for
HZ == 300, we multiply by 300 and divide by 1000).
This is exposed to the user when passing a large timeout to poll(), for
example.
This patch replaces the multiply-divide with a reciprocal multiplication on
32-bit platforms. When the input is an unsigned long, there is no portable
way to do this on 64-bit platforms there is no portable way to do this
since it requires a 128-bit intermediate result (which gcc does support on
64-bit platforms but may generate libgcc calls, e.g. on 64-bit s390), but
since the output is a 32-bit integer in the cases affected, just simplify
the multiply-divide (*3/10 instead of *300/1000).
The reciprocal multiply used can have off-by-one errors in the upper half
of the valid output range. This could be avoided at the expense of having
to deal with a potential 65-bit intermediate result. Since the intent is
to avoid overflow problems and most of the other time conversions are only
semiexact, the off-by-one errors were considered an acceptable tradeoff.
At Ralf Baechle's suggestion, this version uses a Perl script to compute
the necessary constants. We already have dependencies on Perl for kernel
compiles. This does, however, require the Perl module Math::BigInt, which
is included in the standard Perl distribution starting with version 5.8.0.
In order to support older versions of Perl, include a table of canned
constants in the script itself, and structure the script so that
Math::BigInt isn't required if pulling values from said table.
Running the script requires that the HZ value is available from the
Makefile. Thus, this patch also adds the Kconfig variable CONFIG_HZ to the
architectures which didn't already have it (alpha, cris, frv, h8300, m32r,
m68k, m68knommu, sparc, v850, and xtensa.) It does *not* touch the sh or
sh64 architectures, since Paul Mundt has dealt with those separately in the
sh tree.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Ralf Baechle <ralf@linux-mips.org>,
Cc: Sam Ravnborg <sam@ravnborg.org>,
Cc: Paul Mundt <lethal@linux-sh.org>,
Cc: Richard Henderson <rth@twiddle.net>,
Cc: Michael Starvik <starvik@axis.com>,
Cc: David Howells <dhowells@redhat.com>,
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>,
Cc: Hirokazu Takata <takata@linux-m32r.org>,
Cc: Geert Uytterhoeven <geert@linux-m68k.org>,
Cc: Roman Zippel <zippel@linux-m68k.org>,
Cc: William L. Irwin <sparclinux@vger.kernel.org>,
Cc: Chris Zankel <chris@zankel.net>,
Cc: H. Peter Anvin <hpa@zytor.com>,
Cc: Jan Engelhardt <jengelh@computergmbh.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-08 20:21:26 +08:00
|
|
|
# if BITS_PER_LONG == 32
|
2008-05-03 07:18:42 +08:00
|
|
|
return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
|
avoid overflows in kernel/time.c
When the conversion factor between jiffies and milli- or microseconds is
not a single multiply or divide, as for the case of HZ == 300, we currently
do a multiply followed by a divide. The intervening result, however, is
subject to overflows, especially since the fraction is not simplified (for
HZ == 300, we multiply by 300 and divide by 1000).
This is exposed to the user when passing a large timeout to poll(), for
example.
This patch replaces the multiply-divide with a reciprocal multiplication on
32-bit platforms. When the input is an unsigned long, there is no portable
way to do this on 64-bit platforms there is no portable way to do this
since it requires a 128-bit intermediate result (which gcc does support on
64-bit platforms but may generate libgcc calls, e.g. on 64-bit s390), but
since the output is a 32-bit integer in the cases affected, just simplify
the multiply-divide (*3/10 instead of *300/1000).
The reciprocal multiply used can have off-by-one errors in the upper half
of the valid output range. This could be avoided at the expense of having
to deal with a potential 65-bit intermediate result. Since the intent is
to avoid overflow problems and most of the other time conversions are only
semiexact, the off-by-one errors were considered an acceptable tradeoff.
At Ralf Baechle's suggestion, this version uses a Perl script to compute
the necessary constants. We already have dependencies on Perl for kernel
compiles. This does, however, require the Perl module Math::BigInt, which
is included in the standard Perl distribution starting with version 5.8.0.
In order to support older versions of Perl, include a table of canned
constants in the script itself, and structure the script so that
Math::BigInt isn't required if pulling values from said table.
Running the script requires that the HZ value is available from the
Makefile. Thus, this patch also adds the Kconfig variable CONFIG_HZ to the
architectures which didn't already have it (alpha, cris, frv, h8300, m32r,
m68k, m68knommu, sparc, v850, and xtensa.) It does *not* touch the sh or
sh64 architectures, since Paul Mundt has dealt with those separately in the
sh tree.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Ralf Baechle <ralf@linux-mips.org>,
Cc: Sam Ravnborg <sam@ravnborg.org>,
Cc: Paul Mundt <lethal@linux-sh.org>,
Cc: Richard Henderson <rth@twiddle.net>,
Cc: Michael Starvik <starvik@axis.com>,
Cc: David Howells <dhowells@redhat.com>,
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>,
Cc: Hirokazu Takata <takata@linux-m32r.org>,
Cc: Geert Uytterhoeven <geert@linux-m68k.org>,
Cc: Roman Zippel <zippel@linux-m68k.org>,
Cc: William L. Irwin <sparclinux@vger.kernel.org>,
Cc: Chris Zankel <chris@zankel.net>,
Cc: H. Peter Anvin <hpa@zytor.com>,
Cc: Jan Engelhardt <jengelh@computergmbh.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-08 20:21:26 +08:00
|
|
|
# else
|
|
|
|
return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN;
|
|
|
|
# endif
|
Optimize timespec_trunc()
The first thing done by timespec_trunc() is :
if (gran <= jiffies_to_usecs(1) * 1000)
This should really be a test against a constant known at compile time.
Alas, it isnt. jiffies_to_usec() was unilined so C compiler emits a function
call and a multiply to compute : a CONSTANT.
mov $0x1,%edi
mov %rbx,0xffffffffffffffe8(%rbp)
mov %r12,0xfffffffffffffff0(%rbp)
mov %edx,%ebx
mov %rsi,0xffffffffffffffc8(%rbp)
mov %rsi,%r12
callq ffffffff80232010 <jiffies_to_usecs>
imul $0x3e8,%eax,%eax
cmp %ebx,%eax
This patch reorders kernel/time.c a bit so that jiffies_to_usecs() is defined
before timespec_trunc() so that compiler now generates :
cmp $0x3d0900,%edx (HZ=250 on my machine)
This gives a better code (timespec_trunc() becoming a leaf function), and
shorter kernel size as well.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-08 15:25:32 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(jiffies_to_usecs);
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
2014-11-18 19:15:18 +08:00
|
|
|
* mktime64 - Converts date to seconds.
|
2023-07-04 13:24:05 +08:00
|
|
|
* @year0: year to convert
|
|
|
|
* @mon0: month to convert
|
|
|
|
* @day: day to convert
|
|
|
|
* @hour: hour to convert
|
|
|
|
* @min: minute to convert
|
|
|
|
* @sec: second to convert
|
|
|
|
*
|
2014-11-18 19:15:18 +08:00
|
|
|
* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
|
2006-01-10 12:52:22 +08:00
|
|
|
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
|
|
|
|
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
|
|
|
|
*
|
|
|
|
* [For the Julian calendar (which was used in Russia before 1917,
|
|
|
|
* Britain & colonies before 1752, anywhere else before 1582,
|
|
|
|
* and is still in use by some communities) leave out the
|
|
|
|
* -year/100+year/400 terms, and add 10.]
|
|
|
|
*
|
|
|
|
* This algorithm was first published by Gauss (I think).
|
2016-02-24 22:37:53 +08:00
|
|
|
*
|
|
|
|
* A leap second can be indicated by calling this function with sec as
|
|
|
|
* 60 (allowable under ISO 8601). The leap second is treated the same
|
|
|
|
* as the following second since they don't exist in UNIX time.
|
|
|
|
*
|
|
|
|
* An encoding of midnight at the end of the day as 24:00:00 - ie. midnight
|
|
|
|
* tomorrow - (allowable under ISO 8601) is supported.
|
2023-07-04 13:24:05 +08:00
|
|
|
*
|
|
|
|
* Return: seconds since the epoch time for the given input date
|
2006-01-10 12:52:22 +08:00
|
|
|
*/
|
2014-11-18 19:15:18 +08:00
|
|
|
time64_t mktime64(const unsigned int year0, const unsigned int mon0,
|
|
|
|
const unsigned int day, const unsigned int hour,
|
|
|
|
const unsigned int min, const unsigned int sec)
|
2006-01-10 12:52:22 +08:00
|
|
|
{
|
2006-01-10 12:52:23 +08:00
|
|
|
unsigned int mon = mon0, year = year0;
|
|
|
|
|
|
|
|
/* 1..12 -> 11,12,1..10 */
|
|
|
|
if (0 >= (int) (mon -= 2)) {
|
|
|
|
mon += 12; /* Puts Feb last since it has leap day */
|
2006-01-10 12:52:22 +08:00
|
|
|
year -= 1;
|
|
|
|
}
|
|
|
|
|
2014-11-18 19:15:18 +08:00
|
|
|
return ((((time64_t)
|
2006-01-10 12:52:22 +08:00
|
|
|
(year/4 - year/100 + year/400 + 367*mon/12 + day) +
|
|
|
|
year*365 - 719499
|
2016-02-24 22:37:53 +08:00
|
|
|
)*24 + hour /* now have hours - midnight tomorrow handled here */
|
2006-01-10 12:52:22 +08:00
|
|
|
)*60 + min /* now have minutes */
|
|
|
|
)*60 + sec; /* finally seconds */
|
|
|
|
}
|
2014-11-18 19:15:18 +08:00
|
|
|
EXPORT_SYMBOL(mktime64);
|
2006-01-10 12:52:24 +08:00
|
|
|
|
2022-07-12 17:47:15 +08:00
|
|
|
struct __kernel_old_timeval ns_to_kernel_old_timeval(s64 nsec)
|
y2038: Introduce struct __kernel_old_timeval
Dealing with 'struct timeval' users in the y2038 series is a bit tricky:
We have two definitions of timeval that are visible to user space,
one comes from glibc (or some other C library), the other comes from
linux/time.h. The kernel copy is what we want to be used for a number of
structures defined by the kernel itself, e.g. elf_prstatus (used it core
dumps), sysinfo and rusage (used in system calls). These generally tend
to be used for passing time intervals rather than absolute (epoch-based)
times, so they do not suffer from the y2038 overflow. Some of them
could be changed to use 64-bit timestamps by creating new system calls,
others like the core files cannot easily be changed.
An application using these interfaces likely also uses gettimeofday()
or other interfaces that use absolute times, and pass 'struct timeval'
pointers directly into kernel interfaces, so glibc must redefine their
timeval based on a 64-bit time_t when they introduce their y2038-safe
interfaces.
The only reasonable way forward I see is to remove the 'timeval'
definion from the kernel's uapi headers, and change the interfaces that
we do not want to (or cannot) duplicate for 64-bit times to use a new
__kernel_old_timeval definition instead. This type should be avoided
for all new interfaces (those can use 64-bit nanoseconds, or the 64-bit
version of timespec instead), and should be used with great care when
converting existing interfaces from timeval, to be sure they don't suffer
from the y2038 overflow, and only with consensus for the particular user
that using __kernel_old_timeval is better than moving to a 64-bit based
interface. The structure name is intentionally chosen to not conflict
with user space types, and to be ugly enough to discourage its use.
Note that ioctl based interfaces that pass a bare 'timeval' pointer
cannot change to '__kernel_old_timeval' because the user space source
code refers to 'timeval' instead, and we don't want to modify the user
space sources if possible. However, any application that relies on a
structure to contain an embedded 'timeval' (e.g. by passing a pointer
to the member into a function call that expects a timeval pointer) is
broken when that structure gets converted to __kernel_old_timeval. I
don't see any way around that, and we have to rely on the compiler to
produce a warning or compile failure that will alert users when they
recompile their sources against a new libc.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lkml.kernel.org/r/20180315161739.576085-1-arnd@arndb.de
2018-03-16 00:12:40 +08:00
|
|
|
{
|
|
|
|
struct timespec64 ts = ns_to_timespec64(nsec);
|
|
|
|
struct __kernel_old_timeval tv;
|
|
|
|
|
|
|
|
tv.tv_sec = ts.tv_sec;
|
|
|
|
tv.tv_usec = (suseconds_t)ts.tv_nsec / 1000;
|
|
|
|
|
|
|
|
return tv;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ns_to_kernel_old_timeval);
|
|
|
|
|
2014-07-17 05:03:59 +08:00
|
|
|
/**
|
2023-01-03 11:28:49 +08:00
|
|
|
* set_normalized_timespec64 - set timespec sec and nsec parts and normalize
|
2014-07-17 05:03:59 +08:00
|
|
|
*
|
|
|
|
* @ts: pointer to timespec variable to be set
|
|
|
|
* @sec: seconds to set
|
|
|
|
* @nsec: nanoseconds to set
|
|
|
|
*
|
|
|
|
* Set seconds and nanoseconds field of a timespec variable and
|
|
|
|
* normalize to the timespec storage format
|
|
|
|
*
|
2023-07-04 13:24:05 +08:00
|
|
|
* Note: The tv_nsec part is always in the range of 0 <= tv_nsec < NSEC_PER_SEC.
|
2014-07-17 05:03:59 +08:00
|
|
|
* For negative values only the tv_sec field is negative !
|
|
|
|
*/
|
|
|
|
void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec)
|
|
|
|
{
|
|
|
|
while (nsec >= NSEC_PER_SEC) {
|
|
|
|
/*
|
|
|
|
* The following asm() prevents the compiler from
|
|
|
|
* optimising this loop into a modulo operation. See
|
|
|
|
* also __iter_div_u64_rem() in include/linux/time.h
|
|
|
|
*/
|
|
|
|
asm("" : "+rm"(nsec));
|
|
|
|
nsec -= NSEC_PER_SEC;
|
|
|
|
++sec;
|
|
|
|
}
|
|
|
|
while (nsec < 0) {
|
|
|
|
asm("" : "+rm"(nsec));
|
|
|
|
nsec += NSEC_PER_SEC;
|
|
|
|
--sec;
|
|
|
|
}
|
|
|
|
ts->tv_sec = sec;
|
|
|
|
ts->tv_nsec = nsec;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(set_normalized_timespec64);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ns_to_timespec64 - Convert nanoseconds to timespec64
|
|
|
|
* @nsec: the nanoseconds value to be converted
|
|
|
|
*
|
2023-07-04 13:24:05 +08:00
|
|
|
* Return: the timespec64 representation of the nsec parameter.
|
2014-07-17 05:03:59 +08:00
|
|
|
*/
|
2022-07-12 17:47:15 +08:00
|
|
|
struct timespec64 ns_to_timespec64(s64 nsec)
|
2014-07-17 05:03:59 +08:00
|
|
|
{
|
2019-11-09 04:34:25 +08:00
|
|
|
struct timespec64 ts = { 0, 0 };
|
2014-07-17 05:03:59 +08:00
|
|
|
s32 rem;
|
|
|
|
|
2019-11-09 04:34:25 +08:00
|
|
|
if (likely(nsec > 0)) {
|
|
|
|
ts.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
|
|
|
|
ts.tv_nsec = rem;
|
|
|
|
} else if (nsec < 0) {
|
|
|
|
/*
|
|
|
|
* With negative times, tv_sec points to the earlier
|
|
|
|
* second, and tv_nsec counts the nanoseconds since
|
|
|
|
* then, so tv_nsec is always a positive number.
|
|
|
|
*/
|
|
|
|
ts.tv_sec = -div_u64_rem(-nsec - 1, NSEC_PER_SEC, &rem) - 1;
|
|
|
|
ts.tv_nsec = NSEC_PER_SEC - rem - 1;
|
2014-07-17 05:03:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return ts;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ns_to_timespec64);
|
2017-10-19 19:14:48 +08:00
|
|
|
|
2015-05-18 20:19:13 +08:00
|
|
|
/**
|
2023-01-03 11:28:49 +08:00
|
|
|
* __msecs_to_jiffies: - convert milliseconds to jiffies
|
2015-05-18 20:19:13 +08:00
|
|
|
* @m: time in milliseconds
|
|
|
|
*
|
|
|
|
* conversion is done as follows:
|
2007-02-16 17:27:28 +08:00
|
|
|
*
|
|
|
|
* - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
|
|
|
|
*
|
|
|
|
* - 'too large' values [that would result in larger than
|
|
|
|
* MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
|
|
|
|
*
|
|
|
|
* - all other values are converted to jiffies by either multiplying
|
2015-05-18 20:19:13 +08:00
|
|
|
* the input value by a factor or dividing it with a factor and
|
|
|
|
* handling any 32-bit overflows.
|
|
|
|
* for the details see __msecs_to_jiffies()
|
2007-02-16 17:27:28 +08:00
|
|
|
*
|
2023-01-03 11:28:49 +08:00
|
|
|
* __msecs_to_jiffies() checks for the passed in value being a constant
|
2015-05-18 20:19:13 +08:00
|
|
|
* via __builtin_constant_p() allowing gcc to eliminate most of the
|
|
|
|
* code, __msecs_to_jiffies() is called if the value passed does not
|
|
|
|
* allow constant folding and the actual conversion must be done at
|
|
|
|
* runtime.
|
2023-01-03 11:28:49 +08:00
|
|
|
* The _msecs_to_jiffies helpers are the HZ dependent conversion
|
2015-05-18 20:19:13 +08:00
|
|
|
* routines found in include/linux/jiffies.h
|
2023-07-04 13:24:05 +08:00
|
|
|
*
|
|
|
|
* Return: jiffies value
|
2007-02-16 17:27:28 +08:00
|
|
|
*/
|
2015-05-18 20:19:13 +08:00
|
|
|
unsigned long __msecs_to_jiffies(const unsigned int m)
|
2007-02-16 17:27:27 +08:00
|
|
|
{
|
2007-02-16 17:27:28 +08:00
|
|
|
/*
|
|
|
|
* Negative value, means infinite timeout:
|
|
|
|
*/
|
|
|
|
if ((int)m < 0)
|
2007-02-16 17:27:27 +08:00
|
|
|
return MAX_JIFFY_OFFSET;
|
2015-05-18 20:19:13 +08:00
|
|
|
return _msecs_to_jiffies(m);
|
2007-02-16 17:27:27 +08:00
|
|
|
}
|
2015-05-18 20:19:13 +08:00
|
|
|
EXPORT_SYMBOL(__msecs_to_jiffies);
|
2007-02-16 17:27:27 +08:00
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* __usecs_to_jiffies: - convert microseconds to jiffies
|
|
|
|
* @u: time in milliseconds
|
|
|
|
*
|
|
|
|
* Return: jiffies value
|
|
|
|
*/
|
2015-05-29 01:09:55 +08:00
|
|
|
unsigned long __usecs_to_jiffies(const unsigned int u)
|
2007-02-16 17:27:27 +08:00
|
|
|
{
|
|
|
|
if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
|
|
|
|
return MAX_JIFFY_OFFSET;
|
2015-05-29 01:09:55 +08:00
|
|
|
return _usecs_to_jiffies(u);
|
2007-02-16 17:27:27 +08:00
|
|
|
}
|
2015-05-29 01:09:55 +08:00
|
|
|
EXPORT_SYMBOL(__usecs_to_jiffies);
|
2007-02-16 17:27:27 +08:00
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* timespec64_to_jiffies - convert a timespec64 value to jiffies
|
|
|
|
* @value: pointer to &struct timespec64
|
|
|
|
*
|
2007-02-16 17:27:27 +08:00
|
|
|
* The TICK_NSEC - 1 rounds up the value to the next resolution. Note
|
|
|
|
* that a remainder subtract here would not do the right thing as the
|
2021-03-23 05:39:03 +08:00
|
|
|
* resolution values don't fall on second boundaries. I.e. the line:
|
2007-02-16 17:27:27 +08:00
|
|
|
* nsec -= nsec % TICK_NSEC; is NOT a correct resolution rounding.
|
jiffies: Fix timeval conversion to jiffies
timeval_to_jiffies tried to round a timeval up to an integral number
of jiffies, but the logic for doing so was incorrect: intervals
corresponding to exactly N jiffies would become N+1. This manifested
itself particularly repeatedly stopping/starting an itimer:
setitimer(ITIMER_PROF, &val, NULL);
setitimer(ITIMER_PROF, NULL, &val);
would add a full tick to val, _even if it was exactly representable in
terms of jiffies_ (say, the result of a previous rounding.) Doing
this repeatedly would cause unbounded growth in val. So fix the math.
Here's what was wrong with the conversion: we essentially computed
(eliding seconds)
jiffies = usec * (NSEC_PER_USEC/TICK_NSEC)
by using scaling arithmetic, which took the best approximation of
NSEC_PER_USEC/TICK_NSEC with denominator of 2^USEC_JIFFIE_SC =
x/(2^USEC_JIFFIE_SC), and computed:
jiffies = (usec * x) >> USEC_JIFFIE_SC
and rounded this calculation up in the intermediate form (since we
can't necessarily exactly represent TICK_NSEC in usec.) But the
scaling arithmetic is a (very slight) *over*approximation of the true
value; that is, instead of dividing by (1 usec/ 1 jiffie), we
effectively divided by (1 usec/1 jiffie)-epsilon (rounding
down). This would normally be fine, but we want to round timeouts up,
and we did so by adding 2^USEC_JIFFIE_SC - 1 before the shift; this
would be fine if our division was exact, but dividing this by the
slightly smaller factor was equivalent to adding just _over_ 1 to the
final result (instead of just _under_ 1, as desired.)
In particular, with HZ=1000, we consistently computed that 10000 usec
was 11 jiffies; the same was true for any exact multiple of
TICK_NSEC.
We could possibly still round in the intermediate form, adding
something less than 2^USEC_JIFFIE_SC - 1, but easier still is to
convert usec->nsec, round in nanoseconds, and then convert using
time*spec*_to_jiffies. This adds one constant multiplication, and is
not observably slower in microbenchmarks on recent x86 hardware.
Tested: the following program:
int main() {
struct itimerval zero = {{0, 0}, {0, 0}};
/* Initially set to 10 ms. */
struct itimerval initial = zero;
initial.it_interval.tv_usec = 10000;
setitimer(ITIMER_PROF, &initial, NULL);
/* Save and restore several times. */
for (size_t i = 0; i < 10; ++i) {
struct itimerval prev;
setitimer(ITIMER_PROF, &zero, &prev);
/* on old kernels, this goes up by TICK_USEC every iteration */
printf("previous value: %ld %ld %ld %ld\n",
prev.it_interval.tv_sec, prev.it_interval.tv_usec,
prev.it_value.tv_sec, prev.it_value.tv_usec);
setitimer(ITIMER_PROF, &prev, NULL);
}
return 0;
}
Cc: stable@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Paul Turner <pjt@google.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Reviewed-by: Paul Turner <pjt@google.com>
Reported-by: Aaron Jacobs <jacobsa@google.com>
Signed-off-by: Andrew Hunter <ahh@google.com>
[jstultz: Tweaked to apply to 3.17-rc]
Signed-off-by: John Stultz <john.stultz@linaro.org>
2014-09-05 05:17:16 +08:00
|
|
|
* Note that due to the small error in the multiplier here, this
|
|
|
|
* rounding is incorrect for sufficiently large values of tv_nsec, but
|
|
|
|
* well formed timespecs should have tv_nsec < NSEC_PER_SEC, so we're
|
|
|
|
* OK.
|
2007-02-16 17:27:27 +08:00
|
|
|
*
|
|
|
|
* Rather, we just shift the bits off the right.
|
|
|
|
*
|
|
|
|
* The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
|
|
|
|
* value to a scaled second value.
|
2023-07-04 13:24:05 +08:00
|
|
|
*
|
|
|
|
* Return: jiffies value
|
2007-02-16 17:27:27 +08:00
|
|
|
*/
|
2019-10-25 04:53:19 +08:00
|
|
|
unsigned long
|
|
|
|
timespec64_to_jiffies(const struct timespec64 *value)
|
2007-02-16 17:27:27 +08:00
|
|
|
{
|
2019-10-25 04:53:19 +08:00
|
|
|
u64 sec = value->tv_sec;
|
|
|
|
long nsec = value->tv_nsec + TICK_NSEC - 1;
|
2007-02-16 17:27:27 +08:00
|
|
|
|
|
|
|
if (sec >= MAX_SEC_IN_JIFFIES){
|
|
|
|
sec = MAX_SEC_IN_JIFFIES;
|
|
|
|
nsec = 0;
|
|
|
|
}
|
2015-07-29 20:18:31 +08:00
|
|
|
return ((sec * SEC_CONVERSION) +
|
2007-02-16 17:27:27 +08:00
|
|
|
(((u64)nsec * NSEC_CONVERSION) >>
|
|
|
|
(NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
|
|
|
|
|
|
|
|
}
|
2015-07-29 20:18:31 +08:00
|
|
|
EXPORT_SYMBOL(timespec64_to_jiffies);
|
2007-02-16 17:27:27 +08:00
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* jiffies_to_timespec64 - convert jiffies value to &struct timespec64
|
|
|
|
* @jiffies: jiffies value
|
|
|
|
* @value: pointer to &struct timespec64
|
|
|
|
*/
|
2007-02-16 17:27:27 +08:00
|
|
|
void
|
2015-07-29 20:18:31 +08:00
|
|
|
jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value)
|
2007-02-16 17:27:27 +08:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Convert jiffies to nanoseconds and separate with
|
|
|
|
* one divide.
|
|
|
|
*/
|
2008-05-01 19:34:31 +08:00
|
|
|
u32 rem;
|
|
|
|
value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
|
|
|
|
NSEC_PER_SEC, &rem);
|
|
|
|
value->tv_nsec = rem;
|
2007-02-16 17:27:27 +08:00
|
|
|
}
|
2015-07-29 20:18:31 +08:00
|
|
|
EXPORT_SYMBOL(jiffies_to_timespec64);
|
2007-02-16 17:27:27 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert jiffies/jiffies_64 to clock_t and back.
|
|
|
|
*/
|
2023-07-04 13:24:05 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* jiffies_to_clock_t - Convert jiffies to clock_t
|
|
|
|
* @x: jiffies value
|
|
|
|
*
|
|
|
|
* Return: jiffies converted to clock_t (CLOCKS_PER_SEC)
|
|
|
|
*/
|
2011-09-21 04:53:39 +08:00
|
|
|
clock_t jiffies_to_clock_t(unsigned long x)
|
2007-02-16 17:27:27 +08:00
|
|
|
{
|
|
|
|
#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
|
2008-02-06 17:38:04 +08:00
|
|
|
# if HZ < USER_HZ
|
|
|
|
return x * (USER_HZ / HZ);
|
|
|
|
# else
|
2007-02-16 17:27:27 +08:00
|
|
|
return x / (HZ / USER_HZ);
|
2008-02-06 17:38:04 +08:00
|
|
|
# endif
|
2007-02-16 17:27:27 +08:00
|
|
|
#else
|
2008-05-01 19:34:26 +08:00
|
|
|
return div_u64((u64)x * TICK_NSEC, NSEC_PER_SEC / USER_HZ);
|
2007-02-16 17:27:27 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(jiffies_to_clock_t);
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* clock_t_to_jiffies - Convert clock_t to jiffies
|
|
|
|
* @x: clock_t value
|
|
|
|
*
|
|
|
|
* Return: clock_t value converted to jiffies
|
|
|
|
*/
|
2007-02-16 17:27:27 +08:00
|
|
|
unsigned long clock_t_to_jiffies(unsigned long x)
|
|
|
|
{
|
|
|
|
#if (HZ % USER_HZ)==0
|
|
|
|
if (x >= ~0UL / (HZ / USER_HZ))
|
|
|
|
return ~0UL;
|
|
|
|
return x * (HZ / USER_HZ);
|
|
|
|
#else
|
|
|
|
/* Don't worry about loss of precision here .. */
|
|
|
|
if (x >= ~0UL / HZ * USER_HZ)
|
|
|
|
return ~0UL;
|
|
|
|
|
|
|
|
/* .. but do try to contain it here */
|
2008-05-01 19:34:26 +08:00
|
|
|
return div_u64((u64)x * HZ, USER_HZ);
|
2007-02-16 17:27:27 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(clock_t_to_jiffies);
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* jiffies_64_to_clock_t - Convert jiffies_64 to clock_t
|
|
|
|
* @x: jiffies_64 value
|
|
|
|
*
|
|
|
|
* Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
|
|
|
|
*/
|
2007-02-16 17:27:27 +08:00
|
|
|
u64 jiffies_64_to_clock_t(u64 x)
|
|
|
|
{
|
|
|
|
#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
|
2008-02-06 17:38:04 +08:00
|
|
|
# if HZ < USER_HZ
|
2008-05-01 19:34:26 +08:00
|
|
|
x = div_u64(x * USER_HZ, HZ);
|
2008-02-06 17:38:06 +08:00
|
|
|
# elif HZ > USER_HZ
|
2008-05-01 19:34:26 +08:00
|
|
|
x = div_u64(x, HZ / USER_HZ);
|
2008-02-06 17:38:06 +08:00
|
|
|
# else
|
|
|
|
/* Nothing to do */
|
2008-02-06 17:38:04 +08:00
|
|
|
# endif
|
2007-02-16 17:27:27 +08:00
|
|
|
#else
|
|
|
|
/*
|
|
|
|
* There are better ways that don't overflow early,
|
|
|
|
* but even this doesn't overflow in hundreds of years
|
|
|
|
* in 64 bits, so..
|
|
|
|
*/
|
2008-05-01 19:34:26 +08:00
|
|
|
x = div_u64(x * TICK_NSEC, (NSEC_PER_SEC / USER_HZ));
|
2007-02-16 17:27:27 +08:00
|
|
|
#endif
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(jiffies_64_to_clock_t);
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* nsec_to_clock_t - Convert nsec value to clock_t
|
|
|
|
* @x: nsec value
|
|
|
|
*
|
|
|
|
* Return: nsec value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
|
|
|
|
*/
|
2007-02-16 17:27:27 +08:00
|
|
|
u64 nsec_to_clock_t(u64 x)
|
|
|
|
{
|
|
|
|
#if (NSEC_PER_SEC % USER_HZ) == 0
|
2008-05-01 19:34:26 +08:00
|
|
|
return div_u64(x, NSEC_PER_SEC / USER_HZ);
|
2007-02-16 17:27:27 +08:00
|
|
|
#elif (USER_HZ % 512) == 0
|
2008-05-01 19:34:26 +08:00
|
|
|
return div_u64(x * USER_HZ / 512, NSEC_PER_SEC / 512);
|
2007-02-16 17:27:27 +08:00
|
|
|
#else
|
|
|
|
/*
|
|
|
|
* max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024,
|
|
|
|
* overflow after 64.99 years.
|
|
|
|
* exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ...
|
|
|
|
*/
|
2008-05-01 19:34:26 +08:00
|
|
|
return div_u64(x * 9, (9ull * NSEC_PER_SEC + (USER_HZ / 2)) / USER_HZ);
|
2007-02-16 17:27:27 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* jiffies64_to_nsecs - Convert jiffies64 to nanoseconds
|
|
|
|
* @j: jiffies64 value
|
|
|
|
*
|
|
|
|
* Return: nanoseconds value
|
|
|
|
*/
|
2017-01-31 11:09:17 +08:00
|
|
|
u64 jiffies64_to_nsecs(u64 j)
|
|
|
|
{
|
|
|
|
#if !(NSEC_PER_SEC % HZ)
|
|
|
|
return (NSEC_PER_SEC / HZ) * j;
|
|
|
|
# else
|
|
|
|
return div_u64(j * HZ_TO_NSEC_NUM, HZ_TO_NSEC_DEN);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(jiffies64_to_nsecs);
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* jiffies64_to_msecs - Convert jiffies64 to milliseconds
|
|
|
|
* @j: jiffies64 value
|
|
|
|
*
|
|
|
|
* Return: milliseconds value
|
|
|
|
*/
|
2019-02-28 13:13:26 +08:00
|
|
|
u64 jiffies64_to_msecs(const u64 j)
|
|
|
|
{
|
|
|
|
#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
|
|
|
|
return (MSEC_PER_SEC / HZ) * j;
|
|
|
|
#else
|
|
|
|
return div_u64(j * HZ_TO_MSEC_NUM, HZ_TO_MSEC_DEN);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(jiffies64_to_msecs);
|
|
|
|
|
2009-11-26 13:49:27 +08:00
|
|
|
/**
|
2010-12-22 09:09:01 +08:00
|
|
|
* nsecs_to_jiffies64 - Convert nsecs in u64 to jiffies64
|
2009-11-26 13:49:27 +08:00
|
|
|
*
|
|
|
|
* @n: nsecs in u64
|
|
|
|
*
|
|
|
|
* Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64.
|
|
|
|
* And this doesn't return MAX_JIFFY_OFFSET since this function is designed
|
|
|
|
* for scheduler, not for use in device drivers to calculate timeout value.
|
|
|
|
*
|
|
|
|
* note:
|
|
|
|
* NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
|
|
|
|
* ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
|
2023-07-04 13:24:05 +08:00
|
|
|
*
|
|
|
|
* Return: nsecs converted to jiffies64 value
|
2009-11-26 13:49:27 +08:00
|
|
|
*/
|
2010-12-22 09:09:01 +08:00
|
|
|
u64 nsecs_to_jiffies64(u64 n)
|
2009-11-26 13:49:27 +08:00
|
|
|
{
|
|
|
|
#if (NSEC_PER_SEC % HZ) == 0
|
|
|
|
/* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */
|
|
|
|
return div_u64(n, NSEC_PER_SEC / HZ);
|
|
|
|
#elif (HZ % 512) == 0
|
|
|
|
/* overflow after 292 years if HZ = 1024 */
|
|
|
|
return div_u64(n * HZ / 512, NSEC_PER_SEC / 512);
|
|
|
|
#else
|
|
|
|
/*
|
|
|
|
* Generic case - optimized for cases where HZ is a multiple of 3.
|
|
|
|
* overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc.
|
|
|
|
*/
|
|
|
|
return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ);
|
|
|
|
#endif
|
|
|
|
}
|
2014-12-04 18:12:54 +08:00
|
|
|
EXPORT_SYMBOL(nsecs_to_jiffies64);
|
2009-11-26 13:49:27 +08:00
|
|
|
|
2010-12-22 09:09:01 +08:00
|
|
|
/**
|
|
|
|
* nsecs_to_jiffies - Convert nsecs in u64 to jiffies
|
|
|
|
*
|
|
|
|
* @n: nsecs in u64
|
|
|
|
*
|
|
|
|
* Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64.
|
|
|
|
* And this doesn't return MAX_JIFFY_OFFSET since this function is designed
|
|
|
|
* for scheduler, not for use in device drivers to calculate timeout value.
|
|
|
|
*
|
|
|
|
* note:
|
|
|
|
* NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
|
|
|
|
* ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
|
2023-07-04 13:24:05 +08:00
|
|
|
*
|
|
|
|
* Return: nsecs converted to jiffies value
|
2010-12-22 09:09:01 +08:00
|
|
|
*/
|
|
|
|
unsigned long nsecs_to_jiffies(u64 n)
|
|
|
|
{
|
|
|
|
return (unsigned long)nsecs_to_jiffies64(n);
|
|
|
|
}
|
2014-07-17 05:04:31 +08:00
|
|
|
EXPORT_SYMBOL_GPL(nsecs_to_jiffies);
|
2010-12-22 09:09:01 +08:00
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* timespec64_add_safe - Add two timespec64 values and do a safety check
|
|
|
|
* for overflow.
|
|
|
|
* @lhs: first (left) timespec64 to add
|
|
|
|
* @rhs: second (right) timespec64 to add
|
|
|
|
*
|
2016-05-20 08:09:02 +08:00
|
|
|
* It's assumed that both values are valid (>= 0).
|
|
|
|
* And, each timespec64 is in normalized form.
|
2023-07-04 13:24:05 +08:00
|
|
|
*
|
|
|
|
* Return: sum of @lhs + @rhs
|
2016-05-20 08:09:02 +08:00
|
|
|
*/
|
|
|
|
struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
|
|
|
|
const struct timespec64 rhs)
|
|
|
|
{
|
|
|
|
struct timespec64 res;
|
|
|
|
|
2016-08-13 02:14:09 +08:00
|
|
|
set_normalized_timespec64(&res, (timeu64_t) lhs.tv_sec + rhs.tv_sec,
|
2016-05-20 08:09:02 +08:00
|
|
|
lhs.tv_nsec + rhs.tv_nsec);
|
|
|
|
|
|
|
|
if (unlikely(res.tv_sec < lhs.tv_sec || res.tv_sec < rhs.tv_sec)) {
|
|
|
|
res.tv_sec = TIME64_MAX;
|
|
|
|
res.tv_nsec = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
2017-06-25 02:45:02 +08:00
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* get_timespec64 - get user's time value into kernel space
|
|
|
|
* @ts: destination &struct timespec64
|
|
|
|
* @uts: user's time value as &struct __kernel_timespec
|
|
|
|
*
|
|
|
|
* Handles compat or 32-bit modes.
|
|
|
|
*
|
|
|
|
* Return: %0 on success or negative errno on error
|
|
|
|
*/
|
2017-06-25 02:45:02 +08:00
|
|
|
int get_timespec64(struct timespec64 *ts,
|
2018-03-14 12:03:31 +08:00
|
|
|
const struct __kernel_timespec __user *uts)
|
2017-06-25 02:45:02 +08:00
|
|
|
{
|
2018-03-14 12:03:31 +08:00
|
|
|
struct __kernel_timespec kts;
|
2017-06-25 02:45:02 +08:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = copy_from_user(&kts, uts, sizeof(kts));
|
|
|
|
if (ret)
|
|
|
|
return -EFAULT;
|
|
|
|
|
|
|
|
ts->tv_sec = kts.tv_sec;
|
2018-03-14 12:03:31 +08:00
|
|
|
|
2019-12-04 04:20:25 +08:00
|
|
|
/* Zero out the padding in compat mode */
|
2019-04-23 23:43:50 +08:00
|
|
|
if (in_compat_syscall())
|
2018-03-14 12:03:31 +08:00
|
|
|
kts.tv_nsec &= 0xFFFFFFFFUL;
|
|
|
|
|
2019-12-04 04:20:25 +08:00
|
|
|
/* In 32-bit mode, this drops the padding */
|
2017-06-25 02:45:02 +08:00
|
|
|
ts->tv_nsec = kts.tv_nsec;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(get_timespec64);
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* put_timespec64 - convert timespec64 value to __kernel_timespec format and
|
|
|
|
* copy the latter to userspace
|
|
|
|
* @ts: input &struct timespec64
|
|
|
|
* @uts: user's &struct __kernel_timespec
|
|
|
|
*
|
|
|
|
* Return: %0 on success or negative errno on error
|
|
|
|
*/
|
2017-06-25 02:45:02 +08:00
|
|
|
int put_timespec64(const struct timespec64 *ts,
|
2018-03-14 12:03:31 +08:00
|
|
|
struct __kernel_timespec __user *uts)
|
2017-06-25 02:45:02 +08:00
|
|
|
{
|
2018-03-14 12:03:31 +08:00
|
|
|
struct __kernel_timespec kts = {
|
2017-06-25 02:45:02 +08:00
|
|
|
.tv_sec = ts->tv_sec,
|
|
|
|
.tv_nsec = ts->tv_nsec
|
|
|
|
};
|
2018-03-14 12:03:31 +08:00
|
|
|
|
2017-06-25 02:45:02 +08:00
|
|
|
return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(put_timespec64);
|
2017-06-25 02:45:03 +08:00
|
|
|
|
2018-08-29 20:50:52 +08:00
|
|
|
static int __get_old_timespec32(struct timespec64 *ts64,
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
const struct old_timespec32 __user *cts)
|
2018-03-14 12:03:26 +08:00
|
|
|
{
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
struct old_timespec32 ts;
|
2018-03-14 12:03:26 +08:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = copy_from_user(&ts, cts, sizeof(ts));
|
|
|
|
if (ret)
|
|
|
|
return -EFAULT;
|
|
|
|
|
|
|
|
ts64->tv_sec = ts.tv_sec;
|
|
|
|
ts64->tv_nsec = ts.tv_nsec;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-08-29 20:50:52 +08:00
|
|
|
static int __put_old_timespec32(const struct timespec64 *ts64,
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
struct old_timespec32 __user *cts)
|
2018-03-14 12:03:26 +08:00
|
|
|
{
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
struct old_timespec32 ts = {
|
2018-03-14 12:03:26 +08:00
|
|
|
.tv_sec = ts64->tv_sec,
|
|
|
|
.tv_nsec = ts64->tv_nsec
|
|
|
|
};
|
|
|
|
return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0;
|
|
|
|
}
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* get_old_timespec32 - get user's old-format time value into kernel space
|
|
|
|
* @ts: destination &struct timespec64
|
|
|
|
* @uts: user's old-format time value (&struct old_timespec32)
|
|
|
|
*
|
|
|
|
* Handles X86_X32_ABI compatibility conversion.
|
|
|
|
*
|
|
|
|
* Return: %0 on success or negative errno on error
|
|
|
|
*/
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
int get_old_timespec32(struct timespec64 *ts, const void __user *uts)
|
2018-03-14 12:03:26 +08:00
|
|
|
{
|
|
|
|
if (COMPAT_USE_64BIT_TIME)
|
|
|
|
return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0;
|
|
|
|
else
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
return __get_old_timespec32(ts, uts);
|
2018-03-14 12:03:26 +08:00
|
|
|
}
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
EXPORT_SYMBOL_GPL(get_old_timespec32);
|
2018-03-14 12:03:26 +08:00
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* put_old_timespec32 - convert timespec64 value to &struct old_timespec32 and
|
|
|
|
* copy the latter to userspace
|
|
|
|
* @ts: input &struct timespec64
|
|
|
|
* @uts: user's &struct old_timespec32
|
|
|
|
*
|
|
|
|
* Handles X86_X32_ABI compatibility conversion.
|
|
|
|
*
|
|
|
|
* Return: %0 on success or negative errno on error
|
|
|
|
*/
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
int put_old_timespec32(const struct timespec64 *ts, void __user *uts)
|
2018-03-14 12:03:26 +08:00
|
|
|
{
|
|
|
|
if (COMPAT_USE_64BIT_TIME)
|
|
|
|
return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0;
|
|
|
|
else
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
return __put_old_timespec32(ts, uts);
|
2018-03-14 12:03:26 +08:00
|
|
|
}
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
EXPORT_SYMBOL_GPL(put_old_timespec32);
|
2018-03-14 12:03:26 +08:00
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* get_itimerspec64 - get user's &struct __kernel_itimerspec into kernel space
|
|
|
|
* @it: destination &struct itimerspec64
|
|
|
|
* @uit: user's &struct __kernel_itimerspec
|
|
|
|
*
|
|
|
|
* Return: %0 on success or negative errno on error
|
|
|
|
*/
|
2017-06-25 02:45:03 +08:00
|
|
|
int get_itimerspec64(struct itimerspec64 *it,
|
2018-06-17 13:11:42 +08:00
|
|
|
const struct __kernel_itimerspec __user *uit)
|
2017-06-25 02:45:03 +08:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = get_timespec64(&it->it_interval, &uit->it_interval);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = get_timespec64(&it->it_value, &uit->it_value);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(get_itimerspec64);
|
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* put_itimerspec64 - convert &struct itimerspec64 to __kernel_itimerspec format
|
|
|
|
* and copy the latter to userspace
|
|
|
|
* @it: input &struct itimerspec64
|
|
|
|
* @uit: user's &struct __kernel_itimerspec
|
|
|
|
*
|
|
|
|
* Return: %0 on success or negative errno on error
|
|
|
|
*/
|
2017-06-25 02:45:03 +08:00
|
|
|
int put_itimerspec64(const struct itimerspec64 *it,
|
2018-06-17 13:11:42 +08:00
|
|
|
struct __kernel_itimerspec __user *uit)
|
2017-06-25 02:45:03 +08:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = put_timespec64(&it->it_interval, &uit->it_interval);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = put_timespec64(&it->it_value, &uit->it_value);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(put_itimerspec64);
|
2018-06-17 13:11:43 +08:00
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* get_old_itimerspec32 - get user's &struct old_itimerspec32 into kernel space
|
|
|
|
* @its: destination &struct itimerspec64
|
|
|
|
* @uits: user's &struct old_itimerspec32
|
|
|
|
*
|
|
|
|
* Return: %0 on success or negative errno on error
|
|
|
|
*/
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
int get_old_itimerspec32(struct itimerspec64 *its,
|
|
|
|
const struct old_itimerspec32 __user *uits)
|
2018-06-17 13:11:43 +08:00
|
|
|
{
|
|
|
|
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
if (__get_old_timespec32(&its->it_interval, &uits->it_interval) ||
|
|
|
|
__get_old_timespec32(&its->it_value, &uits->it_value))
|
2018-06-17 13:11:43 +08:00
|
|
|
return -EFAULT;
|
|
|
|
return 0;
|
|
|
|
}
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
EXPORT_SYMBOL_GPL(get_old_itimerspec32);
|
2018-06-17 13:11:43 +08:00
|
|
|
|
2023-07-04 13:24:05 +08:00
|
|
|
/**
|
|
|
|
* put_old_itimerspec32 - convert &struct itimerspec64 to &struct
|
|
|
|
* old_itimerspec32 and copy the latter to userspace
|
|
|
|
* @its: input &struct itimerspec64
|
|
|
|
* @uits: user's &struct old_itimerspec32
|
|
|
|
*
|
|
|
|
* Return: %0 on success or negative errno on error
|
|
|
|
*/
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
int put_old_itimerspec32(const struct itimerspec64 *its,
|
|
|
|
struct old_itimerspec32 __user *uits)
|
2018-06-17 13:11:43 +08:00
|
|
|
{
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
if (__put_old_timespec32(&its->it_interval, &uits->it_interval) ||
|
|
|
|
__put_old_timespec32(&its->it_value, &uits->it_value))
|
2018-06-17 13:11:43 +08:00
|
|
|
return -EFAULT;
|
|
|
|
return 0;
|
|
|
|
}
|
y2038: globally rename compat_time to old_time32
Christoph Hellwig suggested a slightly different path for handling
backwards compatibility with the 32-bit time_t based system calls:
Rather than simply reusing the compat_sys_* entry points on 32-bit
architectures unchanged, we get rid of those entry points and the
compat_time types by renaming them to something that makes more sense
on 32-bit architectures (which don't have a compat mode otherwise),
and then share the entry points under the new name with the 64-bit
architectures that use them for implementing the compatibility.
The following types and interfaces are renamed here, and moved
from linux/compat_time.h to linux/time32.h:
old new
--- ---
compat_time_t old_time32_t
struct compat_timeval struct old_timeval32
struct compat_timespec struct old_timespec32
struct compat_itimerspec struct old_itimerspec32
ns_to_compat_timeval() ns_to_old_timeval32()
get_compat_itimerspec64() get_old_itimerspec32()
put_compat_itimerspec64() put_old_itimerspec32()
compat_get_timespec64() get_old_timespec32()
compat_put_timespec64() put_old_timespec32()
As we already have aliases in place, this patch addresses only the
instances that are relevant to the system call interface in particular,
not those that occur in device drivers and other modules. Those
will get handled separately, while providing the 64-bit version
of the respective interfaces.
I'm not renaming the timex, rusage and itimerval structures, as we are
still debating what the new interface will look like, and whether we
will need a replacement at all.
This also doesn't change the names of the syscall entry points, which can
be done more easily when we actually switch over the 32-bit architectures
to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2018-07-13 18:52:28 +08:00
|
|
|
EXPORT_SYMBOL_GPL(put_old_itimerspec32);
|