Commit 3efca583 authored by Philippe Gerum's avatar Philippe Gerum Committed by Jan Kiszka
Browse files

cobalt/kernel: y2038: convert struct itimerspec to itimerspec64



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's avatarPhilippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka's avatarJan Kiszka <jan.kiszka@siemens.com>
parent ac8a0377
......@@ -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);
......
......@@ -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 */
......@@ -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 */
......
......@@ -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);
......
......@@ -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,
......
......@@ -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);
......
......@@ -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))
......
......@@ -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));
......
......@@ -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);
}
......@@ -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 */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment