y2038: Introduce __ASSUME_TIME64_SYSCALLS define

Message ID 20190508155608.24791-1-lukma@denx.de
State Superseded
Headers

Commit Message

Lukasz Majewski May 8, 2019, 3:56 p.m. UTC
  This define indicates if the Linux kernel (5.1+) provides syscalls supporting
64 bit versions of struct timespec and timeval.

For architectures with __WORDSIZE==64 && __TIMESIZE==64 (e.g. x86_64, aarch64
this flag is never defined (as those already use 64 bit versions of struct
timespec and timeval).

The __ASSUME_TIME64_SYSCALLS shall be only defined on systems with
__WORDSIZE==32.

For x32 this flag is explicitly undefined as this architecture has
64 bit registers but only 32 bit longs and pointers. Moreover, it uses
syscalls from x86_64.

* sysdeps/unix/sysv/linux/kernel-features.h: (__ASSUME_TIME64_SYSCALLS):
[__LINUX_KERNEL_VERSION >= 0x050100]: Define.
* sysdeps/unix/sysv/linux/x86_64/kernel-features.h (__ASSUME_TIME64_SYSCALLS):
#undef the __ASSUME_TIME64_SYSCALLS for x32 architecture

---
Changes for v4:
- Exclude this patch from the clock_settime64 patch series
- Rewrite the in-code comment
- Change patch description

Changes for v3:
- Provide more detailed and verbose description
- Change name to __ASSUME_TIME64_SYSCALLS
- Undefine __ASSUME_TIME64_SYSCALLS on x32

Changes for v2:
- New patch
---
 sysdeps/unix/sysv/linux/kernel-features.h        | 38 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/kernel-features.h |  9 ++++++
 2 files changed, 47 insertions(+)
  

Comments

Joseph Myers May 9, 2019, 3:58 p.m. UTC | #1
On Wed, 8 May 2019, Lukasz Majewski wrote:

> For x32 this flag is explicitly undefined as this architecture has
> 64 bit registers but only 32 bit longs and pointers. Moreover, it uses
> syscalls from x86_64.

The first sentence there is not an accurate description of the reason for 
undefining this for x32; other ILP32 configurations with 64-bit registers 
don't have this peculiarity.  "Moreover, it uses syscalls from x86_64." 
isn't a good description either; x86_64 has three syscall tables (for 
32-bit compat, x32 and the normal LP64 syscall interface).

> +   Linux kernel, as of version 5.1, provides following set of syscalls,
> +   which accept data based on struct timespec and timeval with 64 bit
> +   tv_sec:

Do any of these actually use timeval?  I thought the idea was that the new 
syscalls for 64-bit time would all use timespec, with it being the 
responsibility of libc to handle conversions to and from timeval as needed 
(e.g. for gettimeofday with _TIME_BITS=64).
  
Stepan Golosunov May 9, 2019, 4:18 p.m. UTC | #2
09.05.2019 в 15:58:38 +0000 Joseph Myers написал:
> On Wed, 8 May 2019, Lukasz Majewski wrote:
> > +   Linux kernel, as of version 5.1, provides following set of syscalls,
> > +   which accept data based on struct timespec and timeval with 64 bit
> > +   tv_sec:
> 
> Do any of these actually use timeval?  I thought the idea was that the new 
> syscalls for 64-bit time would all use timespec, with it being the 
> responsibility of libc to handle conversions to and from timeval as needed 
> (e.g. for gettimeofday with _TIME_BITS=64).

clock_adjtime uses __kernel_timex_timeval, as is explained in
https://lore.kernel.org/lkml/CAK8P3a0OBBEwU044jbe-YK2CmCnpNpUSiCA9uRo-8EwtcUva6g@mail.gmail.com/
  

Patch

diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index bc5c959f58..30e77dd213 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -143,3 +143,41 @@ 
    */
 
 #define __ASSUME_CLONE_DEFAULT 1
+
+#include <bits/wordsize.h>
+#if __WORDSIZE != 64
+/* Support for Linux kernel syscalls, which are able to handle 64 bit
+   time on 32 bit systems (with 'long' and __WORDSIZE equal to 32 bits).
+
+   Linux kernel, as of version 5.1, provides following set of syscalls,
+   which accept data based on struct timespec and timeval with 64 bit
+   tv_sec:
+
+   clock_gettime64
+   clock_settime64
+   clock_adjtime64
+   clock_getres_time64
+   clock_nanosleep_time64
+   timer_gettime64
+   timer_settime64
+   timerfd_gettime64
+   timerfd_settime64
+   utimensat_time64
+   pselect6_time64
+   ppoll_time64
+   io_pgetevents_time64
+   recvmmsg_time64
+   mq_timedsend_time64
+   mq_timedreceive_time64
+   semtimedop_time64
+   rt_sigtimedwait_time64
+   futex_time64
+   sched_rr_get_interval_time64
+
+   Above syscalls are supposed to replace legacy ones, which handle 32
+   bit version of struct timespec and timeval (i.e. without the '64'
+   suffix).  */
+# if __LINUX_KERNEL_VERSION >= 0x050100
+#  define __ASSUME_TIME64_SYSCALLS 1
+# endif
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/kernel-features.h b/sysdeps/unix/sysv/linux/x86_64/kernel-features.h
index 26280f57ec..e1e923f497 100644
--- a/sysdeps/unix/sysv/linux/x86_64/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/x86_64/kernel-features.h
@@ -24,3 +24,12 @@ 
 #endif
 
 #include_next <kernel-features.h>
+
+/* For x32, which is a special case in respect to 64 bit time support,
+   the __ASSUME_TIME64_SYSCALLS define needs to be explicitly undefined.
+
+   It uses Linux time related syscalls for x86_64 (in compatibility
+   mode).  */
+#ifdef __ILP32__
+# undef __ASSUME_TIME64_SYSCALLS
+#endif