53 lines
1.7 KiB
Diff
53 lines
1.7 KiB
Diff
|
|
From 95d334a905e8ddaac4a8cec908dcdb03b2e5993f Mon Sep 17 00:00:00 2001
|
||
|
|
From: Jinhua Cao <caojinhua1@huawei.com>
|
||
|
|
Date: Thu, 10 Feb 2022 10:17:20 +0800
|
||
|
|
Subject: [PATCH] virtio: bugfix: clean up callback when del virtqueue
|
||
|
|
|
||
|
|
We will access NULL pointer as follow:
|
||
|
|
1. Start a vm with multiqueue vhost-net
|
||
|
|
2. then we write VIRTIO_PCI_GUEST_FEATURES in PCI configuration to
|
||
|
|
trigger multiqueue disable in this vm which will delete the virtqueue.
|
||
|
|
In this step, the tx_bh is deleted but the callback virtio_net_handle_tx_bh
|
||
|
|
still exist.
|
||
|
|
3. Finally, we write VIRTIO_PCI_QUEUE_NOTIFY in PCI configuration to
|
||
|
|
notify the deleted virtqueue. In this way, virtio_net_handle_tx_bh
|
||
|
|
will be called and qemu will be crashed.
|
||
|
|
|
||
|
|
Signed-off-by: Jinhua Cao <caojinhua1@huawei.com>
|
||
|
|
---
|
||
|
|
hw/net/virtio-net.c | 5 ++++-
|
||
|
|
hw/virtio/virtio.c | 1 +
|
||
|
|
2 files changed, 5 insertions(+), 1 deletion(-)
|
||
|
|
|
||
|
|
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
|
||
|
|
index f2014d5ea0..b3a5d0b19e 100644
|
||
|
|
--- a/hw/net/virtio-net.c
|
||
|
|
+++ b/hw/net/virtio-net.c
|
||
|
|
@@ -2644,7 +2644,10 @@ static void virtio_net_handle_tx_bh(VirtIODevice *vdev, VirtQueue *vq)
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
virtio_queue_set_notification(vq, 0);
|
||
|
|
- qemu_bh_schedule(q->tx_bh);
|
||
|
|
+
|
||
|
|
+ if (q->tx_bh) {
|
||
|
|
+ qemu_bh_schedule(q->tx_bh);
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
static void virtio_net_tx_timer(void *opaque)
|
||
|
|
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
|
||
|
|
index 9b4ac58a16..ec3e96af3b 100644
|
||
|
|
--- a/hw/virtio/virtio.c
|
||
|
|
+++ b/hw/virtio/virtio.c
|
||
|
|
@@ -2417,6 +2417,7 @@ void virtio_delete_queue(VirtQueue *vq)
|
||
|
|
{
|
||
|
|
vq->vring.num = 0;
|
||
|
|
vq->vring.num_default = 0;
|
||
|
|
+ vq->vring.align = 0;
|
||
|
|
vq->handle_output = NULL;
|
||
|
|
vq->handle_aio_output = NULL;
|
||
|
|
g_free(vq->used_elems);
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|