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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon Oct 27 17:27:35 2014 +0100

cobalt/posix: expose compat helpers to RTDM drivers

---

 include/cobalt/kernel/rtdm/cobalt.h |    1 +
 include/cobalt/kernel/rtdm/compat.h |    3 +
 kernel/cobalt/posix/Makefile        |    2 +-
 kernel/cobalt/posix/compat.c        |  381 +++++++++++++++++++++++++++++++++++
 kernel/cobalt/posix/compat.h        |  155 ++++++++++++++
 kernel/cobalt/posix/syscall32.c     |  342 -------------------------------
 kernel/cobalt/posix/syscall32.h     |   74 +------
 kernel/cobalt/posix/thread.h        |    4 +-
 8 files changed, 545 insertions(+), 417 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/cobalt.h 
b/include/cobalt/kernel/rtdm/cobalt.h
index 2c38053..fc75430 100644
--- a/include/cobalt/kernel/rtdm/cobalt.h
+++ b/include/cobalt/kernel/rtdm/cobalt.h
@@ -29,5 +29,6 @@
 #include <xenomai/posix/clock.h>
 #include <xenomai/posix/event.h>
 #include <xenomai/posix/monitor.h>
+#include <xenomai/posix/compat.h>
 
 #endif /* !_COBALT_RTDM_COBALT_H */
diff --git a/include/cobalt/kernel/rtdm/compat.h 
b/include/cobalt/kernel/rtdm/compat.h
index fdf493f..44b6884 100644
--- a/include/cobalt/kernel/rtdm/compat.h
+++ b/include/cobalt/kernel/rtdm/compat.h
@@ -22,6 +22,7 @@
 
 #include <linux/compat.h>
 #include <net/compat.h>
+#include <rtdm/rtdm.h>
 
 struct compat_rtdm_getsockopt_args {
        int level;
@@ -70,4 +71,6 @@ struct compat_rtdm_setsockaddr_args {
 
 #endif /* !CONFIG_COMPAT */
 
+#define COMPAT_CASE(__op)      case __op __COMPAT_CASE(__op  ## _COMPAT)
+
 #endif /* !_COBALT_RTDM_COMPAT_H */
diff --git a/kernel/cobalt/posix/Makefile b/kernel/cobalt/posix/Makefile
index 22d5f2b..2ac92ff 100644
--- a/kernel/cobalt/posix/Makefile
+++ b/kernel/cobalt/posix/Makefile
@@ -20,6 +20,6 @@ xenomai-y :=          \
        timer.o         \
        timerfd.o
 
-xenomai-$(CONFIG_XENO_ARCH_SYS3264) += syscall32.o
+xenomai-$(CONFIG_XENO_ARCH_SYS3264) += compat.o syscall32.o
 
 ccflags-y := -Iarch/$(SRCARCH)/xenomai/include -Iinclude/xenomai -Ikernel
diff --git a/kernel/cobalt/posix/compat.c b/kernel/cobalt/posix/compat.c
new file mode 100644
index 0000000..de2143a
--- /dev/null
+++ b/kernel/cobalt/posix/compat.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2014 Philippe Gerum <r...@xenomai.org>
+ *
+ * Xenomai is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/err.h>
+#include <linux/module.h>
+#include "compat.h"
+
+int sys32_get_timespec(struct timespec *ts,
+                      const struct compat_timespec __user *cts)
+{
+       return (cts == NULL ||
+               !access_rok(cts, sizeof(*cts)) ||
+               __xn_get_user(ts->tv_sec, &cts->tv_sec) ||
+               __xn_get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
+}
+EXPORT_SYMBOL_GPL(sys32_get_timespec);
+
+int sys32_put_timespec(struct compat_timespec __user *cts,
+                      const struct timespec *ts)
+{
+       return (cts == NULL ||
+               !access_wok(cts, sizeof(*cts)) ||
+               __xn_put_user(ts->tv_sec, &cts->tv_sec) ||
+               __xn_put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
+}
+EXPORT_SYMBOL_GPL(sys32_put_timespec);
+
+int sys32_get_itimerspec(struct itimerspec *its,
+                        const struct compat_itimerspec __user *cits)
+{
+       int ret = sys32_get_timespec(&its->it_value, &cits->it_value);
+
+       return ret ?: sys32_get_timespec(&its->it_interval, &cits->it_interval);
+}
+EXPORT_SYMBOL_GPL(sys32_get_itimerspec);
+
+int sys32_put_itimerspec(struct compat_itimerspec __user *cits,
+                        const struct itimerspec *its)
+{
+       int ret = sys32_put_timespec(&cits->it_value, &its->it_value);
+
+       return ret ?: sys32_put_timespec(&cits->it_interval, &its->it_interval);
+}
+EXPORT_SYMBOL_GPL(sys32_put_itimerspec);
+
+int sys32_get_timeval(struct timeval *tv,
+                     const struct compat_timeval __user *ctv)
+{
+       return (ctv == NULL ||
+               !access_rok(ctv, sizeof(*ctv)) ||
+               __xn_get_user(tv->tv_sec, &ctv->tv_sec) ||
+               __xn_get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
+}
+EXPORT_SYMBOL_GPL(sys32_get_timeval);
+
+int sys32_put_timeval(struct compat_timeval __user *ctv,
+                     const struct timeval *tv)
+{
+       return (ctv == NULL ||
+               !access_wok(ctv, sizeof(*ctv)) ||
+               __xn_put_user(tv->tv_sec, &ctv->tv_sec) ||
+               __xn_put_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
+}
+EXPORT_SYMBOL_GPL(sys32_put_timeval);
+
+ssize_t sys32_get_fdset(fd_set *fds, const compat_fd_set __user *cfds,
+                       size_t cfdsize)
+{
+       int rdpos, wrpos, rdlim = cfdsize / sizeof(compat_ulong_t);
+
+       if (cfds == NULL || !access_rok(cfds, cfdsize))
+               return -EFAULT;
+
+       for (rdpos = 0, wrpos = 0; rdpos < rdlim; rdpos++, wrpos++)
+               if (__xn_get_user(fds->fds_bits[wrpos], cfds->fds_bits + rdpos))
+                       return -EFAULT;
+
+       return (ssize_t)rdlim * sizeof(long);
+}
+EXPORT_SYMBOL_GPL(sys32_get_fdset);
+
+ssize_t sys32_put_fdset(compat_fd_set __user *cfds, const fd_set *fds,
+                       size_t fdsize)
+{
+       int rdpos, wrpos, wrlim = fdsize / sizeof(long);
+
+       if (cfds == NULL || !access_wok(cfds, wrlim * sizeof(compat_ulong_t)))
+               return -EFAULT;
+
+       for (rdpos = 0, wrpos = 0; wrpos < wrlim; rdpos++, wrpos++)
+               if (__xn_put_user(fds->fds_bits[rdpos], cfds->fds_bits + wrpos))
+                       return -EFAULT;
+
+       return (ssize_t)wrlim * sizeof(compat_ulong_t);
+}
+EXPORT_SYMBOL_GPL(sys32_put_fdset);
+
+int sys32_get_param_ex(int policy,
+                      struct sched_param_ex *p,
+                      const struct compat_sched_param_ex __user *u_cp)
+{
+       struct compat_sched_param_ex cpex;
+
+       if (u_cp == NULL || __xn_safe_copy_from_user(&cpex, u_cp, sizeof(cpex)))
+               return -EFAULT;
+
+       p->sched_priority = cpex.sched_priority;
+
+       switch (policy) {
+       case SCHED_SPORADIC:
+               p->sched_ss_low_priority = cpex.sched_ss_low_priority;
+               p->sched_ss_max_repl = cpex.sched_ss_max_repl;
+               p->sched_ss_repl_period.tv_sec = 
cpex.sched_ss_repl_period.tv_sec;
+               p->sched_ss_repl_period.tv_nsec = 
cpex.sched_ss_repl_period.tv_nsec;
+               p->sched_ss_init_budget.tv_sec = 
cpex.sched_ss_init_budget.tv_sec;
+               p->sched_ss_init_budget.tv_nsec = 
cpex.sched_ss_init_budget.tv_nsec;
+               break;
+       case SCHED_RR:
+               p->sched_rr_quantum.tv_sec = cpex.sched_rr_quantum.tv_sec;
+               p->sched_rr_quantum.tv_nsec = cpex.sched_rr_quantum.tv_nsec;
+               break;
+       case SCHED_TP:
+               p->sched_tp_partition = cpex.sched_tp_partition;
+               break;
+       case SCHED_QUOTA:
+               p->sched_quota_group = cpex.sched_quota_group;
+               break;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sys32_get_param_ex);
+
+int sys32_put_param_ex(int policy,
+                      struct compat_sched_param_ex __user *u_cp,
+                      const struct sched_param_ex *p)
+{
+       struct compat_sched_param_ex cpex;
+
+       if (u_cp == NULL)
+               return -EFAULT;
+
+       cpex.sched_priority = p->sched_priority;
+
+       switch (policy) {
+       case SCHED_SPORADIC:
+               cpex.sched_ss_low_priority = p->sched_ss_low_priority;
+               cpex.sched_ss_max_repl = p->sched_ss_max_repl;
+               cpex.sched_ss_repl_period.tv_sec = 
p->sched_ss_repl_period.tv_sec;
+               cpex.sched_ss_repl_period.tv_nsec = 
p->sched_ss_repl_period.tv_nsec;
+               cpex.sched_ss_init_budget.tv_sec = 
p->sched_ss_init_budget.tv_sec;
+               cpex.sched_ss_init_budget.tv_nsec = 
p->sched_ss_init_budget.tv_nsec;
+               break;
+       case SCHED_RR:
+               cpex.sched_rr_quantum.tv_sec = p->sched_rr_quantum.tv_sec;
+               cpex.sched_rr_quantum.tv_nsec = p->sched_rr_quantum.tv_nsec;
+               break;
+       case SCHED_TP:
+               cpex.sched_tp_partition = p->sched_tp_partition;
+               break;
+       case SCHED_QUOTA:
+               cpex.sched_quota_group = p->sched_quota_group;
+               break;
+       }
+
+       return __xn_safe_copy_to_user(u_cp, &cpex, sizeof(cpex));
+}
+EXPORT_SYMBOL_GPL(sys32_put_param_ex);
+
+int sys32_get_mqattr(struct mq_attr *ap,
+                    const struct compat_mq_attr __user *u_cap)
+{
+       struct compat_mq_attr cattr;
+
+       if (u_cap == NULL ||
+           __xn_safe_copy_from_user(&cattr, u_cap, sizeof(cattr)))
+               return -EFAULT;
+
+       ap->mq_flags = cattr.mq_flags;
+       ap->mq_maxmsg = cattr.mq_maxmsg;
+       ap->mq_msgsize = cattr.mq_msgsize;
+       ap->mq_curmsgs = cattr.mq_curmsgs;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sys32_get_mqattr);
+
+int sys32_put_mqattr(struct compat_mq_attr __user *u_cap,
+                    const struct mq_attr *ap)
+{
+       struct compat_mq_attr cattr;
+
+       cattr.mq_flags = ap->mq_flags;
+       cattr.mq_maxmsg = ap->mq_maxmsg;
+       cattr.mq_msgsize = ap->mq_msgsize;
+       cattr.mq_curmsgs = ap->mq_curmsgs;
+
+       return u_cap == NULL ? -EFAULT :
+               __xn_safe_copy_to_user(u_cap, &cattr, sizeof(cattr));
+}
+EXPORT_SYMBOL_GPL(sys32_put_mqattr);
+
+int sys32_get_sigevent(struct sigevent *ev,
+                      const struct compat_sigevent *__user u_cev)
+{
+       struct compat_sigevent cev;
+       compat_int_t *cp;
+       int ret, *p;
+
+       if (u_cev == NULL)
+               return -EFAULT;
+
+       ret = __xn_safe_copy_from_user(&cev, u_cev, sizeof(cev));
+       if (ret)
+               return ret;
+
+       memset(ev, 0, sizeof(*ev));
+       ev->sigev_value.sival_int = cev.sigev_value.sival_int;
+       ev->sigev_signo = cev.sigev_signo;
+       ev->sigev_notify = cev.sigev_notify;
+       /*
+        * Extensions may define extra fields we don't know about in
+        * the padding area, so we have to load it entirely.
+        */
+       p = ev->_sigev_un._pad;
+       cp = cev._sigev_un._pad;
+       while ((void *)cp < (void *)cev._sigev_un._pad
+              + sizeof(cev._sigev_un._pad))
+               *p++ = *cp++;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sys32_get_sigevent);
+
+int sys32_get_sigset(sigset_t *set, const compat_sigset_t *u_cset)
+{
+       compat_sigset_t cset;
+       int ret;
+
+       if (u_cset == NULL)
+               return -EFAULT;
+
+       ret = __xn_safe_copy_from_user(&cset, u_cset, sizeof(cset));
+       if (ret)
+               return ret;
+
+       sigset_from_compat(set, &cset);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sys32_get_sigset);
+
+int sys32_put_sigset(compat_sigset_t *u_cset, const sigset_t *set)
+{
+       compat_sigset_t cset;
+
+       if (u_cset == NULL)
+               return -EFAULT;
+
+       sigset_to_compat(&cset, set);
+
+       return __xn_safe_copy_from_user(u_cset, &cset, sizeof(cset));
+}
+EXPORT_SYMBOL_GPL(sys32_put_sigset);
+
+int sys32_get_sigval(union sigval *val, const union compat_sigval *u_cval)
+{
+       union compat_sigval cval;
+       int ret;
+
+       if (u_cval == NULL)
+               return -EFAULT;
+
+       ret = __xn_safe_copy_from_user(&cval, u_cval, sizeof(cval));
+       if (ret)
+               return ret;
+
+       val->sival_ptr = compat_ptr(cval.sival_ptr);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sys32_get_sigval);
+
+int sys32_put_siginfo(void __user *u_si, const struct siginfo *si,
+                     int overrun)
+{
+       struct compat_siginfo __user *u_p = u_si;
+       int code, ret;
+
+       if (u_p == NULL)
+               return -EFAULT;
+
+       /* Translate kernel codes for userland. */
+       code = si->si_code;
+       if (code & __SI_MASK)
+               code |= __SI_MASK;
+
+       ret = __xn_put_user(si->si_signo, &u_p->si_signo);
+       ret |= __xn_put_user(si->si_errno, &u_p->si_errno);
+       ret |= __xn_put_user(code, &u_p->si_code);
+
+       /*
+        * Copy the generic/standard siginfo bits to userland.
+        */
+       switch (si->si_code) {
+       case SI_TIMER:
+               ret |= __xn_put_user(si->si_tid, &u_p->si_tid);
+               ret |= __xn_put_user(ptr_to_compat(si->si_ptr), &u_p->si_ptr);
+               ret |= __xn_put_user(overrun, &u_p->si_overrun);
+               break;
+       case SI_QUEUE:
+       case SI_MESGQ:
+               ret |= __xn_put_user(ptr_to_compat(si->si_ptr), &u_p->si_ptr);
+               /* falldown wanted. */
+       case SI_USER:
+               ret |= __xn_put_user(si->si_pid, &u_p->si_pid);
+               ret |= __xn_put_user(si->si_uid, &u_p->si_uid);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(sys32_put_siginfo);
+
+int sys32_get_msghdr(struct msghdr *msg,
+                    const struct compat_msghdr __user *u_cmsg)
+{
+       compat_uptr_t tmp1, tmp2, tmp3;
+
+       if (u_cmsg == NULL ||
+           !access_rok(u_cmsg, sizeof(*u_cmsg)) ||
+           __xn_get_user(tmp1, &u_cmsg->msg_name) ||
+           __xn_get_user(msg->msg_namelen, &u_cmsg->msg_namelen) ||
+           __xn_get_user(tmp2, &u_cmsg->msg_iov) ||
+           __xn_get_user(msg->msg_iovlen, &u_cmsg->msg_iovlen) ||
+           __xn_get_user(tmp3, &u_cmsg->msg_control) ||
+           __xn_get_user(msg->msg_controllen, &u_cmsg->msg_controllen) ||
+           __xn_get_user(msg->msg_flags, &u_cmsg->msg_flags))
+               return -EFAULT;
+
+       if (msg->msg_namelen > sizeof(struct sockaddr_storage))
+               msg->msg_namelen = sizeof(struct sockaddr_storage);
+
+       msg->msg_name = compat_ptr(tmp1);
+       msg->msg_iov = compat_ptr(tmp2);
+       msg->msg_control = compat_ptr(tmp3);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sys32_get_msghdr);
+
+int sys32_put_msghdr(struct compat_msghdr __user *u_cmsg,
+                    const struct msghdr *msg)
+{
+       if (u_cmsg == NULL ||
+           !access_wok(u_cmsg, sizeof(*u_cmsg)) ||
+           __xn_put_user(ptr_to_compat(msg->msg_name), &u_cmsg->msg_name) ||
+           __xn_put_user(msg->msg_namelen, &u_cmsg->msg_namelen) ||
+           __xn_put_user(ptr_to_compat(msg->msg_iov), &u_cmsg->msg_iov) ||
+           __xn_put_user(msg->msg_iovlen, &u_cmsg->msg_iovlen) ||
+           __xn_put_user(ptr_to_compat(msg->msg_control), 
&u_cmsg->msg_control) ||
+           __xn_put_user(msg->msg_controllen, &u_cmsg->msg_controllen) ||
+           __xn_put_user(msg->msg_flags, &u_cmsg->msg_flags))
+               return -EFAULT;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sys32_put_msghdr);
diff --git a/kernel/cobalt/posix/compat.h b/kernel/cobalt/posix/compat.h
new file mode 100644
index 0000000..466ea43
--- /dev/null
+++ b/kernel/cobalt/posix/compat.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2014 Philippe Gerum <r...@xenomai.org>
+ *
+ * Xenomai is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef _COBALT_POSIX_COMPAT_H
+#define _COBALT_POSIX_COMPAT_H
+
+#ifdef CONFIG_COMPAT
+
+#include <rtdm/compat.h>
+/* CAUTION: rtdm/cobalt.h reads this header. */
+#include <xenomai/posix/thread.h>
+#include <xenomai/posix/mutex.h>
+#include <xenomai/posix/cond.h>
+#include <xenomai/posix/sem.h>
+#include <xenomai/posix/sched.h>
+#include <xenomai/posix/mqueue.h>
+#include <xenomai/posix/clock.h>
+#include <xenomai/posix/timer.h>
+#include <xenomai/posix/timerfd.h>
+#include <xenomai/posix/signal.h>
+#include <xenomai/posix/monitor.h>
+#include <xenomai/posix/event.h>
+#include <xenomai/posix/io.h>
+
+struct __compat_sched_ss_param {
+       int __sched_low_priority;
+       struct compat_timespec __sched_repl_period;
+       struct compat_timespec __sched_init_budget;
+       int __sched_max_repl;
+};
+
+struct __compat_sched_rr_param {
+       struct compat_timespec __sched_rr_quantum;
+};
+
+struct compat_sched_param_ex {
+       int sched_priority;
+       union {
+               struct __compat_sched_ss_param ss;
+               struct __compat_sched_rr_param rr;
+               struct __sched_tp_param tp;
+               struct __sched_quota_param quota;
+       } sched_u;
+};
+
+struct compat_mq_attr {
+       compat_long_t mq_flags;
+       compat_long_t mq_maxmsg;
+       compat_long_t mq_msgsize;
+       compat_long_t mq_curmsgs;
+};
+
+struct compat_sched_tp_window {
+       struct compat_timespec offset;
+       struct compat_timespec duration;
+       int ptid;
+};
+
+struct __compat_sched_config_tp {
+       int nr_windows;
+       struct compat_sched_tp_window windows[0];
+};
+
+union compat_sched_config {
+       struct __compat_sched_config_tp tp;
+       struct __sched_config_quota quota;
+};
+
+#define compat_sched_tp_confsz(nr_win) \
+  (sizeof(struct __compat_sched_config_tp) + nr_win * sizeof(struct 
compat_sched_tp_window))
+
+typedef struct {
+       compat_ulong_t fds_bits[__FD_SETSIZE / (8 * sizeof(compat_long_t))];
+} compat_fd_set;
+
+struct compat_rtdm_mmap_request {
+       compat_size_t length;
+       compat_off_t offset;
+       int prot;
+       int flags;
+};
+
+int sys32_get_timespec(struct timespec *ts,
+                      const struct compat_timespec __user *cts);
+
+int sys32_put_timespec(struct compat_timespec __user *cts,
+                      const struct timespec *ts);
+
+int sys32_get_itimerspec(struct itimerspec *its,
+                        const struct compat_itimerspec __user *cits);
+
+int sys32_put_itimerspec(struct compat_itimerspec __user *cits,
+                        const struct itimerspec *its);
+
+int sys32_get_timeval(struct timeval *tv,
+                     const struct compat_timeval __user *ctv);
+
+int sys32_put_timeval(struct compat_timeval __user *ctv,
+                     const struct timeval *tv);
+
+ssize_t sys32_get_fdset(fd_set *fds, const compat_fd_set __user *cfds,
+                       size_t cfdsize);
+
+ssize_t sys32_put_fdset(compat_fd_set __user *cfds, const fd_set *fds,
+                       size_t fdsize);
+
+int sys32_get_param_ex(int policy,
+                      struct sched_param_ex *p,
+                      const struct compat_sched_param_ex __user *u_cp);
+
+int sys32_put_param_ex(int policy,
+                      struct compat_sched_param_ex __user *u_cp,
+                      const struct sched_param_ex *p);
+
+int sys32_get_mqattr(struct mq_attr *ap,
+                    const struct compat_mq_attr __user *u_cap);
+
+int sys32_put_mqattr(struct compat_mq_attr __user *u_cap,
+                    const struct mq_attr *ap);
+
+int sys32_get_sigevent(struct sigevent *ev,
+                      const struct compat_sigevent *__user u_cev);
+
+int sys32_get_sigset(sigset_t *set, const compat_sigset_t *u_cset);
+
+int sys32_put_sigset(compat_sigset_t *u_cset, const sigset_t *set);
+
+int sys32_get_sigval(union sigval *val, const union compat_sigval *u_cval);
+
+int sys32_put_siginfo(void __user *u_si, const struct siginfo *si,
+                     int overrun);
+
+int sys32_get_msghdr(struct msghdr *msg,
+                    const struct compat_msghdr __user *u_cmsg);
+
+int sys32_put_msghdr(struct compat_msghdr __user *u_cmsg,
+                    const struct msghdr *msg);
+
+#endif /* CONFIG_COMPAT */
+
+#endif /* !_COBALT_POSIX_COMPAT_H */
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 633cc22..a9b0ade 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -23,348 +23,6 @@
 #include "syscall32.h"
 #include "../debug.h"
 
-static int sys32_get_timespec(struct timespec *ts,
-                             const struct compat_timespec __user *cts)
-{
-       return (cts == NULL ||
-               !access_rok(cts, sizeof(*cts)) ||
-               __xn_get_user(ts->tv_sec, &cts->tv_sec) ||
-               __xn_get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
-}
-
-static int sys32_put_timespec(struct compat_timespec __user *cts,
-                             const struct timespec *ts)
-{
-       return (cts == NULL ||
-               !access_wok(cts, sizeof(*cts)) ||
-               __xn_put_user(ts->tv_sec, &cts->tv_sec) ||
-               __xn_put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
-}
-
-static int sys32_get_itimerspec(struct itimerspec *its,
-                               const struct compat_itimerspec __user *cits)
-{
-       int ret = sys32_get_timespec(&its->it_value, &cits->it_value);
-
-       return ret ?: sys32_get_timespec(&its->it_interval, &cits->it_interval);
-}
-
-static int sys32_put_itimerspec(struct compat_itimerspec __user *cits,
-                               const struct itimerspec *its)
-{
-       int ret = sys32_put_timespec(&cits->it_value, &its->it_value);
-
-       return ret ?: sys32_put_timespec(&cits->it_interval, &its->it_interval);
-}
-
-static int sys32_get_timeval(struct timeval *tv,
-                            const struct compat_timeval __user *ctv)
-{
-       return (ctv == NULL ||
-               !access_rok(ctv, sizeof(*ctv)) ||
-               __xn_get_user(tv->tv_sec, &ctv->tv_sec) ||
-               __xn_get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
-}
-
-static int sys32_put_timeval(struct compat_timeval __user *ctv,
-                            const struct timeval *tv)
-{
-       return (ctv == NULL ||
-               !access_wok(ctv, sizeof(*ctv)) ||
-               __xn_put_user(tv->tv_sec, &ctv->tv_sec) ||
-               __xn_put_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
-}
-
-static ssize_t sys32_get_fdset(fd_set *fds, const compat_fd_set __user *cfds,
-                              size_t cfdsize)
-{
-       int rdpos, wrpos, rdlim = cfdsize / sizeof(compat_ulong_t);
-
-       if (cfds == NULL || !access_rok(cfds, cfdsize))
-               return -EFAULT;
-
-       for (rdpos = 0, wrpos = 0; rdpos < rdlim; rdpos++, wrpos++)
-               if (__xn_get_user(fds->fds_bits[wrpos], cfds->fds_bits + rdpos))
-                       return -EFAULT;
-
-       return (ssize_t)rdlim * sizeof(long);
-}
-
-static ssize_t sys32_put_fdset(compat_fd_set __user *cfds, const fd_set *fds,
-                              size_t fdsize)
-{
-       int rdpos, wrpos, wrlim = fdsize / sizeof(long);
-
-       if (cfds == NULL || !access_wok(cfds, wrlim * sizeof(compat_ulong_t)))
-               return -EFAULT;
-
-       for (rdpos = 0, wrpos = 0; wrpos < wrlim; rdpos++, wrpos++)
-               if (__xn_put_user(fds->fds_bits[rdpos], cfds->fds_bits + wrpos))
-                       return -EFAULT;
-
-       return (ssize_t)wrlim * sizeof(compat_ulong_t);
-}
-
-static int sys32_get_param_ex(int policy,
-                             struct sched_param_ex *p,
-                             const struct compat_sched_param_ex __user *u_cp)
-{
-       struct compat_sched_param_ex cpex;
-
-       if (u_cp == NULL || __xn_safe_copy_from_user(&cpex, u_cp, sizeof(cpex)))
-               return -EFAULT;
-
-       p->sched_priority = cpex.sched_priority;
-
-       switch (policy) {
-       case SCHED_SPORADIC:
-               p->sched_ss_low_priority = cpex.sched_ss_low_priority;
-               p->sched_ss_max_repl = cpex.sched_ss_max_repl;
-               p->sched_ss_repl_period.tv_sec = 
cpex.sched_ss_repl_period.tv_sec;
-               p->sched_ss_repl_period.tv_nsec = 
cpex.sched_ss_repl_period.tv_nsec;
-               p->sched_ss_init_budget.tv_sec = 
cpex.sched_ss_init_budget.tv_sec;
-               p->sched_ss_init_budget.tv_nsec = 
cpex.sched_ss_init_budget.tv_nsec;
-               break;
-       case SCHED_RR:
-               p->sched_rr_quantum.tv_sec = cpex.sched_rr_quantum.tv_sec;
-               p->sched_rr_quantum.tv_nsec = cpex.sched_rr_quantum.tv_nsec;
-               break;
-       case SCHED_TP:
-               p->sched_tp_partition = cpex.sched_tp_partition;
-               break;
-       case SCHED_QUOTA:
-               p->sched_quota_group = cpex.sched_quota_group;
-               break;
-       }
-
-       return 0;
-}
-
-static int sys32_put_param_ex(int policy,
-                             struct compat_sched_param_ex __user *u_cp,
-                             const struct sched_param_ex *p)
-{
-       struct compat_sched_param_ex cpex;
-
-       if (u_cp == NULL)
-               return -EFAULT;
-
-       cpex.sched_priority = p->sched_priority;
-
-       switch (policy) {
-       case SCHED_SPORADIC:
-               cpex.sched_ss_low_priority = p->sched_ss_low_priority;
-               cpex.sched_ss_max_repl = p->sched_ss_max_repl;
-               cpex.sched_ss_repl_period.tv_sec = 
p->sched_ss_repl_period.tv_sec;
-               cpex.sched_ss_repl_period.tv_nsec = 
p->sched_ss_repl_period.tv_nsec;
-               cpex.sched_ss_init_budget.tv_sec = 
p->sched_ss_init_budget.tv_sec;
-               cpex.sched_ss_init_budget.tv_nsec = 
p->sched_ss_init_budget.tv_nsec;
-               break;
-       case SCHED_RR:
-               cpex.sched_rr_quantum.tv_sec = p->sched_rr_quantum.tv_sec;
-               cpex.sched_rr_quantum.tv_nsec = p->sched_rr_quantum.tv_nsec;
-               break;
-       case SCHED_TP:
-               cpex.sched_tp_partition = p->sched_tp_partition;
-               break;
-       case SCHED_QUOTA:
-               cpex.sched_quota_group = p->sched_quota_group;
-               break;
-       }
-
-       return __xn_safe_copy_to_user(u_cp, &cpex, sizeof(cpex));
-}
-
-static int sys32_get_mqattr(struct mq_attr *ap,
-                           const struct compat_mq_attr __user *u_cap)
-{
-       struct compat_mq_attr cattr;
-
-       if (u_cap == NULL ||
-           __xn_safe_copy_from_user(&cattr, u_cap, sizeof(cattr)))
-               return -EFAULT;
-
-       ap->mq_flags = cattr.mq_flags;
-       ap->mq_maxmsg = cattr.mq_maxmsg;
-       ap->mq_msgsize = cattr.mq_msgsize;
-       ap->mq_curmsgs = cattr.mq_curmsgs;
-
-       return 0;
-}
-
-static int sys32_put_mqattr(struct compat_mq_attr __user *u_cap,
-                           const struct mq_attr *ap)
-{
-       struct compat_mq_attr cattr;
-
-       cattr.mq_flags = ap->mq_flags;
-       cattr.mq_maxmsg = ap->mq_maxmsg;
-       cattr.mq_msgsize = ap->mq_msgsize;
-       cattr.mq_curmsgs = ap->mq_curmsgs;
-
-       return u_cap == NULL ? -EFAULT :
-               __xn_safe_copy_to_user(u_cap, &cattr, sizeof(cattr));
-}
-
-static int sys32_get_sigevent(struct sigevent *ev,
-                             const struct compat_sigevent *__user u_cev)
-{
-       struct compat_sigevent cev;
-       compat_int_t *cp;
-       int ret, *p;
-
-       if (u_cev == NULL)
-               return -EFAULT;
-
-       ret = __xn_safe_copy_from_user(&cev, u_cev, sizeof(cev));
-       if (ret)
-               return ret;
-
-       memset(ev, 0, sizeof(*ev));
-       ev->sigev_value.sival_int = cev.sigev_value.sival_int;
-       ev->sigev_signo = cev.sigev_signo;
-       ev->sigev_notify = cev.sigev_notify;
-       /*
-        * Extensions may define extra fields we don't know about in
-        * the padding area, so we have to load it entirely.
-        */
-       p = ev->_sigev_un._pad;
-       cp = cev._sigev_un._pad;
-       while ((void *)cp < (void *)cev._sigev_un._pad
-              + sizeof(cev._sigev_un._pad))
-               *p++ = *cp++;
-
-       return 0;
-}
-
-static int sys32_get_sigset(sigset_t *set, const compat_sigset_t *u_cset)
-{
-       compat_sigset_t cset;
-       int ret;
-
-       if (u_cset == NULL)
-               return -EFAULT;
-
-       ret = __xn_safe_copy_from_user(&cset, u_cset, sizeof(cset));
-       if (ret)
-               return ret;
-
-       sigset_from_compat(set, &cset);
-
-       return 0;
-}
-
-static int sys32_put_sigset(compat_sigset_t *u_cset, const sigset_t *set)
-{
-       compat_sigset_t cset;
-
-       if (u_cset == NULL)
-               return -EFAULT;
-
-       sigset_to_compat(&cset, set);
-
-       return __xn_safe_copy_from_user(u_cset, &cset, sizeof(cset));
-}
-
-static int sys32_get_sigval(union sigval *val, const union compat_sigval 
*u_cval)
-{
-       union compat_sigval cval;
-       int ret;
-
-       if (u_cval == NULL)
-               return -EFAULT;
-
-       ret = __xn_safe_copy_from_user(&cval, u_cval, sizeof(cval));
-       if (ret)
-               return ret;
-
-       val->sival_ptr = compat_ptr(cval.sival_ptr);
-
-       return 0;
-}
-
-static int sys32_put_siginfo(void __user *u_si, const struct siginfo *si,
-                            int overrun)
-{
-       struct compat_siginfo __user *u_p = u_si;
-       int code, ret;
-
-       if (u_p == NULL)
-               return -EFAULT;
-
-       /* Translate kernel codes for userland. */
-       code = si->si_code;
-       if (code & __SI_MASK)
-               code |= __SI_MASK;
-
-       ret = __xn_put_user(si->si_signo, &u_p->si_signo);
-       ret |= __xn_put_user(si->si_errno, &u_p->si_errno);
-       ret |= __xn_put_user(code, &u_p->si_code);
-
-       /*
-        * Copy the generic/standard siginfo bits to userland.
-        */
-       switch (si->si_code) {
-       case SI_TIMER:
-               ret |= __xn_put_user(si->si_tid, &u_p->si_tid);
-               ret |= __xn_put_user(ptr_to_compat(si->si_ptr), &u_p->si_ptr);
-               ret |= __xn_put_user(overrun, &u_p->si_overrun);
-               break;
-       case SI_QUEUE:
-       case SI_MESGQ:
-               ret |= __xn_put_user(ptr_to_compat(si->si_ptr), &u_p->si_ptr);
-               /* falldown wanted. */
-       case SI_USER:
-               ret |= __xn_put_user(si->si_pid, &u_p->si_pid);
-               ret |= __xn_put_user(si->si_uid, &u_p->si_uid);
-       }
-
-       return ret;
-}
-
-static int sys32_get_msghdr(struct msghdr *msg,
-                           const struct compat_msghdr __user *u_cmsg)
-{
-       compat_uptr_t tmp1, tmp2, tmp3;
-
-       if (u_cmsg == NULL ||
-           !access_rok(u_cmsg, sizeof(*u_cmsg)) ||
-           __xn_get_user(tmp1, &u_cmsg->msg_name) ||
-           __xn_get_user(msg->msg_namelen, &u_cmsg->msg_namelen) ||
-           __xn_get_user(tmp2, &u_cmsg->msg_iov) ||
-           __xn_get_user(msg->msg_iovlen, &u_cmsg->msg_iovlen) ||
-           __xn_get_user(tmp3, &u_cmsg->msg_control) ||
-           __xn_get_user(msg->msg_controllen, &u_cmsg->msg_controllen) ||
-           __xn_get_user(msg->msg_flags, &u_cmsg->msg_flags))
-               return -EFAULT;
-
-       if (msg->msg_namelen > sizeof(struct sockaddr_storage))
-               msg->msg_namelen = sizeof(struct sockaddr_storage);
-
-       msg->msg_name = compat_ptr(tmp1);
-       msg->msg_iov = compat_ptr(tmp2);
-       msg->msg_control = compat_ptr(tmp3);
-
-       return 0;
-}
-
-static int sys32_put_msghdr(struct compat_msghdr __user *u_cmsg,
-                           const struct msghdr *msg)
-{
-       if (u_cmsg == NULL ||
-           !access_wok(u_cmsg, sizeof(*u_cmsg)) ||
-           __xn_put_user(ptr_to_compat(msg->msg_name), &u_cmsg->msg_name) ||
-           __xn_put_user(msg->msg_namelen, &u_cmsg->msg_namelen) ||
-           __xn_put_user(ptr_to_compat(msg->msg_iov), &u_cmsg->msg_iov) ||
-           __xn_put_user(msg->msg_iovlen, &u_cmsg->msg_iovlen) ||
-           __xn_put_user(ptr_to_compat(msg->msg_control), 
&u_cmsg->msg_control) ||
-           __xn_put_user(msg->msg_controllen, &u_cmsg->msg_controllen) ||
-           __xn_put_user(msg->msg_flags, &u_cmsg->msg_flags))
-               return -EFAULT;
-
-       return 0;
-}
-
 COBALT_SYSCALL32emu(thread_create, init,
                    int, (compat_ulong_t pth,
                          int policy,
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index f4e41e7..f1ebaec 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -18,79 +18,7 @@
 #ifndef _COBALT_POSIX_SYSCALL32_H
 #define _COBALT_POSIX_SYSCALL32_H
 
-#include <linux/compat.h>
-#include <net/compat.h>
-#include "thread.h"
-#include "mutex.h"
-#include "cond.h"
-#include "sem.h"
-#include "sched.h"
-#include "mqueue.h"
-#include "clock.h"
-#include "timer.h"
-#include "timerfd.h"
-#include "signal.h"
-#include "monitor.h"
-#include "event.h"
-#include "io.h"
-
-struct __compat_sched_ss_param {
-       int __sched_low_priority;
-       struct compat_timespec __sched_repl_period;
-       struct compat_timespec __sched_init_budget;
-       int __sched_max_repl;
-};
-
-struct __compat_sched_rr_param {
-       struct compat_timespec __sched_rr_quantum;
-};
-
-struct compat_sched_param_ex {
-       int sched_priority;
-       union {
-               struct __compat_sched_ss_param ss;
-               struct __compat_sched_rr_param rr;
-               struct __sched_tp_param tp;
-               struct __sched_quota_param quota;
-       } sched_u;
-};
-
-struct compat_mq_attr {
-       compat_long_t mq_flags;
-       compat_long_t mq_maxmsg;
-       compat_long_t mq_msgsize;
-       compat_long_t mq_curmsgs;
-};
-
-struct compat_sched_tp_window {
-       struct compat_timespec offset;
-       struct compat_timespec duration;
-       int ptid;
-};
-
-struct __compat_sched_config_tp {
-       int nr_windows;
-       struct compat_sched_tp_window windows[0];
-};
-
-union compat_sched_config {
-       struct __compat_sched_config_tp tp;
-       struct __sched_config_quota quota;
-};
-
-#define compat_sched_tp_confsz(nr_win) \
-  (sizeof(struct __compat_sched_config_tp) + nr_win * sizeof(struct 
compat_sched_tp_window))
-
-typedef struct {
-       compat_ulong_t fds_bits[__FD_SETSIZE / (8 * sizeof(compat_long_t))];
-} compat_fd_set;
-
-struct compat_rtdm_mmap_request {
-       compat_size_t length;
-       compat_off_t offset;
-       int prot;
-       int flags;
-};
+#include "compat.h"
 
 COBALT_SYSCALL32emu_DECL(thread_create,
                         int, (compat_ulong_t pth,
diff --git a/kernel/cobalt/posix/thread.h b/kernel/cobalt/posix/thread.h
index 392cb51..d1bc034 100644
--- a/kernel/cobalt/posix/thread.h
+++ b/kernel/cobalt/posix/thread.h
@@ -25,7 +25,9 @@
 #include <cobalt/kernel/thread.h>
 #include <cobalt/uapi/thread.h>
 #include <cobalt/uapi/sched.h>
-#include <xenomai/posix/syscall.h> /* CAUTION: rtdm/cobalt.h reads this. */
+/* CAUTION: rtdm/cobalt.h reads this header. */
+#include <xenomai/posix/syscall.h>
+#include <xenomai/posix/extension.h>
 
 #define PTHREAD_PROCESS_PRIVATE 0
 #define PTHREAD_PROCESS_SHARED  1


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

Reply via email to