[libvirt] [PATCH v2 08/10] nodedev: Introduce mdev capability for child devices

Erik Skultety eskultet at redhat.com
Thu Apr 20 13:05:58 UTC 2017


Start discovering the mediated devices on the host system and format the
attributes for the child device into the XML. Compared to the parent
device which reports generic information about the abstract mediated
devices types, a child device only reports the type name it has been
instantiated from and the iommu group number, since that's device
specific compared to the rest of the info that can be gathered about
mdevs at the moment.
This patch introduces both the formatting and parsing routines, updates
nodedev.rng schema, adding a testcase for mdev child device as well.

The resulting mdev child device XML:
<device>
  <name>mdev_4b20d080_1b54_4048_85b3_a6a62d165c01</name>
  <path>/sys/devices/.../4b20d080-1b54-4048-85b3-a6a62d165c01</path>
  <parent>pci_0000_06_00_0</parent>
  <driver>
    <name>vfio_mdev</name>
  </driver>
  <capability type='mdev'>
    <type id='vendor-supplied-type-id'/>
    <iommuGroup number='NUM'/>
  <capability/>
<device/>

Signed-off-by: Erik Skultety <eskultet at redhat.com>
---
 docs/schemas/nodedev.rng                           | 17 ++++++++
 src/conf/node_device_conf.c                        | 43 +++++++++++++++++++-
 src/node_device/node_device_udev.c                 | 46 ++++++++++++++++++++++
 .../mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml  |  8 ++++
 tests/nodedevxml2xmltest.c                         |  1 +
 5 files changed, 114 insertions(+), 1 deletion(-)
 create mode 100644 tests/nodedevschemadata/mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml

diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng
index 4b5dca777..8466d504d 100644
--- a/docs/schemas/nodedev.rng
+++ b/docs/schemas/nodedev.rng
@@ -83,6 +83,7 @@
         <ref name="capscsi"/>
         <ref name="capstorage"/>
         <ref name="capdrm"/>
+        <ref name="capmdev"/>
       </choice>
     </element>
   </define>
@@ -578,6 +579,22 @@
     </element>
   </define>
 
+  <define name='capmdev'>
+    <attribute name='type'>
+      <value>mdev</value>
+    </attribute>
+    <element name='type'>
+      <attribute name='id'>
+        <data type='string'/>
+      </attribute>
+    </element>
+    <element name='iommuGroup'>
+      <attribute name='number'>
+        <ref name='unsignedInt'/>
+      </attribute>
+    </element>
+  </define>
+
   <define name='address'>
     <element name='address'>
       <attribute name='domain'><ref name='hexuint'/></attribute>
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index fe4f1bc60..757e4bed7 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -582,9 +582,13 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def)
         case VIR_NODE_DEV_CAP_DRM:
             virBufferEscapeString(&buf, "<type>%s</type>\n", virNodeDevDRMTypeToString(data->drm.type));
             break;
+        case VIR_NODE_DEV_CAP_MDEV:
+            virBufferEscapeString(&buf, "<type id='%s'/>\n", data->mdev.type);
+            virBufferAsprintf(&buf, "<iommuGroup number='%u'/>\n",
+                              data->mdev.iommuGroupNumber);
+            break;
         case VIR_NODE_DEV_CAP_FC_HOST:
         case VIR_NODE_DEV_CAP_VPORTS:
-        case VIR_NODE_DEV_CAP_MDEV:
         case VIR_NODE_DEV_CAP_LAST:
             break;
         }
@@ -1645,6 +1649,39 @@ virNodeDevCapSystemParseXML(xmlXPathContextPtr ctxt,
 }
 
 
+static int
+virNodeDevCapMdevParseXML(xmlXPathContextPtr ctxt,
+                          virNodeDeviceDefPtr def,
+                          xmlNodePtr node,
+                          virNodeDevCapMdevPtr mdev)
+{
+    xmlNodePtr orignode;
+    int ret = -1;
+
+    orignode = ctxt->node;
+    ctxt->node = node;
+
+    if (!(mdev->type = virXPathString("string(./type[1]/@id)", ctxt))) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("missing type id attribute for '%s'"), def->name);
+        goto out;
+    }
+
+    if (virNodeDevCapsDefParseULong("number(./iommuGroup[1]/@number)", ctxt,
+                                    &mdev->iommuGroupNumber, def,
+                                    _("missing iommuGroup number atribute for "
+                                      "'%s'"),
+                                    _("invalid iommuGroup number attribute for "
+                                      "'%s'")) < 0)
+        goto out;
+
+    ret = 0;
+ out:
+    ctxt->node = orignode;
+    return ret;
+}
+
+
 static virNodeDevCapsDefPtr
 virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
                           virNodeDeviceDefPtr def,
@@ -1716,6 +1753,8 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
     case VIR_NODE_DEV_CAP_VPORTS:
     case VIR_NODE_DEV_CAP_SCSI_GENERIC:
     case VIR_NODE_DEV_CAP_MDEV:
+        ret = virNodeDevCapMdevParseXML(ctxt, def, node, &caps->data.mdev);
+        break;
     case VIR_NODE_DEV_CAP_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unknown capability type '%d' for '%s'"),
@@ -2035,6 +2074,8 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
         VIR_FREE(data->sg.path);
         break;
     case VIR_NODE_DEV_CAP_MDEV:
+        virNodeDevCapMdevClear(&data->mdev);
+        break;
     case VIR_NODE_DEV_CAP_DRM:
     case VIR_NODE_DEV_CAP_FC_HOST:
     case VIR_NODE_DEV_CAP_VPORTS:
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 79f1537d9..a04009110 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1083,6 +1083,51 @@ udevProcessSCSIGeneric(struct udev_device *dev,
 }
 
 static int
+udevProcessMediatedDevice(struct udev_device *dev,
+                          virNodeDeviceDefPtr def)
+{
+    int ret = -1;
+    const char *uuidstr = NULL;
+    int iommugrp = -1;
+    int model = -1;
+    char *path = NULL;
+    virMediatedDevicePtr mdev = NULL;
+    virNodeDevCapMdevPtr data = &def->caps->data.mdev;
+
+    if (virAsprintf(&path, "%s/mdev_type", udev_device_get_syspath(dev)) < 0)
+        goto cleanup;
+
+    if (udevGetMdevCaps(dev, path, data) < 0)
+        goto cleanup;
+
+    if ((model = virMediatedDeviceModelTypeFromString(data->device_api)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Device API '%s' not supported yet"),
+                       data->device_api);
+        goto cleanup;
+    }
+
+    uuidstr = udev_device_get_sysname(dev);
+    if (!(mdev = virMediatedDeviceNew(uuidstr, model)))
+        goto cleanup;
+
+    if ((iommugrp = virMediatedDeviceGetIOMMUGroupNum(mdev)) < 0)
+        goto cleanup;
+
+    if (udevGenerateDeviceName(dev, def, NULL) != 0)
+        goto cleanup;
+
+    data->iommuGroupNumber = iommugrp;
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(path);
+    virMediatedDeviceFree(mdev);
+    return ret;
+
+}
+
+static int
 udevGetDeviceNodes(struct udev_device *device,
                    virNodeDeviceDefPtr def)
 {
@@ -1199,6 +1244,7 @@ static int udevGetDeviceDetails(struct udev_device *device,
     case VIR_NODE_DEV_CAP_DRM:
         return udevProcessDRMDevice(device, def);
     case VIR_NODE_DEV_CAP_MDEV:
+        return udevProcessMediatedDevice(device, def);
     case VIR_NODE_DEV_CAP_SYSTEM:
     case VIR_NODE_DEV_CAP_FC_HOST:
     case VIR_NODE_DEV_CAP_VPORTS:
diff --git a/tests/nodedevschemadata/mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml b/tests/nodedevschemadata/mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml
new file mode 100644
index 000000000..470e5917e
--- /dev/null
+++ b/tests/nodedevschemadata/mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml
@@ -0,0 +1,8 @@
+<device>
+  <name>mdev_3627463d_b7f0_4fea_b468_f1da537d301b</name>
+  <parent>computer</parent>
+  <capability type='mdev'>
+    <type id='mtty-1'/>
+    <iommuGroup number='12'/>
+  </capability>
+</device>
diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c
index f023d8a13..88c75ea78 100644
--- a/tests/nodedevxml2xmltest.c
+++ b/tests/nodedevxml2xmltest.c
@@ -101,6 +101,7 @@ mymain(void)
     DO_TEST("pci_0000_02_10_7_sriov_pf_vfs_all");
     DO_TEST("pci_0000_02_10_7_sriov_pf_vfs_all_header_type");
     DO_TEST("drm_renderD129");
+    DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
-- 
2.12.2




More information about the libvir-list mailing list