xenomai.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] y2038: Finalize and enable y2038 support
@ 2023-08-11  7:37 Florian Bezdeka
  2023-08-11  7:37 ` [PATCH 1/7] y2038: kernel/drivers: Implement SO_RCVTIMEO_NEW and SO_SNDTIMEO_NEW Florian Bezdeka
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-11  7:37 UTC (permalink / raw)
  To: xenomai, jan.kiszka; +Cc: Florian Bezdeka

Hi all,
    
this is the final y2038 related patch series. With this series applied
y2038 support will be enabled by default for all affected
builds/architectures.

There is a kill switch (--disable-y2038) available in case unexpected
problems come up after merge but that is not expected. The y2038 queue
was regularly tested over the last two years now.
    
Short summary:
  - Implement y2038 safe ioctls around SO_RCVTIMEO and SO_SNDTIMEO
  - Enable additional function wrapping
  - Fix some smokey tests (reading of reference clocks)

Fingers crossed, seems the y2038 issue is solved now.

Best regards,
Florian

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
Florian Bezdeka (7):
      y2038: kernel/drivers: Implement SO_RCVTIMEO_NEW and SO_SNDTIMEO_NEW
      y2038: lib/cobalt: Switch vdso to gettime64
      y2038: testsuite/clocktest: Fix reading of reference clock
      y2038: build: Introduce new build parameter --disable-y2038
      y2038: lib/cobalt: Add additional time64_t related function wrappers
      y2038: Route explicitly requested stdlib calls to time64 equivalents
      y2038: lib/cobalt/select: Fix __RT(select()) routing

 configure.ac                                     |  63 ++++++-
 include/cobalt/mqueue.h                          |  11 ++
 include/cobalt/pthread.h                         |  10 ++
 include/cobalt/semaphore.h                       |   4 +
 include/cobalt/signal.h                          |   5 +
 include/cobalt/sys/ioctl.h                       |   3 +
 include/cobalt/sys/select.h                      |   8 +
 include/cobalt/sys/socket.h                      |  15 ++
 include/cobalt/sys/time.h                        |   4 +
 include/cobalt/sys/timerfd.h                     |   9 +
 include/cobalt/time.h                            |  35 ++++
 include/cobalt/wrappers.h                        |  10 ++
 kernel/drivers/ipc/bufp.c                        |  34 ++++
 kernel/drivers/ipc/iddp.c                        |  34 ++++
 kernel/drivers/ipc/internal.h                    |  27 +++
 kernel/drivers/ipc/rtipc.c                       |  29 ++++
 kernel/drivers/ipc/xddp.c                        |  18 ++
 kernel/drivers/net/stack/ipv4/tcp/tcp.c          |  31 ++++
 lib/cobalt/Makefile.am                           |   7 +
 lib/cobalt/arch/arm/include/asm/xenomai/time.h   |   5 +
 lib/cobalt/arch/arm64/include/asm/xenomai/time.h |   5 +
 lib/cobalt/arch/x86/include/asm/xenomai/time.h   |   5 +
 lib/cobalt/cobalt-glibc-time64.wrappers          |  23 +++
 lib/cobalt/select.c                              |  15 ++
 lib/cobalt/wrappers-time64.c                     | 203 +++++++++++++++++++++++
 scripts/xeno-config-cobalt.in                    |   5 +
 testsuite/clocktest/clocktest.c                  |  11 +-
 testsuite/smokey/y2038/syscall-tests.c           |  46 +++++
 28 files changed, 669 insertions(+), 6 deletions(-)
---
base-commit: b6c84c13785ebb2c5493bdfe8fad50974eda442e
change-id: 20230809-florian-y2038-2-23303aa750cf

Best regards,
-- 
Florian Bezdeka <florian.bezdeka@siemens.com>


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

* [PATCH 1/7] y2038: kernel/drivers: Implement SO_RCVTIMEO_NEW and SO_SNDTIMEO_NEW
  2023-08-11  7:37 [PATCH 0/7] y2038: Finalize and enable y2038 support Florian Bezdeka
@ 2023-08-11  7:37 ` Florian Bezdeka
  2023-08-11  7:37 ` [PATCH 2/7] y2038: lib/cobalt: Switch vdso to gettime64 Florian Bezdeka
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-11  7:37 UTC (permalink / raw)
  To: xenomai, jan.kiszka; +Cc: Florian Bezdeka

When requesting y2038 support from recent glibc versions SO_RCVTIMEO and
SO_SNDTIMEO will be auto-converted to the _NEW variants to make clear
that we have to deal with a different (now y2038 safe) ABI.

Implementing SO_RCVTIMEO_NEW and SO_SNDTIMEO_NEW where necessary.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 kernel/drivers/ipc/bufp.c               | 34 +++++++++++++++++++++++++++++++++
 kernel/drivers/ipc/iddp.c               | 34 +++++++++++++++++++++++++++++++++
 kernel/drivers/ipc/internal.h           | 27 ++++++++++++++++++++++++++
 kernel/drivers/ipc/rtipc.c              | 29 ++++++++++++++++++++++++++++
 kernel/drivers/ipc/xddp.c               | 18 +++++++++++++++++
 kernel/drivers/net/stack/ipv4/tcp/tcp.c | 31 ++++++++++++++++++++++++++++++
 6 files changed, 173 insertions(+)

diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c
index 565409dd6..f1936d846 100644
--- a/kernel/drivers/ipc/bufp.c
+++ b/kernel/drivers/ipc/bufp.c
@@ -824,6 +824,7 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
 			     void *arg)
 {
 	struct _rtdm_setsockopt_args sopt;
+	struct __kernel_sock_timeval stv;
 	struct rtipc_port_label plabel;
 	struct __kernel_old_timeval tv;
 	rtdm_lockctx_t s;
@@ -844,6 +845,14 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
 			sk->rx_timeout = rtipc_timeval_to_ns(&tv);
 			break;
 
+		case SO_RCVTIMEO_NEW:
+			ret = rtipc_get_sock_timeval(fd, &stv, sopt.optval,
+						     sopt.optlen);
+			if (ret)
+				return ret;
+			sk->rx_timeout = rtipc_sock_timeval_to_ns(&stv);
+			break;
+
 		case SO_SNDTIMEO_OLD:
 			ret = rtipc_get_timeval(fd, &tv, sopt.optval, sopt.optlen);
 			if (ret)
@@ -851,6 +860,14 @@ static int __bufp_setsockopt(struct bufp_socket *sk,
 			sk->tx_timeout = rtipc_timeval_to_ns(&tv);
 			break;
 
+		case SO_SNDTIMEO_NEW:
+			ret = rtipc_get_sock_timeval(fd, &stv, sopt.optval,
+						     sopt.optlen);
+			if (ret)
+				return ret;
+			sk->tx_timeout = rtipc_sock_timeval_to_ns(&stv);
+			break;
+
 		default:
 			ret = -EINVAL;
 		}
@@ -913,6 +930,7 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
 			     void *arg)
 {
 	struct _rtdm_getsockopt_args sopt;
+	struct __kernel_sock_timeval stv;
 	struct rtipc_port_label plabel;
 	struct __kernel_old_timeval tv;
 	rtdm_lockctx_t s;
@@ -936,6 +954,14 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
 				return ret;
 			break;
 
+		case SO_RCVTIMEO_NEW:
+			rtipc_ns_to_sock_timeval(&stv, sk->rx_timeout);
+			ret = rtipc_put_sock_timeval(fd, sopt.optval, &stv,
+						     len);
+			if (ret)
+				return ret;
+			break;
+
 		case SO_SNDTIMEO_OLD:
 			rtipc_ns_to_timeval(&tv, sk->tx_timeout);
 			ret = rtipc_put_timeval(fd, sopt.optval, &tv, len);
@@ -943,6 +969,14 @@ static int __bufp_getsockopt(struct bufp_socket *sk,
 				return ret;
 			break;
 
+		case SO_SNDTIMEO_NEW:
+			rtipc_ns_to_sock_timeval(&stv, sk->tx_timeout);
+			ret = rtipc_put_sock_timeval(fd, sopt.optval, &stv,
+						     len);
+			if (ret)
+				return ret;
+			break;
+
 		default:
 			ret = -EINVAL;
 		}
diff --git a/kernel/drivers/ipc/iddp.c b/kernel/drivers/ipc/iddp.c
index 05d019339..e4893a378 100644
--- a/kernel/drivers/ipc/iddp.c
+++ b/kernel/drivers/ipc/iddp.c
@@ -704,6 +704,7 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
 			     void *arg)
 {
 	struct _rtdm_setsockopt_args sopt;
+	struct __kernel_sock_timeval stv;
 	struct rtipc_port_label plabel;
 	struct __kernel_old_timeval tv;
 	rtdm_lockctx_t s;
@@ -724,6 +725,14 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
 			sk->rx_timeout = rtipc_timeval_to_ns(&tv);
 			break;
 
+		case SO_RCVTIMEO_NEW:
+			ret = rtipc_get_sock_timeval(fd, &stv, sopt.optval,
+						     sopt.optlen);
+			if (ret)
+				return ret;
+			sk->rx_timeout = rtipc_sock_timeval_to_ns(&stv);
+			break;
+
 		case SO_SNDTIMEO_OLD:
 			ret = rtipc_get_timeval(fd, &tv, sopt.optval, sopt.optlen);
 			if (ret)
@@ -731,6 +740,14 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
 			sk->tx_timeout = rtipc_timeval_to_ns(&tv);
 			break;
 
+		case SO_SNDTIMEO_NEW:
+			ret = rtipc_get_sock_timeval(fd, &stv, sopt.optval,
+						     sopt.optlen);
+			if (ret)
+				return ret;
+			sk->tx_timeout = rtipc_sock_timeval_to_ns(&stv);
+			break;
+
 		default:
 			ret = -EINVAL;
 		}
@@ -793,6 +810,7 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
 			     void *arg)
 {
 	struct _rtdm_getsockopt_args sopt;
+	struct __kernel_sock_timeval stv;
 	struct rtipc_port_label plabel;
 	struct __kernel_old_timeval tv;
 	rtdm_lockctx_t s;
@@ -817,6 +835,14 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
 				return ret;
 			break;
 
+		case SO_RCVTIMEO_NEW:
+			rtipc_ns_to_sock_timeval(&stv, sk->rx_timeout);
+			ret = rtipc_put_sock_timeval(fd, sopt.optval, &stv,
+						     len);
+			if (ret)
+				return ret;
+			break;
+
 		case SO_SNDTIMEO_OLD:
 			rtipc_ns_to_timeval(&tv, sk->tx_timeout);
 			ret = rtipc_put_timeval(fd, sopt.optval, &tv, len);
@@ -824,6 +850,14 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
 				return ret;
 			break;
 
+		case SO_SNDTIMEO_NEW:
+			rtipc_ns_to_sock_timeval(&stv, sk->tx_timeout);
+			ret = rtipc_put_sock_timeval(fd, sopt.optval, &stv,
+						     len);
+			if (ret)
+				return ret;
+			break;
+
 		default:
 			ret = -EINVAL;
 		}
diff --git a/kernel/drivers/ipc/internal.h b/kernel/drivers/ipc/internal.h
index 919a5d978..f29ba2204 100644
--- a/kernel/drivers/ipc/internal.h
+++ b/kernel/drivers/ipc/internal.h
@@ -76,6 +76,17 @@ static inline nanosecs_rel_t rtipc_timeval_to_ns(const struct __kernel_old_timev
 	return ns;
 }
 
+static inline nanosecs_rel_t
+rtipc_sock_timeval_to_ns(const struct __kernel_sock_timeval *tv)
+{
+	nanosecs_rel_t ns = tv->tv_usec * 1000;
+
+	if (tv->tv_sec)
+		ns += (nanosecs_rel_t)tv->tv_sec * 1000000000UL;
+
+	return ns;
+}
+
 static inline void rtipc_ns_to_timeval(struct __kernel_old_timeval *tv, nanosecs_rel_t ns)
 {
 	unsigned long nsecs;
@@ -84,6 +95,15 @@ static inline void rtipc_ns_to_timeval(struct __kernel_old_timeval *tv, nanosecs
 	tv->tv_usec = nsecs / 1000;
 }
 
+static inline void rtipc_ns_to_sock_timeval(struct __kernel_sock_timeval *tv,
+					    nanosecs_rel_t ns)
+{
+	unsigned long nsecs;
+
+	tv->tv_sec = xnclock_divrem_billion(ns, &nsecs);
+	tv->tv_usec = nsecs / 1000;
+}
+
 int rtipc_get_sockaddr(struct rtdm_fd *fd,
 		       struct sockaddr_ipc **saddrp,
 		       const void *arg);
@@ -105,9 +125,16 @@ int rtipc_get_sockoptin(struct rtdm_fd *fd,
 int rtipc_get_timeval(struct rtdm_fd *fd, struct __kernel_old_timeval *tv,
 		      const void *arg, size_t arglen);
 
+int rtipc_get_sock_timeval(struct rtdm_fd *fd, struct __kernel_sock_timeval *tv,
+			   const void *arg, size_t arglen);
+
 int rtipc_put_timeval(struct rtdm_fd *fd, void *arg,
 		      const struct __kernel_old_timeval *tv, size_t arglen);
 
+int rtipc_put_sock_timeval(struct rtdm_fd *fd, void *arg,
+			   const struct __kernel_sock_timeval *tv,
+			   size_t arglen);
+
 int rtipc_get_length(struct rtdm_fd *fd, size_t *lenp,
 		     const void *arg, size_t arglen);
 
diff --git a/kernel/drivers/ipc/rtipc.c b/kernel/drivers/ipc/rtipc.c
index 211b496ec..66176adad 100644
--- a/kernel/drivers/ipc/rtipc.c
+++ b/kernel/drivers/ipc/rtipc.c
@@ -290,6 +290,20 @@ int rtipc_get_timeval(struct rtdm_fd *fd, struct __kernel_old_timeval *tv,
 	return rtdm_safe_copy_from_user(fd, tv, arg, sizeof(*tv));
 }
 
+int rtipc_get_sock_timeval(struct rtdm_fd *fd, struct __kernel_sock_timeval *tv,
+			   const void *arg, size_t arglen)
+{
+	if (arglen != sizeof(*tv))
+		return -EINVAL;
+
+	if (!rtdm_fd_is_user(fd)) {
+		*tv = *(struct __kernel_sock_timeval *)arg;
+		return 0;
+	}
+
+	return rtdm_safe_copy_from_user(fd, tv, arg, sizeof(*tv));
+}
+
 int rtipc_put_timeval(struct rtdm_fd *fd, void *arg,
 		      const struct __kernel_old_timeval *tv, size_t arglen)
 {
@@ -312,6 +326,21 @@ int rtipc_put_timeval(struct rtdm_fd *fd, void *arg,
 	return rtdm_safe_copy_to_user(fd, arg, tv, sizeof(*tv));
 }
 
+int rtipc_put_sock_timeval(struct rtdm_fd *fd, void *arg,
+			   const struct __kernel_sock_timeval *tv,
+			   size_t arglen)
+{
+	if (arglen != sizeof(*tv))
+		return -EINVAL;
+
+	if (!rtdm_fd_is_user(fd)) {
+		*(struct __kernel_sock_timeval *)arg = *tv;
+		return 0;
+	}
+
+	return rtdm_safe_copy_to_user(fd, arg, tv, sizeof(*tv));
+}
+
 int rtipc_get_length(struct rtdm_fd *fd, size_t *lenp,
 		     const void *arg, size_t arglen)
 {
diff --git a/kernel/drivers/ipc/xddp.c b/kernel/drivers/ipc/xddp.c
index 2ca0da5fd..8f1b2ece7 100644
--- a/kernel/drivers/ipc/xddp.c
+++ b/kernel/drivers/ipc/xddp.c
@@ -859,6 +859,7 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
 {
 	int (*monitor)(struct rtdm_fd *fd, int event, long arg);
 	struct _rtdm_setsockopt_args sopt;
+	struct __kernel_sock_timeval stv;
 	struct rtipc_port_label plabel;
 	struct __kernel_old_timeval tv;
 	rtdm_lockctx_t s;
@@ -879,6 +880,14 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
 			sk->timeout = rtipc_timeval_to_ns(&tv);
 			break;
 
+		case SO_RCVTIMEO_NEW:
+			ret = rtipc_get_sock_timeval(fd, &stv, sopt.optval,
+						     sopt.optlen);
+			if (ret)
+				return ret;
+
+			sk->timeout = rtipc_sock_timeval_to_ns(&stv);
+			break;
 		default:
 			ret = -EINVAL;
 		}
@@ -965,6 +974,7 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
 			     void *arg)
 {
 	struct _rtdm_getsockopt_args sopt;
+	struct __kernel_sock_timeval stv;
 	struct rtipc_port_label plabel;
 	struct __kernel_old_timeval tv;
 	rtdm_lockctx_t s;
@@ -988,6 +998,14 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
 				return ret;
 			break;
 
+		case SO_RCVTIMEO_NEW:
+			rtipc_ns_to_sock_timeval(&stv, sk->timeout);
+			ret = rtipc_put_sock_timeval(fd, sopt.optval, &stv,
+						     len);
+			if (ret)
+				return ret;
+			break;
+
 		default:
 			ret = -EINVAL;
 		}
diff --git a/kernel/drivers/net/stack/ipv4/tcp/tcp.c b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
index 71628ba03..5bd114530 100644
--- a/kernel/drivers/net/stack/ipv4/tcp/tcp.c
+++ b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
@@ -1743,6 +1743,7 @@ static int rt_tcp_setsockopt(struct rtdm_fd *fd, struct tcp_socket *ts,
 			     socklen_t optlen)
 {
 	/* uint64_t val; */
+	struct __kernel_sock_timeval stv;
 	struct __kernel_old_timeval tv;
 	rtdm_lockctx_t context;
 
@@ -1793,6 +1794,36 @@ static int rt_tcp_setsockopt(struct rtdm_fd *fd, struct tcp_socket *ts,
 
 		return 0;
 
+	case SO_SNDTIMEO_NEW:
+		if (optlen < sizeof(stv))
+			return -EINVAL;
+		if (rtdm_copy_from_user(fd, &stv, optval, sizeof(stv)))
+			return -EFAULT;
+		if (stv.tv_usec < 0 || stv.tv_usec >= 1000000)
+			return -EDOM;
+
+		rtdm_lock_get_irqsave(&ts->socket_lock, context);
+
+		if (stv.tv_sec < 0) {
+			ts->sk_sndtimeo = RTDM_TIMEOUT_NONE;
+			rtdm_lock_put_irqrestore(&ts->socket_lock, context);
+			return 0;
+		}
+
+		ts->sk_sndtimeo = RTDM_TIMEOUT_INFINITE;
+		if (stv.tv_sec == 0 && stv.tv_usec == 0) {
+			rtdm_lock_put_irqrestore(&ts->socket_lock, context);
+			return 0;
+		}
+
+		if (stv.tv_sec < (MAX_SCHEDULE_TIMEOUT / 1000000000ull - 1))
+			ts->sk_sndtimeo =
+				(stv.tv_sec * 1000000 + stv.tv_usec) * 1000;
+
+		rtdm_lock_put_irqrestore(&ts->socket_lock, context);
+
+		return 0;
+
 	case SO_REUSEADDR:
 		/* to implement */
 		return -EOPNOTSUPP;

-- 
2.39.2


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

* [PATCH 2/7] y2038: lib/cobalt: Switch vdso to gettime64
  2023-08-11  7:37 [PATCH 0/7] y2038: Finalize and enable y2038 support Florian Bezdeka
  2023-08-11  7:37 ` [PATCH 1/7] y2038: kernel/drivers: Implement SO_RCVTIMEO_NEW and SO_SNDTIMEO_NEW Florian Bezdeka
@ 2023-08-11  7:37 ` Florian Bezdeka
  2023-08-11  7:37 ` [PATCH 3/7] y2038: testsuite/clocktest: Fix reading of reference clock Florian Bezdeka
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-11  7:37 UTC (permalink / raw)
  To: xenomai, jan.kiszka; +Cc: Florian Bezdeka

In case y2038 support was requested we have to switch to the gettime64
variant of the vdso interface.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 lib/cobalt/arch/arm/include/asm/xenomai/time.h   | 5 +++++
 lib/cobalt/arch/arm64/include/asm/xenomai/time.h | 5 +++++
 lib/cobalt/arch/x86/include/asm/xenomai/time.h   | 5 +++++
 3 files changed, 15 insertions(+)

diff --git a/lib/cobalt/arch/arm/include/asm/xenomai/time.h b/lib/cobalt/arch/arm/include/asm/xenomai/time.h
index 34df7e9df..1b4947b2d 100644
--- a/lib/cobalt/arch/arm/include/asm/xenomai/time.h
+++ b/lib/cobalt/arch/arm/include/asm/xenomai/time.h
@@ -11,6 +11,11 @@
 #define _LIB_COBALT_ARM_TIME_H
 
 #define COBALT_VDSO_VERSION	"LINUX_2.6"
+
+#ifdef __USE_TIME_BITS64
+#define COBALT_VDSO_GETTIME	"__vdso_clock_gettime64"
+#else
 #define COBALT_VDSO_GETTIME	"__vdso_clock_gettime"
+#endif
 
 #endif /* !_LIB_COBALT_ARM_TIME_H */
diff --git a/lib/cobalt/arch/arm64/include/asm/xenomai/time.h b/lib/cobalt/arch/arm64/include/asm/xenomai/time.h
index d0dad6d88..9577aa773 100644
--- a/lib/cobalt/arch/arm64/include/asm/xenomai/time.h
+++ b/lib/cobalt/arch/arm64/include/asm/xenomai/time.h
@@ -11,6 +11,11 @@
 #define _LIB_COBALT_ARM64_TIME_H
 
 #define COBALT_VDSO_VERSION	"LINUX_2.6.39"
+
+#ifdef __USE_TIME_BITS64
+#define COBALT_VDSO_GETTIME	"__vdso_clock_gettime64"
+#else
 #define COBALT_VDSO_GETTIME	"__kernel_clock_gettime"
+#endif
 
 #endif /* !_LIB_COBALT_ARM64_TIME_H */
diff --git a/lib/cobalt/arch/x86/include/asm/xenomai/time.h b/lib/cobalt/arch/x86/include/asm/xenomai/time.h
index 693be8736..18eb76697 100644
--- a/lib/cobalt/arch/x86/include/asm/xenomai/time.h
+++ b/lib/cobalt/arch/x86/include/asm/xenomai/time.h
@@ -11,6 +11,11 @@
 #define _LIB_COBALT_X86_TIME_H
 
 #define COBALT_VDSO_VERSION	"LINUX_2.6"
+
+#ifdef __USE_TIME_BITS64
+#define COBALT_VDSO_GETTIME	"__vdso_clock_gettime64"
+#else
 #define COBALT_VDSO_GETTIME	"__vdso_clock_gettime"
+#endif
 
 #endif /* !_LIB_COBALT_X86_TIME_H */

-- 
2.39.2


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

* [PATCH 3/7] y2038: testsuite/clocktest: Fix reading of reference clock
  2023-08-11  7:37 [PATCH 0/7] y2038: Finalize and enable y2038 support Florian Bezdeka
  2023-08-11  7:37 ` [PATCH 1/7] y2038: kernel/drivers: Implement SO_RCVTIMEO_NEW and SO_SNDTIMEO_NEW Florian Bezdeka
  2023-08-11  7:37 ` [PATCH 2/7] y2038: lib/cobalt: Switch vdso to gettime64 Florian Bezdeka
@ 2023-08-11  7:37 ` Florian Bezdeka
  2023-08-11  7:37 ` [PATCH 4/7] y2038: build: Introduce new build parameter --disable-y2038 Florian Bezdeka
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-11  7:37 UTC (permalink / raw)
  To: xenomai, jan.kiszka; +Cc: Florian Bezdeka

With y2038 support enabled the wrong syscall was triggered for reading
the reference clock. struct timeval is "auto-converted" to time64_t so
we have to call the time64 based syscall as well.

There is no gettimeofday64 syscall so we have to migrate to
clock_gettime using CLOCK_REALTIME.

Old output:
CPU      ToD offset [us] ToD drift [us/s]      warps max delta [us]
--- -------------------- ---------------- ---------- --------------
  0                  0.0            0.000          0            0.0
  0   1009065219904768.5     -1000000.000          0            0.0
  0    715530549306452.6     -1000000.000          0            0.0

New output:
CPU      ToD offset [us] ToD drift [us/s]      warps max delta [us]
--- -------------------- ---------------- ---------- --------------
  0                  1.8           -5.803          0            0.0
  1                  0.0            0.000          0            0.0

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 testsuite/clocktest/clocktest.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/testsuite/clocktest/clocktest.c b/testsuite/clocktest/clocktest.c
index c524f42fb..acf952de4 100644
--- a/testsuite/clocktest/clocktest.c
+++ b/testsuite/clocktest/clocktest.c
@@ -126,14 +126,19 @@ static inline uint64_t read_clock(clockid_t clock_id)
 
 static inline uint64_t read_reference_clock(void)
 {
-	struct timeval tv;
+	struct timespec ts;
 
 	/*
 	 * Make sure we do not pick the vsyscall variant. It won't
 	 * switch us into secondary mode and can easily deadlock.
 	 */
-	syscall(SYS_gettimeofday, &tv, NULL);
-	return tv.tv_usec * 1000ULL + tv.tv_sec * 1000000000ULL;
+#if __USE_TIME_BITS64
+	syscall(SYS_clock_gettime64, CLOCK_REALTIME, &ts);
+#else
+	syscall(SYS_clock_gettime, CLOCK_REALTIME, &ts);
+#endif
+
+	return ts.tv_nsec + ts.tv_sec * 1000000000ULL;
 }
 
 static void check_reference(struct per_cpu_data *per_cpu_data)

-- 
2.39.2


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

* [PATCH 4/7] y2038: build: Introduce new build parameter --disable-y2038
  2023-08-11  7:37 [PATCH 0/7] y2038: Finalize and enable y2038 support Florian Bezdeka
                   ` (2 preceding siblings ...)
  2023-08-11  7:37 ` [PATCH 3/7] y2038: testsuite/clocktest: Fix reading of reference clock Florian Bezdeka
@ 2023-08-11  7:37 ` Florian Bezdeka
  2023-08-11 15:06   ` Jan Kiszka
  2023-08-11  7:37 ` [PATCH 5/7] y2038: lib/cobalt: Add additional time64_t related function wrappers Florian Bezdeka
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-11  7:37 UTC (permalink / raw)
  To: xenomai, jan.kiszka; +Cc: Florian Bezdeka

The new --disable-y2038 build parameter will be used to disable
additional function wrapping when the architecture we build for is
affected by the y2038 problem.

The default value is "no" so y2038 support is enabled by default.

If --disable-y2038 is given for an architecture that is not affected it
will be ignored.

CONFIG_XENO_LIBS_Y2038 will be set to 1 if the following conditions
are met:
  - y2038 support was requested (default, no --disable-y2038 given)
  - the target platform is affected by the y2038 problem
  - glibc is used as libc
  - glibc has y2038 support (glibc >= 2.34)

CONFIG_XENO_LIBS_Y2038 will be used later to add necessary glibc
wrappers.

If y2038 support was requested and is available in glibc the CFLAGS
-D_TIME_BITS=64 and -D_FILE_OFFSET_BITS=64 will be added to
affect all compile units.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 configure.ac | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/configure.ac b/configure.ac
index a601f94cd..dade7e9d7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -138,19 +138,23 @@ case "$build_for" in
 	use_tls=yes
 	target_cpu_arch=x86
 	CONFIG_XENO_DEFAULT_PERIOD=100000
+	y2038_affected=yes
 	;;
  arm*-*)
 	target_cpu_arch=arm
 	CONFIG_XENO_DEFAULT_PERIOD=1000000
+	y2038_affected=yes
 	;;
  aarch64-*)
 	target_cpu_arch=arm64
 	CONFIG_XENO_DEFAULT_PERIOD=1000000
+	y2038_affected=no
 	;;
  x86_64-*|amd64-*)
 	use_tls=yes
 	target_cpu_arch=x86
 	CONFIG_XENO_DEFAULT_PERIOD=100000
+	y2038_affected=no
 	;;
  *)
 	if test $rtcore_type = cobalt; then
@@ -781,6 +785,49 @@ AC_ARG_ENABLE([tls],
 	    [use_tls=$enableval])
 AC_MSG_RESULT($use_tls)
 
+AC_MSG_CHECKING(whether glibc has y2038 support)
+AC_TRY_COMPILE([#include <features.h>],
+	[
+		#if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 34))
+			#error "No y2038 support"
+		#endif
+	],
+	glibc_has_y2038_support=yes,
+	glibc_has_y2038_support=no)
+AC_MSG_RESULT($glibc_has_y2038_support)
+
+AC_MSG_CHECKING(whether to enable y2038 support in Xenomai libraries)
+AC_ARG_ENABLE(y2038,
+	AC_HELP_STRING([--disable-y2038], [Disable y2038 support]),
+	[
+		CONFIG_XENO_LIBS_TIME64=no
+	],
+	[
+		if test "$y2038_affected" = "yes"; then
+			CONFIG_XENO_LIBS_TIME64="$glibc_has_y2038_support"
+		else
+			CONFIG_XENO_LIBS_TIME64=no
+		fi
+	])
+AC_MSG_RESULT(${CONFIG_XENO_LIBS_TIME64})
+
+if test "$CONFIG_XENO_LIBS_TIME64" = "yes"; then
+	AC_DEFINE(CONFIG_XENO_LIBS_TIME64,1,[config])
+	XENO_TIME64_CFLAGS="-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64"
+	XENO_USER_CFLAGS="$XENO_USER_CFLAGS $XENO_TIME64_CFLAGS"
+	XENO_USER_APP_CFLAGS="$XENO_USER_APP_CFLAGS $XENO_TIME64_CFLAGS"
+	AC_SUBST(CONFIG_XENO_LIBS_TIME64)
+else
+	if test "$y2038_affected" = "yes"; then
+		AC_MSG_WARN([You're affected by the time_t overflow in 2038])
+		if test "$glibc_has_y2038_support" = "yes"; then
+			AC_MSG_WARN([You should consider removing --disable-y2038])
+		fi
+	fi
+fi
+AM_CONDITIONAL(CONFIG_XENO_LIBS_TIME64,[test "$CONFIG_XENO_LIBS_TIME64" = "yes"])
+
+
 dnl Check whether the compiler supports the __thread keyword.
 if test "x$use_tls" != xno; then
 	AC_CACHE_CHECK([for __thread keyword], libc_cv_gcc_tls,

-- 
2.39.2


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

* [PATCH 5/7] y2038: lib/cobalt: Add additional time64_t related function wrappers
  2023-08-11  7:37 [PATCH 0/7] y2038: Finalize and enable y2038 support Florian Bezdeka
                   ` (3 preceding siblings ...)
  2023-08-11  7:37 ` [PATCH 4/7] y2038: build: Introduce new build parameter --disable-y2038 Florian Bezdeka
@ 2023-08-11  7:37 ` Florian Bezdeka
  2023-08-11  7:37 ` [PATCH 6/7] y2038: Route explicitly requested stdlib calls to time64 equivalents Florian Bezdeka
  2023-08-11  7:37 ` [PATCH 7/7] y2038: lib/cobalt/select: Fix __RT(select()) routing Florian Bezdeka
  6 siblings, 0 replies; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-11  7:37 UTC (permalink / raw)
  To: xenomai, jan.kiszka; +Cc: Florian Bezdeka

When requesting y2038 support from recent glibc versions some
preprocessor magic will happen. clock_nanosleep will be replaced by
__clock_nanosleep_time64 for example.

To fix up the necessary function wrapping that we need on linker level
we have to wrap all the necessary glibc symbols/functions again.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 configure.ac                            |  16 ++-
 lib/cobalt/Makefile.am                  |   7 ++
 lib/cobalt/cobalt-glibc-time64.wrappers |  23 ++++
 lib/cobalt/wrappers-time64.c            | 203 ++++++++++++++++++++++++++++++++
 scripts/xeno-config-cobalt.in           |   5 +
 5 files changed, 251 insertions(+), 3 deletions(-)

diff --git a/configure.ac b/configure.ac
index dade7e9d7..d6737a09f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -944,17 +944,27 @@ dnl in-tree executables which require POSIX symbol wrapping.
 
    modechk_wrappers="$topdir/lib/cobalt/modechk.wrappers"
    cobalt_wrappers="$topdir/lib/cobalt/cobalt.wrappers"
+   cobalt_wrappers_glibc_time64="$topdir/lib/cobalt/cobalt-glibc-time64.wrappers"
+   all_wrappers="$modechk_wrappers $cobalt_wrappers"
+
+   linker_flags="-Wl,@$modechk_wrappers -Wl,@$cobalt_wrappers"
+
+   if [[ "$CONFIG_XENO_LIBS_TIME64" = "yes" ]]; then
+      all_wrappers="$all_wrappers $cobalt_wrappers_glibc_time64"
+      linker_flags="$linker_flags -Wl,@$cobalt_wrappers_glibc_time64"
+   fi
+
    if [[ $ac_cv_ld_file_option = yes ]]; then
-	XENO_POSIX_WRAPPERS="-Wl,@$modechk_wrappers -Wl,@$cobalt_wrappers"
+	XENO_POSIX_WRAPPERS="$linker_flags"
    else
-	XENO_POSIX_WRAPPERS=`cat $modechk_wrappers $cobalt_wrappers | \
+	XENO_POSIX_WRAPPERS=`cat $all_wrappers | \
 			while read wrap_option symbol ; do \
 				echo -n "-Wl,$wrap_option,$symbol " ; \
 			done`
    fi
 
    AC_SUBST(XENO_POSIX_WRAPPERS)
-   AC_SUBST([CONFIG_STATUS_DEPENDENCIES], ["$modechk_wrappers $cobalt_wrappers"])
+   AC_SUBST([CONFIG_STATUS_DEPENDENCIES], ["$all_wrappers"])
 fi
 
 dnl Multi-library support.
diff --git a/lib/cobalt/Makefile.am b/lib/cobalt/Makefile.am
index 3159695b3..436399f21 100644
--- a/lib/cobalt/Makefile.am
+++ b/lib/cobalt/Makefile.am
@@ -38,6 +38,11 @@ libcobalt_la_SOURCES =		\
 	umm.c			\
 	wrappers.c
 
+if CONFIG_XENO_LIBS_TIME64
+libcobalt_la_SOURCES +=         \
+	wrappers-time64.c
+endif
+
 libcobalt_la_CPPFLAGS =			\
 	@XENO_COBALT_CFLAGS@		\
 	-I$(top_srcdir)/include/cobalt	\
@@ -59,10 +64,12 @@ AM_LIBTOOLFLAGS = --silent
 install-data-local:
 	$(mkinstalldirs) $(DESTDIR)$(libdir)
 	$(INSTALL_DATA) $(srcdir)/cobalt.wrappers $(DESTDIR)$(libdir)
+	$(INSTALL_DATA) $(srcdir)/cobalt-glibc-time64.wrappers $(DESTDIR)$(libdir)
 	$(INSTALL_DATA) $(srcdir)/modechk.wrappers $(DESTDIR)$(libdir)
 
 uninstall-local:
 	$(RM) $(DESTDIR)$(libdir)/cobalt.wrappers
+	$(RM) $(DESTDIR)$(libdir)/cobalt-glibc-time64.wrappers
 	$(RM) $(DESTDIR)$(libdir)/modechk.wrappers
 
 EXTRA_DIST = cobalt.wrappers modechk.wrappers
diff --git a/lib/cobalt/cobalt-glibc-time64.wrappers b/lib/cobalt/cobalt-glibc-time64.wrappers
new file mode 100644
index 000000000..0bf895ca9
--- /dev/null
+++ b/lib/cobalt/cobalt-glibc-time64.wrappers
@@ -0,0 +1,23 @@
+--wrap __sem_timedwait64
+--wrap __clock_gettime64
+--wrap __clock_settime64
+--wrap __clock_nanosleep_time64
+--wrap __clock_getres64
+--wrap __clock_adjtime64
+--wrap __pthread_mutex_timedlock64
+--wrap __mq_timedsend_time64
+--wrap __mq_timedreceive_time64
+--wrap __sigtimedwait64
+--wrap __recvmmsg64
+--wrap __pthread_cond_timedwait64
+--wrap __timer_settime64
+--wrap __timer_gettime64
+--wrap __timerfd_settime64
+--wrap __timerfd_gettime64
+--wrap __setsockopt64
+--wrap __getsockopt64
+--wrap __select64
+--wrap __ioctl_time64
+--wrap __gettimeofday64
+--wrap __time64
+--wrap __nanosleep64
diff --git a/lib/cobalt/wrappers-time64.c b/lib/cobalt/wrappers-time64.c
new file mode 100644
index 000000000..4a3ac44dc
--- /dev/null
+++ b/lib/cobalt/wrappers-time64.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: LGPL-2.0-or-later
+/*
+ * Copyright (c) Siemens AG 2023
+ *
+ * Authors:
+ *  Florian Bezdeka <florian.bezdeka@siemens.com>
+ */
+#include <asm/xenomai/syscall.h>
+#include <cobalt/mqueue.h>
+#include <cobalt/pthread.h>
+#include <cobalt/semaphore.h>
+#include <cobalt/signal.h>
+#include <cobalt/sys/ioctl.h>
+#include <cobalt/sys/select.h>
+#include <cobalt/sys/socket.h>
+#include <cobalt/sys/time.h>
+#include <cobalt/sys/timerfd.h>
+
+#include <errno.h>
+#include <time.h>
+#include <stdarg.h>
+
+COBALT_IMPL(int, __sem_timedwait64,
+	    (sem_t *sem, const struct timespec *abs_timeout))
+{
+	return __WRAP(sem_timedwait(sem, abs_timeout));
+}
+
+COBALT_IMPL(int, __clock_gettime64, (clockid_t clock_id, struct timespec *tp))
+{
+	return __WRAP(clock_gettime(clock_id, tp));
+}
+
+COBALT_IMPL(int, __clock_settime64,
+	    (clockid_t clock_id, const struct timespec *tp))
+{
+	return __WRAP(clock_settime(clock_id, tp));
+}
+
+COBALT_IMPL(int, __clock_nanosleep_time64,
+	    (clockid_t clock_id, int flags, const struct timespec *rqtp,
+	     struct timespec *rmtp))
+{
+	return __WRAP(clock_nanosleep(clock_id, flags, rqtp, rmtp));
+}
+
+COBALT_IMPL(int, __clock_getres64, (clockid_t clock_id, struct timespec *tp))
+{
+	return __WRAP(clock_getres(clock_id, tp));
+}
+
+COBALT_IMPL(int, __clock_adjtime64, (clockid_t clock_id, struct timex *tx))
+{
+	return __WRAP(clock_adjtime(clock_id, tx));
+}
+
+COBALT_IMPL(int, __pthread_mutex_timedlock64,
+	    (pthread_mutex_t *mutex, const struct timespec *to))
+{
+	return __WRAP(pthread_mutex_timedlock(mutex, to));
+}
+
+COBALT_IMPL(int, __mq_timedsend_time64,
+	    (mqd_t q, const char *buffer, size_t len, unsigned int prio,
+	     const struct timespec *timeout))
+{
+	return __WRAP(mq_timedsend(q, buffer, len, prio, timeout));
+}
+
+COBALT_IMPL(ssize_t, __mq_timedreceive_time64,
+	    (mqd_t q, char *__restrict__ buffer, size_t len,
+	     unsigned *__restrict__ prio,
+	     const struct timespec *__restrict__ timeout))
+{
+	return __WRAP(mq_timedreceive(q, buffer, len, prio, timeout));
+}
+
+COBALT_IMPL(int, __sigtimedwait64,
+	    (const sigset_t *set, siginfo_t *si,
+	     const struct timespec *timeout))
+{
+	return __WRAP(sigtimedwait(set, si, timeout));
+}
+
+COBALT_IMPL(int, __recvmmsg64,
+	    (int fd, struct mmsghdr *msgvec, unsigned int vlen,
+	     unsigned int flags, struct timespec *timeout))
+{
+	return __WRAP(recvmmsg(fd, msgvec, vlen, flags, timeout));
+}
+
+COBALT_IMPL(int, __pthread_cond_timedwait64,
+	    (pthread_cond_t *cond, pthread_mutex_t *mutex,
+	     const struct timespec *abstime))
+{
+	return __WRAP(pthread_cond_timedwait(cond, mutex, abstime));
+}
+
+COBALT_IMPL(int, __timer_settime64,
+	    (timer_t timerid, int flags,
+	     const struct itimerspec *__restrict__ value,
+	     struct itimerspec *__restrict__ ovalue))
+{
+	return __WRAP(timer_settime(timerid, flags, value, ovalue));
+}
+
+COBALT_IMPL(int, __timer_gettime64, (timer_t timerid, struct itimerspec *value))
+{
+	return __WRAP(timer_gettime(timerid, value));
+}
+
+COBALT_IMPL(int, __timerfd_settime64,
+	    (int fd, int flags, const struct itimerspec *new_value,
+	     struct itimerspec *old_value))
+{
+	return __WRAP(timerfd_settime(fd, flags, new_value, old_value));
+}
+
+COBALT_IMPL(int, __timerfd_gettime64, (int fd, struct itimerspec *curr_value))
+{
+	return __WRAP(timerfd_gettime(fd, curr_value));
+}
+
+COBALT_IMPL(int, __getsockopt64,
+	    (int fd, int level, int optname, void *optval, socklen_t *optlen))
+{
+	return __WRAP(getsockopt(fd, level, optname, optval, optlen));
+}
+
+COBALT_IMPL(int, __setsockopt64,
+	    (int fd, int level, int optname, const void *optval,
+	     socklen_t optlen))
+{
+	return __WRAP(setsockopt(fd, level, optname, optval, optlen));
+}
+
+COBALT_IMPL(int, __ioctl_time64, (int fd, unsigned int request, ...))
+{
+	va_list ap;
+	void *arg;
+
+	va_start(ap, request);
+	arg = va_arg(ap, void *);
+	va_end(ap);
+
+	return __WRAP(ioctl(fd, request, arg));
+}
+
+/*
+ * The y2038 wrapper for select() is a little different:
+ * There is no y2038 safe syscall for select() itself, but we have pselect()
+ * without signal support.
+ */
+COBALT_IMPL(int, __select64,
+	    (int __nfds, fd_set *__restrict __readfds,
+	     fd_set *__restrict __writefds, fd_set *__restrict __exceptfds,
+	     struct timeval *__restrict __timeout))
+{
+	struct timespec to;
+	int err, oldtype;
+
+	if (__timeout) {
+		to.tv_sec = __timeout->tv_sec;
+		to.tv_nsec = __timeout->tv_usec * 1000;
+	}
+
+	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+	/*
+	 * Note: No sigmask here, we already reached the limit of 5
+	 * syscall parameters
+	 */
+	err = XENOMAI_SYSCALL5(sc_cobalt_pselect64, __nfds, __readfds,
+			       __writefds, __exceptfds, __timeout ? &to : NULL);
+
+	pthread_setcanceltype(oldtype, NULL);
+
+	if (err == -EADV || err == -EPERM || err == -ENOSYS)
+		err = __STD(__select64(__nfds, __readfds, __writefds,
+				       __exceptfds, __timeout));
+
+	if (err >= 0)
+		return err;
+
+	errno = -err;
+	return -1;
+}
+
+COBALT_IMPL(int, __gettimeofday64, (struct timeval *tv, struct timezone *tz))
+{
+	return __WRAP(gettimeofday(tv, tz));
+}
+
+COBALT_IMPL(time_t, __time64, (time_t *t))
+{
+	return __WRAP(time(t));
+}
+
+COBALT_IMPL(int, __nanosleep64,
+	    (const struct timespec *rqtp, struct timespec *rmtp))
+{
+	return __WRAP(nanosleep(rqtp, rmtp));
+}
diff --git a/scripts/xeno-config-cobalt.in b/scripts/xeno-config-cobalt.in
index a093779b9..46b6c11b9 100644
--- a/scripts/xeno-config-cobalt.in
+++ b/scripts/xeno-config-cobalt.in
@@ -20,6 +20,7 @@ XENO_COBALT_LDFLAGS="-L${staging}${libdir} -lcobalt"
 XENO_POSIX_LDFLAGS="-lpthread -lrt @XENO_USER_APP_LDFLAGS@"
 XENO_LIBRARY_DIR="${staging}${libdir}"
 LD_FILE_OPTION="@LD_FILE_OPTION@"
+CONFIG_XENO_LIBS_TIME64="@CONFIG_XENO_LIBS_TIME64@"
 
 unset skin_list compat codegen
 
@@ -252,6 +253,10 @@ if test x$do_ldflags = xy; then
 	case "$skin" in
 	    posix|rtdm)
 		ldflags="`dump_wrappers cobalt.wrappers` $ldflags"
+
+		if test "$CONFIG_XENO_LIBS_TIME64" = "yes"; then
+			ldflags="$(dump_wrappers cobalt-glibc-time64.wrappers) $ldflags"
+		fi
 		;;
 	    cobalt)
 		# do NOT wrap POSIX symbols in application code with

-- 
2.39.2


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

* [PATCH 6/7] y2038: Route explicitly requested stdlib calls to time64 equivalents
  2023-08-11  7:37 [PATCH 0/7] y2038: Finalize and enable y2038 support Florian Bezdeka
                   ` (4 preceding siblings ...)
  2023-08-11  7:37 ` [PATCH 5/7] y2038: lib/cobalt: Add additional time64_t related function wrappers Florian Bezdeka
@ 2023-08-11  7:37 ` Florian Bezdeka
  2023-08-11 14:57   ` Jan Kiszka
  2023-08-11  7:37 ` [PATCH 7/7] y2038: lib/cobalt/select: Fix __RT(select()) routing Florian Bezdeka
  6 siblings, 1 reply; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-11  7:37 UTC (permalink / raw)
  To: xenomai, jan.kiszka; +Cc: Florian Bezdeka

Xenomai provides the __STD() macro to request a service from Linux.
The code normally looks like below, taking clock_gettime() as example.

Note: Some y2038 safe services in glibc have the "_time64" suffix, while
others only have the 64 at the end. This is taken into account while
redirecting.

  int ret = __STD(clock_gettime(...));

For compat applications with available y2038 support in glibc the
preprocessor will generate the following code:

  int ret = __real_clock_gettime(...);

__real_clock_gettime() is the service taking 32 bit time_t. We have to
make sure that __real_clock_gettime() is redirected to
__real___clock_gettime64() service. The same applies to all other
affected services.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 include/cobalt/mqueue.h                | 11 ++++++++
 include/cobalt/pthread.h               | 10 ++++++++
 include/cobalt/semaphore.h             |  4 +++
 include/cobalt/signal.h                |  5 ++++
 include/cobalt/sys/ioctl.h             |  3 +++
 include/cobalt/sys/select.h            |  8 ++++++
 include/cobalt/sys/socket.h            | 15 +++++++++++
 include/cobalt/sys/time.h              |  4 +++
 include/cobalt/sys/timerfd.h           |  9 +++++++
 include/cobalt/time.h                  | 35 ++++++++++++++++++++++++++
 include/cobalt/wrappers.h              | 10 ++++++++
 testsuite/smokey/y2038/syscall-tests.c | 46 ++++++++++++++++++++++++++++++++++
 12 files changed, 160 insertions(+)

diff --git a/include/cobalt/mqueue.h b/include/cobalt/mqueue.h
index 496632dea..3da525a04 100644
--- a/include/cobalt/mqueue.h
+++ b/include/cobalt/mqueue.h
@@ -67,6 +67,17 @@ COBALT_DECL(ssize_t, mq_timedreceive(mqd_t q,
 COBALT_DECL(int, mq_notify(mqd_t q,
 			   const struct sigevent *evp));
 
+COBALT_DECL_TIME64(int, mq_timedsend,
+		   (mqd_t q, const char *buffer, size_t len, unsigned int prio,
+		    const struct timespec *timeout),
+		   __mq_timedsend64);
+
+COBALT_DECL_TIME64(int, mq_timedreceive,
+		   (mqd_t q, char *__restrict__ buffer, size_t len,
+		    unsigned *__restrict__ prio,
+		    const struct timespec *__restrict__ timeout),
+		   __mq_timedsend_time64);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/pthread.h b/include/cobalt/pthread.h
index 3e9bd4705..1caa54372 100644
--- a/include/cobalt/pthread.h
+++ b/include/cobalt/pthread.h
@@ -173,6 +173,16 @@ int pthread_attr_getpersonality_ex(const pthread_attr_ex_t *attr_ex,
 
 int pthread_attr_setpersonality_ex(pthread_attr_ex_t *attr_ex,
 				   int personality);
+
+COBALT_DECL_TIME64(int, pthread_mutex_timedlock,
+		   (pthread_mutex_t *mutex, const struct timespec *to),
+		   __pthread_mutex_timedlock64);
+
+COBALT_DECL_TIME64(int, pthread_cond_timedwait,
+		   (pthread_cond_t *cond, pthread_mutex_t *mutex,
+		    const struct timespec *abstime),
+		   __pthread_cond_timedwait64);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/semaphore.h b/include/cobalt/semaphore.h
index a7714fd34..20195094c 100644
--- a/include/cobalt/semaphore.h
+++ b/include/cobalt/semaphore.h
@@ -58,6 +58,10 @@ int sem_init_np(sem_t *sem,
 
 int sem_broadcast_np(sem_t *sem);
 
+COBALT_DECL_TIME64(int, sem_timedwait,
+		   (sem_t *sem, const struct timespec *abs_timeout),
+		   __sem_timedwait64);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/signal.h b/include/cobalt/signal.h
index 62694f93a..9082765d0 100644
--- a/include/cobalt/signal.h
+++ b/include/cobalt/signal.h
@@ -54,6 +54,11 @@ COBALT_DECL(int, kill(pid_t pid, int sig));
 COBALT_DECL(int, sigqueue(pid_t pid, int sig,
 			  const union sigval value));
 
+COBALT_DECL_TIME64(int, sigtimedwait,
+		   (const sigset_t *set, siginfo_t *si,
+		    const struct timespec *timeout),
+		   __sigtimedwait64);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/sys/ioctl.h b/include/cobalt/sys/ioctl.h
index 553aa566d..d7602ddf8 100644
--- a/include/cobalt/sys/ioctl.h
+++ b/include/cobalt/sys/ioctl.h
@@ -29,6 +29,9 @@ extern "C" {
 
 COBALT_DECL(int, ioctl(int fildes, unsigned int request, ...));
 
+COBALT_DECL_TIME64(int, ioctl, (int fd, unsigned int request, ...),
+		   __ioctl_time64);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/sys/select.h b/include/cobalt/sys/select.h
index 76e8476bb..8262e7764 100644
--- a/include/cobalt/sys/select.h
+++ b/include/cobalt/sys/select.h
@@ -31,6 +31,14 @@ COBALT_DECL(int, select(int __nfds, fd_set *__restrict __readfds,
 			fd_set *__restrict __writefds,
 			fd_set *__restrict __exceptfds,
 			struct timeval *__restrict __timeout));
+
+COBALT_DECL_TIME64(int, select,
+		   (int __nfds, fd_set *__restrict __readfds,
+		    fd_set *__restrict __writefds,
+		    fd_set *__restrict __exceptfds,
+		    struct timeval *__restrict __timeout),
+		   __select64);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/sys/socket.h b/include/cobalt/sys/socket.h
index 156b49356..d16843877 100644
--- a/include/cobalt/sys/socket.h
+++ b/include/cobalt/sys/socket.h
@@ -81,6 +81,21 @@ COBALT_DECL(int, getpeername(int fd, struct sockaddr *name,
 
 COBALT_DECL(int, shutdown(int fd, int how));
 
+COBALT_DECL_TIME64(int, recvmmsg,
+		   (int fd, struct mmsghdr *msgvec, unsigned int vlen,
+		    unsigned int flags, struct timespec *timeout),
+		   __recvmmsg64);
+
+COBALT_DECL_TIME64(int, getsockopt,
+		   (int fd, int level, int optname, void *optval,
+		    socklen_t *optlen),
+		   __getsockopt64);
+
+COBALT_DECL_TIME64(int, setsockopt,
+		   (int fd, int level, int optname, const void *optval,
+		    socklen_t optlen),
+		   __setsockopt64);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/sys/time.h b/include/cobalt/sys/time.h
index 38f5a34b6..d3bd9f1f5 100644
--- a/include/cobalt/sys/time.h
+++ b/include/cobalt/sys/time.h
@@ -32,6 +32,10 @@ extern "C" {
 COBALT_DECL(int, gettimeofday(struct timeval *tv,
 			      struct timezone *tz));
 
+COBALT_DECL_TIME64(int, gettimeofday,
+		   (struct timeval *tv, struct timezone *tz),
+		   __gettimeofday64);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/sys/timerfd.h b/include/cobalt/sys/timerfd.h
index a7df836e6..109409cf7 100644
--- a/include/cobalt/sys/timerfd.h
+++ b/include/cobalt/sys/timerfd.h
@@ -35,6 +35,15 @@ COBALT_DECL(int, timerfd_settime(int fd, int flags,
 
 COBALT_DECL(int, timerfd_gettime(int fd, struct itimerspec *curr_value));
 
+COBALT_DECL_TIME64(int, timerfd_settime,
+		   (int fd, int flags, const struct itimerspec *new_value,
+		    struct itimerspec *old_value),
+		   __timerfd_settime64);
+
+COBALT_DECL_TIME64(int, timerfd_gettime,
+		   (int fd, struct itimerspec *curr_value),
+		   __timerfd_gettime64);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/include/cobalt/time.h b/include/cobalt/time.h
index e3f355c61..38e43fb9e 100644
--- a/include/cobalt/time.h
+++ b/include/cobalt/time.h
@@ -70,6 +70,41 @@ COBALT_DECL(int, timer_gettime(timer_t timerid,
 
 COBALT_DECL(int, timer_getoverrun(timer_t timerid));
 
+COBALT_DECL_TIME64(int, clock_gettime,
+		   (clockid_t __clock_id, struct timespec *tp),
+		   __clock_gettime64);
+
+COBALT_DECL_TIME64(int, clock_settime,
+		   (clockid_t __clock_id, const struct timespec *tp),
+		   __clock_settime64);
+
+COBALT_DECL_TIME64(int, clock_nanosleep,
+		   (clockid_t clock_id, int flags, const struct timespec *rqtp,
+		    struct timespec *rmtp),
+		   __clock_nanosleep_time64);
+
+COBALT_DECL_TIME64(int, clock_getres, (clockid_t clock_id, struct timespec *tp),
+		   __clock_getres64);
+
+COBALT_DECL_TIME64(int, clock_adjtime, (clockid_t clock_id, struct timex *tx),
+		   __clock_adjtime64);
+
+COBALT_DECL_TIME64(int, timer_settime,
+		   (timer_t timerid, int flags,
+		    const struct itimerspec *__restrict__ value,
+		    struct itimerspec *__restrict__ ovalue),
+		   __timer_settime64);
+
+COBALT_DECL_TIME64(int, timer_gettime,
+		   (timer_t timerid, struct itimerspec *value),
+		   __timer_gettime64);
+
+COBALT_DECL_TIME64(time_t, time, (time_t *t), __time64);
+
+COBALT_DECL_TIME64(int, nanosleep,
+		   (const struct timespec *rqtp, struct timespec *rmtp),
+		   __nanosleep64);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/wrappers.h b/include/cobalt/wrappers.h
index 7e061caf9..fe3132127 100644
--- a/include/cobalt/wrappers.h
+++ b/include/cobalt/wrappers.h
@@ -32,6 +32,16 @@
 	__typeof__(T) __STD(P); \
 	__typeof__(T) __WRAP(P)
 
+#if __USE_TIME_BITS64
+/*
+ * Make __STD() usable in combination with time64_t related services.
+ */
+#define COBALT_DECL_TIME64(T, F, I, A)                                         \
+	extern T __REDIRECT_NTH(__STD(F), I, __real_##A)
+#else
+#define COBALT_DECL_TIME64(T, F, I, A)
+#endif
+
 /*
  * 
  * Each "foo" Cobalt routine shadowing a POSIX service may be
diff --git a/testsuite/smokey/y2038/syscall-tests.c b/testsuite/smokey/y2038/syscall-tests.c
index 0c7de5216..45508641e 100644
--- a/testsuite/smokey/y2038/syscall-tests.c
+++ b/testsuite/smokey/y2038/syscall-tests.c
@@ -1613,6 +1613,48 @@ out:
 	return test_pselect64_interruption();
 }
 
+static int test_function_wrapping(void)
+{
+#ifndef __USE_TIME_BITS64
+	/*
+	 * We're testing some functions here that are wrapped only for 32 bit
+	 * applications with y2038 support enabled. If that's not the case we
+	 * can simply bail out and simulate success.
+	 */
+	return 0;
+#endif
+	struct timespec ts64 = { 0 };
+	int ret;
+
+	/*
+	 * If the nsec part of ts64 is still 0 it's a good indication that our
+	 * function wrapping does not work as expected. We retry up to three
+	 * times to avoid shaky test results.
+	 *
+	 * __STD(clock_gettime()) is replaced with
+	 * __real_clock_gettime() by the preprocessor. If
+	 * __real_clock_gettime() is not properly redirected by the use of
+	 * COBALT_DECL_TIME64() (linker magic) we will end up in the glibc
+	 * implementation with "native" time_t.
+	 */
+	for (int i = 0; i < 3; i++) {
+		ret = smokey_check_errno(
+			__STD(clock_gettime(CLOCK_REALTIME, &ts64)));
+		if (ret)
+			return ret;
+
+		if (ts64.tv_nsec != 0)
+			break;
+
+		if (i == 2) {
+			smokey_warning("Function wrapping seems broken.");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int check_kernel_version(void)
 {
 	int ret, major, minor;
@@ -1722,5 +1764,9 @@ static int run_y2038(struct smokey_test *t, int argc, char *const argv[])
 	if (ret)
 		return ret;
 
+	ret = test_function_wrapping();
+	if (ret)
+		return ret;
+
 	return 0;
 }

-- 
2.39.2


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

* [PATCH 7/7] y2038: lib/cobalt/select: Fix __RT(select()) routing
  2023-08-11  7:37 [PATCH 0/7] y2038: Finalize and enable y2038 support Florian Bezdeka
                   ` (5 preceding siblings ...)
  2023-08-11  7:37 ` [PATCH 6/7] y2038: Route explicitly requested stdlib calls to time64 equivalents Florian Bezdeka
@ 2023-08-11  7:37 ` Florian Bezdeka
  2023-08-11 15:07   ` Jan Kiszka
  6 siblings, 1 reply; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-11  7:37 UTC (permalink / raw)
  To: xenomai, jan.kiszka; +Cc: Florian Bezdeka

Some parts of the testsuite use the __RT() macro to make clear that the
Xenomai implementation is called instead of the Linux service.

Code:
  __RT(select(...)

Result after preprocessor:
  __cobalt_select(...)

In case y2038 support has been requested (default) by 32 bit
applications the Xenomai select() implementation will be called instead
of the __select64(). Catch that case and wire it up to our limited
pselect64() implementation.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 lib/cobalt/select.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/lib/cobalt/select.c b/lib/cobalt/select.c
index 7727012c7..d2897066b 100644
--- a/lib/cobalt/select.c
+++ b/lib/cobalt/select.c
@@ -27,6 +27,20 @@ COBALT_IMPL(int, select, (int __nfds, fd_set *__restrict __readfds,
 			  fd_set *__restrict __exceptfds,
 			  struct timeval *__restrict __timeout))
 {
+#if __USE_TIME_BITS64
+	/* Might be called by __RT(select()) only. select() - without __RT() -
+	 * will be redirected to __select64(). Catch that special case here and
+	 * forward it to our __select64() wrapper - which might be overwritten
+	 * by application code.
+	 */
+	int __wrap___select64(int __nfds, fd_set *__restrict __readfds,
+			      fd_set *__restrict __writefds,
+			      fd_set *__restrict __exceptfds,
+			      struct timeval *__restrict __timeout);
+
+	return __wrap___select64(__nfds, __readfds, __writefds, __exceptfds,
+				 __timeout);
+#else
 	int err, oldtype;
 
 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
@@ -45,4 +59,5 @@ COBALT_IMPL(int, select, (int __nfds, fd_set *__restrict __readfds,
 
 	errno = -err;
 	return -1;
+#endif
 }

-- 
2.39.2


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

* Re: [PATCH 6/7] y2038: Route explicitly requested stdlib calls to time64 equivalents
  2023-08-11  7:37 ` [PATCH 6/7] y2038: Route explicitly requested stdlib calls to time64 equivalents Florian Bezdeka
@ 2023-08-11 14:57   ` Jan Kiszka
  2023-08-15  9:19     ` Florian Bezdeka
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Kiszka @ 2023-08-11 14:57 UTC (permalink / raw)
  To: Florian Bezdeka, xenomai

On 11.08.23 09:37, Florian Bezdeka wrote:
> Xenomai provides the __STD() macro to request a service from Linux.
> The code normally looks like below, taking clock_gettime() as example.
> 
> Note: Some y2038 safe services in glibc have the "_time64" suffix, while
> others only have the 64 at the end. This is taken into account while
> redirecting.
> 
>   int ret = __STD(clock_gettime(...));
> 
> For compat applications with available y2038 support in glibc the
> preprocessor will generate the following code:
> 
>   int ret = __real_clock_gettime(...);
> 
> __real_clock_gettime() is the service taking 32 bit time_t. We have to
> make sure that __real_clock_gettime() is redirected to
> __real___clock_gettime64() service. The same applies to all other
> affected services.
> 
> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> ---
>  include/cobalt/mqueue.h                | 11 ++++++++
>  include/cobalt/pthread.h               | 10 ++++++++
>  include/cobalt/semaphore.h             |  4 +++
>  include/cobalt/signal.h                |  5 ++++
>  include/cobalt/sys/ioctl.h             |  3 +++
>  include/cobalt/sys/select.h            |  8 ++++++
>  include/cobalt/sys/socket.h            | 15 +++++++++++
>  include/cobalt/sys/time.h              |  4 +++
>  include/cobalt/sys/timerfd.h           |  9 +++++++
>  include/cobalt/time.h                  | 35 ++++++++++++++++++++++++++
>  include/cobalt/wrappers.h              | 10 ++++++++
>  testsuite/smokey/y2038/syscall-tests.c | 46 ++++++++++++++++++++++++++++++++++
>  12 files changed, 160 insertions(+)
> 
> diff --git a/include/cobalt/mqueue.h b/include/cobalt/mqueue.h
> index 496632dea..3da525a04 100644
> --- a/include/cobalt/mqueue.h
> +++ b/include/cobalt/mqueue.h
> @@ -67,6 +67,17 @@ COBALT_DECL(ssize_t, mq_timedreceive(mqd_t q,
>  COBALT_DECL(int, mq_notify(mqd_t q,
>  			   const struct sigevent *evp));
>  
> +COBALT_DECL_TIME64(int, mq_timedsend,
> +		   (mqd_t q, const char *buffer, size_t len, unsigned int prio,
> +		    const struct timespec *timeout),
> +		   __mq_timedsend64);
> +
> +COBALT_DECL_TIME64(int, mq_timedreceive,
> +		   (mqd_t q, char *__restrict__ buffer, size_t len,
> +		    unsigned *__restrict__ prio,
> +		    const struct timespec *__restrict__ timeout),
> +		   __mq_timedsend_time64);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/cobalt/pthread.h b/include/cobalt/pthread.h
> index 3e9bd4705..1caa54372 100644
> --- a/include/cobalt/pthread.h
> +++ b/include/cobalt/pthread.h
> @@ -173,6 +173,16 @@ int pthread_attr_getpersonality_ex(const pthread_attr_ex_t *attr_ex,
>  
>  int pthread_attr_setpersonality_ex(pthread_attr_ex_t *attr_ex,
>  				   int personality);
> +
> +COBALT_DECL_TIME64(int, pthread_mutex_timedlock,
> +		   (pthread_mutex_t *mutex, const struct timespec *to),
> +		   __pthread_mutex_timedlock64);
> +
> +COBALT_DECL_TIME64(int, pthread_cond_timedwait,
> +		   (pthread_cond_t *cond, pthread_mutex_t *mutex,
> +		    const struct timespec *abstime),
> +		   __pthread_cond_timedwait64);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/cobalt/semaphore.h b/include/cobalt/semaphore.h
> index a7714fd34..20195094c 100644
> --- a/include/cobalt/semaphore.h
> +++ b/include/cobalt/semaphore.h
> @@ -58,6 +58,10 @@ int sem_init_np(sem_t *sem,
>  
>  int sem_broadcast_np(sem_t *sem);
>  
> +COBALT_DECL_TIME64(int, sem_timedwait,
> +		   (sem_t *sem, const struct timespec *abs_timeout),
> +		   __sem_timedwait64);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/cobalt/signal.h b/include/cobalt/signal.h
> index 62694f93a..9082765d0 100644
> --- a/include/cobalt/signal.h
> +++ b/include/cobalt/signal.h
> @@ -54,6 +54,11 @@ COBALT_DECL(int, kill(pid_t pid, int sig));
>  COBALT_DECL(int, sigqueue(pid_t pid, int sig,
>  			  const union sigval value));
>  
> +COBALT_DECL_TIME64(int, sigtimedwait,
> +		   (const sigset_t *set, siginfo_t *si,
> +		    const struct timespec *timeout),
> +		   __sigtimedwait64);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/cobalt/sys/ioctl.h b/include/cobalt/sys/ioctl.h
> index 553aa566d..d7602ddf8 100644
> --- a/include/cobalt/sys/ioctl.h
> +++ b/include/cobalt/sys/ioctl.h
> @@ -29,6 +29,9 @@ extern "C" {
>  
>  COBALT_DECL(int, ioctl(int fildes, unsigned int request, ...));
>  
> +COBALT_DECL_TIME64(int, ioctl, (int fd, unsigned int request, ...),
> +		   __ioctl_time64);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/cobalt/sys/select.h b/include/cobalt/sys/select.h
> index 76e8476bb..8262e7764 100644
> --- a/include/cobalt/sys/select.h
> +++ b/include/cobalt/sys/select.h
> @@ -31,6 +31,14 @@ COBALT_DECL(int, select(int __nfds, fd_set *__restrict __readfds,
>  			fd_set *__restrict __writefds,
>  			fd_set *__restrict __exceptfds,
>  			struct timeval *__restrict __timeout));
> +
> +COBALT_DECL_TIME64(int, select,
> +		   (int __nfds, fd_set *__restrict __readfds,
> +		    fd_set *__restrict __writefds,
> +		    fd_set *__restrict __exceptfds,
> +		    struct timeval *__restrict __timeout),
> +		   __select64);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/cobalt/sys/socket.h b/include/cobalt/sys/socket.h
> index 156b49356..d16843877 100644
> --- a/include/cobalt/sys/socket.h
> +++ b/include/cobalt/sys/socket.h
> @@ -81,6 +81,21 @@ COBALT_DECL(int, getpeername(int fd, struct sockaddr *name,
>  
>  COBALT_DECL(int, shutdown(int fd, int how));
>  
> +COBALT_DECL_TIME64(int, recvmmsg,
> +		   (int fd, struct mmsghdr *msgvec, unsigned int vlen,
> +		    unsigned int flags, struct timespec *timeout),
> +		   __recvmmsg64);
> +
> +COBALT_DECL_TIME64(int, getsockopt,
> +		   (int fd, int level, int optname, void *optval,
> +		    socklen_t *optlen),
> +		   __getsockopt64);
> +
> +COBALT_DECL_TIME64(int, setsockopt,
> +		   (int fd, int level, int optname, const void *optval,
> +		    socklen_t optlen),
> +		   __setsockopt64);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/cobalt/sys/time.h b/include/cobalt/sys/time.h
> index 38f5a34b6..d3bd9f1f5 100644
> --- a/include/cobalt/sys/time.h
> +++ b/include/cobalt/sys/time.h
> @@ -32,6 +32,10 @@ extern "C" {
>  COBALT_DECL(int, gettimeofday(struct timeval *tv,
>  			      struct timezone *tz));
>  
> +COBALT_DECL_TIME64(int, gettimeofday,
> +		   (struct timeval *tv, struct timezone *tz),
> +		   __gettimeofday64);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/cobalt/sys/timerfd.h b/include/cobalt/sys/timerfd.h
> index a7df836e6..109409cf7 100644
> --- a/include/cobalt/sys/timerfd.h
> +++ b/include/cobalt/sys/timerfd.h
> @@ -35,6 +35,15 @@ COBALT_DECL(int, timerfd_settime(int fd, int flags,
>  
>  COBALT_DECL(int, timerfd_gettime(int fd, struct itimerspec *curr_value));
>  
> +COBALT_DECL_TIME64(int, timerfd_settime,
> +		   (int fd, int flags, const struct itimerspec *new_value,
> +		    struct itimerspec *old_value),
> +		   __timerfd_settime64);
> +
> +COBALT_DECL_TIME64(int, timerfd_gettime,
> +		   (int fd, struct itimerspec *curr_value),
> +		   __timerfd_gettime64);
> +
>  #ifdef __cplusplus
>  }
>  #endif /* __cplusplus */
> diff --git a/include/cobalt/time.h b/include/cobalt/time.h
> index e3f355c61..38e43fb9e 100644
> --- a/include/cobalt/time.h
> +++ b/include/cobalt/time.h
> @@ -70,6 +70,41 @@ COBALT_DECL(int, timer_gettime(timer_t timerid,
>  
>  COBALT_DECL(int, timer_getoverrun(timer_t timerid));
>  
> +COBALT_DECL_TIME64(int, clock_gettime,
> +		   (clockid_t __clock_id, struct timespec *tp),
> +		   __clock_gettime64);
> +
> +COBALT_DECL_TIME64(int, clock_settime,
> +		   (clockid_t __clock_id, const struct timespec *tp),
> +		   __clock_settime64);
> +
> +COBALT_DECL_TIME64(int, clock_nanosleep,
> +		   (clockid_t clock_id, int flags, const struct timespec *rqtp,
> +		    struct timespec *rmtp),
> +		   __clock_nanosleep_time64);
> +
> +COBALT_DECL_TIME64(int, clock_getres, (clockid_t clock_id, struct timespec *tp),
> +		   __clock_getres64);
> +
> +COBALT_DECL_TIME64(int, clock_adjtime, (clockid_t clock_id, struct timex *tx),
> +		   __clock_adjtime64);
> +
> +COBALT_DECL_TIME64(int, timer_settime,
> +		   (timer_t timerid, int flags,
> +		    const struct itimerspec *__restrict__ value,
> +		    struct itimerspec *__restrict__ ovalue),
> +		   __timer_settime64);
> +
> +COBALT_DECL_TIME64(int, timer_gettime,
> +		   (timer_t timerid, struct itimerspec *value),
> +		   __timer_gettime64);
> +
> +COBALT_DECL_TIME64(time_t, time, (time_t *t), __time64);
> +
> +COBALT_DECL_TIME64(int, nanosleep,
> +		   (const struct timespec *rqtp, struct timespec *rmtp),
> +		   __nanosleep64);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/cobalt/wrappers.h b/include/cobalt/wrappers.h
> index 7e061caf9..fe3132127 100644
> --- a/include/cobalt/wrappers.h
> +++ b/include/cobalt/wrappers.h
> @@ -32,6 +32,16 @@
>  	__typeof__(T) __STD(P); \
>  	__typeof__(T) __WRAP(P)
>  
> +#if __USE_TIME_BITS64
> +/*
> + * Make __STD() usable in combination with time64_t related services.
> + */
> +#define COBALT_DECL_TIME64(T, F, I, A)                                         \
> +	extern T __REDIRECT_NTH(__STD(F), I, __real_##A)
> +#else
> +#define COBALT_DECL_TIME64(T, F, I, A)
> +#endif
> +
>  /*
>   * 
>   * Each "foo" Cobalt routine shadowing a POSIX service may be
> diff --git a/testsuite/smokey/y2038/syscall-tests.c b/testsuite/smokey/y2038/syscall-tests.c
> index 0c7de5216..45508641e 100644
> --- a/testsuite/smokey/y2038/syscall-tests.c
> +++ b/testsuite/smokey/y2038/syscall-tests.c
> @@ -1613,6 +1613,48 @@ out:
>  	return test_pselect64_interruption();
>  }
>  
> +static int test_function_wrapping(void)
> +{
> +#ifndef __USE_TIME_BITS64
> +	/*
> +	 * We're testing some functions here that are wrapped only for 32 bit
> +	 * applications with y2038 support enabled. If that's not the case we
> +	 * can simply bail out and simulate success.
> +	 */
> +	return 0;
> +#endif

Won't that cause warnings about unreachable code after the return? Let's
rather do an #else ... #endif here.

Jan

> +	struct timespec ts64 = { 0 };
> +	int ret;
> +
> +	/*
> +	 * If the nsec part of ts64 is still 0 it's a good indication that our
> +	 * function wrapping does not work as expected. We retry up to three
> +	 * times to avoid shaky test results.
> +	 *
> +	 * __STD(clock_gettime()) is replaced with
> +	 * __real_clock_gettime() by the preprocessor. If
> +	 * __real_clock_gettime() is not properly redirected by the use of
> +	 * COBALT_DECL_TIME64() (linker magic) we will end up in the glibc
> +	 * implementation with "native" time_t.
> +	 */
> +	for (int i = 0; i < 3; i++) {
> +		ret = smokey_check_errno(
> +			__STD(clock_gettime(CLOCK_REALTIME, &ts64)));
> +		if (ret)
> +			return ret;
> +
> +		if (ts64.tv_nsec != 0)
> +			break;
> +
> +		if (i == 2) {
> +			smokey_warning("Function wrapping seems broken.");
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static int check_kernel_version(void)
>  {
>  	int ret, major, minor;
> @@ -1722,5 +1764,9 @@ static int run_y2038(struct smokey_test *t, int argc, char *const argv[])
>  	if (ret)
>  		return ret;
>  
> +	ret = test_function_wrapping();
> +	if (ret)
> +		return ret;
> +
>  	return 0;
>  }
> 

-- 
Siemens AG, Technology
Linux Expert Center


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

* Re: [PATCH 4/7] y2038: build: Introduce new build parameter --disable-y2038
  2023-08-11  7:37 ` [PATCH 4/7] y2038: build: Introduce new build parameter --disable-y2038 Florian Bezdeka
@ 2023-08-11 15:06   ` Jan Kiszka
  2023-08-15  9:09     ` Florian Bezdeka
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Kiszka @ 2023-08-11 15:06 UTC (permalink / raw)
  To: Florian Bezdeka, xenomai

On 11.08.23 09:37, Florian Bezdeka wrote:
> The new --disable-y2038 build parameter will be used to disable
> additional function wrapping when the architecture we build for is
> affected by the y2038 problem.
> 
> The default value is "no" so y2038 support is enabled by default.
> 
> If --disable-y2038 is given for an architecture that is not affected it
> will be ignored.
> 
> CONFIG_XENO_LIBS_Y2038 will be set to 1 if the following conditions
> are met:
>   - y2038 support was requested (default, no --disable-y2038 given)
>   - the target platform is affected by the y2038 problem
>   - glibc is used as libc
>   - glibc has y2038 support (glibc >= 2.34)
> 
> CONFIG_XENO_LIBS_Y2038 will be used later to add necessary glibc
> wrappers.
> 
> If y2038 support was requested and is available in glibc the CFLAGS
> -D_TIME_BITS=64 and -D_FILE_OFFSET_BITS=64 will be added to
> affect all compile units.

So, in contrast to glibc which will support both legacy and time64 ABIs
at runtime, Xenomai is selecting this at built-time for ALL Xenomai
applications on a target system. Right?

Jan

-- 
Siemens AG, Technology
Linux Expert Center


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

* Re: [PATCH 7/7] y2038: lib/cobalt/select: Fix __RT(select()) routing
  2023-08-11  7:37 ` [PATCH 7/7] y2038: lib/cobalt/select: Fix __RT(select()) routing Florian Bezdeka
@ 2023-08-11 15:07   ` Jan Kiszka
  2023-08-15  9:18     ` Florian Bezdeka
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Kiszka @ 2023-08-11 15:07 UTC (permalink / raw)
  To: Florian Bezdeka, xenomai

On 11.08.23 09:37, Florian Bezdeka wrote:
> Some parts of the testsuite use the __RT() macro to make clear that the
> Xenomai implementation is called instead of the Linux service.
> 
> Code:
>   __RT(select(...)
> 
> Result after preprocessor:
>   __cobalt_select(...)
> 
> In case y2038 support has been requested (default) by 32 bit
> applications the Xenomai select() implementation will be called instead
> of the __select64(). Catch that case and wire it up to our limited
> pselect64() implementation.
> 
> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> ---
>  lib/cobalt/select.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/lib/cobalt/select.c b/lib/cobalt/select.c
> index 7727012c7..d2897066b 100644
> --- a/lib/cobalt/select.c
> +++ b/lib/cobalt/select.c
> @@ -27,6 +27,20 @@ COBALT_IMPL(int, select, (int __nfds, fd_set *__restrict __readfds,
>  			  fd_set *__restrict __exceptfds,
>  			  struct timeval *__restrict __timeout))
>  {
> +#if __USE_TIME_BITS64
> +	/* Might be called by __RT(select()) only. select() - without __RT() -
> +	 * will be redirected to __select64(). Catch that special case here and
> +	 * forward it to our __select64() wrapper - which might be overwritten
> +	 * by application code.
> +	 */
> +	int __wrap___select64(int __nfds, fd_set *__restrict __readfds,
> +			      fd_set *__restrict __writefds,
> +			      fd_set *__restrict __exceptfds,
> +			      struct timeval *__restrict __timeout);
> +
> +	return __wrap___select64(__nfds, __readfds, __writefds, __exceptfds,
> +				 __timeout);

Rather than taking a real call, can't we define a symbol alias?

> +#else
>  	int err, oldtype;
>  
>  	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
> @@ -45,4 +59,5 @@ COBALT_IMPL(int, select, (int __nfds, fd_set *__restrict __readfds,
>  
>  	errno = -err;
>  	return -1;
> +#endif
>  }
> 

Jan

-- 
Siemens AG, Technology
Linux Expert Center


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

* Re: [PATCH 4/7] y2038: build: Introduce new build parameter --disable-y2038
  2023-08-11 15:06   ` Jan Kiszka
@ 2023-08-15  9:09     ` Florian Bezdeka
  0 siblings, 0 replies; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-15  9:09 UTC (permalink / raw)
  To: Jan Kiszka, xenomai

On Fri, 2023-08-11 at 17:06 +0200, Jan Kiszka wrote:
> On 11.08.23 09:37, Florian Bezdeka wrote:
> > The new --disable-y2038 build parameter will be used to disable
> > additional function wrapping when the architecture we build for is
> > affected by the y2038 problem.
> > 
> > The default value is "no" so y2038 support is enabled by default.
> > 
> > If --disable-y2038 is given for an architecture that is not affected it
> > will be ignored.
> > 
> > CONFIG_XENO_LIBS_Y2038 will be set to 1 if the following conditions
> > are met:
> >   - y2038 support was requested (default, no --disable-y2038 given)
> >   - the target platform is affected by the y2038 problem
> >   - glibc is used as libc
> >   - glibc has y2038 support (glibc >= 2.34)
> > 
> > CONFIG_XENO_LIBS_Y2038 will be used later to add necessary glibc
> > wrappers.
> > 
> > If y2038 support was requested and is available in glibc the CFLAGS
> > -D_TIME_BITS=64 and -D_FILE_OFFSET_BITS=64 will be added to
> > affect all compile units.
> 
> So, in contrast to glibc which will support both legacy and time64 ABIs
> at runtime, Xenomai is selecting this at built-time for ALL Xenomai
> applications on a target system. Right?

Right. Is there a need/requirement for supporting both worlds in
Xenomai at runtime? The kernel infrastructure could stay as is but the
plumbing in libcobalt would have to evolve. The time64_t wrappers will
have to introduce separate code paths down to the syscall layer.

Florian

> 
> Jan
> 
> -- 
> Siemens AG, Technology
> Linux Expert Center


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

* Re: [PATCH 7/7] y2038: lib/cobalt/select: Fix __RT(select()) routing
  2023-08-11 15:07   ` Jan Kiszka
@ 2023-08-15  9:18     ` Florian Bezdeka
  0 siblings, 0 replies; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-15  9:18 UTC (permalink / raw)
  To: Jan Kiszka, xenomai

On Fri, 2023-08-11 at 17:07 +0200, Jan Kiszka wrote:
> On 11.08.23 09:37, Florian Bezdeka wrote:
> > Some parts of the testsuite use the __RT() macro to make clear that the
> > Xenomai implementation is called instead of the Linux service.
> > 
> > Code:
> >   __RT(select(...)
> > 
> > Result after preprocessor:
> >   __cobalt_select(...)
> > 
> > In case y2038 support has been requested (default) by 32 bit
> > applications the Xenomai select() implementation will be called instead
> > of the __select64(). Catch that case and wire it up to our limited
> > pselect64() implementation.
> > 
> > Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> > ---
> >  lib/cobalt/select.c | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> > 
> > diff --git a/lib/cobalt/select.c b/lib/cobalt/select.c
> > index 7727012c7..d2897066b 100644
> > --- a/lib/cobalt/select.c
> > +++ b/lib/cobalt/select.c
> > @@ -27,6 +27,20 @@ COBALT_IMPL(int, select, (int __nfds, fd_set *__restrict __readfds,
> >  			  fd_set *__restrict __exceptfds,
> >  			  struct timeval *__restrict __timeout))
> >  {
> > +#if __USE_TIME_BITS64
> > +	/* Might be called by __RT(select()) only. select() - without __RT() -
> > +	 * will be redirected to __select64(). Catch that special case here and
> > +	 * forward it to our __select64() wrapper - which might be overwritten
> > +	 * by application code.
> > +	 */
> > +	int __wrap___select64(int __nfds, fd_set *__restrict __readfds,
> > +			      fd_set *__restrict __writefds,
> > +			      fd_set *__restrict __exceptfds,
> > +			      struct timeval *__restrict __timeout);
> > +
> > +	return __wrap___select64(__nfds, __readfds, __writefds, __exceptfds,
> > +				 __timeout);
> 
> Rather than taking a real call, can't we define a symbol alias?

I tried but gave up after some hours ;-)

It has been some time, but some details I can remember:

The header where we publish the necessary wrappers for select() is
included by some libc headers, sys/types.h for example. When we start
working with aliases (__attribute__((alias(cname)))) we have to make
sure that the target symbol can be found. Otherwise we will end up with
"aliased to undefined symbol" compiler errors.

Compile units that use this header but do not directly contain the
implementation coming from wrappers-time64.c will fail to build - even
if they never call select().

We have at least lib/boilerplate/bootstrap.c that can no longer be
build. The same could happen to user applications.

If you have any idea how to fix this: Let me know.

Florian

> 
> > +#else
> >  	int err, oldtype;
> >  
> >  	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
> > @@ -45,4 +59,5 @@ COBALT_IMPL(int, select, (int __nfds, fd_set *__restrict __readfds,
> >  
> >  	errno = -err;
> >  	return -1;
> > +#endif
> >  }
> > 
> 
> Jan
> 
> -- 
> Siemens AG, Technology
> Linux Expert Center


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

* Re: [PATCH 6/7] y2038: Route explicitly requested stdlib calls to time64 equivalents
  2023-08-11 14:57   ` Jan Kiszka
@ 2023-08-15  9:19     ` Florian Bezdeka
  0 siblings, 0 replies; 14+ messages in thread
From: Florian Bezdeka @ 2023-08-15  9:19 UTC (permalink / raw)
  To: Jan Kiszka, xenomai

On Fri, 2023-08-11 at 16:57 +0200, Jan Kiszka wrote:
> > +static int test_function_wrapping(void)
> > +{
> > +#ifndef __USE_TIME_BITS64
> > +	/*
> > +	 * We're testing some functions here that are wrapped only for 32 bit
> > +	 * applications with y2038 support enabled. If that's not the case we
> > +	 * can simply bail out and simulate success.
> > +	 */
> > +	return 0;
> > +#endif
> 
> Won't that cause warnings about unreachable code after the return? Let's
> rather do an #else ... #endif here.

Will be part of v2. (It did not trigger the warning for some reason...)

Florian

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

end of thread, other threads:[~2023-08-15  9:20 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-11  7:37 [PATCH 0/7] y2038: Finalize and enable y2038 support Florian Bezdeka
2023-08-11  7:37 ` [PATCH 1/7] y2038: kernel/drivers: Implement SO_RCVTIMEO_NEW and SO_SNDTIMEO_NEW Florian Bezdeka
2023-08-11  7:37 ` [PATCH 2/7] y2038: lib/cobalt: Switch vdso to gettime64 Florian Bezdeka
2023-08-11  7:37 ` [PATCH 3/7] y2038: testsuite/clocktest: Fix reading of reference clock Florian Bezdeka
2023-08-11  7:37 ` [PATCH 4/7] y2038: build: Introduce new build parameter --disable-y2038 Florian Bezdeka
2023-08-11 15:06   ` Jan Kiszka
2023-08-15  9:09     ` Florian Bezdeka
2023-08-11  7:37 ` [PATCH 5/7] y2038: lib/cobalt: Add additional time64_t related function wrappers Florian Bezdeka
2023-08-11  7:37 ` [PATCH 6/7] y2038: Route explicitly requested stdlib calls to time64 equivalents Florian Bezdeka
2023-08-11 14:57   ` Jan Kiszka
2023-08-15  9:19     ` Florian Bezdeka
2023-08-11  7:37 ` [PATCH 7/7] y2038: lib/cobalt/select: Fix __RT(select()) routing Florian Bezdeka
2023-08-11 15:07   ` Jan Kiszka
2023-08-15  9:18     ` Florian Bezdeka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).