[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen staging] virtio-pci: Changed vdev to proxy for VirtIO PCI BAR callbacks.



commit ccec7e9603f446fe75c6c563ba335c00cfda6a06
Author:     Andrew Melnychenko <andrew@xxxxxxxxxx>
AuthorDate: Mon Jul 6 14:21:23 2020 +0300
Commit:     Michael S. Tsirkin <mst@xxxxxxxxxx>
CommitDate: Wed Jul 22 08:05:37 2020 -0400

    virtio-pci: Changed vdev to proxy for VirtIO PCI BAR callbacks.
    
    There is an issue when callback may be called with invalid vdev.
    It happens on unplug when vdev already deleted and VirtIOPciProxy is not.
    So now, callbacks accept proxy device, and vdev retrieved from it.
    Technically memio callbacks should be removed during the flatview update,
    but memoryregions remain til PCI device(and it's address space) completely 
deleted.
    Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1716352
    
    Signed-off-by: Andrew Melnychenko <andrew@xxxxxxxxxx>
    Message-Id: <20200706112123.971087-1-andrew@xxxxxxxxxx>
    Cc: qemu-stable@xxxxxxxxxx
    Reviewed-by: Michael S. Tsirkin <mst@xxxxxxxxxx>
    Signed-off-by: Michael S. Tsirkin <mst@xxxxxxxxxx>
---
 hw/virtio/virtio-pci.c | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index db8b711b35..ada1101d07 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1333,11 +1333,12 @@ static uint64_t virtio_pci_notify_read(void *opaque, 
hwaddr addr,
 static void virtio_pci_notify_write(void *opaque, hwaddr addr,
                                     uint64_t val, unsigned size)
 {
-    VirtIODevice *vdev = opaque;
-    VirtIOPCIProxy *proxy = VIRTIO_PCI(DEVICE(vdev)->parent_bus->parent);
+    VirtIOPCIProxy *proxy = opaque;
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+
     unsigned queue = addr / virtio_pci_queue_mem_mult(proxy);
 
-    if (queue < VIRTIO_QUEUE_MAX) {
+    if (vdev != NULL && queue < VIRTIO_QUEUE_MAX) {
         virtio_queue_notify(vdev, queue);
     }
 }
@@ -1345,10 +1346,12 @@ static void virtio_pci_notify_write(void *opaque, 
hwaddr addr,
 static void virtio_pci_notify_write_pio(void *opaque, hwaddr addr,
                                         uint64_t val, unsigned size)
 {
-    VirtIODevice *vdev = opaque;
+    VirtIOPCIProxy *proxy = opaque;
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+
     unsigned queue = val;
 
-    if (queue < VIRTIO_QUEUE_MAX) {
+    if (vdev != NULL && queue < VIRTIO_QUEUE_MAX) {
         virtio_queue_notify(vdev, queue);
     }
 }
@@ -1372,9 +1375,14 @@ static void virtio_pci_isr_write(void *opaque, hwaddr 
addr,
 static uint64_t virtio_pci_device_read(void *opaque, hwaddr addr,
                                        unsigned size)
 {
-    VirtIODevice *vdev = opaque;
+    VirtIOPCIProxy *proxy = opaque;
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
     uint64_t val = 0;
 
+    if (vdev == NULL) {
+        return val;
+    }
+
     switch (size) {
     case 1:
         val = virtio_config_modern_readb(vdev, addr);
@@ -1392,7 +1400,13 @@ static uint64_t virtio_pci_device_read(void *opaque, 
hwaddr addr,
 static void virtio_pci_device_write(void *opaque, hwaddr addr,
                                     uint64_t val, unsigned size)
 {
-    VirtIODevice *vdev = opaque;
+    VirtIOPCIProxy *proxy = opaque;
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+
+    if (vdev == NULL) {
+        return;
+    }
+
     switch (size) {
     case 1:
         virtio_config_modern_writeb(vdev, addr, val);
@@ -1469,19 +1483,19 @@ static void 
virtio_pci_modern_regions_init(VirtIOPCIProxy *proxy)
 
     memory_region_init_io(&proxy->device.mr, OBJECT(proxy),
                           &device_ops,
-                          virtio_bus_get_device(&proxy->bus),
+                          proxy,
                           "virtio-pci-device",
                           proxy->device.size);
 
     memory_region_init_io(&proxy->notify.mr, OBJECT(proxy),
                           &notify_ops,
-                          virtio_bus_get_device(&proxy->bus),
+                          proxy,
                           "virtio-pci-notify",
                           proxy->notify.size);
 
     memory_region_init_io(&proxy->notify_pio.mr, OBJECT(proxy),
                           &notify_pio_ops,
-                          virtio_bus_get_device(&proxy->bus),
+                          proxy,
                           "virtio-pci-notify-pio",
                           proxy->notify_pio.size);
 }
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#staging



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.