[libvirt] [RFC PATCH 08/28] util: virpci: detect if the device is a multifunction device from sysfs

Shivaprasad G Bhat posted 28 patches 6 years, 8 months ago
[libvirt] [RFC PATCH 08/28] util: virpci: detect if the device is a multifunction device from sysfs
Posted by Shivaprasad G Bhat 6 years, 8 months ago
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.vnet.ibm.com>
---
 src/libvirt_private.syms           |    1 +
 src/node_device/node_device_udev.c |    2 +-
 src/util/virhostdev.c              |    2 +-
 src/util/virpci.c                  |   20 ++++++++++++++++++--
 src/util/virpci.h                  |    3 ++-
 5 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e1bdaa127e..53e174a223 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2462,6 +2462,7 @@ virPCIDeviceGetUnbindFromStub;
 virPCIDeviceGetUsedBy;
 virPCIDeviceHasPCIExpressLink;
 virPCIDeviceIsAssignable;
+virPCIDeviceIsMultifunction;
 virPCIDeviceIsPCIExpress;
 virPCIDeviceListAdd;
 virPCIDeviceListAddCopy;
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index e87eb32a85..99b936bb5c 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -455,7 +455,7 @@ udevProcessPCI(struct udev_device *device,
 
     /* We need to be root to read PCI device configs */
     if (privileged) {
-        if (virPCIGetHeaderType(pciDev, &pci_dev->hdrType) < 0)
+        if (virPCIGetHeaderType(pciDev, &pci_dev->hdrType, NULL) < 0)
             goto cleanup;
 
         if (virPCIDeviceIsPCIExpress(pciDev) > 0) {
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index e0133cdeec..807caf567a 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -693,7 +693,7 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
         struct virHostdevIsPCINodeDeviceUsedData data = { mgr, dom_name, usesVFIO };
         int hdrType = -1;
 
-        if (virPCIGetHeaderType(pci, &hdrType) < 0)
+        if (virPCIGetHeaderType(pci, &hdrType, NULL) < 0)
             goto cleanup;
 
         if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 55e4c3e492..a827b3bc0f 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -936,7 +936,7 @@ virPCIDeviceReset(virPCIDevicePtr dev,
     int fd = -1;
     int hdrType = -1;
 
-    if (virPCIGetHeaderType(dev, &hdrType) < 0)
+    if (virPCIGetHeaderType(dev, &hdrType, NULL) < 0)
         return -1;
 
     if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
@@ -3169,6 +3169,18 @@ virPCIGetMdevTypes(const char *sysfspath ATTRIBUTE_UNUSED,
 }
 #endif /* __linux__ */
 
+bool
+virPCIDeviceIsMultifunction(virPCIDevicePtr dev)
+{
+    bool multifunction = false;
+    int hdrType = -1;
+
+    if (virPCIGetHeaderType(dev, &hdrType, &multifunction) < 0)
+        return false;
+
+    return multifunction;
+}
+
 int
 virPCIDeviceIsPCIExpress(virPCIDevicePtr dev)
 {
@@ -3254,10 +3266,11 @@ virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
 }
 
 
-int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType)
+int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType, bool *multiFunc)
 {
     int fd;
     uint8_t type;
+    bool multi = false;
 
     *hdrType = -1;
 
@@ -3268,6 +3281,7 @@ int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType)
 
     virPCIDeviceConfigClose(dev, fd);
 
+    multi = type & PCI_HEADER_TYPE_MULTI;
     type &= PCI_HEADER_TYPE_MASK;
     if (type >= VIR_PCI_HEADER_LAST) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -3276,6 +3290,8 @@ int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType)
     }
 
     *hdrType = type;
+    if (multiFunc)
+        *multiFunc = multi;
 
     return 0;
 }
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 794b7e59db..179249677a 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -199,6 +199,7 @@ int virPCIGetVirtualFunctions(const char *sysfs_path,
                               size_t *num_virtual_functions,
                               unsigned int *max_virtual_functions);
 
+bool virPCIDeviceIsMultifunction(virPCIDevicePtr dev);
 int virPCIIsVirtualFunction(const char *vf_sysfs_device_link);
 
 int virPCIGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
@@ -246,7 +247,7 @@ int virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
                               unsigned int *sta_speed,
                               unsigned int *sta_width);
 
-int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType);
+int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType, bool *multiFunc);
 
 void virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev);
 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list