From: Philippe Gerum <[email protected]> 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 <[email protected]> --- 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
