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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Oct 16 14:37:53 2014 +0200

cobalt/posix/clock: prepare for 32bit syscall emulation

---

 kernel/cobalt/posix/clock.c |  133 +++++++++++++++++++++++++++++--------------
 kernel/cobalt/posix/clock.h |   13 +++++
 2 files changed, 102 insertions(+), 44 deletions(-)

diff --git a/kernel/cobalt/posix/clock.c b/kernel/cobalt/posix/clock.c
index 28dd18f..dbd7132 100644
--- a/kernel/cobalt/posix/clock.c
+++ b/kernel/cobalt/posix/clock.c
@@ -106,10 +106,8 @@ static int do_clock_host_realtime(struct timespec *tp)
        __val;                                                  \
 })
 
-COBALT_SYSCALL(clock_getres, current,
-              int, (clockid_t clock_id, struct timespec __user *u_ts))
+int __cobalt_clock_getres(clockid_t clock_id, struct timespec *ts)
 {
-       struct timespec ts;
        xnticks_t ns;
        int ret;
 
@@ -117,15 +115,30 @@ COBALT_SYSCALL(clock_getres, current,
        case CLOCK_REALTIME:
        case CLOCK_MONOTONIC:
        case CLOCK_MONOTONIC_RAW:
-               ns2ts(&ts, 1);
+               ns2ts(ts, 1);
                break;
        default:
                ret = do_ext_clock(clock_id, get_resolution, ns);
                if (ret)
                        return ret;
-               ns2ts(&ts, ns);
+               ns2ts(ts, ns);
        }
 
+       trace_cobalt_clock_getres(clock_id, ts);
+
+       return 0;
+}
+
+COBALT_SYSCALL(clock_getres, current,
+              int, (clockid_t clock_id, struct timespec __user *u_ts))
+{
+       struct timespec ts;
+       int ret;
+
+       ret = __cobalt_clock_getres(clock_id, &ts);
+       if (ret)
+               return ret;
+
        if (u_ts && __xn_safe_copy_to_user(u_ts, &ts, sizeof(ts)))
                return -EFAULT;
 
@@ -134,32 +147,45 @@ COBALT_SYSCALL(clock_getres, current,
        return 0;
 }
 
-COBALT_SYSCALL(clock_gettime, current,
-              int, (clockid_t clock_id, struct timespec __user *u_ts))
+int __cobalt_clock_gettime(clockid_t clock_id, struct timespec *ts)
 {
-       struct timespec ts;
        xnticks_t ns;
        int ret;
 
        switch (clock_id) {
        case CLOCK_REALTIME:
-               ns2ts(&ts, xnclock_read_realtime(&nkclock));
+               ns2ts(ts, xnclock_read_realtime(&nkclock));
                break;
        case CLOCK_MONOTONIC:
        case CLOCK_MONOTONIC_RAW:
-               ns2ts(&ts, xnclock_read_monotonic(&nkclock));
+               ns2ts(ts, xnclock_read_monotonic(&nkclock));
                break;
        case CLOCK_HOST_REALTIME:
-               if (do_clock_host_realtime(&ts) != 0)
+               if (do_clock_host_realtime(ts) != 0)
                        return -EINVAL;
                break;
        default:
                ret = do_ext_clock(clock_id, read_monotonic, ns);
                if (ret)
                        return ret;
-               ns2ts(&ts, ns);
+               ns2ts(ts, ns);
        }
 
+       trace_cobalt_clock_gettime(clock_id, ts);
+
+       return 0;
+}
+
+COBALT_SYSCALL(clock_gettime, current,
+              int, (clockid_t clock_id, struct timespec __user *u_ts))
+{
+       struct timespec ts;
+       int ret;
+
+       ret = __cobalt_clock_gettime(clock_id, &ts);
+       if (ret)
+               return ret;
+
        if (__xn_safe_copy_to_user(u_ts, &ts, sizeof(*u_ts)))
                return -EFAULT;
 
@@ -168,67 +194,65 @@ COBALT_SYSCALL(clock_gettime, current,
        return 0;
 }
 
-COBALT_SYSCALL(clock_settime, current,
-              int, (clockid_t clock_id,
-                    const struct timespec __user *u_ts))
+int __cobalt_clock_settime(clockid_t clock_id, const struct timespec *ts)
 {
-       struct timespec ts;
        int _ret, ret = 0;
        xnticks_t now;
        spl_t s;
 
-       if (__xn_safe_copy_from_user(&ts, u_ts, sizeof(ts)))
-               return -EFAULT;
-
-       if ((unsigned long)ts.tv_nsec >= ONE_BILLION)
+       if ((unsigned long)ts->tv_nsec >= ONE_BILLION)
                return -EINVAL;
 
        switch (clock_id) {
        case CLOCK_REALTIME:
                xnlock_get_irqsave(&nklock, s);
                now = xnclock_read_realtime(&nkclock);
-               xnclock_adjust(&nkclock, (xnsticks_t) (ts2ns(&ts) - now));
+               xnclock_adjust(&nkclock, (xnsticks_t) (ts2ns(ts) - now));
                xnlock_put_irqrestore(&nklock, s);
                break;
        default:
-               _ret = do_ext_clock(clock_id, set_time, ret, &ts);
+               _ret = do_ext_clock(clock_id, set_time, ret, ts);
                if (_ret || ret)
                        return _ret ?: ret;
        }
 
-       trace_cobalt_clock_settime(clock_id, &ts);
+       trace_cobalt_clock_settime(clock_id, ts);
 
        return 0;
 }
 
-COBALT_SYSCALL(clock_nanosleep, nonrestartable,
-              int, (clockid_t clock_id, int flags,
-                    const struct timespec __user *u_rqt,
-                    struct timespec __user *u_rmt))
+COBALT_SYSCALL(clock_settime, current,
+              int, (clockid_t clock_id,
+                    const struct timespec __user *u_ts))
+{
+       struct timespec ts;
+
+       if (__xn_safe_copy_from_user(&ts, u_ts, sizeof(ts)))
+               return -EFAULT;
+
+       return __cobalt_clock_settime(clock_id, &ts);
+}
+
+int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
+                            const struct timespec *rqt,
+                            struct timespec *rmt)
 {
-       struct timespec rqt, rmt, *rmtp = NULL;
        struct xnthread *cur;
        xnsticks_t rem;
-       int err = 0;
+       int ret = 0;
        spl_t s;
 
-       if (u_rmt)
-               rmtp = &rmt;
-
-       if (__xn_safe_copy_from_user(&rqt, u_rqt, sizeof(rqt)))
-               return -EFAULT;
-
-       trace_cobalt_clock_nanosleep(clock_id, flags, &rqt);
+       trace_cobalt_clock_nanosleep(clock_id, flags, rqt);
 
        if (clock_id != CLOCK_MONOTONIC &&
            clock_id != CLOCK_MONOTONIC_RAW &&
            clock_id != CLOCK_REALTIME)
                return -EOPNOTSUPP;
 
-       if (rqt.tv_sec < 0)
+       if (rqt->tv_sec < 0)
                return -EINVAL;
 
-       if ((unsigned long)rqt.tv_nsec >= ONE_BILLION)
+       if ((unsigned long)rqt->tv_nsec >= ONE_BILLION)
                return -EINVAL;
 
        if (flags & ~TIMER_ABSTIME)
@@ -238,16 +262,14 @@ COBALT_SYSCALL(clock_nanosleep, nonrestartable,
 
        xnlock_get_irqsave(&nklock, s);
 
-       xnthread_suspend(cur, XNDELAY, ts2ns(&rqt) + 1,
+       xnthread_suspend(cur, XNDELAY, ts2ns(rqt) + 1,
                         clock_flag(flags, clock_id), NULL);
 
        if (xnthread_test_info(cur, XNBREAK)) {
-               if (flags == 0 && rmtp) {
+               if (flags == 0 && rmt) {
                        rem = xntimer_get_timeout_stopped(&cur->rtimer);
                        xnlock_put_irqrestore(&nklock, s);
-                       ns2ts(rmtp, rem > 1 ? rem : 0);
-                       if (__xn_safe_copy_to_user(u_rmt, rmtp, sizeof(*u_rmt)))
-                               return -EFAULT;
+                       ns2ts(rmt, rem > 1 ? rem : 0);
                } else
                        xnlock_put_irqrestore(&nklock, s);
 
@@ -256,7 +278,30 @@ COBALT_SYSCALL(clock_nanosleep, nonrestartable,
 
        xnlock_put_irqrestore(&nklock, s);
 
-       return err;
+       return ret;
+}
+
+COBALT_SYSCALL(clock_nanosleep, nonrestartable,
+              int, (clockid_t clock_id, int flags,
+                    const struct timespec __user *u_rqt,
+                    struct timespec __user *u_rmt))
+{
+       struct timespec rqt, rmt, *rmtp = NULL;
+       int ret;
+
+       if (u_rmt)
+               rmtp = &rmt;
+
+       if (__xn_safe_copy_from_user(&rqt, u_rqt, sizeof(rqt)))
+               return -EFAULT;
+
+       ret = __cobalt_clock_nanosleep(clock_id, flags, &rqt, rmtp);
+       if (ret == -EINTR && flags == 0 && rmtp) {
+               if (__xn_safe_copy_to_user(u_rmt, rmtp, sizeof(*u_rmt)))
+                       return -EFAULT;
+       }
+
+       return ret;
 }
 
 int cobalt_clock_register(struct xnclock *clock, clockid_t *clk_id)
diff --git a/kernel/cobalt/posix/clock.h b/kernel/cobalt/posix/clock.h
index 75ff9f4..5fa0f16 100644
--- a/kernel/cobalt/posix/clock.h
+++ b/kernel/cobalt/posix/clock.h
@@ -84,6 +84,19 @@ static inline int clock_flag(int flag, clockid_t clock_id)
        return -EINVAL;
 }
 
+int __cobalt_clock_getres(clockid_t clock_id,
+                         struct timespec *ts);
+
+int __cobalt_clock_gettime(clockid_t clock_id,
+                          struct timespec *ts);
+
+int __cobalt_clock_settime(clockid_t clock_id,
+                          const struct timespec *ts);
+
+int __cobalt_clock_nanosleep(clockid_t clock_id, int flags,
+                            const struct timespec *rqt,
+                            struct timespec *rmt);
+
 COBALT_SYSCALL_DECL(clock_getres,
                    int, (clockid_t clock_id,
                          struct timespec __user *u_ts));


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

Reply via email to