The code to check the adjtimex() or clock_adjtime() arguments is spread
out across multiple files for presumably only historic reasons. As a
preparatation for a rework to get rid of the use of 'struct timeval'
and 'struct timespec' in there, this moves all the portions into
kernel/time/timekeeping.c and marks them as 'static'.
The warp_clock() function here is not as closely related as the others,
but I feel it still makes sense to move it here in order to consolidate
all callers of timekeeping_inject_offset().
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
include/linux/time.h | 26 ----------
kernel/time/ntp.c | 61 ----------------------
kernel/time/ntp_internal.h | 1 -
kernel/time/time.c | 36 +------------
kernel/time/timekeeping.c | 123 ++++++++++++++++++++++++++++++++++++++++++++-
kernel/time/timekeeping.h | 2 +-
6 files changed, 123 insertions(+), 126 deletions(-)
diff --git a/include/linux/time.h b/include/linux/time.h
index 9bc1f945777c..c0fbad08448f 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -134,32 +134,6 @@ static inline bool timeval_valid(const struct timeval *tv)
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
-/*
- * Validates if a timespec/timeval used to inject a time offset is valid.
- * Offsets can be postive or negative. The value of the timeval/timespec
- * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must
- * always be non-negative.
- */
-static inline bool timeval_inject_offset_valid(const struct timeval *tv)
-{
- /* We don't check the tv_sec as it can be positive or negative */
-
- /* Can't have more microseconds then a second */
- if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
- return false;
- return true;
-}
-
-static inline bool timespec_inject_offset_valid(const struct timespec *ts)
-{
- /* We don't check the tv_sec as it can be positive or negative */
-
- /* Can't have more nanoseconds then a second */
- if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC)
- return false;
- return true;
-}
-
/* Some architectures do not supply their own clocksource.
* This is mainly the case in architectures that get their
* inter-tick times by reading the counter on their interval
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index edf19cc53140..a5e702669d84 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -653,67 +653,6 @@ static inline void process_adjtimex_modes(struct timex *txc,
}
-
-/**
- * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex
- */
-int ntp_validate_timex(struct timex *txc)
-{
- if (txc->modes & ADJ_ADJTIME) {
- /* singleshot must not be used with any other mode bits */
- if (!(txc->modes & ADJ_OFFSET_SINGLESHOT))
- return -EINVAL;
- if (!(txc->modes & ADJ_OFFSET_READONLY) &&
- !capable(CAP_SYS_TIME))
- return -EPERM;
- } else {
- /* In order to modify anything, you gotta be super-user! */
- if (txc->modes && !capable(CAP_SYS_TIME))
- return -EPERM;
- /*
- * if the quartz is off by more than 10% then
- * something is VERY wrong!
- */
- if (txc->modes & ADJ_TICK &&
- (txc->tick < 900000/USER_HZ ||
- txc->tick > 1100000/USER_HZ))
- return -EINVAL;
- }
-
- if (txc->modes & ADJ_SETOFFSET) {
- /* In order to inject time, you gotta be super-user! */
- if (!capable(CAP_SYS_TIME))
- return -EPERM;
-
- if (txc->modes & ADJ_NANO) {
- struct timespec ts;
-
- ts.tv_sec = txc->time.tv_sec;
- ts.tv_nsec = txc->time.tv_usec;
- if (!timespec_inject_offset_valid(&ts))
- return -EINVAL;
-
- } else {
- if (!timeval_inject_offset_valid(&txc->time))
- return -EINVAL;
- }
- }
-
- /*
- * Check for potential multiplication overflows that can
- * only happen on 64-bit systems:
- */
- if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) {
- if (LLONG_MIN / PPM_SCALE > txc->freq)
- return -EINVAL;
- if (LLONG_MAX / PPM_SCALE < txc->freq)
- return -EINVAL;
- }
-
- return 0;
-}
-
-
/*
* adjtimex mainly allows reading (and writing, if superuser) of
* kernel time-keeping variables. used by xntpd.
diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h
index d8a7c11fa71a..74b52cd48209 100644
--- a/kernel/time/ntp_internal.h
+++ b/kernel/time/ntp_internal.h
@@ -7,7 +7,6 @@ extern void ntp_clear(void);
extern u64 ntp_tick_length(void);
extern ktime_t ntp_get_next_leap(void);
extern int second_overflow(time64_t secs);
-extern int ntp_validate_timex(struct timex *);
extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *);
extern void __hardpps(const struct timespec64 *, const struct timespec64 *);
#endif /* _LINUX_NTP_INTERNAL_H */
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 44a8c1402133..04684e294f00 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -158,40 +158,6 @@ SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
}
/*
- * Indicates if there is an offset between the system clock and the hardware
- * clock/persistent clock/rtc.
- */
-int persistent_clock_is_local;
-
-/*
- * Adjust the time obtained from the CMOS to be UTC time instead of
- * local time.
- *
- * This is ugly, but preferable to the alternatives. Otherwise we
- * would either need to write a program to do it in /etc/rc (and risk
- * confusion if the program gets run more than once; it would also be
- * hard to make the program warp the clock precisely n hours) or
- * compile in the timezone information into the kernel. Bad, bad....
- *
- * - TYT, 1992-01-01
- *
- * The best thing to do is to keep the CMOS clock in universal time (UTC)
- * as real UNIX machines always do it. This avoids all headaches about
- * daylight saving times and warping kernel clocks.
- */
-static inline void warp_clock(void)
-{
- if (sys_tz.tz_minuteswest != 0) {
- struct timespec adjust;
-
- persistent_clock_is_local = 1;
- adjust.tv_sec = sys_tz.tz_minuteswest * 60;
- adjust.tv_nsec = 0;
- timekeeping_inject_offset(&adjust);
- }
-}
-
-/*
* 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
@@ -224,7 +190,7 @@ int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz
if (firsttime) {
firsttime = 0;
if (!tv)
- warp_clock();
+ timekeeping_warp_clock();
}
}
if (tv)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8af77006e937..679dbfbea419 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1300,13 +1300,39 @@ int do_settimeofday64(const struct timespec64 *ts)
}
EXPORT_SYMBOL(do_settimeofday64);
+/*
+ * Validates if a timespec/timeval used to inject a time offset is valid.
+ * Offsets can be postive or negative. The value of the timeval/timespec
+ * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must
+ * always be non-negative.
+ */
+static inline bool timeval_inject_offset_valid(const struct timeval *tv)
+{
+ /* We don't check the tv_sec as it can be positive or negative */
+
+ /* Can't have more microseconds then a second */
+ if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
+ return false;
+ return true;
+}
+
+static inline bool timespec_inject_offset_valid(const struct timespec *ts)
+{
+ /* We don't check the tv_sec as it can be positive or negative */
+
+ /* Can't have more nanoseconds then a second */
+ if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC)
+ return false;
+ return true;
+}
+
/**
* timekeeping_inject_offset - Adds or subtracts from the current time.
* @tv: pointer to the timespec variable containing the offset
*
* Adds or subtracts an offset value from the current time.
*/
-int timekeeping_inject_offset(struct timespec *ts)
+static int timekeeping_inject_offset(struct timespec *ts)
{
struct timekeeper *tk = &tk_core.timekeeper;
unsigned long flags;
@@ -1345,7 +1371,40 @@ int timekeeping_inject_offset(struct timespec *ts)
return ret;
}
-EXPORT_SYMBOL(timekeeping_inject_offset);
+
+/*
+ * Indicates if there is an offset between the system clock and the hardware
+ * clock/persistent clock/rtc.
+ */
+int persistent_clock_is_local;
+
+/*
+ * Adjust the time obtained from the CMOS to be UTC time instead of
+ * local time.
+ *
+ * This is ugly, but preferable to the alternatives. Otherwise we
+ * would either need to write a program to do it in /etc/rc (and risk
+ * confusion if the program gets run more than once; it would also be
+ * hard to make the program warp the clock precisely n hours) or
+ * compile in the timezone information into the kernel. Bad, bad....
+ *
+ * - TYT, 1992-01-01
+ *
+ * The best thing to do is to keep the CMOS clock in universal time (UTC)
+ * as real UNIX machines always do it. This avoids all headaches about
+ * daylight saving times and warping kernel clocks.
+ */
+void timekeeping_warp_clock(void)
+{
+ if (sys_tz.tz_minuteswest != 0) {
+ struct timespec adjust;
+
+ persistent_clock_is_local = 1;
+ adjust.tv_sec = sys_tz.tz_minuteswest * 60;
+ adjust.tv_nsec = 0;
+ timekeeping_inject_offset(&adjust);
+ }
+}
/**
* __timekeeping_set_tai_offset - Sets the TAI offset from UTC and monotonic
@@ -2290,6 +2349,66 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
}
/**
+ * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex
+ */
+static int ntp_validate_timex(struct timex *txc)
+{
+ if (txc->modes & ADJ_ADJTIME) {
+ /* singleshot must not be used with any other mode bits */
+ if (!(txc->modes & ADJ_OFFSET_SINGLESHOT))
+ return -EINVAL;
+ if (!(txc->modes & ADJ_OFFSET_READONLY) &&
+ !capable(CAP_SYS_TIME))
+ return -EPERM;
+ } else {
+ /* In order to modify anything, you gotta be super-user! */
+ if (txc->modes && !capable(CAP_SYS_TIME))
+ return -EPERM;
+ /*
+ * if the quartz is off by more than 10% then
+ * something is VERY wrong!
+ */
+ if (txc->modes & ADJ_TICK &&
+ (txc->tick < 900000/USER_HZ ||
+ txc->tick > 1100000/USER_HZ))
+ return -EINVAL;
+ }
+
+ if (txc->modes & ADJ_SETOFFSET) {
+ /* In order to inject time, you gotta be super-user! */
+ if (!capable(CAP_SYS_TIME))
+ return -EPERM;
+
+ if (txc->modes & ADJ_NANO) {
+ struct timespec ts;
+
+ ts.tv_sec = txc->time.tv_sec;
+ ts.tv_nsec = txc->time.tv_usec;
+ if (!timespec_inject_offset_valid(&ts))
+ return -EINVAL;
+
+ } else {
+ if (!timeval_inject_offset_valid(&txc->time))
+ return -EINVAL;
+ }
+ }
+
+ /*
+ * Check for potential multiplication overflows that can
+ * only happen on 64-bit systems:
+ */
+ if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) {
+ if (LLONG_MIN / PPM_SCALE > txc->freq)
+ return -EINVAL;
+ if (LLONG_MAX / PPM_SCALE < txc->freq)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+/**
* do_adjtimex() - Accessor function to NTP __do_adjtimex function
*/
int do_adjtimex(struct timex *txc)
diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h
index d0914676d4c5..44aec7893cdd 100644
--- a/kernel/time/timekeeping.h
+++ b/kernel/time/timekeeping.h
@@ -10,7 +10,7 @@ extern ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq,
extern int timekeeping_valid_for_hres(void);
extern u64 timekeeping_max_deferment(void);
-extern int timekeeping_inject_offset(struct timespec *ts);
+extern void timekeeping_warp_clock(void);
extern int timekeeping_suspend(void);
extern void timekeeping_resume(void);
--
2.9.0
The test helps to validate clamping and mount behaviors
according to supported file system timestamp ranges.
Note that the test can fail on 32-bit systems for a
few file systems. This will be corrected when vfs is
transitioned to use 64-bit timestamps.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
The branch of the kernel tree can be located at
https://github.com/deepa-hub/vfs refs/heads/vfs_timestamp_policy
The xfs_io patch to add utimes is at
https://www.spinics.net/lists/linux-xfs/msg02952.html
Changes since v2:
* Refactored notrun handling
* Updated comments
Changes since v1:
* Use xfs_io utimes command
* Updated error handling
* Reorganized code according to review comments
common/rc | 48 +++++++++++++
tests/generic/390 | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++
tests/generic/390.out | 2 +
tests/generic/group | 1 +
4 files changed, 243 insertions(+)
create mode 100755 tests/generic/390
create mode 100644 tests/generic/390.out
diff --git a/common/rc b/common/rc
index e3b54ec..17f025e 100644
--- a/common/rc
+++ b/common/rc
@@ -1960,6 +1960,51 @@ _run_aiodio()
return $status
}
+# this test requires y2038 sysfs switch and filesystem
+# timestamp ranges support.
+_require_y2038()
+{
+ local device=${1:-$TEST_DEV}
+ local sysfsdir=/proc/sys/fs/fs-timestamp-check-on
+
+ if [ ! -e $sysfsdir ]; then
+ _notrun "no kernel support for y2038 sysfs switch"
+ fi
+
+ local tsmin tsmax
+ read tsmin tsmax <<<$(_filesystem_timestamp_range $device)
+ if [ $tsmin -eq -1 -a $tsmax -eq -1 ]; then
+ _notrun "filesystem $FSTYP timestamp bounds are unknown"
+ fi
+}
+
+_filesystem_timestamp_range()
+{
+ device=${1:-$TEST_DEV}
+ case $FSTYP in
+ ext4)
+ if [ $(dumpe2fs -h $device 2>/dev/null | grep "Inode size:" | cut -d: -f2) -gt 128 ]; then
+ echo "-2147483648 15032385535"
+ else
+ echo "-2147483648 2147483647"
+ fi
+ ;;
+
+ xfs)
+ echo "-2147483648 2147483647"
+ ;;
+ jfs)
+ echo "0 4294967295"
+ ;;
+ f2fs)
+ echo "-2147483648 2147483647"
+ ;;
+ *)
+ echo "-1 -1"
+ ;;
+ esac
+}
+
# indicate whether YP/NIS is active or not
#
_yp_active()
@@ -2070,6 +2115,9 @@ _require_xfs_io_command()
echo $testio | egrep -q "Inappropriate ioctl" && \
_notrun "xfs_io $command support is missing"
;;
+ "utimes" )
+ testio=`$XFS_IO_PROG -f -c "utimes" 0 0 0 0 $testfile 2>&1`
+ ;;
*)
testio=`$XFS_IO_PROG -c "$command help" 2>&1`
esac
diff --git a/tests/generic/390 b/tests/generic/390
new file mode 100755
index 0000000..f68b931
--- /dev/null
+++ b/tests/generic/390
@@ -0,0 +1,192 @@
+#! /bin/bash
+# FS QA Test 390
+#
+# Tests to verify policy for filesystem timestamps for
+# supported ranges:
+# 1. Verify filesystem rw mount according to sysctl
+# timestamp_supported.
+# 2. Verify timestamp clamping for timestamps beyond max
+# timestamp supported.
+#
+# Exit status 1: either or both tests above fail.
+# Exit status 0: both the above tests pass.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2016 Deepa Dinamani. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#-----------------------------------------------------------------------
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "exit \$status" 0 1 2 3 15
+
+# Get standard environment, filters and checks.
+. ./common/rc
+. ./common/filter
+. ./common/attr
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# Prerequisites for the test run.
+_supported_fs generic
+_supported_os Linux
+_require_scratch
+_require_xfs_io_command utimes
+
+# Compare file timestamps obtained from stat
+# with a given timestamp.
+check_stat()
+{
+ file=$1
+ timestamp=$2
+
+ stat_timestamp=`stat -c"%X;%Y" $file`
+
+ prev_timestamp="$timestamp;$timestamp"
+ if [ $prev_timestamp != $stat_timestamp ]; then
+ echo "$prev_timestamp != $stat_timestamp" | tee -a $seqres.full
+ fi
+}
+
+run_test_individual()
+{
+ file=$1
+ timestamp=$2
+ update_time=$3
+
+ #check if the time needs update
+ if [ $update_time -eq 1 ]; then
+ echo "Updating file: $file to timestamp `date -d @$timestamp`" >> $seqres.full
+ $XFS_IO_PROG -f -c "utimes $timestamp 0 $timestamp 0" $file
+ if [ $? -ne 0 ]; then
+ echo "Failed to update times on $file" | tee -a $seqres.full
+ fi
+ fi
+
+ tsclamp=$(($timestamp>$tsmax?$tsmax:$timestamp))
+ echo "Checking file: $file Updated timestamp is `date -d @$tsclamp`" >> $seqres.full
+ check_stat $file $tsclamp
+}
+
+run_test()
+{
+ update_time=$1
+
+ n=1
+
+ for TIME in "${TIMESTAMPS[@]}"
+ do
+ #Run the test
+ run_test_individual ${SCRATCH_MNT}/test_$n $TIME $update_time
+
+ #update iterator
+ ((n++))
+ done
+}
+
+_scratch_mkfs &>> $seqres.full 2>&1 || _fail "mkfs failed"
+_require_y2038 $SCRATCH_DEV
+
+read tsmin tsmax <<<$(_filesystem_timestamp_range $SCRATCH_DEV)
+echo min supported timestamp $tsmin $(date --date=@$tsmin) >> $seqres.full
+echo max supported timestamp $tsmax $(date --date=@$tsmax) >> $seqres.full
+
+# Test timestamps array
+
+declare -a TIMESTAMPS=(
+ $tsmin
+ 0
+ $tsmax
+ $((tsmax+1))
+ 4294967295
+ 8589934591
+ 34359738367
+)
+
+# Max timestamp is hardcoded to Mon Jan 18 19:14:07 PST 2038
+sys_tsmax=2147483647
+echo "max timestamp that needs to be supported by fs for rw mount is" \
+ "$((sys_tsmax+1)) $(date --date=@$((sys_tsmax+1)))" >> $seqres.full
+
+read ts_check <<<$(cat /proc/sys/fs/fs-timestamp-check-on)
+
+_scratch_mount
+result=$?
+
+if [ $ts_check -ne 0 ]; then
+ echo "sysctl filesystem timestamp check is on" >> $seqres.full
+ # check for mount failure if the minimum requirement for max timestamp
+ # supported is not met.
+ if [ $sys_tsmax -ge $tsmax ]; then
+ if [ $result -eq 0 ]; then
+ echo "mount test failed" | tee -a $seqres.full
+ exit
+ fi
+ else
+ if [ $result -ne 0 ]; then
+ echo "failed to mount $SCRATCH_DEV" | tee -a $seqres.full
+ exit
+ fi
+ fi
+else
+ # if sysctl switch is off then mount should succeed always.
+ echo "sysctl filesystem timestamp check is off" >> $seqres.full
+ if [ $result -ne 0 ]; then
+ echo "failed to mount $SCRATCH_DEV and timestamp check is off" >> $seqres.full
+ exit
+ fi
+fi
+
+# Begin test case 1
+echo "In memory timestamps update test start" >> $seqres.full
+
+# update time on the file
+update_time=1
+
+run_test $update_time
+
+echo "In memory timestamps update complete" >> $seqres.full
+
+echo "Unmounting and mounting scratch $SCRATCH_MNT" >> $seqres.full
+
+# unmount and remount $SCRATCH_DEV
+_scratch_cycle_mount
+
+# Begin test case 2
+
+n=1
+
+# Do not update time on the file this time, just read from disk
+update_time=0
+
+echo "On disk timestamps update test start" >> $seqres.full
+
+# Re-run test
+run_test $update_time
+
+echo "On disk timestamps update test complete" >> $seqres.full
+
+echo "y2038 inode timestamp tests completed successfully"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/390.out b/tests/generic/390.out
new file mode 100644
index 0000000..82bd4eb
--- /dev/null
+++ b/tests/generic/390.out
@@ -0,0 +1,2 @@
+QA output created by 390
+y2038 inode timestamp tests completed successfully
diff --git a/tests/generic/group b/tests/generic/group
index 08007d7..d137d01 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -392,3 +392,4 @@
387 auto clone
388 auto log metadata
389 auto quick acl
+390 auto quick rw
--
2.7.4
The series is aimed at making input events y2038 safe.
It extends the lifetime of the realtime timestamps in the
events to year 2106.
The series is also a necessary update as glibc is set to provide
64 bit time_t support for 32 bit binaries. glibc plan is detailed
at https://sourceware.org/glibc/wiki/Y2038ProofnessDesign .
The series is a result of discussions with Arnd Bergmann and
Dmitry Torokhov at last Plumbers.
The plan is to deprecate realtime timestamps anyway as they
are not appropriate for these timestamps as noted in the patch
a80b83b7b8 by John Stultz.
The design also updates the format of the input events read/ written
to the device nodes. This breaks 32 bit interface to the input
events at compile time as preferred by the maintainer.
The userspace library changes to libevdev, libuinput and mtdev
will be posted to the respective mailing groups for review.
Changes from v4:
* Dropped serio hil patch
Changes from v3:
* Updated uinput to support monotonic time only
* Addressed review comments
Changes from v2:
* Updated the design to break 32 bit interfaces at compile time.
Changes from v1:
* Updated changes according to review comments.
* Posted userspace library changes that go along with the series.
Deepa Dinamani (3):
uinput: Use monotonic times for uinput timestamps.
input: evdev: Replace timeval with timespec64
input: Deprecate real timestamps beyond year 2106
drivers/input/evdev.c | 43 +++++++++++++++++++++++++++----------------
drivers/input/input-compat.c | 11 ++++++-----
drivers/input/input-compat.h | 3 ++-
drivers/input/misc/uinput.c | 5 ++++-
include/uapi/linux/input.h | 12 +++++++++++-
5 files changed, 50 insertions(+), 24 deletions(-)
base-commit: 0c1f9d81ac360d8ad31cbfd2bdcf44de8204188e
--
2.14.1
The series is a preparation series for individual architectures
to use 64 bit time_t syscalls in compat and 32 bit emulation modes.
This is a follow up to the series Arnd Bergmann posted:
https://sourceware.org/ml/libc-alpha/2015-05/msg00070.html [1]
Big picture is as per the lwn article:
https://lwn.net/Articles/643234/ [2]
The series is directed at converting posix clock syscalls:
clock_gettime, clock_settime, clock_getres and clock_nanosleep
to use a new data structure __kernel_timespec at syscall boundaries.
__kernel_timespec maintains 64 bit time_t across all execution modes.
vdso will be handled as part of each architecture when they enable
support for 64 bit time_t.
The compat syscalls are repurposed to provide backward compatibility
by using them as native syscalls as well for 32 bit architectures.
They will continue to use timespec at syscall boundaries.
CONFIG_64_BIT_TIME controls whether the syscalls use __kernel_timespec
or timespec at syscall boundaries.
The series does the following:
1. Enable compat syscalls on 32 bit architectures.
2. Add a new __kernel_timespec type to be used as the data structure
for all the new syscalls.
3. Add new config CONFIG_64BIT_TIME(intead of the CONFIG_COMPAT_TIME in
[1] and [2] to switch to new definition of __kernel_timespec. It is
the same as struct timespec otherwise.
4. Add new CONFIG_32BIT_TIME to conditionally compile compat syscalls.
* Changes since v1:
* Introduce CONFIG_32BIT_TIME
* Fixed zeroing out of higher order bits of tv_nsec
* Included Arnd's changes to fix up use of compat headers
I decided against using LEGACY_TIME_SYSCALLS to conditionally compile
legacy time syscalls such as sys_nanosleep because this will need to
enclose compat_sys_nanosleep as well. So, defining it as
config LEGACY_TIME_SYSCALLS
def_bool 64BIT || !64BIT_TIME
will not include compat_sys_nanosleep. We will instead need a new config to
exclusively mark legacy syscalls.
Deepa Dinamani (10):
compat: Make compat helpers independent of CONFIG_COMPAT
include: Move compat_timespec/ timeval to compat_time.h
compat: enable compat_get/put_timespec64 always
arch: introduce CONFIG_64BIT_TIME
arch: Introduce CONFIG_COMPAT_32BIT_TIME
posix-clocks: Make compat syscalls depend on CONFIG_COMPAT_32BIT_TIME
include: Add new y2038 safe __kernel_timespec
fix get_timespec64() for y2038 safe compat interfaces
change time types to new y2038 safe __kernel_* types
nanosleep: change time types to safe __kernel_* types
arch/Kconfig | 18 +++++++
arch/arm64/include/asm/compat.h | 11 ----
arch/arm64/include/asm/stat.h | 1 +
arch/arm64/kernel/hw_breakpoint.c | 1 -
arch/arm64/kernel/perf_regs.c | 2 +-
arch/arm64/kernel/process.c | 1 -
arch/mips/include/asm/compat.h | 11 ----
arch/mips/kernel/signal32.c | 2 +-
arch/parisc/include/asm/compat.h | 11 ----
arch/powerpc/include/asm/compat.h | 11 ----
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/oprofile/backtrace.c | 2 +-
arch/s390/hypfs/hypfs_sprp.c | 1 -
arch/s390/include/asm/compat.h | 11 ----
arch/s390/include/asm/elf.h | 3 +-
arch/s390/kvm/priv.c | 1 -
arch/s390/pci/pci_clp.c | 1 -
arch/sparc/include/asm/compat.h | 11 ----
arch/tile/include/asm/compat.h | 11 ----
arch/x86/events/core.c | 2 +-
arch/x86/include/asm/compat.h | 11 ----
arch/x86/include/asm/ftrace.h | 2 +-
arch/x86/include/asm/sys_ia32.h | 2 +-
arch/x86/kernel/sys_x86_64.c | 2 +-
drivers/s390/block/dasd_ioctl.c | 1 -
drivers/s390/char/fs3270.c | 1 -
drivers/s390/char/sclp_ctl.c | 1 -
drivers/s390/char/vmcp.c | 1 -
drivers/s390/cio/chsc_sch.c | 1 -
drivers/s390/net/qeth_core_main.c | 2 +-
drivers/staging/pi433/pi433_if.c | 2 +-
include/linux/compat.h | 11 ++--
include/linux/compat_time.h | 23 +++++++++
include/linux/restart_block.h | 7 +--
include/linux/syscalls.h | 12 ++---
include/linux/time.h | 4 +-
include/linux/time64.h | 10 +++-
include/uapi/asm-generic/posix_types.h | 1 +
include/uapi/linux/time.h | 7 +++
kernel/Makefile | 2 +-
kernel/compat.c | 92 ++++++++++++++++++----------------
kernel/time/hrtimer.c | 10 ++--
kernel/time/posix-stubs.c | 12 +++--
kernel/time/posix-timers.c | 24 ++++++---
kernel/time/time.c | 10 +++-
45 files changed, 175 insertions(+), 190 deletions(-)
create mode 100644 include/linux/compat_time.h
base-commit: b0a84f19a5161418d4360cd57603e94ed489915e
--
2.14.1
Cc: acme(a)kernel.org
Cc: benh(a)kernel.crashing.org
Cc: borntraeger(a)de.ibm.com
Cc: catalin.marinas(a)arm.com
Cc: cmetcalf(a)mellanox.com
Cc: cohuck(a)redhat.com
Cc: davem(a)davemloft.net
Cc: deller(a)gmx.de
Cc: devel(a)driverdev.osuosl.org
Cc: gerald.schaefer(a)de.ibm.com
Cc: gregkh(a)linuxfoundation.org
Cc: heiko.carstens(a)de.ibm.com
Cc: hoeppner(a)linux.vnet.ibm.com
Cc: hpa(a)zytor.com
Cc: jejb(a)parisc-linux.org
Cc: jwi(a)linux.vnet.ibm.com
Cc: linux-api(a)vger.kernel.org
Cc: linux-arch(a)vger.kernel.org
Cc: linux-kernel(a)vger.kernel.org
Cc: linux-mips(a)linux-mips.org
Cc: linux-parisc(a)vger.kernel.org
Cc: linuxppc-dev(a)lists.ozlabs.org
Cc: linux-s390(a)vger.kernel.org
Cc: mark.rutland(a)arm.com
Cc: mingo(a)redhat.com
Cc: mpe(a)ellerman.id.au
Cc: oberpar(a)linux.vnet.ibm.com
Cc: oprofile-list(a)lists.sf.net
Cc: paulus(a)samba.org
Cc: peterz(a)infradead.org
Cc: ralf(a)linux-mips.org
Cc: rostedt(a)goodmis.org
Cc: rric(a)kernel.org
Cc: schwidefsky(a)de.ibm.com
Cc: sebott(a)linux.vnet.ibm.com
Cc: sparclinux(a)vger.kernel.org
Cc: sth(a)linux.vnet.ibm.com
Cc: ubraun(a)linux.vnet.ibm.com
Cc: will.deacon(a)arm.com
Cc: x86(a)kernel.org
The series is aimed at making input events y2038 safe.
It extends the lifetime of the realtime timestamps in the
events to year 2106.
The series is also a necessary update as glibc is set to provide
64 bit time_t support for 32 bit binaries. glibc plan is detailed
at https://sourceware.org/glibc/wiki/Y2038ProofnessDesign .
The series is a result of discussions with Arnd Bergmann and
Dmitry Torokhov at last Plumbers.
The plan is to deprecate realtime timestamps anyway as they
are not appropriate for these timestamps as noted in the patch
a80b83b7b8 by John Stultz.
The design also updates the format of the input events read/ written
to the device nodes. This breaks 32 bit interface to the input
events at compile time as preferred by the maintainer.
The userspace library changes to libevdev, libuinput and mtdev
will be posted to the respective mailing groups for review.
Changes from v3:
* Updated uinput to support monotonic time only
* Addressed review comments
Changes from v2:
* Updated the design to break 32 bit interfaces at compile time.
Changes from v1:
* Updated changes according to review comments.
* Posted userspace library changes that go along with the series.
Deepa Dinamani (4):
uinput: Use monotonic times for uinput timestamps.
input: evdev: Replace timeval with timespec64
input: Deprecate real timestamps beyond year 2106
input: serio: Replace timeval by timespec64
drivers/input/evdev.c | 43 +++++++++++++++++++++++++---------------
drivers/input/input-compat.c | 11 +++++-----
drivers/input/input-compat.h | 3 ++-
drivers/input/misc/uinput.c | 5 ++++-
drivers/input/serio/hil_mlc.c | 37 +++++++++++++++++-----------------
drivers/input/serio/hp_sdc.c | 17 ++++++++--------
drivers/input/serio/hp_sdc_mlc.c | 10 +++++-----
include/linux/hil_mlc.h | 6 +++---
include/linux/hp_sdc.h | 6 +++---
include/uapi/linux/input.h | 12 ++++++++++-
10 files changed, 88 insertions(+), 62 deletions(-)
base-commit: b0a84f19a5161418d4360cd57603e94ed489915e
--
2.14.1
There is a stale entry in i40iw_cm_tcp_context that apparently
was copied from the 'nes' driver but never used in i40iw.
I'm trying to kill off all users of timeval as part of the
y2038-safety work, so let's just remove this one.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/infiniband/hw/i40iw/i40iw_cm.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.h b/drivers/infiniband/hw/i40iw/i40iw_cm.h
index 0d5840d2c4fc..1577608fc51a 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_cm.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_cm.h
@@ -276,8 +276,6 @@ struct i40iw_cm_tcp_context {
u32 mss;
u8 snd_wscale;
u8 rcv_wscale;
-
- struct timeval sent_ts;
};
enum i40iw_cm_listener_state {
--
2.9.0
getnstimeofday() suffers from the overflow in y2038 on 32-bit
architectures and requires a conversion into the nanosecond format that
we want here.
This changes ssp_parse_dataframe() to use ktime_get_real_ns() directly,
which does not have that problem.
An open question is what time base should be used here. Normally
timestamps should use ktime_get_ns() or ktime_get_boot_ns() to read
monotonic time instead of "real" time, which suffers from time jumps
due to settimeofday() calls or leap seconds.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/iio/common/ssp_sensors/ssp_spi.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/iio/common/ssp_sensors/ssp_spi.c b/drivers/iio/common/ssp_sensors/ssp_spi.c
index 704284a475ae..2ab106bb3e03 100644
--- a/drivers/iio/common/ssp_sensors/ssp_spi.c
+++ b/drivers/iio/common/ssp_sensors/ssp_spi.c
@@ -277,12 +277,9 @@ static int ssp_handle_big_data(struct ssp_data *data, char *dataframe, int *idx)
static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len)
{
int idx, sd;
- struct timespec ts;
struct ssp_sensor_data *spd;
struct iio_dev **indio_devs = data->sensor_devs;
- getnstimeofday(&ts);
-
for (idx = 0; idx < len;) {
switch (dataframe[idx++]) {
case SSP_MSG2AP_INST_BYPASS_DATA:
@@ -329,7 +326,7 @@ static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len)
}
if (data->time_syncing)
- data->timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
+ data->timestamp = ktime_get_real_ns();
return 0;
}
--
2.9.0
The series is a preparation series for individual architectures
to use 64 bit time_t syscalls in compat and 32 bit emulation modes.
This is a follow up to the series Arnd Bergmann posted:
https://sourceware.org/ml/libc-alpha/2015-05/msg00070.html
Big picture is as per the lwn article:
https://lwn.net/Articles/643234/
The series is directed at converting posix clock syscalls:
clock_gettime, clock_settime, clock_getres and clock_nanosleep
to use a new data structure __kernel_timespec at syscall boundaries.
__kernel_timespec maintains 64 bit time_t across all execution modes.
vdso will be handled as part of each architecture when they enable
support for 64 bit time_t.
The compat syscalls are repurposed to provide backward compatibility
by using them as native syscalls as well for 32 bit architectures.
They will continue to use timespec at syscall boundaries.
CONFIG_64_BIT_TIME controls whether the syscalls use __kernel_timespec
or timespec at syscall boundaries.
The series does the following:
1. Enable compat syscalls unconditionally.
2. Add a new __kernel_timespec type to be used as the data structure
for all the new syscalls.
3. Add new config CONFIG_64BIT_TIME(intead of the CONFIG_COMPAT_TIME in
[1] and [2] to switch to new definition of __kernel_timespec. It is
the same as struct timespec otherwise.
Arnd Bergmann (1):
y2038: introduce CONFIG_64BIT_TIME
Deepa Dinamani (8):
include: Move compat_timespec/ timeval to compat_time.h
compat: Make compat helpers independent of CONFIG_COMPAT
compat: enable compat_get/put_timespec64 always
posix-clocks: Enable compat syscalls always
include: Add new y2038 safe __kernel_timespec
fix get_timespec64() for y2038 safe compat interfaces
change time types to new y2038 safe __kernel_* types
nanosleep: change time types to safe __kernel_* types
arch/Kconfig | 11 ++++
arch/arm64/include/asm/compat.h | 11 ----
arch/arm64/include/asm/stat.h | 1 +
arch/arm64/kernel/hw_breakpoint.c | 1 -
arch/arm64/kernel/perf_regs.c | 2 +-
arch/arm64/kernel/process.c | 1 -
arch/mips/include/asm/compat.h | 11 ----
arch/mips/kernel/signal32.c | 2 +-
arch/parisc/include/asm/compat.h | 11 ----
arch/powerpc/include/asm/compat.h | 11 ----
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/oprofile/backtrace.c | 2 +-
arch/s390/hypfs/hypfs_sprp.c | 1 -
arch/s390/include/asm/compat.h | 11 ----
arch/s390/include/asm/elf.h | 3 +-
arch/s390/kvm/priv.c | 1 -
arch/s390/pci/pci_clp.c | 1 -
arch/sparc/include/asm/compat.h | 11 ----
arch/tile/include/asm/compat.h | 11 ----
arch/x86/events/core.c | 2 +-
arch/x86/include/asm/compat.h | 11 ----
arch/x86/include/asm/ftrace.h | 2 +-
arch/x86/include/asm/sys_ia32.h | 2 +-
arch/x86/kernel/sys_x86_64.c | 2 +-
drivers/s390/block/dasd_ioctl.c | 1 -
drivers/s390/char/fs3270.c | 1 -
drivers/s390/char/sclp_ctl.c | 1 -
drivers/s390/char/vmcp.c | 1 -
drivers/s390/cio/chsc_sch.c | 1 -
drivers/s390/net/qeth_core_main.c | 2 +-
drivers/staging/pi433/pi433_if.c | 2 +-
include/linux/compat.h | 7 ++-
include/linux/compat_time.h | 23 +++++++++
include/linux/restart_block.h | 7 +--
include/linux/syscalls.h | 12 ++---
include/linux/time.h | 4 +-
include/linux/time64.h | 10 +++-
include/uapi/asm-generic/posix_types.h | 1 +
include/uapi/linux/time.h | 7 +++
kernel/Makefile | 2 +-
kernel/compat.c | 92 ++++++++++++++++++----------------
kernel/time/hrtimer.c | 7 +--
kernel/time/posix-stubs.c | 12 ++---
kernel/time/posix-timers.c | 20 ++++----
kernel/time/time.c | 10 +++-
45 files changed, 152 insertions(+), 195 deletions(-)
create mode 100644 include/linux/compat_time.h
base-commit: d9e0e63d9a6f88440eb201e1491fcf730272c706
--
2.11.0
Cc: acme(a)kernel.org
Cc: benh(a)kernel.crashing.org
Cc: borntraeger(a)de.ibm.com
Cc: catalin.marinas(a)arm.com
Cc: cmetcalf(a)mellanox.com
Cc: cohuck(a)redhat.com
Cc: davem(a)davemloft.net
Cc: deller(a)gmx.de
Cc: devel(a)driverdev.osuosl.org
Cc: gerald.schaefer(a)de.ibm.com
Cc: gregkh(a)linuxfoundation.org
Cc: heiko.carstens(a)de.ibm.com
Cc: hoeppner(a)linux.vnet.ibm.com
Cc: hpa(a)zytor.com
Cc: jejb(a)parisc-linux.org
Cc: jwi(a)linux.vnet.ibm.com
Cc: linux-api(a)vger.kernel.org
Cc: linux-arch(a)vger.kernel.org
Cc: linux-kernel(a)vger.kernel.org
Cc: linux-mips(a)linux-mips.org
Cc: linux-parisc(a)vger.kernel.org
Cc: linuxppc-dev(a)lists.ozlabs.org
Cc: linux-s390(a)vger.kernel.org
Cc: mark.rutland(a)arm.com
Cc: mingo(a)redhat.com
Cc: mpe(a)ellerman.id.au
Cc: oberpar(a)linux.vnet.ibm.com
Cc: oprofile-list(a)lists.sf.net
Cc: paulus(a)samba.org
Cc: peterz(a)infradead.org
Cc: ralf(a)linux-mips.org
Cc: rostedt(a)goodmis.org
Cc: rric(a)kernel.org
Cc: schwidefsky(a)de.ibm.com
Cc: sebott(a)linux.vnet.ibm.com
Cc: sparclinux(a)vger.kernel.org
Cc: sth(a)linux.vnet.ibm.com
Cc: ubraun(a)linux.vnet.ibm.com
Cc: will.deacon(a)arm.com
Cc: x86(a)kernel.org