* [PATCH 01/12] tools/nolibc: use 64-bit ino_t
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
@ 2025-10-29 16:02 ` Thomas Weißschuh
2025-10-29 16:02 ` [PATCH 02/12] tools/nolibc: handle 64-bit off_t for llseek Thomas Weißschuh
` (11 subsequent siblings)
12 siblings, 0 replies; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:02 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
The kernel uses 64-bit values for inode numbers.
Currently these might be truncated to 32-bit when assigned to
nolibc's ino_t values.
Switch to 64-bit ino_t consistently.
As ino_t is never used directly in kernel ABIs, no systemcall wrappers
need to be adapted.
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/lkml/cec27d94-c99d-4c57-9a12-275ea663dda8@app.fastmail.com/
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/std.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/include/nolibc/std.h b/tools/include/nolibc/std.h
index 2c1ad23b9b5c..eae457d60858 100644
--- a/tools/include/nolibc/std.h
+++ b/tools/include/nolibc/std.h
@@ -20,7 +20,7 @@
/* those are commonly provided by sys/types.h */
typedef unsigned int dev_t;
-typedef unsigned long ino_t;
+typedef uint64_t ino_t;
typedef unsigned int mode_t;
typedef signed int pid_t;
typedef unsigned int uid_t;
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 02/12] tools/nolibc: handle 64-bit off_t for llseek
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
2025-10-29 16:02 ` [PATCH 01/12] tools/nolibc: use 64-bit ino_t Thomas Weißschuh
@ 2025-10-29 16:02 ` Thomas Weißschuh
2025-10-30 14:56 ` Arnd Bergmann
2025-10-29 16:02 ` [PATCH 03/12] tools/nolibc: prefer the llseek syscall Thomas Weißschuh
` (10 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:02 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
Correctly handle 64-bit off_t values in preparation for 64-bit off_t on
32-bit architectures.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/sys.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 386ed80aead0..321a3bd16ff4 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -599,8 +599,7 @@ off_t sys_lseek(int fd, off_t offset, int whence)
off_t result;
int ret;
- /* Only exists on 32bit where nolibc off_t is also 32bit */
- ret = my_syscall5(__NR_llseek, fd, 0, offset, &loff, whence);
+ ret = my_syscall5(__NR_llseek, fd, offset >> 32, (uint32_t)offset, &loff, whence);
if (ret < 0)
result = ret;
else if (loff != (off_t)loff)
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 02/12] tools/nolibc: handle 64-bit off_t for llseek
2025-10-29 16:02 ` [PATCH 02/12] tools/nolibc: handle 64-bit off_t for llseek Thomas Weißschuh
@ 2025-10-30 14:56 ` Arnd Bergmann
0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2025-10-30 14:56 UTC (permalink / raw)
To: Thomas Weißschuh, Willy Tarreau, shuah; +Cc: linux-kernel, linux-kselftest
On Wed, Oct 29, 2025, at 17:02, Thomas Weißschuh wrote:
> Correctly handle 64-bit off_t values in preparation for 64-bit off_t on
> 32-bit architectures.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> tools/include/nolibc/sys.h | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
> index 386ed80aead0..321a3bd16ff4 100644
> --- a/tools/include/nolibc/sys.h
> +++ b/tools/include/nolibc/sys.h
> @@ -599,8 +599,7 @@ off_t sys_lseek(int fd, off_t offset, int whence)
> off_t result;
> int ret;
>
> - /* Only exists on 32bit where nolibc off_t is also 32bit */
> - ret = my_syscall5(__NR_llseek, fd, 0, offset, &loff, whence);
> + ret = my_syscall5(__NR_llseek, fd, offset >> 32, (uint32_t)offset,
> &loff, whence);
Acked-by: Arnd Bergmann <arnd@arndb.de>
This one is easier than some of the others because it passes
the two halves explictly. It's a bit trickier for preadv/pwritev,
preadv2/pwritev2, fallocate, truncate64/ftruncate64, sync_file_range,
and fadvise64/fadvise64_64, all of which have slightly tricky
calling conventions. Not sure if any of these are currently
supported in nolibc.
Arnd
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 03/12] tools/nolibc: prefer the llseek syscall
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
2025-10-29 16:02 ` [PATCH 01/12] tools/nolibc: use 64-bit ino_t Thomas Weißschuh
2025-10-29 16:02 ` [PATCH 02/12] tools/nolibc: handle 64-bit off_t for llseek Thomas Weißschuh
@ 2025-10-29 16:02 ` Thomas Weißschuh
2025-10-29 16:02 ` [PATCH 04/12] tools/nolibc: use 64-bit off_t Thomas Weißschuh
` (9 subsequent siblings)
12 siblings, 0 replies; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:02 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
Make sure to always use the 64-bit safe system call
in preparation for 64-bit off_t on 32 bit architectures.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/sys.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 321a3bd16ff4..58cd2bb0f6ce 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -592,9 +592,7 @@ int link(const char *old, const char *new)
static __attribute__((unused))
off_t sys_lseek(int fd, off_t offset, int whence)
{
-#if defined(__NR_lseek)
- return my_syscall3(__NR_lseek, fd, offset, whence);
-#else
+#if defined(__NR_llseek)
__kernel_loff_t loff = 0;
off_t result;
int ret;
@@ -608,6 +606,8 @@ off_t sys_lseek(int fd, off_t offset, int whence)
result = loff;
return result;
+#else
+ return my_syscall3(__NR_lseek, fd, offset, whence);
#endif
}
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 04/12] tools/nolibc: use 64-bit off_t
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (2 preceding siblings ...)
2025-10-29 16:02 ` [PATCH 03/12] tools/nolibc: prefer the llseek syscall Thomas Weißschuh
@ 2025-10-29 16:02 ` Thomas Weißschuh
2025-10-29 16:02 ` [PATCH 05/12] tools/nolibc: remove now superfluous overflow check in llseek Thomas Weißschuh
` (8 subsequent siblings)
12 siblings, 0 replies; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:02 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
The kernel uses 64-bit values for file offsets.
Currently these might be truncated to 32-bit when assigned to
nolibc's off_t values.
Switch to 64-bit off_t consistently.
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/lkml/cec27d94-c99d-4c57-9a12-275ea663dda8@app.fastmail.com/
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/std.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/include/nolibc/std.h b/tools/include/nolibc/std.h
index eae457d60858..392f4dd94158 100644
--- a/tools/include/nolibc/std.h
+++ b/tools/include/nolibc/std.h
@@ -26,7 +26,7 @@ typedef signed int pid_t;
typedef unsigned int uid_t;
typedef unsigned int gid_t;
typedef unsigned long nlink_t;
-typedef signed long off_t;
+typedef int64_t off_t;
typedef signed long blksize_t;
typedef signed long blkcnt_t;
typedef __kernel_time_t time_t;
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 05/12] tools/nolibc: remove now superfluous overflow check in llseek
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (3 preceding siblings ...)
2025-10-29 16:02 ` [PATCH 04/12] tools/nolibc: use 64-bit off_t Thomas Weißschuh
@ 2025-10-29 16:02 ` Thomas Weißschuh
2025-10-30 14:58 ` Arnd Bergmann
2025-10-29 16:02 ` [PATCH 06/12] tools/nolibc: remove more __nolibc_enosys() fallbacks Thomas Weißschuh
` (7 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:02 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
As off_t is now always 64-bit wide this overflow can not happen anymore,
remove the check.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/sys.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 58cd2bb0f6ce..e91b7d947161 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -600,8 +600,6 @@ off_t sys_lseek(int fd, off_t offset, int whence)
ret = my_syscall5(__NR_llseek, fd, offset >> 32, (uint32_t)offset, &loff, whence);
if (ret < 0)
result = ret;
- else if (loff != (off_t)loff)
- result = -EOVERFLOW;
else
result = loff;
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 06/12] tools/nolibc: remove more __nolibc_enosys() fallbacks
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (4 preceding siblings ...)
2025-10-29 16:02 ` [PATCH 05/12] tools/nolibc: remove now superfluous overflow check in llseek Thomas Weißschuh
@ 2025-10-29 16:02 ` Thomas Weißschuh
2025-10-29 16:02 ` [PATCH 07/12] tools/nolibc: prefer explicit 64-bit time-related system calls Thomas Weißschuh
` (6 subsequent siblings)
12 siblings, 0 replies; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:02 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
Commit e6366101ce1f ("tools/nolibc: remove __nolibc_enosys() fallback
from time64-related functions") removed many of these fallbacks but
forgot a few.
Finish the job.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/time.h | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/tools/include/nolibc/time.h b/tools/include/nolibc/time.h
index 6c276b8d646a..48e78f8becf9 100644
--- a/tools/include/nolibc/time.h
+++ b/tools/include/nolibc/time.h
@@ -89,13 +89,11 @@ int sys_clock_settime(clockid_t clockid, struct timespec *tp)
{
#if defined(__NR_clock_settime)
return my_syscall2(__NR_clock_settime, clockid, tp);
-#elif defined(__NR_clock_settime64)
+#else
struct __kernel_timespec ktp;
__nolibc_timespec_user_to_kernel(tp, &ktp);
return my_syscall2(__NR_clock_settime64, clockid, &ktp);
-#else
- return __nolibc_enosys(__func__, clockid, tp);
#endif
}
@@ -111,7 +109,7 @@ int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqt
{
#if defined(__NR_clock_nanosleep)
return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp);
-#elif defined(__NR_clock_nanosleep_time64)
+#else
struct __kernel_timespec krqtp, krmtp;
int ret;
@@ -120,8 +118,6 @@ int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqt
if (rmtp)
__nolibc_timespec_kernel_to_user(&krmtp, rmtp);
return ret;
-#else
- return __nolibc_enosys(__func__, clockid, flags, rqtp, rmtp);
#endif
}
@@ -195,7 +191,7 @@ int sys_timer_gettime(timer_t timerid, struct itimerspec *curr_value)
{
#if defined(__NR_timer_gettime)
return my_syscall2(__NR_timer_gettime, timerid, curr_value);
-#elif defined(__NR_timer_gettime64)
+#else
struct __kernel_itimerspec kcurr_value;
int ret;
@@ -203,8 +199,6 @@ int sys_timer_gettime(timer_t timerid, struct itimerspec *curr_value)
__nolibc_timespec_kernel_to_user(&kcurr_value.it_interval, &curr_value->it_interval);
__nolibc_timespec_kernel_to_user(&kcurr_value.it_value, &curr_value->it_value);
return ret;
-#else
- return __nolibc_enosys(__func__, timerid, curr_value);
#endif
}
@@ -220,7 +214,7 @@ int sys_timer_settime(timer_t timerid, int flags,
{
#if defined(__NR_timer_settime)
return my_syscall4(__NR_timer_settime, timerid, flags, new_value, old_value);
-#elif defined(__NR_timer_settime64)
+#else
struct __kernel_itimerspec knew_value, kold_value;
int ret;
@@ -232,8 +226,6 @@ int sys_timer_settime(timer_t timerid, int flags,
__nolibc_timespec_kernel_to_user(&kold_value.it_value, &old_value->it_value);
}
return ret;
-#else
- return __nolibc_enosys(__func__, timerid, flags, new_value, old_value);
#endif
}
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 07/12] tools/nolibc: prefer explicit 64-bit time-related system calls
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (5 preceding siblings ...)
2025-10-29 16:02 ` [PATCH 06/12] tools/nolibc: remove more __nolibc_enosys() fallbacks Thomas Weißschuh
@ 2025-10-29 16:02 ` Thomas Weißschuh
2025-10-30 14:44 ` Arnd Bergmann
2025-10-29 16:02 ` [PATCH 08/12] tools/nolibc: gettimeofday(): avoid libgcc 64-bit divisions Thomas Weißschuh
` (5 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:02 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
Make sure to always use the 64-bit safe system calls
in preparation for 64-bit time_t on 32-bit architectures.
Also prevent issues on kernels which disable CONFIG_COMPAT_32BIT_TIME
and therefore don't provide the 32-bit system calls anymore.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/poll.h | 12 ++++++------
tools/include/nolibc/sys.h | 10 +++++-----
tools/include/nolibc/time.h | 36 ++++++++++++++++++------------------
3 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/tools/include/nolibc/poll.h b/tools/include/nolibc/poll.h
index 0d053f93ea99..5ff911b73b34 100644
--- a/tools/include/nolibc/poll.h
+++ b/tools/include/nolibc/poll.h
@@ -23,22 +23,22 @@
static __attribute__((unused))
int sys_poll(struct pollfd *fds, int nfds, int timeout)
{
-#if defined(__NR_ppoll)
- struct timespec t;
+#if defined(__NR_ppoll_time64)
+ struct __kernel_timespec t;
if (timeout >= 0) {
t.tv_sec = timeout / 1000;
t.tv_nsec = (timeout % 1000) * 1000000;
}
- return my_syscall5(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0);
-#elif defined(__NR_ppoll_time64)
- struct __kernel_timespec t;
+ return my_syscall5(__NR_ppoll_time64, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0);
+#elif defined(__NR_ppoll)
+ struct timespec t;
if (timeout >= 0) {
t.tv_sec = timeout / 1000;
t.tv_nsec = (timeout % 1000) * 1000000;
}
- return my_syscall5(__NR_ppoll_time64, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0);
+ return my_syscall5(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0);
#else
return my_syscall3(__NR_poll, fds, nfds, timeout);
#endif
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index e91b7d947161..10c517a38f86 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -772,22 +772,22 @@ int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeva
return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
#elif defined(__NR_select)
return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout);
-#elif defined(__NR_pselect6)
- struct timespec t;
+#elif defined(__NR_pselect6_time64)
+ struct __kernel_timespec t;
if (timeout) {
t.tv_sec = timeout->tv_sec;
t.tv_nsec = timeout->tv_usec * 1000;
}
- return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
+ return my_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
#else
- struct __kernel_timespec t;
+ struct timespec t;
if (timeout) {
t.tv_sec = timeout->tv_sec;
t.tv_nsec = timeout->tv_usec * 1000;
}
- return my_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
+ return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
#endif
}
diff --git a/tools/include/nolibc/time.h b/tools/include/nolibc/time.h
index 48e78f8becf9..45df9b09d7b6 100644
--- a/tools/include/nolibc/time.h
+++ b/tools/include/nolibc/time.h
@@ -43,9 +43,7 @@ void __nolibc_timespec_kernel_to_user(const struct __kernel_timespec *kts, struc
static __attribute__((unused))
int sys_clock_getres(clockid_t clockid, struct timespec *res)
{
-#if defined(__NR_clock_getres)
- return my_syscall2(__NR_clock_getres, clockid, res);
-#else
+#if defined(__NR_clock_getres_time64)
struct __kernel_timespec kres;
int ret;
@@ -53,6 +51,8 @@ int sys_clock_getres(clockid_t clockid, struct timespec *res)
if (res)
__nolibc_timespec_kernel_to_user(&kres, res);
return ret;
+#else
+ return my_syscall2(__NR_clock_getres, clockid, res);
#endif
}
@@ -65,9 +65,7 @@ int clock_getres(clockid_t clockid, struct timespec *res)
static __attribute__((unused))
int sys_clock_gettime(clockid_t clockid, struct timespec *tp)
{
-#if defined(__NR_clock_gettime)
- return my_syscall2(__NR_clock_gettime, clockid, tp);
-#else
+#if defined(__NR_clock_gettime64)
struct __kernel_timespec ktp;
int ret;
@@ -75,6 +73,8 @@ int sys_clock_gettime(clockid_t clockid, struct timespec *tp)
if (tp)
__nolibc_timespec_kernel_to_user(&ktp, tp);
return ret;
+#else
+ return my_syscall2(__NR_clock_gettime, clockid, tp);
#endif
}
@@ -87,13 +87,13 @@ int clock_gettime(clockid_t clockid, struct timespec *tp)
static __attribute__((unused))
int sys_clock_settime(clockid_t clockid, struct timespec *tp)
{
-#if defined(__NR_clock_settime)
- return my_syscall2(__NR_clock_settime, clockid, tp);
-#else
+#if defined(__NR_clock_settime64)
struct __kernel_timespec ktp;
__nolibc_timespec_user_to_kernel(tp, &ktp);
return my_syscall2(__NR_clock_settime64, clockid, &ktp);
+#else
+ return my_syscall2(__NR_clock_settime, clockid, tp);
#endif
}
@@ -107,9 +107,7 @@ static __attribute__((unused))
int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp,
struct timespec *rmtp)
{
-#if defined(__NR_clock_nanosleep)
- return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp);
-#else
+#if defined(__NR_clock_nanosleep_time64)
struct __kernel_timespec krqtp, krmtp;
int ret;
@@ -118,6 +116,8 @@ int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqt
if (rmtp)
__nolibc_timespec_kernel_to_user(&krmtp, rmtp);
return ret;
+#else
+ return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp);
#endif
}
@@ -189,9 +189,7 @@ int timer_delete(timer_t timerid)
static __attribute__((unused))
int sys_timer_gettime(timer_t timerid, struct itimerspec *curr_value)
{
-#if defined(__NR_timer_gettime)
- return my_syscall2(__NR_timer_gettime, timerid, curr_value);
-#else
+#if defined(__NR_timer_gettime64)
struct __kernel_itimerspec kcurr_value;
int ret;
@@ -199,6 +197,8 @@ int sys_timer_gettime(timer_t timerid, struct itimerspec *curr_value)
__nolibc_timespec_kernel_to_user(&kcurr_value.it_interval, &curr_value->it_interval);
__nolibc_timespec_kernel_to_user(&kcurr_value.it_value, &curr_value->it_value);
return ret;
+#else
+ return my_syscall2(__NR_timer_gettime, timerid, curr_value);
#endif
}
@@ -212,9 +212,7 @@ static __attribute__((unused))
int sys_timer_settime(timer_t timerid, int flags,
const struct itimerspec *new_value, struct itimerspec *old_value)
{
-#if defined(__NR_timer_settime)
- return my_syscall4(__NR_timer_settime, timerid, flags, new_value, old_value);
-#else
+#if defined(__NR_timer_settime64)
struct __kernel_itimerspec knew_value, kold_value;
int ret;
@@ -226,6 +224,8 @@ int sys_timer_settime(timer_t timerid, int flags,
__nolibc_timespec_kernel_to_user(&kold_value.it_value, &old_value->it_value);
}
return ret;
+#else
+ return my_syscall4(__NR_timer_settime, timerid, flags, new_value, old_value);
#endif
}
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 07/12] tools/nolibc: prefer explicit 64-bit time-related system calls
2025-10-29 16:02 ` [PATCH 07/12] tools/nolibc: prefer explicit 64-bit time-related system calls Thomas Weißschuh
@ 2025-10-30 14:44 ` Arnd Bergmann
0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2025-10-30 14:44 UTC (permalink / raw)
To: Thomas Weißschuh, Willy Tarreau, shuah; +Cc: linux-kernel, linux-kselftest
On Wed, Oct 29, 2025, at 17:02, Thomas Weißschuh wrote:
> Make sure to always use the 64-bit safe system calls
> in preparation for 64-bit time_t on 32-bit architectures.
>
> Also prevent issues on kernels which disable CONFIG_COMPAT_32BIT_TIME
> and therefore don't provide the 32-bit system calls anymore.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Thanks for working on this!
> -#if defined(__NR_ppoll)
> - struct timespec t;
> +#if defined(__NR_ppoll_time64)
> + struct __kernel_timespec t;
>
> if (timeout >= 0) {
> t.tv_sec = timeout / 1000;
> t.tv_nsec = (timeout % 1000) * 1000000;
> }
> - return my_syscall5(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL,
> NULL, 0);
> + return my_syscall5(__NR_ppoll_time64, fds, nfds, (timeout >= 0) ? &t
This looks good to me.
> -#elif defined(__NR_ppoll_time64)
> - struct __kernel_timespec t;
> : NULL, NULL, 0);
> +#elif defined(__NR_ppoll)
> + struct timespec t;
>
> if (timeout >= 0) {
> t.tv_sec = timeout / 1000;
> t.tv_nsec = (timeout % 1000) * 1000000;
> }
This is not wrong, but for consistency, I would use
__kernel_old_timespec with the old syscall macros, rather
than the nolibc-defined type.
A different approach would be to rely on timespec/timeval/time_t
to always use the 64-bit types and then just pick the time64
macros on 32-bit vs the old macros on 64-bit builds.
> - return my_syscall5(__NR_ppoll_time64, fds, nfds, (timeout >= 0) ? &t
> : NULL, NULL, 0);
> + return my_syscall5(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL,
> NULL, 0);
> #else
> return my_syscall3(__NR_poll, fds, nfds, timeout);
> #endif
I would think that we can remove the final #else clause here
and just use the __NR_ppoll case as #else. It would also make
sense to change the first #if to check for a 32-bit ABI.
> diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
> index e91b7d947161..10c517a38f86 100644
> --- a/tools/include/nolibc/sys.h
> +++ b/tools/include/nolibc/sys.h
> @@ -772,22 +772,22 @@ int sys_select(int nfds, fd_set *rfds, fd_set
> *wfds, fd_set *efds, struct timeva
> return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
> #elif defined(__NR_select)
> return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout);
> -#elif defined(__NR_pselect6)
> - struct timespec t;
> +#elif defined(__NR_pselect6_time64)
> + struct __kernel_timespec t;
These probably need to be flipped around, so that
__NR_pselect6_time64/__NR_pselect6 comes first because the other
ones use the wrong type on 32-bit targets.
Probably also do the same thing here with the #ifdef checking
the architecture instead of the syscall macro.
Arnd
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 08/12] tools/nolibc: gettimeofday(): avoid libgcc 64-bit divisions
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (6 preceding siblings ...)
2025-10-29 16:02 ` [PATCH 07/12] tools/nolibc: prefer explicit 64-bit time-related system calls Thomas Weißschuh
@ 2025-10-29 16:02 ` Thomas Weißschuh
2025-10-30 14:57 ` Arnd Bergmann
2025-11-02 8:31 ` Willy Tarreau
2025-10-29 16:02 ` [PATCH 09/12] tools/nolibc: use a custom struct timespec Thomas Weißschuh
` (4 subsequent siblings)
12 siblings, 2 replies; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:02 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
timespec::tv_nsec is going to be 64-bit wide even on 32-bit
architectures. As not all architectures support 64-bit division
instructions, calls to libgcc (__divdi3()) may be emitted by the
compiler which are not provided by nolibc.
As tv_nsec is guaranteed to always fit into an uint32_t, perform a
32-bit division instead.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/sys/time.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/include/nolibc/sys/time.h b/tools/include/nolibc/sys/time.h
index 33782a19aae9..6dd3705c6c9d 100644
--- a/tools/include/nolibc/sys/time.h
+++ b/tools/include/nolibc/sys/time.h
@@ -33,7 +33,7 @@ int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
ret = sys_clock_gettime(CLOCK_REALTIME, &tp);
if (!ret && tv) {
tv->tv_sec = tp.tv_sec;
- tv->tv_usec = tp.tv_nsec / 1000;
+ tv->tv_usec = (uint32_t)tp.tv_nsec / 1000;
}
return ret;
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 08/12] tools/nolibc: gettimeofday(): avoid libgcc 64-bit divisions
2025-10-29 16:02 ` [PATCH 08/12] tools/nolibc: gettimeofday(): avoid libgcc 64-bit divisions Thomas Weißschuh
@ 2025-10-30 14:57 ` Arnd Bergmann
2025-11-02 8:31 ` Willy Tarreau
1 sibling, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2025-10-30 14:57 UTC (permalink / raw)
To: Thomas Weißschuh, Willy Tarreau, shuah; +Cc: linux-kernel, linux-kselftest
On Wed, Oct 29, 2025, at 17:02, Thomas Weißschuh wrote:
> timespec::tv_nsec is going to be 64-bit wide even on 32-bit
> architectures. As not all architectures support 64-bit division
> instructions, calls to libgcc (__divdi3()) may be emitted by the
> compiler which are not provided by nolibc.
>
> As tv_nsec is guaranteed to always fit into an uint32_t, perform a
> 32-bit division instead.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 08/12] tools/nolibc: gettimeofday(): avoid libgcc 64-bit divisions
2025-10-29 16:02 ` [PATCH 08/12] tools/nolibc: gettimeofday(): avoid libgcc 64-bit divisions Thomas Weißschuh
2025-10-30 14:57 ` Arnd Bergmann
@ 2025-11-02 8:31 ` Willy Tarreau
2025-11-02 9:27 ` Thomas Weißschuh
1 sibling, 1 reply; 27+ messages in thread
From: Willy Tarreau @ 2025-11-02 8:31 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Shuah Khan, Arnd Bergmann, linux-kernel, linux-kselftest
On Wed, Oct 29, 2025 at 05:02:58PM +0100, Thomas Weißschuh wrote:
> timespec::tv_nsec is going to be 64-bit wide even on 32-bit
> architectures. As not all architectures support 64-bit division
> instructions, calls to libgcc (__divdi3()) may be emitted by the
> compiler which are not provided by nolibc.
>
> As tv_nsec is guaranteed to always fit into an uint32_t, perform a
> 32-bit division instead.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> tools/include/nolibc/sys/time.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tools/include/nolibc/sys/time.h b/tools/include/nolibc/sys/time.h
> index 33782a19aae9..6dd3705c6c9d 100644
> --- a/tools/include/nolibc/sys/time.h
> +++ b/tools/include/nolibc/sys/time.h
> @@ -33,7 +33,7 @@ int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
> ret = sys_clock_gettime(CLOCK_REALTIME, &tp);
> if (!ret && tv) {
> tv->tv_sec = tp.tv_sec;
> - tv->tv_usec = tp.tv_nsec / 1000;
> + tv->tv_usec = (uint32_t)tp.tv_nsec / 1000;
> }
Good catch! I'm wondering if this one shouldn't be marked as a build
fix for 5e7392dc82ed ("tools/nolibc: fall back to sys_clock_gettime()
in gettimeofday()") so that it can be backported.
Acked-by: Willy Tarreau <w@1wt.eu>
Willy
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 08/12] tools/nolibc: gettimeofday(): avoid libgcc 64-bit divisions
2025-11-02 8:31 ` Willy Tarreau
@ 2025-11-02 9:27 ` Thomas Weißschuh
2025-11-02 9:49 ` Willy Tarreau
0 siblings, 1 reply; 27+ messages in thread
From: Thomas Weißschuh @ 2025-11-02 9:27 UTC (permalink / raw)
To: Willy Tarreau; +Cc: Shuah Khan, Arnd Bergmann, linux-kernel, linux-kselftest
On 2025-11-02 09:31:56+0100, Willy Tarreau wrote:
> On Wed, Oct 29, 2025 at 05:02:58PM +0100, Thomas Weißschuh wrote:
> > timespec::tv_nsec is going to be 64-bit wide even on 32-bit
> > architectures. As not all architectures support 64-bit division
> > instructions, calls to libgcc (__divdi3()) may be emitted by the
> > compiler which are not provided by nolibc.
> >
> > As tv_nsec is guaranteed to always fit into an uint32_t, perform a
> > 32-bit division instead.
> >
> > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > ---
> > tools/include/nolibc/sys/time.h | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/tools/include/nolibc/sys/time.h b/tools/include/nolibc/sys/time.h
> > index 33782a19aae9..6dd3705c6c9d 100644
> > --- a/tools/include/nolibc/sys/time.h
> > +++ b/tools/include/nolibc/sys/time.h
> > @@ -33,7 +33,7 @@ int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
> > ret = sys_clock_gettime(CLOCK_REALTIME, &tp);
> > if (!ret && tv) {
> > tv->tv_sec = tp.tv_sec;
> > - tv->tv_usec = tp.tv_nsec / 1000;
> > + tv->tv_usec = (uint32_t)tp.tv_nsec / 1000;
> > }
>
> Good catch! I'm wondering if this one shouldn't be marked as a build
> fix for 5e7392dc82ed ("tools/nolibc: fall back to sys_clock_gettime()
> in gettimeofday()") so that it can be backported.
Right now timespec::tv_nsec is of type 'long', so it should only be
64-bits on architectures which have native 64-bit division instructions.
But marking it as fix shouldn't hurt either.
Thomas
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 08/12] tools/nolibc: gettimeofday(): avoid libgcc 64-bit divisions
2025-11-02 9:27 ` Thomas Weißschuh
@ 2025-11-02 9:49 ` Willy Tarreau
0 siblings, 0 replies; 27+ messages in thread
From: Willy Tarreau @ 2025-11-02 9:49 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Shuah Khan, Arnd Bergmann, linux-kernel, linux-kselftest
On Sun, Nov 02, 2025 at 10:27:18AM +0100, Thomas Weißschuh wrote:
> On 2025-11-02 09:31:56+0100, Willy Tarreau wrote:
> > On Wed, Oct 29, 2025 at 05:02:58PM +0100, Thomas Weißschuh wrote:
> > > timespec::tv_nsec is going to be 64-bit wide even on 32-bit
> > > architectures. As not all architectures support 64-bit division
> > > instructions, calls to libgcc (__divdi3()) may be emitted by the
> > > compiler which are not provided by nolibc.
> > >
> > > As tv_nsec is guaranteed to always fit into an uint32_t, perform a
> > > 32-bit division instead.
> > >
> > > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > > ---
> > > tools/include/nolibc/sys/time.h | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/tools/include/nolibc/sys/time.h b/tools/include/nolibc/sys/time.h
> > > index 33782a19aae9..6dd3705c6c9d 100644
> > > --- a/tools/include/nolibc/sys/time.h
> > > +++ b/tools/include/nolibc/sys/time.h
> > > @@ -33,7 +33,7 @@ int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
> > > ret = sys_clock_gettime(CLOCK_REALTIME, &tp);
> > > if (!ret && tv) {
> > > tv->tv_sec = tp.tv_sec;
> > > - tv->tv_usec = tp.tv_nsec / 1000;
> > > + tv->tv_usec = (uint32_t)tp.tv_nsec / 1000;
> > > }
> >
> > Good catch! I'm wondering if this one shouldn't be marked as a build
> > fix for 5e7392dc82ed ("tools/nolibc: fall back to sys_clock_gettime()
> > in gettimeofday()") so that it can be backported.
>
> Right now timespec::tv_nsec is of type 'long', so it should only be
> 64-bits on architectures which have native 64-bit division instructions.
> But marking it as fix shouldn't hurt either.
Ah yeah you're right. Don't bother with that then.
Thanks!
Willy
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 09/12] tools/nolibc: use a custom struct timespec
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (7 preceding siblings ...)
2025-10-29 16:02 ` [PATCH 08/12] tools/nolibc: gettimeofday(): avoid libgcc 64-bit divisions Thomas Weißschuh
@ 2025-10-29 16:02 ` Thomas Weißschuh
2025-10-30 14:46 ` Arnd Bergmann
2025-10-29 16:03 ` [PATCH 10/12] tools/nolibc: always use 64-bit time types Thomas Weißschuh
` (3 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:02 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
A custom 'struct timespec' will be necessary for 64-bit time types on
32-bit architectures. <linux/time.h> will define other time-related
types in terms of the custom definition.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/arch-s390.h | 3 +++
tools/include/nolibc/types.h | 9 ++++++++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/tools/include/nolibc/arch-s390.h b/tools/include/nolibc/arch-s390.h
index 6237211385c0..1e87ac42ab9c 100644
--- a/tools/include/nolibc/arch-s390.h
+++ b/tools/include/nolibc/arch-s390.h
@@ -5,6 +5,9 @@
#ifndef _NOLIBC_ARCH_S390_H
#define _NOLIBC_ARCH_S390_H
+
+#include "types.h"
+
#include <linux/signal.h>
#include <linux/unistd.h>
diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
index 16c6e9ec9451..4f5a25567e5c 100644
--- a/tools/include/nolibc/types.h
+++ b/tools/include/nolibc/types.h
@@ -13,9 +13,16 @@
#include "std.h"
#include <linux/mman.h>
#include <linux/stat.h>
-#include <linux/time.h>
#include <linux/wait.h>
+struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+};
+#define _STRUCT_TIMESPEC
+
+#include <linux/time.h>
+
/* Only the generic macros and types may be defined here. The arch-specific
* ones such as the O_RDONLY and related macros used by fcntl() and open()
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 09/12] tools/nolibc: use a custom struct timespec
2025-10-29 16:02 ` [PATCH 09/12] tools/nolibc: use a custom struct timespec Thomas Weißschuh
@ 2025-10-30 14:46 ` Arnd Bergmann
2025-11-02 8:36 ` Willy Tarreau
0 siblings, 1 reply; 27+ messages in thread
From: Arnd Bergmann @ 2025-10-30 14:46 UTC (permalink / raw)
To: Thomas Weißschuh, Willy Tarreau, shuah; +Cc: linux-kernel, linux-kselftest
On Wed, Oct 29, 2025, at 17:02, Thomas Weißschuh wrote:
>
> +struct timespec {
> + time_t tv_sec;
> + long tv_nsec;
> +};
> +#define _STRUCT_TIMESPEC
> +
> +#include <linux/time.h>
Unfortunately this is not the definition we want on big-endian
systems because it puts the tv_nsec field in the wrong place.
You can either uses the simple (non-POSIX) __kernel_timespec
definition in nolibc with a 64-bit tv_nsec, or copy the more
complicated definition with explicit padding that is used
in musl and glibc.
Arnd
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 09/12] tools/nolibc: use a custom struct timespec
2025-10-30 14:46 ` Arnd Bergmann
@ 2025-11-02 8:36 ` Willy Tarreau
2025-11-02 8:40 ` Willy Tarreau
2025-11-02 9:41 ` Thomas Weißschuh
0 siblings, 2 replies; 27+ messages in thread
From: Willy Tarreau @ 2025-11-02 8:36 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: Thomas Weißschuh, shuah, linux-kernel, linux-kselftest
On Thu, Oct 30, 2025 at 03:46:21PM +0100, Arnd Bergmann wrote:
> On Wed, Oct 29, 2025, at 17:02, Thomas Weißschuh wrote:
> >
> > +struct timespec {
> > + time_t tv_sec;
> > + long tv_nsec;
> > +};
> > +#define _STRUCT_TIMESPEC
> > +
> > +#include <linux/time.h>
>
> Unfortunately this is not the definition we want on big-endian
> systems because it puts the tv_nsec field in the wrong place.
Indeed!
> You can either uses the simple (non-POSIX) __kernel_timespec
> definition in nolibc with a 64-bit tv_nsec, or copy the more
> complicated definition with explicit padding that is used
> in musl and glibc.
I think that switching this patch and the next one (10/12) would
just do the trick since both fields will become __kernel_time64_t.
Or maybe the two should be squashed into a single one.
Willy
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 09/12] tools/nolibc: use a custom struct timespec
2025-11-02 8:36 ` Willy Tarreau
@ 2025-11-02 8:40 ` Willy Tarreau
2025-11-02 9:41 ` Thomas Weißschuh
1 sibling, 0 replies; 27+ messages in thread
From: Willy Tarreau @ 2025-11-02 8:40 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: Thomas Weißschuh, shuah, linux-kernel, linux-kselftest
On Sun, Nov 02, 2025 at 09:36:22AM +0100, Willy Tarreau wrote:
> On Thu, Oct 30, 2025 at 03:46:21PM +0100, Arnd Bergmann wrote:
> > On Wed, Oct 29, 2025, at 17:02, Thomas Weißschuh wrote:
> > >
> > > +struct timespec {
> > > + time_t tv_sec;
> > > + long tv_nsec;
> > > +};
> > > +#define _STRUCT_TIMESPEC
> > > +
> > > +#include <linux/time.h>
> >
> > Unfortunately this is not the definition we want on big-endian
> > systems because it puts the tv_nsec field in the wrong place.
>
> Indeed!
>
> > You can either uses the simple (non-POSIX) __kernel_timespec
> > definition in nolibc with a 64-bit tv_nsec, or copy the more
> > complicated definition with explicit padding that is used
> > in musl and glibc.
>
> I think that switching this patch and the next one (10/12) would
> just do the trick since both fields will become __kernel_time64_t.
> Or maybe the two should be squashed into a single one.
OK like Arnd, I just saw with the last commit that this one will not
harm. That's good.
Willy
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 09/12] tools/nolibc: use a custom struct timespec
2025-11-02 8:36 ` Willy Tarreau
2025-11-02 8:40 ` Willy Tarreau
@ 2025-11-02 9:41 ` Thomas Weißschuh
2025-11-02 9:50 ` Willy Tarreau
1 sibling, 1 reply; 27+ messages in thread
From: Thomas Weißschuh @ 2025-11-02 9:41 UTC (permalink / raw)
To: Willy Tarreau; +Cc: Arnd Bergmann, shuah, linux-kernel, linux-kselftest
On 2025-11-02 09:36:22+0100, Willy Tarreau wrote:
> On Thu, Oct 30, 2025 at 03:46:21PM +0100, Arnd Bergmann wrote:
> > On Wed, Oct 29, 2025, at 17:02, Thomas Weißschuh wrote:
> > >
> > > +struct timespec {
> > > + time_t tv_sec;
> > > + long tv_nsec;
> > > +};
> > > +#define _STRUCT_TIMESPEC
> > > +
> > > +#include <linux/time.h>
> >
> > Unfortunately this is not the definition we want on big-endian
> > systems because it puts the tv_nsec field in the wrong place.
>
> Indeed!
>
> > You can either uses the simple (non-POSIX) __kernel_timespec
> > definition in nolibc with a 64-bit tv_nsec, or copy the more
> > complicated definition with explicit padding that is used
> > in musl and glibc.
>
> I think that switching this patch and the next one (10/12) would
> just do the trick since both fields will become __kernel_time64_t.
> Or maybe the two should be squashed into a single one.
Maybe I can make it clearer that this patch does not change anything.
This custom definition of 'struct timespec' is the same as the one we
got from linux/time.h before. This is just a preparation for the next
commit. Merging would also work, but it will be a bit messy to look at.
Thomas
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 09/12] tools/nolibc: use a custom struct timespec
2025-11-02 9:41 ` Thomas Weißschuh
@ 2025-11-02 9:50 ` Willy Tarreau
0 siblings, 0 replies; 27+ messages in thread
From: Willy Tarreau @ 2025-11-02 9:50 UTC (permalink / raw)
To: Thomas Weißschuh; +Cc: Arnd Bergmann, shuah, linux-kernel, linux-kselftest
On Sun, Nov 02, 2025 at 10:41:39AM +0100, Thomas Weißschuh wrote:
> On 2025-11-02 09:36:22+0100, Willy Tarreau wrote:
> > On Thu, Oct 30, 2025 at 03:46:21PM +0100, Arnd Bergmann wrote:
> > > On Wed, Oct 29, 2025, at 17:02, Thomas Weißschuh wrote:
> > > >
> > > > +struct timespec {
> > > > + time_t tv_sec;
> > > > + long tv_nsec;
> > > > +};
> > > > +#define _STRUCT_TIMESPEC
> > > > +
> > > > +#include <linux/time.h>
> > >
> > > Unfortunately this is not the definition we want on big-endian
> > > systems because it puts the tv_nsec field in the wrong place.
> >
> > Indeed!
> >
> > > You can either uses the simple (non-POSIX) __kernel_timespec
> > > definition in nolibc with a 64-bit tv_nsec, or copy the more
> > > complicated definition with explicit padding that is used
> > > in musl and glibc.
> >
> > I think that switching this patch and the next one (10/12) would
> > just do the trick since both fields will become __kernel_time64_t.
> > Or maybe the two should be squashed into a single one.
>
> Maybe I can make it clearer that this patch does not change anything.
> This custom definition of 'struct timespec' is the same as the one we
> got from linux/time.h before. This is just a preparation for the next
> commit. Merging would also work, but it will be a bit messy to look at.
Yes a slightly improved description in the patch wouldn't hurt. Since
we were two to get caught, it will definitely happen in the future when
people read commits.
Thanks!
Willy
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 10/12] tools/nolibc: always use 64-bit time types
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (8 preceding siblings ...)
2025-10-29 16:02 ` [PATCH 09/12] tools/nolibc: use a custom struct timespec Thomas Weißschuh
@ 2025-10-29 16:03 ` Thomas Weißschuh
2025-10-29 16:03 ` [PATCH 11/12] selftests/nolibc: test compatibility of timespec and __kernel_timespec Thomas Weißschuh
` (2 subsequent siblings)
12 siblings, 0 replies; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:03 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
32-bit time types will stop working in 2038.
Switch to 64-bit time types everywhere.
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/lkml/cec27d94-c99d-4c57-9a12-275ea663dda8@app.fastmail.com/
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/std.h | 2 +-
tools/include/nolibc/types.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/include/nolibc/std.h b/tools/include/nolibc/std.h
index 392f4dd94158..b9a116123902 100644
--- a/tools/include/nolibc/std.h
+++ b/tools/include/nolibc/std.h
@@ -29,6 +29,6 @@ typedef unsigned long nlink_t;
typedef int64_t off_t;
typedef signed long blksize_t;
typedef signed long blkcnt_t;
-typedef __kernel_time_t time_t;
+typedef __kernel_time64_t time_t;
#endif /* _NOLIBC_STD_H */
diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
index 4f5a25567e5c..3b086f68b2be 100644
--- a/tools/include/nolibc/types.h
+++ b/tools/include/nolibc/types.h
@@ -17,7 +17,7 @@
struct timespec {
time_t tv_sec;
- long tv_nsec;
+ int64_t tv_nsec;
};
#define _STRUCT_TIMESPEC
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 11/12] selftests/nolibc: test compatibility of timespec and __kernel_timespec
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (9 preceding siblings ...)
2025-10-29 16:03 ` [PATCH 10/12] tools/nolibc: always use 64-bit time types Thomas Weißschuh
@ 2025-10-29 16:03 ` Thomas Weißschuh
2025-10-29 16:03 ` [PATCH 12/12] tools/nolibc: remove time conversions Thomas Weißschuh
2025-11-02 8:44 ` [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Willy Tarreau
12 siblings, 0 replies; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:03 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
Keeping 'struct timespec' and 'struct __kernel_timespec' compatible
allows the source code to stay simple.
Validate that the types stay compatible.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/testing/selftests/nolibc/nolibc-test.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index f1d6d6c766dd..938af8d6e2bf 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -1428,6 +1428,23 @@ int test_difftime(void)
return 0;
}
+int test_timespec(void)
+{
+ struct __kernel_timespec kts;
+ struct timespec ts;
+
+ if (sizeof(ts) != sizeof(kts))
+ return 1;
+
+ if (!__builtin_types_compatible_p(__typeof__(ts.tv_sec), __typeof__(kts.tv_sec)))
+ return 1;
+
+ if (!__builtin_types_compatible_p(__typeof__(ts.tv_nsec), __typeof__(kts.tv_nsec)))
+ return 1;
+
+ return 0;
+}
+
int run_stdlib(int min, int max)
{
int test;
@@ -1551,6 +1568,7 @@ int run_stdlib(int min, int max)
CASE_TEST(abs); EXPECT_EQ(1, abs(-10), 10); break;
CASE_TEST(abs_noop); EXPECT_EQ(1, abs(10), 10); break;
CASE_TEST(difftime); EXPECT_ZR(1, test_difftime()); break;
+ CASE_TEST(test_timespec); EXPECT_ZR(1, test_timespec()); break;
case __LINE__:
return ret; /* must be last */
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 12/12] tools/nolibc: remove time conversions
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (10 preceding siblings ...)
2025-10-29 16:03 ` [PATCH 11/12] selftests/nolibc: test compatibility of timespec and __kernel_timespec Thomas Weißschuh
@ 2025-10-29 16:03 ` Thomas Weißschuh
2025-10-30 14:58 ` Arnd Bergmann
2025-11-02 8:44 ` [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Willy Tarreau
12 siblings, 1 reply; 27+ messages in thread
From: Thomas Weißschuh @ 2025-10-29 16:03 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: Arnd Bergmann, linux-kernel, linux-kselftest,
Thomas Weißschuh
Now that 'struct timespec' and 'struct __kernel_timespec' are
compatible, the conversions are not necessary anymore.
The same holds true for 'struct itimerspec' and 'struct
__kernel_itimerspec'.
Remove the conversions.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/sys/timerfd.h | 20 ++----------
tools/include/nolibc/time.h | 64 ++++----------------------------------
2 files changed, 8 insertions(+), 76 deletions(-)
diff --git a/tools/include/nolibc/sys/timerfd.h b/tools/include/nolibc/sys/timerfd.h
index 5dd61030c991..ae3153b7635d 100644
--- a/tools/include/nolibc/sys/timerfd.h
+++ b/tools/include/nolibc/sys/timerfd.h
@@ -35,13 +35,7 @@ int sys_timerfd_gettime(int fd, struct itimerspec *curr_value)
#if defined(__NR_timerfd_gettime)
return my_syscall2(__NR_timerfd_gettime, fd, curr_value);
#else
- struct __kernel_itimerspec kcurr_value;
- int ret;
-
- ret = my_syscall2(__NR_timerfd_gettime64, fd, &kcurr_value);
- __nolibc_timespec_kernel_to_user(&kcurr_value.it_interval, &curr_value->it_interval);
- __nolibc_timespec_kernel_to_user(&kcurr_value.it_value, &curr_value->it_value);
- return ret;
+ return my_syscall2(__NR_timerfd_gettime64, fd, curr_value);
#endif
}
@@ -59,17 +53,7 @@ int sys_timerfd_settime(int fd, int flags,
#if defined(__NR_timerfd_settime)
return my_syscall4(__NR_timerfd_settime, fd, flags, new_value, old_value);
#else
- struct __kernel_itimerspec knew_value, kold_value;
- int ret;
-
- __nolibc_timespec_user_to_kernel(&new_value->it_value, &knew_value.it_value);
- __nolibc_timespec_user_to_kernel(&new_value->it_interval, &knew_value.it_interval);
- ret = my_syscall4(__NR_timerfd_settime64, fd, flags, &knew_value, &kold_value);
- if (old_value) {
- __nolibc_timespec_kernel_to_user(&kold_value.it_interval, &old_value->it_interval);
- __nolibc_timespec_kernel_to_user(&kold_value.it_value, &old_value->it_value);
- }
- return ret;
+ return my_syscall4(__NR_timerfd_settime64, fd, flags, new_value, old_value);
#endif
}
diff --git a/tools/include/nolibc/time.h b/tools/include/nolibc/time.h
index 45df9b09d7b6..ab67f209c99f 100644
--- a/tools/include/nolibc/time.h
+++ b/tools/include/nolibc/time.h
@@ -18,20 +18,6 @@
#include <linux/signal.h>
#include <linux/time.h>
-static __inline__
-void __nolibc_timespec_user_to_kernel(const struct timespec *ts, struct __kernel_timespec *kts)
-{
- kts->tv_sec = ts->tv_sec;
- kts->tv_nsec = ts->tv_nsec;
-}
-
-static __inline__
-void __nolibc_timespec_kernel_to_user(const struct __kernel_timespec *kts, struct timespec *ts)
-{
- ts->tv_sec = kts->tv_sec;
- ts->tv_nsec = kts->tv_nsec;
-}
-
/*
* int clock_getres(clockid_t clockid, struct timespec *res);
* int clock_gettime(clockid_t clockid, struct timespec *tp);
@@ -44,13 +30,7 @@ static __attribute__((unused))
int sys_clock_getres(clockid_t clockid, struct timespec *res)
{
#if defined(__NR_clock_getres_time64)
- struct __kernel_timespec kres;
- int ret;
-
- ret = my_syscall2(__NR_clock_getres_time64, clockid, &kres);
- if (res)
- __nolibc_timespec_kernel_to_user(&kres, res);
- return ret;
+ return my_syscall2(__NR_clock_getres_time64, clockid, res);
#else
return my_syscall2(__NR_clock_getres, clockid, res);
#endif
@@ -66,13 +46,7 @@ static __attribute__((unused))
int sys_clock_gettime(clockid_t clockid, struct timespec *tp)
{
#if defined(__NR_clock_gettime64)
- struct __kernel_timespec ktp;
- int ret;
-
- ret = my_syscall2(__NR_clock_gettime64, clockid, &ktp);
- if (tp)
- __nolibc_timespec_kernel_to_user(&ktp, tp);
- return ret;
+ return my_syscall2(__NR_clock_gettime64, clockid, tp);
#else
return my_syscall2(__NR_clock_gettime, clockid, tp);
#endif
@@ -88,10 +62,7 @@ static __attribute__((unused))
int sys_clock_settime(clockid_t clockid, struct timespec *tp)
{
#if defined(__NR_clock_settime64)
- struct __kernel_timespec ktp;
-
- __nolibc_timespec_user_to_kernel(tp, &ktp);
- return my_syscall2(__NR_clock_settime64, clockid, &ktp);
+ return my_syscall2(__NR_clock_settime64, clockid, tp);
#else
return my_syscall2(__NR_clock_settime, clockid, tp);
#endif
@@ -108,14 +79,7 @@ int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqt
struct timespec *rmtp)
{
#if defined(__NR_clock_nanosleep_time64)
- struct __kernel_timespec krqtp, krmtp;
- int ret;
-
- __nolibc_timespec_user_to_kernel(rqtp, &krqtp);
- ret = my_syscall4(__NR_clock_nanosleep_time64, clockid, flags, &krqtp, &krmtp);
- if (rmtp)
- __nolibc_timespec_kernel_to_user(&krmtp, rmtp);
- return ret;
+ return my_syscall4(__NR_clock_nanosleep_time64, clockid, flags, rqtp, rmtp);
#else
return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp);
#endif
@@ -190,13 +154,7 @@ static __attribute__((unused))
int sys_timer_gettime(timer_t timerid, struct itimerspec *curr_value)
{
#if defined(__NR_timer_gettime64)
- struct __kernel_itimerspec kcurr_value;
- int ret;
-
- ret = my_syscall2(__NR_timer_gettime64, timerid, &kcurr_value);
- __nolibc_timespec_kernel_to_user(&kcurr_value.it_interval, &curr_value->it_interval);
- __nolibc_timespec_kernel_to_user(&kcurr_value.it_value, &curr_value->it_value);
- return ret;
+ return my_syscall2(__NR_timer_gettime64, timerid, curr_value);
#else
return my_syscall2(__NR_timer_gettime, timerid, curr_value);
#endif
@@ -213,17 +171,7 @@ int sys_timer_settime(timer_t timerid, int flags,
const struct itimerspec *new_value, struct itimerspec *old_value)
{
#if defined(__NR_timer_settime64)
- struct __kernel_itimerspec knew_value, kold_value;
- int ret;
-
- __nolibc_timespec_user_to_kernel(&new_value->it_value, &knew_value.it_value);
- __nolibc_timespec_user_to_kernel(&new_value->it_interval, &knew_value.it_interval);
- ret = my_syscall4(__NR_timer_settime64, timerid, flags, &knew_value, &kold_value);
- if (old_value) {
- __nolibc_timespec_kernel_to_user(&kold_value.it_interval, &old_value->it_interval);
- __nolibc_timespec_kernel_to_user(&kold_value.it_value, &old_value->it_value);
- }
- return ret;
+ return my_syscall4(__NR_timer_settime64, timerid, flags, new_value, old_value);
#else
return my_syscall4(__NR_timer_settime, timerid, flags, new_value, old_value);
#endif
--
2.51.1.dirty
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 12/12] tools/nolibc: remove time conversions
2025-10-29 16:03 ` [PATCH 12/12] tools/nolibc: remove time conversions Thomas Weißschuh
@ 2025-10-30 14:58 ` Arnd Bergmann
0 siblings, 0 replies; 27+ messages in thread
From: Arnd Bergmann @ 2025-10-30 14:58 UTC (permalink / raw)
To: Thomas Weißschuh, Willy Tarreau, shuah; +Cc: linux-kernel, linux-kselftest
On Wed, Oct 29, 2025, at 17:03, Thomas Weißschuh wrote:
> Now that 'struct timespec' and 'struct __kernel_timespec' are
> compatible, the conversions are not necessary anymore.
> The same holds true for 'struct itimerspec' and 'struct
> __kernel_itimerspec'.
>
> Remove the conversions.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Ah, I started commenting before I got to the end of the
series. This looks good,
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types
2025-10-29 16:02 [PATCH 00/12] tools/nolibc: always use 64-bit ino_t, off_t and time-related types Thomas Weißschuh
` (11 preceding siblings ...)
2025-10-29 16:03 ` [PATCH 12/12] tools/nolibc: remove time conversions Thomas Weißschuh
@ 2025-11-02 8:44 ` Willy Tarreau
12 siblings, 0 replies; 27+ messages in thread
From: Willy Tarreau @ 2025-11-02 8:44 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Shuah Khan, Arnd Bergmann, linux-kernel, linux-kselftest
On Wed, Oct 29, 2025 at 05:02:50PM +0100, Thomas Weißschuh wrote:
> nolibc currently uses 32-bit types for various APIs. These are
> problematic as their reduced value range can lead to truncated values.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Thanks Thomas for this cleanup! Overall this looks good to me. I also
tested my preinit code against it based both on latest and older UAPI
headers (5.4) and everything still builds and seems to work fine.
For the whole series: Acked-by: Willy Tarreau <w@1wt.eu>
Willy
^ permalink raw reply [flat|nested] 27+ messages in thread