diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 63ddd35fb5d8649df8c364b959aaaf607382ec43..45a2cfcaaec74d0292a12826ae2976b802850d1a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3107,7 +3107,7 @@ qemuPrepareHostdevPCIDevices(struct qemud_driver *driver, * reset them */ for (i = 0; i < pciDeviceListCount(pcidevs); i++) { pciDevice *dev = pciDeviceListGet(pcidevs, i); - if (pciResetDevice(dev, driver->activePciHostdevs) < 0) + if (pciResetDevice(dev, driver->activePciHostdevs, pcidevs) < 0) goto cleanup; } @@ -3253,7 +3253,7 @@ qemuDomainReAttachHostdevDevices(struct qemud_driver *driver, for (i = 0; i < pciDeviceListCount(pcidevs); i++) { pciDevice *dev = pciDeviceListGet(pcidevs, i); - if (pciResetDevice(dev, driver->activePciHostdevs) < 0) { + if (pciResetDevice(dev, driver->activePciHostdevs, pcidevs) < 0) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Failed to reset PCI device: %s"), err ? err->message : _("unknown error")); @@ -8995,7 +8995,7 @@ static int qemudDomainDetachHostPciDevice(struct qemud_driver *driver, else { pciDeviceSetManaged(pci, detach->managed); pciDeviceListDel(driver->activePciHostdevs, pci); - if (pciResetDevice(pci, driver->activePciHostdevs) < 0) + if (pciResetDevice(pci, driver->activePciHostdevs, NULL) < 0) ret = -1; qemudReattachManagedDevice(pci, driver); pciFreeDevice(pci); @@ -11620,7 +11620,7 @@ qemudNodeDeviceReset (virNodeDevicePtr dev) qemuDriverLock(driver); - if (pciResetDevice(pci, driver->activePciHostdevs) < 0) + if (pciResetDevice(pci, driver->activePciHostdevs, NULL) < 0) goto out; ret = 0; diff --git a/src/util/pci.c b/src/util/pci.c index 6d0ca24f6c19672c4a2c21900290ec467e286f5e..1c10067d972a71bdff22993a8112fc3419fc3053 100644 --- a/src/util/pci.c +++ b/src/util/pci.c @@ -440,11 +440,11 @@ pciDetectPowerManagementReset(pciDevice *dev) return 0; } -/* Any active devices other than the one supplied on the same domain/bus ? */ +/* Any active devices on the same domain/bus ? */ static int pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data) { - pciDeviceList *activeDevs = data; + pciDeviceList *inactiveDevs = data; /* Different domain, different bus, or simply identical device */ if (dev->domain != check->domain || @@ -453,7 +453,8 @@ pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data) dev->function == check->function)) return 0; - if (activeDevs && !pciDeviceListFind(activeDevs, check)) + /* same bus, but inactive, i.e. about to be assigned to guest */ + if (inactiveDevs && pciDeviceListFind(inactiveDevs, check)) return 0; return 1; @@ -461,11 +462,11 @@ pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data) static pciDevice * pciBusContainsActiveDevices(pciDevice *dev, - pciDeviceList *activeDevs) + pciDeviceList *inactiveDevs) { pciDevice *active = NULL; if (pciIterDevices(pciSharesBusWithActive, - dev, &active, activeDevs) < 0) + dev, &active, inactiveDevs) < 0) return NULL; return active; } @@ -512,7 +513,7 @@ pciGetParentDevice(pciDevice *dev) */ static int pciTrySecondaryBusReset(pciDevice *dev, - pciDeviceList *activeDevs) + pciDeviceList *inactiveDevs) { pciDevice *parent, *conflict; uint8_t config_space[PCI_CONF_LEN]; @@ -524,7 +525,7 @@ pciTrySecondaryBusReset(pciDevice *dev, * In future, we could allow it so long as those devices * are not in use by the host or other guests. */ - if ((conflict = pciBusContainsActiveDevices(dev, activeDevs))) { + if ((conflict = pciBusContainsActiveDevices(dev, inactiveDevs))) { pciReportError(VIR_ERR_NO_SUPPORT, _("Active %s devices on bus with %s, not doing bus reset"), conflict->name, dev->name); @@ -642,7 +643,8 @@ pciInitDevice(pciDevice *dev) int pciResetDevice(pciDevice *dev, - pciDeviceList *activeDevs) + pciDeviceList *activeDevs, + pciDeviceList *inactiveDevs) { int ret = -1; @@ -670,7 +672,7 @@ pciResetDevice(pciDevice *dev, /* Bus reset is not an option with the root bus */ if (ret < 0 && dev->bus != 0) - ret = pciTrySecondaryBusReset(dev, activeDevs); + ret = pciTrySecondaryBusReset(dev, inactiveDevs); if (ret < 0) { virErrorPtr err = virGetLastError(); diff --git a/src/util/pci.h b/src/util/pci.h index 9aef81f9e29031f7fa537c06bd30486ea9298674..b767930bbccecd7bde26248f33e74cc65369c7ac 100644 --- a/src/util/pci.h +++ b/src/util/pci.h @@ -35,7 +35,8 @@ void pciFreeDevice (pciDevice *dev); int pciDettachDevice (pciDevice *dev, pciDeviceList *activeDevs); int pciReAttachDevice (pciDevice *dev, pciDeviceList *activeDevs); int pciResetDevice (pciDevice *dev, - pciDeviceList *activeDevs); + pciDeviceList *activeDevs, + pciDeviceList *inactiveDevs); void pciDeviceSetManaged(pciDevice *dev, unsigned managed); unsigned pciDeviceGetManaged(pciDevice *dev); diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index b55e4945308d01e13025c316ed6b52b9c444404b..d121ea4c3f048dc36df9f3f9ffb0379d24e3192e 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1892,7 +1892,7 @@ xenUnifiedNodeDeviceReset (virNodeDevicePtr dev) if (!pci) return -1; - if (pciResetDevice(pci, NULL) < 0) + if (pciResetDevice(pci, NULL, NULL) < 0) goto out; ret = 0;