diff --git a/hw/pci.c b/hw/pci.c index 679f06737f..8d84651f19 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -324,7 +324,7 @@ static VMStateInfo vmstate_info_pci_config = { static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size) { - PCIDevice *s = container_of(pv, PCIDevice, config); + PCIDevice *s = container_of(pv, PCIDevice, irq_state); uint32_t irq_state[PCI_NUM_PINS]; int i; for (i = 0; i < PCI_NUM_PINS; ++i) { @@ -346,7 +346,7 @@ static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size) static void put_pci_irq_state(QEMUFile *f, void *pv, size_t size) { int i; - PCIDevice *s = container_of(pv, PCIDevice, config); + PCIDevice *s = container_of(pv, PCIDevice, irq_state); for (i = 0; i < PCI_NUM_PINS; ++i) { qemu_put_be32(f, pci_irq_state(s, i)); @@ -627,6 +627,13 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, return pci_dev; } +static void do_pci_unregister_device(PCIDevice *pci_dev) +{ + qemu_free_irqs(pci_dev->irq); + pci_dev->bus->devices[pci_dev->devfn] = NULL; + pci_config_free(pci_dev); +} + PCIDevice *pci_register_device(PCIBus *bus, const char *name, int instance_size, int devfn, PCIConfigReadFunc *config_read, @@ -682,10 +689,7 @@ static int pci_unregister_device(DeviceState *dev) return ret; pci_unregister_io_regions(pci_dev); - - qemu_free_irqs(pci_dev->irq); - pci_dev->bus->devices[pci_dev->devfn] = NULL; - pci_config_free(pci_dev); + do_pci_unregister_device(pci_dev); return 0; } @@ -1654,8 +1658,10 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) if (pci_dev == NULL) return -1; rc = info->init(pci_dev); - if (rc != 0) + if (rc != 0) { + do_pci_unregister_device(pci_dev); return rc; + } /* rom loading */ if (pci_dev->romfile == NULL && info->romfile != NULL) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index d602c56c25..cb664e6207 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -227,7 +227,7 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) if (!tap_get_vhost_net(n->nic->nc.peer)) { return; } - return vhost_net_ack_features(tap_get_vhost_net(n->nic->nc.peer), features); + vhost_net_ack_features(tap_get_vhost_net(n->nic->nc.peer), features); } static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd, diff --git a/hw/virtio.c b/hw/virtio.c index e7657ae8aa..4475bb3e44 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -677,6 +677,8 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) features, supported_features); return -1; } + if (vdev->set_features) + vdev->set_features(vdev, features); vdev->guest_features = features; vdev->config_len = qemu_get_be32(f); qemu_get_buffer(f, vdev->config, vdev->config_len);