[Xenomai-git] Philippe Gerum : cobalt/rtdm: factor out iovec[] copy routines

2018-01-23 Thread git repository hosting
Module: xenomai-3
Branch: wip/rtnet-fixes
Commit: 3a2fbc62b2dce64e959a49db9bcc049e6acc4e21
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=3a2fbc62b2dce64e959a49db9bcc049e6acc4e21

Author: Philippe Gerum 
Date:   Tue Dec  5 11:22:59 2017 +0100

cobalt/rtdm: factor out iovec[] copy routines

---

 include/cobalt/kernel/rtdm/driver.h |   19 +
 kernel/cobalt/rtdm/drvlib.c |   80 +++
 kernel/drivers/ipc/bufp.c   |   20 -
 kernel/drivers/ipc/iddp.c   |   20 -
 kernel/drivers/ipc/internal.h   |   19 -
 kernel/drivers/ipc/rtipc.c  |   76 -
 kernel/drivers/ipc/xddp.c   |   20 -
 7 files changed, 129 insertions(+), 125 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 0c7b62e..63beb48 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -1339,6 +1339,25 @@ static inline int rtdm_in_rt_context(void)
return (ipipe_current_domain != ipipe_root_domain);
 }
 
+#define RTDM_IOV_FASTMAX  16
+
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+static inline
+void rtdm_drop_iovec(struct iovec *iov, struct iovec *iov_fast)
+{
+   if (iov != iov_fast)
+   xnfree(iov);
+}
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen);
+
 #endif /* !DOXYGEN_CPP */
 
 #endif /* _COBALT_RTDM_DRIVER_H */
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index fb7bd7e..847e18f 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "internal.h"
 #include 
 
@@ -2151,6 +2152,85 @@ int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, 
const char *func)
 }
 EXPORT_SYMBOL_GPL(rtdm_ratelimit);
 
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(struct iovec) * msg->msg_iovlen;
+   struct iovec *iov = iov_fast;
+
+   /*
+* If the I/O vector doesn't fit in the fast memory, allocate
+* a chunk from the system heap which is large enough to hold
+* it.
+*/
+   if (msg->msg_iovlen > RTDM_IOV_FASTMAX) {
+   iov = xnmalloc(len);
+   if (iov == NULL)
+   return -ENOMEM;
+   }
+
+   *iovp = iov;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(iov, msg->msg_iov, len);
+   return 0;
+   }
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   return sys32_get_iovec(iov,
+  (struct compat_iovec __user *)msg->msg_iov,
+  msg->msg_iovlen);
+#endif
+
+   return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iovec);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(iov[0]) * msg->msg_iovlen;
+   int ret;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(msg->msg_iov, iov, len);
+   ret = 0;
+   } else
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   ret = sys32_put_iovec((struct compat_iovec __user 
*)msg->msg_iov,
+ iov, msg->msg_iovlen);
+   else
+#endif
+   ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
+
+   if (iov != iov_fast)
+   xnfree(iov);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(rtdm_put_iovec);
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen)
+{
+   ssize_t len;
+   int nvec;
+
+   /* Return the flattened vector length. */
+   for (len = 0, nvec = 0; nvec < iovlen; nvec++) {
+   ssize_t l = iov[nvec].iov_len;
+   if (l < 0 || len + l < len) /* SuS wants this. */
+   return -EINVAL;
+   len += l;
+   }
+
+   return len;
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iov_flatlen);
+
 #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
 
 /**
diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c
index 3b565bd..e1c8672 100644
--- a/kernel/drivers/ipc/bufp.c
+++ b/kernel/drivers/ipc/bufp.c
@@ -307,7 +307,7 @@ static ssize_t __bufp_recvmsg(struct rtdm_fd *fd,
if (!test_bit(_BUFP_BOUND, >status))
return -EAGAIN;
 
-   len = rtipc_get_iov_flatlen(iov, iovlen);
+   len = 

[Xenomai-git] Philippe Gerum : cobalt/rtdm: factor out iovec[] copy routines

2018-01-23 Thread git repository hosting
Module: xenomai-3
Branch: stable-3.0.x
Commit: 3a2fbc62b2dce64e959a49db9bcc049e6acc4e21
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=3a2fbc62b2dce64e959a49db9bcc049e6acc4e21

Author: Philippe Gerum 
Date:   Tue Dec  5 11:22:59 2017 +0100

cobalt/rtdm: factor out iovec[] copy routines

---

 include/cobalt/kernel/rtdm/driver.h |   19 +
 kernel/cobalt/rtdm/drvlib.c |   80 +++
 kernel/drivers/ipc/bufp.c   |   20 -
 kernel/drivers/ipc/iddp.c   |   20 -
 kernel/drivers/ipc/internal.h   |   19 -
 kernel/drivers/ipc/rtipc.c  |   76 -
 kernel/drivers/ipc/xddp.c   |   20 -
 7 files changed, 129 insertions(+), 125 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 0c7b62e..63beb48 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -1339,6 +1339,25 @@ static inline int rtdm_in_rt_context(void)
return (ipipe_current_domain != ipipe_root_domain);
 }
 
+#define RTDM_IOV_FASTMAX  16
+
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+static inline
+void rtdm_drop_iovec(struct iovec *iov, struct iovec *iov_fast)
+{
+   if (iov != iov_fast)
+   xnfree(iov);
+}
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen);
+
 #endif /* !DOXYGEN_CPP */
 
 #endif /* _COBALT_RTDM_DRIVER_H */
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index fb7bd7e..847e18f 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "internal.h"
 #include 
 
@@ -2151,6 +2152,85 @@ int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, 
const char *func)
 }
 EXPORT_SYMBOL_GPL(rtdm_ratelimit);
 
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(struct iovec) * msg->msg_iovlen;
+   struct iovec *iov = iov_fast;
+
+   /*
+* If the I/O vector doesn't fit in the fast memory, allocate
+* a chunk from the system heap which is large enough to hold
+* it.
+*/
+   if (msg->msg_iovlen > RTDM_IOV_FASTMAX) {
+   iov = xnmalloc(len);
+   if (iov == NULL)
+   return -ENOMEM;
+   }
+
+   *iovp = iov;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(iov, msg->msg_iov, len);
+   return 0;
+   }
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   return sys32_get_iovec(iov,
+  (struct compat_iovec __user *)msg->msg_iov,
+  msg->msg_iovlen);
+#endif
+
+   return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iovec);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(iov[0]) * msg->msg_iovlen;
+   int ret;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(msg->msg_iov, iov, len);
+   ret = 0;
+   } else
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   ret = sys32_put_iovec((struct compat_iovec __user 
*)msg->msg_iov,
+ iov, msg->msg_iovlen);
+   else
+#endif
+   ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
+
+   if (iov != iov_fast)
+   xnfree(iov);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(rtdm_put_iovec);
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen)
+{
+   ssize_t len;
+   int nvec;
+
+   /* Return the flattened vector length. */
+   for (len = 0, nvec = 0; nvec < iovlen; nvec++) {
+   ssize_t l = iov[nvec].iov_len;
+   if (l < 0 || len + l < len) /* SuS wants this. */
+   return -EINVAL;
+   len += l;
+   }
+
+   return len;
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iov_flatlen);
+
 #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
 
 /**
diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c
index 3b565bd..e1c8672 100644
--- a/kernel/drivers/ipc/bufp.c
+++ b/kernel/drivers/ipc/bufp.c
@@ -307,7 +307,7 @@ static ssize_t __bufp_recvmsg(struct rtdm_fd *fd,
if (!test_bit(_BUFP_BOUND, >status))
return -EAGAIN;
 
-   len = rtipc_get_iov_flatlen(iov, iovlen);
+   len = 

[Xenomai-git] Philippe Gerum : cobalt/rtdm: factor out iovec[] copy routines

2018-01-23 Thread git repository hosting
Module: xenomai-3
Branch: wip/rtnet-fixes
Commit: 103a67cac3c7560e8b5e0b9551401968b79ae1e4
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=103a67cac3c7560e8b5e0b9551401968b79ae1e4

Author: Philippe Gerum 
Date:   Tue Dec  5 11:22:59 2017 +0100

cobalt/rtdm: factor out iovec[] copy routines

---

 include/cobalt/kernel/rtdm/driver.h |   19 +
 kernel/cobalt/rtdm/drvlib.c |   80 +++
 kernel/drivers/ipc/bufp.c   |   20 -
 kernel/drivers/ipc/iddp.c   |   20 -
 kernel/drivers/ipc/internal.h   |   19 -
 kernel/drivers/ipc/rtipc.c  |   76 -
 kernel/drivers/ipc/xddp.c   |   20 -
 7 files changed, 129 insertions(+), 125 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 0c7b62e..63beb48 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -1339,6 +1339,25 @@ static inline int rtdm_in_rt_context(void)
return (ipipe_current_domain != ipipe_root_domain);
 }
 
+#define RTDM_IOV_FASTMAX  16
+
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+static inline
+void rtdm_drop_iovec(struct iovec *iov, struct iovec *iov_fast)
+{
+   if (iov != iov_fast)
+   xnfree(iov);
+}
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen);
+
 #endif /* !DOXYGEN_CPP */
 
 #endif /* _COBALT_RTDM_DRIVER_H */
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index fb7bd7e..847e18f 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "internal.h"
 #include 
 
@@ -2151,6 +2152,85 @@ int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, 
const char *func)
 }
 EXPORT_SYMBOL_GPL(rtdm_ratelimit);
 
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(struct iovec) * msg->msg_iovlen;
+   struct iovec *iov = iov_fast;
+
+   /*
+* If the I/O vector doesn't fit in the fast memory, allocate
+* a chunk from the system heap which is large enough to hold
+* it.
+*/
+   if (msg->msg_iovlen > RTDM_IOV_FASTMAX) {
+   iov = xnmalloc(len);
+   if (iov == NULL)
+   return -ENOMEM;
+   }
+
+   *iovp = iov;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(iov, msg->msg_iov, len);
+   return 0;
+   }
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   return sys32_get_iovec(iov,
+  (struct compat_iovec __user *)msg->msg_iov,
+  msg->msg_iovlen);
+#endif
+
+   return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iovec);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(iov[0]) * msg->msg_iovlen;
+   int ret;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(msg->msg_iov, iov, len);
+   ret = 0;
+   } else
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   ret = sys32_put_iovec((struct compat_iovec __user 
*)msg->msg_iov,
+ iov, msg->msg_iovlen);
+   else
+#endif
+   ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
+
+   if (iov != iov_fast)
+   xnfree(iov);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(rtdm_put_iovec);
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen)
+{
+   ssize_t len;
+   int nvec;
+
+   /* Return the flattened vector length. */
+   for (len = 0, nvec = 0; nvec < iovlen; nvec++) {
+   ssize_t l = iov[nvec].iov_len;
+   if (l < 0 || len + l < len) /* SuS wants this. */
+   return -EINVAL;
+   len += l;
+   }
+
+   return len;
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iov_flatlen);
+
 #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
 
 /**
diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c
index 3b565bd..e1c8672 100644
--- a/kernel/drivers/ipc/bufp.c
+++ b/kernel/drivers/ipc/bufp.c
@@ -307,7 +307,7 @@ static ssize_t __bufp_recvmsg(struct rtdm_fd *fd,
if (!test_bit(_BUFP_BOUND, >status))
return -EAGAIN;
 
-   len = rtipc_get_iov_flatlen(iov, iovlen);
+   len = 

[Xenomai-git] Philippe Gerum : cobalt/rtdm: factor out iovec[] copy routines

2018-01-15 Thread git repository hosting
Module: xenomai-3
Branch: wip/rtnet-fixes
Commit: 33c43f43cf6d8851e08424e0ad15a42c5d88c2bf
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=33c43f43cf6d8851e08424e0ad15a42c5d88c2bf

Author: Philippe Gerum 
Date:   Tue Dec  5 11:22:59 2017 +0100

cobalt/rtdm: factor out iovec[] copy routines

---

 include/cobalt/kernel/rtdm/driver.h |   19 +
 kernel/cobalt/rtdm/drvlib.c |   80 +++
 kernel/drivers/ipc/bufp.c   |   20 -
 kernel/drivers/ipc/iddp.c   |   20 -
 kernel/drivers/ipc/internal.h   |   19 -
 kernel/drivers/ipc/rtipc.c  |   76 -
 kernel/drivers/ipc/xddp.c   |   20 -
 7 files changed, 129 insertions(+), 125 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 0c7b62e..63beb48 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -1339,6 +1339,25 @@ static inline int rtdm_in_rt_context(void)
return (ipipe_current_domain != ipipe_root_domain);
 }
 
+#define RTDM_IOV_FASTMAX  16
+
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+static inline
+void rtdm_drop_iovec(struct iovec *iov, struct iovec *iov_fast)
+{
+   if (iov != iov_fast)
+   xnfree(iov);
+}
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen);
+
 #endif /* !DOXYGEN_CPP */
 
 #endif /* _COBALT_RTDM_DRIVER_H */
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index fb7bd7e..847e18f 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "internal.h"
 #include 
 
@@ -2151,6 +2152,85 @@ int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, 
const char *func)
 }
 EXPORT_SYMBOL_GPL(rtdm_ratelimit);
 
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(struct iovec) * msg->msg_iovlen;
+   struct iovec *iov = iov_fast;
+
+   /*
+* If the I/O vector doesn't fit in the fast memory, allocate
+* a chunk from the system heap which is large enough to hold
+* it.
+*/
+   if (msg->msg_iovlen > RTDM_IOV_FASTMAX) {
+   iov = xnmalloc(len);
+   if (iov == NULL)
+   return -ENOMEM;
+   }
+
+   *iovp = iov;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(iov, msg->msg_iov, len);
+   return 0;
+   }
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   return sys32_get_iovec(iov,
+  (struct compat_iovec __user *)msg->msg_iov,
+  msg->msg_iovlen);
+#endif
+
+   return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iovec);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(iov[0]) * msg->msg_iovlen;
+   int ret;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(msg->msg_iov, iov, len);
+   ret = 0;
+   } else
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   ret = sys32_put_iovec((struct compat_iovec __user 
*)msg->msg_iov,
+ iov, msg->msg_iovlen);
+   else
+#endif
+   ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
+
+   if (iov != iov_fast)
+   xnfree(iov);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(rtdm_put_iovec);
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen)
+{
+   ssize_t len;
+   int nvec;
+
+   /* Return the flattened vector length. */
+   for (len = 0, nvec = 0; nvec < iovlen; nvec++) {
+   ssize_t l = iov[nvec].iov_len;
+   if (l < 0 || len + l < len) /* SuS wants this. */
+   return -EINVAL;
+   len += l;
+   }
+
+   return len;
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iov_flatlen);
+
 #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
 
 /**
diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c
index 3b565bd..e1c8672 100644
--- a/kernel/drivers/ipc/bufp.c
+++ b/kernel/drivers/ipc/bufp.c
@@ -307,7 +307,7 @@ static ssize_t __bufp_recvmsg(struct rtdm_fd *fd,
if (!test_bit(_BUFP_BOUND, >status))
return -EAGAIN;
 
-   len = rtipc_get_iov_flatlen(iov, iovlen);
+   len = 

[Xenomai-git] Philippe Gerum : cobalt/rtdm: factor out iovec[] copy routines

2018-01-15 Thread git repository hosting
Module: xenomai-3
Branch: wip/rtnet-fixes
Commit: 9a5a058a6fde92f7286928907a83cb47ae144a95
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=9a5a058a6fde92f7286928907a83cb47ae144a95

Author: Philippe Gerum 
Date:   Tue Dec  5 11:22:59 2017 +0100

cobalt/rtdm: factor out iovec[] copy routines

---

 include/cobalt/kernel/rtdm/driver.h |   19 +
 kernel/cobalt/rtdm/drvlib.c |   80 +++
 kernel/drivers/ipc/bufp.c   |   20 -
 kernel/drivers/ipc/iddp.c   |   20 -
 kernel/drivers/ipc/internal.h   |   19 -
 kernel/drivers/ipc/rtipc.c  |   76 -
 kernel/drivers/ipc/xddp.c   |   20 -
 7 files changed, 129 insertions(+), 125 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 0c7b62e..63beb48 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -1339,6 +1339,25 @@ static inline int rtdm_in_rt_context(void)
return (ipipe_current_domain != ipipe_root_domain);
 }
 
+#define RTDM_IOV_FASTMAX  16
+
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+static inline
+void rtdm_drop_iovec(struct iovec *iov, struct iovec *iov_fast)
+{
+   if (iov != iov_fast)
+   xnfree(iov);
+}
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen);
+
 #endif /* !DOXYGEN_CPP */
 
 #endif /* _COBALT_RTDM_DRIVER_H */
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index fb7bd7e..847e18f 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "internal.h"
 #include 
 
@@ -2151,6 +2152,85 @@ int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, 
const char *func)
 }
 EXPORT_SYMBOL_GPL(rtdm_ratelimit);
 
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(struct iovec) * msg->msg_iovlen;
+   struct iovec *iov = iov_fast;
+
+   /*
+* If the I/O vector doesn't fit in the fast memory, allocate
+* a chunk from the system heap which is large enough to hold
+* it.
+*/
+   if (msg->msg_iovlen > RTDM_IOV_FASTMAX) {
+   iov = xnmalloc(len);
+   if (iov == NULL)
+   return -ENOMEM;
+   }
+
+   *iovp = iov;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(iov, msg->msg_iov, len);
+   return 0;
+   }
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   return sys32_get_iovec(iov,
+  (struct compat_iovec __user *)msg->msg_iov,
+  msg->msg_iovlen);
+#endif
+
+   return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iovec);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(iov[0]) * msg->msg_iovlen;
+   int ret;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(msg->msg_iov, iov, len);
+   ret = 0;
+   } else
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   ret = sys32_put_iovec((struct compat_iovec __user 
*)msg->msg_iov,
+ iov, msg->msg_iovlen);
+   else
+#endif
+   ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
+
+   if (iov != iov_fast)
+   xnfree(iov);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(rtdm_put_iovec);
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen)
+{
+   ssize_t len;
+   int nvec;
+
+   /* Return the flattened vector length. */
+   for (len = 0, nvec = 0; nvec < iovlen; nvec++) {
+   ssize_t l = iov[nvec].iov_len;
+   if (l < 0 || len + l < len) /* SuS wants this. */
+   return -EINVAL;
+   len += l;
+   }
+
+   return len;
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iov_flatlen);
+
 #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
 
 /**
diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c
index 3b565bd..e1c8672 100644
--- a/kernel/drivers/ipc/bufp.c
+++ b/kernel/drivers/ipc/bufp.c
@@ -307,7 +307,7 @@ static ssize_t __bufp_recvmsg(struct rtdm_fd *fd,
if (!test_bit(_BUFP_BOUND, >status))
return -EAGAIN;
 
-   len = rtipc_get_iov_flatlen(iov, iovlen);
+   len = 

[Xenomai-git] Philippe Gerum : cobalt/rtdm: factor out iovec[] copy routines

2017-12-20 Thread git repository hosting
Module: xenomai-3
Branch: wip/rtnet-fixes
Commit: 439ee1bc1e8bfcc29a51c5d15d434b6373a4f79f
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=439ee1bc1e8bfcc29a51c5d15d434b6373a4f79f

Author: Philippe Gerum 
Date:   Tue Dec  5 11:22:59 2017 +0100

cobalt/rtdm: factor out iovec[] copy routines

---

 include/cobalt/kernel/rtdm/driver.h |   19 +
 kernel/cobalt/rtdm/drvlib.c |   80 +++
 kernel/drivers/ipc/bufp.c   |   20 -
 kernel/drivers/ipc/iddp.c   |   20 -
 kernel/drivers/ipc/internal.h   |   19 -
 kernel/drivers/ipc/rtipc.c  |   76 -
 kernel/drivers/ipc/xddp.c   |   20 -
 7 files changed, 129 insertions(+), 125 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 0c7b62e..63beb48 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -1339,6 +1339,25 @@ static inline int rtdm_in_rt_context(void)
return (ipipe_current_domain != ipipe_root_domain);
 }
 
+#define RTDM_IOV_FASTMAX  16
+
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast);
+
+static inline
+void rtdm_drop_iovec(struct iovec *iov, struct iovec *iov_fast)
+{
+   if (iov != iov_fast)
+   xnfree(iov);
+}
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen);
+
 #endif /* !DOXYGEN_CPP */
 
 #endif /* _COBALT_RTDM_DRIVER_H */
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index fb7bd7e..847e18f 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "internal.h"
 #include 
 
@@ -2151,6 +2152,85 @@ int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, 
const char *func)
 }
 EXPORT_SYMBOL_GPL(rtdm_ratelimit);
 
+int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(struct iovec) * msg->msg_iovlen;
+   struct iovec *iov = iov_fast;
+
+   /*
+* If the I/O vector doesn't fit in the fast memory, allocate
+* a chunk from the system heap which is large enough to hold
+* it.
+*/
+   if (msg->msg_iovlen > RTDM_IOV_FASTMAX) {
+   iov = xnmalloc(len);
+   if (iov == NULL)
+   return -ENOMEM;
+   }
+
+   *iovp = iov;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(iov, msg->msg_iov, len);
+   return 0;
+   }
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   return sys32_get_iovec(iov,
+  (struct compat_iovec __user *)msg->msg_iov,
+  msg->msg_iovlen);
+#endif
+
+   return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iovec);
+
+int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
+  const struct user_msghdr *msg,
+  struct iovec *iov_fast)
+{
+   size_t len = sizeof(iov[0]) * msg->msg_iovlen;
+   int ret;
+
+   if (!rtdm_fd_is_user(fd)) {
+   memcpy(msg->msg_iov, iov, len);
+   ret = 0;
+   } else
+#ifdef CONFIG_XENO_ARCH_SYS3264
+   if (rtdm_fd_is_compat(fd))
+   ret = sys32_put_iovec((struct compat_iovec __user 
*)msg->msg_iov,
+ iov, msg->msg_iovlen);
+   else
+#endif
+   ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
+
+   if (iov != iov_fast)
+   xnfree(iov);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(rtdm_put_iovec);
+
+ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen)
+{
+   ssize_t len;
+   int nvec;
+
+   /* Return the flattened vector length. */
+   for (len = 0, nvec = 0; nvec < iovlen; nvec++) {
+   ssize_t l = iov[nvec].iov_len;
+   if (l < 0 || len + l < len) /* SuS wants this. */
+   return -EINVAL;
+   len += l;
+   }
+
+   return len;
+}
+EXPORT_SYMBOL_GPL(rtdm_get_iov_flatlen);
+
 #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
 
 /**
diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c
index 3b565bd..e1c8672 100644
--- a/kernel/drivers/ipc/bufp.c
+++ b/kernel/drivers/ipc/bufp.c
@@ -307,7 +307,7 @@ static ssize_t __bufp_recvmsg(struct rtdm_fd *fd,
if (!test_bit(_BUFP_BOUND, >status))
return -EAGAIN;
 
-   len = rtipc_get_iov_flatlen(iov, iovlen);
+   len =