This patch adds a few helper routines around get_user and put_user
to ease byteswapping.

Signed-off-by: Cédric Le Goater <c...@fr.ibm.com>
---

I am not sure these routines belong to this file. There is room for 
improvement to remove the ugly  switch (sizeof(*(ptr))). Please 
comment !

 drivers/vhost/vhost.c |   93 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 72c21b790ba3..afcb3368370c 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -25,6 +25,7 @@
 #include <linux/kthread.h>
 #include <linux/cgroup.h>
 #include <linux/module.h>
+#include <linux/swab.h>
 
 #include "vhost.h"
 
@@ -1001,6 +1002,98 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct 
vhost_log *log,
 }
 EXPORT_SYMBOL_GPL(vhost_log_write);
 
+#define vq_get_user(vq, x, ptr)                                        \
+({                                                             \
+       int ret = get_user(x, ptr);                             \
+       if (vq->byteswap) {                                     \
+               switch (sizeof(*(ptr))) {                       \
+               case 2:                                         \
+                       x = swab16(x);                          \
+                       break;                                  \
+               case 4:                                         \
+                       x = swab32(x);                          \
+                       break;                                  \
+               case 8:                                         \
+                       x = swab64(x);                          \
+                       break;                                  \
+               default:                                        \
+                       break;                                  \
+               }                                               \
+       }                                                       \
+       ret;                                                    \
+})
+
+#define vq_put_user(vq, x, ptr)                                        \
+({                                                             \
+       __typeof__(*(ptr)) y = (x);                             \
+       if (vq->byteswap) {                                     \
+               switch (sizeof(*(ptr))) {                       \
+               case 2:                                         \
+                       y = swab16(x);                          \
+                       break;                                  \
+               case 4:                                         \
+                       y = swab32(x);                          \
+                       break;                                  \
+               case 8:                                         \
+                       y = swab64(x);                          \
+                       break;                                  \
+               default:                                        \
+                       break;                                  \
+               }                                               \
+       }                                                       \
+       put_user(y, ptr);                                       \
+})
+
+#define __vq_get_user(vq, x, ptr)                                      \
+({                                                             \
+       int ret = __get_user(x, ptr);                           \
+       if (vq->byteswap) {                                     \
+               switch (sizeof(*(ptr))) {                       \
+               case 2:                                         \
+                       x = swab16(x);                          \
+                       break;                                  \
+               case 4:                                         \
+                       x = swab32(x);                          \
+                       break;                                  \
+               case 8:                                         \
+                       x = swab64(x);                          \
+                       break;                                  \
+               default:                                        \
+                       break;                                  \
+               }                                               \
+       }                                                       \
+       ret;                                                    \
+})
+
+#define __vq_put_user(vq, x, ptr)                                      \
+({                                                             \
+       __typeof__(*(ptr)) y = (x);                             \
+       if (vq->byteswap) {                                     \
+               switch (sizeof(*(ptr))) {                       \
+               case 2:                                         \
+                       y = swab16(x);                          \
+                       break;                                  \
+               case 4:                                         \
+                       y = swab32(x);                          \
+                       break;                                  \
+               case 8:                                         \
+                       y = swab64(x);                          \
+                       break;                                  \
+               default:                                        \
+                       break;                                  \
+               }                                               \
+       }                                                       \
+       __put_user(y, ptr);                                     \
+})
+
+static void vring_desc_swap(struct vring_desc *desc)
+{
+       desc->addr  = swab64(desc->addr);
+       desc->len   = swab32(desc->len);
+       desc->flags = swab16(desc->flags);
+       desc->next  = swab16(desc->next);
+}
+
 static int vhost_update_used_flags(struct vhost_virtqueue *vq)
 {
        void __user *used;
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to