aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCédric Le Goater <clg@fr.ibm.com>2014-06-16 11:51:02 +0200
committerAlexey Kardashevskiy <aik@ozlabs.ru>2014-08-08 19:23:24 +1000
commitfd07bd4b157940c1b5af2c2a0e1bffe36396a482 (patch)
treed0544c0e1041cdba6cbafa5688fbb23603ff88ae
parent9fa767348ab58bd0ba9abed3672569839fd14975 (diff)
downloadpowerpc-fd07bd4b157940c1b5af2c2a0e1bffe36396a482.tar.gz
vhost: Add byteswap routines
This patch adds a few helper routines around get_user and put_user to ease byteswapping. Signed-off-by: Cédric Le Goater <clg@fr.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org> (cherry picked from commit 727174f8bb2d1be197cb94e5c0341fa640952a79) Signed-off-by: Scott E. Garfinkle <seg@us.ibm.com>
-rw-r--r--drivers/vhost/vhost.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 60aa5ad09a2fdb..e1a061e308aee1 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/cgroup.h>
+#include <linux/swab.h>
#include "vhost.h"
@@ -969,6 +970,98 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
return 0;
}
+#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;