Commit 89c473fd authored by Michael S. Tsirkin's avatar Michael S. Tsirkin
Browse files

virtio-pci: fix bus master work around on load



Commit c81131db
detects old guests by comparing virtio and
PCI status. It attempts to do this on load,
as well, but load_config callback in a binding
is invoked too early and so the virtio status
isn't set yet.

We could add yet another callback to the
binding, to invoke after load, but it
seems easier to reuse the existing vmstate
callback.

Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Cc: Alexander Graf <agraf@suse.de>
parent 6f3279b5
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -160,13 +160,6 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
    }

    /* Try to find out if the guest has bus master disabled, but is
       in ready state. Then we have a buggy guest OS. */
    if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
        !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
        proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
    }
    return 0;
}

@@ -651,6 +644,12 @@ static void virtio_pci_vmstate_change(void *opaque, bool running)
    VirtIOPCIProxy *proxy = opaque;

    if (running) {
        /* Try to find out if the guest has bus master disabled, but is
           in ready state. Then we have a buggy guest OS. */
        if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
        }
        virtio_pci_start_ioeventfd(proxy);
    } else {
        virtio_pci_stop_ioeventfd(proxy);
+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ typedef struct {
    void (*save_queue)(void * opaque, int n, QEMUFile *f);
    int (*load_config)(void * opaque, QEMUFile *f);
    int (*load_queue)(void * opaque, int n, QEMUFile *f);
    int (*load_done)(void * opaque, QEMUFile *f);
    unsigned (*get_features)(void * opaque);
    bool (*query_guest_notifiers)(void * opaque);
    int (*set_guest_notifiers)(void * opaque, bool assigned);