All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9] y2038 groundwork and first steps
@ 2021-05-05 16:52 Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 1/9] cobalt/kernel: y2038: convert struct timespec to timespec64 Jan Kiszka
                   ` (9 more replies)
  0 siblings, 10 replies; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:52 UTC (permalink / raw)
  To: xenomai

Picking up from Philippe's queue:

This patch series prepares the tree for the upcoming y2038 work,
converting obsolete/ambiguous time specification types to the proper
ones introduced upstream by the v5.x kernel series.

In v2, feedback on the first round has been addressed, primarily
regarding folding fixing into the patches that need them.

In addition, this includes 3 patches from Florian that add
sem_timedwait64 system call and a test suite for it.

Jan


CC: Florian Bezdeka <florian.bezdeka@siemens.com>
CC: Philippe Gerum <rpm@xenomai.org>

Florian Bezdeka (4):
  cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems
  y2038: Adding sem_timedwait64
  y2038: Add tests for the sc_cobalt_sem_timedwait64 syscall
  y2038: lib/cobalt: Add support of sc_cobalt_sem_timedwait64

Philippe Gerum (5):
  cobalt/kernel: y2038: convert struct timespec to timespec64
  lib: y2038: convert to internal timespec type
  cobalt/kernel: y2038: convert struct itimerspec to itimerspec64
  cobalt/kernel: y2038: convert struct timex to __kernel_timex
  cobalt/kernel: y2038: switch to new legacy type names

 configure.ac                                  |   1 +
 include/cobalt/kernel/clock.h                 |  13 +-
 include/cobalt/kernel/compat.h                |  34 ++--
 .../cobalt/kernel/dovetail/pipeline/clock.h   |   4 +-
 include/cobalt/kernel/ipipe/pipeline/clock.h  |   4 +-
 include/cobalt/kernel/rtdm/fd.h               |   2 +-
 include/cobalt/kernel/time.h                  |  22 +++
 include/cobalt/uapi/kernel/types.h            |  53 ++++++
 include/cobalt/uapi/sched.h                   |  12 +-
 include/cobalt/uapi/syscall.h                 |   1 +
 kernel/cobalt/Makefile                        |   1 +
 .../include/asm-generic/xenomai/syscall.h     | 103 ++++++++++
 .../include/asm-generic/xenomai/wrappers.h    |   7 +
 kernel/cobalt/ipipe/clock.c                   |   2 +-
 kernel/cobalt/posix/clock.c                   |  44 ++---
 kernel/cobalt/posix/clock.h                   |  43 +++--
 kernel/cobalt/posix/compat.c                  |  86 ++++++---
 kernel/cobalt/posix/cond.c                    |  11 +-
 kernel/cobalt/posix/cond.h                    |   4 +-
 kernel/cobalt/posix/event.c                   |   8 +-
 kernel/cobalt/posix/event.h                   |   4 +-
 kernel/cobalt/posix/extension.h               |   4 +-
 kernel/cobalt/posix/io.c                      |   6 +-
 kernel/cobalt/posix/io.h                      |   2 +-
 kernel/cobalt/posix/monitor.c                 |   8 +-
 kernel/cobalt/posix/monitor.h                 |   4 +-
 kernel/cobalt/posix/mqueue.c                  |  21 +--
 kernel/cobalt/posix/mqueue.h                  |   8 +-
 kernel/cobalt/posix/mutex.c                   |  13 +-
 kernel/cobalt/posix/mutex.h                   |   6 +-
 kernel/cobalt/posix/sched.c                   |  16 +-
 kernel/cobalt/posix/sem.c                     |  60 +++---
 kernel/cobalt/posix/sem.h                     |  13 +-
 kernel/cobalt/posix/signal.c                  |   6 +-
 kernel/cobalt/posix/signal.h                  |   4 +-
 kernel/cobalt/posix/syscall32.c               |  93 +++++----
 kernel/cobalt/posix/syscall32.h               |  48 ++---
 kernel/cobalt/posix/thread.c                  |   6 +-
 kernel/cobalt/posix/timer.c                   |  30 +--
 kernel/cobalt/posix/timer.h                   |  16 +-
 kernel/cobalt/posix/timerfd.c                 |  22 +--
 kernel/cobalt/posix/timerfd.h                 |  12 +-
 kernel/cobalt/rtdm/fd.c                       |   4 +-
 kernel/cobalt/time.c                          |  29 +++
 kernel/cobalt/trace/cobalt-posix.h            |  34 ++--
 kernel/drivers/ipc/rtipc.c                    |   4 +-
 lib/alchemy/task.c                            |   9 +-
 lib/cobalt/semaphore.c                        |   5 +
 lib/copperplate/threadobj.c                   |   9 +-
 lib/psos/task.c                               |   9 +-
 lib/vxworks/kernLib.c                         |   6 +-
 lib/vxworks/taskLib.c                         |   6 +-
 testsuite/smokey/Makefile.am                  |   6 +-
 testsuite/smokey/y2038/Makefile.am            |   9 +
 testsuite/smokey/y2038/syscall-tests.c        | 176 ++++++++++++++++++
 55 files changed, 835 insertions(+), 328 deletions(-)
 create mode 100644 include/cobalt/kernel/time.h
 create mode 100644 kernel/cobalt/time.c
 create mode 100644 testsuite/smokey/y2038/Makefile.am
 create mode 100644 testsuite/smokey/y2038/syscall-tests.c

-- 
2.26.2



^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v2 1/9] cobalt/kernel: y2038: convert struct timespec to timespec64
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
@ 2021-05-05 16:53 ` Jan Kiszka
  2021-05-07  6:09   ` Florian Bezdeka
  2021-05-05 16:53 ` [PATCH v2 2/9] lib: y2038: convert to internal timespec type Jan Kiszka
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:53 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

As internal interfaces are gradually being made y2038-safe, the
timespec64 type should be used internally by the kernel to represent
time values. Apply the same reasoning to Cobalt.

We still use a legacy y2038-unsafe timespec type at the kernel<->user
interface boundary (struct __user_old_timespec) until libcobalt is
y2038-safe.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
[Florian: Fix regression in 32bit mode]
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/clock.h                 |  6 +-
 include/cobalt/kernel/compat.h                |  4 +-
 .../cobalt/kernel/dovetail/pipeline/clock.h   |  4 +-
 include/cobalt/kernel/ipipe/pipeline/clock.h  |  4 +-
 include/cobalt/kernel/rtdm/fd.h               |  2 +-
 include/cobalt/uapi/kernel/types.h            | 10 ++++
 include/cobalt/uapi/sched.h                   | 12 ++--
 .../include/asm-generic/xenomai/syscall.h     | 58 +++++++++++++++++++
 kernel/cobalt/ipipe/clock.c                   |  2 +-
 kernel/cobalt/posix/clock.c                   | 38 ++++++------
 kernel/cobalt/posix/clock.h                   | 39 +++++++++----
 kernel/cobalt/posix/compat.c                  | 46 ++++++++++-----
 kernel/cobalt/posix/cond.c                    | 11 ++--
 kernel/cobalt/posix/cond.h                    |  4 +-
 kernel/cobalt/posix/event.c                   |  8 +--
 kernel/cobalt/posix/event.h                   |  4 +-
 kernel/cobalt/posix/io.c                      |  6 +-
 kernel/cobalt/posix/io.h                      |  2 +-
 kernel/cobalt/posix/monitor.c                 |  8 +--
 kernel/cobalt/posix/monitor.h                 |  4 +-
 kernel/cobalt/posix/mqueue.c                  | 21 ++++---
 kernel/cobalt/posix/mqueue.h                  |  8 +--
 kernel/cobalt/posix/mutex.c                   | 13 ++---
 kernel/cobalt/posix/mutex.h                   |  6 +-
 kernel/cobalt/posix/sched.c                   | 16 ++---
 kernel/cobalt/posix/sem.c                     |  8 +--
 kernel/cobalt/posix/sem.h                     |  4 +-
 kernel/cobalt/posix/signal.c                  |  6 +-
 kernel/cobalt/posix/signal.h                  |  4 +-
 kernel/cobalt/posix/syscall32.c               | 26 ++++-----
 kernel/cobalt/posix/syscall32.h               |  2 +-
 kernel/cobalt/posix/thread.c                  |  6 +-
 kernel/cobalt/rtdm/fd.c                       |  4 +-
 kernel/cobalt/trace/cobalt-posix.h            | 30 +++++-----
 34 files changed, 262 insertions(+), 164 deletions(-)

diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
index bbf34c53cf..1c99173ff8 100644
--- a/include/cobalt/kernel/clock.h
+++ b/include/cobalt/kernel/clock.h
@@ -54,7 +54,7 @@ struct xnclock {
 		xnticks_t (*read_raw)(struct xnclock *clock);
 		xnticks_t (*read_monotonic)(struct xnclock *clock);
 		int (*set_time)(struct xnclock *clock,
-				const struct timespec *ts);
+				const struct timespec64 *ts);
 		xnsticks_t (*ns_to_ticks)(struct xnclock *clock,
 					  xnsticks_t ns);
 		xnsticks_t (*ticks_to_ns)(struct xnclock *clock,
@@ -211,7 +211,7 @@ static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
 }
 
 static inline int xnclock_set_time(struct xnclock *clock,
-				   const struct timespec *ts)
+				   const struct timespec64 *ts)
 {
 	if (likely(clock == &nkclock))
 		return -EINVAL;
@@ -264,7 +264,7 @@ static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
 }
 
 static inline int xnclock_set_time(struct xnclock *clock,
-				   const struct timespec *ts)
+				   const struct timespec64 *ts)
 {
 	/*
 	 * There is no way to change the core clock's idea of time.
diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
index 313b6251b4..c57ef65325 100644
--- a/include/cobalt/kernel/compat.h
+++ b/include/cobalt/kernel/compat.h
@@ -86,11 +86,11 @@ struct compat_rtdm_mmap_request {
 	int flags;
 };
 
-int sys32_get_timespec(struct timespec *ts,
+int sys32_get_timespec(struct timespec64 *ts,
 		       const struct compat_timespec __user *cts);
 
 int sys32_put_timespec(struct compat_timespec __user *cts,
-		       const struct timespec *ts);
+		       const struct timespec64 *ts);
 
 int sys32_get_itimerspec(struct itimerspec *its,
 			 const struct compat_itimerspec __user *cits);
diff --git a/include/cobalt/kernel/dovetail/pipeline/clock.h b/include/cobalt/kernel/dovetail/pipeline/clock.h
index 933e100baf..19e3d89865 100644
--- a/include/cobalt/kernel/dovetail/pipeline/clock.h
+++ b/include/cobalt/kernel/dovetail/pipeline/clock.h
@@ -8,7 +8,7 @@
 #include <cobalt/uapi/kernel/types.h>
 #include <cobalt/kernel/assert.h>
 
-struct timespec;
+struct timespec64;
 
 static inline u64 pipeline_read_cycle_counter(void)
 {
@@ -49,7 +49,7 @@ static inline const char *pipeline_clock_name(void)
 	return "?";
 }
 
-static inline int pipeline_get_host_time(struct timespec *tp)
+static inline int pipeline_get_host_time(struct timespec64 *tp)
 {
 	/* Convert ktime_get_real_fast_ns() to timespec. */
 	TODO();
diff --git a/include/cobalt/kernel/ipipe/pipeline/clock.h b/include/cobalt/kernel/ipipe/pipeline/clock.h
index fa7ac2a5e0..d35aea17b1 100644
--- a/include/cobalt/kernel/ipipe/pipeline/clock.h
+++ b/include/cobalt/kernel/ipipe/pipeline/clock.h
@@ -7,7 +7,7 @@
 
 #include <linux/ipipe_tickdev.h>
 
-struct timespec;
+struct timespec64;
 
 static inline u64 pipeline_read_cycle_counter(void)
 {
@@ -31,7 +31,7 @@ static inline const char *pipeline_clock_name(void)
 	return ipipe_clock_name();
 }
 
-int pipeline_get_host_time(struct timespec *tp);
+int pipeline_get_host_time(struct timespec64 *tp);
 
 void pipeline_update_clock_freq(unsigned long long freq);
 
diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
index 289065082b..37a09c43e8 100644
--- a/include/cobalt/kernel/rtdm/fd.h
+++ b/include/cobalt/kernel/rtdm/fd.h
@@ -380,7 +380,7 @@ int __rtdm_fd_recvmmsg(int ufd, void __user *u_msgvec, unsigned int vlen,
 		       unsigned int flags, void __user *u_timeout,
 		       int (*get_mmsg)(struct mmsghdr *mmsg, void __user *u_mmsg),
 		       int (*put_mmsg)(void __user **u_mmsg_p, const struct mmsghdr *mmsg),
-		       int (*get_timespec)(struct timespec *ts, const void __user *u_ts));
+		       int (*get_timespec)(struct timespec64 *ts, const void __user *u_ts));
 
 ssize_t rtdm_fd_sendmsg(int ufd, const struct user_msghdr *msg,
 			int flags);
diff --git a/include/cobalt/uapi/kernel/types.h b/include/cobalt/uapi/kernel/types.h
index ee5bbadcae..8ce9b03df4 100644
--- a/include/cobalt/uapi/kernel/types.h
+++ b/include/cobalt/uapi/kernel/types.h
@@ -57,4 +57,14 @@ static inline xnhandle_t xnhandle_get_id(xnhandle_t handle)
 	return handle & ~XN_HANDLE_TRANSIENT_MASK;
 }
 
+/*
+ * Our representation of time at the kernel<->user interface boundary
+ * at the moment, until we have fully transitioned to a y2038-safe
+ * implementation in libcobalt.
+ */
+struct __user_old_timespec {
+	long  tv_sec;
+	long  tv_nsec;
+};
+
 #endif /* !_COBALT_UAPI_KERNEL_TYPES_H */
diff --git a/include/cobalt/uapi/sched.h b/include/cobalt/uapi/sched.h
index b672095c3b..14095870f3 100644
--- a/include/cobalt/uapi/sched.h
+++ b/include/cobalt/uapi/sched.h
@@ -18,6 +18,8 @@
 #ifndef _COBALT_UAPI_SCHED_H
 #define _COBALT_UAPI_SCHED_H
 
+#include <cobalt/uapi/kernel/types.h>
+
 #define SCHED_COBALT		42
 #define SCHED_WEAK		43
 
@@ -31,15 +33,15 @@
 
 struct __sched_ss_param {
 	int __sched_low_priority;
-	struct timespec __sched_repl_period;
-	struct timespec __sched_init_budget;
+	struct __user_old_timespec __sched_repl_period;
+	struct __user_old_timespec __sched_init_budget;
 	int __sched_max_repl;
 };
 
 #define sched_rr_quantum	sched_u.rr.__sched_rr_quantum
 
 struct __sched_rr_param {
-	struct timespec __sched_rr_quantum;
+	struct __user_old_timespec __sched_rr_quantum;
 };
 
 #ifndef SCHED_TP
@@ -52,8 +54,8 @@ struct __sched_tp_param {
 };
 
 struct sched_tp_window {
-	struct timespec offset;
-	struct timespec duration;
+	struct __user_old_timespec offset;
+	struct __user_old_timespec duration;
 	int ptid;
 };
 
diff --git a/kernel/cobalt/include/asm-generic/xenomai/syscall.h b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
index 0d50d4107d..05a7d28685 100644
--- a/kernel/cobalt/include/asm-generic/xenomai/syscall.h
+++ b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
@@ -26,6 +26,7 @@
 #include <asm/xenomai/wrappers.h>
 #include <asm/xenomai/machine.h>
 #include <cobalt/uapi/asm-generic/syscall.h>
+#include <cobalt/uapi/kernel/types.h>
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
 #define access_rok(addr, size)	access_ok((addr), (size))
@@ -81,6 +82,63 @@ static inline int cobalt_strncpy_from_user(char *dst, const char __user *src,
 	return __xn_strncpy_from_user(dst, src, count);
 }
 
+#if __BITS_PER_LONG == 64
+
+/*
+ * NOTE: those copy helpers won't work in compat mode: use
+ * sys32_get_timespec(), sys32_put_timespec() instead.
+ */
+
+static inline int cobalt_get_u_timespec(struct timespec64 *dst,
+			const struct __user_old_timespec __user *src)
+{
+	return cobalt_copy_from_user(dst, src, sizeof(*dst));
+}
+
+static inline int cobalt_put_u_timespec(
+	struct __user_old_timespec __user *dst,
+	const struct timespec64 *src)
+{
+	return cobalt_copy_to_user(dst, src, sizeof(*dst));
+}
+
+#else /* __BITS_PER_LONG == 32 */
+
+static inline int cobalt_get_u_timespec(struct timespec64 *dst,
+			const struct __user_old_timespec __user *src)
+{
+	struct __user_old_timespec u_ts;
+	int ret;
+
+	ret = cobalt_copy_from_user(&u_ts, src, sizeof(u_ts));
+	if (ret)
+		return ret;
+
+	dst->tv_sec = u_ts.tv_sec;
+	dst->tv_nsec = u_ts.tv_nsec;
+
+	return 0;
+}
+
+static inline int cobalt_put_u_timespec(
+	struct __user_old_timespec __user *dst,
+	const struct timespec64 *src)
+{
+	struct __user_old_timespec u_ts;
+	int ret;
+
+	u_ts.tv_sec = src->tv_sec;
+	u_ts.tv_nsec = src->tv_nsec;
+
+	ret = cobalt_copy_to_user(dst, &u_ts, sizeof(*dst));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+#endif
+
 /* 32bit syscall emulation */
 #define __COBALT_COMPAT_BIT	0x1
 /* 32bit syscall emulation - extended form */
diff --git a/kernel/cobalt/ipipe/clock.c b/kernel/cobalt/ipipe/clock.c
index 606c6bf8c0..d40b0ac890 100644
--- a/kernel/cobalt/ipipe/clock.c
+++ b/kernel/cobalt/ipipe/clock.c
@@ -67,7 +67,7 @@ EXPORT_SYMBOL_GPL(xnclock_core_ticks_to_ns);
 EXPORT_SYMBOL_GPL(xnclock_core_ticks_to_ns_rounded);
 EXPORT_SYMBOL_GPL(xnclock_core_ns_to_ticks);
 
-int pipeline_get_host_time(struct timespec *tp)
+int pipeline_get_host_time(struct timespec64 *tp)
 {
 #ifdef CONFIG_IPIPE_HAVE_HOSTRT
 	struct xnvdso_hostrt_data *hostrt_data;
diff --git a/kernel/cobalt/posix/clock.c b/kernel/cobalt/posix/clock.c
index e957dd9569..4a3365d2a9 100644
--- a/kernel/cobalt/posix/clock.c
+++ b/kernel/cobalt/posix/clock.c
@@ -51,7 +51,7 @@ DECLARE_BITMAP(cobalt_clock_extids, COBALT_MAX_EXTCLOCKS);
 	__val;							\
 })
 
-int __cobalt_clock_getres(clockid_t clock_id, struct timespec *ts)
+int __cobalt_clock_getres(clockid_t clock_id, struct timespec64 *ts)
 {
 	xnticks_t ns;
 	int ret;
@@ -75,16 +75,16 @@ int __cobalt_clock_getres(clockid_t clock_id, struct timespec *ts)
 }
 
 COBALT_SYSCALL(clock_getres, current,
-	       (clockid_t clock_id, struct timespec __user *u_ts))
+	       (clockid_t clock_id, struct __user_old_timespec __user *u_ts))
 {
-	struct timespec ts;
+	struct timespec64 ts;
 	int ret;
 
 	ret = __cobalt_clock_getres(clock_id, &ts);
 	if (ret)
 		return ret;
 
-	if (u_ts && cobalt_copy_to_user(u_ts, &ts, sizeof(ts)))
+	if (u_ts && cobalt_put_u_timespec(u_ts, &ts))
 		return -EFAULT;
 
 	trace_cobalt_clock_getres(clock_id, &ts);
@@ -92,7 +92,7 @@ COBALT_SYSCALL(clock_getres, current,
 	return 0;
 }
 
-int __cobalt_clock_gettime(clockid_t clock_id, struct timespec *ts)
+int __cobalt_clock_gettime(clockid_t clock_id, struct timespec64 *ts)
 {
 	xnticks_t ns;
 	int ret;
@@ -122,16 +122,16 @@ int __cobalt_clock_gettime(clockid_t clock_id, struct timespec *ts)
 }
 
 COBALT_SYSCALL(clock_gettime, current,
-	       (clockid_t clock_id, struct timespec __user *u_ts))
+	       (clockid_t clock_id, struct __user_old_timespec __user *u_ts))
 {
-	struct timespec ts;
+	struct timespec64 ts;
 	int ret;
 
 	ret = __cobalt_clock_gettime(clock_id, &ts);
 	if (ret)
 		return ret;
 
-	if (cobalt_copy_to_user(u_ts, &ts, sizeof(*u_ts)))
+	if (cobalt_put_u_timespec(u_ts, &ts))
 		return -EFAULT;
 
 	trace_cobalt_clock_gettime(clock_id, &ts);
@@ -139,7 +139,7 @@ COBALT_SYSCALL(clock_gettime, current,
 	return 0;
 }
 
-int __cobalt_clock_settime(clockid_t clock_id, const struct timespec *ts)
+int __cobalt_clock_settime(clockid_t clock_id, const struct timespec64 *ts)
 {
 	int _ret, ret = 0;
 	xnticks_t now;
@@ -188,11 +188,11 @@ int __cobalt_clock_adjtime(clockid_t clock_id, struct timex *tx)
 }
 
 COBALT_SYSCALL(clock_settime, current,
-	       (clockid_t clock_id, const struct timespec __user *u_ts))
+	       (clockid_t clock_id, const struct __user_old_timespec __user *u_ts))
 {
-	struct timespec ts;
+	struct timespec64 ts;
 
-	if (cobalt_copy_from_user(&ts, u_ts, sizeof(ts)))
+	if (cobalt_get_u_timespec(&ts, u_ts))
 		return -EFAULT;
 
 	return __cobalt_clock_settime(clock_id, &ts);
@@ -215,8 +215,8 @@ COBALT_SYSCALL(clock_adjtime, current,
 }
 
 int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
-			     const struct timespec *rqt,
-			     struct timespec *rmt)
+			     const struct timespec64 *rqt,
+			     struct timespec64 *rmt)
 {
 	struct restart_block *restart;
 	struct xnthread *cur;
@@ -296,21 +296,21 @@ int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
 
 COBALT_SYSCALL(clock_nanosleep, primary,
 	       (clockid_t clock_id, int flags,
-		const struct timespec __user *u_rqt,
-		struct timespec __user *u_rmt))
+		const struct __user_old_timespec __user *u_rqt,
+		struct __user_old_timespec __user *u_rmt))
 {
-	struct timespec rqt, rmt, *rmtp = NULL;
+	struct timespec64 rqt, rmt, *rmtp = NULL;
 	int ret;
 
 	if (u_rmt)
 		rmtp = &rmt;
 
-	if (cobalt_copy_from_user(&rqt, u_rqt, sizeof(rqt)))
+	if (cobalt_get_u_timespec(&rqt, u_rqt))
 		return -EFAULT;
 
 	ret = __cobalt_clock_nanosleep(clock_id, flags, &rqt, rmtp);
 	if (ret == -EINTR && flags == 0 && rmtp) {
-		if (cobalt_copy_to_user(u_rmt, rmtp, sizeof(*u_rmt)))
+		if (cobalt_put_u_timespec(u_rmt, rmtp))
 			return -EFAULT;
 	}
 
diff --git a/kernel/cobalt/posix/clock.h b/kernel/cobalt/posix/clock.h
index 7cb161df24..7e45fdcc6b 100644
--- a/kernel/cobalt/posix/clock.h
+++ b/kernel/cobalt/posix/clock.h
@@ -28,12 +28,27 @@
 
 struct xnclock;
 
-static inline void ns2ts(struct timespec *ts, xnticks_t nsecs)
+static inline void ns2ts(struct timespec64 *ts, xnticks_t nsecs)
 {
 	ts->tv_sec = xnclock_divrem_billion(nsecs, &ts->tv_nsec);
 }
 
-static inline xnticks_t ts2ns(const struct timespec *ts)
+static inline void u_ns2ts(struct __user_old_timespec *ts, xnticks_t nsecs)
+{
+	ts->tv_sec = xnclock_divrem_billion(nsecs, &ts->tv_nsec);
+}
+
+static inline xnticks_t ts2ns(const struct timespec64 *ts)
+{
+	xnticks_t nsecs = ts->tv_nsec;
+
+	if (ts->tv_sec)
+		nsecs += (xnticks_t)ts->tv_sec * ONE_BILLION;
+
+	return nsecs;
+}
+
+static inline xnticks_t u_ts2ns(const struct __user_old_timespec *ts)
 {
 	xnticks_t nsecs = ts->tv_nsec;
 
@@ -80,37 +95,37 @@ static inline int clock_flag(int flag, clockid_t clock_id)
 }
 
 int __cobalt_clock_getres(clockid_t clock_id,
-			  struct timespec *ts);
+			  struct timespec64 *ts);
 
 int __cobalt_clock_gettime(clockid_t clock_id,
-			   struct timespec *ts);
+			   struct timespec64 *ts);
 
 int __cobalt_clock_settime(clockid_t clock_id,
-			   const struct timespec *ts);
+			   const struct timespec64 *ts);
 
 int __cobalt_clock_adjtime(clockid_t clock_id,
 			   struct timex *tx);
 
 int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
-			     const struct timespec *rqt,
-			     struct timespec *rmt);
+			     const struct timespec64 *rqt,
+			     struct timespec64 *rmt);
 
 COBALT_SYSCALL_DECL(clock_getres,
-		    (clockid_t clock_id, struct timespec __user *u_ts));
+		    (clockid_t clock_id, struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(clock_gettime,
-		    (clockid_t clock_id, struct timespec __user *u_ts));
+		    (clockid_t clock_id, struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(clock_settime,
-		    (clockid_t clock_id, const struct timespec __user *u_ts));
+		    (clockid_t clock_id, const struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(clock_adjtime,
 		    (clockid_t clock_id, struct timex __user *u_tx));
 
 COBALT_SYSCALL_DECL(clock_nanosleep,
 		    (clockid_t clock_id, int flags,
-		     const struct timespec __user *u_rqt,
-		     struct timespec __user *u_rmt));
+		     const struct __user_old_timespec __user *u_rqt,
+		     struct __user_old_timespec __user *u_rmt));
 
 int cobalt_clock_register(struct xnclock *clock,
 			  const cpumask_t *affinity,
diff --git a/kernel/cobalt/posix/compat.c b/kernel/cobalt/posix/compat.c
index 2ffc0dbdf4..1852950821 100644
--- a/kernel/cobalt/posix/compat.c
+++ b/kernel/cobalt/posix/compat.c
@@ -22,23 +22,41 @@
 #include <asm/xenomai/syscall.h>
 #include <xenomai/posix/mqueue.h>
 
-int sys32_get_timespec(struct timespec *ts,
-		       const struct compat_timespec __user *cts)
+int sys32_get_timespec(struct timespec64 *ts,
+		       const struct compat_timespec __user *u_cts)
 {
-	return (cts == NULL ||
-		!access_rok(cts, sizeof(*cts)) ||
-		__xn_get_user(ts->tv_sec, &cts->tv_sec) ||
-		__xn_get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
+	struct compat_timespec cts;
+
+	if (u_cts == NULL || !access_rok(u_cts, sizeof(*u_cts)))
+		return -EFAULT;
+
+	if (__xn_get_user(cts.tv_sec, &u_cts->tv_sec) ||
+		__xn_get_user(cts.tv_nsec, &u_cts->tv_nsec))
+		return -EFAULT;
+
+	ts->tv_sec = cts.tv_sec;
+	ts->tv_nsec = cts.tv_nsec;
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(sys32_get_timespec);
 
-int sys32_put_timespec(struct compat_timespec __user *cts,
-		       const struct timespec *ts)
+int sys32_put_timespec(struct compat_timespec __user *u_cts,
+		       const struct timespec64 *ts)
 {
-	return (cts == NULL ||
-		!access_wok(cts, sizeof(*cts)) ||
-		__xn_put_user(ts->tv_sec, &cts->tv_sec) ||
-		__xn_put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
+	struct compat_timespec cts;
+
+	if (u_cts == NULL || !access_wok(u_cts, sizeof(*u_cts)))
+		return -EFAULT;
+
+	cts.tv_sec = ts->tv_sec;
+	cts.tv_nsec = ts->tv_nsec;
+
+	if (__xn_put_user(cts.tv_sec, &u_cts->tv_sec) ||
+	    __xn_put_user(cts.tv_nsec, &u_cts->tv_nsec))
+		return -EFAULT;
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(sys32_put_timespec);
 
@@ -478,7 +496,7 @@ int sys32_get_iovec(struct iovec *iov,
 	const struct compat_iovec __user *p;
 	struct compat_iovec ciov;
 	int ret, n;
-	
+
 	for (n = 0, p = u_ciov; n < ciovlen; n++, p++) {
 		ret = cobalt_copy_from_user(&ciov, p, sizeof(ciov));
 		if (ret)
@@ -498,7 +516,7 @@ int sys32_put_iovec(struct compat_iovec __user *u_ciov,
 	struct compat_iovec __user *p;
 	struct compat_iovec ciov;
 	int ret, n;
-	
+
 	for (n = 0, p = u_ciov; n < iovlen; n++, p++) {
 		ciov.iov_base = ptr_to_compat(iov[n].iov_base);
 		ciov.iov_len = iov[n].iov_len;
diff --git a/kernel/cobalt/posix/cond.c b/kernel/cobalt/posix/cond.c
index 35a8f7176d..bb18fe316e 100644
--- a/kernel/cobalt/posix/cond.c
+++ b/kernel/cobalt/posix/cond.c
@@ -270,25 +270,24 @@ struct us_cond_data {
 	int err;
 };
 
-static inline int cond_fetch_timeout(struct timespec *ts,
+static inline int cond_fetch_timeout(struct timespec64 *ts,
 				     const void __user *u_ts)
 {
-	return u_ts == NULL ? -EFAULT :
-		cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
+	return u_ts == NULL ? -EFAULT :	cobalt_get_u_timespec(ts, u_ts);
 }
 
 int __cobalt_cond_wait_prologue(struct cobalt_cond_shadow __user *u_cnd,
 				struct cobalt_mutex_shadow __user *u_mx,
 				int *u_err,
 				void __user *u_ts,
-				int (*fetch_timeout)(struct timespec *ts,
+				int (*fetch_timeout)(struct timespec64 *ts,
 						     const void __user *u_ts))
 {
 	struct xnthread *cur = xnthread_current();
 	struct cobalt_cond *cond;
 	struct cobalt_mutex *mx;
 	struct us_cond_data d;
-	struct timespec ts;
+	struct timespec64 ts;
 	xnhandle_t handle;
 	int err, perr = 0;
 	__u32 offset;
@@ -349,7 +348,7 @@ COBALT_SYSCALL(cond_wait_prologue, nonrestartable,
 		struct cobalt_mutex_shadow __user *u_mx,
 		int *u_err,
 		unsigned int timed,
-		struct timespec __user *u_ts))
+		struct __user_old_timespec __user *u_ts))
 {
 	return __cobalt_cond_wait_prologue(u_cnd, u_mx, u_err, u_ts,
 					   timed ? cond_fetch_timeout : NULL);
diff --git a/kernel/cobalt/posix/cond.h b/kernel/cobalt/posix/cond.h
index c7a9be4514..7bec2a649a 100644
--- a/kernel/cobalt/posix/cond.h
+++ b/kernel/cobalt/posix/cond.h
@@ -43,7 +43,7 @@ int __cobalt_cond_wait_prologue(struct cobalt_cond_shadow __user *u_cnd,
 				struct cobalt_mutex_shadow __user *u_mx,
 				int *u_err,
 				void __user *u_ts,
-				int (*fetch_timeout)(struct timespec *ts,
+				int (*fetch_timeout)(struct timespec64 *ts,
 						     const void __user *u_ts));
 COBALT_SYSCALL_DECL(cond_init,
 		    (struct cobalt_cond_shadow __user *u_cnd,
@@ -57,7 +57,7 @@ COBALT_SYSCALL_DECL(cond_wait_prologue,
 		     struct cobalt_mutex_shadow __user *u_mx,
 		     int *u_err,
 		     unsigned int timed,
-		     struct timespec __user *u_ts));
+		     struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(cond_wait_epilogue,
 		    (struct cobalt_cond_shadow __user *u_cnd,
diff --git a/kernel/cobalt/posix/event.c b/kernel/cobalt/posix/event.c
index c566a09e36..3712154f53 100644
--- a/kernel/cobalt/posix/event.c
+++ b/kernel/cobalt/posix/event.c
@@ -104,7 +104,7 @@ COBALT_SYSCALL(event_init, current,
 int __cobalt_event_wait(struct cobalt_event_shadow __user *u_event,
 			unsigned int bits,
 			unsigned int __user *u_bits_r,
-			int mode, const struct timespec *ts)
+			int mode, const struct timespec64 *ts)
 {
 	unsigned int rbits = 0, testval;
 	xnticks_t timeout = XN_INFINITE;
@@ -193,14 +193,14 @@ COBALT_SYSCALL(event_wait, primary,
 	       (struct cobalt_event_shadow __user *u_event,
 		unsigned int bits,
 		unsigned int __user *u_bits_r,
-		int mode, const struct timespec __user *u_ts))
+		int mode, const struct __user_old_timespec __user *u_ts))
 {
-	struct timespec ts, *tsp = NULL;
+	struct timespec64 ts, *tsp = NULL;
 	int ret;
 
 	if (u_ts) {
 		tsp = &ts;
-		ret = cobalt_copy_from_user(&ts, u_ts, sizeof(ts));
+		ret = cobalt_get_u_timespec(&ts, u_ts);
 		if (ret)
 			return ret;
 	}
diff --git a/kernel/cobalt/posix/event.h b/kernel/cobalt/posix/event.h
index 28d4516acf..ef592f72c0 100644
--- a/kernel/cobalt/posix/event.h
+++ b/kernel/cobalt/posix/event.h
@@ -39,7 +39,7 @@ struct cobalt_event {
 int __cobalt_event_wait(struct cobalt_event_shadow __user *u_event,
 			unsigned int bits,
 			unsigned int __user *u_bits_r,
-			int mode, const struct timespec *ts);
+			int mode, const struct timespec64 *ts);
 
 COBALT_SYSCALL_DECL(event_init,
 		    (struct cobalt_event_shadow __user *u_evtsh,
@@ -51,7 +51,7 @@ COBALT_SYSCALL_DECL(event_wait,
 		     unsigned int bits,
 		     unsigned int __user *u_bits_r,
 		     int mode,
-		     const struct timespec __user *u_ts));
+		     const struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(event_sync,
 		    (struct cobalt_event_shadow __user *u_evtsh));
diff --git a/kernel/cobalt/posix/io.c b/kernel/cobalt/posix/io.c
index e9908feeb4..97a1f6afcd 100644
--- a/kernel/cobalt/posix/io.c
+++ b/kernel/cobalt/posix/io.c
@@ -93,10 +93,10 @@ COBALT_SYSCALL(recvmsg, handover,
 	return cobalt_copy_to_user(umsg, &m, sizeof(*umsg)) ?: ret;
 }
 
-static int get_timespec(struct timespec *ts,
+static int get_timespec(struct timespec64 *ts,
 			const void __user *u_ts)
 {
-	return cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
+	return cobalt_get_u_timespec(ts, u_ts);
 }
 
 static int get_mmsg(struct mmsghdr *mmsg, void __user *u_mmsg)
@@ -114,7 +114,7 @@ static int put_mmsg(void __user **u_mmsg_p, const struct mmsghdr *mmsg)
 
 COBALT_SYSCALL(recvmmsg, primary,
 	       (int fd, struct mmsghdr __user *u_msgvec, unsigned int vlen,
-		unsigned int flags, struct timespec *u_timeout))
+		unsigned int flags, struct __user_old_timespec __user *u_timeout))
 {
 	return __rtdm_fd_recvmmsg(fd, u_msgvec, vlen, flags, u_timeout,
 				  get_mmsg, put_mmsg, get_timespec);
diff --git a/kernel/cobalt/posix/io.h b/kernel/cobalt/posix/io.h
index 82187cc7ba..e4f7d4d51f 100644
--- a/kernel/cobalt/posix/io.h
+++ b/kernel/cobalt/posix/io.h
@@ -53,7 +53,7 @@ COBALT_SYSCALL_DECL(recvmsg,
 
 COBALT_SYSCALL_DECL(recvmmsg,
 		    (int fd, struct mmsghdr __user *u_msgvec, unsigned int vlen,
-		     unsigned int flags, struct timespec *u_timeout));
+		     unsigned int flags, struct __user_old_timespec __user *u_timeout));
 
 COBALT_SYSCALL_DECL(sendmsg,
 		    (int fd, struct user_msghdr __user *umsg, int flags));
diff --git a/kernel/cobalt/posix/monitor.c b/kernel/cobalt/posix/monitor.c
index 5237545bec..b907e0050a 100644
--- a/kernel/cobalt/posix/monitor.c
+++ b/kernel/cobalt/posix/monitor.c
@@ -203,7 +203,7 @@ drain:
 }
 
 int __cobalt_monitor_wait(struct cobalt_monitor_shadow __user *u_mon,
-			  int event, const struct timespec *ts,
+			  int event, const struct timespec64 *ts,
 			  int __user *u_ret)
 {
 	struct cobalt_thread *curr = cobalt_current_thread();
@@ -291,15 +291,15 @@ out:
 
 COBALT_SYSCALL(monitor_wait, nonrestartable,
 	       (struct cobalt_monitor_shadow __user *u_mon,
-	       int event, const struct timespec __user *u_ts,
+	       int event, const struct __user_old_timespec __user *u_ts,
 	       int __user *u_ret))
 {
-	struct timespec ts, *tsp = NULL;
+	struct timespec64 ts, *tsp = NULL;
 	int ret;
 
 	if (u_ts) {
 		tsp = &ts;
-		ret = cobalt_copy_from_user(&ts, u_ts, sizeof(ts));
+		ret = cobalt_get_u_timespec(&ts, u_ts);
 		if (ret)
 			return ret;
 	}
diff --git a/kernel/cobalt/posix/monitor.h b/kernel/cobalt/posix/monitor.h
index 8b321aaec6..d4a4aa24e5 100644
--- a/kernel/cobalt/posix/monitor.h
+++ b/kernel/cobalt/posix/monitor.h
@@ -39,7 +39,7 @@ struct cobalt_monitor {
 };
 
 int __cobalt_monitor_wait(struct cobalt_monitor_shadow __user *u_mon,
-			  int event, const struct timespec *ts,
+			  int event, const struct timespec64 *ts,
 			  int __user *u_ret);
 
 COBALT_SYSCALL_DECL(monitor_init,
@@ -58,7 +58,7 @@ COBALT_SYSCALL_DECL(monitor_exit,
 
 COBALT_SYSCALL_DECL(monitor_wait,
 		    (struct cobalt_monitor_shadow __user *u_monsh,
-		     int event, const struct timespec __user *u_ts,
+		     int event, const struct __user_old_timespec __user *u_ts,
 		     int __user *u_ret));
 
 COBALT_SYSCALL_DECL(monitor_destroy,
diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
index b58d111db8..dd8acd55b0 100644
--- a/kernel/cobalt/posix/mqueue.c
+++ b/kernel/cobalt/posix/mqueue.c
@@ -471,13 +471,13 @@ mq_tryrcv(struct cobalt_mqd *mqd, size_t len)
 static struct cobalt_msg *
 mq_timedsend_inner(struct cobalt_mqd *mqd,
 		   size_t len, const void __user *u_ts,
-		   int (*fetch_timeout)(struct timespec *ts,
+		   int (*fetch_timeout)(struct timespec64 *ts,
 					const void __user *u_ts))
 {
 	struct cobalt_mqwait_context mwc;
 	struct cobalt_msg *msg;
 	struct cobalt_mq *mq;
-	struct timespec ts;
+	struct timespec64 ts;
 	xntmode_t tmode;
 	xnticks_t to;
 	spl_t s;
@@ -600,13 +600,13 @@ static struct cobalt_msg *
 mq_timedrcv_inner(struct cobalt_mqd *mqd,
 		  size_t len,
 		  const void __user *u_ts,
-		  int (*fetch_timeout)(struct timespec *ts,
+		  int (*fetch_timeout)(struct timespec64 *ts,
 				       const void __user *u_ts))
 {
 	struct cobalt_mqwait_context mwc;
 	struct cobalt_msg *msg;
 	struct cobalt_mq *mq;
-	struct timespec ts;
+	struct timespec64 ts;
 	xntmode_t tmode;
 	xnticks_t to;
 	spl_t s;
@@ -883,16 +883,15 @@ COBALT_SYSCALL(mq_getattr, current,
 	return cobalt_copy_to_user(u_attr, &attr, sizeof(attr));
 }
 
-static inline int mq_fetch_timeout(struct timespec *ts,
+static inline int mq_fetch_timeout(struct timespec64 *ts,
 				   const void __user *u_ts)
 {
-	return u_ts == NULL ? -EFAULT :
-		cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
+	return u_ts == NULL ? -EFAULT : cobalt_get_u_timespec(ts, u_ts);
 }
 
 int __cobalt_mq_timedsend(mqd_t uqd, const void __user *u_buf, size_t len,
 			  unsigned int prio, const void __user *u_ts,
-			  int (*fetch_timeout)(struct timespec *ts,
+			  int (*fetch_timeout)(struct timespec64 *ts,
 					       const void __user *u_ts))
 {
 	struct cobalt_msg *msg;
@@ -936,7 +935,7 @@ out:
 
 COBALT_SYSCALL(mq_timedsend, primary,
 	       (mqd_t uqd, const void __user *u_buf, size_t len,
-		unsigned int prio, const struct timespec __user *u_ts))
+		unsigned int prio, const struct __user_old_timespec __user *u_ts))
 {
 	return __cobalt_mq_timedsend(uqd, u_buf, len, prio,
 				     u_ts, u_ts ? mq_fetch_timeout : NULL);
@@ -946,7 +945,7 @@ int __cobalt_mq_timedreceive(mqd_t uqd, void __user *u_buf,
 			     ssize_t *lenp,
 			     unsigned int __user *u_prio,
 			     const void __user *u_ts,
-			     int (*fetch_timeout)(struct timespec *ts,
+			     int (*fetch_timeout)(struct timespec64 *ts,
 						  const void __user *u_ts))
 {
 	struct cobalt_mqd *mqd;
@@ -997,7 +996,7 @@ COBALT_SYSCALL(mq_timedreceive, primary,
 	       (mqd_t uqd, void __user *u_buf,
 		ssize_t __user *u_len,
 		unsigned int __user *u_prio,
-		const struct timespec __user *u_ts))
+		const struct __user_old_timespec __user *u_ts))
 {
 	ssize_t len;
 	int ret;
diff --git a/kernel/cobalt/posix/mqueue.h b/kernel/cobalt/posix/mqueue.h
index acae2a4247..d33220227e 100644
--- a/kernel/cobalt/posix/mqueue.h
+++ b/kernel/cobalt/posix/mqueue.h
@@ -37,14 +37,14 @@ int __cobalt_mq_getattr(mqd_t uqd, struct mq_attr *attr);
 
 int __cobalt_mq_timedsend(mqd_t uqd, const void __user *u_buf, size_t len,
 			  unsigned int prio, const void __user *u_ts,
-			  int (*fetch_timeout)(struct timespec *ts,
+			  int (*fetch_timeout)(struct timespec64 *ts,
 					       const void __user *u_ts));
 
 int __cobalt_mq_timedreceive(mqd_t uqd, void __user *u_buf,
 			     ssize_t *lenp,
 			     unsigned int __user *u_prio,
 			     const void __user *u_ts,
-			     int (*fetch_timeout)(struct timespec *ts,
+			     int (*fetch_timeout)(struct timespec64 *ts,
 						  const void __user *u_ts));
 
 int __cobalt_mq_notify(mqd_t fd, const struct sigevent *evp);
@@ -61,12 +61,12 @@ COBALT_SYSCALL_DECL(mq_getattr, (mqd_t uqd, struct mq_attr __user *u_attr));
 
 COBALT_SYSCALL_DECL(mq_timedsend,
 		    (mqd_t uqd, const void __user *u_buf, size_t len,
-		     unsigned int prio, const struct timespec __user *u_ts));
+		     unsigned int prio, const struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(mq_timedreceive,
 		    (mqd_t uqd, void __user *u_buf, ssize_t __user *u_len,
 		     unsigned int __user *u_prio,
-		     const struct timespec __user *u_ts));
+		     const struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(mq_notify,
 		    (mqd_t fd, const struct sigevent *__user evp));
diff --git a/kernel/cobalt/posix/mutex.c b/kernel/cobalt/posix/mutex.c
index 79260b5448..70fe7960a0 100644
--- a/kernel/cobalt/posix/mutex.c
+++ b/kernel/cobalt/posix/mutex.c
@@ -71,7 +71,7 @@ static int cobalt_mutex_init_inner(struct cobalt_mutex_shadow *shadow,
 /* must be called with nklock locked, interrupts off. */
 int __cobalt_mutex_acquire_unchecked(struct xnthread *cur,
 				     struct cobalt_mutex *mutex,
-				     const struct timespec *ts)
+				     const struct timespec64 *ts)
 {
 	int ret;
 
@@ -134,11 +134,11 @@ int cobalt_mutex_release(struct xnthread *curr,
 
 int __cobalt_mutex_timedlock_break(struct cobalt_mutex_shadow __user *u_mx,
 				   const void __user *u_ts,
-				   int (*fetch_timeout)(struct timespec *ts,
+				   int (*fetch_timeout)(struct timespec64 *ts,
 							const void __user *u_ts))
 {
 	struct xnthread *curr = xnthread_current();
-	struct timespec ts, *tsp = NULL;
+	struct timespec64 ts, *tsp = NULL;
 	struct cobalt_mutex *mutex;
 	xnhandle_t handle;
 	spl_t s;
@@ -346,16 +346,15 @@ COBALT_SYSCALL(mutex_lock, primary,
 	return __cobalt_mutex_timedlock_break(u_mx, NULL, NULL);
 }
 
-static inline int mutex_fetch_timeout(struct timespec *ts,
+static inline int mutex_fetch_timeout(struct timespec64 *ts,
 				      const void __user *u_ts)
 {
-	return u_ts == NULL ? -EFAULT :
-		cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
+	return u_ts == NULL ? -EFAULT : cobalt_get_u_timespec(ts, u_ts);
 }
 
 COBALT_SYSCALL(mutex_timedlock, primary,
 	       (struct cobalt_mutex_shadow __user *u_mx,
-		const struct timespec __user *u_ts))
+		const struct __user_old_timespec __user *u_ts))
 {
 	return __cobalt_mutex_timedlock_break(u_mx, u_ts, mutex_fetch_timeout);
 }
diff --git a/kernel/cobalt/posix/mutex.h b/kernel/cobalt/posix/mutex.h
index ac1c50291d..d76f2a9ead 100644
--- a/kernel/cobalt/posix/mutex.h
+++ b/kernel/cobalt/posix/mutex.h
@@ -37,12 +37,12 @@ struct cobalt_mutex {
 
 int __cobalt_mutex_timedlock_break(struct cobalt_mutex_shadow __user *u_mx,
 				   const void __user *u_ts,
-				   int (*fetch_timeout)(struct timespec *ts,
+				   int (*fetch_timeout)(struct timespec64 *ts,
 							const void __user *u_ts));
 
 int __cobalt_mutex_acquire_unchecked(struct xnthread *cur,
 				     struct cobalt_mutex *mutex,
-				     const struct timespec *ts);
+				     const struct timespec64 *ts);
 
 COBALT_SYSCALL_DECL(mutex_check_init,
 		    (struct cobalt_mutex_shadow __user *u_mx));
@@ -62,7 +62,7 @@ COBALT_SYSCALL_DECL(mutex_lock,
 
 COBALT_SYSCALL_DECL(mutex_timedlock,
 		    (struct cobalt_mutex_shadow __user *u_mx,
-		     const struct timespec __user *u_ts));
+		     const struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(mutex_unlock,
 		    (struct cobalt_mutex_shadow __user *u_mx));
diff --git a/kernel/cobalt/posix/sched.c b/kernel/cobalt/posix/sched.c
index 798a172d7f..4fd9c2b46e 100644
--- a/kernel/cobalt/posix/sched.c
+++ b/kernel/cobalt/posix/sched.c
@@ -73,7 +73,7 @@ cobalt_sched_policy_param(union xnsched_policy_param *param,
 		break;
 	case SCHED_RR:
 		/* if unspecified, use current one. */
-		tslice = ts2ns(&param_ex->sched_rr_quantum);
+		tslice = u_ts2ns(&param_ex->sched_rr_quantum);
 		if (tslice == XN_INFINITE && tslice_r)
 			tslice = *tslice_r;
 		/* fallthrough */
@@ -92,8 +92,8 @@ cobalt_sched_policy_param(union xnsched_policy_param *param,
 		param->pss.normal_prio = param_ex->sched_priority;
 		param->pss.low_prio = param_ex->sched_ss_low_priority;
 		param->pss.current_prio = param->pss.normal_prio;
-		param->pss.init_budget = ts2ns(&param_ex->sched_ss_init_budget);
-		param->pss.repl_period = ts2ns(&param_ex->sched_ss_repl_period);
+		param->pss.init_budget = u_ts2ns(&param_ex->sched_ss_init_budget);
+		param->pss.repl_period = u_ts2ns(&param_ex->sched_ss_repl_period);
 		param->pss.max_repl = param_ex->sched_ss_max_repl;
 		sched_class = &xnsched_class_sporadic;
 		break;
@@ -280,11 +280,11 @@ int set_tp_config(int cpu, union sched_config *config, size_t len)
 		 * be defined using windows assigned to the pseudo
 		 * partition #-1.
 		 */
-		offset = ts2ns(&p->offset);
+		offset = u_ts2ns(&p->offset);
 		if (offset != next_offset)
 			goto cleanup_and_fail;
 
-		duration = ts2ns(&p->duration);
+		duration = u_ts2ns(&p->duration);
 		if (duration <= 0)
 			goto cleanup_and_fail;
 
@@ -357,11 +357,11 @@ ssize_t get_tp_config(int cpu, void __user *u_config, size_t len,
 	config->tp.nr_windows = gps->pwin_nr;
 	for (n = 0, pp = p = config->tp.windows, pw = w = gps->pwins;
 	     n < gps->pwin_nr; pp = p, p++, pw = w, w++, n++) {
-		ns2ts(&p->offset, w->w_offset);
-		ns2ts(&pp->duration, w->w_offset - pw->w_offset);
+		u_ns2ts(&p->offset, w->w_offset);
+		u_ns2ts(&pp->duration, w->w_offset - pw->w_offset);
 		p->ptid = w->w_part;
 	}
-	ns2ts(&pp->duration, gps->tf_duration - pw->w_offset);
+	u_ns2ts(&pp->duration, gps->tf_duration - pw->w_offset);
 	ret = put_config(SCHED_TP, u_config, len, config, elen);
 	xnfree(config);
 out:
diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index 05a861dfe3..467a9b7dd6 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -267,7 +267,7 @@ out:
 	return ret;
 }
 
-static inline int sem_fetch_timeout(struct timespec *ts,
+static inline int sem_fetch_timeout(struct timespec64 *ts,
 				    const void __user *u_ts)
 {
 	return u_ts == NULL ? -EFAULT :
@@ -276,10 +276,10 @@ static inline int sem_fetch_timeout(struct timespec *ts,
 
 int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user *u_sem,
 			   const void __user *u_ts,
-			   int (*fetch_timeout)(struct timespec *ts,
+			   int (*fetch_timeout)(struct timespec64 *ts,
 						const void __user *u_ts))
 {
-	struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
+	struct timespec64 ts = { .tv_sec = 0, .tv_nsec = 0 };
 	int pull_ts = 1, ret, info;
 	struct cobalt_sem *sem;
 	xnhandle_t handle;
@@ -434,7 +434,7 @@ COBALT_SYSCALL(sem_wait, primary,
 
 COBALT_SYSCALL(sem_timedwait, primary,
 	       (struct cobalt_sem_shadow __user *u_sem,
-		struct timespec __user *u_ts))
+		struct __user_old_timespec __user *u_ts))
 {
 	return __cobalt_sem_timedwait(u_sem, u_ts, sem_fetch_timeout);
 }
diff --git a/kernel/cobalt/posix/sem.h b/kernel/cobalt/posix/sem.h
index 17238078e5..d172994950 100644
--- a/kernel/cobalt/posix/sem.h
+++ b/kernel/cobalt/posix/sem.h
@@ -65,7 +65,7 @@ __cobalt_sem_open(struct cobalt_sem_shadow __user *usm,
 
 int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user *u_sem,
 			   const void __user *u_ts,
-			   int (*fetch_timeout)(struct timespec *ts,
+			   int (*fetch_timeout)(struct timespec64 *ts,
 						const void __user *u_ts));
 
 int __cobalt_sem_destroy(xnhandle_t handle);
@@ -91,7 +91,7 @@ COBALT_SYSCALL_DECL(sem_wait,
 
 COBALT_SYSCALL_DECL(sem_timedwait,
 		    (struct cobalt_sem_shadow __user *u_sem,
-		     struct timespec __user *u_ts));
+		     struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(sem_trywait,
 		    (struct cobalt_sem_shadow __user *u_sem));
diff --git a/kernel/cobalt/posix/signal.c b/kernel/cobalt/posix/signal.c
index 862a644c0b..0b43b5fcfa 100644
--- a/kernel/cobalt/posix/signal.c
+++ b/kernel/cobalt/posix/signal.c
@@ -407,7 +407,7 @@ COBALT_SYSCALL(sigwait, primary,
 }
 
 int __cobalt_sigtimedwait(sigset_t *set,
-			  const struct timespec *timeout,
+			  const struct timespec64 *timeout,
 			  void __user *u_si,
 			  bool compat)
 {
@@ -426,9 +426,9 @@ int __cobalt_sigtimedwait(sigset_t *set,
 COBALT_SYSCALL(sigtimedwait, nonrestartable,
 	       (const sigset_t __user *u_set,
 		struct siginfo __user *u_si,
-		const struct timespec __user *u_timeout))
+		const struct __user_old_timespec __user *u_timeout))
 {
-	struct timespec timeout;
+	struct timespec64 timeout;
 	sigset_t set;
 
 	if (cobalt_copy_from_user(&set, u_set, sizeof(set)))
diff --git a/kernel/cobalt/posix/signal.h b/kernel/cobalt/posix/signal.h
index 7a0b4b22b8..fc26ad0653 100644
--- a/kernel/cobalt/posix/signal.h
+++ b/kernel/cobalt/posix/signal.h
@@ -59,7 +59,7 @@ void cobalt_copy_siginfo(int code,
 int __cobalt_sigwait(sigset_t *set);
 
 int __cobalt_sigtimedwait(sigset_t *set,
-			  const struct timespec *timeout,
+			  const struct timespec64 *timeout,
 			  void __user *u_si,
 			  bool compat);
 
@@ -94,7 +94,7 @@ COBALT_SYSCALL_DECL(sigwait,
 COBALT_SYSCALL_DECL(sigtimedwait,
 		    (const sigset_t __user *u_set,
 		     struct siginfo __user *u_si,
-		     const struct timespec __user *u_timeout));
+		     const struct __user_old_timespec __user *u_timeout));
 
 COBALT_SYSCALL_DECL(sigwaitinfo,
 		    (const sigset_t __user *u_set,
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index cb02dacd3d..ae25a6e743 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -97,7 +97,7 @@ COBALT_SYSCALL32emu(thread_setschedprio, conforming,
 	return cobalt_thread_setschedprio(pth, prio, u_winoff, u_promoted);
 }
 
-static inline int sys32_fetch_timeout(struct timespec *ts,
+static inline int sys32_fetch_timeout(struct timespec64 *ts,
 				      const void __user *u_ts)
 {
 	return u_ts == NULL ? -EFAULT :
@@ -133,7 +133,7 @@ COBALT_SYSCALL32emu(clock_getres, current,
 		    (clockid_t clock_id,
 		     struct compat_timespec __user *u_ts))
 {
-	struct timespec ts;
+	struct timespec64 ts;
 	int ret;
 
 	ret = __cobalt_clock_getres(clock_id, &ts);
@@ -147,7 +147,7 @@ COBALT_SYSCALL32emu(clock_gettime, current,
 		    (clockid_t clock_id,
 		     struct compat_timespec __user *u_ts))
 {
-	struct timespec ts;
+	struct timespec64 ts;
 	int ret;
 
 	ret = __cobalt_clock_gettime(clock_id, &ts);
@@ -161,7 +161,7 @@ COBALT_SYSCALL32emu(clock_settime, current,
 		    (clockid_t clock_id,
 		     const struct compat_timespec __user *u_ts))
 {
-	struct timespec ts;
+	struct timespec64 ts;
 	int ret;
 
 	ret = sys32_get_timespec(&ts, u_ts);
@@ -193,7 +193,7 @@ COBALT_SYSCALL32emu(clock_nanosleep, nonrestartable,
 		     const struct compat_timespec __user *u_rqt,
 		     struct compat_timespec __user *u_rmt))
 {
-	struct timespec rqt, rmt, *rmtp = NULL;
+	struct timespec64 rqt, rmt, *rmtp = NULL;
 	int ret;
 
 	if (u_rmt)
@@ -289,12 +289,10 @@ COBALT_SYSCALL32emu(mq_timedreceive, primary,
 	return ret ?: cobalt_copy_to_user(u_len, &clen, sizeof(*u_len));
 }
 
-static inline int mq_fetch_timeout(struct timespec *ts,
+static inline int mq_fetch_timeout(struct timespec64 *ts,
 				   const void __user *u_ts)
 {
-	return u_ts == NULL ? -EFAULT :
-		cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
-
+	return u_ts == NULL ? -EFAULT : cobalt_get_u_timespec(ts, u_ts);
 }
 
 COBALT_SYSCALL32emu(mq_notify, primary,
@@ -610,7 +608,7 @@ COBALT_SYSCALL32emu(sigtimedwait, nonrestartable,
 		     struct compat_siginfo __user *u_si,
 		     const struct compat_timespec __user *u_timeout))
 {
-	struct timespec timeout;
+	struct timespec64 timeout;
 	sigset_t set;
 	int ret;
 
@@ -663,7 +661,7 @@ COBALT_SYSCALL32emu(monitor_wait, nonrestartable,
 		     int event, const struct compat_timespec __user *u_ts,
 		     int __user *u_ret))
 {
-	struct timespec ts, *tsp = NULL;
+	struct timespec64 ts, *tsp = NULL;
 	int ret;
 
 	if (u_ts) {
@@ -682,7 +680,7 @@ COBALT_SYSCALL32emu(event_wait, primary,
 		     unsigned int __user *u_bits_r,
 		     int mode, const struct compat_timespec __user *u_ts))
 {
-	struct timespec ts, *tsp = NULL;
+	struct timespec64 ts, *tsp = NULL;
 	int ret;
 
 	if (u_ts) {
@@ -810,7 +808,7 @@ COBALT_SYSCALL32emu(recvmsg, handover,
 	return sys32_put_msghdr(umsg, &m) ?: ret;
 }
 
-static int get_timespec32(struct timespec *ts,
+static int get_timespec32(struct timespec64 *ts,
 			  const void __user *u_ts)
 {
 	return sys32_get_timespec(ts, u_ts);
@@ -924,7 +922,7 @@ COBALT_SYSCALL32x(mq_timedreceive, primary,
 		  (mqd_t uqd, void __user *u_buf,
 		   compat_ssize_t __user *u_len,
 		   unsigned int __user *u_prio,
-		   const struct timespec __user *u_ts))
+		   const struct __user_old_timespec __user *u_ts))
 {
 	compat_ssize_t clen;
 	ssize_t len;
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index eb3e4bd300..9da4052297 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -105,7 +105,7 @@ COBALT_SYSCALL32x_DECL(mq_timedreceive,
 		       (mqd_t uqd, void __user *u_buf,
 			compat_ssize_t __user *u_len,
 			unsigned int __user *u_prio,
-			const struct timespec __user *u_ts));
+			const struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL32emu_DECL(mq_notify,
 			 (mqd_t fd, const struct compat_sigevent *__user u_cev));
diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c
index bf9c082123..cdeb66d4f3 100644
--- a/kernel/cobalt/posix/thread.c
+++ b/kernel/cobalt/posix/thread.c
@@ -302,7 +302,7 @@ int __cobalt_thread_getschedparam_ex(struct cobalt_thread *thread,
 
 	if (base_class == &xnsched_class_rt) {
 		if (xnthread_test_state(base_thread, XNRRB)) {
-			ns2ts(&param_ex->sched_rr_quantum, base_thread->rrperiod);
+			u_ns2ts(&param_ex->sched_rr_quantum, base_thread->rrperiod);
 			*policy_r = SCHED_RR;
 		}
 		goto out;
@@ -318,8 +318,8 @@ int __cobalt_thread_getschedparam_ex(struct cobalt_thread *thread,
 #ifdef CONFIG_XENO_OPT_SCHED_SPORADIC
 	if (base_class == &xnsched_class_sporadic) {
 		param_ex->sched_ss_low_priority = base_thread->pss->param.low_prio;
-		ns2ts(&param_ex->sched_ss_repl_period, base_thread->pss->param.repl_period);
-		ns2ts(&param_ex->sched_ss_init_budget, base_thread->pss->param.init_budget);
+		u_ns2ts(&param_ex->sched_ss_repl_period, base_thread->pss->param.repl_period);
+		u_ns2ts(&param_ex->sched_ss_init_budget, base_thread->pss->param.init_budget);
 		param_ex->sched_ss_max_repl = base_thread->pss->param.max_repl;
 		goto out;
 	}
diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
index 7956a88008..038247d54f 100644
--- a/kernel/cobalt/rtdm/fd.c
+++ b/kernel/cobalt/rtdm/fd.c
@@ -650,11 +650,11 @@ int __rtdm_fd_recvmmsg(int ufd, void __user *u_msgvec, unsigned int vlen,
 		       unsigned int flags, void __user *u_timeout,
 		       int (*get_mmsg)(struct mmsghdr *mmsg, void __user *u_mmsg),
 		       int (*put_mmsg)(void __user **u_mmsg_p, const struct mmsghdr *mmsg),
-		       int (*get_timespec)(struct timespec *ts, const void __user *u_ts))
+		       int (*get_timespec)(struct timespec64 *ts, const void __user *u_ts))
 {
 	struct cobalt_recvmmsg_timer rq;
 	xntmode_t tmode = XN_RELATIVE;
-	struct timespec ts = { 0 };
+	struct timespec64 ts = { 0 };
 	int ret = 0, datagrams = 0;
 	xnticks_t timeout = 0;
 	struct mmsghdr mmsg;
diff --git a/kernel/cobalt/trace/cobalt-posix.h b/kernel/cobalt/trace/cobalt-posix.h
index aa78efbc01..3a649a6712 100644
--- a/kernel/cobalt/trace/cobalt-posix.h
+++ b/kernel/cobalt/trace/cobalt-posix.h
@@ -30,7 +30,7 @@
 #include <xenomai/posix/event.h>
 
 #define __timespec_fields(__name)				\
-	__field(__kernel_time_t, tv_sec_##__name)		\
+	__field(time64_t, tv_sec_##__name)			\
 	__field(long, tv_nsec_##__name)
 
 #define __assign_timespec(__to, __from)				\
@@ -40,7 +40,7 @@
 	} while (0)
 
 #define __timespec_args(__name)					\
-	__entry->tv_sec_##__name, __entry->tv_nsec_##__name
+	(long long)__entry->tv_sec_##__name, __entry->tv_nsec_##__name
 
 #ifdef CONFIG_X86_X32
 #define __sc_x32(__name)	, { sc_cobalt_##__name + __COBALT_X32_BASE, "x32-" #__name }
@@ -729,7 +729,7 @@ TRACE_EVENT(cobalt_psem_unlink,
 );
 
 DECLARE_EVENT_CLASS(cobalt_clock_timespec,
-	TP_PROTO(clockid_t clk_id, const struct timespec *val),
+	TP_PROTO(clockid_t clk_id, const struct timespec64 *val),
 	TP_ARGS(clk_id, val),
 
 	TP_STRUCT__entry(
@@ -742,24 +742,24 @@ DECLARE_EVENT_CLASS(cobalt_clock_timespec,
 		__assign_timespec(val, val);
 	),
 
-	TP_printk("clock_id=%d timeval=(%ld.%09ld)",
+	TP_printk("clock_id=%d timeval=(%lld.%09ld)",
 		  __entry->clk_id,
 		  __timespec_args(val)
 	)
 );
 
 DEFINE_EVENT(cobalt_clock_timespec, cobalt_clock_getres,
-	TP_PROTO(clockid_t clk_id, const struct timespec *res),
+	TP_PROTO(clockid_t clk_id, const struct timespec64 *res),
 	TP_ARGS(clk_id, res)
 );
 
 DEFINE_EVENT(cobalt_clock_timespec, cobalt_clock_gettime,
-	TP_PROTO(clockid_t clk_id, const struct timespec *time),
+	TP_PROTO(clockid_t clk_id, const struct timespec64 *time),
 	TP_ARGS(clk_id, time)
 );
 
 DEFINE_EVENT(cobalt_clock_timespec, cobalt_clock_settime,
-	TP_PROTO(clockid_t clk_id, const struct timespec *time),
+	TP_PROTO(clockid_t clk_id, const struct timespec64 *time),
 	TP_ARGS(clk_id, time)
 );
 
@@ -788,7 +788,7 @@ TRACE_EVENT(cobalt_clock_adjtime,
 		      {TIMER_ABSTIME, "TIMER_ABSTIME"})
 
 TRACE_EVENT(cobalt_clock_nanosleep,
-	TP_PROTO(clockid_t clk_id, int flags, const struct timespec *time),
+	TP_PROTO(clockid_t clk_id, int flags, const struct timespec64 *time),
 	TP_ARGS(clk_id, flags, time),
 
 	TP_STRUCT__entry(
@@ -803,7 +803,7 @@ TRACE_EVENT(cobalt_clock_nanosleep,
 		__assign_timespec(time, time);
 	),
 
-	TP_printk("clock_id=%d flags=%#x(%s) rqt=(%ld.%09ld)",
+	TP_printk("clock_id=%d flags=%#x(%s) rqt=(%lld.%09ld)",
 		  __entry->clk_id,
 		  __entry->flags, cobalt_print_timer_flags(__entry->flags),
 		  __timespec_args(time)
@@ -875,7 +875,7 @@ TRACE_EVENT(cobalt_cond_destroy,
 TRACE_EVENT(cobalt_cond_timedwait,
 	TP_PROTO(const struct cobalt_cond_shadow __user *u_cnd,
 		 const struct cobalt_mutex_shadow __user *u_mx,
-		 const struct timespec *timeout),
+		 const struct timespec64 *timeout),
 	TP_ARGS(u_cnd, u_mx, timeout),
 	TP_STRUCT__entry(
 		__field(const struct cobalt_cond_shadow __user *, u_cnd)
@@ -887,7 +887,7 @@ TRACE_EVENT(cobalt_cond_timedwait,
 		__entry->u_mx = u_mx;
 		__assign_timespec(timeout, timeout);
 	),
-	TP_printk("cond=%p, mutex=%p, timeout=(%ld.%09ld)",
+	TP_printk("cond=%p, mutex=%p, timeout=(%lld.%09ld)",
 		  __entry->u_cnd, __entry->u_mx, __timespec_args(timeout))
 );
 
@@ -1001,7 +1001,7 @@ TRACE_EVENT(cobalt_mq_send,
 
 TRACE_EVENT(cobalt_mq_timedreceive,
 	TP_PROTO(mqd_t mqd, const void __user *u_buf, size_t len,
-		 const struct timespec *timeout),
+		 const struct timespec64 *timeout),
 	TP_ARGS(mqd, u_buf, len, timeout),
 	TP_STRUCT__entry(
 		__field(mqd_t, mqd)
@@ -1015,7 +1015,7 @@ TRACE_EVENT(cobalt_mq_timedreceive,
 		__entry->len = len;
 		__assign_timespec(timeout, timeout);
 	),
-	TP_printk("mqd=%d buf=%p len=%zu timeout=(%ld.%09ld)",
+	TP_printk("mqd=%d buf=%p len=%zu timeout=(%lld.%09ld)",
 		  __entry->mqd, __entry->u_buf, __entry->len,
 		  __timespec_args(timeout))
 );
@@ -1105,7 +1105,7 @@ TRACE_EVENT(cobalt_event_init,
 TRACE_EVENT(cobalt_event_timedwait,
 	TP_PROTO(const struct cobalt_event_shadow __user *u_event,
 		 unsigned long bits, int mode,
-		 const struct timespec *timeout),
+		 const struct timespec64 *timeout),
 	TP_ARGS(u_event, bits, mode, timeout),
 	TP_STRUCT__entry(
 		__field(const struct cobalt_event_shadow __user *, u_event)
@@ -1119,7 +1119,7 @@ TRACE_EVENT(cobalt_event_timedwait,
 		__entry->mode = mode;
 		__assign_timespec(timeout, timeout);
 	),
-	TP_printk("event=%p bits=%#lx mode=%#x(%s) timeout=(%ld.%09ld)",
+	TP_printk("event=%p bits=%#lx mode=%#x(%s) timeout=(%lld.%09ld)",
 		  __entry->u_event, __entry->bits, __entry->mode,
 		  cobalt_print_evmode(__entry->mode),
 		  __timespec_args(timeout))
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v2 2/9] lib: y2038: convert to internal timespec type
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 1/9] cobalt/kernel: y2038: convert struct timespec to timespec64 Jan Kiszka
@ 2021-05-05 16:53 ` Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 3/9] cobalt/kernel: y2038: convert struct itimerspec to itimerspec64 Jan Kiszka
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:53 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 lib/alchemy/task.c          | 9 ++++++---
 lib/copperplate/threadobj.c | 9 ++++++---
 lib/psos/task.c             | 9 ++++++---
 lib/vxworks/kernLib.c       | 6 ++++--
 lib/vxworks/taskLib.c       | 6 ++++--
 5 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/lib/alchemy/task.c b/lib/alchemy/task.c
index 949a996d00..9afa2af579 100644
--- a/lib/alchemy/task.c
+++ b/lib/alchemy/task.c
@@ -1410,11 +1410,14 @@ int rt_task_slice(RT_TASK *task, RTIME quantum)
 
 	param_ex.sched_priority = threadobj_get_priority(&tcb->thobj);
 	if (quantum) {
+		struct timespec ts;
 		policy = SCHED_RR;
-		clockobj_ticks_to_timespec(&alchemy_clock, quantum,
-					   &param_ex.sched_rr_quantum);
-	} else
+		clockobj_ticks_to_timespec(&alchemy_clock, quantum, &ts);
+		param_ex.sched_rr_quantum.tv_sec = ts.tv_sec;
+		param_ex.sched_rr_quantum.tv_nsec = ts.tv_nsec;
+	} else {
 		policy = param_ex.sched_priority ? SCHED_FIFO : SCHED_OTHER;
+	}
 
 	ret = threadobj_set_schedparam(&tcb->thobj, policy, &param_ex);
 	switch (ret) {
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index a3101baa15..f4588a17a8 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -1741,7 +1741,8 @@ int threadobj_set_schedparam(struct threadobj *thobj, int policy,
 		ret = enable_rr_corespec(thobj, param_ex);
 		if (ret)
 			return __bt(ret);
-		thobj->tslice = param_ex->sched_rr_quantum;
+		thobj->tslice.tv_sec = param_ex->sched_rr_quantum.tv_sec;
+		thobj->tslice.tv_nsec = param_ex->sched_rr_quantum.tv_nsec;
 	} else if (thobj->policy == SCHED_RR) /* Switching off round-robin. */
 		disable_rr_corespec(thobj);
 
@@ -1761,8 +1762,10 @@ int threadobj_set_schedprio(struct threadobj *thobj, int priority)
 	param_ex.sched_priority = priority;
 	policy = thobj->policy;
 
-	if (policy == SCHED_RR)
-		param_ex.sched_rr_quantum = thobj->tslice;
+	if (policy == SCHED_RR) {
+		param_ex.sched_rr_quantum.tv_sec = thobj->tslice.tv_sec;
+		param_ex.sched_rr_quantum.tv_nsec = thobj->tslice.tv_nsec;
+	}
 
 	return threadobj_set_schedparam(thobj, policy, &param_ex);
 }
diff --git a/lib/psos/task.c b/lib/psos/task.c
index 46e49ea888..f678be61d1 100644
--- a/lib/psos/task.c
+++ b/lib/psos/task.c
@@ -192,7 +192,8 @@ static void *task_trampoline(void *arg)
 
 	if (task->mode & T_TSLICE) {
 		param_ex.sched_priority = threadobj_get_priority(&task->thobj);
-		param_ex.sched_rr_quantum = psos_rrperiod;
+		param_ex.sched_rr_quantum.tv_sec = psos_rrperiod.tv_sec;
+		param_ex.sched_rr_quantum.tv_nsec = psos_rrperiod.tv_nsec;
 		threadobj_set_schedparam(&task->thobj, SCHED_RR, &param_ex);
 	}
 
@@ -630,9 +631,11 @@ u_long t_mode(u_long mask, u_long newmask, u_long *oldmode_r)
 
 	if (task->mode & T_TSLICE) {
 		policy = SCHED_RR;
-		param_ex.sched_rr_quantum = psos_rrperiod;
-	} else
+		param_ex.sched_rr_quantum.tv_sec = psos_rrperiod.tv_sec;
+		param_ex.sched_rr_quantum.tv_nsec = psos_rrperiod.tv_nsec;
+	} else {
 		policy = param_ex.sched_priority ? SCHED_FIFO : SCHED_OTHER;
+	}
 
 	/* Working on self, so -EIDRM can't happen. */
 	threadobj_set_schedparam(&task->thobj, policy, &param_ex);
diff --git a/lib/vxworks/kernLib.c b/lib/vxworks/kernLib.c
index 4f3bd82015..d67502730d 100644
--- a/lib/vxworks/kernLib.c
+++ b/lib/vxworks/kernLib.c
@@ -30,9 +30,11 @@ static int switch_slicing(struct threadobj *thobj, struct timespec *quantum)
 
 	if (quantum) {
 		policy = SCHED_RR;
-		param_ex.sched_rr_quantum = *quantum;
-	} else
+		param_ex.sched_rr_quantum.tv_sec = quantum->tv_sec;
+		param_ex.sched_rr_quantum.tv_nsec = quantum->tv_nsec;
+	} else {
 		policy = param_ex.sched_priority ? SCHED_FIFO : SCHED_OTHER;
+	}
 
 	return threadobj_set_schedparam(thobj, policy, &param_ex);
 }
diff --git a/lib/vxworks/taskLib.c b/lib/vxworks/taskLib.c
index a4af36c1f9..c8723c6be6 100644
--- a/lib/vxworks/taskLib.c
+++ b/lib/vxworks/taskLib.c
@@ -265,8 +265,10 @@ static void *task_trampoline(void *arg)
 
 	/* Turn on time slicing if RR globally enabled. */
 	if (wind_time_slice) {
-		clockobj_ticks_to_timespec(&wind_clock, wind_time_slice,
-					   &param_ex.sched_rr_quantum);
+		struct timespec ts;
+		clockobj_ticks_to_timespec(&wind_clock, wind_time_slice, &ts);
+		param_ex.sched_rr_quantum.tv_sec = ts.tv_sec;
+		param_ex.sched_rr_quantum.tv_nsec = ts.tv_nsec;
 		threadobj_lock(&task->thobj);
 		param_ex.sched_priority = threadobj_get_priority(&task->thobj);
 		threadobj_set_schedparam(&task->thobj, SCHED_RR, &param_ex);
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v2 3/9] cobalt/kernel: y2038: convert struct itimerspec to itimerspec64
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 1/9] cobalt/kernel: y2038: convert struct timespec to timespec64 Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 2/9] lib: y2038: convert to internal timespec type Jan Kiszka
@ 2021-05-05 16:53 ` Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 4/9] cobalt/kernel: y2038: convert struct timex to __kernel_timex Jan Kiszka
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:53 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

As internal interfaces are gradually being made y2038-safe, the
itimerspec64 type should be used internally by the kernel to represent
interval timer specs. Apply the same reasoning to Cobalt.

We still use a legacy y2038-unsafe itimerspec type at the
kernel<->user interface boundary (struct __user_old_itimerspec) until
libcobalt is y2038-safe.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/compat.h                |  4 +-
 include/cobalt/uapi/kernel/types.h            |  5 ++
 .../include/asm-generic/xenomai/syscall.h     | 47 ++++++++++++++++++-
 kernel/cobalt/posix/compat.c                  |  4 +-
 kernel/cobalt/posix/extension.h               |  4 +-
 kernel/cobalt/posix/syscall32.c               |  8 ++--
 kernel/cobalt/posix/timer.c                   | 30 ++++++------
 kernel/cobalt/posix/timer.h                   | 16 +++----
 kernel/cobalt/posix/timerfd.c                 | 22 ++++-----
 kernel/cobalt/posix/timerfd.h                 | 12 ++---
 10 files changed, 101 insertions(+), 51 deletions(-)

diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
index c57ef65325..7bec8c3be5 100644
--- a/include/cobalt/kernel/compat.h
+++ b/include/cobalt/kernel/compat.h
@@ -92,11 +92,11 @@ int sys32_get_timespec(struct timespec64 *ts,
 int sys32_put_timespec(struct compat_timespec __user *cts,
 		       const struct timespec64 *ts);
 
-int sys32_get_itimerspec(struct itimerspec *its,
+int sys32_get_itimerspec(struct itimerspec64 *its,
 			 const struct compat_itimerspec __user *cits);
 
 int sys32_put_itimerspec(struct compat_itimerspec __user *cits,
-			 const struct itimerspec *its);
+			 const struct itimerspec64 *its);
 
 int sys32_get_timeval(struct __kernel_old_timeval *tv,
 		      const struct compat_timeval __user *ctv);
diff --git a/include/cobalt/uapi/kernel/types.h b/include/cobalt/uapi/kernel/types.h
index 8ce9b03df4..10abbb55a5 100644
--- a/include/cobalt/uapi/kernel/types.h
+++ b/include/cobalt/uapi/kernel/types.h
@@ -67,4 +67,9 @@ struct __user_old_timespec {
 	long  tv_nsec;
 };
 
+struct __user_old_itimerspec {
+	struct __user_old_timespec it_interval;
+	struct __user_old_timespec it_value;
+};
+
 #endif /* !_COBALT_UAPI_KERNEL_TYPES_H */
diff --git a/kernel/cobalt/include/asm-generic/xenomai/syscall.h b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
index 05a7d28685..91bbf3bfd1 100644
--- a/kernel/cobalt/include/asm-generic/xenomai/syscall.h
+++ b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
@@ -86,7 +86,7 @@ static inline int cobalt_strncpy_from_user(char *dst, const char __user *src,
 
 /*
  * NOTE: those copy helpers won't work in compat mode: use
- * sys32_get_timespec(), sys32_put_timespec() instead.
+ * sys32_get_*(), sys32_put_*() instead.
  */
 
 static inline int cobalt_get_u_timespec(struct timespec64 *dst,
@@ -102,6 +102,19 @@ static inline int cobalt_put_u_timespec(
 	return cobalt_copy_to_user(dst, src, sizeof(*dst));
 }
 
+static inline int cobalt_get_u_itimerspec(struct itimerspec64 *dst,
+			const struct __user_old_itimerspec __user *src)
+{
+	return cobalt_copy_from_user(dst, src, sizeof(*dst));
+}
+
+static inline int cobalt_put_u_itimerspec(
+	struct __user_old_itimerspec __user *dst,
+	const struct itimerspec64 *src)
+{
+	return cobalt_copy_to_user(dst, src, sizeof(*dst));
+}
+
 #else /* __BITS_PER_LONG == 32 */
 
 static inline int cobalt_get_u_timespec(struct timespec64 *dst,
@@ -137,6 +150,38 @@ static inline int cobalt_put_u_timespec(
 	return 0;
 }
 
+static inline int cobalt_get_u_itimerspec(struct itimerspec64 *dst,
+			const struct __user_old_itimerspec __user *src)
+{
+	struct __user_old_itimerspec u_its;
+	int ret;
+
+	ret = cobalt_copy_from_user(&u_its, src, sizeof(u_its));
+	if (ret)
+		return ret;
+
+	dst->it_interval.tv_sec = u_its.it_interval.tv_sec;
+	dst->it_interval.tv_nsec = u_its.it_interval.tv_nsec;
+	dst->it_value.tv_sec = u_its.it_value.tv_sec;
+	dst->it_value.tv_nsec = u_its.it_value.tv_nsec;
+
+	return 0;
+}
+
+static inline int cobalt_put_u_itimerspec(
+	struct __user_old_itimerspec __user *dst,
+	const struct itimerspec64 *src)
+{
+	struct __user_old_itimerspec u_its;
+
+	u_its.it_interval.tv_sec = src->it_interval.tv_sec;
+	u_its.it_interval.tv_nsec = src->it_interval.tv_nsec;
+	u_its.it_value.tv_sec = src->it_value.tv_sec;
+	u_its.it_value.tv_nsec = src->it_value.tv_nsec;
+
+	return cobalt_copy_to_user(dst, &u_its, sizeof(*dst));
+}
+
 #endif
 
 /* 32bit syscall emulation */
diff --git a/kernel/cobalt/posix/compat.c b/kernel/cobalt/posix/compat.c
index 1852950821..767a8033a6 100644
--- a/kernel/cobalt/posix/compat.c
+++ b/kernel/cobalt/posix/compat.c
@@ -60,7 +60,7 @@ int sys32_put_timespec(struct compat_timespec __user *u_cts,
 }
 EXPORT_SYMBOL_GPL(sys32_put_timespec);
 
-int sys32_get_itimerspec(struct itimerspec *its,
+int sys32_get_itimerspec(struct itimerspec64 *its,
 			 const struct compat_itimerspec __user *cits)
 {
 	int ret = sys32_get_timespec(&its->it_value, &cits->it_value);
@@ -70,7 +70,7 @@ int sys32_get_itimerspec(struct itimerspec *its,
 EXPORT_SYMBOL_GPL(sys32_get_itimerspec);
 
 int sys32_put_itimerspec(struct compat_itimerspec __user *cits,
-			 const struct itimerspec *its)
+			 const struct itimerspec64 *its)
 {
 	int ret = sys32_put_timespec(&cits->it_value, &its->it_value);
 
diff --git a/kernel/cobalt/posix/extension.h b/kernel/cobalt/posix/extension.h
index ae365c7874..e23c26ccca 100644
--- a/kernel/cobalt/posix/extension.h
+++ b/kernel/cobalt/posix/extension.h
@@ -39,10 +39,10 @@ struct cobalt_extension {
 		(*timer_init)(struct cobalt_extref *reftimer, /* nklocked, IRQs off. */
 			      const struct sigevent *__restrict__ evp);
 		int (*timer_settime)(struct cobalt_extref *reftimer, /* nklocked, IRQs off. */
-				     const struct itimerspec *__restrict__ value,
+				     const struct itimerspec64 *__restrict__ value,
 				     int flags);
 		int (*timer_gettime)(struct cobalt_extref *reftimer, /* nklocked, IRQs off. */
-				     struct itimerspec *__restrict__ value);
+				     struct itimerspec64 *__restrict__ value);
 		int (*timer_delete)(struct cobalt_extref *reftimer); /* nklocked, IRQs off. */
 		int (*timer_cleanup)(struct cobalt_extref *reftimer); /* nklocked, IRQs off. */
 		int (*signal_deliver)(struct cobalt_extref *refthread,
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index ae25a6e743..5c858806b6 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -514,7 +514,7 @@ COBALT_SYSCALL32emu(timer_settime, primary,
 		     const struct compat_itimerspec __user *u_newval,
 		     struct compat_itimerspec __user *u_oldval))
 {
-	struct itimerspec newv, oldv, *oldvp = &oldv;
+	struct itimerspec64 newv, oldv, *oldvp = &oldv;
 	int ret;
 
 	if (u_oldval == NULL)
@@ -540,7 +540,7 @@ COBALT_SYSCALL32emu(timer_settime, primary,
 COBALT_SYSCALL32emu(timer_gettime, current,
 		    (timer_t tm, struct compat_itimerspec __user *u_val))
 {
-	struct itimerspec val;
+	struct itimerspec64 val;
 	int ret;
 
 	ret = __cobalt_timer_gettime(tm, &val);
@@ -553,7 +553,7 @@ COBALT_SYSCALL32emu(timerfd_settime, primary,
 		     const struct compat_itimerspec __user *new_value,
 		     struct compat_itimerspec __user *old_value))
 {
-	struct itimerspec ovalue, value;
+	struct itimerspec64 ovalue, value;
 	int ret;
 
 	ret = sys32_get_itimerspec(&value, new_value);
@@ -577,7 +577,7 @@ COBALT_SYSCALL32emu(timerfd_settime, primary,
 COBALT_SYSCALL32emu(timerfd_gettime, current,
 		    (int fd, struct compat_itimerspec __user *curr_value))
 {
-	struct itimerspec value;
+	struct itimerspec64 value;
 	int ret;
 
 	ret = __cobalt_timerfd_gettime(fd, &value);
diff --git a/kernel/cobalt/posix/timer.c b/kernel/cobalt/posix/timer.c
index 3aca90de9f..a58ea99a36 100644
--- a/kernel/cobalt/posix/timer.c
+++ b/kernel/cobalt/posix/timer.c
@@ -261,7 +261,7 @@ out:
 }
 
 void __cobalt_timer_getval(struct xntimer *__restrict__ timer,
-			   struct itimerspec *__restrict__ value)
+			   struct itimerspec64 *__restrict__ value)
 {
 	ns2ts(&value->it_interval, xntimer_interval(timer));
 
@@ -275,7 +275,7 @@ void __cobalt_timer_getval(struct xntimer *__restrict__ timer,
 
 static inline void
 timer_gettimeout(struct cobalt_timer *__restrict__ timer,
-		 struct itimerspec *__restrict__ value)
+		 struct itimerspec64 *__restrict__ value)
 {
 	int ret = 0;
 
@@ -287,7 +287,7 @@ timer_gettimeout(struct cobalt_timer *__restrict__ timer,
 }
 
 int __cobalt_timer_setval(struct xntimer *__restrict__ timer, int clock_flag,
-			  const struct itimerspec *__restrict__ value)
+			  const struct itimerspec64 *__restrict__ value)
 {
 	xnticks_t start, period;
 
@@ -312,7 +312,7 @@ int __cobalt_timer_setval(struct xntimer *__restrict__ timer, int clock_flag,
 }
 
 static inline int timer_set(struct cobalt_timer *timer, int flags,
-			    const struct itimerspec *__restrict__ value)
+			    const struct itimerspec64 *__restrict__ value)
 {				/* nklocked, IRQs off. */
 	struct cobalt_thread *thread;
 	int ret = 0;
@@ -362,8 +362,8 @@ timer_deliver_late(struct cobalt_process *cc, timer_t timerid)
 }
 
 int __cobalt_timer_settime(timer_t timerid, int flags,
-			   const struct itimerspec *__restrict__ value,
-			   struct itimerspec *__restrict__ ovalue)
+			   const struct itimerspec64 *__restrict__ value,
+			   struct itimerspec64 *__restrict__ ovalue)
 {
 	struct cobalt_timer *timer;
 	struct cobalt_process *cc;
@@ -402,7 +402,7 @@ out:
 	return ret;
 }
 
-int __cobalt_timer_gettime(timer_t timerid, struct itimerspec *value)
+int __cobalt_timer_gettime(timer_t timerid, struct itimerspec64 *value)
 {
 	struct cobalt_timer *timer;
 	struct cobalt_process *cc;
@@ -471,23 +471,23 @@ COBALT_SYSCALL(timer_create, current,
 
 COBALT_SYSCALL(timer_settime, primary,
 	       (timer_t tm, int flags,
-		const struct itimerspec __user *u_newval,
-		struct itimerspec __user *u_oldval))
+		const struct __user_old_itimerspec __user *u_newval,
+		struct __user_old_itimerspec __user *u_oldval))
 {
-	struct itimerspec newv, oldv, *oldvp = &oldv;
+	struct itimerspec64 newv, oldv, *oldvp = &oldv;
 	int ret;
 
 	if (u_oldval == NULL)
 		oldvp = NULL;
 
-	if (cobalt_copy_from_user(&newv, u_newval, sizeof(newv)))
+	if (cobalt_get_u_itimerspec(&newv, u_newval))
 		return -EFAULT;
 
 	ret = __cobalt_timer_settime(tm, flags, &newv, oldvp);
 	if (ret)
 		return ret;
 
-	if (oldvp && cobalt_copy_to_user(u_oldval, oldvp, sizeof(oldv))) {
+	if (oldvp && cobalt_put_u_itimerspec(u_oldval, oldvp)) {
 		__cobalt_timer_settime(tm, flags, oldvp, NULL);
 		return -EFAULT;
 	}
@@ -496,16 +496,16 @@ COBALT_SYSCALL(timer_settime, primary,
 }
 
 COBALT_SYSCALL(timer_gettime, current,
-	       (timer_t tm, struct itimerspec __user *u_val))
+	       (timer_t tm, struct __user_old_itimerspec __user *u_val))
 {
-	struct itimerspec val;
+	struct itimerspec64 val;
 	int ret;
 
 	ret = __cobalt_timer_gettime(tm, &val);
 	if (ret)
 		return ret;
 
-	return cobalt_copy_to_user(u_val, &val, sizeof(val));
+	return cobalt_put_u_itimerspec(u_val, &val);
 }
 
 COBALT_SYSCALL(timer_getoverrun, current, (timer_t timerid))
diff --git a/kernel/cobalt/posix/timer.h b/kernel/cobalt/posix/timer.h
index 0f5402aee9..3b580d4707 100644
--- a/kernel/cobalt/posix/timer.h
+++ b/kernel/cobalt/posix/timer.h
@@ -51,20 +51,20 @@ cobalt_timer_by_id(struct cobalt_process *p, timer_t timer_id);
 void cobalt_timer_handler(struct xntimer *xntimer);
 
 void __cobalt_timer_getval(struct xntimer *__restrict__ timer, 
-			   struct itimerspec *__restrict__ value);
+			   struct itimerspec64 *__restrict__ value);
 
 int __cobalt_timer_setval(struct xntimer *__restrict__ timer, int clock_flag, 
-			  const struct itimerspec *__restrict__ value);
+			  const struct itimerspec64 *__restrict__ value);
 
 int __cobalt_timer_create(clockid_t clock,
 			  const struct sigevent *sev,
 			  timer_t __user *u_tm);
 
 int __cobalt_timer_settime(timer_t timerid, int flags,
-			   const struct itimerspec *__restrict__ value,
-			   struct itimerspec *__restrict__ ovalue);
+			   const struct itimerspec64 *__restrict__ value,
+			   struct itimerspec64 *__restrict__ ovalue);
 
-int __cobalt_timer_gettime(timer_t timerid, struct itimerspec *value);
+int __cobalt_timer_gettime(timer_t timerid, struct itimerspec64 *value);
 
 COBALT_SYSCALL_DECL(timer_create,
 		    (clockid_t clock,
@@ -75,11 +75,11 @@ COBALT_SYSCALL_DECL(timer_delete, (timer_t tm));
 
 COBALT_SYSCALL_DECL(timer_settime,
 		    (timer_t tm, int flags,
-		     const struct itimerspec __user *u_newval,
-		     struct itimerspec __user *u_oldval));
+		     const struct __user_old_itimerspec __user *u_newval,
+		     struct __user_old_itimerspec __user *u_oldval));
 
 COBALT_SYSCALL_DECL(timer_gettime,
-		    (timer_t tm, struct itimerspec __user *u_val));
+		    (timer_t tm, struct __user_old_itimerspec __user *u_val));
 
 COBALT_SYSCALL_DECL(timer_getoverrun, (timer_t tm));
 
diff --git a/kernel/cobalt/posix/timerfd.c b/kernel/cobalt/posix/timerfd.c
index 29046cfec5..472c4cba0c 100644
--- a/kernel/cobalt/posix/timerfd.c
+++ b/kernel/cobalt/posix/timerfd.c
@@ -32,7 +32,7 @@ struct cobalt_tfd {
 	struct rtdm_fd fd;
 	struct xntimer timer;
 	DECLARE_XNSELECT(read_select);
-	struct itimerspec value;
+	struct itimerspec64 value;
 	struct xnsynch readers;
 	struct xnthread *target;
 };
@@ -236,8 +236,8 @@ static inline void tfd_put(struct cobalt_tfd *tfd)
 }
 
 int __cobalt_timerfd_settime(int fd, int flags,
-			     const struct itimerspec *value,
-			     struct itimerspec *ovalue)
+			     const struct itimerspec64 *value,
+			     struct itimerspec64 *ovalue)
 {
 	struct cobalt_tfd *tfd;
 	int cflag, ret;
@@ -280,13 +280,13 @@ out:
 
 COBALT_SYSCALL(timerfd_settime, primary,
 	       (int fd, int flags,
-		const struct itimerspec __user *new_value,
-		struct itimerspec __user *old_value))
+		const struct __user_old_itimerspec __user *new_value,
+		struct __user_old_itimerspec __user *old_value))
 {
-	struct itimerspec ovalue, value;
+	struct itimerspec64 ovalue, value;
 	int ret;
 
-	ret = cobalt_copy_from_user(&value, new_value, sizeof(value));
+	ret = cobalt_get_u_itimerspec(&value, new_value);
 	if (ret)
 		return ret;
 
@@ -304,7 +304,7 @@ COBALT_SYSCALL(timerfd_settime, primary,
 	return ret;
 }
 
-int __cobalt_timerfd_gettime(int fd, struct itimerspec *value)
+int __cobalt_timerfd_gettime(int fd, struct itimerspec64 *value)
 {
 	struct cobalt_tfd *tfd;
 	spl_t s;
@@ -323,12 +323,12 @@ int __cobalt_timerfd_gettime(int fd, struct itimerspec *value)
 }
 
 COBALT_SYSCALL(timerfd_gettime, current,
-	       (int fd, struct itimerspec __user *curr_value))
+	       (int fd, struct __user_old_itimerspec __user *curr_value))
 {
-	struct itimerspec value;
+	struct itimerspec64 value;
 	int ret;
 
 	ret = __cobalt_timerfd_gettime(fd, &value);
 
-	return ret ?: cobalt_copy_to_user(curr_value, &value, sizeof(value));
+	return ret ?: cobalt_put_u_itimerspec(curr_value, &value);
 }
diff --git a/kernel/cobalt/posix/timerfd.h b/kernel/cobalt/posix/timerfd.h
index 5787ff60a0..245b8698bf 100644
--- a/kernel/cobalt/posix/timerfd.h
+++ b/kernel/cobalt/posix/timerfd.h
@@ -22,21 +22,21 @@
 #include <xenomai/posix/syscall.h>
 
 int __cobalt_timerfd_settime(int fd, int flags,
-			     const struct itimerspec *new_value,
-			     struct itimerspec *old_value);
+			     const struct itimerspec64 *new_value,
+			     struct itimerspec64 *old_value);
 
 int __cobalt_timerfd_gettime(int fd,
-			     struct itimerspec *value);
+			     struct itimerspec64 *value);
 
 COBALT_SYSCALL_DECL(timerfd_create,
 		    (int clockid, int flags));
 
 COBALT_SYSCALL_DECL(timerfd_settime,
 		    (int fd, int flags,
-		     const struct itimerspec __user *new_value,
-		     struct itimerspec __user *old_value));
+		     const struct __user_old_itimerspec __user *new_value,
+		     struct __user_old_itimerspec __user *old_value));
 
 COBALT_SYSCALL_DECL(timerfd_gettime,
-		    (int fd, struct itimerspec __user *curr_value));
+		    (int fd, struct __user_old_itimerspec __user *curr_value));
 
 #endif /* TIMERFD_H */
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v2 4/9] cobalt/kernel: y2038: convert struct timex to __kernel_timex
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
                   ` (2 preceding siblings ...)
  2021-05-05 16:53 ` [PATCH v2 3/9] cobalt/kernel: y2038: convert struct itimerspec to itimerspec64 Jan Kiszka
@ 2021-05-05 16:53 ` Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 5/9] cobalt/kernel: y2038: switch to new legacy type names Jan Kiszka
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:53 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

As internal interfaces are gradually being made y2038-safe, the
__kernel_timex type should be used internally by the kernel to
represent time adjustment parameters. Apply the same reasoning to
Cobalt.

We still use a legacy y2038-unsafe timex type at the kernel<->user
interface boundary (struct __user_old_timex) until libcobalt is
y2038-safe.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/clock.h                 |  7 +--
 include/cobalt/kernel/compat.h                |  4 +-
 include/cobalt/uapi/kernel/types.h            | 44 +++++++++++++++++--
 .../include/asm-generic/xenomai/wrappers.h    |  4 ++
 kernel/cobalt/posix/clock.c                   |  6 +--
 kernel/cobalt/posix/clock.h                   |  4 +-
 kernel/cobalt/posix/compat.c                  | 28 +++++++++---
 kernel/cobalt/posix/syscall32.c               |  2 +-
 kernel/cobalt/trace/cobalt-posix.h            |  4 +-
 9 files changed, 81 insertions(+), 22 deletions(-)

diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
index 1c99173ff8..0e4f1e1cbe 100644
--- a/include/cobalt/kernel/clock.h
+++ b/include/cobalt/kernel/clock.h
@@ -24,6 +24,7 @@
 #include <cobalt/kernel/list.h>
 #include <cobalt/kernel/vfile.h>
 #include <cobalt/uapi/kernel/types.h>
+#include <asm/xenomai/wrappers.h>
 
 /**
  * @addtogroup cobalt_core_clock
@@ -32,7 +33,7 @@
 
 struct xnsched;
 struct xntimerdata;
-struct timex;
+struct __kernel_timex;
 
 struct xnclock_gravity {
 	unsigned long irq;
@@ -67,7 +68,7 @@ struct xnclock {
 					    struct xnsched *sched);
 #endif
 		int (*adjust_time)(struct xnclock *clock,
-				   struct timex *tx);
+				   struct __kernel_timex *tx);
 		int (*set_gravity)(struct xnclock *clock,
 				   const struct xnclock_gravity *p);
 		void (*reset_gravity)(struct xnclock *clock);
@@ -275,7 +276,7 @@ static inline int xnclock_set_time(struct xnclock *clock,
 #endif /* !CONFIG_XENO_OPT_EXTCLOCK */
 
 static inline int xnclock_adjust_time(struct xnclock *clock,
-				      struct timex *tx)
+				      struct __kernel_timex *tx)
 {
 	if (clock->ops.adjust_time == NULL)
 		return -EOPNOTSUPP;
diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
index 7bec8c3be5..d7f0008d9f 100644
--- a/include/cobalt/kernel/compat.h
+++ b/include/cobalt/kernel/compat.h
@@ -104,11 +104,11 @@ int sys32_get_timeval(struct __kernel_old_timeval *tv,
 int sys32_put_timeval(struct compat_timeval __user *ctv,
 		      const struct __kernel_old_timeval *tv);
 
-int sys32_get_timex(struct timex *tx,
+int sys32_get_timex(struct __kernel_timex *tx,
 		    const struct old_timex32 __user *ctx);
 
 int sys32_put_timex(struct old_timex32 __user *ctx,
-		    const struct timex *tx);
+		    const struct __kernel_timex *tx);
 
 ssize_t sys32_get_fdset(fd_set *fds, const compat_fd_set __user *cfds,
 			size_t cfdsize);
diff --git a/include/cobalt/uapi/kernel/types.h b/include/cobalt/uapi/kernel/types.h
index 10abbb55a5..2c931c29c3 100644
--- a/include/cobalt/uapi/kernel/types.h
+++ b/include/cobalt/uapi/kernel/types.h
@@ -58,9 +58,10 @@ static inline xnhandle_t xnhandle_get_id(xnhandle_t handle)
 }
 
 /*
- * Our representation of time at the kernel<->user interface boundary
- * at the moment, until we have fully transitioned to a y2038-safe
- * implementation in libcobalt.
+ * Our representation of time specs at the kernel<->user interface
+ * boundary at the moment, until we have fully transitioned to a
+ * y2038-safe implementation in libcobalt. Once done, those legacy
+ * types will be removed.
  */
 struct __user_old_timespec {
 	long  tv_sec;
@@ -72,4 +73,41 @@ struct __user_old_itimerspec {
 	struct __user_old_timespec it_value;
 };
 
+struct __user_old_timeval {
+	long  tv_sec;
+	long  tv_usec;
+};
+
+/* Lifted from include/uapi/linux/timex.h. */
+struct __user_old_timex {
+	unsigned int modes;	/* mode selector */
+	__kernel_long_t offset;	/* time offset (usec) */
+	__kernel_long_t freq;	/* frequency offset (scaled ppm) */
+	__kernel_long_t maxerror;/* maximum error (usec) */
+	__kernel_long_t esterror;/* estimated error (usec) */
+	int status;		/* clock command/status */
+	__kernel_long_t constant;/* pll time constant */
+	__kernel_long_t precision;/* clock precision (usec) (read only) */
+	__kernel_long_t tolerance;/* clock frequency tolerance (ppm)
+				   * (read only)
+				   */
+	struct __user_old_timeval time;	/* (read only, except for ADJ_SETOFFSET) */
+	__kernel_long_t tick;	/* (modified) usecs between clock ticks */
+
+	__kernel_long_t ppsfreq;/* pps frequency (scaled ppm) (ro) */
+	__kernel_long_t jitter; /* pps jitter (us) (ro) */
+	int shift;              /* interval duration (s) (shift) (ro) */
+	__kernel_long_t stabil;            /* pps stability (scaled ppm) (ro) */
+	__kernel_long_t jitcnt; /* jitter limit exceeded (ro) */
+	__kernel_long_t calcnt; /* calibration intervals (ro) */
+	__kernel_long_t errcnt; /* calibration errors (ro) */
+	__kernel_long_t stbcnt; /* stability limit exceeded (ro) */
+
+	int tai;		/* TAI offset (ro) */
+
+	int  :32; int  :32; int  :32; int  :32;
+	int  :32; int  :32; int  :32; int  :32;
+	int  :32; int  :32; int  :32;
+};
+
 #endif /* !_COBALT_UAPI_KERNEL_TYPES_H */
diff --git a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
index be62ab744b..42cd1955ac 100644
--- a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
+++ b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
@@ -152,6 +152,10 @@ devm_hwmon_device_register_with_groups(struct device *dev, const char *name,
 #error "Xenomai/cobalt requires Linux kernel 3.10 or above"
 #endif /* < 3.10 */
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
+#define __kernel_timex		timex
+#endif
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,1,0)
 #define old_timex32		compat_timex
 #define SO_RCVTIMEO_OLD		SO_RCVTIMEO
diff --git a/kernel/cobalt/posix/clock.c b/kernel/cobalt/posix/clock.c
index 4a3365d2a9..23a45bba9b 100644
--- a/kernel/cobalt/posix/clock.c
+++ b/kernel/cobalt/posix/clock.c
@@ -166,7 +166,7 @@ int __cobalt_clock_settime(clockid_t clock_id, const struct timespec64 *ts)
 	return 0;
 }
 
-int __cobalt_clock_adjtime(clockid_t clock_id, struct timex *tx)
+int __cobalt_clock_adjtime(clockid_t clock_id, struct __kernel_timex *tx)
 {
 	int _ret, ret = 0;
 
@@ -199,9 +199,9 @@ COBALT_SYSCALL(clock_settime, current,
 }
 
 COBALT_SYSCALL(clock_adjtime, current,
-	       (clockid_t clock_id, struct timex __user *u_tx))
+	       (clockid_t clock_id, struct __user_old_timex __user *u_tx))
 {
-	struct timex tx;
+	struct __kernel_timex tx;
 	int ret;
 
 	if (cobalt_copy_from_user(&tx, u_tx, sizeof(tx)))
diff --git a/kernel/cobalt/posix/clock.h b/kernel/cobalt/posix/clock.h
index 7e45fdcc6b..e69e76e1be 100644
--- a/kernel/cobalt/posix/clock.h
+++ b/kernel/cobalt/posix/clock.h
@@ -104,7 +104,7 @@ int __cobalt_clock_settime(clockid_t clock_id,
 			   const struct timespec64 *ts);
 
 int __cobalt_clock_adjtime(clockid_t clock_id,
-			   struct timex *tx);
+			   struct __kernel_timex *tx);
 
 int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
 			     const struct timespec64 *rqt,
@@ -120,7 +120,7 @@ COBALT_SYSCALL_DECL(clock_settime,
 		    (clockid_t clock_id, const struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(clock_adjtime,
-		    (clockid_t clock_id, struct timex __user *u_tx));
+		    (clockid_t clock_id, struct __user_old_timex __user *u_tx));
 
 COBALT_SYSCALL_DECL(clock_nanosleep,
 		    (clockid_t clock_id, int flags,
diff --git a/kernel/cobalt/posix/compat.c b/kernel/cobalt/posix/compat.c
index 767a8033a6..6002d74802 100644
--- a/kernel/cobalt/posix/compat.c
+++ b/kernel/cobalt/posix/compat.c
@@ -98,11 +98,21 @@ int sys32_put_timeval(struct compat_timeval __user *ctv,
 }
 EXPORT_SYMBOL_GPL(sys32_put_timeval);
 
-int sys32_get_timex(struct timex *tx,
+int sys32_get_timex(struct __kernel_timex *tx,
 		    const struct old_timex32 __user *ctx)
 {
+	struct __kernel_old_timeval time;
+	int ret;
+
 	memset(tx, 0, sizeof(*tx));
 
+	ret = sys32_get_timeval(&time, &ctx->time);
+	if (ret)
+		return ret;
+
+	tx->time.tv_sec = time.tv_sec;
+	tx->time.tv_usec = time.tv_usec;
+
 	if (!access_rok(ctx, sizeof(*ctx)) ||
 	    __xn_get_user(tx->modes, &ctx->modes) ||
 	    __xn_get_user(tx->offset, &ctx->offset) ||
@@ -113,8 +123,6 @@ int sys32_get_timex(struct timex *tx,
 	    __xn_get_user(tx->constant, &ctx->constant) ||
 	    __xn_get_user(tx->precision, &ctx->precision) ||
 	    __xn_get_user(tx->tolerance, &ctx->tolerance) ||
-	    __xn_get_user(tx->time.tv_sec, &ctx->time.tv_sec) ||
-	    __xn_get_user(tx->time.tv_usec, &ctx->time.tv_usec) ||
 	    __xn_get_user(tx->tick, &ctx->tick) ||
 	    __xn_get_user(tx->ppsfreq, &ctx->ppsfreq) ||
 	    __xn_get_user(tx->jitter, &ctx->jitter) ||
@@ -131,8 +139,18 @@ int sys32_get_timex(struct timex *tx,
 EXPORT_SYMBOL_GPL(sys32_get_timex);
 
 int sys32_put_timex(struct old_timex32 __user *ctx,
-		    const struct timex *tx)
+		    const struct __kernel_timex *tx)
 {
+	struct __kernel_old_timeval time;
+	int ret;
+
+	time.tv_sec = tx->time.tv_sec;
+	time.tv_usec = tx->time.tv_usec;
+
+	ret = sys32_put_timeval(&ctx->time, &time);
+	if (ret)
+		return ret;
+
 	if (!access_wok(ctx, sizeof(*ctx)) ||
 	    __xn_put_user(tx->modes, &ctx->modes) ||
 	    __xn_put_user(tx->offset, &ctx->offset) ||
@@ -143,8 +161,6 @@ int sys32_put_timex(struct old_timex32 __user *ctx,
 	    __xn_put_user(tx->constant, &ctx->constant) ||
 	    __xn_put_user(tx->precision, &ctx->precision) ||
 	    __xn_put_user(tx->tolerance, &ctx->tolerance) ||
-	    __xn_put_user(tx->time.tv_sec, &ctx->time.tv_sec) ||
-	    __xn_put_user(tx->time.tv_usec, &ctx->time.tv_usec) ||
 	    __xn_put_user(tx->tick, &ctx->tick) ||
 	    __xn_put_user(tx->ppsfreq, &ctx->ppsfreq) ||
 	    __xn_put_user(tx->jitter, &ctx->jitter) ||
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 5c858806b6..4f819e0e5a 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -174,7 +174,7 @@ COBALT_SYSCALL32emu(clock_settime, current,
 COBALT_SYSCALL32emu(clock_adjtime, current,
 		    (clockid_t clock_id, struct old_timex32 __user *u_tx))
 {
-	struct timex tx;
+	struct __kernel_timex tx;
 	int ret;
 
 	ret = sys32_get_timex(&tx, u_tx);
diff --git a/kernel/cobalt/trace/cobalt-posix.h b/kernel/cobalt/trace/cobalt-posix.h
index 3a649a6712..cff1bd9b71 100644
--- a/kernel/cobalt/trace/cobalt-posix.h
+++ b/kernel/cobalt/trace/cobalt-posix.h
@@ -764,12 +764,12 @@ DEFINE_EVENT(cobalt_clock_timespec, cobalt_clock_settime,
 );
 
 TRACE_EVENT(cobalt_clock_adjtime,
-	TP_PROTO(clockid_t clk_id, struct timex *tx),
+	TP_PROTO(clockid_t clk_id, struct __kernel_timex *tx),
 	TP_ARGS(clk_id, tx),
 
 	TP_STRUCT__entry(
 		__field(clockid_t, clk_id)
-		__field(struct timex *, tx)
+		__field(struct __kernel_timex *, tx)
 	),
 
 	TP_fast_assign(
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v2 5/9] cobalt/kernel: y2038: switch to new legacy type names
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
                   ` (3 preceding siblings ...)
  2021-05-05 16:53 ` [PATCH v2 4/9] cobalt/kernel: y2038: convert struct timex to __kernel_timex Jan Kiszka
@ 2021-05-05 16:53 ` Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 6/9] cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems Jan Kiszka
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:53 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Since 5.6-rc3, former 32bit compatibility types for time-related
structs have been renamed as follows:

compat_timeval -> old_timeval32
compat_timespec -> old_timespec32
compat_itimerspec -> old_itimerspec32

Apply the same changes to the tree, providing backward compatibility
wrappers for pre-5.7 kernels.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/compat.h                | 22 +++++-----
 .../include/asm-generic/xenomai/wrappers.h    |  3 ++
 kernel/cobalt/posix/compat.c                  | 16 +++----
 kernel/cobalt/posix/syscall32.c               | 42 +++++++++----------
 kernel/cobalt/posix/syscall32.h               | 42 +++++++++----------
 kernel/drivers/ipc/rtipc.c                    |  4 +-
 6 files changed, 66 insertions(+), 63 deletions(-)

diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
index d7f0008d9f..6da7bafaf8 100644
--- a/include/cobalt/kernel/compat.h
+++ b/include/cobalt/kernel/compat.h
@@ -29,13 +29,13 @@ struct mq_attr;
 
 struct __compat_sched_ss_param {
 	int __sched_low_priority;
-	struct compat_timespec __sched_repl_period;
-	struct compat_timespec __sched_init_budget;
+	struct old_timespec32 __sched_repl_period;
+	struct old_timespec32 __sched_init_budget;
 	int __sched_max_repl;
 };
 
 struct __compat_sched_rr_param {
-	struct compat_timespec __sched_rr_quantum;
+	struct old_timespec32 __sched_rr_quantum;
 };
 
 struct compat_sched_param_ex {
@@ -56,8 +56,8 @@ struct compat_mq_attr {
 };
 
 struct compat_sched_tp_window {
-	struct compat_timespec offset;
-	struct compat_timespec duration;
+	struct old_timespec32 offset;
+	struct old_timespec32 duration;
 	int ptid;
 };
 
@@ -87,21 +87,21 @@ struct compat_rtdm_mmap_request {
 };
 
 int sys32_get_timespec(struct timespec64 *ts,
-		       const struct compat_timespec __user *cts);
+		       const struct old_timespec32 __user *cts);
 
-int sys32_put_timespec(struct compat_timespec __user *cts,
+int sys32_put_timespec(struct old_timespec32 __user *cts,
 		       const struct timespec64 *ts);
 
 int sys32_get_itimerspec(struct itimerspec64 *its,
-			 const struct compat_itimerspec __user *cits);
+			 const struct old_itimerspec32 __user *cits);
 
-int sys32_put_itimerspec(struct compat_itimerspec __user *cits,
+int sys32_put_itimerspec(struct old_itimerspec32 __user *cits,
 			 const struct itimerspec64 *its);
 
 int sys32_get_timeval(struct __kernel_old_timeval *tv,
-		      const struct compat_timeval __user *ctv);
+		      const struct old_timeval32 __user *ctv);
 
-int sys32_put_timeval(struct compat_timeval __user *ctv,
+int sys32_put_timeval(struct old_timeval32 __user *ctv,
 		      const struct __kernel_old_timeval *tv);
 
 int sys32_get_timex(struct __kernel_timex *tx,
diff --git a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
index 42cd1955ac..930e6364e5 100644
--- a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
+++ b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
@@ -205,6 +205,9 @@ devm_hwmon_device_register_with_groups(struct device *dev, const char *name,
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0)
 #define pci_aer_clear_nonfatal_status	pci_cleanup_aer_uncorrect_error_status
+#define old_timespec32    compat_timespec
+#define old_itimerspec32  compat_itimerspec
+#define old_timeval32     compat_timeval
 #endif
 
 #endif /* _COBALT_ASM_GENERIC_WRAPPERS_H */
diff --git a/kernel/cobalt/posix/compat.c b/kernel/cobalt/posix/compat.c
index 6002d74802..dbc9a9cf02 100644
--- a/kernel/cobalt/posix/compat.c
+++ b/kernel/cobalt/posix/compat.c
@@ -23,9 +23,9 @@
 #include <xenomai/posix/mqueue.h>
 
 int sys32_get_timespec(struct timespec64 *ts,
-		       const struct compat_timespec __user *u_cts)
+		       const struct old_timespec32 __user *u_cts)
 {
-	struct compat_timespec cts;
+	struct old_timespec32 cts;
 
 	if (u_cts == NULL || !access_rok(u_cts, sizeof(*u_cts)))
 		return -EFAULT;
@@ -41,10 +41,10 @@ int sys32_get_timespec(struct timespec64 *ts,
 }
 EXPORT_SYMBOL_GPL(sys32_get_timespec);
 
-int sys32_put_timespec(struct compat_timespec __user *u_cts,
+int sys32_put_timespec(struct old_timespec32 __user *u_cts,
 		       const struct timespec64 *ts)
 {
-	struct compat_timespec cts;
+	struct old_timespec32 cts;
 
 	if (u_cts == NULL || !access_wok(u_cts, sizeof(*u_cts)))
 		return -EFAULT;
@@ -61,7 +61,7 @@ int sys32_put_timespec(struct compat_timespec __user *u_cts,
 EXPORT_SYMBOL_GPL(sys32_put_timespec);
 
 int sys32_get_itimerspec(struct itimerspec64 *its,
-			 const struct compat_itimerspec __user *cits)
+			 const struct old_itimerspec32 __user *cits)
 {
 	int ret = sys32_get_timespec(&its->it_value, &cits->it_value);
 
@@ -69,7 +69,7 @@ int sys32_get_itimerspec(struct itimerspec64 *its,
 }
 EXPORT_SYMBOL_GPL(sys32_get_itimerspec);
 
-int sys32_put_itimerspec(struct compat_itimerspec __user *cits,
+int sys32_put_itimerspec(struct old_itimerspec32 __user *cits,
 			 const struct itimerspec64 *its)
 {
 	int ret = sys32_put_timespec(&cits->it_value, &its->it_value);
@@ -79,7 +79,7 @@ int sys32_put_itimerspec(struct compat_itimerspec __user *cits,
 EXPORT_SYMBOL_GPL(sys32_put_itimerspec);
 
 int sys32_get_timeval(struct __kernel_old_timeval *tv,
-		      const struct compat_timeval __user *ctv)
+		      const struct old_timeval32 __user *ctv)
 {
 	return (ctv == NULL ||
 		!access_rok(ctv, sizeof(*ctv)) ||
@@ -88,7 +88,7 @@ int sys32_get_timeval(struct __kernel_old_timeval *tv,
 }
 EXPORT_SYMBOL_GPL(sys32_get_timeval);
 
-int sys32_put_timeval(struct compat_timeval __user *ctv,
+int sys32_put_timeval(struct old_timeval32 __user *ctv,
 		      const struct __kernel_old_timeval *tv)
 {
 	return (ctv == NULL ||
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 4f819e0e5a..57aa7251a4 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -124,14 +124,14 @@ COBALT_SYSCALL32emu(sem_open, lostage,
 
 COBALT_SYSCALL32emu(sem_timedwait, primary,
 		    (struct cobalt_sem_shadow __user *u_sem,
-		     struct compat_timespec __user *u_ts))
+		     struct old_timespec32 __user *u_ts))
 {
 	return __cobalt_sem_timedwait(u_sem, u_ts, sys32_fetch_timeout);
 }
 
 COBALT_SYSCALL32emu(clock_getres, current,
 		    (clockid_t clock_id,
-		     struct compat_timespec __user *u_ts))
+		     struct old_timespec32 __user *u_ts))
 {
 	struct timespec64 ts;
 	int ret;
@@ -145,7 +145,7 @@ COBALT_SYSCALL32emu(clock_getres, current,
 
 COBALT_SYSCALL32emu(clock_gettime, current,
 		    (clockid_t clock_id,
-		     struct compat_timespec __user *u_ts))
+		     struct old_timespec32 __user *u_ts))
 {
 	struct timespec64 ts;
 	int ret;
@@ -159,7 +159,7 @@ COBALT_SYSCALL32emu(clock_gettime, current,
 
 COBALT_SYSCALL32emu(clock_settime, current,
 		    (clockid_t clock_id,
-		     const struct compat_timespec __user *u_ts))
+		     const struct old_timespec32 __user *u_ts))
 {
 	struct timespec64 ts;
 	int ret;
@@ -190,8 +190,8 @@ COBALT_SYSCALL32emu(clock_adjtime, current,
 
 COBALT_SYSCALL32emu(clock_nanosleep, nonrestartable,
 		    (clockid_t clock_id, int flags,
-		     const struct compat_timespec __user *u_rqt,
-		     struct compat_timespec __user *u_rmt))
+		     const struct old_timespec32 __user *u_rqt,
+		     struct old_timespec32 __user *u_rmt))
 {
 	struct timespec64 rqt, rmt, *rmtp = NULL;
 	int ret;
@@ -212,7 +212,7 @@ COBALT_SYSCALL32emu(clock_nanosleep, nonrestartable,
 
 COBALT_SYSCALL32emu(mutex_timedlock, primary,
 		    (struct cobalt_mutex_shadow __user *u_mx,
-		     const struct compat_timespec __user *u_ts))
+		     const struct old_timespec32 __user *u_ts))
 {
 	return __cobalt_mutex_timedlock_break(u_mx, u_ts, sys32_fetch_timeout);
 }
@@ -222,7 +222,7 @@ COBALT_SYSCALL32emu(cond_wait_prologue, nonrestartable,
 		     struct cobalt_mutex_shadow __user *u_mx,
 		     int *u_err,
 		     unsigned int timed,
-		     struct compat_timespec __user *u_ts))
+		     struct old_timespec32 __user *u_ts))
 {
 	return __cobalt_cond_wait_prologue(u_cnd, u_mx, u_err, u_ts,
 					   timed ? sys32_fetch_timeout : NULL);
@@ -261,7 +261,7 @@ COBALT_SYSCALL32emu(mq_getattr, current,
 COBALT_SYSCALL32emu(mq_timedsend, primary,
 		    (mqd_t uqd, const void __user *u_buf, size_t len,
 		     unsigned int prio,
-		     const struct compat_timespec __user *u_ts))
+		     const struct old_timespec32 __user *u_ts))
 {
 	return __cobalt_mq_timedsend(uqd, u_buf, len, prio,
 				     u_ts, u_ts ? sys32_fetch_timeout : NULL);
@@ -271,7 +271,7 @@ COBALT_SYSCALL32emu(mq_timedreceive, primary,
 		    (mqd_t uqd, void __user *u_buf,
 		     compat_ssize_t __user *u_len,
 		     unsigned int __user *u_prio,
-		     const struct compat_timespec __user *u_ts))
+		     const struct old_timespec32 __user *u_ts))
 {
 	compat_ssize_t clen;
 	ssize_t len;
@@ -511,8 +511,8 @@ COBALT_SYSCALL32emu(timer_create, current,
 
 COBALT_SYSCALL32emu(timer_settime, primary,
 		    (timer_t tm, int flags,
-		     const struct compat_itimerspec __user *u_newval,
-		     struct compat_itimerspec __user *u_oldval))
+		     const struct old_itimerspec32 __user *u_newval,
+		     struct old_itimerspec32 __user *u_oldval))
 {
 	struct itimerspec64 newv, oldv, *oldvp = &oldv;
 	int ret;
@@ -538,7 +538,7 @@ COBALT_SYSCALL32emu(timer_settime, primary,
 }
 
 COBALT_SYSCALL32emu(timer_gettime, current,
-		    (timer_t tm, struct compat_itimerspec __user *u_val))
+		    (timer_t tm, struct old_itimerspec32 __user *u_val))
 {
 	struct itimerspec64 val;
 	int ret;
@@ -550,8 +550,8 @@ COBALT_SYSCALL32emu(timer_gettime, current,
 
 COBALT_SYSCALL32emu(timerfd_settime, primary,
 		    (int fd, int flags,
-		     const struct compat_itimerspec __user *new_value,
-		     struct compat_itimerspec __user *old_value))
+		     const struct old_itimerspec32 __user *new_value,
+		     struct old_itimerspec32 __user *old_value))
 {
 	struct itimerspec64 ovalue, value;
 	int ret;
@@ -575,7 +575,7 @@ COBALT_SYSCALL32emu(timerfd_settime, primary,
 }
 
 COBALT_SYSCALL32emu(timerfd_gettime, current,
-		    (int fd, struct compat_itimerspec __user *curr_value))
+		    (int fd, struct old_itimerspec32 __user *curr_value))
 {
 	struct itimerspec64 value;
 	int ret;
@@ -606,7 +606,7 @@ COBALT_SYSCALL32emu(sigwait, primary,
 COBALT_SYSCALL32emu(sigtimedwait, nonrestartable,
 		    (const compat_sigset_t __user *u_set,
 		     struct compat_siginfo __user *u_si,
-		     const struct compat_timespec __user *u_timeout))
+		     const struct old_timespec32 __user *u_timeout))
 {
 	struct timespec64 timeout;
 	sigset_t set;
@@ -658,7 +658,7 @@ COBALT_SYSCALL32emu(sigqueue, conforming,
 
 COBALT_SYSCALL32emu(monitor_wait, nonrestartable,
 		    (struct cobalt_monitor_shadow __user *u_mon,
-		     int event, const struct compat_timespec __user *u_ts,
+		     int event, const struct old_timespec32 __user *u_ts,
 		     int __user *u_ret))
 {
 	struct timespec64 ts, *tsp = NULL;
@@ -678,7 +678,7 @@ COBALT_SYSCALL32emu(event_wait, primary,
 		    (struct cobalt_event_shadow __user *u_event,
 		     unsigned int bits,
 		     unsigned int __user *u_bits_r,
-		     int mode, const struct compat_timespec __user *u_ts))
+		     int mode, const struct old_timespec32 __user *u_ts))
 {
 	struct timespec64 ts, *tsp = NULL;
 	int ret;
@@ -698,7 +698,7 @@ COBALT_SYSCALL32emu(select, nonrestartable,
 		     compat_fd_set __user *u_rfds,
 		     compat_fd_set __user *u_wfds,
 		     compat_fd_set __user *u_xfds,
-		     struct compat_timeval __user *u_tv))
+		     struct old_timeval32 __user *u_tv))
 {
 	compat_fd_set __user *ufd_sets[XNSELECT_MAX_TYPES] = {
 		[XNSELECT_READ] = u_rfds,
@@ -829,7 +829,7 @@ static int put_mmsg32(void __user **u_mmsg_p, const struct mmsghdr *mmsg)
 
 COBALT_SYSCALL32emu(recvmmsg, primary,
 	       (int ufd, struct compat_mmsghdr __user *u_msgvec, unsigned int vlen,
-		unsigned int flags, struct compat_timespec *u_timeout))
+		unsigned int flags, struct old_timespec32 *u_timeout))
 {
 	return __rtdm_fd_recvmmsg(ufd, u_msgvec, vlen, flags, u_timeout,
 				  get_mmsg32, put_mmsg32,
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index 9da4052297..66cd2a5d24 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -53,15 +53,15 @@ COBALT_SYSCALL32emu_DECL(thread_setschedprio,
 
 COBALT_SYSCALL32emu_DECL(clock_getres,
 			 (clockid_t clock_id,
-			  struct compat_timespec __user *u_ts));
+			  struct old_timespec32 __user *u_ts));
 
 COBALT_SYSCALL32emu_DECL(clock_gettime,
 			 (clockid_t clock_id,
-			  struct compat_timespec __user *u_ts));
+			  struct old_timespec32 __user *u_ts));
 
 COBALT_SYSCALL32emu_DECL(clock_settime,
 			 (clockid_t clock_id,
-			  const struct compat_timespec __user *u_ts));
+			  const struct old_timespec32 __user *u_ts));
 
 COBALT_SYSCALL32emu_DECL(clock_adjtime,
 			 (clockid_t clock_id,
@@ -69,19 +69,19 @@ COBALT_SYSCALL32emu_DECL(clock_adjtime,
 
 COBALT_SYSCALL32emu_DECL(clock_nanosleep,
 			 (clockid_t clock_id, int flags,
-			  const struct compat_timespec __user *u_rqt,
-			  struct compat_timespec __user *u_rmt));
+			  const struct old_timespec32 __user *u_rqt,
+			  struct old_timespec32 __user *u_rmt));
 
 COBALT_SYSCALL32emu_DECL(mutex_timedlock,
 			 (struct cobalt_mutex_shadow __user *u_mx,
-			  const struct compat_timespec __user *u_ts));
+			  const struct old_timespec32 __user *u_ts));
 
 COBALT_SYSCALL32emu_DECL(cond_wait_prologue,
 			 (struct cobalt_cond_shadow __user *u_cnd,
 			  struct cobalt_mutex_shadow __user *u_mx,
 			  int *u_err,
 			  unsigned int timed,
-			  struct compat_timespec __user *u_ts));
+			  struct old_timespec32 __user *u_ts));
 
 COBALT_SYSCALL32emu_DECL(mq_open,
 			 (const char __user *u_name, int oflags,
@@ -93,13 +93,13 @@ COBALT_SYSCALL32emu_DECL(mq_getattr,
 COBALT_SYSCALL32emu_DECL(mq_timedsend,
 			 (mqd_t uqd, const void __user *u_buf, size_t len,
 			  unsigned int prio,
-			  const struct compat_timespec __user *u_ts));
+			  const struct old_timespec32 __user *u_ts));
 
 COBALT_SYSCALL32emu_DECL(mq_timedreceive,
 			 (mqd_t uqd, void __user *u_buf,
 			  compat_ssize_t __user *u_len,
 			  unsigned int __user *u_prio,
-			  const struct compat_timespec __user *u_ts));
+			  const struct old_timespec32 __user *u_ts));
 
 COBALT_SYSCALL32x_DECL(mq_timedreceive,
 		       (mqd_t uqd, void __user *u_buf,
@@ -143,20 +143,20 @@ COBALT_SYSCALL32emu_DECL(timer_create,
 
 COBALT_SYSCALL32emu_DECL(timer_settime,
 			 (timer_t tm, int flags,
-			  const struct compat_itimerspec __user *u_newval,
-			  struct compat_itimerspec __user *u_oldval));
+			  const struct old_itimerspec32 __user *u_newval,
+			  struct old_itimerspec32 __user *u_oldval));
 
 COBALT_SYSCALL32emu_DECL(timer_gettime,
 			 (timer_t tm,
-			  struct compat_itimerspec __user *u_val));
+			  struct old_itimerspec32 __user *u_val));
 
 COBALT_SYSCALL32emu_DECL(timerfd_settime,
 			 (int fd, int flags,
-			  const struct compat_itimerspec __user *new_value,
-			  struct compat_itimerspec __user *old_value));
+			  const struct old_itimerspec32 __user *new_value,
+			  struct old_itimerspec32 __user *old_value));
 
 COBALT_SYSCALL32emu_DECL(timerfd_gettime,
-			 (int fd, struct compat_itimerspec __user *value));
+			 (int fd, struct old_itimerspec32 __user *value));
 
 COBALT_SYSCALL32emu_DECL(sigwait,
 			 (const compat_sigset_t __user *u_set,
@@ -165,7 +165,7 @@ COBALT_SYSCALL32emu_DECL(sigwait,
 COBALT_SYSCALL32emu_DECL(sigtimedwait,
 			 (const compat_sigset_t __user *u_set,
 			  struct compat_siginfo __user *u_si,
-			  const struct compat_timespec __user *u_timeout));
+			  const struct old_timespec32 __user *u_timeout));
 
 COBALT_SYSCALL32emu_DECL(sigwaitinfo,
 			 (const compat_sigset_t __user *u_set,
@@ -180,21 +180,21 @@ COBALT_SYSCALL32emu_DECL(sigqueue,
 
 COBALT_SYSCALL32emu_DECL(monitor_wait,
 			 (struct cobalt_monitor_shadow __user *u_mon,
-			  int event, const struct compat_timespec __user *u_ts,
+			  int event, const struct old_timespec32 __user *u_ts,
 			  int __user *u_ret));
 
 COBALT_SYSCALL32emu_DECL(event_wait,
 			 (struct cobalt_event_shadow __user *u_event,
 			  unsigned int bits,
 			  unsigned int __user *u_bits_r,
-			  int mode, const struct compat_timespec __user *u_ts));
+			  int mode, const struct old_timespec32 __user *u_ts));
 
 COBALT_SYSCALL32emu_DECL(select,
 			 (int nfds,
 			  compat_fd_set __user *u_rfds,
 			  compat_fd_set __user *u_wfds,
 			  compat_fd_set __user *u_xfds,
-			  struct compat_timeval __user *u_tv));
+			  struct old_timeval32 __user *u_tv));
 
 COBALT_SYSCALL32emu_DECL(recvmsg,
 			 (int fd, struct compat_msghdr __user *umsg,
@@ -203,7 +203,7 @@ COBALT_SYSCALL32emu_DECL(recvmsg,
 COBALT_SYSCALL32emu_DECL(recvmmsg,
 			 (int fd, struct compat_mmsghdr __user *u_msgvec,
 			  unsigned int vlen,
-			  unsigned int flags, struct compat_timespec *u_timeout));
+			  unsigned int flags, struct old_timespec32 *u_timeout));
 
 COBALT_SYSCALL32emu_DECL(sendmsg,
 			 (int fd, struct compat_msghdr __user *umsg,
@@ -229,6 +229,6 @@ COBALT_SYSCALL32emu_DECL(sem_open,
 
 COBALT_SYSCALL32emu_DECL(sem_timedwait,
 			 (struct cobalt_sem_shadow __user *u_sem,
-			  struct compat_timespec __user *u_ts));
+			  struct old_timespec32 __user *u_ts));
 
 #endif /* !_COBALT_POSIX_SYSCALL32_H */
diff --git a/kernel/drivers/ipc/rtipc.c b/kernel/drivers/ipc/rtipc.c
index b6fafdb413..abb76817a6 100644
--- a/kernel/drivers/ipc/rtipc.c
+++ b/kernel/drivers/ipc/rtipc.c
@@ -273,7 +273,7 @@ int rtipc_get_timeval(struct rtdm_fd *fd, struct __kernel_old_timeval *tv,
 {
 #ifdef CONFIG_XENO_ARCH_SYS3264
 	if (rtdm_fd_is_compat(fd)) {
-		if (arglen != sizeof(struct compat_timeval))
+		if (arglen != sizeof(struct old_timeval32))
 			return -EINVAL;
 		return sys32_get_timeval(tv, arg);
 	}
@@ -295,7 +295,7 @@ int rtipc_put_timeval(struct rtdm_fd *fd, void *arg,
 {
 #ifdef CONFIG_XENO_ARCH_SYS3264
 	if (rtdm_fd_is_compat(fd)) {
-		if (arglen != sizeof(struct compat_timeval))
+		if (arglen != sizeof(struct old_timeval32))
 			return -EINVAL;
 		return sys32_put_timeval(arg, tv);
 	}
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v2 6/9] cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
                   ` (4 preceding siblings ...)
  2021-05-05 16:53 ` [PATCH v2 5/9] cobalt/kernel: y2038: switch to new legacy type names Jan Kiszka
@ 2021-05-05 16:53 ` Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 7/9] y2038: Adding sem_timedwait64 Jan Kiszka
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:53 UTC (permalink / raw)
  To: xenomai

From: Florian Bezdeka <florian.bezdeka@siemens.com>

On systems using 32 bit for time_t the sem_timedwait syscall was broken
because the function used for copying the timeout value from userspace
to kernel (=sem_fetch_timeout()) was always copying
sizeof(struct timespec64).

A 32 bit application (or more specific an application with 4 byte
time_t) would only provide sizeof(struct old_timespec32).

Notable changes:
  - The copy operation from userspace to kernel is now already done in
    the syscall handler. So it is always done and might fail. Reporting
    a failure is delayed until the timeout is being validated.

  - Validation: Switched to timespec64_valid() instead of our own
    check.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/posix/sem.c       | 40 +++++++++++++++------------------
 kernel/cobalt/posix/sem.h       |  6 ++---
 kernel/cobalt/posix/syscall32.c | 10 +++++++--
 kernel/cobalt/posix/syscall32.h |  2 +-
 4 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index 467a9b7dd6..827a4751a0 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -267,20 +267,11 @@ out:
 	return ret;
 }
 
-static inline int sem_fetch_timeout(struct timespec64 *ts,
-				    const void __user *u_ts)
-{
-	return u_ts == NULL ? -EFAULT :
-		cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
-}
-
 int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user *u_sem,
-			   const void __user *u_ts,
-			   int (*fetch_timeout)(struct timespec64 *ts,
-						const void __user *u_ts))
+			   const struct timespec64 *ts)
 {
-	struct timespec64 ts = { .tv_sec = 0, .tv_nsec = 0 };
-	int pull_ts = 1, ret, info;
+	int ret, info;
+	bool validate_ts = true;
 	struct cobalt_sem *sem;
 	xnhandle_t handle;
 	xntmode_t tmode;
@@ -304,24 +295,23 @@ int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user *u_sem,
 		 * it's actually more complex, to keep some
 		 * applications ported to Linux happy.
 		 */
-		if (pull_ts) {
+		if (validate_ts) {
 			atomic_inc(&sem->state->value);
-			xnlock_put_irqrestore(&nklock, s);
-			ret = fetch_timeout(&ts, u_ts);
-			xnlock_get_irqsave(&nklock, s);
-			if (ret)
+			if (!ts) {
+				ret = -EFAULT;
 				break;
-			if (ts.tv_nsec >= ONE_BILLION) {
+			}
+			if (!timespec64_valid(ts)) {
 				ret = -EINVAL;
 				break;
 			}
-			pull_ts = 0;
+			validate_ts = false;
 			continue;
 		}
 
 		ret = 0;
 		tmode = sem->flags & SEM_RAWCLOCK ? XN_ABSOLUTE : XN_REALTIME;
-		info = xnsynch_sleep_on(&sem->synchbase, ts2ns(&ts) + 1, tmode);
+		info = xnsynch_sleep_on(&sem->synchbase, ts2ns(ts) + 1, tmode);
 		if (info & XNRMID)
 			ret = -EINVAL;
 		else if (info & (XNBREAK|XNTIMEO)) {
@@ -434,9 +424,15 @@ COBALT_SYSCALL(sem_wait, primary,
 
 COBALT_SYSCALL(sem_timedwait, primary,
 	       (struct cobalt_sem_shadow __user *u_sem,
-		struct __user_old_timespec __user *u_ts))
+		const struct __user_old_timespec __user *u_ts))
 {
-	return __cobalt_sem_timedwait(u_sem, u_ts, sem_fetch_timeout);
+	int ret = 1;
+	struct timespec64 ts64;
+
+	if (u_ts)
+		ret = cobalt_get_u_timespec(&ts64, u_ts);
+
+	return __cobalt_sem_timedwait(u_sem, ret ? NULL : &ts64);
 }
 
 COBALT_SYSCALL(sem_trywait, primary,
diff --git a/kernel/cobalt/posix/sem.h b/kernel/cobalt/posix/sem.h
index d172994950..658e11f7a6 100644
--- a/kernel/cobalt/posix/sem.h
+++ b/kernel/cobalt/posix/sem.h
@@ -64,9 +64,7 @@ __cobalt_sem_open(struct cobalt_sem_shadow __user *usm,
 		  int oflags, mode_t mode, unsigned int value);
 
 int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user *u_sem,
-			   const void __user *u_ts,
-			   int (*fetch_timeout)(struct timespec64 *ts,
-						const void __user *u_ts));
+			   const struct timespec64 *ts);
 
 int __cobalt_sem_destroy(xnhandle_t handle);
 
@@ -91,7 +89,7 @@ COBALT_SYSCALL_DECL(sem_wait,
 
 COBALT_SYSCALL_DECL(sem_timedwait,
 		    (struct cobalt_sem_shadow __user *u_sem,
-		     struct __user_old_timespec __user *u_ts));
+		     const struct __user_old_timespec __user *u_ts));
 
 COBALT_SYSCALL_DECL(sem_trywait,
 		    (struct cobalt_sem_shadow __user *u_sem));
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 57aa7251a4..edac7ea4ae 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -124,9 +124,15 @@ COBALT_SYSCALL32emu(sem_open, lostage,
 
 COBALT_SYSCALL32emu(sem_timedwait, primary,
 		    (struct cobalt_sem_shadow __user *u_sem,
-		     struct old_timespec32 __user *u_ts))
+		     const struct old_timespec32 __user *u_ts))
 {
-	return __cobalt_sem_timedwait(u_sem, u_ts, sys32_fetch_timeout);
+	int ret = 1;
+	struct timespec64 ts64;
+
+	if (u_ts)
+		ret = sys32_fetch_timeout(&ts64, u_ts);
+
+	return __cobalt_sem_timedwait(u_sem, ret ? NULL : &ts64);
 }
 
 COBALT_SYSCALL32emu(clock_getres, current,
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index 66cd2a5d24..d72fd20229 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -229,6 +229,6 @@ COBALT_SYSCALL32emu_DECL(sem_open,
 
 COBALT_SYSCALL32emu_DECL(sem_timedwait,
 			 (struct cobalt_sem_shadow __user *u_sem,
-			  struct old_timespec32 __user *u_ts));
+			  const struct old_timespec32 __user *u_ts));
 
 #endif /* !_COBALT_POSIX_SYSCALL32_H */
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v2 7/9] y2038: Adding sem_timedwait64
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
                   ` (5 preceding siblings ...)
  2021-05-05 16:53 ` [PATCH v2 6/9] cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems Jan Kiszka
@ 2021-05-05 16:53 ` Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 8/9] y2038: Add tests for the sc_cobalt_sem_timedwait64 syscall Jan Kiszka
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:53 UTC (permalink / raw)
  To: xenomai

From: Florian Bezdeka <florian.bezdeka@siemens.com>

Implementation is heavily inspired by the sem_timedwait syscall,
but expecting time64 based timespec / timeout.

We need two new syscall handlers:
  - The native one (COBALT_SYSCALL()) to get 32 bit kernels time64
    aware. This handler is added for 64 bit kernels as well, but not
    used. As we don't have separate syscall tables for this both
    worlds we have to add it.

 - The compat handler (COBALT_SYSCALL32emu()) for x32 or x86
   applications running on an x86_64 kernel. Otherwise the redirection
   to the compat / emulation syscalls is broken.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/time.h    | 22 ++++++++++++++++++++++
 include/cobalt/uapi/syscall.h   |  1 +
 kernel/cobalt/Makefile          |  1 +
 kernel/cobalt/posix/sem.c       | 20 ++++++++++++++++++++
 kernel/cobalt/posix/sem.h       |  7 +++++++
 kernel/cobalt/posix/syscall32.c |  7 +++++++
 kernel/cobalt/posix/syscall32.h |  4 ++++
 kernel/cobalt/time.c            | 29 +++++++++++++++++++++++++++++
 8 files changed, 91 insertions(+)
 create mode 100644 include/cobalt/kernel/time.h
 create mode 100644 kernel/cobalt/time.c

diff --git a/include/cobalt/kernel/time.h b/include/cobalt/kernel/time.h
new file mode 100644
index 0000000000..19e8f2c563
--- /dev/null
+++ b/include/cobalt/kernel/time.h
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _COBALT_KERNEL_TIME_H
+#define _COBALT_KERNEL_TIME_H
+
+#include <linux/time.h>
+#include <linux/time64.h>
+
+/**
+ * Read struct __kernel_timespec from userspace and convert to
+ * struct timespec64
+ *
+ * @param ts The destination, will be filled
+ * @param uts The source, provided by an application
+ * @return 0 on success, -EFAULT otherwise
+ */
+int cobalt_get_timespec64(struct timespec64 *ts,
+			  const struct __kernel_timespec __user *uts);
+
+#endif //_COBALT_KERNEL_TIME_H
diff --git a/include/cobalt/uapi/syscall.h b/include/cobalt/uapi/syscall.h
index aa3c308d0b..8895d2bffb 100644
--- a/include/cobalt/uapi/syscall.h
+++ b/include/cobalt/uapi/syscall.h
@@ -122,6 +122,7 @@
 #define sc_cobalt_sendmmsg			99
 #define sc_cobalt_clock_adjtime			100
 #define sc_cobalt_thread_setschedprio		101
+#define sc_cobalt_sem_timedwait64		102
 
 #define __NR_COBALT_SYSCALLS			128 /* Power of 2 */
 
diff --git a/kernel/cobalt/Makefile b/kernel/cobalt/Makefile
index 129005d8fa..6cd2d5994e 100644
--- a/kernel/cobalt/Makefile
+++ b/kernel/cobalt/Makefile
@@ -13,6 +13,7 @@ xenomai-y :=	arith.o 	\
 		select.o	\
 		synch.o		\
 		thread.o	\
+		time.o		\
 		timer.o		\
 		tree.o
 
diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index 827a4751a0..72b20c78d2 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -19,6 +19,7 @@
 
 #include <stddef.h>
 #include <linux/err.h>
+#include <cobalt/kernel/time.h>
 #include "internal.h"
 #include "thread.h"
 #include "clock.h"
@@ -326,6 +327,18 @@ int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user *u_sem,
 	return ret;
 }
 
+int __cobalt_sem_timedwait64(struct cobalt_sem_shadow __user *u_sem,
+			     const struct __kernel_timespec __user *u_ts)
+{
+	int ret = 1;
+	struct timespec64 ts64;
+
+	if (u_ts)
+		ret = cobalt_get_timespec64(&ts64, u_ts);
+
+	return __cobalt_sem_timedwait(u_sem, ret ? NULL : &ts64);
+}
+
 static int sem_post(xnhandle_t handle)
 {
 	struct cobalt_sem *sem;
@@ -435,6 +448,13 @@ COBALT_SYSCALL(sem_timedwait, primary,
 	return __cobalt_sem_timedwait(u_sem, ret ? NULL : &ts64);
 }
 
+COBALT_SYSCALL(sem_timedwait64, primary,
+	       (struct cobalt_sem_shadow __user *u_sem,
+		const struct __kernel_timespec __user *u_ts))
+{
+	return __cobalt_sem_timedwait64(u_sem, u_ts);
+}
+
 COBALT_SYSCALL(sem_trywait, primary,
 	       (struct cobalt_sem_shadow __user *u_sem))
 {
diff --git a/kernel/cobalt/posix/sem.h b/kernel/cobalt/posix/sem.h
index 658e11f7a6..d7dbb9098b 100644
--- a/kernel/cobalt/posix/sem.h
+++ b/kernel/cobalt/posix/sem.h
@@ -66,6 +66,9 @@ __cobalt_sem_open(struct cobalt_sem_shadow __user *usm,
 int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user *u_sem,
 			   const struct timespec64 *ts);
 
+int __cobalt_sem_timedwait64(struct cobalt_sem_shadow __user *u_sem,
+			     const struct __kernel_timespec __user *u_ts);
+
 int __cobalt_sem_destroy(xnhandle_t handle);
 
 void cobalt_nsem_reclaim(struct cobalt_process *process);
@@ -91,6 +94,10 @@ COBALT_SYSCALL_DECL(sem_timedwait,
 		    (struct cobalt_sem_shadow __user *u_sem,
 		     const struct __user_old_timespec __user *u_ts));
 
+COBALT_SYSCALL_DECL(sem_timedwait64,
+		    (struct cobalt_sem_shadow __user *u_sem,
+		     const struct __kernel_timespec __user *u_ts));
+
 COBALT_SYSCALL_DECL(sem_trywait,
 		    (struct cobalt_sem_shadow __user *u_sem));
 
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index edac7ea4ae..a5dc6e48f9 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -135,6 +135,13 @@ COBALT_SYSCALL32emu(sem_timedwait, primary,
 	return __cobalt_sem_timedwait(u_sem, ret ? NULL : &ts64);
 }
 
+COBALT_SYSCALL32emu(sem_timedwait64, primary,
+		    (struct cobalt_sem_shadow __user *u_sem,
+		     const struct __kernel_timespec __user *u_ts))
+{
+	return __cobalt_sem_timedwait64(u_sem, u_ts);
+}
+
 COBALT_SYSCALL32emu(clock_getres, current,
 		    (clockid_t clock_id,
 		     struct old_timespec32 __user *u_ts))
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index d72fd20229..0b5e26d9e4 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -231,4 +231,8 @@ COBALT_SYSCALL32emu_DECL(sem_timedwait,
 			 (struct cobalt_sem_shadow __user *u_sem,
 			  const struct old_timespec32 __user *u_ts));
 
+COBALT_SYSCALL32emu_DECL(sem_timedwait64,
+			 (struct cobalt_sem_shadow __user * u_sem,
+			  const struct __kernel_timespec __user *u_ts));
+
 #endif /* !_COBALT_POSIX_SYSCALL32_H */
diff --git a/kernel/cobalt/time.c b/kernel/cobalt/time.c
new file mode 100644
index 0000000000..a3fd8a740a
--- /dev/null
+++ b/kernel/cobalt/time.c
@@ -0,0 +1,29 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <asm-generic/xenomai/syscall.h>
+#include <cobalt/kernel/time.h>
+#include <linux/compat.h>
+
+int cobalt_get_timespec64(struct timespec64 *ts,
+			  const struct __kernel_timespec __user *uts)
+{
+	struct __kernel_timespec kts;
+	int ret;
+
+	ret = cobalt_copy_from_user(&kts, uts, sizeof(kts));
+	if (ret)
+		return -EFAULT;
+
+	ts->tv_sec = kts.tv_sec;
+
+	/* Zero out the padding in compat mode */
+	if (in_compat_syscall())
+		kts.tv_nsec &= 0xFFFFFFFFUL;
+
+	/* In 32-bit mode, this drops the padding */
+	ts->tv_nsec = kts.tv_nsec;
+
+	return 0;
+}
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v2 8/9] y2038: Add tests for the sc_cobalt_sem_timedwait64 syscall
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
                   ` (6 preceding siblings ...)
  2021-05-05 16:53 ` [PATCH v2 7/9] y2038: Adding sem_timedwait64 Jan Kiszka
@ 2021-05-05 16:53 ` Jan Kiszka
  2021-05-05 16:53 ` [PATCH v2 9/9] y2038: lib/cobalt: Add support of sc_cobalt_sem_timedwait64 Jan Kiszka
  2021-05-06  5:20 ` [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
  9 siblings, 0 replies; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:53 UTC (permalink / raw)
  To: xenomai

From: Florian Bezdeka <florian.bezdeka@siemens.com>

Introducing a new smokey plugin that can be extended for all kind of
y2038 tests. For now we are testing the new sc_cobalt_sem_timedwait64
syscall without using any libc wrappers provided by libcobalt.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
[Jan: add missing stdbool include]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 configure.ac                           |   1 +
 testsuite/smokey/Makefile.am           |   6 +-
 testsuite/smokey/y2038/Makefile.am     |   9 ++
 testsuite/smokey/y2038/syscall-tests.c | 176 +++++++++++++++++++++++++
 4 files changed, 190 insertions(+), 2 deletions(-)
 create mode 100644 testsuite/smokey/y2038/Makefile.am
 create mode 100644 testsuite/smokey/y2038/syscall-tests.c

diff --git a/configure.ac b/configure.ac
index abe538dbd4..bd5fd5ba9a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -990,6 +990,7 @@ AC_CONFIG_FILES([ \
 	testsuite/smokey/net_common/Makefile \
 	testsuite/smokey/cpu-affinity/Makefile \
 	testsuite/smokey/gdb/Makefile \
+	testsuite/smokey/y2038/Makefile \
 	testsuite/clocktest/Makefile \
 	testsuite/xeno-test/Makefile \
 	utils/Makefile \
diff --git a/testsuite/smokey/Makefile.am b/testsuite/smokey/Makefile.am
index 02613c7dc7..56c8730268 100644
--- a/testsuite/smokey/Makefile.am
+++ b/testsuite/smokey/Makefile.am
@@ -38,7 +38,8 @@ COBALT_SUBDIRS = 	\
 	timerfd		\
 	tsc		\
 	vdso-access 	\
-	xddp
+	xddp		\
+	y2038
 
 MERCURY_SUBDIRS =	\
 	memory-heapmem	\
@@ -76,7 +77,8 @@ DIST_SUBDIRS = 		\
 	timerfd		\
 	tsc		\
 	vdso-access 	\
-	xddp
+	xddp		\
+	y2038
 
 if XENO_COBALT
 if CONFIG_XENO_LIBS_DLOPEN
diff --git a/testsuite/smokey/y2038/Makefile.am b/testsuite/smokey/y2038/Makefile.am
new file mode 100644
index 0000000000..96fc13cb6f
--- /dev/null
+++ b/testsuite/smokey/y2038/Makefile.am
@@ -0,0 +1,9 @@
+
+noinst_LIBRARIES = liby2038.a
+
+liby2038_a_SOURCES = syscall-tests.c
+
+liby2038_a_CPPFLAGS = 	\
+	@XENO_USER_CFLAGS@	\
+	-I$(top_srcdir)		\
+	-I$(top_srcdir)/include
diff --git a/testsuite/smokey/y2038/syscall-tests.c b/testsuite/smokey/y2038/syscall-tests.c
new file mode 100644
index 0000000000..efc7562d75
--- /dev/null
+++ b/testsuite/smokey/y2038/syscall-tests.c
@@ -0,0 +1,176 @@
+/*
+ * y2038 tests
+ *
+ * Copyright (c) Siemens AG 2021
+ *
+ * Authors:
+ *  Florian Bezdeka <florian.bezdeka@siemens.com>
+ *
+ * Released under the terms of GPLv2.
+ */
+#include <cobalt/uapi/syscall.h>
+#include <smokey/smokey.h>
+#include <semaphore.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+
+smokey_test_plugin(y2038, SMOKEY_NOARGS, "Validate correct y2038 support");
+
+/*
+ * libc independent data type representing a time64_t based struct timespec
+ */
+struct xn_timespec64 {
+	int64_t tv_sec;
+	int64_t tv_nsec;
+};
+
+#define NSEC_PER_SEC 1000000000
+
+static void ts_normalise(struct xn_timespec64 *ts)
+{
+	while (ts->tv_nsec >= NSEC_PER_SEC) {
+		ts->tv_nsec += 1;
+		ts->tv_nsec -= NSEC_PER_SEC;
+	}
+
+	while (ts->tv_nsec <= -NSEC_PER_SEC) {
+		ts->tv_sec -= 1;
+		ts->tv_nsec += NSEC_PER_SEC;
+	}
+
+	if (ts->tv_nsec < 0) {
+		/*
+		 * Negative nanoseconds isn't valid according to POSIX.
+		 * Decrement tv_sec and roll tv_nsec over.
+		 */
+		ts->tv_sec -= 1;
+		ts->tv_nsec = (NSEC_PER_SEC + ts->tv_nsec);
+	}
+}
+
+static inline void ts_add_ns(struct xn_timespec64 *ts, int ns)
+{
+	ts->tv_nsec += ns;
+	ts_normalise(ts);
+}
+
+/**
+ * Compare two struct timespec instances
+ *
+ * @param a
+ * @param b
+ * @return True if a < b, false otherwise
+ */
+static inline bool ts_less(const struct xn_timespec64 *a,
+			   const struct xn_timespec64 *b)
+{
+	if (a->tv_sec < b->tv_sec)
+		return true;
+
+	if (a->tv_sec > b->tv_sec)
+		return false;
+
+	/* a->tv_sec == b->tv_sec */
+
+	if (a->tv_nsec < b->tv_nsec)
+		return true;
+
+	return false;
+}
+
+static int test_sc_cobalt_sem_timedwait64(void)
+{
+	long ret;
+	sem_t sem;
+	int code = __xn_syscode(sc_cobalt_sem_timedwait64);
+	struct xn_timespec64 ts64, ts_wu;
+	struct timespec ts_nat;
+
+	sem_init(&sem, 0, 0);
+
+	/* Make sure we don't crash because of NULL pointers */
+	ret = syscall(code, NULL, NULL);
+	if (ret == -1 && errno == ENOSYS) {
+		smokey_note("sem_timedwait64: skipped. (no kernel support)");
+		return 0; // Not implemented, nothing to test, success
+	}
+	if (!smokey_assert(ret == -1) || !smokey_assert(errno == EINVAL))
+		return errno;
+
+	/* Timeout is never read by the kernel, so NULL should be OK */
+	sem_post(&sem);
+	ret = syscall(code, &sem, NULL);
+	if (!smokey_assert(!ret))
+		return errno;
+
+	/*
+	 * The semaphore is already exhausted, so calling again will validate
+	 * the provided timeout now. Providing NULL has to deliver EFAULT
+	 */
+	ret = syscall(code, &sem, NULL);
+	if (!smokey_assert(ret == -1) || !smokey_assert(errno == EFAULT))
+		return errno;
+
+	/*
+	 * The semaphore is already exhausted, so calling again will validate
+	 * the provided timeout now. Providing an invalid adress has to deliver
+	 * EFAULT
+	 */
+	ret = syscall(code, &sem, (void*) 0xdeadbeefUL);
+	if (!smokey_assert(ret == -1) || !smokey_assert(errno == EFAULT))
+		return errno;
+
+	/*
+	 * The semaphore is still exhausted, calling again will validate the
+	 * timeout, providing an invalid timeout has to deliver EINVAL
+	 */
+	ts64.tv_sec = -1;
+	ret = syscall(code, &sem, &ts64);
+	if (!smokey_assert(ret == -1) || !smokey_assert(errno == EINVAL))
+		return errno;
+
+	/*
+	 * Providing a valid timeout, waiting for it to time out and check
+	 * that we didn't come back to early.
+	 */
+	ret = clock_gettime(CLOCK_MONOTONIC, &ts_nat);
+	if (ret)
+		return errno;
+
+	ts64.tv_sec = ts_nat.tv_sec;
+	ts64.tv_nsec = ts_nat.tv_nsec;
+	ts_add_ns(&ts64, 500000);
+
+	ret = syscall(code, &sem, &ts64);
+	if (!smokey_assert(ret == -1) || !smokey_assert(errno == ETIMEDOUT))
+		return errno;
+
+	ret = clock_gettime(CLOCK_MONOTONIC, &ts_nat);
+	if (ret)
+		return errno;
+
+	ts_wu.tv_sec = ts_nat.tv_sec;
+	ts_wu.tv_nsec = ts_nat.tv_nsec;
+
+	if (ts_less(&ts_wu, &ts64))
+		smokey_warning("sem_timedwait64 returned to early!\n"
+			       "Expected wakeup at: %lld sec %lld nsec\n"
+			       "Back at           : %lld sec %lld nsec\n",
+			       ts64.tv_sec, ts64.tv_nsec, ts_wu.tv_sec,
+			       ts_wu.tv_nsec);
+
+	return 0;
+}
+
+static int run_y2038(struct smokey_test *t, int argc, char *const argv[])
+{
+	int ret;
+
+	ret = test_sc_cobalt_sem_timedwait64();
+	if (ret)
+		return ret;
+
+	return 0;
+}
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v2 9/9] y2038: lib/cobalt: Add support of sc_cobalt_sem_timedwait64
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
                   ` (7 preceding siblings ...)
  2021-05-05 16:53 ` [PATCH v2 8/9] y2038: Add tests for the sc_cobalt_sem_timedwait64 syscall Jan Kiszka
@ 2021-05-05 16:53 ` Jan Kiszka
  2021-05-06  5:20 ` [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
  9 siblings, 0 replies; 22+ messages in thread
From: Jan Kiszka @ 2021-05-05 16:53 UTC (permalink / raw)
  To: xenomai

From: Florian Bezdeka <florian.bezdeka@siemens.com>

In case libcobalt is build with -D_TIME_BITS=64
sc_cobalt_sem_timedwait64 will be used instead of
sc_cobalt_sem_timedwait.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 lib/cobalt/semaphore.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/cobalt/semaphore.c b/lib/cobalt/semaphore.c
index 45705d48f3..bff0054401 100644
--- a/lib/cobalt/semaphore.c
+++ b/lib/cobalt/semaphore.c
@@ -373,7 +373,12 @@ COBALT_IMPL(int, sem_timedwait, (sem_t *sem, const struct timespec *abs_timeout)
 
 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
+#ifdef __USE_TIME_BITS64
+	ret = XENOMAI_SYSCALL2(sc_cobalt_sem_timedwait64, _sem,
+			       abs_timeout);
+#else
 	ret = XENOMAI_SYSCALL2(sc_cobalt_sem_timedwait, _sem, abs_timeout);
+#endif
 
 	pthread_setcanceltype(oldtype, NULL);
 
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
                   ` (8 preceding siblings ...)
  2021-05-05 16:53 ` [PATCH v2 9/9] y2038: lib/cobalt: Add support of sc_cobalt_sem_timedwait64 Jan Kiszka
@ 2021-05-06  5:20 ` Jan Kiszka
  2021-05-06  7:02   ` Philippe Gerum
  9 siblings, 1 reply; 22+ messages in thread
From: Jan Kiszka @ 2021-05-06  5:20 UTC (permalink / raw)
  To: xenomai, Bezdeka, Florian (T RDA IOT SES-DE)

On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
> Picking up from Philippe's queue:
> 
> This patch series prepares the tree for the upcoming y2038 work,
> converting obsolete/ambiguous time specification types to the proper
> ones introduced upstream by the v5.x kernel series.
> 
> In v2, feedback on the first round has been addressed, primarily
> regarding folding fixing into the patches that need them.
> 
> In addition, this includes 3 patches from Florian that add
> sem_timedwait64 system call and a test suite for it.
> 

Seems we have some issue on ARM ("Illegal instruction" in smokey):
https://source.denx.de/Xenomai/xenomai-images/-/jobs/264219
https://source.denx.de/Xenomai/xenomai-images/-/jobs/264225

Florian, could you check that?

Thanks,
Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-06  5:20 ` [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
@ 2021-05-06  7:02   ` Philippe Gerum
  2021-05-06  7:08     ` Bezdeka, Florian
  0 siblings, 1 reply; 22+ messages in thread
From: Philippe Gerum @ 2021-05-06  7:02 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Bezdeka, Florian (T RDA IOT SES-DE), xenomai


Jan Kiszka via Xenomai <xenomai@xenomai.org> writes:

> On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
>> Picking up from Philippe's queue:
>> 
>> This patch series prepares the tree for the upcoming y2038 work,
>> converting obsolete/ambiguous time specification types to the proper
>> ones introduced upstream by the v5.x kernel series.
>> 
>> In v2, feedback on the first round has been addressed, primarily
>> regarding folding fixing into the patches that need them.
>> 
>> In addition, this includes 3 patches from Florian that add
>> sem_timedwait64 system call and a test suite for it.
>> 
>
> Seems we have some issue on ARM ("Illegal instruction" in smokey):
> https://source.denx.de/Xenomai/xenomai-images/-/jobs/264219
> https://source.denx.de/Xenomai/xenomai-images/-/jobs/264225

That one may be related to the code directing clock_gettime() either to
the vDSO with Dovetail, or TSC readouts via a memory mapping with the
I-pipe, all in libcobalt.

>
> Florian, could you check that?
>
> Thanks,
> Jan


-- 
Philippe.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-06  7:02   ` Philippe Gerum
@ 2021-05-06  7:08     ` Bezdeka, Florian
  2021-05-07 11:29       ` Florian Bezdeka
  0 siblings, 1 reply; 22+ messages in thread
From: Bezdeka, Florian @ 2021-05-06  7:08 UTC (permalink / raw)
  To: rpm, jan.kiszka; +Cc: xenomai

On Thu, 2021-05-06 at 09:02 +0200, Philippe Gerum wrote:
> Jan Kiszka via Xenomai <xenomai@xenomai.org> writes:
> 
> > On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
> > > Picking up from Philippe's queue:
> > > 
> > > This patch series prepares the tree for the upcoming y2038 work,
> > > converting obsolete/ambiguous time specification types to the proper
> > > ones introduced upstream by the v5.x kernel series.
> > > 
> > > In v2, feedback on the first round has been addressed, primarily
> > > regarding folding fixing into the patches that need them.
> > > 
> > > In addition, this includes 3 patches from Florian that add
> > > sem_timedwait64 system call and a test suite for it.
> > > 
> > 
> > Seems we have some issue on ARM ("Illegal instruction" in smokey):
> > https://source.denx.de/Xenomai/xenomai-images/-/jobs/264219
> > https://source.denx.de/Xenomai/xenomai-images/-/jobs/264225
> 
> That one may be related to the code directing clock_gettime() either to
> the vDSO with Dovetail, or TSC readouts via a memory mapping with the
> I-pipe, all in libcobalt.

Thanks for the hint! I will check that and report back.

> 
> > 
> > Florian, could you check that?
> > 
> > Thanks,
> > Jan
> 
> 


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 1/9] cobalt/kernel: y2038: convert struct timespec to timespec64
  2021-05-05 16:53 ` [PATCH v2 1/9] cobalt/kernel: y2038: convert struct timespec to timespec64 Jan Kiszka
@ 2021-05-07  6:09   ` Florian Bezdeka
  2021-05-07  6:54     ` Philippe Gerum
  0 siblings, 1 reply; 22+ messages in thread
From: Florian Bezdeka @ 2021-05-07  6:09 UTC (permalink / raw)
  To: Jan Kiszka, xenomai, Philippe Gerum

On 05.05.21 18:53, Jan Kiszka via Xenomai wrote:
> From: Philippe Gerum <rpm@xenomai.org>
> 
> As internal interfaces are gradually being made y2038-safe, the
> timespec64 type should be used internally by the kernel to represent
> time values. Apply the same reasoning to Cobalt.
> 
> We still use a legacy y2038-unsafe timespec type at the kernel<->user
> interface boundary (struct __user_old_timespec) until libcobalt is
> y2038-safe.
> 
> Signed-off-by: Philippe Gerum <rpm@xenomai.org>
> [Florian: Fix regression in 32bit mode]
> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  include/cobalt/kernel/clock.h                 |  6 +-
>  include/cobalt/kernel/compat.h                |  4 +-
>  .../cobalt/kernel/dovetail/pipeline/clock.h   |  4 +-
>  include/cobalt/kernel/ipipe/pipeline/clock.h  |  4 +-
>  include/cobalt/kernel/rtdm/fd.h               |  2 +-
>  include/cobalt/uapi/kernel/types.h            | 10 ++++
>  include/cobalt/uapi/sched.h                   | 12 ++--
>  .../include/asm-generic/xenomai/syscall.h     | 58 +++++++++++++++++++
>  kernel/cobalt/ipipe/clock.c                   |  2 +-
>  kernel/cobalt/posix/clock.c                   | 38 ++++++------
>  kernel/cobalt/posix/clock.h                   | 39 +++++++++----
>  kernel/cobalt/posix/compat.c                  | 46 ++++++++++-----
>  kernel/cobalt/posix/cond.c                    | 11 ++--
>  kernel/cobalt/posix/cond.h                    |  4 +-
>  kernel/cobalt/posix/event.c                   |  8 +--
>  kernel/cobalt/posix/event.h                   |  4 +-
>  kernel/cobalt/posix/io.c                      |  6 +-
>  kernel/cobalt/posix/io.h                      |  2 +-
>  kernel/cobalt/posix/monitor.c                 |  8 +--
>  kernel/cobalt/posix/monitor.h                 |  4 +-
>  kernel/cobalt/posix/mqueue.c                  | 21 ++++---
>  kernel/cobalt/posix/mqueue.h                  |  8 +--
>  kernel/cobalt/posix/mutex.c                   | 13 ++---
>  kernel/cobalt/posix/mutex.h                   |  6 +-
>  kernel/cobalt/posix/sched.c                   | 16 ++---
>  kernel/cobalt/posix/sem.c                     |  8 +--
>  kernel/cobalt/posix/sem.h                     |  4 +-
>  kernel/cobalt/posix/signal.c                  |  6 +-
>  kernel/cobalt/posix/signal.h                  |  4 +-
>  kernel/cobalt/posix/syscall32.c               | 26 ++++-----
>  kernel/cobalt/posix/syscall32.h               |  2 +-
>  kernel/cobalt/posix/thread.c                  |  6 +-
>  kernel/cobalt/rtdm/fd.c                       |  4 +-
>  kernel/cobalt/trace/cobalt-posix.h            | 30 +++++-----
>  34 files changed, 262 insertions(+), 164 deletions(-)
> 
> diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
> index bbf34c53cf..1c99173ff8 100644
> --- a/include/cobalt/kernel/clock.h
> +++ b/include/cobalt/kernel/clock.h
> @@ -54,7 +54,7 @@ struct xnclock {
>  		xnticks_t (*read_raw)(struct xnclock *clock);
>  		xnticks_t (*read_monotonic)(struct xnclock *clock);
>  		int (*set_time)(struct xnclock *clock,
> -				const struct timespec *ts);
> +				const struct timespec64 *ts);
>  		xnsticks_t (*ns_to_ticks)(struct xnclock *clock,
>  					  xnsticks_t ns);
>  		xnsticks_t (*ticks_to_ns)(struct xnclock *clock,
> @@ -211,7 +211,7 @@ static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
>  }
>  
>  static inline int xnclock_set_time(struct xnclock *clock,
> -				   const struct timespec *ts)
> +				   const struct timespec64 *ts)
>  {
>  	if (likely(clock == &nkclock))
>  		return -EINVAL;
> @@ -264,7 +264,7 @@ static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
>  }
>  
>  static inline int xnclock_set_time(struct xnclock *clock,
> -				   const struct timespec *ts)
> +				   const struct timespec64 *ts)
>  {
>  	/*
>  	 * There is no way to change the core clock's idea of time.
> diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
> index 313b6251b4..c57ef65325 100644
> --- a/include/cobalt/kernel/compat.h
> +++ b/include/cobalt/kernel/compat.h
> @@ -86,11 +86,11 @@ struct compat_rtdm_mmap_request {
>  	int flags;
>  };
>  
> -int sys32_get_timespec(struct timespec *ts,
> +int sys32_get_timespec(struct timespec64 *ts,
>  		       const struct compat_timespec __user *cts);
>  
>  int sys32_put_timespec(struct compat_timespec __user *cts,
> -		       const struct timespec *ts);
> +		       const struct timespec64 *ts);
>  
>  int sys32_get_itimerspec(struct itimerspec *its,
>  			 const struct compat_itimerspec __user *cits);
> diff --git a/include/cobalt/kernel/dovetail/pipeline/clock.h b/include/cobalt/kernel/dovetail/pipeline/clock.h
> index 933e100baf..19e3d89865 100644
> --- a/include/cobalt/kernel/dovetail/pipeline/clock.h
> +++ b/include/cobalt/kernel/dovetail/pipeline/clock.h
> @@ -8,7 +8,7 @@
>  #include <cobalt/uapi/kernel/types.h>
>  #include <cobalt/kernel/assert.h>
>  
> -struct timespec;
> +struct timespec64;
>  
>  static inline u64 pipeline_read_cycle_counter(void)
>  {
> @@ -49,7 +49,7 @@ static inline const char *pipeline_clock_name(void)
>  	return "?";
>  }
>  
> -static inline int pipeline_get_host_time(struct timespec *tp)
> +static inline int pipeline_get_host_time(struct timespec64 *tp)
>  {
>  	/* Convert ktime_get_real_fast_ns() to timespec. */
>  	TODO();
> diff --git a/include/cobalt/kernel/ipipe/pipeline/clock.h b/include/cobalt/kernel/ipipe/pipeline/clock.h
> index fa7ac2a5e0..d35aea17b1 100644
> --- a/include/cobalt/kernel/ipipe/pipeline/clock.h
> +++ b/include/cobalt/kernel/ipipe/pipeline/clock.h
> @@ -7,7 +7,7 @@
>  
>  #include <linux/ipipe_tickdev.h>
>  
> -struct timespec;
> +struct timespec64;
>  
>  static inline u64 pipeline_read_cycle_counter(void)
>  {
> @@ -31,7 +31,7 @@ static inline const char *pipeline_clock_name(void)
>  	return ipipe_clock_name();
>  }
>  
> -int pipeline_get_host_time(struct timespec *tp);
> +int pipeline_get_host_time(struct timespec64 *tp);
>  
>  void pipeline_update_clock_freq(unsigned long long freq);
>  
> diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
> index 289065082b..37a09c43e8 100644
> --- a/include/cobalt/kernel/rtdm/fd.h
> +++ b/include/cobalt/kernel/rtdm/fd.h
> @@ -380,7 +380,7 @@ int __rtdm_fd_recvmmsg(int ufd, void __user *u_msgvec, unsigned int vlen,
>  		       unsigned int flags, void __user *u_timeout,
>  		       int (*get_mmsg)(struct mmsghdr *mmsg, void __user *u_mmsg),
>  		       int (*put_mmsg)(void __user **u_mmsg_p, const struct mmsghdr *mmsg),
> -		       int (*get_timespec)(struct timespec *ts, const void __user *u_ts));
> +		       int (*get_timespec)(struct timespec64 *ts, const void __user *u_ts));
>  
>  ssize_t rtdm_fd_sendmsg(int ufd, const struct user_msghdr *msg,
>  			int flags);
> diff --git a/include/cobalt/uapi/kernel/types.h b/include/cobalt/uapi/kernel/types.h
> index ee5bbadcae..8ce9b03df4 100644
> --- a/include/cobalt/uapi/kernel/types.h
> +++ b/include/cobalt/uapi/kernel/types.h
> @@ -57,4 +57,14 @@ static inline xnhandle_t xnhandle_get_id(xnhandle_t handle)
>  	return handle & ~XN_HANDLE_TRANSIENT_MASK;
>  }
>  
> +/*
> + * Our representation of time at the kernel<->user interface boundary
> + * at the moment, until we have fully transitioned to a y2038-safe
> + * implementation in libcobalt.
> + */
> +struct __user_old_timespec {
> +	long  tv_sec;
> +	long  tv_nsec;
> +};
> +
>  #endif /* !_COBALT_UAPI_KERNEL_TYPES_H */
> diff --git a/include/cobalt/uapi/sched.h b/include/cobalt/uapi/sched.h
> index b672095c3b..14095870f3 100644
> --- a/include/cobalt/uapi/sched.h
> +++ b/include/cobalt/uapi/sched.h
> @@ -18,6 +18,8 @@
>  #ifndef _COBALT_UAPI_SCHED_H
>  #define _COBALT_UAPI_SCHED_H
>  
> +#include <cobalt/uapi/kernel/types.h>
> +
>  #define SCHED_COBALT		42
>  #define SCHED_WEAK		43
>  
> @@ -31,15 +33,15 @@
>  
>  struct __sched_ss_param {
>  	int __sched_low_priority;
> -	struct timespec __sched_repl_period;
> -	struct timespec __sched_init_budget;
> +	struct __user_old_timespec __sched_repl_period;
> +	struct __user_old_timespec __sched_init_budget;
>  	int __sched_max_repl;
>  };
>  
>  #define sched_rr_quantum	sched_u.rr.__sched_rr_quantum
>  
>  struct __sched_rr_param {
> -	struct timespec __sched_rr_quantum;
> +	struct __user_old_timespec __sched_rr_quantum;
>  };
>  
>  #ifndef SCHED_TP
> @@ -52,8 +54,8 @@ struct __sched_tp_param {
>  };
>  
>  struct sched_tp_window {
> -	struct timespec offset;
> -	struct timespec duration;
> +	struct __user_old_timespec offset;
> +	struct __user_old_timespec duration;
>  	int ptid;
>  };
>  
> diff --git a/kernel/cobalt/include/asm-generic/xenomai/syscall.h b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
> index 0d50d4107d..05a7d28685 100644
> --- a/kernel/cobalt/include/asm-generic/xenomai/syscall.h
> +++ b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
> @@ -26,6 +26,7 @@
>  #include <asm/xenomai/wrappers.h>
>  #include <asm/xenomai/machine.h>
>  #include <cobalt/uapi/asm-generic/syscall.h>
> +#include <cobalt/uapi/kernel/types.h>
>  
>  #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
>  #define access_rok(addr, size)	access_ok((addr), (size))
> @@ -81,6 +82,63 @@ static inline int cobalt_strncpy_from_user(char *dst, const char __user *src,
>  	return __xn_strncpy_from_user(dst, src, count);
>  }
>  
> +#if __BITS_PER_LONG == 64
> +
> +/*
> + * NOTE: those copy helpers won't work in compat mode: use
> + * sys32_get_timespec(), sys32_put_timespec() instead.
> + */
> +
> +static inline int cobalt_get_u_timespec(struct timespec64 *dst,
> +			const struct __user_old_timespec __user *src)
> +{
> +	return cobalt_copy_from_user(dst, src, sizeof(*dst));
> +}
> +
> +static inline int cobalt_put_u_timespec(
> +	struct __user_old_timespec __user *dst,
> +	const struct timespec64 *src)
> +{
> +	return cobalt_copy_to_user(dst, src, sizeof(*dst));
> +}
> +
> +#else /* __BITS_PER_LONG == 32 */
> +
> +static inline int cobalt_get_u_timespec(struct timespec64 *dst,
> +			const struct __user_old_timespec __user *src)
> +{
> +	struct __user_old_timespec u_ts;
> +	int ret;
> +
> +	ret = cobalt_copy_from_user(&u_ts, src, sizeof(u_ts));
> +	if (ret)
> +		return ret;
> +
> +	dst->tv_sec = u_ts.tv_sec;
> +	dst->tv_nsec = u_ts.tv_nsec;
> +
> +	return 0;
> +}
> +
> +static inline int cobalt_put_u_timespec(
> +	struct __user_old_timespec __user *dst,
> +	const struct timespec64 *src)
> +{
> +	struct __user_old_timespec u_ts;
> +	int ret;
> +
> +	u_ts.tv_sec = src->tv_sec;
> +	u_ts.tv_nsec = src->tv_nsec;
> +
> +	ret = cobalt_copy_to_user(dst, &u_ts, sizeof(*dst));
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +#endif
> +

IIRC I already mentioned that after the first post of this patch:

The __BITS_PER_LONG == 32 version of that helpers work in both worlds.
So if we don't care about a few additional element on the stack (and a
few instructions) we could simplify the code a bit.


>  /* 32bit syscall emulation */
>  #define __COBALT_COMPAT_BIT	0x1
>  /* 32bit syscall emulation - extended form */
> diff --git a/kernel/cobalt/ipipe/clock.c b/kernel/cobalt/ipipe/clock.c
> index 606c6bf8c0..d40b0ac890 100644
> --- a/kernel/cobalt/ipipe/clock.c
> +++ b/kernel/cobalt/ipipe/clock.c
> @@ -67,7 +67,7 @@ EXPORT_SYMBOL_GPL(xnclock_core_ticks_to_ns);
>  EXPORT_SYMBOL_GPL(xnclock_core_ticks_to_ns_rounded);
>  EXPORT_SYMBOL_GPL(xnclock_core_ns_to_ticks);
>  
> -int pipeline_get_host_time(struct timespec *tp)
> +int pipeline_get_host_time(struct timespec64 *tp)
>  {
>  #ifdef CONFIG_IPIPE_HAVE_HOSTRT
>  	struct xnvdso_hostrt_data *hostrt_data;
> diff --git a/kernel/cobalt/posix/clock.c b/kernel/cobalt/posix/clock.c
> index e957dd9569..4a3365d2a9 100644
> --- a/kernel/cobalt/posix/clock.c
> +++ b/kernel/cobalt/posix/clock.c
> @@ -51,7 +51,7 @@ DECLARE_BITMAP(cobalt_clock_extids, COBALT_MAX_EXTCLOCKS);
>  	__val;							\
>  })
>  
> -int __cobalt_clock_getres(clockid_t clock_id, struct timespec *ts)
> +int __cobalt_clock_getres(clockid_t clock_id, struct timespec64 *ts)
>  {
>  	xnticks_t ns;
>  	int ret;
> @@ -75,16 +75,16 @@ int __cobalt_clock_getres(clockid_t clock_id, struct timespec *ts)
>  }
>  
>  COBALT_SYSCALL(clock_getres, current,
> -	       (clockid_t clock_id, struct timespec __user *u_ts))
> +	       (clockid_t clock_id, struct __user_old_timespec __user *u_ts))
>  {
> -	struct timespec ts;
> +	struct timespec64 ts;
>  	int ret;
>  
>  	ret = __cobalt_clock_getres(clock_id, &ts);
>  	if (ret)
>  		return ret;
>  
> -	if (u_ts && cobalt_copy_to_user(u_ts, &ts, sizeof(ts)))
> +	if (u_ts && cobalt_put_u_timespec(u_ts, &ts))
>  		return -EFAULT;
>  
>  	trace_cobalt_clock_getres(clock_id, &ts);
> @@ -92,7 +92,7 @@ COBALT_SYSCALL(clock_getres, current,
>  	return 0;
>  }
>  
> -int __cobalt_clock_gettime(clockid_t clock_id, struct timespec *ts)
> +int __cobalt_clock_gettime(clockid_t clock_id, struct timespec64 *ts)
>  {
>  	xnticks_t ns;
>  	int ret;
> @@ -122,16 +122,16 @@ int __cobalt_clock_gettime(clockid_t clock_id, struct timespec *ts)
>  }
>  
>  COBALT_SYSCALL(clock_gettime, current,
> -	       (clockid_t clock_id, struct timespec __user *u_ts))
> +	       (clockid_t clock_id, struct __user_old_timespec __user *u_ts))
>  {
> -	struct timespec ts;
> +	struct timespec64 ts;
>  	int ret;
>  
>  	ret = __cobalt_clock_gettime(clock_id, &ts);
>  	if (ret)
>  		return ret;
>  
> -	if (cobalt_copy_to_user(u_ts, &ts, sizeof(*u_ts)))
> +	if (cobalt_put_u_timespec(u_ts, &ts))
>  		return -EFAULT;
>  
>  	trace_cobalt_clock_gettime(clock_id, &ts);
> @@ -139,7 +139,7 @@ COBALT_SYSCALL(clock_gettime, current,
>  	return 0;
>  }
>  
> -int __cobalt_clock_settime(clockid_t clock_id, const struct timespec *ts)
> +int __cobalt_clock_settime(clockid_t clock_id, const struct timespec64 *ts)
>  {
>  	int _ret, ret = 0;
>  	xnticks_t now;
> @@ -188,11 +188,11 @@ int __cobalt_clock_adjtime(clockid_t clock_id, struct timex *tx)
>  }
>  
>  COBALT_SYSCALL(clock_settime, current,
> -	       (clockid_t clock_id, const struct timespec __user *u_ts))
> +	       (clockid_t clock_id, const struct __user_old_timespec __user *u_ts))
>  {
> -	struct timespec ts;
> +	struct timespec64 ts;
>  
> -	if (cobalt_copy_from_user(&ts, u_ts, sizeof(ts)))
> +	if (cobalt_get_u_timespec(&ts, u_ts))
>  		return -EFAULT;
>  
>  	return __cobalt_clock_settime(clock_id, &ts);
> @@ -215,8 +215,8 @@ COBALT_SYSCALL(clock_adjtime, current,
>  }
>  
>  int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
> -			     const struct timespec *rqt,
> -			     struct timespec *rmt)
> +			     const struct timespec64 *rqt,
> +			     struct timespec64 *rmt)
>  {
>  	struct restart_block *restart;
>  	struct xnthread *cur;
> @@ -296,21 +296,21 @@ int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
>  
>  COBALT_SYSCALL(clock_nanosleep, primary,
>  	       (clockid_t clock_id, int flags,
> -		const struct timespec __user *u_rqt,
> -		struct timespec __user *u_rmt))
> +		const struct __user_old_timespec __user *u_rqt,
> +		struct __user_old_timespec __user *u_rmt))
>  {
> -	struct timespec rqt, rmt, *rmtp = NULL;
> +	struct timespec64 rqt, rmt, *rmtp = NULL;
>  	int ret;
>  
>  	if (u_rmt)
>  		rmtp = &rmt;
>  
> -	if (cobalt_copy_from_user(&rqt, u_rqt, sizeof(rqt)))
> +	if (cobalt_get_u_timespec(&rqt, u_rqt))
>  		return -EFAULT;
>  
>  	ret = __cobalt_clock_nanosleep(clock_id, flags, &rqt, rmtp);
>  	if (ret == -EINTR && flags == 0 && rmtp) {
> -		if (cobalt_copy_to_user(u_rmt, rmtp, sizeof(*u_rmt)))
> +		if (cobalt_put_u_timespec(u_rmt, rmtp))
>  			return -EFAULT;
>  	}
>  
> diff --git a/kernel/cobalt/posix/clock.h b/kernel/cobalt/posix/clock.h
> index 7cb161df24..7e45fdcc6b 100644
> --- a/kernel/cobalt/posix/clock.h
> +++ b/kernel/cobalt/posix/clock.h
> @@ -28,12 +28,27 @@
>  
>  struct xnclock;
>  
> -static inline void ns2ts(struct timespec *ts, xnticks_t nsecs)
> +static inline void ns2ts(struct timespec64 *ts, xnticks_t nsecs)
>  {
>  	ts->tv_sec = xnclock_divrem_billion(nsecs, &ts->tv_nsec);
>  }
>  
> -static inline xnticks_t ts2ns(const struct timespec *ts)
> +static inline void u_ns2ts(struct __user_old_timespec *ts, xnticks_t nsecs)
> +{
> +	ts->tv_sec = xnclock_divrem_billion(nsecs, &ts->tv_nsec);
> +}
> +
> +static inline xnticks_t ts2ns(const struct timespec64 *ts)
> +{
> +	xnticks_t nsecs = ts->tv_nsec;
> +
> +	if (ts->tv_sec)
> +		nsecs += (xnticks_t)ts->tv_sec * ONE_BILLION;
> +
> +	return nsecs;
> +}
> +
> +static inline xnticks_t u_ts2ns(const struct __user_old_timespec *ts)
>  {
>  	xnticks_t nsecs = ts->tv_nsec;
>  
> @@ -80,37 +95,37 @@ static inline int clock_flag(int flag, clockid_t clock_id)
>  }
>  
>  int __cobalt_clock_getres(clockid_t clock_id,
> -			  struct timespec *ts);
> +			  struct timespec64 *ts);
>  
>  int __cobalt_clock_gettime(clockid_t clock_id,
> -			   struct timespec *ts);
> +			   struct timespec64 *ts);
>  
>  int __cobalt_clock_settime(clockid_t clock_id,
> -			   const struct timespec *ts);
> +			   const struct timespec64 *ts);
>  
>  int __cobalt_clock_adjtime(clockid_t clock_id,
>  			   struct timex *tx);
>  
>  int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
> -			     const struct timespec *rqt,
> -			     struct timespec *rmt);
> +			     const struct timespec64 *rqt,
> +			     struct timespec64 *rmt);
>  
>  COBALT_SYSCALL_DECL(clock_getres,
> -		    (clockid_t clock_id, struct timespec __user *u_ts));
> +		    (clockid_t clock_id, struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL_DECL(clock_gettime,
> -		    (clockid_t clock_id, struct timespec __user *u_ts));
> +		    (clockid_t clock_id, struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL_DECL(clock_settime,
> -		    (clockid_t clock_id, const struct timespec __user *u_ts));
> +		    (clockid_t clock_id, const struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL_DECL(clock_adjtime,
>  		    (clockid_t clock_id, struct timex __user *u_tx));
>  
>  COBALT_SYSCALL_DECL(clock_nanosleep,
>  		    (clockid_t clock_id, int flags,
> -		     const struct timespec __user *u_rqt,
> -		     struct timespec __user *u_rmt));
> +		     const struct __user_old_timespec __user *u_rqt,
> +		     struct __user_old_timespec __user *u_rmt));
>  
>  int cobalt_clock_register(struct xnclock *clock,
>  			  const cpumask_t *affinity,
> diff --git a/kernel/cobalt/posix/compat.c b/kernel/cobalt/posix/compat.c
> index 2ffc0dbdf4..1852950821 100644
> --- a/kernel/cobalt/posix/compat.c
> +++ b/kernel/cobalt/posix/compat.c
> @@ -22,23 +22,41 @@
>  #include <asm/xenomai/syscall.h>
>  #include <xenomai/posix/mqueue.h>
>  
> -int sys32_get_timespec(struct timespec *ts,
> -		       const struct compat_timespec __user *cts)
> +int sys32_get_timespec(struct timespec64 *ts,
> +		       const struct compat_timespec __user *u_cts)
>  {
> -	return (cts == NULL ||
> -		!access_rok(cts, sizeof(*cts)) ||
> -		__xn_get_user(ts->tv_sec, &cts->tv_sec) ||
> -		__xn_get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
> +	struct compat_timespec cts;
> +
> +	if (u_cts == NULL || !access_rok(u_cts, sizeof(*u_cts)))
> +		return -EFAULT;
> +
> +	if (__xn_get_user(cts.tv_sec, &u_cts->tv_sec) ||
> +		__xn_get_user(cts.tv_nsec, &u_cts->tv_nsec))
> +		return -EFAULT;
> +
> +	ts->tv_sec = cts.tv_sec;
> +	ts->tv_nsec = cts.tv_nsec;
> +
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(sys32_get_timespec);
>  
> -int sys32_put_timespec(struct compat_timespec __user *cts,
> -		       const struct timespec *ts)
> +int sys32_put_timespec(struct compat_timespec __user *u_cts,
> +		       const struct timespec64 *ts)
>  {
> -	return (cts == NULL ||
> -		!access_wok(cts, sizeof(*cts)) ||
> -		__xn_put_user(ts->tv_sec, &cts->tv_sec) ||
> -		__xn_put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
> +	struct compat_timespec cts;
> +
> +	if (u_cts == NULL || !access_wok(u_cts, sizeof(*u_cts)))
> +		return -EFAULT;
> +
> +	cts.tv_sec = ts->tv_sec;
> +	cts.tv_nsec = ts->tv_nsec;
> +
> +	if (__xn_put_user(cts.tv_sec, &u_cts->tv_sec) ||
> +	    __xn_put_user(cts.tv_nsec, &u_cts->tv_nsec))
> +		return -EFAULT;
> +
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(sys32_put_timespec);
>  
> @@ -478,7 +496,7 @@ int sys32_get_iovec(struct iovec *iov,
>  	const struct compat_iovec __user *p;
>  	struct compat_iovec ciov;
>  	int ret, n;
> -	
> +
>  	for (n = 0, p = u_ciov; n < ciovlen; n++, p++) {
>  		ret = cobalt_copy_from_user(&ciov, p, sizeof(ciov));
>  		if (ret)
> @@ -498,7 +516,7 @@ int sys32_put_iovec(struct compat_iovec __user *u_ciov,
>  	struct compat_iovec __user *p;
>  	struct compat_iovec ciov;
>  	int ret, n;
> -	
> +
>  	for (n = 0, p = u_ciov; n < iovlen; n++, p++) {
>  		ciov.iov_base = ptr_to_compat(iov[n].iov_base);
>  		ciov.iov_len = iov[n].iov_len;
> diff --git a/kernel/cobalt/posix/cond.c b/kernel/cobalt/posix/cond.c
> index 35a8f7176d..bb18fe316e 100644
> --- a/kernel/cobalt/posix/cond.c
> +++ b/kernel/cobalt/posix/cond.c
> @@ -270,25 +270,24 @@ struct us_cond_data {
>  	int err;
>  };
>  
> -static inline int cond_fetch_timeout(struct timespec *ts,
> +static inline int cond_fetch_timeout(struct timespec64 *ts,
>  				     const void __user *u_ts)
>  {
> -	return u_ts == NULL ? -EFAULT :
> -		cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
> +	return u_ts == NULL ? -EFAULT :	cobalt_get_u_timespec(ts, u_ts);
>  }
>  
>  int __cobalt_cond_wait_prologue(struct cobalt_cond_shadow __user *u_cnd,
>  				struct cobalt_mutex_shadow __user *u_mx,
>  				int *u_err,
>  				void __user *u_ts,
> -				int (*fetch_timeout)(struct timespec *ts,
> +				int (*fetch_timeout)(struct timespec64 *ts,
>  						     const void __user *u_ts))
>  {
>  	struct xnthread *cur = xnthread_current();
>  	struct cobalt_cond *cond;
>  	struct cobalt_mutex *mx;
>  	struct us_cond_data d;
> -	struct timespec ts;
> +	struct timespec64 ts;
>  	xnhandle_t handle;
>  	int err, perr = 0;
>  	__u32 offset;
> @@ -349,7 +348,7 @@ COBALT_SYSCALL(cond_wait_prologue, nonrestartable,
>  		struct cobalt_mutex_shadow __user *u_mx,
>  		int *u_err,
>  		unsigned int timed,
> -		struct timespec __user *u_ts))
> +		struct __user_old_timespec __user *u_ts))
>  {
>  	return __cobalt_cond_wait_prologue(u_cnd, u_mx, u_err, u_ts,
>  					   timed ? cond_fetch_timeout : NULL);
> diff --git a/kernel/cobalt/posix/cond.h b/kernel/cobalt/posix/cond.h
> index c7a9be4514..7bec2a649a 100644
> --- a/kernel/cobalt/posix/cond.h
> +++ b/kernel/cobalt/posix/cond.h
> @@ -43,7 +43,7 @@ int __cobalt_cond_wait_prologue(struct cobalt_cond_shadow __user *u_cnd,
>  				struct cobalt_mutex_shadow __user *u_mx,
>  				int *u_err,
>  				void __user *u_ts,
> -				int (*fetch_timeout)(struct timespec *ts,
> +				int (*fetch_timeout)(struct timespec64 *ts,
>  						     const void __user *u_ts));
>  COBALT_SYSCALL_DECL(cond_init,
>  		    (struct cobalt_cond_shadow __user *u_cnd,
> @@ -57,7 +57,7 @@ COBALT_SYSCALL_DECL(cond_wait_prologue,
>  		     struct cobalt_mutex_shadow __user *u_mx,
>  		     int *u_err,
>  		     unsigned int timed,
> -		     struct timespec __user *u_ts));
> +		     struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL_DECL(cond_wait_epilogue,
>  		    (struct cobalt_cond_shadow __user *u_cnd,
> diff --git a/kernel/cobalt/posix/event.c b/kernel/cobalt/posix/event.c
> index c566a09e36..3712154f53 100644
> --- a/kernel/cobalt/posix/event.c
> +++ b/kernel/cobalt/posix/event.c
> @@ -104,7 +104,7 @@ COBALT_SYSCALL(event_init, current,
>  int __cobalt_event_wait(struct cobalt_event_shadow __user *u_event,
>  			unsigned int bits,
>  			unsigned int __user *u_bits_r,
> -			int mode, const struct timespec *ts)
> +			int mode, const struct timespec64 *ts)
>  {
>  	unsigned int rbits = 0, testval;
>  	xnticks_t timeout = XN_INFINITE;
> @@ -193,14 +193,14 @@ COBALT_SYSCALL(event_wait, primary,
>  	       (struct cobalt_event_shadow __user *u_event,
>  		unsigned int bits,
>  		unsigned int __user *u_bits_r,
> -		int mode, const struct timespec __user *u_ts))
> +		int mode, const struct __user_old_timespec __user *u_ts))
>  {
> -	struct timespec ts, *tsp = NULL;
> +	struct timespec64 ts, *tsp = NULL;
>  	int ret;
>  
>  	if (u_ts) {
>  		tsp = &ts;
> -		ret = cobalt_copy_from_user(&ts, u_ts, sizeof(ts));
> +		ret = cobalt_get_u_timespec(&ts, u_ts);
>  		if (ret)
>  			return ret;
>  	}
> diff --git a/kernel/cobalt/posix/event.h b/kernel/cobalt/posix/event.h
> index 28d4516acf..ef592f72c0 100644
> --- a/kernel/cobalt/posix/event.h
> +++ b/kernel/cobalt/posix/event.h
> @@ -39,7 +39,7 @@ struct cobalt_event {
>  int __cobalt_event_wait(struct cobalt_event_shadow __user *u_event,
>  			unsigned int bits,
>  			unsigned int __user *u_bits_r,
> -			int mode, const struct timespec *ts);
> +			int mode, const struct timespec64 *ts);
>  
>  COBALT_SYSCALL_DECL(event_init,
>  		    (struct cobalt_event_shadow __user *u_evtsh,
> @@ -51,7 +51,7 @@ COBALT_SYSCALL_DECL(event_wait,
>  		     unsigned int bits,
>  		     unsigned int __user *u_bits_r,
>  		     int mode,
> -		     const struct timespec __user *u_ts));
> +		     const struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL_DECL(event_sync,
>  		    (struct cobalt_event_shadow __user *u_evtsh));
> diff --git a/kernel/cobalt/posix/io.c b/kernel/cobalt/posix/io.c
> index e9908feeb4..97a1f6afcd 100644
> --- a/kernel/cobalt/posix/io.c
> +++ b/kernel/cobalt/posix/io.c
> @@ -93,10 +93,10 @@ COBALT_SYSCALL(recvmsg, handover,
>  	return cobalt_copy_to_user(umsg, &m, sizeof(*umsg)) ?: ret;
>  }
>  
> -static int get_timespec(struct timespec *ts,
> +static int get_timespec(struct timespec64 *ts,
>  			const void __user *u_ts)
>  {
> -	return cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
> +	return cobalt_get_u_timespec(ts, u_ts);
>  }
>  
>  static int get_mmsg(struct mmsghdr *mmsg, void __user *u_mmsg)
> @@ -114,7 +114,7 @@ static int put_mmsg(void __user **u_mmsg_p, const struct mmsghdr *mmsg)
>  
>  COBALT_SYSCALL(recvmmsg, primary,
>  	       (int fd, struct mmsghdr __user *u_msgvec, unsigned int vlen,
> -		unsigned int flags, struct timespec *u_timeout))
> +		unsigned int flags, struct __user_old_timespec __user *u_timeout))
>  {
>  	return __rtdm_fd_recvmmsg(fd, u_msgvec, vlen, flags, u_timeout,
>  				  get_mmsg, put_mmsg, get_timespec);
> diff --git a/kernel/cobalt/posix/io.h b/kernel/cobalt/posix/io.h
> index 82187cc7ba..e4f7d4d51f 100644
> --- a/kernel/cobalt/posix/io.h
> +++ b/kernel/cobalt/posix/io.h
> @@ -53,7 +53,7 @@ COBALT_SYSCALL_DECL(recvmsg,
>  
>  COBALT_SYSCALL_DECL(recvmmsg,
>  		    (int fd, struct mmsghdr __user *u_msgvec, unsigned int vlen,
> -		     unsigned int flags, struct timespec *u_timeout));
> +		     unsigned int flags, struct __user_old_timespec __user *u_timeout));
>  
>  COBALT_SYSCALL_DECL(sendmsg,
>  		    (int fd, struct user_msghdr __user *umsg, int flags));
> diff --git a/kernel/cobalt/posix/monitor.c b/kernel/cobalt/posix/monitor.c
> index 5237545bec..b907e0050a 100644
> --- a/kernel/cobalt/posix/monitor.c
> +++ b/kernel/cobalt/posix/monitor.c
> @@ -203,7 +203,7 @@ drain:
>  }
>  
>  int __cobalt_monitor_wait(struct cobalt_monitor_shadow __user *u_mon,
> -			  int event, const struct timespec *ts,
> +			  int event, const struct timespec64 *ts,
>  			  int __user *u_ret)
>  {
>  	struct cobalt_thread *curr = cobalt_current_thread();
> @@ -291,15 +291,15 @@ out:
>  
>  COBALT_SYSCALL(monitor_wait, nonrestartable,
>  	       (struct cobalt_monitor_shadow __user *u_mon,
> -	       int event, const struct timespec __user *u_ts,
> +	       int event, const struct __user_old_timespec __user *u_ts,
>  	       int __user *u_ret))
>  {
> -	struct timespec ts, *tsp = NULL;
> +	struct timespec64 ts, *tsp = NULL;
>  	int ret;
>  
>  	if (u_ts) {
>  		tsp = &ts;
> -		ret = cobalt_copy_from_user(&ts, u_ts, sizeof(ts));
> +		ret = cobalt_get_u_timespec(&ts, u_ts);
>  		if (ret)
>  			return ret;
>  	}
> diff --git a/kernel/cobalt/posix/monitor.h b/kernel/cobalt/posix/monitor.h
> index 8b321aaec6..d4a4aa24e5 100644
> --- a/kernel/cobalt/posix/monitor.h
> +++ b/kernel/cobalt/posix/monitor.h
> @@ -39,7 +39,7 @@ struct cobalt_monitor {
>  };
>  
>  int __cobalt_monitor_wait(struct cobalt_monitor_shadow __user *u_mon,
> -			  int event, const struct timespec *ts,
> +			  int event, const struct timespec64 *ts,
>  			  int __user *u_ret);
>  
>  COBALT_SYSCALL_DECL(monitor_init,
> @@ -58,7 +58,7 @@ COBALT_SYSCALL_DECL(monitor_exit,
>  
>  COBALT_SYSCALL_DECL(monitor_wait,
>  		    (struct cobalt_monitor_shadow __user *u_monsh,
> -		     int event, const struct timespec __user *u_ts,
> +		     int event, const struct __user_old_timespec __user *u_ts,
>  		     int __user *u_ret));
>  
>  COBALT_SYSCALL_DECL(monitor_destroy,
> diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
> index b58d111db8..dd8acd55b0 100644
> --- a/kernel/cobalt/posix/mqueue.c
> +++ b/kernel/cobalt/posix/mqueue.c
> @@ -471,13 +471,13 @@ mq_tryrcv(struct cobalt_mqd *mqd, size_t len)
>  static struct cobalt_msg *
>  mq_timedsend_inner(struct cobalt_mqd *mqd,
>  		   size_t len, const void __user *u_ts,
> -		   int (*fetch_timeout)(struct timespec *ts,
> +		   int (*fetch_timeout)(struct timespec64 *ts,
>  					const void __user *u_ts))
>  {
>  	struct cobalt_mqwait_context mwc;
>  	struct cobalt_msg *msg;
>  	struct cobalt_mq *mq;
> -	struct timespec ts;
> +	struct timespec64 ts;
>  	xntmode_t tmode;
>  	xnticks_t to;
>  	spl_t s;
> @@ -600,13 +600,13 @@ static struct cobalt_msg *
>  mq_timedrcv_inner(struct cobalt_mqd *mqd,
>  		  size_t len,
>  		  const void __user *u_ts,
> -		  int (*fetch_timeout)(struct timespec *ts,
> +		  int (*fetch_timeout)(struct timespec64 *ts,
>  				       const void __user *u_ts))
>  {
>  	struct cobalt_mqwait_context mwc;
>  	struct cobalt_msg *msg;
>  	struct cobalt_mq *mq;
> -	struct timespec ts;
> +	struct timespec64 ts;
>  	xntmode_t tmode;
>  	xnticks_t to;
>  	spl_t s;
> @@ -883,16 +883,15 @@ COBALT_SYSCALL(mq_getattr, current,
>  	return cobalt_copy_to_user(u_attr, &attr, sizeof(attr));
>  }
>  
> -static inline int mq_fetch_timeout(struct timespec *ts,
> +static inline int mq_fetch_timeout(struct timespec64 *ts,
>  				   const void __user *u_ts)
>  {
> -	return u_ts == NULL ? -EFAULT :
> -		cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
> +	return u_ts == NULL ? -EFAULT : cobalt_get_u_timespec(ts, u_ts);
>  }
>  
>  int __cobalt_mq_timedsend(mqd_t uqd, const void __user *u_buf, size_t len,
>  			  unsigned int prio, const void __user *u_ts,
> -			  int (*fetch_timeout)(struct timespec *ts,
> +			  int (*fetch_timeout)(struct timespec64 *ts,
>  					       const void __user *u_ts))
>  {
>  	struct cobalt_msg *msg;
> @@ -936,7 +935,7 @@ out:
>  
>  COBALT_SYSCALL(mq_timedsend, primary,
>  	       (mqd_t uqd, const void __user *u_buf, size_t len,
> -		unsigned int prio, const struct timespec __user *u_ts))
> +		unsigned int prio, const struct __user_old_timespec __user *u_ts))
>  {
>  	return __cobalt_mq_timedsend(uqd, u_buf, len, prio,
>  				     u_ts, u_ts ? mq_fetch_timeout : NULL);
> @@ -946,7 +945,7 @@ int __cobalt_mq_timedreceive(mqd_t uqd, void __user *u_buf,
>  			     ssize_t *lenp,
>  			     unsigned int __user *u_prio,
>  			     const void __user *u_ts,
> -			     int (*fetch_timeout)(struct timespec *ts,
> +			     int (*fetch_timeout)(struct timespec64 *ts,
>  						  const void __user *u_ts))
>  {
>  	struct cobalt_mqd *mqd;
> @@ -997,7 +996,7 @@ COBALT_SYSCALL(mq_timedreceive, primary,
>  	       (mqd_t uqd, void __user *u_buf,
>  		ssize_t __user *u_len,
>  		unsigned int __user *u_prio,
> -		const struct timespec __user *u_ts))
> +		const struct __user_old_timespec __user *u_ts))
>  {
>  	ssize_t len;
>  	int ret;
> diff --git a/kernel/cobalt/posix/mqueue.h b/kernel/cobalt/posix/mqueue.h
> index acae2a4247..d33220227e 100644
> --- a/kernel/cobalt/posix/mqueue.h
> +++ b/kernel/cobalt/posix/mqueue.h
> @@ -37,14 +37,14 @@ int __cobalt_mq_getattr(mqd_t uqd, struct mq_attr *attr);
>  
>  int __cobalt_mq_timedsend(mqd_t uqd, const void __user *u_buf, size_t len,
>  			  unsigned int prio, const void __user *u_ts,
> -			  int (*fetch_timeout)(struct timespec *ts,
> +			  int (*fetch_timeout)(struct timespec64 *ts,
>  					       const void __user *u_ts));
>  
>  int __cobalt_mq_timedreceive(mqd_t uqd, void __user *u_buf,
>  			     ssize_t *lenp,
>  			     unsigned int __user *u_prio,
>  			     const void __user *u_ts,
> -			     int (*fetch_timeout)(struct timespec *ts,
> +			     int (*fetch_timeout)(struct timespec64 *ts,
>  						  const void __user *u_ts));
>  
>  int __cobalt_mq_notify(mqd_t fd, const struct sigevent *evp);
> @@ -61,12 +61,12 @@ COBALT_SYSCALL_DECL(mq_getattr, (mqd_t uqd, struct mq_attr __user *u_attr));
>  
>  COBALT_SYSCALL_DECL(mq_timedsend,
>  		    (mqd_t uqd, const void __user *u_buf, size_t len,
> -		     unsigned int prio, const struct timespec __user *u_ts));
> +		     unsigned int prio, const struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL_DECL(mq_timedreceive,
>  		    (mqd_t uqd, void __user *u_buf, ssize_t __user *u_len,
>  		     unsigned int __user *u_prio,
> -		     const struct timespec __user *u_ts));
> +		     const struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL_DECL(mq_notify,
>  		    (mqd_t fd, const struct sigevent *__user evp));
> diff --git a/kernel/cobalt/posix/mutex.c b/kernel/cobalt/posix/mutex.c
> index 79260b5448..70fe7960a0 100644
> --- a/kernel/cobalt/posix/mutex.c
> +++ b/kernel/cobalt/posix/mutex.c
> @@ -71,7 +71,7 @@ static int cobalt_mutex_init_inner(struct cobalt_mutex_shadow *shadow,
>  /* must be called with nklock locked, interrupts off. */
>  int __cobalt_mutex_acquire_unchecked(struct xnthread *cur,
>  				     struct cobalt_mutex *mutex,
> -				     const struct timespec *ts)
> +				     const struct timespec64 *ts)
>  {
>  	int ret;
>  
> @@ -134,11 +134,11 @@ int cobalt_mutex_release(struct xnthread *curr,
>  
>  int __cobalt_mutex_timedlock_break(struct cobalt_mutex_shadow __user *u_mx,
>  				   const void __user *u_ts,
> -				   int (*fetch_timeout)(struct timespec *ts,
> +				   int (*fetch_timeout)(struct timespec64 *ts,
>  							const void __user *u_ts))
>  {
>  	struct xnthread *curr = xnthread_current();
> -	struct timespec ts, *tsp = NULL;
> +	struct timespec64 ts, *tsp = NULL;
>  	struct cobalt_mutex *mutex;
>  	xnhandle_t handle;
>  	spl_t s;
> @@ -346,16 +346,15 @@ COBALT_SYSCALL(mutex_lock, primary,
>  	return __cobalt_mutex_timedlock_break(u_mx, NULL, NULL);
>  }
>  
> -static inline int mutex_fetch_timeout(struct timespec *ts,
> +static inline int mutex_fetch_timeout(struct timespec64 *ts,
>  				      const void __user *u_ts)
>  {
> -	return u_ts == NULL ? -EFAULT :
> -		cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
> +	return u_ts == NULL ? -EFAULT : cobalt_get_u_timespec(ts, u_ts);
>  }
>  
>  COBALT_SYSCALL(mutex_timedlock, primary,
>  	       (struct cobalt_mutex_shadow __user *u_mx,
> -		const struct timespec __user *u_ts))
> +		const struct __user_old_timespec __user *u_ts))
>  {
>  	return __cobalt_mutex_timedlock_break(u_mx, u_ts, mutex_fetch_timeout);
>  }
> diff --git a/kernel/cobalt/posix/mutex.h b/kernel/cobalt/posix/mutex.h
> index ac1c50291d..d76f2a9ead 100644
> --- a/kernel/cobalt/posix/mutex.h
> +++ b/kernel/cobalt/posix/mutex.h
> @@ -37,12 +37,12 @@ struct cobalt_mutex {
>  
>  int __cobalt_mutex_timedlock_break(struct cobalt_mutex_shadow __user *u_mx,
>  				   const void __user *u_ts,
> -				   int (*fetch_timeout)(struct timespec *ts,
> +				   int (*fetch_timeout)(struct timespec64 *ts,
>  							const void __user *u_ts));
>  
>  int __cobalt_mutex_acquire_unchecked(struct xnthread *cur,
>  				     struct cobalt_mutex *mutex,
> -				     const struct timespec *ts);
> +				     const struct timespec64 *ts);
>  
>  COBALT_SYSCALL_DECL(mutex_check_init,
>  		    (struct cobalt_mutex_shadow __user *u_mx));
> @@ -62,7 +62,7 @@ COBALT_SYSCALL_DECL(mutex_lock,
>  
>  COBALT_SYSCALL_DECL(mutex_timedlock,
>  		    (struct cobalt_mutex_shadow __user *u_mx,
> -		     const struct timespec __user *u_ts));
> +		     const struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL_DECL(mutex_unlock,
>  		    (struct cobalt_mutex_shadow __user *u_mx));
> diff --git a/kernel/cobalt/posix/sched.c b/kernel/cobalt/posix/sched.c
> index 798a172d7f..4fd9c2b46e 100644
> --- a/kernel/cobalt/posix/sched.c
> +++ b/kernel/cobalt/posix/sched.c
> @@ -73,7 +73,7 @@ cobalt_sched_policy_param(union xnsched_policy_param *param,
>  		break;
>  	case SCHED_RR:
>  		/* if unspecified, use current one. */
> -		tslice = ts2ns(&param_ex->sched_rr_quantum);
> +		tslice = u_ts2ns(&param_ex->sched_rr_quantum);
>  		if (tslice == XN_INFINITE && tslice_r)
>  			tslice = *tslice_r;
>  		/* fallthrough */
> @@ -92,8 +92,8 @@ cobalt_sched_policy_param(union xnsched_policy_param *param,
>  		param->pss.normal_prio = param_ex->sched_priority;
>  		param->pss.low_prio = param_ex->sched_ss_low_priority;
>  		param->pss.current_prio = param->pss.normal_prio;
> -		param->pss.init_budget = ts2ns(&param_ex->sched_ss_init_budget);
> -		param->pss.repl_period = ts2ns(&param_ex->sched_ss_repl_period);
> +		param->pss.init_budget = u_ts2ns(&param_ex->sched_ss_init_budget);
> +		param->pss.repl_period = u_ts2ns(&param_ex->sched_ss_repl_period);
>  		param->pss.max_repl = param_ex->sched_ss_max_repl;
>  		sched_class = &xnsched_class_sporadic;
>  		break;
> @@ -280,11 +280,11 @@ int set_tp_config(int cpu, union sched_config *config, size_t len)
>  		 * be defined using windows assigned to the pseudo
>  		 * partition #-1.
>  		 */
> -		offset = ts2ns(&p->offset);
> +		offset = u_ts2ns(&p->offset);
>  		if (offset != next_offset)
>  			goto cleanup_and_fail;
>  
> -		duration = ts2ns(&p->duration);
> +		duration = u_ts2ns(&p->duration);
>  		if (duration <= 0)
>  			goto cleanup_and_fail;
>  
> @@ -357,11 +357,11 @@ ssize_t get_tp_config(int cpu, void __user *u_config, size_t len,
>  	config->tp.nr_windows = gps->pwin_nr;
>  	for (n = 0, pp = p = config->tp.windows, pw = w = gps->pwins;
>  	     n < gps->pwin_nr; pp = p, p++, pw = w, w++, n++) {
> -		ns2ts(&p->offset, w->w_offset);
> -		ns2ts(&pp->duration, w->w_offset - pw->w_offset);
> +		u_ns2ts(&p->offset, w->w_offset);
> +		u_ns2ts(&pp->duration, w->w_offset - pw->w_offset);
>  		p->ptid = w->w_part;
>  	}
> -	ns2ts(&pp->duration, gps->tf_duration - pw->w_offset);
> +	u_ns2ts(&pp->duration, gps->tf_duration - pw->w_offset);
>  	ret = put_config(SCHED_TP, u_config, len, config, elen);
>  	xnfree(config);
>  out:
> diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
> index 05a861dfe3..467a9b7dd6 100644
> --- a/kernel/cobalt/posix/sem.c
> +++ b/kernel/cobalt/posix/sem.c
> @@ -267,7 +267,7 @@ out:
>  	return ret;
>  }
>  
> -static inline int sem_fetch_timeout(struct timespec *ts,
> +static inline int sem_fetch_timeout(struct timespec64 *ts,
>  				    const void __user *u_ts)
>  {
>  	return u_ts == NULL ? -EFAULT :
> @@ -276,10 +276,10 @@ static inline int sem_fetch_timeout(struct timespec *ts,
>  
>  int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user *u_sem,
>  			   const void __user *u_ts,
> -			   int (*fetch_timeout)(struct timespec *ts,
> +			   int (*fetch_timeout)(struct timespec64 *ts,
>  						const void __user *u_ts))
>  {
> -	struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
> +	struct timespec64 ts = { .tv_sec = 0, .tv_nsec = 0 };
>  	int pull_ts = 1, ret, info;
>  	struct cobalt_sem *sem;
>  	xnhandle_t handle;
> @@ -434,7 +434,7 @@ COBALT_SYSCALL(sem_wait, primary,
>  
>  COBALT_SYSCALL(sem_timedwait, primary,
>  	       (struct cobalt_sem_shadow __user *u_sem,
> -		struct timespec __user *u_ts))
> +		struct __user_old_timespec __user *u_ts))
>  {
>  	return __cobalt_sem_timedwait(u_sem, u_ts, sem_fetch_timeout);
>  }
> diff --git a/kernel/cobalt/posix/sem.h b/kernel/cobalt/posix/sem.h
> index 17238078e5..d172994950 100644
> --- a/kernel/cobalt/posix/sem.h
> +++ b/kernel/cobalt/posix/sem.h
> @@ -65,7 +65,7 @@ __cobalt_sem_open(struct cobalt_sem_shadow __user *usm,
>  
>  int __cobalt_sem_timedwait(struct cobalt_sem_shadow __user *u_sem,
>  			   const void __user *u_ts,
> -			   int (*fetch_timeout)(struct timespec *ts,
> +			   int (*fetch_timeout)(struct timespec64 *ts,
>  						const void __user *u_ts));
>  
>  int __cobalt_sem_destroy(xnhandle_t handle);
> @@ -91,7 +91,7 @@ COBALT_SYSCALL_DECL(sem_wait,
>  
>  COBALT_SYSCALL_DECL(sem_timedwait,
>  		    (struct cobalt_sem_shadow __user *u_sem,
> -		     struct timespec __user *u_ts));
> +		     struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL_DECL(sem_trywait,
>  		    (struct cobalt_sem_shadow __user *u_sem));
> diff --git a/kernel/cobalt/posix/signal.c b/kernel/cobalt/posix/signal.c
> index 862a644c0b..0b43b5fcfa 100644
> --- a/kernel/cobalt/posix/signal.c
> +++ b/kernel/cobalt/posix/signal.c
> @@ -407,7 +407,7 @@ COBALT_SYSCALL(sigwait, primary,
>  }
>  
>  int __cobalt_sigtimedwait(sigset_t *set,
> -			  const struct timespec *timeout,
> +			  const struct timespec64 *timeout,
>  			  void __user *u_si,
>  			  bool compat)
>  {
> @@ -426,9 +426,9 @@ int __cobalt_sigtimedwait(sigset_t *set,
>  COBALT_SYSCALL(sigtimedwait, nonrestartable,
>  	       (const sigset_t __user *u_set,
>  		struct siginfo __user *u_si,
> -		const struct timespec __user *u_timeout))
> +		const struct __user_old_timespec __user *u_timeout))
>  {
> -	struct timespec timeout;
> +	struct timespec64 timeout;
>  	sigset_t set;
>  
>  	if (cobalt_copy_from_user(&set, u_set, sizeof(set)))
> diff --git a/kernel/cobalt/posix/signal.h b/kernel/cobalt/posix/signal.h
> index 7a0b4b22b8..fc26ad0653 100644
> --- a/kernel/cobalt/posix/signal.h
> +++ b/kernel/cobalt/posix/signal.h
> @@ -59,7 +59,7 @@ void cobalt_copy_siginfo(int code,
>  int __cobalt_sigwait(sigset_t *set);
>  
>  int __cobalt_sigtimedwait(sigset_t *set,
> -			  const struct timespec *timeout,
> +			  const struct timespec64 *timeout,
>  			  void __user *u_si,
>  			  bool compat);
>  
> @@ -94,7 +94,7 @@ COBALT_SYSCALL_DECL(sigwait,
>  COBALT_SYSCALL_DECL(sigtimedwait,
>  		    (const sigset_t __user *u_set,
>  		     struct siginfo __user *u_si,
> -		     const struct timespec __user *u_timeout));
> +		     const struct __user_old_timespec __user *u_timeout));
>  
>  COBALT_SYSCALL_DECL(sigwaitinfo,
>  		    (const sigset_t __user *u_set,
> diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
> index cb02dacd3d..ae25a6e743 100644
> --- a/kernel/cobalt/posix/syscall32.c
> +++ b/kernel/cobalt/posix/syscall32.c
> @@ -97,7 +97,7 @@ COBALT_SYSCALL32emu(thread_setschedprio, conforming,
>  	return cobalt_thread_setschedprio(pth, prio, u_winoff, u_promoted);
>  }
>  
> -static inline int sys32_fetch_timeout(struct timespec *ts,
> +static inline int sys32_fetch_timeout(struct timespec64 *ts,
>  				      const void __user *u_ts)
>  {
>  	return u_ts == NULL ? -EFAULT :
> @@ -133,7 +133,7 @@ COBALT_SYSCALL32emu(clock_getres, current,
>  		    (clockid_t clock_id,
>  		     struct compat_timespec __user *u_ts))
>  {
> -	struct timespec ts;
> +	struct timespec64 ts;
>  	int ret;
>  
>  	ret = __cobalt_clock_getres(clock_id, &ts);
> @@ -147,7 +147,7 @@ COBALT_SYSCALL32emu(clock_gettime, current,
>  		    (clockid_t clock_id,
>  		     struct compat_timespec __user *u_ts))
>  {
> -	struct timespec ts;
> +	struct timespec64 ts;
>  	int ret;
>  
>  	ret = __cobalt_clock_gettime(clock_id, &ts);
> @@ -161,7 +161,7 @@ COBALT_SYSCALL32emu(clock_settime, current,
>  		    (clockid_t clock_id,
>  		     const struct compat_timespec __user *u_ts))
>  {
> -	struct timespec ts;
> +	struct timespec64 ts;
>  	int ret;
>  
>  	ret = sys32_get_timespec(&ts, u_ts);
> @@ -193,7 +193,7 @@ COBALT_SYSCALL32emu(clock_nanosleep, nonrestartable,
>  		     const struct compat_timespec __user *u_rqt,
>  		     struct compat_timespec __user *u_rmt))
>  {
> -	struct timespec rqt, rmt, *rmtp = NULL;
> +	struct timespec64 rqt, rmt, *rmtp = NULL;
>  	int ret;
>  
>  	if (u_rmt)
> @@ -289,12 +289,10 @@ COBALT_SYSCALL32emu(mq_timedreceive, primary,
>  	return ret ?: cobalt_copy_to_user(u_len, &clen, sizeof(*u_len));
>  }
>  
> -static inline int mq_fetch_timeout(struct timespec *ts,
> +static inline int mq_fetch_timeout(struct timespec64 *ts,
>  				   const void __user *u_ts)
>  {
> -	return u_ts == NULL ? -EFAULT :
> -		cobalt_copy_from_user(ts, u_ts, sizeof(*ts));
> -
> +	return u_ts == NULL ? -EFAULT : cobalt_get_u_timespec(ts, u_ts);
>  }
>  
>  COBALT_SYSCALL32emu(mq_notify, primary,
> @@ -610,7 +608,7 @@ COBALT_SYSCALL32emu(sigtimedwait, nonrestartable,
>  		     struct compat_siginfo __user *u_si,
>  		     const struct compat_timespec __user *u_timeout))
>  {
> -	struct timespec timeout;
> +	struct timespec64 timeout;
>  	sigset_t set;
>  	int ret;
>  
> @@ -663,7 +661,7 @@ COBALT_SYSCALL32emu(monitor_wait, nonrestartable,
>  		     int event, const struct compat_timespec __user *u_ts,
>  		     int __user *u_ret))
>  {
> -	struct timespec ts, *tsp = NULL;
> +	struct timespec64 ts, *tsp = NULL;
>  	int ret;
>  
>  	if (u_ts) {
> @@ -682,7 +680,7 @@ COBALT_SYSCALL32emu(event_wait, primary,
>  		     unsigned int __user *u_bits_r,
>  		     int mode, const struct compat_timespec __user *u_ts))
>  {
> -	struct timespec ts, *tsp = NULL;
> +	struct timespec64 ts, *tsp = NULL;
>  	int ret;
>  
>  	if (u_ts) {
> @@ -810,7 +808,7 @@ COBALT_SYSCALL32emu(recvmsg, handover,
>  	return sys32_put_msghdr(umsg, &m) ?: ret;
>  }
>  
> -static int get_timespec32(struct timespec *ts,
> +static int get_timespec32(struct timespec64 *ts,
>  			  const void __user *u_ts)
>  {
>  	return sys32_get_timespec(ts, u_ts);
> @@ -924,7 +922,7 @@ COBALT_SYSCALL32x(mq_timedreceive, primary,
>  		  (mqd_t uqd, void __user *u_buf,
>  		   compat_ssize_t __user *u_len,
>  		   unsigned int __user *u_prio,
> -		   const struct timespec __user *u_ts))
> +		   const struct __user_old_timespec __user *u_ts))
>  {
>  	compat_ssize_t clen;
>  	ssize_t len;
> diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
> index eb3e4bd300..9da4052297 100644
> --- a/kernel/cobalt/posix/syscall32.h
> +++ b/kernel/cobalt/posix/syscall32.h
> @@ -105,7 +105,7 @@ COBALT_SYSCALL32x_DECL(mq_timedreceive,
>  		       (mqd_t uqd, void __user *u_buf,
>  			compat_ssize_t __user *u_len,
>  			unsigned int __user *u_prio,
> -			const struct timespec __user *u_ts));
> +			const struct __user_old_timespec __user *u_ts));
>  
>  COBALT_SYSCALL32emu_DECL(mq_notify,
>  			 (mqd_t fd, const struct compat_sigevent *__user u_cev));
> diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c
> index bf9c082123..cdeb66d4f3 100644
> --- a/kernel/cobalt/posix/thread.c
> +++ b/kernel/cobalt/posix/thread.c
> @@ -302,7 +302,7 @@ int __cobalt_thread_getschedparam_ex(struct cobalt_thread *thread,
>  
>  	if (base_class == &xnsched_class_rt) {
>  		if (xnthread_test_state(base_thread, XNRRB)) {
> -			ns2ts(&param_ex->sched_rr_quantum, base_thread->rrperiod);
> +			u_ns2ts(&param_ex->sched_rr_quantum, base_thread->rrperiod);
>  			*policy_r = SCHED_RR;
>  		}
>  		goto out;
> @@ -318,8 +318,8 @@ int __cobalt_thread_getschedparam_ex(struct cobalt_thread *thread,
>  #ifdef CONFIG_XENO_OPT_SCHED_SPORADIC
>  	if (base_class == &xnsched_class_sporadic) {
>  		param_ex->sched_ss_low_priority = base_thread->pss->param.low_prio;
> -		ns2ts(&param_ex->sched_ss_repl_period, base_thread->pss->param.repl_period);
> -		ns2ts(&param_ex->sched_ss_init_budget, base_thread->pss->param.init_budget);
> +		u_ns2ts(&param_ex->sched_ss_repl_period, base_thread->pss->param.repl_period);
> +		u_ns2ts(&param_ex->sched_ss_init_budget, base_thread->pss->param.init_budget);
>  		param_ex->sched_ss_max_repl = base_thread->pss->param.max_repl;
>  		goto out;
>  	}
> diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
> index 7956a88008..038247d54f 100644
> --- a/kernel/cobalt/rtdm/fd.c
> +++ b/kernel/cobalt/rtdm/fd.c
> @@ -650,11 +650,11 @@ int __rtdm_fd_recvmmsg(int ufd, void __user *u_msgvec, unsigned int vlen,
>  		       unsigned int flags, void __user *u_timeout,
>  		       int (*get_mmsg)(struct mmsghdr *mmsg, void __user *u_mmsg),
>  		       int (*put_mmsg)(void __user **u_mmsg_p, const struct mmsghdr *mmsg),
> -		       int (*get_timespec)(struct timespec *ts, const void __user *u_ts))
> +		       int (*get_timespec)(struct timespec64 *ts, const void __user *u_ts))
>  {
>  	struct cobalt_recvmmsg_timer rq;
>  	xntmode_t tmode = XN_RELATIVE;
> -	struct timespec ts = { 0 };
> +	struct timespec64 ts = { 0 };
>  	int ret = 0, datagrams = 0;
>  	xnticks_t timeout = 0;
>  	struct mmsghdr mmsg;
> diff --git a/kernel/cobalt/trace/cobalt-posix.h b/kernel/cobalt/trace/cobalt-posix.h
> index aa78efbc01..3a649a6712 100644
> --- a/kernel/cobalt/trace/cobalt-posix.h
> +++ b/kernel/cobalt/trace/cobalt-posix.h
> @@ -30,7 +30,7 @@
>  #include <xenomai/posix/event.h>
>  
>  #define __timespec_fields(__name)				\
> -	__field(__kernel_time_t, tv_sec_##__name)		\
> +	__field(time64_t, tv_sec_##__name)			\
>  	__field(long, tv_nsec_##__name)
>  
>  #define __assign_timespec(__to, __from)				\
> @@ -40,7 +40,7 @@
>  	} while (0)
>  
>  #define __timespec_args(__name)					\
> -	__entry->tv_sec_##__name, __entry->tv_nsec_##__name
> +	(long long)__entry->tv_sec_##__name, __entry->tv_nsec_##__name
>  
>  #ifdef CONFIG_X86_X32
>  #define __sc_x32(__name)	, { sc_cobalt_##__name + __COBALT_X32_BASE, "x32-" #__name }
> @@ -729,7 +729,7 @@ TRACE_EVENT(cobalt_psem_unlink,
>  );
>  
>  DECLARE_EVENT_CLASS(cobalt_clock_timespec,
> -	TP_PROTO(clockid_t clk_id, const struct timespec *val),
> +	TP_PROTO(clockid_t clk_id, const struct timespec64 *val),
>  	TP_ARGS(clk_id, val),
>  
>  	TP_STRUCT__entry(
> @@ -742,24 +742,24 @@ DECLARE_EVENT_CLASS(cobalt_clock_timespec,
>  		__assign_timespec(val, val);
>  	),
>  
> -	TP_printk("clock_id=%d timeval=(%ld.%09ld)",
> +	TP_printk("clock_id=%d timeval=(%lld.%09ld)",
>  		  __entry->clk_id,
>  		  __timespec_args(val)
>  	)
>  );
>  
>  DEFINE_EVENT(cobalt_clock_timespec, cobalt_clock_getres,
> -	TP_PROTO(clockid_t clk_id, const struct timespec *res),
> +	TP_PROTO(clockid_t clk_id, const struct timespec64 *res),
>  	TP_ARGS(clk_id, res)
>  );
>  
>  DEFINE_EVENT(cobalt_clock_timespec, cobalt_clock_gettime,
> -	TP_PROTO(clockid_t clk_id, const struct timespec *time),
> +	TP_PROTO(clockid_t clk_id, const struct timespec64 *time),
>  	TP_ARGS(clk_id, time)
>  );
>  
>  DEFINE_EVENT(cobalt_clock_timespec, cobalt_clock_settime,
> -	TP_PROTO(clockid_t clk_id, const struct timespec *time),
> +	TP_PROTO(clockid_t clk_id, const struct timespec64 *time),
>  	TP_ARGS(clk_id, time)
>  );
>  
> @@ -788,7 +788,7 @@ TRACE_EVENT(cobalt_clock_adjtime,
>  		      {TIMER_ABSTIME, "TIMER_ABSTIME"})
>  
>  TRACE_EVENT(cobalt_clock_nanosleep,
> -	TP_PROTO(clockid_t clk_id, int flags, const struct timespec *time),
> +	TP_PROTO(clockid_t clk_id, int flags, const struct timespec64 *time),
>  	TP_ARGS(clk_id, flags, time),
>  
>  	TP_STRUCT__entry(
> @@ -803,7 +803,7 @@ TRACE_EVENT(cobalt_clock_nanosleep,
>  		__assign_timespec(time, time);
>  	),
>  
> -	TP_printk("clock_id=%d flags=%#x(%s) rqt=(%ld.%09ld)",
> +	TP_printk("clock_id=%d flags=%#x(%s) rqt=(%lld.%09ld)",
>  		  __entry->clk_id,
>  		  __entry->flags, cobalt_print_timer_flags(__entry->flags),
>  		  __timespec_args(time)
> @@ -875,7 +875,7 @@ TRACE_EVENT(cobalt_cond_destroy,
>  TRACE_EVENT(cobalt_cond_timedwait,
>  	TP_PROTO(const struct cobalt_cond_shadow __user *u_cnd,
>  		 const struct cobalt_mutex_shadow __user *u_mx,
> -		 const struct timespec *timeout),
> +		 const struct timespec64 *timeout),
>  	TP_ARGS(u_cnd, u_mx, timeout),
>  	TP_STRUCT__entry(
>  		__field(const struct cobalt_cond_shadow __user *, u_cnd)
> @@ -887,7 +887,7 @@ TRACE_EVENT(cobalt_cond_timedwait,
>  		__entry->u_mx = u_mx;
>  		__assign_timespec(timeout, timeout);
>  	),
> -	TP_printk("cond=%p, mutex=%p, timeout=(%ld.%09ld)",
> +	TP_printk("cond=%p, mutex=%p, timeout=(%lld.%09ld)",
>  		  __entry->u_cnd, __entry->u_mx, __timespec_args(timeout))
>  );
>  
> @@ -1001,7 +1001,7 @@ TRACE_EVENT(cobalt_mq_send,
>  
>  TRACE_EVENT(cobalt_mq_timedreceive,
>  	TP_PROTO(mqd_t mqd, const void __user *u_buf, size_t len,
> -		 const struct timespec *timeout),
> +		 const struct timespec64 *timeout),
>  	TP_ARGS(mqd, u_buf, len, timeout),
>  	TP_STRUCT__entry(
>  		__field(mqd_t, mqd)
> @@ -1015,7 +1015,7 @@ TRACE_EVENT(cobalt_mq_timedreceive,
>  		__entry->len = len;
>  		__assign_timespec(timeout, timeout);
>  	),
> -	TP_printk("mqd=%d buf=%p len=%zu timeout=(%ld.%09ld)",
> +	TP_printk("mqd=%d buf=%p len=%zu timeout=(%lld.%09ld)",
>  		  __entry->mqd, __entry->u_buf, __entry->len,
>  		  __timespec_args(timeout))
>  );
> @@ -1105,7 +1105,7 @@ TRACE_EVENT(cobalt_event_init,
>  TRACE_EVENT(cobalt_event_timedwait,
>  	TP_PROTO(const struct cobalt_event_shadow __user *u_event,
>  		 unsigned long bits, int mode,
> -		 const struct timespec *timeout),
> +		 const struct timespec64 *timeout),
>  	TP_ARGS(u_event, bits, mode, timeout),
>  	TP_STRUCT__entry(
>  		__field(const struct cobalt_event_shadow __user *, u_event)
> @@ -1119,7 +1119,7 @@ TRACE_EVENT(cobalt_event_timedwait,
>  		__entry->mode = mode;
>  		__assign_timespec(timeout, timeout);
>  	),
> -	TP_printk("event=%p bits=%#lx mode=%#x(%s) timeout=(%ld.%09ld)",
> +	TP_printk("event=%p bits=%#lx mode=%#x(%s) timeout=(%lld.%09ld)",
>  		  __entry->u_event, __entry->bits, __entry->mode,
>  		  cobalt_print_evmode(__entry->mode),
>  		  __timespec_args(timeout))
> 


-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 1/9] cobalt/kernel: y2038: convert struct timespec to timespec64
  2021-05-07  6:09   ` Florian Bezdeka
@ 2021-05-07  6:54     ` Philippe Gerum
  0 siblings, 0 replies; 22+ messages in thread
From: Philippe Gerum @ 2021-05-07  6:54 UTC (permalink / raw)
  To: Florian Bezdeka; +Cc: Jan Kiszka, xenomai


Florian Bezdeka <florian.bezdeka@siemens.com> writes:

> On 05.05.21 18:53, Jan Kiszka via Xenomai wrote:
>> From: Philippe Gerum <rpm@xenomai.org>
>> 
>> As internal interfaces are gradually being made y2038-safe, the
>> timespec64 type should be used internally by the kernel to represent
>> time values. Apply the same reasoning to Cobalt.
>> 
>> We still use a legacy y2038-unsafe timespec type at the kernel<->user
>> interface boundary (struct __user_old_timespec) until libcobalt is
>> y2038-safe.
>> 
>> Signed-off-by: Philippe Gerum <rpm@xenomai.org>
>> [Florian: Fix regression in 32bit mode]
>> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>  include/cobalt/kernel/clock.h                 |  6 +-
>>  include/cobalt/kernel/compat.h                |  4 +-
>>  .../cobalt/kernel/dovetail/pipeline/clock.h   |  4 +-
>>  include/cobalt/kernel/ipipe/pipeline/clock.h  |  4 +-
>>  include/cobalt/kernel/rtdm/fd.h               |  2 +-
>>  include/cobalt/uapi/kernel/types.h            | 10 ++++
>>  include/cobalt/uapi/sched.h                   | 12 ++--
>>  .../include/asm-generic/xenomai/syscall.h     | 58 +++++++++++++++++++
>>  kernel/cobalt/ipipe/clock.c                   |  2 +-
>>  kernel/cobalt/posix/clock.c                   | 38 ++++++------
>>  kernel/cobalt/posix/clock.h                   | 39 +++++++++----
>>  kernel/cobalt/posix/compat.c                  | 46 ++++++++++-----
>>  kernel/cobalt/posix/cond.c                    | 11 ++--
>>  kernel/cobalt/posix/cond.h                    |  4 +-
>>  kernel/cobalt/posix/event.c                   |  8 +--
>>  kernel/cobalt/posix/event.h                   |  4 +-
>>  kernel/cobalt/posix/io.c                      |  6 +-
>>  kernel/cobalt/posix/io.h                      |  2 +-
>>  kernel/cobalt/posix/monitor.c                 |  8 +--
>>  kernel/cobalt/posix/monitor.h                 |  4 +-
>>  kernel/cobalt/posix/mqueue.c                  | 21 ++++---
>>  kernel/cobalt/posix/mqueue.h                  |  8 +--
>>  kernel/cobalt/posix/mutex.c                   | 13 ++---
>>  kernel/cobalt/posix/mutex.h                   |  6 +-
>>  kernel/cobalt/posix/sched.c                   | 16 ++---
>>  kernel/cobalt/posix/sem.c                     |  8 +--
>>  kernel/cobalt/posix/sem.h                     |  4 +-
>>  kernel/cobalt/posix/signal.c                  |  6 +-
>>  kernel/cobalt/posix/signal.h                  |  4 +-
>>  kernel/cobalt/posix/syscall32.c               | 26 ++++-----
>>  kernel/cobalt/posix/syscall32.h               |  2 +-
>>  kernel/cobalt/posix/thread.c                  |  6 +-
>>  kernel/cobalt/rtdm/fd.c                       |  4 +-
>>  kernel/cobalt/trace/cobalt-posix.h            | 30 +++++-----
>>  34 files changed, 262 insertions(+), 164 deletions(-)
>> 
>> diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
>> index bbf34c53cf..1c99173ff8 100644
>> --- a/include/cobalt/kernel/clock.h
>> +++ b/include/cobalt/kernel/clock.h
>> @@ -54,7 +54,7 @@ struct xnclock {
>>  		xnticks_t (*read_raw)(struct xnclock *clock);
>>  		xnticks_t (*read_monotonic)(struct xnclock *clock);
>>  		int (*set_time)(struct xnclock *clock,
>> -				const struct timespec *ts);
>> +				const struct timespec64 *ts);
>>  		xnsticks_t (*ns_to_ticks)(struct xnclock *clock,
>>  					  xnsticks_t ns);
>>  		xnsticks_t (*ticks_to_ns)(struct xnclock *clock,
>> @@ -211,7 +211,7 @@ static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
>>  }
>>  
>>  static inline int xnclock_set_time(struct xnclock *clock,
>> -				   const struct timespec *ts)
>> +				   const struct timespec64 *ts)
>>  {
>>  	if (likely(clock == &nkclock))
>>  		return -EINVAL;
>> @@ -264,7 +264,7 @@ static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
>>  }
>>  
>>  static inline int xnclock_set_time(struct xnclock *clock,
>> -				   const struct timespec *ts)
>> +				   const struct timespec64 *ts)
>>  {
>>  	/*
>>  	 * There is no way to change the core clock's idea of time.
>> diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
>> index 313b6251b4..c57ef65325 100644
>> --- a/include/cobalt/kernel/compat.h
>> +++ b/include/cobalt/kernel/compat.h
>> @@ -86,11 +86,11 @@ struct compat_rtdm_mmap_request {
>>  	int flags;
>>  };
>>  
>> -int sys32_get_timespec(struct timespec *ts,
>> +int sys32_get_timespec(struct timespec64 *ts,
>>  		       const struct compat_timespec __user *cts);
>>  
>>  int sys32_put_timespec(struct compat_timespec __user *cts,
>> -		       const struct timespec *ts);
>> +		       const struct timespec64 *ts);
>>  
>>  int sys32_get_itimerspec(struct itimerspec *its,
>>  			 const struct compat_itimerspec __user *cits);
>> diff --git a/include/cobalt/kernel/dovetail/pipeline/clock.h b/include/cobalt/kernel/dovetail/pipeline/clock.h
>> index 933e100baf..19e3d89865 100644
>> --- a/include/cobalt/kernel/dovetail/pipeline/clock.h
>> +++ b/include/cobalt/kernel/dovetail/pipeline/clock.h
>> @@ -8,7 +8,7 @@
>>  #include <cobalt/uapi/kernel/types.h>
>>  #include <cobalt/kernel/assert.h>
>>  
>> -struct timespec;
>> +struct timespec64;
>>  
>>  static inline u64 pipeline_read_cycle_counter(void)
>>  {
>> @@ -49,7 +49,7 @@ static inline const char *pipeline_clock_name(void)
>>  	return "?";
>>  }
>>  
>> -static inline int pipeline_get_host_time(struct timespec *tp)
>> +static inline int pipeline_get_host_time(struct timespec64 *tp)
>>  {
>>  	/* Convert ktime_get_real_fast_ns() to timespec. */
>>  	TODO();
>> diff --git a/include/cobalt/kernel/ipipe/pipeline/clock.h b/include/cobalt/kernel/ipipe/pipeline/clock.h
>> index fa7ac2a5e0..d35aea17b1 100644
>> --- a/include/cobalt/kernel/ipipe/pipeline/clock.h
>> +++ b/include/cobalt/kernel/ipipe/pipeline/clock.h
>> @@ -7,7 +7,7 @@
>>  
>>  #include <linux/ipipe_tickdev.h>
>>  
>> -struct timespec;
>> +struct timespec64;
>>  
>>  static inline u64 pipeline_read_cycle_counter(void)
>>  {
>> @@ -31,7 +31,7 @@ static inline const char *pipeline_clock_name(void)
>>  	return ipipe_clock_name();
>>  }
>>  
>> -int pipeline_get_host_time(struct timespec *tp);
>> +int pipeline_get_host_time(struct timespec64 *tp);
>>  
>>  void pipeline_update_clock_freq(unsigned long long freq);
>>  
>> diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
>> index 289065082b..37a09c43e8 100644
>> --- a/include/cobalt/kernel/rtdm/fd.h
>> +++ b/include/cobalt/kernel/rtdm/fd.h
>> @@ -380,7 +380,7 @@ int __rtdm_fd_recvmmsg(int ufd, void __user *u_msgvec, unsigned int vlen,
>>  		       unsigned int flags, void __user *u_timeout,
>>  		       int (*get_mmsg)(struct mmsghdr *mmsg, void __user *u_mmsg),
>>  		       int (*put_mmsg)(void __user **u_mmsg_p, const struct mmsghdr *mmsg),
>> -		       int (*get_timespec)(struct timespec *ts, const void __user *u_ts));
>> +		       int (*get_timespec)(struct timespec64 *ts, const void __user *u_ts));
>>  
>>  ssize_t rtdm_fd_sendmsg(int ufd, const struct user_msghdr *msg,
>>  			int flags);
>> diff --git a/include/cobalt/uapi/kernel/types.h b/include/cobalt/uapi/kernel/types.h
>> index ee5bbadcae..8ce9b03df4 100644
>> --- a/include/cobalt/uapi/kernel/types.h
>> +++ b/include/cobalt/uapi/kernel/types.h
>> @@ -57,4 +57,14 @@ static inline xnhandle_t xnhandle_get_id(xnhandle_t handle)
>>  	return handle & ~XN_HANDLE_TRANSIENT_MASK;
>>  }
>>  
>> +/*
>> + * Our representation of time at the kernel<->user interface boundary
>> + * at the moment, until we have fully transitioned to a y2038-safe
>> + * implementation in libcobalt.
>> + */
>> +struct __user_old_timespec {
>> +	long  tv_sec;
>> +	long  tv_nsec;
>> +};
>> +
>>  #endif /* !_COBALT_UAPI_KERNEL_TYPES_H */
>> diff --git a/include/cobalt/uapi/sched.h b/include/cobalt/uapi/sched.h
>> index b672095c3b..14095870f3 100644
>> --- a/include/cobalt/uapi/sched.h
>> +++ b/include/cobalt/uapi/sched.h
>> @@ -18,6 +18,8 @@
>>  #ifndef _COBALT_UAPI_SCHED_H
>>  #define _COBALT_UAPI_SCHED_H
>>  
>> +#include <cobalt/uapi/kernel/types.h>
>> +
>>  #define SCHED_COBALT		42
>>  #define SCHED_WEAK		43
>>  
>> @@ -31,15 +33,15 @@
>>  
>>  struct __sched_ss_param {
>>  	int __sched_low_priority;
>> -	struct timespec __sched_repl_period;
>> -	struct timespec __sched_init_budget;
>> +	struct __user_old_timespec __sched_repl_period;
>> +	struct __user_old_timespec __sched_init_budget;
>>  	int __sched_max_repl;
>>  };
>>  
>>  #define sched_rr_quantum	sched_u.rr.__sched_rr_quantum
>>  
>>  struct __sched_rr_param {
>> -	struct timespec __sched_rr_quantum;
>> +	struct __user_old_timespec __sched_rr_quantum;
>>  };
>>  
>>  #ifndef SCHED_TP
>> @@ -52,8 +54,8 @@ struct __sched_tp_param {
>>  };
>>  
>>  struct sched_tp_window {
>> -	struct timespec offset;
>> -	struct timespec duration;
>> +	struct __user_old_timespec offset;
>> +	struct __user_old_timespec duration;
>>  	int ptid;
>>  };
>>  
>> diff --git a/kernel/cobalt/include/asm-generic/xenomai/syscall.h b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
>> index 0d50d4107d..05a7d28685 100644
>> --- a/kernel/cobalt/include/asm-generic/xenomai/syscall.h
>> +++ b/kernel/cobalt/include/asm-generic/xenomai/syscall.h
>> @@ -26,6 +26,7 @@
>>  #include <asm/xenomai/wrappers.h>
>>  #include <asm/xenomai/machine.h>
>>  #include <cobalt/uapi/asm-generic/syscall.h>
>> +#include <cobalt/uapi/kernel/types.h>
>>  
>>  #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
>>  #define access_rok(addr, size)	access_ok((addr), (size))
>> @@ -81,6 +82,63 @@ static inline int cobalt_strncpy_from_user(char *dst, const char __user *src,
>>  	return __xn_strncpy_from_user(dst, src, count);
>>  }
>>  
>> +#if __BITS_PER_LONG == 64
>> +
>> +/*
>> + * NOTE: those copy helpers won't work in compat mode: use
>> + * sys32_get_timespec(), sys32_put_timespec() instead.
>> + */
>> +
>> +static inline int cobalt_get_u_timespec(struct timespec64 *dst,
>> +			const struct __user_old_timespec __user *src)
>> +{
>> +	return cobalt_copy_from_user(dst, src, sizeof(*dst));
>> +}
>> +
>> +static inline int cobalt_put_u_timespec(
>> +	struct __user_old_timespec __user *dst,
>> +	const struct timespec64 *src)
>> +{
>> +	return cobalt_copy_to_user(dst, src, sizeof(*dst));
>> +}
>> +
>> +#else /* __BITS_PER_LONG == 32 */
>> +
>> +static inline int cobalt_get_u_timespec(struct timespec64 *dst,
>> +			const struct __user_old_timespec __user *src)
>> +{
>> +	struct __user_old_timespec u_ts;
>> +	int ret;
>> +
>> +	ret = cobalt_copy_from_user(&u_ts, src, sizeof(u_ts));
>> +	if (ret)
>> +		return ret;
>> +
>> +	dst->tv_sec = u_ts.tv_sec;
>> +	dst->tv_nsec = u_ts.tv_nsec;
>> +
>> +	return 0;
>> +}
>> +
>> +static inline int cobalt_put_u_timespec(
>> +	struct __user_old_timespec __user *dst,
>> +	const struct timespec64 *src)
>> +{
>> +	struct __user_old_timespec u_ts;
>> +	int ret;
>> +
>> +	u_ts.tv_sec = src->tv_sec;
>> +	u_ts.tv_nsec = src->tv_nsec;
>> +
>> +	ret = cobalt_copy_to_user(dst, &u_ts, sizeof(*dst));
>> +	if (ret)
>> +		return ret;
>> +
>> +	return 0;
>> +}
>> +
>> +#endif
>> +
>
> IIRC I already mentioned that after the first post of this patch:
>
> The __BITS_PER_LONG == 32 version of that helpers work in both worlds.
> So if we don't care about a few additional element on the stack (and a
> few instructions) we could simplify the code a bit.
>

Please submit a patch on top of my queue which Jan is currently
upstreaming. Since I already agreed on this issue, let's be flexible.

-- 
Philippe.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-06  7:08     ` Bezdeka, Florian
@ 2021-05-07 11:29       ` Florian Bezdeka
  2021-05-07 11:49         ` Philippe Gerum
  2021-05-09  9:37         ` Philippe Gerum
  0 siblings, 2 replies; 22+ messages in thread
From: Florian Bezdeka @ 2021-05-07 11:29 UTC (permalink / raw)
  To: rpm, jan.kiszka; +Cc: xenomai

On 06.05.21 09:08, Bezdeka, Florian via Xenomai wrote:
> On Thu, 2021-05-06 at 09:02 +0200, Philippe Gerum wrote:
>> Jan Kiszka via Xenomai <xenomai@xenomai.org> writes:
>>
>>> On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
>>>> Picking up from Philippe's queue:
>>>>
>>>> This patch series prepares the tree for the upcoming y2038 work,
>>>> converting obsolete/ambiguous time specification types to the proper
>>>> ones introduced upstream by the v5.x kernel series.
>>>>
>>>> In v2, feedback on the first round has been addressed, primarily
>>>> regarding folding fixing into the patches that need them.
>>>>
>>>> In addition, this includes 3 patches from Florian that add
>>>> sem_timedwait64 system call and a test suite for it.
>>>>
>>>
>>> Seems we have some issue on ARM ("Illegal instruction" in smokey):
>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264219&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=eH%2FvAfRIX8ORSkqcvjrmd%2BD0s6N%2FcpKD66Ptm0c0pbc%3D&amp;reserved=0
>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264225&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=HWAdg9KpJhevXa97ziRGDwLzyHq5%2Fj1Yv7IBcH3uTsY%3D&amp;reserved=0
>>
>> That one may be related to the code directing clock_gettime() either to
>> the vDSO with Dovetail, or TSC readouts via a memory mapping with the
>> I-pipe, all in libcobalt.
> 
> Thanks for the hint! I will check that and report back.

I was able to find the root cause. It's glibc syscall() vs.
XENOMAI_SYSCALLx(). I have a fix around that was already tested on some
qemu targets (arm as well as x86). I will provide it soon.

There is still one open question to me: Why is there a special syscall
handling (userland) implemented in Xenomai? I did not fully understand
why we end up with an invalid instruction on arm, but I guess it's
because of different registers being used.

IOW: syscall() is fine as long as you are calling Linux syscalls, but
you might run into problems (at least on arm) when trying to call
Xenomai specific ones.

> 
>>
>>>
>>> Florian, could you check that?
>>>
>>> Thanks,
>>> Jan
>>
>>
> 


-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-07 11:29       ` Florian Bezdeka
@ 2021-05-07 11:49         ` Philippe Gerum
  2021-05-07 11:56           ` Philippe Gerum
  2021-05-09  9:37         ` Philippe Gerum
  1 sibling, 1 reply; 22+ messages in thread
From: Philippe Gerum @ 2021-05-07 11:49 UTC (permalink / raw)
  To: Florian Bezdeka; +Cc: jan.kiszka, xenomai


Florian Bezdeka <florian.bezdeka@siemens.com> writes:

> On 06.05.21 09:08, Bezdeka, Florian via Xenomai wrote:
>> On Thu, 2021-05-06 at 09:02 +0200, Philippe Gerum wrote:
>>> Jan Kiszka via Xenomai <xenomai@xenomai.org> writes:
>>>
>>>> On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
>>>>> Picking up from Philippe's queue:
>>>>>
>>>>> This patch series prepares the tree for the upcoming y2038 work,
>>>>> converting obsolete/ambiguous time specification types to the proper
>>>>> ones introduced upstream by the v5.x kernel series.
>>>>>
>>>>> In v2, feedback on the first round has been addressed, primarily
>>>>> regarding folding fixing into the patches that need them.
>>>>>
>>>>> In addition, this includes 3 patches from Florian that add
>>>>> sem_timedwait64 system call and a test suite for it.
>>>>>
>>>>
>>>> Seems we have some issue on ARM ("Illegal instruction" in smokey):
>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264219&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=eH%2FvAfRIX8ORSkqcvjrmd%2BD0s6N%2FcpKD66Ptm0c0pbc%3D&amp;reserved=0
>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264225&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=HWAdg9KpJhevXa97ziRGDwLzyHq5%2Fj1Yv7IBcH3uTsY%3D&amp;reserved=0
>>>
>>> That one may be related to the code directing clock_gettime() either to
>>> the vDSO with Dovetail, or TSC readouts via a memory mapping with the
>>> I-pipe, all in libcobalt.
>> 
>> Thanks for the hint! I will check that and report back.
>
> I was able to find the root cause. It's glibc syscall() vs.
> XENOMAI_SYSCALLx(). I have a fix around that was already tested on some
> qemu targets (arm as well as x86). I will provide it soon.
>
> There is still one open question to me: Why is there a special syscall
> handling (userland) implemented in Xenomai? I did not fully understand
> why we end up with an invalid instruction on arm, but I guess it's
> because of different registers being used.
>
> IOW: syscall() is fine as long as you are calling Linux syscalls, but
> you might run into problems (at least on arm) when trying to call
> Xenomai specific ones.
>

I may know this one, there is an ABI change in recent glibc,
specifically in the glue code for the arm unwinder, which may cause
this. Turning off -fasynchronous-unwind-tables should paper over that
particular issue.

-- 
Philippe.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-07 11:49         ` Philippe Gerum
@ 2021-05-07 11:56           ` Philippe Gerum
  2021-05-07 12:17             ` Florian Bezdeka
  0 siblings, 1 reply; 22+ messages in thread
From: Philippe Gerum @ 2021-05-07 11:56 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: Florian Bezdeka, xenomai


Philippe Gerum via Xenomai <xenomai@xenomai.org> writes:

> Florian Bezdeka <florian.bezdeka@siemens.com> writes:
>
>> On 06.05.21 09:08, Bezdeka, Florian via Xenomai wrote:
>>> On Thu, 2021-05-06 at 09:02 +0200, Philippe Gerum wrote:
>>>> Jan Kiszka via Xenomai <xenomai@xenomai.org> writes:
>>>>
>>>>> On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
>>>>>> Picking up from Philippe's queue:
>>>>>>
>>>>>> This patch series prepares the tree for the upcoming y2038 work,
>>>>>> converting obsolete/ambiguous time specification types to the proper
>>>>>> ones introduced upstream by the v5.x kernel series.
>>>>>>
>>>>>> In v2, feedback on the first round has been addressed, primarily
>>>>>> regarding folding fixing into the patches that need them.
>>>>>>
>>>>>> In addition, this includes 3 patches from Florian that add
>>>>>> sem_timedwait64 system call and a test suite for it.
>>>>>>
>>>>>
>>>>> Seems we have some issue on ARM ("Illegal instruction" in smokey):
>>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264219&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=eH%2FvAfRIX8ORSkqcvjrmd%2BD0s6N%2FcpKD66Ptm0c0pbc%3D&amp;reserved=0
>>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264225&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=HWAdg9KpJhevXa97ziRGDwLzyHq5%2Fj1Yv7IBcH3uTsY%3D&amp;reserved=0
>>>>
>>>> That one may be related to the code directing clock_gettime() either to
>>>> the vDSO with Dovetail, or TSC readouts via a memory mapping with the
>>>> I-pipe, all in libcobalt.
>>> 
>>> Thanks for the hint! I will check that and report back.
>>
>> I was able to find the root cause. It's glibc syscall() vs.
>> XENOMAI_SYSCALLx(). I have a fix around that was already tested on some
>> qemu targets (arm as well as x86). I will provide it soon.
>>
>> There is still one open question to me: Why is there a special syscall
>> handling (userland) implemented in Xenomai? I did not fully understand
>> why we end up with an invalid instruction on arm, but I guess it's
>> because of different registers being used.
>>
>> IOW: syscall() is fine as long as you are calling Linux syscalls, but
>> you might run into problems (at least on arm) when trying to call
>> Xenomai specific ones.
>>
>
> I may know this one, there is an ABI change in recent glibc,
> specifically in the glue code for the arm unwinder, which may cause
> this. Turning off -fasynchronous-unwind-tables should paper over that
> particular issue.

If so, then we need to fix the Xenomai syscall prologue/epilogue
(possibly some CPU register now has a specific function and/or should
hold a particular value across calls).

-- 
Philippe.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-07 11:56           ` Philippe Gerum
@ 2021-05-07 12:17             ` Florian Bezdeka
  2021-05-07 13:00               ` Philippe Gerum
  0 siblings, 1 reply; 22+ messages in thread
From: Florian Bezdeka @ 2021-05-07 12:17 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: xenomai, Jan Kiszka

On 07.05.21 13:56, Philippe Gerum wrote:
> 
> Philippe Gerum via Xenomai <xenomai@xenomai.org> writes:
> 
>> Florian Bezdeka <florian.bezdeka@siemens.com> writes:
>>
>>> On 06.05.21 09:08, Bezdeka, Florian via Xenomai wrote:
>>>> On Thu, 2021-05-06 at 09:02 +0200, Philippe Gerum wrote:
>>>>> Jan Kiszka via Xenomai <xenomai@xenomai.org> writes:
>>>>>
>>>>>> On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
>>>>>>> Picking up from Philippe's queue:
>>>>>>>
>>>>>>> This patch series prepares the tree for the upcoming y2038 work,
>>>>>>> converting obsolete/ambiguous time specification types to the proper
>>>>>>> ones introduced upstream by the v5.x kernel series.
>>>>>>>
>>>>>>> In v2, feedback on the first round has been addressed, primarily
>>>>>>> regarding folding fixing into the patches that need them.
>>>>>>>
>>>>>>> In addition, this includes 3 patches from Florian that add
>>>>>>> sem_timedwait64 system call and a test suite for it.
>>>>>>>
>>>>>>
>>>>>> Seems we have some issue on ARM ("Illegal instruction" in smokey):
>>>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264219&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=eH%2FvAfRIX8ORSkqcvjrmd%2BD0s6N%2FcpKD66Ptm0c0pbc%3D&amp;reserved=0
>>>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264225&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=HWAdg9KpJhevXa97ziRGDwLzyHq5%2Fj1Yv7IBcH3uTsY%3D&amp;reserved=0
>>>>>
>>>>> That one may be related to the code directing clock_gettime() either to
>>>>> the vDSO with Dovetail, or TSC readouts via a memory mapping with the
>>>>> I-pipe, all in libcobalt.
>>>>
>>>> Thanks for the hint! I will check that and report back.
>>>
>>> I was able to find the root cause. It's glibc syscall() vs.
>>> XENOMAI_SYSCALLx(). I have a fix around that was already tested on some
>>> qemu targets (arm as well as x86). I will provide it soon.
>>>
>>> There is still one open question to me: Why is there a special syscall
>>> handling (userland) implemented in Xenomai? I did not fully understand
>>> why we end up with an invalid instruction on arm, but I guess it's
>>> because of different registers being used.
>>>
>>> IOW: syscall() is fine as long as you are calling Linux syscalls, but
>>> you might run into problems (at least on arm) when trying to call
>>> Xenomai specific ones.
>>>
>>
>> I may know this one, there is an ABI change in recent glibc,
>> specifically in the glue code for the arm unwinder, which may cause
>> this. Turning off -fasynchronous-unwind-tables should paper over that
>> particular issue.
> 
> If so, then we need to fix the Xenomai syscall prologue/epilogue
> (possibly some CPU register now has a specific function and/or should
> hold a particular value across calls).
> 

Any references? We did not update glibc recently (CI images are still
using glibc from Debian 10). The smokey tests running into problems now
are the first ones that are using the *libc syscall() function. So maybe
it was already broken on ARM?

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-07 12:17             ` Florian Bezdeka
@ 2021-05-07 13:00               ` Philippe Gerum
  2021-05-08 19:33                 ` Florian Bezdeka
  0 siblings, 1 reply; 22+ messages in thread
From: Philippe Gerum @ 2021-05-07 13:00 UTC (permalink / raw)
  To: Florian Bezdeka; +Cc: xenomai, Jan Kiszka


Florian Bezdeka <florian.bezdeka@siemens.com> writes:

> On 07.05.21 13:56, Philippe Gerum wrote:
>> 
>> Philippe Gerum via Xenomai <xenomai@xenomai.org> writes:
>> 
>>> Florian Bezdeka <florian.bezdeka@siemens.com> writes:
>>>
>>>> On 06.05.21 09:08, Bezdeka, Florian via Xenomai wrote:
>>>>> On Thu, 2021-05-06 at 09:02 +0200, Philippe Gerum wrote:
>>>>>> Jan Kiszka via Xenomai <xenomai@xenomai.org> writes:
>>>>>>
>>>>>>> On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
>>>>>>>> Picking up from Philippe's queue:
>>>>>>>>
>>>>>>>> This patch series prepares the tree for the upcoming y2038 work,
>>>>>>>> converting obsolete/ambiguous time specification types to the proper
>>>>>>>> ones introduced upstream by the v5.x kernel series.
>>>>>>>>
>>>>>>>> In v2, feedback on the first round has been addressed, primarily
>>>>>>>> regarding folding fixing into the patches that need them.
>>>>>>>>
>>>>>>>> In addition, this includes 3 patches from Florian that add
>>>>>>>> sem_timedwait64 system call and a test suite for it.
>>>>>>>>
>>>>>>>
>>>>>>> Seems we have some issue on ARM ("Illegal instruction" in smokey):
>>>>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264219&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=eH%2FvAfRIX8ORSkqcvjrmd%2BD0s6N%2FcpKD66Ptm0c0pbc%3D&amp;reserved=0
>>>>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264225&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=HWAdg9KpJhevXa97ziRGDwLzyHq5%2Fj1Yv7IBcH3uTsY%3D&amp;reserved=0
>>>>>>
>>>>>> That one may be related to the code directing clock_gettime() either to
>>>>>> the vDSO with Dovetail, or TSC readouts via a memory mapping with the
>>>>>> I-pipe, all in libcobalt.
>>>>>
>>>>> Thanks for the hint! I will check that and report back.
>>>>
>>>> I was able to find the root cause. It's glibc syscall() vs.
>>>> XENOMAI_SYSCALLx(). I have a fix around that was already tested on some
>>>> qemu targets (arm as well as x86). I will provide it soon.
>>>>
>>>> There is still one open question to me: Why is there a special syscall
>>>> handling (userland) implemented in Xenomai? I did not fully understand
>>>> why we end up with an invalid instruction on arm, but I guess it's
>>>> because of different registers being used.
>>>>
>>>> IOW: syscall() is fine as long as you are calling Linux syscalls, but
>>>> you might run into problems (at least on arm) when trying to call
>>>> Xenomai specific ones.
>>>>
>>>
>>> I may know this one, there is an ABI change in recent glibc,
>>> specifically in the glue code for the arm unwinder, which may cause
>>> this. Turning off -fasynchronous-unwind-tables should paper over that
>>> particular issue.
>> 
>> If so, then we need to fix the Xenomai syscall prologue/epilogue
>> (possibly some CPU register now has a specific function and/or should
>> hold a particular value across calls).
>> 
>
> Any references? We did not update glibc recently (CI images are still
> using glibc from Debian 10). The smokey tests running into problems now
> are the first ones that are using the *libc syscall() function. So maybe
> it was already broken on ARM?

Not sure. First caught this with EVL after an upgrade to
gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf, when the issue
started showing up.

Some calls like pthread_cancel() would crash randomly. I still have this
issue on my todo list as I want to re-enable async tables for libevl
although this is not required anymore (unlike libcobalt).

-- 
Philippe.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-07 13:00               ` Philippe Gerum
@ 2021-05-08 19:33                 ` Florian Bezdeka
  0 siblings, 0 replies; 22+ messages in thread
From: Florian Bezdeka @ 2021-05-08 19:33 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: xenomai, Jan Kiszka

On 07.05.21 15:00, Philippe Gerum wrote:
> 
> Florian Bezdeka <florian.bezdeka@siemens.com> writes:
> 
>> On 07.05.21 13:56, Philippe Gerum wrote:
>>>
>>> Philippe Gerum via Xenomai <xenomai@xenomai.org> writes:
>>>
>>>> Florian Bezdeka <florian.bezdeka@siemens.com> writes:
>>>>
>>>>> On 06.05.21 09:08, Bezdeka, Florian via Xenomai wrote:
>>>>>> On Thu, 2021-05-06 at 09:02 +0200, Philippe Gerum wrote:
>>>>>>> Jan Kiszka via Xenomai <xenomai@xenomai.org> writes:
>>>>>>>
>>>>>>>> On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
>>>>>>>>> Picking up from Philippe's queue:
>>>>>>>>>
>>>>>>>>> This patch series prepares the tree for the upcoming y2038 work,
>>>>>>>>> converting obsolete/ambiguous time specification types to the proper
>>>>>>>>> ones introduced upstream by the v5.x kernel series.
>>>>>>>>>
>>>>>>>>> In v2, feedback on the first round has been addressed, primarily
>>>>>>>>> regarding folding fixing into the patches that need them.
>>>>>>>>>
>>>>>>>>> In addition, this includes 3 patches from Florian that add
>>>>>>>>> sem_timedwait64 system call and a test suite for it.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Seems we have some issue on ARM ("Illegal instruction" in smokey):
>>>>>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264219&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=eH%2FvAfRIX8ORSkqcvjrmd%2BD0s6N%2FcpKD66Ptm0c0pbc%3D&amp;reserved=0
>>>>>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264225&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=HWAdg9KpJhevXa97ziRGDwLzyHq5%2Fj1Yv7IBcH3uTsY%3D&amp;reserved=0
>>>>>>>
>>>>>>> That one may be related to the code directing clock_gettime() either to
>>>>>>> the vDSO with Dovetail, or TSC readouts via a memory mapping with the
>>>>>>> I-pipe, all in libcobalt.
>>>>>>
>>>>>> Thanks for the hint! I will check that and report back.
>>>>>
>>>>> I was able to find the root cause. It's glibc syscall() vs.
>>>>> XENOMAI_SYSCALLx(). I have a fix around that was already tested on some
>>>>> qemu targets (arm as well as x86). I will provide it soon.
>>>>>
>>>>> There is still one open question to me: Why is there a special syscall
>>>>> handling (userland) implemented in Xenomai? I did not fully understand
>>>>> why we end up with an invalid instruction on arm, but I guess it's
>>>>> because of different registers being used.
>>>>>
>>>>> IOW: syscall() is fine as long as you are calling Linux syscalls, but
>>>>> you might run into problems (at least on arm) when trying to call
>>>>> Xenomai specific ones.
>>>>>
>>>>
>>>> I may know this one, there is an ABI change in recent glibc,
>>>> specifically in the glue code for the arm unwinder, which may cause
>>>> this. Turning off -fasynchronous-unwind-tables should paper over that
>>>> particular issue.
>>>
>>> If so, then we need to fix the Xenomai syscall prologue/epilogue
>>> (possibly some CPU register now has a specific function and/or should
>>> hold a particular value across calls).
>>>
>>
>> Any references? We did not update glibc recently (CI images are still
>> using glibc from Debian 10). The smokey tests running into problems now
>> are the first ones that are using the *libc syscall() function. So maybe
>> it was already broken on ARM?
> 
> Not sure. First caught this with EVL after an upgrade to
> gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf, when the issue
> started showing up.
> 
> Some calls like pthread_cancel() would crash randomly. I still have this
> issue on my todo list as I want to re-enable async tables for libevl
> although this is not required anymore (unlike libcobalt).
> 

I tried building with the following diff applied, but had no success:

diff --git a/configure.ac b/configure.ac
index bd5fd5ba9..5b0ddb561 100644
--- a/configure.ac
+++ b/configure.ac
@@ -681,7 +681,7 @@ AC_CHECK_FUNC(__vfprintf_chk,
       fi])

 dnl Exported CFLAGS and LDFLAGS, shared with internal flags
-XENO_USER_APP_CFLAGS="-D_GNU_SOURCE -D_REENTRANT
-fasynchronous-unwind-tables"
+XENO_USER_APP_CFLAGS="-D_GNU_SOURCE -D_REENTRANT
-fno-asynchronous-unwind-tables"
 XENO_USER_APP_LDFLAGS=



-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 0/9] y2038 groundwork and first steps
  2021-05-07 11:29       ` Florian Bezdeka
  2021-05-07 11:49         ` Philippe Gerum
@ 2021-05-09  9:37         ` Philippe Gerum
  1 sibling, 0 replies; 22+ messages in thread
From: Philippe Gerum @ 2021-05-09  9:37 UTC (permalink / raw)
  To: Florian Bezdeka; +Cc: jan.kiszka, xenomai


Florian Bezdeka <florian.bezdeka@siemens.com> writes:

> On 06.05.21 09:08, Bezdeka, Florian via Xenomai wrote:
>> On Thu, 2021-05-06 at 09:02 +0200, Philippe Gerum wrote:
>>> Jan Kiszka via Xenomai <xenomai@xenomai.org> writes:
>>>
>>>> On 05.05.21 18:52, Jan Kiszka via Xenomai wrote:
>>>>> Picking up from Philippe's queue:
>>>>>
>>>>> This patch series prepares the tree for the upcoming y2038 work,
>>>>> converting obsolete/ambiguous time specification types to the proper
>>>>> ones introduced upstream by the v5.x kernel series.
>>>>>
>>>>> In v2, feedback on the first round has been addressed, primarily
>>>>> regarding folding fixing into the patches that need them.
>>>>>
>>>>> In addition, this includes 3 patches from Florian that add
>>>>> sem_timedwait64 system call and a test suite for it.
>>>>>
>>>>
>>>> Seems we have some issue on ARM ("Illegal instruction" in smokey):
>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264219&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=eH%2FvAfRIX8ORSkqcvjrmd%2BD0s6N%2FcpKD66Ptm0c0pbc%3D&amp;reserved=0
>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2FXenomai%2Fxenomai-images%2F-%2Fjobs%2F264225&amp;data=04%7C01%7Cflorian.bezdeka%40siemens.com%7C4809653e590745bc77b008d9105dbc19%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637558817063489934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=HWAdg9KpJhevXa97ziRGDwLzyHq5%2Fj1Yv7IBcH3uTsY%3D&amp;reserved=0
>>>
>>> That one may be related to the code directing clock_gettime() either to
>>> the vDSO with Dovetail, or TSC readouts via a memory mapping with the
>>> I-pipe, all in libcobalt.
>> 
>> Thanks for the hint! I will check that and report back.
>
> I was able to find the root cause. It's glibc syscall() vs.
> XENOMAI_SYSCALLx(). I have a fix around that was already tested on some
> qemu targets (arm as well as x86). I will provide it soon.
>
> There is still one open question to me: Why is there a special syscall
> handling (userland) implemented in Xenomai? I did not fully understand
> why we end up with an invalid instruction on arm, but I guess it's
> because of different registers being used.
>

Ok, forget about the other options I mentioned which - although they
could produce SIGILL the same way - do not apply in this case (I only
figured out lately that you were specifically talking about the new
y2038 smokey test you just introduced). The actual reason for SIGILL
being received in that case is that we indeed have a specific calling
convention for Xenomai, esp. on ARM.

Basically, we use a syscall multiplexer, loading a special value into
register r7 which normally contains the syscall number; this is the job
of the XENOMAI_SYSCALLx() macros. This special value introduces a range
of 'foreign' syscalls (e.g. to cover Xenomai syscalls). When seen by the
kernel early on in the syscall path, it feeds the request to the
real-time core instead of passing it to the regular kernel handler.

By using syscall(__xn_syscode(foo), ...) directly, the multiplexer tag
is not present in r7, the latter contains the syscall number which is
above NR_syscalls, as it was encoded by the __xn_syscode() macro
(i.e. nr | __COBALT_SYSCALL_BIT which is 0x10000000). Because the tag is
not seen, Dovetail does not intercept that syscall, but leaves it
flowing down to the regular handler, which in turn notices that r7 is
not a valid regular syscall either.

On many/most architectures, the process would stop there, leading to
ENOSYS. But ARM has a few arch-specific internal syscalls above
__ARM_NR_BASE (EABI convention), and because any value produced by
__xn_syscode() may qualify as such, the secondary handler for ARM
syscalls runs for it. However, __xn_syscode(sc_cobalt_sem_timedwait64)
does not match any ARM-specific syscall, so the kernel eventually raises
SIGILL for the caller, instead of gracefully returning ENOSYS (see
arch/arm/kernel/traps.c, bad_syscall).

So bottom_line is: if you feed a Xenomai syscall code to the kernel, you
have to use XENOMAI_SYSCALLx().

-- 
Philippe.


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2021-05-09  9:37 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-05 16:52 [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
2021-05-05 16:53 ` [PATCH v2 1/9] cobalt/kernel: y2038: convert struct timespec to timespec64 Jan Kiszka
2021-05-07  6:09   ` Florian Bezdeka
2021-05-07  6:54     ` Philippe Gerum
2021-05-05 16:53 ` [PATCH v2 2/9] lib: y2038: convert to internal timespec type Jan Kiszka
2021-05-05 16:53 ` [PATCH v2 3/9] cobalt/kernel: y2038: convert struct itimerspec to itimerspec64 Jan Kiszka
2021-05-05 16:53 ` [PATCH v2 4/9] cobalt/kernel: y2038: convert struct timex to __kernel_timex Jan Kiszka
2021-05-05 16:53 ` [PATCH v2 5/9] cobalt/kernel: y2038: switch to new legacy type names Jan Kiszka
2021-05-05 16:53 ` [PATCH v2 6/9] cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems Jan Kiszka
2021-05-05 16:53 ` [PATCH v2 7/9] y2038: Adding sem_timedwait64 Jan Kiszka
2021-05-05 16:53 ` [PATCH v2 8/9] y2038: Add tests for the sc_cobalt_sem_timedwait64 syscall Jan Kiszka
2021-05-05 16:53 ` [PATCH v2 9/9] y2038: lib/cobalt: Add support of sc_cobalt_sem_timedwait64 Jan Kiszka
2021-05-06  5:20 ` [PATCH v2 0/9] y2038 groundwork and first steps Jan Kiszka
2021-05-06  7:02   ` Philippe Gerum
2021-05-06  7:08     ` Bezdeka, Florian
2021-05-07 11:29       ` Florian Bezdeka
2021-05-07 11:49         ` Philippe Gerum
2021-05-07 11:56           ` Philippe Gerum
2021-05-07 12:17             ` Florian Bezdeka
2021-05-07 13:00               ` Philippe Gerum
2021-05-08 19:33                 ` Florian Bezdeka
2021-05-09  9:37         ` Philippe Gerum

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.