Signed-off-by: Shivaprasad G Bhat <sbhat(a)linux.vnet.ibm.com>
---
src/libvirt_private.syms | 2 ++
src/util/virhostdev.c | 29 +++++++++++++++++++++++++++++
src/util/virhostdev.h | 5 +++++
src/util/virpci.c | 2 +-
src/util/virpci.h | 3 +++
5 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 53e174a223..68b648ba31 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1919,6 +1919,7 @@ virHostdevHostSupportsPassthroughKVM;
virHostdevHostSupportsPassthroughVFIO;
virHostdevIsSCSIDevice;
virHostdevManagerGetDefault;
+virHostdevPCIDevicesBelongToSameSlot;
virHostdevPCINodeDeviceDetach;
virHostdevPCINodeDeviceReAttach;
virHostdevPCINodeDeviceReset;
@@ -2443,6 +2444,7 @@ virPCIDeviceAddressGetIOMMUGroupAddresses;
virPCIDeviceAddressGetIOMMUGroupNum;
virPCIDeviceAddressGetSysfsFile;
virPCIDeviceAddressIOMMUGroupIterate;
+virPCIDeviceAddressIsEqual;
virPCIDeviceAddressParse;
virPCIDeviceCopy;
virPCIDeviceDetach;
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 807caf567a..9508a29954 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -306,6 +306,35 @@ virHostdevIsVirtualFunction(virDomainHostdevDefPtr hostdev)
}
+bool
+virHostdevPCIDevicesBelongToSameSlot(virDomainHostdevDefPtr dev1,
+ virDomainHostdevDefPtr dev2)
+{
+ virPCIDeviceAddressPtr devAddr1 = NULL, devAddr2 = NULL;
+
+ if (!dev1 || !dev2)
+ return false;
+
+ devAddr1 = &dev1->source.subsys.u.pci.addr;
+ devAddr2 = &dev2->source.subsys.u.pci.addr;
+ if ((devAddr1->domain != devAddr2->domain) ||
+ (devAddr1->bus != devAddr2->bus) ||
+ (devAddr1->slot != devAddr2->slot) ||
+ (virPCIDeviceAddressIsEqual(devAddr1, devAddr2))) {
+ return false;
+ }
+
+ /* The Virtual Functions have multifunction false even though they have same
+ * domain:bus:slot as the Physical function. They are to be treated
+ * like non-multifunction devices
+ */
+ if (virHostdevIsVirtualFunction(dev1) || virHostdevIsVirtualFunction(dev2))
+ return false;
+
+ return true;
+}
+
+
static int
virHostdevNetDevice(virDomainHostdevDefPtr hostdev,
int pfNetDevIdx,
diff --git a/src/util/virhostdev.h b/src/util/virhostdev.h
index d5efffbac2..ded7620355 100644
--- a/src/util/virhostdev.h
+++ b/src/util/virhostdev.h
@@ -155,6 +155,11 @@ virHostdevUpdateActiveUSBDevices(virHostdevManagerPtr mgr,
const char *drv_name,
const char *dom_name)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
+
+bool
+virHostdevPCIDevicesBelongToSameSlot(virDomainHostdevDefPtr dev1,
+ virDomainHostdevDefPtr dev2);
+
int
virHostdevUpdateActiveSCSIDevices(virHostdevManagerPtr mgr,
virDomainHostdevDefPtr *hostdevs,
diff --git a/src/util/virpci.c b/src/util/virpci.c
index a827b3bc0f..987db605cc 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2603,7 +2603,7 @@ virPCIDeviceAddressParse(char *address,
/*
* returns true if equal
*/
-static bool
+bool
virPCIDeviceAddressIsEqual(virPCIDeviceAddressPtr bdf1,
virPCIDeviceAddressPtr bdf2)
{
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 179249677a..5830fb4c12 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -188,6 +188,9 @@ int virPCIDeviceIsAssignable(virPCIDevicePtr dev,
int strict_acs_check);
int virPCIDeviceWaitForCleanup(virPCIDevicePtr dev, const char *matcher);
+bool
+virPCIDeviceAddressIsEqual(virPCIDeviceAddressPtr bdf1,
+ virPCIDeviceAddressPtr bdf2);
virPCIDeviceAddressPtr
virPCIGetDeviceAddressFromSysfsLink(const char *device_link);