Revision c81131db

b/hw/virtio-pci.c
79 79
 * 12 is historical, and due to x86 page size. */
80 80
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
81 81

  
82
/* We can catch some guest bugs inside here so we continue supporting older
83
   guests. */
84
#define VIRTIO_PCI_BUG_BUS_MASTER	(1 << 0)
85

  
82 86
/* QEMU doesn't strictly need write barriers since everything runs in
83 87
 * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
84 88
 * KVM or if kqemu gets SMP support.
......
90 94
typedef struct {
91 95
    PCIDevice pci_dev;
92 96
    VirtIODevice *vdev;
97
    uint32_t bugs;
93 98
    uint32_t addr;
94 99
    uint32_t class_code;
95 100
    uint32_t nvectors;
......
144 149
    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
145 150
        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
146 151
    }
152

  
153
    /* Try to find out if the guest has bus master disabled, but is
154
       in ready state. Then we have a buggy guest OS. */
155
    if (!(proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
156
        !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
157
        proxy->bugs |= VIRTIO_PCI_BUG_BUS_MASTER;
158
    }
147 159
    return 0;
148 160
}
149 161

  
......
168 180
    VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
169 181
    virtio_reset(proxy->vdev);
170 182
    msix_reset(&proxy->pci_dev);
183
    proxy->bugs = 0;
171 184
}
172 185

  
173 186
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
......
211 224
            virtio_reset(proxy->vdev);
212 225
            msix_unuse_all_vectors(&proxy->pci_dev);
213 226
        }
227

  
228
        /* Linux before 2.6.34 sets the device as OK without enabling
229
           the PCI device bus master bit. In this case we need to disable
230
           some safety checks. */
231
        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
232
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
233
            proxy->bugs |= VIRTIO_PCI_BUG_BUS_MASTER;
234
        }
214 235
        break;
215 236
    case VIRTIO_MSI_CONFIG_VECTOR:
216 237
        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
......
377 398

  
378 399
    if (PCI_COMMAND == address) {
379 400
        if (!(val & PCI_COMMAND_MASTER)) {
380
            proxy->vdev->status &= ~VIRTIO_CONFIG_S_DRIVER_OK;
401
            if (!(proxy->bugs & VIRTIO_PCI_BUG_BUS_MASTER)) {
402
                proxy->vdev->status &= ~VIRTIO_CONFIG_S_DRIVER_OK;
403
            }
381 404
        }
382 405
    }
383 406

  

Also available in: Unified diff