[PATCH v2 4/9] cobalt/kernel: y2038: convert struct timex to __kernel_timex

Jan Kiszka jan.kiszka at siemens.com
Wed May 5 18:53:03 CEST 2021


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

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




More information about the Xenomai mailing list