All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] y2038 groundwork
@ 2021-03-27  9:54 Philippe Gerum
  2021-03-27  9:54 ` [PATCH 1/8] cobalt/kernel: y2038: convert struct timespec to timespec64 Philippe Gerum
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-03-27  9:54 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

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.

Florian Bezdeka (3):
  cobalt/mutex: Bring back ia32 support for mutex_timedwait
  cobalt/mqueue: Bring back ia32 support for mq_timed{send,receive}
  cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems

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

 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/uapi/kernel/types.h            |  53 +++++++++
 include/cobalt/uapi/sched.h                   |  12 +-
 .../include/asm-generic/xenomai/syscall.h     | 103 ++++++++++++++++++
 .../include/asm-generic/xenomai/wrappers.h    |  10 ++
 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                     |  40 +++----
 kernel/cobalt/posix/sem.h                     |   6 +-
 kernel/cobalt/posix/signal.c                  |   6 +-
 kernel/cobalt/posix/signal.h                  |   4 +-
 kernel/cobalt/posix/syscall32.c               |  86 ++++++++-------
 kernel/cobalt/posix/syscall32.h               |  44 ++++----
 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/trace/cobalt-posix.h            |  34 +++---
 kernel/drivers/ipc/rtipc.c                    |   4 +-
 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 +-
 46 files changed, 552 insertions(+), 326 deletions(-)

-- 
2.29.2



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

* [PATCH 1/8] cobalt/kernel: y2038: convert struct timespec to timespec64
  2021-03-27  9:54 [PATCH 0/8] y2038 groundwork Philippe Gerum
@ 2021-03-27  9:54 ` Philippe Gerum
  2021-03-27  9:54 ` [PATCH 2/8] cobalt/mutex: Bring back ia32 support for mutex_timedwait Philippe Gerum
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-03-27  9:54 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>
---
 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                  | 18 +++---
 kernel/cobalt/posix/mqueue.h                  |  8 +--
 kernel/cobalt/posix/mutex.c                   | 10 ++--
 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, 260 insertions(+), 160 deletions(-)

diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
index bbf34c53c..1c99173ff 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 313b6251b..c57ef6532 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 933e100ba..19e3d8986 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 fa7ac2a5e..d35aea17b 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 289065082..37a09c43e 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 ee5bbadca..8ce9b03df 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 b672095c3..14095870f 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 0d50d4107..05a7d2868 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 606c6bf8c..d40b0ac89 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 e957dd956..4a3365d2a 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 7cb161df2..7e45fdcc6 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 2ffc0dbdf..185295082 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 35a8f7176..bb18fe316 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 c7a9be451..7bec2a649 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 c566a09e3..3712154f5 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 28d4516ac..ef592f72c 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 e9908feeb..97a1f6afc 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 82187cc7b..e4f7d4d51 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 5237545be..b907e0050 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 8b321aaec..d4a4aa24e 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 b58d111db..f9044d4d2 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,7 +883,7 @@ 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 :
@@ -892,7 +892,7 @@ static inline int mq_fetch_timeout(struct timespec *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 +936,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 +946,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 +997,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 acae2a424..d33220227 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 79260b544..d43a747b3 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,7 +346,7 @@ 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 :
@@ -355,7 +355,7 @@ static inline int mutex_fetch_timeout(struct timespec *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 ac1c50291..d76f2a9ea 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 798a172d7..4fd9c2b46 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 05a861dfe..467a9b7dd 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 17238078e..d17299495 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 862a644c0..0b43b5fcf 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 7a0b4b22b..fc26ad065 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 cb02dacd3..ae25a6e74 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 eb3e4bd30..9da405229 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 bf9c08212..cdeb66d4f 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 7956a8800..038247d54 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 aa78efbc0..3a649a671 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.29.2



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

* [PATCH 2/8] cobalt/mutex: Bring back ia32 support for mutex_timedwait
  2021-03-27  9:54 [PATCH 0/8] y2038 groundwork Philippe Gerum
  2021-03-27  9:54 ` [PATCH 1/8] cobalt/kernel: y2038: convert struct timespec to timespec64 Philippe Gerum
@ 2021-03-27  9:54 ` Philippe Gerum
  2021-04-07 16:35   ` Jan Kiszka
  2021-03-27  9:54 ` [PATCH 3/8] cobalt/mqueue: Bring back ia32 support for mq_timed{send, receive} Philippe Gerum
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Philippe Gerum @ 2021-03-27  9:54 UTC (permalink / raw)
  To: xenomai

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

The helper used for copying the timeout values (=mutex_fetch_timeout())
was always copying sizeof(struct timespec64) from user to kernel space.
For applications with time_t being 4 bytes only (like for native 32 bit
applications) that is simply too much.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 kernel/cobalt/posix/mutex.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/kernel/cobalt/posix/mutex.c b/kernel/cobalt/posix/mutex.c
index d43a747b3..70fe7960a 100644
--- a/kernel/cobalt/posix/mutex.c
+++ b/kernel/cobalt/posix/mutex.c
@@ -349,8 +349,7 @@ COBALT_SYSCALL(mutex_lock, primary,
 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,
-- 
2.29.2



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

* [PATCH 3/8] cobalt/mqueue: Bring back ia32 support for mq_timed{send, receive}
  2021-03-27  9:54 [PATCH 0/8] y2038 groundwork Philippe Gerum
  2021-03-27  9:54 ` [PATCH 1/8] cobalt/kernel: y2038: convert struct timespec to timespec64 Philippe Gerum
  2021-03-27  9:54 ` [PATCH 2/8] cobalt/mutex: Bring back ia32 support for mutex_timedwait Philippe Gerum
@ 2021-03-27  9:54 ` Philippe Gerum
  2021-03-27  9:54 ` [PATCH 4/8] lib: y2038: convert to internal timespec type Philippe Gerum
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-03-27  9:54 UTC (permalink / raw)
  To: xenomai

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

The helper used for copying the timeout values (=mq_fetch_timeout())
was always copying sizeof(struct timespec64) from user to kernel space.
For applications with time_t being 4 bytes only (like for native 32 bit
applications) that is simply too much.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 kernel/cobalt/posix/mqueue.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
index f9044d4d2..dd8acd55b 100644
--- a/kernel/cobalt/posix/mqueue.c
+++ b/kernel/cobalt/posix/mqueue.c
@@ -886,8 +886,7 @@ COBALT_SYSCALL(mq_getattr, current,
 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,
-- 
2.29.2



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

* [PATCH 4/8] lib: y2038: convert to internal timespec type
  2021-03-27  9:54 [PATCH 0/8] y2038 groundwork Philippe Gerum
                   ` (2 preceding siblings ...)
  2021-03-27  9:54 ` [PATCH 3/8] cobalt/mqueue: Bring back ia32 support for mq_timed{send, receive} Philippe Gerum
@ 2021-03-27  9:54 ` Philippe Gerum
  2021-03-30 21:20   ` Florian Bezdeka
  2021-03-27  9:54 ` [PATCH 5/8] cobalt/kernel: y2038: convert struct itimerspec to itimerspec64 Philippe Gerum
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Philippe Gerum @ 2021-03-27  9:54 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
---
 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 949a996d0..9afa2af57 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 a3101baa1..f4588a17a 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 46e49ea88..f678be61d 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 4f3bd8201..d67502730 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 a4af36c1f..c8723c6be 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.29.2



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

* [PATCH 5/8] cobalt/kernel: y2038: convert struct itimerspec to itimerspec64
  2021-03-27  9:54 [PATCH 0/8] y2038 groundwork Philippe Gerum
                   ` (3 preceding siblings ...)
  2021-03-27  9:54 ` [PATCH 4/8] lib: y2038: convert to internal timespec type Philippe Gerum
@ 2021-03-27  9:54 ` Philippe Gerum
  2021-03-27  9:54 ` [PATCH 6/8] cobalt/kernel: y2038: convert struct timex to __kernel_timex Philippe Gerum
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-03-27  9:54 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>
---
 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 c57ef6532..7bec8c3be 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 8ce9b03df..10abbb55a 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 05a7d2868..91bbf3bfd 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 185295082..767a8033a 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 ae365c787..e23c26ccc 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 ae25a6e74..5c858806b 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 3aca90de9..a58ea99a3 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 0f5402aee..3b580d470 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 29046cfec..472c4cba0 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 5787ff60a..245b8698b 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.29.2



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

* [PATCH 6/8] cobalt/kernel: y2038: convert struct timex to __kernel_timex
  2021-03-27  9:54 [PATCH 0/8] y2038 groundwork Philippe Gerum
                   ` (4 preceding siblings ...)
  2021-03-27  9:54 ` [PATCH 5/8] cobalt/kernel: y2038: convert struct itimerspec to itimerspec64 Philippe Gerum
@ 2021-03-27  9:54 ` Philippe Gerum
  2021-03-27  9:54 ` [PATCH 7/8] cobalt/kernel: y2038: switch to new legacy type names Philippe Gerum
  2021-03-27  9:54 ` [PATCH 8/8] cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems Philippe Gerum
  7 siblings, 0 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-03-27  9:54 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>
---
 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 1c99173ff..0e4f1e1cb 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 7bec8c3be..d7f0008d9 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 10abbb55a..2c931c29c 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 2e9fb203a..eaeeafd68 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 4a3365d2a..23a45bba9 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 7e45fdcc6..e69e76e1b 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 767a8033a..6002d7480 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 5c858806b..4f819e0e5 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 3a649a671..cff1bd9b7 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.29.2



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

* [PATCH 7/8] cobalt/kernel: y2038: switch to new legacy type names
  2021-03-27  9:54 [PATCH 0/8] y2038 groundwork Philippe Gerum
                   ` (5 preceding siblings ...)
  2021-03-27  9:54 ` [PATCH 6/8] cobalt/kernel: y2038: convert struct timex to __kernel_timex Philippe Gerum
@ 2021-03-27  9:54 ` Philippe Gerum
  2021-03-27  9:54 ` [PATCH 8/8] cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems Philippe Gerum
  7 siblings, 0 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-03-27  9:54 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>
---
 include/cobalt/kernel/compat.h                | 22 +++++-----
 .../include/asm-generic/xenomai/wrappers.h    |  6 +++
 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, 69 insertions(+), 63 deletions(-)

diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
index d7f0008d9..6da7bafaf 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 eaeeafd68..9e8733b47 100644
--- a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
+++ b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
@@ -170,4 +170,10 @@ devm_hwmon_device_register_with_groups(struct device *dev, const char *name,
 #define __kernel_old_timeval	timeval
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0)
+#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 6002d7480..dbc9a9cf0 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 4f819e0e5..57aa7251a 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 9da405229..66cd2a5d2 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 b6fafdb41..abb76817a 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.29.2



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

* [PATCH 8/8] cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems
  2021-03-27  9:54 [PATCH 0/8] y2038 groundwork Philippe Gerum
                   ` (6 preceding siblings ...)
  2021-03-27  9:54 ` [PATCH 7/8] cobalt/kernel: y2038: switch to new legacy type names Philippe Gerum
@ 2021-03-27  9:54 ` Philippe Gerum
  7 siblings, 0 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-03-27  9:54 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>
---
 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 467a9b7dd..827a4751a 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 d17299495..658e11f7a 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 57aa7251a..edac7ea4a 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 66cd2a5d2..d72fd2022 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.29.2



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

* Re: [PATCH 4/8] lib: y2038: convert to internal timespec type
  2021-03-27  9:54 ` [PATCH 4/8] lib: y2038: convert to internal timespec type Philippe Gerum
@ 2021-03-30 21:20   ` Florian Bezdeka
  2021-03-31  8:13     ` Philippe Gerum
  2021-03-31  9:03     ` Philippe Gerum
  0 siblings, 2 replies; 15+ messages in thread
From: Florian Bezdeka @ 2021-03-30 21:20 UTC (permalink / raw)
  To: Philippe Gerum, chensong; +Cc: Jan Kiszka, xenomai

Hi Philippe,

which "internal timespec type" are you talking about? You're using
struct timespec here, which is not y2038 safe on 32 bit platforms.

I wonder about the effect of splitting the assignments into separate
tv_sec and tv_nsec assignements. I know this pattern from getting aware
of different paddings between kernel and user space in case we handle a
compat application, but this is all library stuff and compat
applications should use the compat syscalls which hopefully care about
different paddings...

On 27.03.21 10:54, Philippe Gerum via Xenomai wrote:
> From: Philippe Gerum <rpm@xenomai.org>
> 
> Signed-off-by: Philippe Gerum <rpm@xenomai.org>
> ---
>  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 949a996d0..9afa2af57 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 a3101baa1..f4588a17a 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 46e49ea88..f678be61d 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 4f3bd8201..d67502730 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);

@Song:
Following this code paths brings me to
sc_cobalt_thread_setschedparam_ex, which is not yet part of our y2038
roadmap.


>  }
> diff --git a/lib/vxworks/taskLib.c b/lib/vxworks/taskLib.c
> index a4af36c1f..c8723c6be 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);
> 


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


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

* Re: [PATCH 4/8] lib: y2038: convert to internal timespec type
  2021-03-30 21:20   ` Florian Bezdeka
@ 2021-03-31  8:13     ` Philippe Gerum
  2021-03-31  9:03     ` Philippe Gerum
  1 sibling, 0 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-03-31  8:13 UTC (permalink / raw)
  To: Florian Bezdeka; +Cc: chensong, Jan Kiszka, xenomai


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

> Hi Philippe,
>
> which "internal timespec type" are you talking about? You're using
> struct timespec here, which is not y2038 safe on 32 bit platforms.
>

The whole point of these series is solely to enable the code base for
building on the recent kernel series, not to address the y2038
issue. Song and yourself are addressing the later in a series of patches
indirectly based on my tree via wip/dovetail.

So I'm introducing the bits aimed at building on v5.x+ kernels which
includes converting to the new time specification types used upstream,
nothing more. Your fixes on the ia32/compat breakage introduced in the
first attempt are part of this new series (i.e. timeout handling in
compat mode for mq, mutex).

IOW, with that series in, we have a fully functional Xenomai 3.x code
base for the most recent kernel releases running on top of the I-pipe,
still not y2038-safe though. According to several discussions which took
place during the Xenomai community meetings, my understanding is that
your y2038 work lives on top of that code base. As we progress with
merging the rest of my tree in, we will gain the ability to run on top
of Dovetail as well for x86, arm and arm64, so that we can move from
running I-pipe/v5.4 to Dovetail/v5.10 and beyond (Dovetail is already on
track for v5.12).

> I wonder about the effect of splitting the assignments into separate
> tv_sec and tv_nsec assignements. I know this pattern from getting aware
> of different paddings between kernel and user space in case we handle a
> compat application, but this is all library stuff and compat
> applications should use the compat syscalls which hopefully care about
> different paddings...
>

It is not related to padding, this is only a matter of having differents
C types on both sides of the assignment: struct timespec vs struct
__user_old_timespec. As mentioned in the log, this series aims at
clearly delimiting the user / kernel boundary wrt time specification,
so we have different types on both sides. This was intended as prep work
before the y2038 issue is addressed on your end, in order to clarify the
interface. If you don't need it eventually, just drop it as part of your
series making Xenomai y2038-safe.

-- 
Philippe.


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

* Re: [PATCH 4/8] lib: y2038: convert to internal timespec type
  2021-03-30 21:20   ` Florian Bezdeka
  2021-03-31  8:13     ` Philippe Gerum
@ 2021-03-31  9:03     ` Philippe Gerum
  2021-03-31 15:58       ` Florian Bezdeka
  1 sibling, 1 reply; 15+ messages in thread
From: Philippe Gerum @ 2021-03-31  9:03 UTC (permalink / raw)
  To: Florian Bezdeka; +Cc: chensong, Jan Kiszka, xenomai


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

> Hi Philippe,
>
> which "internal timespec type" are you talking about?

struct __user_old_timespec. The one added to make the user / kernel
boundary wrt time specification explicit.

-- 
Philippe.


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

* Re: [PATCH 4/8] lib: y2038: convert to internal timespec type
  2021-03-31  9:03     ` Philippe Gerum
@ 2021-03-31 15:58       ` Florian Bezdeka
  0 siblings, 0 replies; 15+ messages in thread
From: Florian Bezdeka @ 2021-03-31 15:58 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: chensong, Jan Kiszka, xenomai

On 31.03.21 11:03, Philippe Gerum wrote:
> 
> Florian Bezdeka <florian.bezdeka@siemens.com> writes:
> 
>> Hi Philippe,
>>
>> which "internal timespec type" are you talking about?
> 
> struct __user_old_timespec. The one added to make the user / kernel
> boundary wrt time specification explicit.
> 


Thanks! I just overlooked

 struct __sched_rr_param {
-	struct timespec __sched_rr_quantum;
+	struct __user_old_timespec __sched_rr_quantum;
 };

from the first patch of the series. That explains it.

Thanks for all the help and sorry for the noise.

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


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

* Re: [PATCH 2/8] cobalt/mutex: Bring back ia32 support for mutex_timedwait
  2021-03-27  9:54 ` [PATCH 2/8] cobalt/mutex: Bring back ia32 support for mutex_timedwait Philippe Gerum
@ 2021-04-07 16:35   ` Jan Kiszka
  2021-04-07 16:57     ` Philippe Gerum
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kiszka @ 2021-04-07 16:35 UTC (permalink / raw)
  To: Philippe Gerum, xenomai

On 27.03.21 10:54, Philippe Gerum wrote:
> From: Florian Bezdeka <florian.bezdeka@siemens.com>
> 
> The helper used for copying the timeout values (=mutex_fetch_timeout())
> was always copying sizeof(struct timespec64) from user to kernel space.
> For applications with time_t being 4 bytes only (like for native 32 bit
> applications) that is simply too much.
> 
> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> ---
>  kernel/cobalt/posix/mutex.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/kernel/cobalt/posix/mutex.c b/kernel/cobalt/posix/mutex.c
> index d43a747b3..70fe7960a 100644
> --- a/kernel/cobalt/posix/mutex.c
> +++ b/kernel/cobalt/posix/mutex.c
> @@ -349,8 +349,7 @@ COBALT_SYSCALL(mutex_lock, primary,
>  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,
> 

Also here: Can we please avoid introducing a regression first and then
fixing it in the same series? To my understanding, this belongs into
patch 1, right?

Same for patch 3 and 8 likely.

Philippe, you can preserve Florian's fix-up credit simply in the commit
message, if that was the concern.

Jan

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


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

* Re: [PATCH 2/8] cobalt/mutex: Bring back ia32 support for mutex_timedwait
  2021-04-07 16:35   ` Jan Kiszka
@ 2021-04-07 16:57     ` Philippe Gerum
  0 siblings, 0 replies; 15+ messages in thread
From: Philippe Gerum @ 2021-04-07 16:57 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai, Florian Bezdeka


Jan Kiszka <jan.kiszka@siemens.com> writes:

> On 27.03.21 10:54, Philippe Gerum wrote:
>> From: Florian Bezdeka <florian.bezdeka@siemens.com>
>> 
>> The helper used for copying the timeout values (=mutex_fetch_timeout())
>> was always copying sizeof(struct timespec64) from user to kernel space.
>> For applications with time_t being 4 bytes only (like for native 32 bit
>> applications) that is simply too much.
>> 
>> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
>> ---
>>  kernel/cobalt/posix/mutex.c | 3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>> 
>> diff --git a/kernel/cobalt/posix/mutex.c b/kernel/cobalt/posix/mutex.c
>> index d43a747b3..70fe7960a 100644
>> --- a/kernel/cobalt/posix/mutex.c
>> +++ b/kernel/cobalt/posix/mutex.c
>> @@ -349,8 +349,7 @@ COBALT_SYSCALL(mutex_lock, primary,
>>  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,
>> 
>
> Also here: Can we please avoid introducing a regression first and then
> fixing it in the same series? To my understanding, this belongs into
> patch 1, right?
>
> Same for patch 3 and 8 likely.
>
> Philippe, you can preserve Florian's fix-up credit simply in the commit
> message, if that was the concern.

That was the concern.

-- 
Philippe.


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

end of thread, other threads:[~2021-04-07 16:57 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-27  9:54 [PATCH 0/8] y2038 groundwork Philippe Gerum
2021-03-27  9:54 ` [PATCH 1/8] cobalt/kernel: y2038: convert struct timespec to timespec64 Philippe Gerum
2021-03-27  9:54 ` [PATCH 2/8] cobalt/mutex: Bring back ia32 support for mutex_timedwait Philippe Gerum
2021-04-07 16:35   ` Jan Kiszka
2021-04-07 16:57     ` Philippe Gerum
2021-03-27  9:54 ` [PATCH 3/8] cobalt/mqueue: Bring back ia32 support for mq_timed{send, receive} Philippe Gerum
2021-03-27  9:54 ` [PATCH 4/8] lib: y2038: convert to internal timespec type Philippe Gerum
2021-03-30 21:20   ` Florian Bezdeka
2021-03-31  8:13     ` Philippe Gerum
2021-03-31  9:03     ` Philippe Gerum
2021-03-31 15:58       ` Florian Bezdeka
2021-03-27  9:54 ` [PATCH 5/8] cobalt/kernel: y2038: convert struct itimerspec to itimerspec64 Philippe Gerum
2021-03-27  9:54 ` [PATCH 6/8] cobalt/kernel: y2038: convert struct timex to __kernel_timex Philippe Gerum
2021-03-27  9:54 ` [PATCH 7/8] cobalt/kernel: y2038: switch to new legacy type names Philippe Gerum
2021-03-27  9:54 ` [PATCH 8/8] cobalt/sem: y2038: Fixing the sem_timedwait syscall for 32 bit systems 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.