aboutsummaryrefslogtreecommitdiffstats
path: root/hw/virtio-pci.c
diff options
context:
space:
mode:
authorYan Vugenfirer <yvugenfi@redhat.com>2009-09-08 10:49:41 -0400
committerAnthony Liguori <aliguori@us.ibm.com>2009-09-11 10:19:47 -0500
commited757e140c0ada220f213036e4497315d24ca8bc (patch)
treefde1552e456e1726b6102466440fd95f34c611cf /hw/virtio-pci.c
parentaa659be3dc2aa86614bcf6960f9d4af2a4362156 (diff)
VirtIO: Fix QEMU crash during Windows PNP tests
Hello, In some cases bus driver can deassert "bus master" bit in PCI command register. The driver will no longer be able to update related registers in the device. Eventually it will cause QEMU to exit in "virtqueue_num_heads" function. Attached path that fixes the described issue. Best regards, Yan Vugenfirer. >From 3fdafbdfad676ec8479dc073cff70bf356868bfe Mon Sep 17 00:00:00 2001 From: Yan Vugenfirer <yvugenfi@redhat.com> Date: Tue, 8 Sep 2009 10:08:14 -0400 Subject: [PATCH] VirtIO: Fix QEMU crash during Windows PNP tests Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/virtio-pci.c')
-rw-r--r--hw/virtio-pci.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index f812ab7a6..f7a51ff76 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -364,8 +364,17 @@ static void virtio_map(PCIDevice *pci_dev, int region_num,
static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
uint32_t val, int len)
{
+ VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+ if (PCI_COMMAND == address) {
+ if (!(val & PCI_COMMAND_MASTER)) {
+ proxy->vdev->status &= !VIRTIO_CONFIG_S_DRIVER_OK;
+ }
+ }
+
pci_default_write_config(pci_dev, address, val, len);
- msix_write_config(pci_dev, address, val, len);
+ if(proxy->vdev->nvectors)
+ msix_write_config(pci_dev, address, val, len);
}
static const VirtIOBindings virtio_pci_bindings = {
@@ -407,11 +416,12 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
msix_bar_size(&proxy->pci_dev),
PCI_ADDRESS_SPACE_MEM,
msix_mmio_map);
- proxy->pci_dev.config_write = virtio_write_config;
proxy->pci_dev.unregister = msix_uninit;
} else
vdev->nvectors = 0;
+ proxy->pci_dev.config_write = virtio_write_config;
+
size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
if (size & (size-1))
size = 1 << qemu_fls(size);