|
|
6d3351 |
From 8e5ac9cdbe38dd3b3320b97385d8e2cf0e862ef7 Mon Sep 17 00:00:00 2001
|
|
|
6d3351 |
Message-Id: <8e5ac9cdbe38dd3b3320b97385d8e2cf0e862ef7@dist-git>
|
|
|
6d3351 |
From: Erik Skultety <eskultet@redhat.com>
|
|
|
6d3351 |
Date: Thu, 18 May 2017 14:02:54 +0200
|
|
|
6d3351 |
Subject: [PATCH] nodedev: Introduce mdev capability for mediated devices
|
|
|
6d3351 |
|
|
|
6d3351 |
Start discovering the mediated devices on the host system and format the
|
|
|
6d3351 |
attributes for the mediated device into the XML. Compared to the parent
|
|
|
6d3351 |
device which reports generic information about the abstract mediated
|
|
|
6d3351 |
devices types, a child device only reports the type name it has been
|
|
|
6d3351 |
instantiated from and the IOMMU group number, since that's device
|
|
|
6d3351 |
specific compared to the rest of the info that can be gathered about
|
|
|
6d3351 |
mediated devices at the moment.
|
|
|
6d3351 |
This patch introduces both the formatting and parsing routines, updates
|
|
|
6d3351 |
nodedev.rng schema, adding a testcase as well.
|
|
|
6d3351 |
|
|
|
6d3351 |
The resulting mdev child device XML:
|
|
|
6d3351 |
<device>
|
|
|
6d3351 |
<name>mdev_4b20d080_1b54_4048_85b3_a6a62d165c01</name>
|
|
|
6d3351 |
<path>/sys/devices/.../4b20d080-1b54-4048-85b3-a6a62d165c01</path>
|
|
|
6d3351 |
<parent>pci_0000_06_00_0</parent>
|
|
|
6d3351 |
<driver>
|
|
|
6d3351 |
<name>vfio_mdev</name>
|
|
|
6d3351 |
</driver>
|
|
|
6d3351 |
<capability type='mdev'>
|
|
|
6d3351 |
<type id='vendor_supplied_type_id'/>
|
|
|
6d3351 |
<iommuGroup number='NUM'/>
|
|
|
6d3351 |
<capability/>
|
|
|
6d3351 |
<device/>
|
|
|
6d3351 |
|
|
|
6d3351 |
https://bugzilla.redhat.com/show_bug.cgi?id=1452072
|
|
|
6d3351 |
|
|
|
6d3351 |
Signed-off-by: Erik Skultety <eskultet@redhat.com>
|
|
|
6d3351 |
(cherry picked from commit 88ef73e13cddc8c0ff01dfe7a914342f8720c517)
|
|
|
6d3351 |
Signed-off-by: Erik Skultety <eskultet@redhat.com>
|
|
|
6d3351 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
6d3351 |
---
|
|
|
6d3351 |
docs/schemas/nodedev.rng | 17 +++++++++
|
|
|
6d3351 |
src/conf/node_device_conf.c | 41 +++++++++++++++++++++
|
|
|
6d3351 |
src/conf/node_device_conf.h | 8 ++++
|
|
|
6d3351 |
src/node_device/node_device_udev.c | 43 +++++++++++++++++++++-
|
|
|
6d3351 |
.../mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml | 8 ++++
|
|
|
6d3351 |
tests/nodedevxml2xmltest.c | 1 +
|
|
|
6d3351 |
6 files changed, 117 insertions(+), 1 deletion(-)
|
|
|
6d3351 |
create mode 100644 tests/nodedevschemadata/mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml
|
|
|
6d3351 |
|
|
|
6d3351 |
diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng
|
|
|
6d3351 |
index e0a2c5032..924f73861 100644
|
|
|
6d3351 |
--- a/docs/schemas/nodedev.rng
|
|
|
6d3351 |
+++ b/docs/schemas/nodedev.rng
|
|
|
6d3351 |
@@ -83,6 +83,7 @@
|
|
|
6d3351 |
<ref name="capscsi"/>
|
|
|
6d3351 |
<ref name="capstorage"/>
|
|
|
6d3351 |
<ref name="capdrm"/>
|
|
|
6d3351 |
+ <ref name="capmdev"/>
|
|
|
6d3351 |
</choice>
|
|
|
6d3351 |
</element>
|
|
|
6d3351 |
</define>
|
|
|
6d3351 |
@@ -580,6 +581,22 @@
|
|
|
6d3351 |
</element>
|
|
|
6d3351 |
</define>
|
|
|
6d3351 |
|
|
|
6d3351 |
+ <define name='capmdev'>
|
|
|
6d3351 |
+ <attribute name='type'>
|
|
|
6d3351 |
+ <value>mdev</value>
|
|
|
6d3351 |
+ </attribute>
|
|
|
6d3351 |
+ <element name='type'>
|
|
|
6d3351 |
+ <attribute name='id'>
|
|
|
6d3351 |
+ <data type='string'/>
|
|
|
6d3351 |
+ </attribute>
|
|
|
6d3351 |
+ </element>
|
|
|
6d3351 |
+ <element name='iommuGroup'>
|
|
|
6d3351 |
+ <attribute name='number'>
|
|
|
6d3351 |
+ <ref name='unsignedInt'/>
|
|
|
6d3351 |
+ </attribute>
|
|
|
6d3351 |
+ </element>
|
|
|
6d3351 |
+ </define>
|
|
|
6d3351 |
+
|
|
|
6d3351 |
<define name='address'>
|
|
|
6d3351 |
<element name='address'>
|
|
|
6d3351 |
<attribute name='domain'><ref name='hexuint'/></attribute>
|
|
|
6d3351 |
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
|
|
|
6d3351 |
index de8ba8f9d..ac61db34c 100644
|
|
|
6d3351 |
--- a/src/conf/node_device_conf.c
|
|
|
6d3351 |
+++ b/src/conf/node_device_conf.c
|
|
|
6d3351 |
@@ -577,6 +577,10 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def)
|
|
|
6d3351 |
virBufferEscapeString(&buf, "<type>%s</type>\n", virNodeDevDRMTypeToString(data->drm.type));
|
|
|
6d3351 |
break;
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_MDEV:
|
|
|
6d3351 |
+ virBufferEscapeString(&buf, "<type id='%s'/>\n", data->mdev.type);
|
|
|
6d3351 |
+ virBufferAsprintf(&buf, "<iommuGroup number='%u'/>\n",
|
|
|
6d3351 |
+ data->mdev.iommuGroupNumber);
|
|
|
6d3351 |
+ break;
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_FC_HOST:
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_VPORTS:
|
|
|
6d3351 |
@@ -1647,6 +1651,39 @@ virNodeDevCapSystemParseXML(xmlXPathContextPtr ctxt,
|
|
|
6d3351 |
}
|
|
|
6d3351 |
|
|
|
6d3351 |
|
|
|
6d3351 |
+static int
|
|
|
6d3351 |
+virNodeDevCapMdevParseXML(xmlXPathContextPtr ctxt,
|
|
|
6d3351 |
+ virNodeDeviceDefPtr def,
|
|
|
6d3351 |
+ xmlNodePtr node,
|
|
|
6d3351 |
+ virNodeDevCapMdevPtr mdev)
|
|
|
6d3351 |
+{
|
|
|
6d3351 |
+ xmlNodePtr orignode;
|
|
|
6d3351 |
+ int ret = -1;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ orignode = ctxt->node;
|
|
|
6d3351 |
+ ctxt->node = node;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ if (!(mdev->type = virXPathString("string(./type[1]/@id)", ctxt))) {
|
|
|
6d3351 |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
6d3351 |
+ _("missing type id attribute for '%s'"), def->name);
|
|
|
6d3351 |
+ goto out;
|
|
|
6d3351 |
+ }
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ if (virNodeDevCapsDefParseULong("number(./iommuGroup[1]/@number)", ctxt,
|
|
|
6d3351 |
+ &mdev->iommuGroupNumber, def,
|
|
|
6d3351 |
+ _("missing iommuGroup number attribute for "
|
|
|
6d3351 |
+ "'%s'"),
|
|
|
6d3351 |
+ _("invalid iommuGroup number attribute for "
|
|
|
6d3351 |
+ "'%s'")) < 0)
|
|
|
6d3351 |
+ goto out;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ ret = 0;
|
|
|
6d3351 |
+ out:
|
|
|
6d3351 |
+ ctxt->node = orignode;
|
|
|
6d3351 |
+ return ret;
|
|
|
6d3351 |
+}
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+
|
|
|
6d3351 |
static virNodeDevCapsDefPtr
|
|
|
6d3351 |
virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
|
|
|
6d3351 |
virNodeDeviceDefPtr def,
|
|
|
6d3351 |
@@ -1715,6 +1752,8 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
|
|
|
6d3351 |
ret = virNodeDevCapDRMParseXML(ctxt, def, node, &caps->data.drm);
|
|
|
6d3351 |
break;
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_MDEV:
|
|
|
6d3351 |
+ ret = virNodeDevCapMdevParseXML(ctxt, def, node, &caps->data.mdev);
|
|
|
6d3351 |
+ break;
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_FC_HOST:
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_VPORTS:
|
|
|
6d3351 |
@@ -2037,6 +2076,8 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
|
|
|
6d3351 |
VIR_FREE(data->sg.path);
|
|
|
6d3351 |
break;
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_MDEV:
|
|
|
6d3351 |
+ VIR_FREE(data->mdev.type);
|
|
|
6d3351 |
+ break;
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_DRM:
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_FC_HOST:
|
|
|
6d3351 |
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
|
|
|
6d3351 |
index 18aaff8b5..5743f9d3e 100644
|
|
|
6d3351 |
--- a/src/conf/node_device_conf.h
|
|
|
6d3351 |
+++ b/src/conf/node_device_conf.h
|
|
|
6d3351 |
@@ -143,6 +143,13 @@ struct _virNodeDevCapMdevType {
|
|
|
6d3351 |
unsigned int available_instances;
|
|
|
6d3351 |
};
|
|
|
6d3351 |
|
|
|
6d3351 |
+typedef struct _virNodeDevCapMdev virNodeDevCapMdev;
|
|
|
6d3351 |
+typedef virNodeDevCapMdev *virNodeDevCapMdevPtr;
|
|
|
6d3351 |
+struct _virNodeDevCapMdev {
|
|
|
6d3351 |
+ char *type;
|
|
|
6d3351 |
+ unsigned int iommuGroupNumber;
|
|
|
6d3351 |
+};
|
|
|
6d3351 |
+
|
|
|
6d3351 |
typedef struct _virNodeDevCapPCIDev virNodeDevCapPCIDev;
|
|
|
6d3351 |
typedef virNodeDevCapPCIDev *virNodeDevCapPCIDevPtr;
|
|
|
6d3351 |
struct _virNodeDevCapPCIDev {
|
|
|
6d3351 |
@@ -276,6 +283,7 @@ struct _virNodeDevCapData {
|
|
|
6d3351 |
virNodeDevCapStorage storage;
|
|
|
6d3351 |
virNodeDevCapSCSIGeneric sg;
|
|
|
6d3351 |
virNodeDevCapDRM drm;
|
|
|
6d3351 |
+ virNodeDevCapMdev mdev;
|
|
|
6d3351 |
};
|
|
|
6d3351 |
};
|
|
|
6d3351 |
|
|
|
6d3351 |
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
|
|
|
6d3351 |
index b89099c82..37528ee48 100644
|
|
|
6d3351 |
--- a/src/node_device/node_device_udev.c
|
|
|
6d3351 |
+++ b/src/node_device/node_device_udev.c
|
|
|
6d3351 |
@@ -1073,6 +1073,42 @@ udevProcessSCSIGeneric(struct udev_device *dev,
|
|
|
6d3351 |
}
|
|
|
6d3351 |
|
|
|
6d3351 |
static int
|
|
|
6d3351 |
+udevProcessMediatedDevice(struct udev_device *dev,
|
|
|
6d3351 |
+ virNodeDeviceDefPtr def)
|
|
|
6d3351 |
+{
|
|
|
6d3351 |
+ int ret = -1;
|
|
|
6d3351 |
+ const char *uuidstr = NULL;
|
|
|
6d3351 |
+ int iommugrp = -1;
|
|
|
6d3351 |
+ char *linkpath = NULL;
|
|
|
6d3351 |
+ char *realpath = NULL;
|
|
|
6d3351 |
+ virNodeDevCapMdevPtr data = &def->caps->data.mdev;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ if (virAsprintf(&linkpath, "%s/mdev_type", udev_device_get_syspath(dev)) < 0)
|
|
|
6d3351 |
+ goto cleanup;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ if (virFileResolveLink(linkpath, &realpath) < 0)
|
|
|
6d3351 |
+ goto cleanup;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ if (VIR_STRDUP(data->type, last_component(realpath)) < 0)
|
|
|
6d3351 |
+ goto cleanup;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ uuidstr = udev_device_get_sysname(dev);
|
|
|
6d3351 |
+ if ((iommugrp = virMediatedDeviceGetIOMMUGroupNum(uuidstr)) < 0)
|
|
|
6d3351 |
+ goto cleanup;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ if (udevGenerateDeviceName(dev, def, NULL) != 0)
|
|
|
6d3351 |
+ goto cleanup;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ data->iommuGroupNumber = iommugrp;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+ ret = 0;
|
|
|
6d3351 |
+ cleanup:
|
|
|
6d3351 |
+ VIR_FREE(linkpath);
|
|
|
6d3351 |
+ VIR_FREE(realpath);
|
|
|
6d3351 |
+ return ret;
|
|
|
6d3351 |
+}
|
|
|
6d3351 |
+
|
|
|
6d3351 |
+static int
|
|
|
6d3351 |
udevGetDeviceNodes(struct udev_device *device,
|
|
|
6d3351 |
virNodeDeviceDefPtr def)
|
|
|
6d3351 |
{
|
|
|
6d3351 |
@@ -1140,12 +1176,16 @@ udevGetDeviceType(struct udev_device *device,
|
|
|
6d3351 |
if (udevHasDeviceProperty(device, "INTERFACE"))
|
|
|
6d3351 |
*type = VIR_NODE_DEV_CAP_NET;
|
|
|
6d3351 |
|
|
|
6d3351 |
- /* SCSI generic device doesn't set DEVTYPE property */
|
|
|
6d3351 |
+ /* Neither SCSI generic devices nor mediated devices set DEVTYPE
|
|
|
6d3351 |
+ * property, therefore we need to rely on the SUBSYSTEM property */
|
|
|
6d3351 |
if (udevGetStringProperty(device, "SUBSYSTEM", &subsystem) < 0)
|
|
|
6d3351 |
return -1;
|
|
|
6d3351 |
|
|
|
6d3351 |
if (STREQ_NULLABLE(subsystem, "scsi_generic"))
|
|
|
6d3351 |
*type = VIR_NODE_DEV_CAP_SCSI_GENERIC;
|
|
|
6d3351 |
+ else if (STREQ_NULLABLE(subsystem, "mdev"))
|
|
|
6d3351 |
+ *type = VIR_NODE_DEV_CAP_MDEV;
|
|
|
6d3351 |
+
|
|
|
6d3351 |
VIR_FREE(subsystem);
|
|
|
6d3351 |
}
|
|
|
6d3351 |
|
|
|
6d3351 |
@@ -1185,6 +1225,7 @@ static int udevGetDeviceDetails(struct udev_device *device,
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_DRM:
|
|
|
6d3351 |
return udevProcessDRMDevice(device, def);
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_MDEV:
|
|
|
6d3351 |
+ return udevProcessMediatedDevice(device, def);
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_SYSTEM:
|
|
|
6d3351 |
case VIR_NODE_DEV_CAP_FC_HOST:
|
|
|
6d3351 |
diff --git a/tests/nodedevschemadata/mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml b/tests/nodedevschemadata/mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml
|
|
|
6d3351 |
new file mode 100644
|
|
|
6d3351 |
index 000000000..470e5917e
|
|
|
6d3351 |
--- /dev/null
|
|
|
6d3351 |
+++ b/tests/nodedevschemadata/mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml
|
|
|
6d3351 |
@@ -0,0 +1,8 @@
|
|
|
6d3351 |
+<device>
|
|
|
6d3351 |
+ <name>mdev_3627463d_b7f0_4fea_b468_f1da537d301b</name>
|
|
|
6d3351 |
+ <parent>computer</parent>
|
|
|
6d3351 |
+ <capability type='mdev'>
|
|
|
6d3351 |
+ <type id='mtty-1'/>
|
|
|
6d3351 |
+ <iommuGroup number='12'/>
|
|
|
6d3351 |
+ </capability>
|
|
|
6d3351 |
+</device>
|
|
|
6d3351 |
diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c
|
|
|
6d3351 |
index eb5c50b86..26f0d25bc 100644
|
|
|
6d3351 |
--- a/tests/nodedevxml2xmltest.c
|
|
|
6d3351 |
+++ b/tests/nodedevxml2xmltest.c
|
|
|
6d3351 |
@@ -102,6 +102,7 @@ mymain(void)
|
|
|
6d3351 |
DO_TEST("pci_0000_02_10_7_sriov_pf_vfs_all_header_type");
|
|
|
6d3351 |
DO_TEST("drm_renderD129");
|
|
|
6d3351 |
DO_TEST("pci_0000_02_10_7_mdev_types");
|
|
|
6d3351 |
+ DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
|
|
|
6d3351 |
|
|
|
6d3351 |
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
|
6d3351 |
}
|
|
|
6d3351 |
--
|
|
|
6d3351 |
2.13.0
|
|
|
6d3351 |
|