If we fail after we have allocated the pci device, we have
to get rid of it. Otherwise, a bogus device will be found on
the bus

Signed-off-by: Glauber Costa <[EMAIL PROTECTED]>
---
 qemu/hw/passthrough/passthrough.c |   11 +++++++----
 qemu/hw/pci.c                     |    6 ++++++
 qemu/hw/pci.h                     |    2 ++
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/qemu/hw/passthrough/passthrough.c 
b/qemu/hw/passthrough/passthrough.c
index a416098..64f0af9 100644
--- a/qemu/hw/passthrough/passthrough.c
+++ b/qemu/hw/passthrough/passthrough.c
@@ -389,13 +389,13 @@ pt_dev_t *register_real_device(PCIBus * 
        if (pt_get_real_device(pci_dev, r_bus, r_dev, r_func)) {
                fprintf(logfile, "register_real_device: Error: Couldn't get "
                        "real device (%s)!\n", e_dev_name);
-               return NULL;
+               goto out;
        }
 
        /* handle real device's MMIO/PIO BARs */
        if (pt_register_regions(pci_dev->real_device.regions,
                                pci_dev->real_device.region_number, pci_dev))
-               return (NULL);
+               goto out;
 
        /* handle interrupt routing */
        e_device = (pci_dev->dev.devfn >> 3) & 0x1f;
@@ -412,7 +412,7 @@ pt_dev_t *register_real_device(PCIBus * 
                if (rc) {
                        fprintf(logfile, "pt_bind %d failed rc=%d\n",
                                pci_dev->mirq, rc);
-                       return NULL;
+                       goto out;
                }
                sprintf(pci_dev->sirq, "%d", pci_dev->mirq);
        }
@@ -433,7 +433,7 @@ pt_dev_t *register_real_device(PCIBus * 
                        fprintf(stderr, "Could not notify kernel about "
                                "passthrough device\n");
                        perror("pt-ioctl:");
-                       return NULL;
+                       goto out;
                }
                fprintf(logfile, "Registered host PCI device %02x:%02x.%1x as "
                        "guest device %02x:%02x.%1x with hypercall support\n",
@@ -445,6 +445,9 @@ pt_dev_t *register_real_device(PCIBus * 
                r_bus, r_dev, r_func, e_dev_name);
 
        return (pci_dev);
+out:
+       pci_unregister_device(e_bus, &pci_dev->dev);
+       return NULL;
 }
 
 #define        MAX_PTDEVS 4
diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
index 72b65db..b605744 100644
--- a/qemu/hw/pci.c
+++ b/qemu/hw/pci.c
@@ -185,6 +185,12 @@ PCIDevice *pci_register_device(PCIBus *b
     return pci_dev;
 }
 
+void pci_unregister_device(PCIBus *bus, PCIDevice *dev)
+{
+       bus->devices[dev->devfn] = NULL;
+       qemu_free(dev);
+}
+
 void pci_register_io_region(PCIDevice *pci_dev, int region_num,
                             uint32_t size, int type,
                             PCIMapIORegionFunc *map_func)
diff --git a/qemu/hw/pci.h b/qemu/hw/pci.h
index e870987..220189f 100644
--- a/qemu/hw/pci.h
+++ b/qemu/hw/pci.h
@@ -70,6 +70,8 @@ PCIDevice *pci_register_device(PCIBus *b
                                PCIConfigReadFunc *config_read,
                                PCIConfigWriteFunc *config_write);
 
+void pci_unregister_device(PCIBus *bus, PCIDevice *dev);
+
 void pci_register_io_region(PCIDevice *pci_dev, int region_num,
                             uint32_t size, int type,
                             PCIMapIORegionFunc *map_func);
-- 
1.4.2


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to