This patch adds a few helper routines around get_user and put_user to ease byteswapping. Signed-off-by: Cédric Le Goater <clg@xxxxxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html