From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35559) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aHEI5-0007YG-DI for qemu-devel@nongnu.org; Thu, 07 Jan 2016 12:24:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aHEI1-0002HT-Te for qemu-devel@nongnu.org; Thu, 07 Jan 2016 12:24:01 -0500 Received: from e06smtp08.uk.ibm.com ([195.75.94.104]:48373) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aHEI1-0002HG-Kr for qemu-devel@nongnu.org; Thu, 07 Jan 2016 12:23:57 -0500 Received: from localhost by e06smtp08.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 7 Jan 2016 17:23:56 -0000 Received: from b06cxnps3075.portsmouth.uk.ibm.com (d06relay10.portsmouth.uk.ibm.com [9.149.109.195]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id AE1C717D805F for ; Thu, 7 Jan 2016 17:24:38 +0000 (GMT) Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u07HNqWG1179952 for ; Thu, 7 Jan 2016 17:23:53 GMT Received: from d06av02.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u07HNqR0032462 for ; Thu, 7 Jan 2016 10:23:52 -0700 Date: Thu, 7 Jan 2016 18:23:49 +0100 From: Greg Kurz Message-ID: <20160107182349.424d08dc@bahia.local> In-Reply-To: <568E90CA.6090501@redhat.com> References: <20160107110747.10897.41118.stgit@bahia.huguette.org> <20160107113202.10897.33293.stgit@bahia.huguette.org> <568E90CA.6090501@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 1/6] virtio-net: use the backend cross-endian capabilities List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Laurent Vivier Cc: qemu-devel@nongnu.org, "Michael S. Tsirkin" On Thu, 7 Jan 2016 17:22:34 +0100 Laurent Vivier wrote: > > > On 07/01/2016 12:32, Greg Kurz wrote: > > When running a fully emulated device in cross-endian conditions, including > > a virtio 1.0 device offered to a big endian guest, we need to fix the vnet > > headers. This is currently handled by the virtio_net_hdr_swap() function > > in the core virtio-net code but it should actually be handled by the net > > backend. > > > > With this patch, virtio-net now tries to configure the backend to do the > > endian fixing when the device starts. If the backend cannot support the > > requested endiannes, we have to fall back on virtio_net_hdr_swap(): this > > is recorded in the needs_vnet_hdr_swap flag, to be used in the TX and RX > > paths. > > > > The current vhost-net code also tries to configure net backends. This will > > be no more needed and will be addressed in a subsequent patch. > > > > Signed-off-by: Greg Kurz > > --- > > hw/net/virtio-net.c | 33 +++++++++++++++++++++++++++++++-- > > include/hw/virtio/virtio-net.h | 1 + > > 2 files changed, 32 insertions(+), 2 deletions(-) > > > > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c > > index a877614e3e7a..d4cc94ea5e55 100644 > > --- a/hw/net/virtio-net.c > > +++ b/hw/net/virtio-net.c > > @@ -152,6 +152,31 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status) > > } > > } > > > > +static void virtio_net_vnet_status(VirtIONet *n, uint8_t status) > > +{ > > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > > + NetClientState *peer = qemu_get_queue(n->nic)->peer; > > + > > + if (virtio_net_started(n, status)) { > > + int r; > > + > > + if (virtio_is_big_endian(vdev)) { > > + r = qemu_set_vnet_be(peer, true); > > + } else { > > + r = qemu_set_vnet_le(peer, true); > > + } > > + > > + n->needs_vnet_hdr_swap = !!r; > > + } else if (virtio_net_started(n, vdev->status) && > > + !virtio_net_started(n, status)) { > > Except if I miss something, > > "!virtio_net_started(n, status)" is always true in the case of > "if (virtio_net_started(n, status)) { } else ...". > Of course... I'll fix it. > > + if (virtio_is_big_endian(vdev)) { > > + qemu_set_vnet_be(peer, false); > > + } else { > > + qemu_set_vnet_le(peer, false); > > + } > > + } > > +} > > + > > static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status) > > { > > VirtIONet *n = VIRTIO_NET(vdev); > > @@ -159,6 +184,7 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status) > > int i; > > uint8_t queue_status; > > > > + virtio_net_vnet_status(n, status); > > virtio_net_vhost_status(n, status); > > > > for (i = 0; i < n->max_queues; i++) { > > @@ -957,7 +983,10 @@ static void receive_header(VirtIONet *n, const struct iovec *iov, int iov_cnt, > > void *wbuf = (void *)buf; > > work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len, > > size - n->host_hdr_len); > > - virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf); > > + > > + if (n->needs_vnet_hdr_swap) { > > + virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf); > > + } > > iov_from_buf(iov, iov_cnt, 0, buf, sizeof(struct virtio_net_hdr)); > > } else { > > struct virtio_net_hdr hdr = { > > @@ -1167,7 +1196,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) > > error_report("virtio-net header incorrect"); > > exit(1); > > } > > - if (virtio_needs_swap(vdev)) { > > + if (n->needs_vnet_hdr_swap) { > > virtio_net_hdr_swap(vdev, (void *) &mhdr); > > sg2[0].iov_base = &mhdr; > > sg2[0].iov_len = n->guest_hdr_len; > > diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h > > index f3cc25feca2b..27bc868fbc7d 100644 > > --- a/include/hw/virtio/virtio-net.h > > +++ b/include/hw/virtio/virtio-net.h > > @@ -94,6 +94,7 @@ typedef struct VirtIONet { > > uint64_t curr_guest_offloads; > > QEMUTimer *announce_timer; > > int announce_counter; > > + bool needs_vnet_hdr_swap; > > } VirtIONet; > > > > void virtio_net_set_netclient_name(VirtIONet *n, const char *name, > > > > >