Module: xenomai-3
Branch: next
Commit: fde7cf60551f56e6d974ee057f4cc2edb068be0b
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=fde7cf60551f56e6d974ee057f4cc2edb068be0b

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon Feb 12 18:09:59 2018 +0100

cobalt/kernel: add clock_adjtime() syscall

---

 include/cobalt/kernel/clock.h      |   11 +++++++
 include/cobalt/kernel/compat.h     |    6 ++++
 include/cobalt/uapi/syscall.h      |    1 +
 kernel/cobalt/posix/clock.c        |   37 +++++++++++++++++++++
 kernel/cobalt/posix/clock.h        |    6 ++++
 kernel/cobalt/posix/compat.c       |   63 ++++++++++++++++++++++++++++++++++++
 kernel/cobalt/posix/syscall32.c    |   17 ++++++++++
 kernel/cobalt/posix/syscall32.h    |    4 +++
 kernel/cobalt/trace/cobalt-posix.h |   20 ++++++++++++
 9 files changed, 165 insertions(+)

diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
index bb56f52..bf03c59 100644
--- a/include/cobalt/kernel/clock.h
+++ b/include/cobalt/kernel/clock.h
@@ -53,6 +53,8 @@ struct xnclock {
                xnticks_t (*read_monotonic)(struct xnclock *clock);
                int (*set_time)(struct xnclock *clock,
                                const struct timespec *ts);
+               int (*adjust_time)(struct xnclock *clock,
+                                  struct timex *tx);
                xnsticks_t (*ns_to_ticks)(struct xnclock *clock,
                                          xnsticks_t ns);
                xnsticks_t (*ticks_to_ns)(struct xnclock *clock,
@@ -252,6 +254,15 @@ 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)
+{
+       if (clock->ops.adjust_time == NULL)
+               return -EOPNOTSUPP;
+
+       return clock->ops.adjust_time(clock, tx);
+}
+
 #ifdef CONFIG_SMP
 int xnclock_get_default_cpu(struct xnclock *clock, int cpu);
 #else
diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
index bb6c754..05754cb 100644
--- a/include/cobalt/kernel/compat.h
+++ b/include/cobalt/kernel/compat.h
@@ -104,6 +104,12 @@ int sys32_get_timeval(struct timeval *tv,
 int sys32_put_timeval(struct compat_timeval __user *ctv,
                      const struct timeval *tv);
 
+int sys32_get_timex(struct timex *tx,
+                   const struct compat_timex __user *ctx);
+
+int sys32_put_timex(struct compat_timex __user *ctx,
+                   const struct 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/syscall.h b/include/cobalt/uapi/syscall.h
index d246f0b..58f9c07 100644
--- a/include/cobalt/uapi/syscall.h
+++ b/include/cobalt/uapi/syscall.h
@@ -120,6 +120,7 @@
 #define sc_cobalt_ftrace_puts                  97
 #define sc_cobalt_recvmmsg                     98
 #define sc_cobalt_sendmmsg                     99
+#define sc_cobalt_clock_adjtime                        100
 
 #define __NR_COBALT_SYSCALLS                   128 /* Power of 2 */
 
diff --git a/kernel/cobalt/posix/clock.c b/kernel/cobalt/posix/clock.c
index 3ebf016..6ba389e 100644
--- a/kernel/cobalt/posix/clock.c
+++ b/kernel/cobalt/posix/clock.c
@@ -221,6 +221,27 @@ int __cobalt_clock_settime(clockid_t clock_id, const 
struct timespec *ts)
        return 0;
 }
 
+int __cobalt_clock_adjtime(clockid_t clock_id, struct timex *tx)
+{
+       int _ret, ret = 0;
+
+       switch (clock_id) {
+       case CLOCK_REALTIME:
+       case CLOCK_MONOTONIC:
+       case CLOCK_MONOTONIC_RAW:
+       case CLOCK_HOST_REALTIME:
+               return -EOPNOTSUPP;
+       default:
+               _ret = do_ext_clock(clock_id, adjust_time, ret, tx);
+               if (_ret || ret)
+                       return _ret ?: ret;
+       }
+
+       trace_cobalt_clock_adjtime(clock_id, tx);
+
+       return 0;
+}
+
 COBALT_SYSCALL(clock_settime, current,
               (clockid_t clock_id, const struct timespec __user *u_ts))
 {
@@ -232,6 +253,22 @@ COBALT_SYSCALL(clock_settime, current,
        return __cobalt_clock_settime(clock_id, &ts);
 }
 
+COBALT_SYSCALL(clock_adjtime, current,
+              (clockid_t clock_id, struct timex __user *u_tx))
+{
+       struct timex tx;
+       int ret;
+
+       if (cobalt_copy_from_user(&tx, u_tx, sizeof(tx)))
+               return -EFAULT;
+
+       ret = __cobalt_clock_adjtime(clock_id, &tx);
+       if (ret)
+               return ret;
+
+       return cobalt_copy_to_user(u_tx, &tx, sizeof(tx));
+}
+
 int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
                             const struct timespec *rqt,
                             struct timespec *rmt)
diff --git a/kernel/cobalt/posix/clock.h b/kernel/cobalt/posix/clock.h
index c77c3a5..0b06b93 100644
--- a/kernel/cobalt/posix/clock.h
+++ b/kernel/cobalt/posix/clock.h
@@ -88,6 +88,9 @@ int __cobalt_clock_gettime(clockid_t clock_id,
 int __cobalt_clock_settime(clockid_t clock_id,
                           const struct timespec *ts);
 
+int __cobalt_clock_adjtime(clockid_t clock_id,
+                          struct timex *tx);
+
 int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
                             const struct timespec *rqt,
                             struct timespec *rmt);
@@ -101,6 +104,9 @@ COBALT_SYSCALL_DECL(clock_gettime,
 COBALT_SYSCALL_DECL(clock_settime,
                    (clockid_t clock_id, const struct timespec __user *u_ts));
 
+COBALT_SYSCALL_DECL(clock_adjtime,
+                   (clockid_t clock_id, struct timex __user *u_tx));
+
 COBALT_SYSCALL_DECL(clock_nanosleep,
                    (clockid_t clock_id, int flags,
                     const struct timespec __user *u_rqt,
diff --git a/kernel/cobalt/posix/compat.c b/kernel/cobalt/posix/compat.c
index 3921510..d7195be 100644
--- a/kernel/cobalt/posix/compat.c
+++ b/kernel/cobalt/posix/compat.c
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 #include <linux/err.h>
+#include <linux/memory.h>
 #include <linux/module.h>
 #include <cobalt/kernel/compat.h>
 #include <asm/xenomai/syscall.h>
@@ -79,6 +80,68 @@ int sys32_put_timeval(struct compat_timeval __user *ctv,
 }
 EXPORT_SYMBOL_GPL(sys32_put_timeval);
 
+int sys32_get_timex(struct timex *tx,
+                   const struct compat_timex __user *ctx)
+{
+       memset(tx, 0, sizeof(*tx));
+
+       if (!access_rok(ctx, sizeof(*ctx)) ||
+           __xn_get_user(tx->modes, &ctx->modes) ||
+           __xn_get_user(tx->offset, &ctx->offset) ||
+           __xn_get_user(tx->freq, &ctx->freq) ||
+           __xn_get_user(tx->maxerror, &ctx->maxerror) ||
+           __xn_get_user(tx->esterror, &ctx->esterror) ||
+           __xn_get_user(tx->status, &ctx->status) ||
+           __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) ||
+           __xn_get_user(tx->shift, &ctx->shift) ||
+           __xn_get_user(tx->stabil, &ctx->stabil) ||
+           __xn_get_user(tx->jitcnt, &ctx->jitcnt) ||
+           __xn_get_user(tx->calcnt, &ctx->calcnt) ||
+           __xn_get_user(tx->errcnt, &ctx->errcnt) ||
+           __xn_get_user(tx->stbcnt, &ctx->stbcnt))
+         return -EFAULT;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sys32_get_timex);
+
+int sys32_put_timex(struct compat_timex __user *ctx,
+                   const struct timex *tx)
+{
+       if (!access_wok(ctx, sizeof(*ctx)) ||
+           __xn_put_user(tx->modes, &ctx->modes) ||
+           __xn_put_user(tx->offset, &ctx->offset) ||
+           __xn_put_user(tx->freq, &ctx->freq) ||
+           __xn_put_user(tx->maxerror, &ctx->maxerror) ||
+           __xn_put_user(tx->esterror, &ctx->esterror) ||
+           __xn_put_user(tx->status, &ctx->status) ||
+           __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) ||
+           __xn_put_user(tx->shift, &ctx->shift) ||
+           __xn_put_user(tx->stabil, &ctx->stabil) ||
+           __xn_put_user(tx->jitcnt, &ctx->jitcnt) ||
+           __xn_put_user(tx->calcnt, &ctx->calcnt) ||
+           __xn_put_user(tx->errcnt, &ctx->errcnt) ||
+           __xn_put_user(tx->stbcnt, &ctx->stbcnt))
+         return -EFAULT;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sys32_put_timex);
+
 ssize_t sys32_get_fdset(fd_set *fds, const compat_fd_set __user *cfds,
                        size_t cfdsize)
 {
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 93e5077..9559991 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -162,6 +162,23 @@ COBALT_SYSCALL32emu(clock_settime, current,
        return __cobalt_clock_settime(clock_id, &ts);
 }
 
+COBALT_SYSCALL32emu(clock_adjtime, current,
+                   (clockid_t clock_id, struct compat_timex __user *u_tx))
+{
+       struct timex tx;
+       int ret;
+
+       ret = sys32_get_timex(&tx, u_tx);
+       if (ret)
+               return ret;
+
+       ret = __cobalt_clock_adjtime(clock_id, &tx);
+       if (ret)
+               return ret;
+
+       return sys32_put_timex(u_tx, &tx);
+}
+
 COBALT_SYSCALL32emu(clock_nanosleep, nonrestartable,
                    (clockid_t clock_id, int flags,
                     const struct compat_timespec __user *u_rqt,
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index 730568c..5ba6513 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -57,6 +57,10 @@ COBALT_SYSCALL32emu_DECL(clock_settime,
                         (clockid_t clock_id,
                          const struct compat_timespec __user *u_ts));
 
+COBALT_SYSCALL32emu_DECL(clock_adjtime,
+                        (clockid_t clock_id,
+                         struct compat_timex __user *u_tx));
+
 COBALT_SYSCALL32emu_DECL(clock_nanosleep,
                         (clockid_t clock_id, int flags,
                          const struct compat_timespec __user *u_rqt,
diff --git a/kernel/cobalt/trace/cobalt-posix.h 
b/kernel/cobalt/trace/cobalt-posix.h
index 4ce67d2..a85a3e6 100644
--- a/kernel/cobalt/trace/cobalt-posix.h
+++ b/kernel/cobalt/trace/cobalt-posix.h
@@ -748,6 +748,26 @@ DEFINE_EVENT(cobalt_clock_timespec, cobalt_clock_settime,
        TP_ARGS(clk_id, time)
 );
 
+TRACE_EVENT(cobalt_clock_adjtime,
+       TP_PROTO(clockid_t clk_id, struct timex *tx),
+       TP_ARGS(clk_id, tx),
+
+       TP_STRUCT__entry(
+               __field(clockid_t, clk_id)
+               __field(struct timex *, tx)
+       ),
+
+       TP_fast_assign(
+               __entry->clk_id = clk_id;
+               __entry->tx = tx;
+       ),
+
+       TP_printk("clock_id=%d timex=%p",
+                 __entry->clk_id,
+                 __entry->tx
+       )
+);
+
 #define cobalt_print_timer_flags(__flags)                      \
        __print_flags(__flags, "|",                             \
                      {TIMER_ABSTIME, "TIMER_ABSTIME"})


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to