From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54235) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XjOqx-0003kA-UT for qemu-devel@nongnu.org; Wed, 29 Oct 2014 04:43:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XjOqm-0006Mo-OK for qemu-devel@nongnu.org; Wed, 29 Oct 2014 04:43:39 -0400 Received: from e06smtp12.uk.ibm.com ([195.75.94.108]:53558) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XjOqm-0006MO-G4 for qemu-devel@nongnu.org; Wed, 29 Oct 2014 04:43:28 -0400 Received: from /spool/local by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 29 Oct 2014 08:43:27 -0000 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Wed, 29 Oct 2014 09:42:09 +0100 Message-Id: <1414572130-17014-2-git-send-email-clg@fr.ibm.com> In-Reply-To: <1414572130-17014-1-git-send-email-clg@fr.ibm.com> References: <1414572130-17014-1-git-send-email-clg@fr.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [Qemu-devel] [RFC PATCH 1/2] vhost: add VHOST_VRING_F_BYTESWAP flag List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: mst@redhat.com Cc: aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , paulus@samba.org, qemu-ppc@nongnu.org When the guest and the host have a different endian order, the data being accessed in the vring queues needs to be byteswapped. This patch adds a VHOST_VRING_F_BYTESWAP flag to inform the vhost kernel backend to byteswap vring data. Signed-off-by: Cédric Le Goater --- hw/virtio/vhost.c | 25 ++++++++++++++++++++++++- include/hw/virtio/vhost.h | 1 + linux-headers/linux/vhost.h | 3 +++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 5d7c40ac04d0..75308d127d90 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -539,7 +539,13 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev, .log_guest_addr = vq->used_phys, .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0, }; - int r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ADDR, &addr); + int r; + + if (vq->byteswap) { + addr.flags |= (1 << VHOST_VRING_F_BYTESWAP); + } + + r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ADDR, &addr); if (r < 0) { return -errno; } @@ -647,6 +653,21 @@ static void vhost_log_stop(MemoryListener *listener, /* FIXME: implement */ } + +static bool vhost_virtqueue_needs_byteswap(VirtIODevice *vdev) +{ +#ifdef TARGET_IS_BIENDIAN +#ifdef HOST_WORDS_BIGENDIAN + return !virtio_is_big_endian(vdev); +#else + return virtio_is_big_endian(vdev); +#endif + +#else + return false; +#endif +} + static int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev, struct vhost_virtqueue *vq, @@ -707,6 +728,8 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, goto fail_alloc_ring; } + vq->byteswap = vhost_virtqueue_needs_byteswap(vdev); + r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled); if (r < 0) { r = -errno; diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index d5593d162079..793f89d71ffb 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -20,6 +20,7 @@ struct vhost_virtqueue { unsigned long long ring_phys; unsigned ring_size; EventNotifier masked_notifier; + bool byteswap; }; typedef unsigned long vhost_log_chunk_t; diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h index c656f61cfc75..0bbd3f1209f3 100644 --- a/linux-headers/linux/vhost.h +++ b/linux-headers/linux/vhost.h @@ -34,6 +34,9 @@ struct vhost_vring_addr { /* Flag values: */ /* Whether log address is valid. If set enables logging. */ #define VHOST_VRING_F_LOG 0 + /* Whether vring memory accesses should be byte-swapped. + * required when the guest has a different endianess */ +#define VHOST_VRING_F_BYTESWAP 1 /* Start of array of descriptors (virtually contiguous) */ __u64 desc_user_addr; -- 1.7.10.4