From: Philippe Gerum <r...@xenomai.org>

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

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

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

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


Reply via email to