Hi,
> This patch replaces auto generated wrapper (as described in
> sysdeps/unix/sysv/linux/syscalls.list) for clock_adjtime with one
> which adds extra support for reading 64 bit time values on machines
> with __TIMESIZE != 64.
>
> To achieve this goal new __clock_adjtime64 explicit 64 bit function
> for adjusting Linux clock has been added.
> Moreover, a 32 bit version - __clock_adjtime has been refactored to
> internally use __clock_adjtime64.
>
> The __clock_adjtime is now supposed to be used on systems still
> supporting 32 bit time (__TIMESIZE != 64) - hence the necessary
> conversions between 64 bit struct __timespec64 and struct timespec.
>
> The new __clock_adjtime64 syscall available from Linux 5.1+ has been
> used, when applicable.
> Up till v5.4 in the Linux kernel there was a bug preventing this call
> from obtaining correct struct's timex time.tv_sec time after time_t
> overflow (i.e. not being Y2038 safe).
>
> Build tests:
> - ./src/scripts/build-many-glibcs.py glibcs
>
> Run-time tests:
> - Run specific tests on ARM/x86 32bit systems (qemu):
> https://github.com/lmajewski/meta-y2038 and run tests:
> https://github.com/lmajewski/y2038-tests/commits/master
>
> Linux kernel, headers and minimal kernel version for glibc build test
> matrix:
> - Linux v5.1 (with clock_adjtime64) and glibc build with v5.1 as
> minimal kernel version (--enable-kernel="5.1.0")
> The __ASSUME_TIME64_SYSCALLS flag defined.
>
> - Linux v5.1 and default minimal kernel version
> The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports
> clock_adjtime64 syscall.
>
> - Linux v4.19 (no clock_adjtime64 support) with default minimal
> kernel version for contemporary glibc (3.2.0)
> This kernel doesn't support clock_adjtime64 syscall, so the
> fallback to clock_adjtime is tested.
>
> Above tests were performed with Y2038 redirection applied as well as
> without (so the __TIMESIZE != 64 execution path is checked as well).
>
> No regressions were observed.
>
> Changes for v2:
> - Fix wrong indentation
> - Remove the check for (ret >= TIME_OK && ret <= TIME_ERROR) in the
> clock_adjtime64 call - just check if syscall returned ENOSYS
> - Add 64 bit time overflow for ADJ_SETOFFSET set in modes
Adhemerval, is this patch OK for pulling? Shall I change anything?
> ---
> sysdeps/unix/sysv/linux/Makefile | 2 +-
> sysdeps/unix/sysv/linux/clock_adjtime.c | 71
> +++++++++++++++++++++ sysdeps/unix/sysv/linux/include/sys/timex.h |
> 3 + sysdeps/unix/sysv/linux/syscalls.list | 1 -
> 4 files changed, 75 insertions(+), 2 deletions(-)
> create mode 100644 sysdeps/unix/sysv/linux/clock_adjtime.c
>
> diff --git a/sysdeps/unix/sysv/linux/Makefile
> b/sysdeps/unix/sysv/linux/Makefile index 0326f92c40..2f2fd5d4d0 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -60,7 +60,7 @@ sysdep_routines += adjtimex clone umount umount2
> readahead sysctl \ personality epoll_wait tee vmsplice splice \
> open_by_handle_at mlock2 pkey_mprotect pkey_set
> pkey_get \ timerfd_gettime timerfd_settime prctl \
> - process_vm_readv process_vm_writev
> + process_vm_readv process_vm_writev clock_adjtime
>
> CFLAGS-gethostid.c = -fexceptions
> CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
> diff --git a/sysdeps/unix/sysv/linux/clock_adjtime.c
> b/sysdeps/unix/sysv/linux/clock_adjtime.c new file mode 100644
> index 0000000000..5c02031bb5
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/clock_adjtime.c
> @@ -0,0 +1,71 @@
> +/* clock_adjtime -- tune kernel clock
> + Copyright (C) 2020 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> License as
> + published by the Free Software Foundation; either version 2.1 of
> the
> + License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be
> useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; see the file COPYING.LIB.
> If
> + not, see . */
> +
> +#include
> +#include
> +#include
> +#include
> +#include
> +#include
> +
> +int
> +__clock_adjtime64 (const clockid_t clock_id, struct __timex64 *tx64)
> +{
> +#ifdef __ASSUME_TIME64_SYSCALLS
> +# ifndef __NR_clock_adjtime64
> +# define __NR_clock_adjtime64 __NR_clock_adjtime
> +# endif
> + return INLINE_SYSCALL_CALL (clock_adjtime64, clock_id, tx64);
> +#else
> + int ret = INLINE_SYSCALL_CALL (clock_adjtime64, clock_id, tx64);
> + if (errno != ENOSYS)
> + return ret;
> +
> + if (tx64->modes & ADJ_SETOFFSET
> + && ! in_time_t_range (tx64->time.tv_sec))
> + {
> + __set_errno (EOVERFLOW);
> + return -1;
> + }
> +
> + struct timex tx32 = valid_timex64_to_timex (*tx64);
> + int retval = INLINE_SYSCALL_CALL (clock_adjtime, clock_id, &tx32);
> + *tx64 = valid_timex_to_timex64 (tx32);
> +
> + return retval;
> +#endif
> +}
> +
> +#if __TIMESIZE != 64
> +libc_hidden_def (__clock_adjtime64)
> +
> +int
> +__clock_adjtime (const clockid_t clock_id, struct timex *tx)
> +{
> + struct __timex64 tx64;
> + int retval;
> +
> + tx64 = valid_timex_to_timex64 (*tx);
> + retval = __clock_adjtime64 (clock_id, &tx64);
> + *tx = valid_timex64_to_timex (tx64);
> +
> + return retval;
> +}
> +#endif
> +libc_hidden_def (__clock_adjtime);
> +strong_alias (__clock_adjtime, clock_adjtime)
> diff --git a/sysdeps/unix/sysv/linux/include/sys/timex.h
> b/sysdeps/unix/sysv/linux/include/sys/timex.h index
> 3efe7cd306..2848c5cf76 100644 ---
> a/sysdeps/unix/sysv/linux/include/sys/timex.h +++
> b/sysdeps/unix/sysv/linux/include/sys/timex.h @@ -30,6 +30,7 @@
> libc_hidden_proto (__adjtimex) /* Local definition of 64 bit time
> supporting timex struct */ # if __TIMESIZE == 64
> # define __timex64 timex
> +# define __clock_adjtime64 __clock_adjtime
> # else
>
> struct __timex64
> @@ -71,6 +72,8 @@ struct __timex64
> int :32;
> int :32;
> };
> +extern int __clock_adjtime64 (const clockid_t clock_id, struct
> __timex64 *tx64); +libc_hidden_proto (__clock_adjtime64);
> # endif
>
> /* Convert a known valid struct timex into a struct __timex64. */
> diff --git a/sysdeps/unix/sysv/linux/syscalls.list
> b/sysdeps/unix/sysv/linux/syscalls.list index 1d8893d1b8..01ec2bfa95
> 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/syscalls.list
> @@ -4,7 +4,6 @@ alarm - alarm
> i:i alarm bdflush EXTRA bdflush
> i:ii __compat_bdflush
> bdflush@GLIBC_2.0:GLIBC_2.23 capget EXTRA
> capget i:pp capget capset
> EXTRA capset i:pp capset
> -clock_adjtime EXTRA clock_adjtime i:ip
> __clock_adjtime clock_adjtime create_module
> EXTRA create_module 3
> __compat_create_module create_module@GLIBC_2.0:GLIBC_2.23
> delete_module EXTRA delete_module 3
> delete_module epoll_create EXTRA epoll_create
> i:i epoll_create
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de