diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fc749e76c3e8132070a91916b86d24a29e1b5965..a34d92f5ef91ac750aaba88e61206f0e57dda233 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2702,7 +2702,6 @@ virPCIDeviceSetStubDriver; virPCIDeviceSetUnbindFromStub; virPCIDeviceSetUsedBy; virPCIDeviceUnbind; -virPCIDeviceWaitForCleanup; virPCIEDeviceInfoFree; virPCIELinkSpeedTypeFromString; virPCIELinkSpeedTypeToString; diff --git a/src/util/virpci.c b/src/util/virpci.c index 9c9ffa55c27965b27309b70e4221294a7baaa770..ea5be620336ffcc4e2db46402b33b44c8781589f 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -1552,114 +1552,6 @@ virPCIDeviceReattach(virPCIDevicePtr dev, return 0; } -/* Certain hypervisors (like qemu/kvm) map the PCI bar(s) on - * the host when doing device passthrough. This can lead to a race - * condition where the hypervisor is still cleaning up the device while - * libvirt is trying to re-attach it to the host device driver. To avoid - * this situation, we look through /proc/iomem, and if the hypervisor is - * still holding on to the bar (denoted by the string in the matcher - * variable), then we can wait around a bit for that to clear up. - * - * A typical /proc/iomem looks like this (snipped for brevity): - * 00010000-0008efff : System RAM - * 0008f000-0008ffff : reserved - * ... - * 00100000-cc9fcfff : System RAM - * 00200000-00483d3b : Kernel code - * 00483d3c-005c88df : Kernel data - * cc9fd000-ccc71fff : ACPI Non-volatile Storage - * ... - * d0200000-d02fffff : PCI Bus #05 - * d0200000-d021ffff : 0000:05:00.0 - * d0200000-d021ffff : e1000e - * d0220000-d023ffff : 0000:05:00.0 - * d0220000-d023ffff : e1000e - * ... - * f0000000-f0003fff : 0000:00:1b.0 - * f0000000-f0003fff : kvm_assigned_device - * - * Returns 0 if we are clear to continue, and 1 if the hypervisor is still - * holding on to the resource. - */ -int -virPCIDeviceWaitForCleanup(virPCIDevicePtr dev, const char *matcher) -{ - FILE *fp; - char line[160]; - char *tmp; - unsigned long long start, end; - unsigned int domain, bus, slot, function; - bool in_matching_device; - int ret; - size_t match_depth; - - fp = fopen("/proc/iomem", "r"); - if (!fp) { - /* If we failed to open iomem, we just basically ignore the error. The - * unbind might succeed anyway, and besides, it's very likely we have - * no way to report the error - */ - VIR_DEBUG("Failed to open /proc/iomem, trying to continue anyway"); - return 0; - } - - ret = 0; - in_matching_device = false; - match_depth = 0; - while (fgets(line, sizeof(line), fp) != 0) { - /* the logic here is a bit confusing. For each line, we look to - * see if it matches the domain:bus:slot.function we were given. - * If this line matches the DBSF, then any subsequent lines indented - * by 2 spaces are the PCI regions for this device. It's also - * possible that none of the PCI regions are currently mapped, in - * which case we have no indented regions. This code handles all - * of these situations - */ - if (in_matching_device && (strspn(line, " ") == (match_depth + 2))) { - /* expected format: - : */ - if (/* start */ - virStrToLong_ull(line, &tmp, 16, &start) < 0 || *tmp != '-' || - /* end */ - virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 || - (tmp = STRSKIP(tmp, " : ")) == NULL) - continue; - - if (STRPREFIX(tmp, matcher)) { - ret = 1; - break; - } - } else { - in_matching_device = false; - - /* expected format: - : ::. */ - if (/* start */ - virStrToLong_ull(line, &tmp, 16, &start) < 0 || *tmp != '-' || - /* end */ - virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 || - (tmp = STRSKIP(tmp, " : ")) == NULL || - /* domain */ - virStrToLong_ui(tmp, &tmp, 16, &domain) < 0 || *tmp != ':' || - /* bus */ - virStrToLong_ui(tmp + 1, &tmp, 16, &bus) < 0 || *tmp != ':' || - /* slot */ - virStrToLong_ui(tmp + 1, &tmp, 16, &slot) < 0 || *tmp != '.' || - /* function */ - virStrToLong_ui(tmp + 1, &tmp, 16, &function) < 0 || *tmp != '\n') - continue; - - if (domain != dev->address.domain || bus != dev->address.bus || - slot != dev->address.slot || function != dev->address.function) - continue; - in_matching_device = true; - match_depth = strspn(line, " "); - } - } - - VIR_FORCE_FCLOSE(fp); - - return ret; -} - static char * virPCIDeviceReadID(virPCIDevicePtr dev, const char *id_name) { diff --git a/src/util/virpci.h b/src/util/virpci.h index 4ac0d230a467e8bfdb6135bbe2b1658d67eba8e3..dc20f9171025e891ec175c8b7ff1a59686dd0adb 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -197,7 +197,6 @@ char *virPCIDeviceGetIOMMUGroupDev(virPCIDevicePtr dev); int virPCIDeviceIsAssignable(virPCIDevicePtr dev, int strict_acs_check); -int virPCIDeviceWaitForCleanup(virPCIDevicePtr dev, const char *matcher); virPCIDeviceAddressPtr virPCIGetDeviceAddressFromSysfsLink(const char *device_link);