Skip to content

Commit ccec7e9

Browse files
AndrewAtDaynixmstsirkin
authored andcommitted
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 <[email protected]> Message-Id: <[email protected]> Cc: [email protected] Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent a4544c4 commit ccec7e9

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

hw/virtio/virtio-pci.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,22 +1333,25 @@ static uint64_t virtio_pci_notify_read(void *opaque, hwaddr addr,
13331333
static void virtio_pci_notify_write(void *opaque, hwaddr addr,
13341334
uint64_t val, unsigned size)
13351335
{
1336-
VirtIODevice *vdev = opaque;
1337-
VirtIOPCIProxy *proxy = VIRTIO_PCI(DEVICE(vdev)->parent_bus->parent);
1336+
VirtIOPCIProxy *proxy = opaque;
1337+
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
1338+
13381339
unsigned queue = addr / virtio_pci_queue_mem_mult(proxy);
13391340

1340-
if (queue < VIRTIO_QUEUE_MAX) {
1341+
if (vdev != NULL && queue < VIRTIO_QUEUE_MAX) {
13411342
virtio_queue_notify(vdev, queue);
13421343
}
13431344
}
13441345

13451346
static void virtio_pci_notify_write_pio(void *opaque, hwaddr addr,
13461347
uint64_t val, unsigned size)
13471348
{
1348-
VirtIODevice *vdev = opaque;
1349+
VirtIOPCIProxy *proxy = opaque;
1350+
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
1351+
13491352
unsigned queue = val;
13501353

1351-
if (queue < VIRTIO_QUEUE_MAX) {
1354+
if (vdev != NULL && queue < VIRTIO_QUEUE_MAX) {
13521355
virtio_queue_notify(vdev, queue);
13531356
}
13541357
}
@@ -1372,9 +1375,14 @@ static void virtio_pci_isr_write(void *opaque, hwaddr addr,
13721375
static uint64_t virtio_pci_device_read(void *opaque, hwaddr addr,
13731376
unsigned size)
13741377
{
1375-
VirtIODevice *vdev = opaque;
1378+
VirtIOPCIProxy *proxy = opaque;
1379+
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
13761380
uint64_t val = 0;
13771381

1382+
if (vdev == NULL) {
1383+
return val;
1384+
}
1385+
13781386
switch (size) {
13791387
case 1:
13801388
val = virtio_config_modern_readb(vdev, addr);
@@ -1392,7 +1400,13 @@ static uint64_t virtio_pci_device_read(void *opaque, hwaddr addr,
13921400
static void virtio_pci_device_write(void *opaque, hwaddr addr,
13931401
uint64_t val, unsigned size)
13941402
{
1395-
VirtIODevice *vdev = opaque;
1403+
VirtIOPCIProxy *proxy = opaque;
1404+
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
1405+
1406+
if (vdev == NULL) {
1407+
return;
1408+
}
1409+
13961410
switch (size) {
13971411
case 1:
13981412
virtio_config_modern_writeb(vdev, addr, val);
@@ -1469,19 +1483,19 @@ static void virtio_pci_modern_regions_init(VirtIOPCIProxy *proxy)
14691483

14701484
memory_region_init_io(&proxy->device.mr, OBJECT(proxy),
14711485
&device_ops,
1472-
virtio_bus_get_device(&proxy->bus),
1486+
proxy,
14731487
"virtio-pci-device",
14741488
proxy->device.size);
14751489

14761490
memory_region_init_io(&proxy->notify.mr, OBJECT(proxy),
14771491
&notify_ops,
1478-
virtio_bus_get_device(&proxy->bus),
1492+
proxy,
14791493
"virtio-pci-notify",
14801494
proxy->notify.size);
14811495

14821496
memory_region_init_io(&proxy->notify_pio.mr, OBJECT(proxy),
14831497
&notify_pio_ops,
1484-
virtio_bus_get_device(&proxy->bus),
1498+
proxy,
14851499
"virtio-pci-notify-pio",
14861500
proxy->notify_pio.size);
14871501
}

0 commit comments

Comments
 (0)