The virtqueue's vdev points to the functional device, while the PCI I/O
register mapping belongs to its parent transport. The current lookup
therefore treats the functional driver's private data as transport data
and uses a queue pointer as the register base.

Queue deletion can overwrite the queue's list links and crash when
unlinking it. Fetch the parent transport's private data instead.

Fixes: 550435edf810 ("virtio: pci: Support non-legacy PCI transport device")
Signed-off-by: Bin Meng <[email protected]>
---

 drivers/virtio/virtio_pci_modern.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/virtio/virtio_pci_modern.c 
b/drivers/virtio/virtio_pci_modern.c
index 5850e0c18c6..d309f9a9dc1 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -305,7 +305,7 @@ error_available:
 
 static void virtio_pci_del_vq(struct virtqueue *vq)
 {
-       struct virtio_pci_priv *priv = dev_get_priv(vq->vdev);
+       struct virtio_pci_priv *priv = dev_get_priv(vq->vdev->parent);
        unsigned int index = vq->index;
 
        iowrite16(index, &priv->common->queue_select);
-- 
2.53.0

Reply via email to