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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Oct 30 10:02:35 2014 +0100

drivers/timerbench: fix 32/64bit neutrality issue

---

 include/cobalt/kernel/rtdm/testing.h |   16 ++++
 kernel/drivers/testing/timerbench.c  |  141 ++++++++++++++++++++++------------
 2 files changed, 108 insertions(+), 49 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/testing.h 
b/include/cobalt/kernel/rtdm/testing.h
index 6a66990..2cf96a2 100644
--- a/include/cobalt/kernel/rtdm/testing.h
+++ b/include/cobalt/kernel/rtdm/testing.h
@@ -22,4 +22,20 @@
 #include <rtdm/rtdm.h>
 #include <rtdm/uapi/testing.h>
 
+#ifdef CONFIG_COMPAT
+
+#include <rtdm/compat.h>
+
+struct compat_rttst_overall_bench_res {
+       struct rttst_bench_res result;
+       compat_uptr_t histogram_avg;
+       compat_uptr_t histogram_min;
+       compat_uptr_t histogram_max;
+};
+
+#define RTTST_RTIOC_TMBENCH_STOP_COMPAT \
+       _IOWR(RTIOC_TYPE_TESTING, 0x11, struct compat_rttst_overall_bench_res)
+
+#endif /* CONFIG_COMPAT */
+
 #endif /* !_COBALT_RTDM_TESTING_H */
diff --git a/kernel/drivers/testing/timerbench.c 
b/kernel/drivers/testing/timerbench.c
index 9dc0e3e..bc4f35d 100644
--- a/kernel/drivers/testing/timerbench.c
+++ b/kernel/drivers/testing/timerbench.c
@@ -315,11 +315,86 @@ static int rt_tmbench_start(struct rtdm_fd *fd,
        return err;
 }
 
-static int rt_tmbench_stop(struct rt_tmbench_context *ctx,
-                          struct rttst_overall_bench_res __user *user_res)
+static int kernel_copy_results(struct rt_tmbench_context *ctx,
+                              struct rttst_overall_bench_res *res)
+{
+       int size;
+
+       memcpy(&res->result, &ctx->result.overall, sizeof(res->result));
+
+       if (ctx->histogram_size > 0) {
+               size = ctx->histogram_size * sizeof(int32_t);
+               memcpy(res->histogram_min, ctx->histogram_min, size);
+               memcpy(res->histogram_max, ctx->histogram_max, size);
+               memcpy(res->histogram_avg, ctx->histogram_avg, size);
+               kfree(ctx->histogram_min);
+       }
+
+       return 0;
+}
+
+static int user_copy_results(struct rt_tmbench_context *ctx,
+                            struct rttst_overall_bench_res __user *u_res)
 {
        struct rtdm_fd *fd = rtdm_private_to_fd(ctx);
-       int err = 0;
+       struct rttst_overall_bench_res res_buf;
+       int ret, size;
+
+       ret = rtdm_safe_copy_to_user(fd, &u_res->result,
+                                    &ctx->result.overall,
+                                    sizeof(u_res->result));
+       if (ret || ctx->histogram_size == 0)
+               return ret;
+
+       size = ctx->histogram_size * sizeof(int32_t);
+
+       if (rtdm_safe_copy_from_user(fd, &res_buf, u_res, sizeof(res_buf)) < 0 
||
+           rtdm_safe_copy_to_user(fd, res_buf.histogram_min,
+                                  ctx->histogram_min, size) < 0 ||
+           rtdm_safe_copy_to_user(fd, res_buf.histogram_max,
+                                  ctx->histogram_max, size) < 0 ||
+           rtdm_safe_copy_to_user(fd, res_buf.histogram_avg,
+                                  ctx->histogram_avg, size) < 0)
+               return -EFAULT;
+
+       return 0;
+}
+
+#ifdef CONFIG_COMPAT
+
+static int compat_user_copy_results(struct rt_tmbench_context *ctx,
+                                   struct compat_rttst_overall_bench_res 
__user *u_res)
+{
+       struct compat_rttst_overall_bench_res res_buf;
+       struct rtdm_fd *fd = rtdm_private_to_fd(ctx);
+       int ret, size;
+
+       ret = rtdm_safe_copy_to_user(fd, &u_res->result,
+                                    &ctx->result.overall,
+                                    sizeof(u_res->result));
+       if (ret || ctx->histogram_size == 0)
+               return ret;
+
+       size = ctx->histogram_size * sizeof(int32_t);
+
+       if (rtdm_safe_copy_from_user(fd, &res_buf, u_res, sizeof(res_buf)) < 0 
||
+           rtdm_safe_copy_to_user(fd, compat_ptr(res_buf.histogram_min),
+                                  ctx->histogram_min, size) < 0 ||
+           rtdm_safe_copy_to_user(fd, compat_ptr(res_buf.histogram_max),
+                                  ctx->histogram_max, size) < 0 ||
+           rtdm_safe_copy_to_user(fd, compat_ptr(res_buf.histogram_avg),
+                                  ctx->histogram_avg, size) < 0)
+               return -EFAULT;
+
+       return 0;
+}
+
+#endif /* CONFIG_COMPAT */
+
+static int rt_tmbench_stop(struct rt_tmbench_context *ctx, void *u_res)
+{
+       struct rtdm_fd *fd = rtdm_private_to_fd(ctx);
+       int ret;
 
        down(&ctx->nrt_mutex);
 
@@ -342,54 +417,22 @@ static int rt_tmbench_stop(struct rt_tmbench_context *ctx,
                   ((ctx->result.overall.test_loops) > 1 ?
                    ctx->result.overall.test_loops : 2) - 1);
 
-       if (rtdm_fd_is_user(fd))
-               err = rtdm_safe_copy_to_user(fd, &user_res->result,
-                                            &ctx->result.overall,
-                                            sizeof(struct rttst_bench_res));
-               /* Do not break on error here - we may have to free a
-                  histogram buffer first. */
-       else {
-               struct rttst_overall_bench_res *res =
-                       (struct rttst_overall_bench_res *)user_res;
-
-               memcpy(&res->result, &ctx->result.overall,
-                      sizeof(struct rttst_bench_res));
-       }
-
-       if (ctx->histogram_size > 0) {
-               int size = ctx->histogram_size * sizeof(int32_t);
-
-               if (rtdm_fd_is_user(fd)) {
-                       struct rttst_overall_bench_res res_buf;
-
-                       if (rtdm_safe_copy_from_user(fd,
-                                                    &res_buf, user_res,
-                                                    sizeof(res_buf)) < 0 ||
-                           rtdm_safe_copy_to_user(fd,
-                                   (void __user *)res_buf.histogram_min,
-                                   ctx->histogram_min, size) < 0 ||
-                           rtdm_safe_copy_to_user(fd,
-                                   (void __user *)res_buf.histogram_max,
-                                   ctx->histogram_max, size) < 0 ||
-                           rtdm_safe_copy_to_user(fd,
-                                   (void __user *)res_buf.histogram_avg,
-                                   ctx->histogram_avg, size) < 0)
-                               err = -EFAULT;
-               } else {
-                       struct rttst_overall_bench_res *res =
-                               (struct rttst_overall_bench_res *)user_res;
-
-                       memcpy(res->histogram_min, ctx->histogram_min, size);
-                       memcpy(res->histogram_max, ctx->histogram_max, size);
-                       memcpy(res->histogram_avg, ctx->histogram_avg, size);
-               }
-
+       if (rtdm_fd_is_user(fd)) {
+#ifdef CONFIG_COMPAT
+               if (rtdm_fd_is_compat(fd))
+                       ret = compat_user_copy_results(ctx, u_res);
+               else
+#endif
+                       ret = user_copy_results(ctx, u_res);
+       } else
+               ret = kernel_copy_results(ctx, u_res);
+
+       if (ctx->histogram_size > 0)
                kfree(ctx->histogram_min);
-       }
 
        up(&ctx->nrt_mutex);
 
-       return err;
+       return ret;
 }
 
 static int rt_tmbench_ioctl_nrt(struct rtdm_fd *fd,
@@ -405,11 +448,11 @@ static int rt_tmbench_ioctl_nrt(struct rtdm_fd *fd,
                err = rt_tmbench_start(fd, ctx, arg);
                break;
 
-       case RTTST_RTIOC_TMBENCH_STOP:
+       COMPAT_CASE(RTTST_RTIOC_TMBENCH_STOP):
                err = rt_tmbench_stop(ctx, arg);
                break;
        default:
-               err = -ENOTTY;
+               err = -EINVAL;
        }
 
        return err;


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

Reply via email to