From 23bfaf77fa801ba30bb136de7cec47728eb02f4b Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 25 Mar 2019 11:40:36 +0800 Subject: [PATCH 1/4] vhost_net: don't set backend for the uninitialized virtqueue We used to set backend unconditionally, this won't work for some guests (e.g windows driver) who may not initialize all virtqueues. For kernel backend, this will fail since it may try to validate the rings during setting backend. Fixing this by simply skipping the backend set when we find desc is not ready. Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- hw/net/vhost_net.c | 10 ++++++++++ hw/virtio/virtio.c | 5 +++++ include/hw/virtio/virtio.h | 1 + 3 files changed, 16 insertions(+) diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index be3cc88370..a6b719035c 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -244,6 +244,11 @@ static int vhost_net_start_one(struct vhost_net *net, qemu_set_fd_handler(net->backend, NULL, NULL, NULL); file.fd = net->backend; for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { + if (!virtio_queue_enabled(dev, net->dev.vq_index + + file.index)) { + /* Queue might not be ready for start */ + continue; + } r = vhost_net_set_backend(&net->dev, &file); if (r < 0) { r = -errno; @@ -256,6 +261,11 @@ fail: file.fd = -1; if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) { while (file.index-- > 0) { + if (!virtio_queue_enabled(dev, net->dev.vq_index + + file.index)) { + /* Queue might not be ready for start */ + continue; + } int r = vhost_net_set_backend(&net->dev, &file); assert(r >= 0); } diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 2626a895cb..28056a7ef7 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2318,6 +2318,11 @@ hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n) return vdev->vq[n].vring.desc; } +bool virtio_queue_enabled(VirtIODevice *vdev, int n) +{ + return virtio_queue_get_desc_addr(vdev, n) != 0; +} + hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n) { return vdev->vq[n].vring.avail; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index ce9516236a..7140381e3a 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -282,6 +282,7 @@ typedef struct VirtIORNGConf VirtIORNGConf; VIRTIO_F_IOMMU_PLATFORM, false) hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); +bool virtio_queue_enabled(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_used_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n); From 427ceb0fecf7afcfd76ae65f7197188b2842d385 Mon Sep 17 00:00:00 2001 From: Chris Kenna Date: Thu, 4 Apr 2019 10:21:26 -0500 Subject: [PATCH 2/4] e1000: Never increment the RX undersize count register In situations where e1000 receives an undersized Ethernet frame, QEMU increments the emulated "Receive Undersize Count (RUC)" register when padding the frame. This is incorrect because this an expected scenario (e.g. with VLAN tag stripping) and not an error. As such, QEMU should not increment the emulated RUC. Fixes: 3b2743017749 ("e1000: Implementing various counters") Reviewed-by: Mark Kanda Reviewed-by: Bhavesh Davda Reviewed-by: Stefano Garzarella Signed-off-by: Chris Kenna Signed-off-by: Jason Wang --- hw/net/e1000.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 9b39bccfb2..121452d508 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -901,7 +901,6 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) if (size < sizeof(min_buf)) { iov_to_buf(iov, iovcnt, 0, min_buf, size); memset(&min_buf[size], 0, sizeof(min_buf) - size); - e1000x_inc_reg_if_not_full(s->mac_reg, RUC); min_iov.iov_base = filter_buf = min_buf; min_iov.iov_len = size = sizeof(min_buf); iovcnt = 1; From 178a0a5dea382ac13bc2cdd3c9c4c5728a40b06b Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Wed, 15 May 2019 11:08:05 +0200 Subject: [PATCH 3/4] net/slirp: fix the IPv6 prefix length error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reword and add a missing parentheses at the end of the error message. Signed-off-by: Stefano Garzarella Reviewed-by: Marc-André Lureau Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Markus Armbruster Signed-off-by: Jason Wang --- net/slirp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/slirp.c b/net/slirp.c index 95934fb36d..b34cb29276 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -498,7 +498,8 @@ static int net_slirp_init(NetClientState *peer, const char *model, } if (vprefix6_len < 0 || vprefix6_len > 126) { error_setg(errp, - "Invalid prefix provided (prefix len must be in range 0-126"); + "Invalid IPv6 prefix provided " + "(IPv6 prefix length must be between 0 and 126)"); return -1; } From 78e4f446d2569210a8558946b2321f9ff2ef47f6 Mon Sep 17 00:00:00 2001 From: Lukas Straub Date: Sat, 20 Apr 2019 19:14:25 +0200 Subject: [PATCH 4/4] net/colo-compare.c: Fix a crash in COLO Primary. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because event_unhandled_count may be accessed concurrently, it needs to be protected by taking the lock. However the assert is outside the lock, probably causing it to read garbage and aborting Qemu erroneously. The Bug only happens when running Qemu in COLO mode. This Patch fixes the following bug: https://bugs.launchpad.net/qemu/+bug/1824622 Signed-off-by: Lukas Straub Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Zhang Chen Signed-off-by: Jason Wang --- net/colo-compare.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/colo-compare.c b/net/colo-compare.c index bf10526f05..fcb491121b 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -813,9 +813,8 @@ static void colo_compare_handle_event(void *opaque) break; } - assert(event_unhandled_count > 0); - qemu_mutex_lock(&event_mtx); + assert(event_unhandled_count > 0); event_unhandled_count--; qemu_cond_broadcast(&event_complete_cond); qemu_mutex_unlock(&event_mtx);