diff options
author | Jason Wang <jasowang@redhat.com> | 2017-11-22 17:57:19 +0800 |
---|---|---|
committer | Jason Wang <jasowang@redhat.com> | 2017-11-28 11:54:50 +0800 |
commit | 70e53e6e4da3db4b2c31981191753a7e974936d0 (patch) | |
tree | ea461d611a699fd39e5fc24887769871f4bcd107 /hw/net | |
parent | 5e19aed59ab48ca3c7f1e2da203eed27b91bef2d (diff) | |
download | qemu-70e53e6e4da3db4b2c31981191753a7e974936d0.zip qemu-70e53e6e4da3db4b2c31981191753a7e974936d0.tar.gz qemu-70e53e6e4da3db4b2c31981191753a7e974936d0.tar.bz2 |
virtio-net: don't touch virtqueue if vm is stopped
Guest state should not be touched if VM is stopped, unfortunately we
didn't check running state and tried to drain tx queue unconditionally
in virtio_net_set_status(). A crash was then noticed as a migration
destination when user type quit after virtqueue state is loaded but
before region cache is initialized. In this case,
virtio_net_drop_tx_queue_data() tries to access the uninitialized
region cache.
Fix this by only dropping tx queue data when vm is running.
Fixes: 283e2c2adcb80 ("net: virtio-net discards TX data after link down")
Cc: Yuri Benditovich <yuri.benditovich@daynix.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'hw/net')
-rw-r--r-- | hw/net/virtio-net.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 150fd07..38674b0 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -288,7 +288,8 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status) qemu_bh_cancel(q->tx_bh); } if ((n->status & VIRTIO_NET_S_LINK_UP) == 0 && - (queue_status & VIRTIO_CONFIG_S_DRIVER_OK)) { + (queue_status & VIRTIO_CONFIG_S_DRIVER_OK) && + vdev->vm_running) { /* if tx is waiting we are likely have some packets in tx queue * and disabled notification */ q->tx_waiting = 0; |