From 23bfaf77fa801ba30bb136de7cec47728eb02f4b Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 25 Mar 2019 11:40:36 +0800 Subject: 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 +++++ 2 files changed, 15 insertions(+) (limited to 'hw') diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index be3cc88..a6b7190 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 2626a89..28056a7 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; -- cgit v1.1 From 427ceb0fecf7afcfd76ae65f7197188b2842d385 Mon Sep 17 00:00:00 2001 From: Chris Kenna Date: Thu, 4 Apr 2019 10:21:26 -0500 Subject: 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(-) (limited to 'hw') diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 9b39bcc..121452d 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; -- cgit v1.1