]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
node_device: new functions to get sriov/iommu info from sysfs
authorLaine Stump <laine@laine.org>
Mon, 11 May 2015 17:35:50 +0000 (13:35 -0400)
committerLaine Stump <laine@laine.org>
Mon, 18 May 2015 14:31:58 +0000 (10:31 -0400)
The udev and hal drivers both already call the same functions as these
new functions added to node_device_linux_sysfs.c, but 1) we need to
call them from node_device_driver.c, and 2) it would be nice to
eliminate the duplicated code from the hal and udev backends.

src/node_device/node_device_linux_sysfs.c
src/node_device/node_device_linux_sysfs.h

index fc82b32c207218c15e450baedfcc5cc4a60377ed..6d5a406ec99384943812a7bd7cfb8b07014b1332 100644 (file)
@@ -137,6 +137,96 @@ nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d)
     return ret;
 }
 
+
+static int
+nodeDeviceSysfsGetPCISRIOVCaps(const char *sysfsPath,
+                               virNodeDevCapDataPtr data)
+{
+    size_t i;
+    int ret;
+
+    /* this could be a refresh, so clear out the old data */
+    for (i = 0; i < data->pci_dev.num_virtual_functions; i++)
+       VIR_FREE(data->pci_dev.virtual_functions[i]);
+    VIR_FREE(data->pci_dev.virtual_functions);
+    data->pci_dev.num_virtual_functions = 0;
+    data->pci_dev.flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION;
+    data->pci_dev.flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION;
+
+    if (!virPCIGetPhysicalFunction(sysfsPath, &data->pci_dev.physical_function))
+        data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION;
+
+    ret = virPCIGetVirtualFunctions(sysfsPath, &data->pci_dev.virtual_functions,
+                                    &data->pci_dev.num_virtual_functions);
+    if (ret < 0)
+        return ret;
+
+    if (data->pci_dev.num_virtual_functions > 0)
+        data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION;
+
+    return ret;
+}
+
+
+static int
+nodeDeviceSysfsGetPCIIOMMUGroupCaps(virNodeDevCapDataPtr data)
+{
+    size_t i;
+    int tmpGroup, ret = -1;
+    virPCIDeviceAddress addr;
+
+    /* this could be a refresh, so clear out the old data */
+    for (i = 0; i < data->pci_dev.nIommuGroupDevices; i++)
+       VIR_FREE(data->pci_dev.iommuGroupDevices[i]);
+    VIR_FREE(data->pci_dev.iommuGroupDevices);
+    data->pci_dev.nIommuGroupDevices = 0;
+    data->pci_dev.iommuGroupNumber = 0;
+
+    addr.domain = data->pci_dev.domain;
+    addr.bus = data->pci_dev.bus;
+    addr.slot = data->pci_dev.slot;
+    addr.function = data->pci_dev.function;
+    tmpGroup = virPCIDeviceAddressGetIOMMUGroupNum(&addr);
+    if (tmpGroup == -1) {
+        /* error was already reported */
+        goto cleanup;
+    }
+    if (tmpGroup == -2) {
+        /* -2 return means there is no iommu_group data */
+        ret = 0;
+        goto cleanup;
+    }
+    if (tmpGroup >= 0) {
+        if (virPCIDeviceAddressGetIOMMUGroupAddresses(&addr, &data->pci_dev.iommuGroupDevices,
+                                                      &data->pci_dev.nIommuGroupDevices) < 0)
+            goto cleanup;
+        data->pci_dev.iommuGroupNumber = tmpGroup;
+    }
+
+    ret = 0;
+ cleanup:
+    return ret;
+}
+
+
+/* nodeDeviceSysfsGetPCIRelatedCaps() get info that is stored in sysfs
+ * about devices related to this device, i.e. things that can change
+ * without this device itself changing. These must be refreshed
+ * anytime full XML of the device is requested, because they can
+ * change with no corresponding notification from the kernel/udev.
+ */
+int
+nodeDeviceSysfsGetPCIRelatedDevCaps(const char *sysfsPath,
+                                    virNodeDevCapDataPtr data)
+{
+    if (nodeDeviceSysfsGetPCISRIOVCaps(sysfsPath, data) < 0)
+        return -1;
+    if (nodeDeviceSysfsGetPCIIOMMUGroupCaps(data) < 0)
+        return -1;
+    return 0;
+}
+
+
 #else
 
 int
index 307a8aade9f9194fa1fb5ea21f3886bc66ba2335..e4afdd726c6d99a1252a8f9bcdc65ffcce52f485 100644 (file)
@@ -26,5 +26,7 @@
 # include "node_device_conf.h"
 
 int nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d);
+int nodeDeviceSysfsGetPCIRelatedDevCaps(const char *sysfsPath,
+                                        virNodeDevCapDataPtr data);
 
 #endif /* __VIR_NODE_DEVICE_LINUX_SYSFS_H__ */