]> xenbits.xensource.com Git - libvirt.git/commitdiff
Fix a potential race in pciInitDevice.
authorChris Lalancette <clalance@redhat.com>
Wed, 28 Jul 2010 18:07:08 +0000 (14:07 -0400)
committerChris Lalancette <clalance@redhat.com>
Thu, 29 Jul 2010 14:18:23 +0000 (10:18 -0400)
If detecting the FLR flag of a pci device fails, then we
could run into the situation of trying to close a file
descriptor twice, once in pciInitDevice() and once in pciFreeDevice().
Fix that by removing the pciCloseConfig() in pciInitDevice() and
just letting pciFreeDevice() handle it.

Thanks to Chris Wright for pointing out this problem.

While we are at it, fix an error check.  While it would actually
work as-is (since success returns 0), it's still more clear to
check for < 0 (as the rest of the code does).

Signed-off-by: Chris Lalancette <clalance@redhat.com>
src/qemu/qemu_driver.c
src/util/pci.c

index 767265d7a540addc7e2a988dfff877c6a9f0a01b..098f4daec0582e1e11911c5adf0ad0e79bf463c5 100644 (file)
@@ -8018,7 +8018,7 @@ static int qemudDomainAttachHostPciDevice(struct qemud_driver *driver,
         return -1;
     }
 
-    if (qemuPrepareHostdevPCIDevices(driver, &hostdev, 1))
+    if (qemuPrepareHostdevPCIDevices(driver, &hostdev, 1) < 0)
         return -1;
 
     if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
index 02d88df55f79b65a6da35ad7af7cea42cacc5325..53f9ded02fa90013035c85e86fccc5e7dafebff7 100644 (file)
@@ -188,8 +188,10 @@ pciCloseConfig(pciDevice *dev)
     if (!dev)
         return;
 
-    if (dev->fd >= 0)
+    if (dev->fd >= 0) {
         close(dev->fd);
+        dev->fd = -1;
+    }
 }
 
 static int
@@ -672,10 +674,8 @@ pciInitDevice(pciDevice *dev)
     dev->pcie_cap_pos   = pciFindCapabilityOffset(dev, PCI_CAP_ID_EXP);
     dev->pci_pm_cap_pos = pciFindCapabilityOffset(dev, PCI_CAP_ID_PM);
     flr = pciDetectFunctionLevelReset(dev);
-    if (flr < 0) {
-        pciCloseConfig(dev);
+    if (flr < 0)
         return flr;
-    }
     dev->has_flr        = flr;
     dev->has_pm_reset   = pciDetectPowerManagementReset(dev);
     dev->initted        = 1;