diff options
author | Cédric Le Goater <clg@fr.ibm.com> | 2014-06-16 11:51:02 +0200 |
---|---|---|
committer | Alexey Kardashevskiy <aik@ozlabs.ru> | 2014-08-08 19:23:24 +1000 |
commit | fd07bd4b157940c1b5af2c2a0e1bffe36396a482 (patch) | |
tree | d0544c0e1041cdba6cbafa5688fbb23603ff88ae | |
parent | 9fa767348ab58bd0ba9abed3672569839fd14975 (diff) | |
download | powerpc-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.c | 93 |
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; |