mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
node_device: detecting mdev_types capability on ap_matrix device
Add detection of mdev_types capability to Adjunct Processor Matrix device. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> Reviewed-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Jonathon Jongsma<jjongsma@redhat.com> Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
a0ab006d5a
commit
53cc495179
@ -456,7 +456,26 @@
|
|||||||
</dd>
|
</dd>
|
||||||
<dt><code>ap_matrix</code></dt>
|
<dt><code>ap_matrix</code></dt>
|
||||||
<dd>Describes an AP Matrix device on a S390 architecture providing
|
<dd>Describes an AP Matrix device on a S390 architecture providing
|
||||||
cryptographic host resources usable for virtualization.</dd>
|
cryptographic host resources usable for virtualization.
|
||||||
|
Sub-elements include:
|
||||||
|
<dl>
|
||||||
|
<dt><code>capability</code></dt>
|
||||||
|
<dd>
|
||||||
|
This optional element can occur multiple times. If it
|
||||||
|
exists, it has a mandatory <code>type</code> attribute
|
||||||
|
which will be set to:
|
||||||
|
<dl>
|
||||||
|
<dt><code><a id="MDEVTypesCapAP">mdev_types</a></code></dt>
|
||||||
|
<dd>
|
||||||
|
<span class="since">Since 6.10.0</span>
|
||||||
|
This device is capable of creating mediated devices.
|
||||||
|
The sub-elements are summarized in
|
||||||
|
<a href="#MDEVTypesCap">mdev_types capability</a>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
@ -464,7 +483,8 @@
|
|||||||
<h3><a id="MDEVTypesCap">mdev_types capability</a></h3>
|
<h3><a id="MDEVTypesCap">mdev_types capability</a></h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="#MDEVTypesCapPCI">PCI</a> and <a href="#MDEVTypesCapCSS">CSS</a>
|
<a href="#MDEVTypesCapPCI">PCI</a>, <a href="#MDEVTypesCapCSS">CSS</a>
|
||||||
|
and <a href="#MDEVTypesCapAP">AP Matrix</a>
|
||||||
devices can be capable of creating mediated devices.
|
devices can be capable of creating mediated devices.
|
||||||
If they indeed are capable, then the parent <code>capability</code>
|
If they indeed are capable, then the parent <code>capability</code>
|
||||||
element for <code>mdev_types</code> type will contain a list of
|
element for <code>mdev_types</code> type will contain a list of
|
||||||
|
@ -696,6 +696,9 @@
|
|||||||
<attribute name='type'>
|
<attribute name='type'>
|
||||||
<value>ap_matrix</value>
|
<value>ap_matrix</value>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
<optional>
|
||||||
|
<ref name="mdev_types"/>
|
||||||
|
</optional>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
<define name="address">
|
<define name="address">
|
||||||
@ -736,6 +739,7 @@
|
|||||||
<choice>
|
<choice>
|
||||||
<value>vfio-pci</value>
|
<value>vfio-pci</value>
|
||||||
<value>vfio-ccw</value>
|
<value>vfio-ccw</value>
|
||||||
|
<value>vfio-ap</value>
|
||||||
</choice>
|
</choice>
|
||||||
</element>
|
</element>
|
||||||
<element name="availableInstances">
|
<element name="availableInstances">
|
||||||
|
@ -663,10 +663,15 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def)
|
|||||||
virBufferAsprintf(&buf, "<ap-domain>0x%04x</ap-domain>\n",
|
virBufferAsprintf(&buf, "<ap-domain>0x%04x</ap-domain>\n",
|
||||||
data->ap_queue.ap_domain);
|
data->ap_queue.ap_domain);
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
||||||
|
if (data->ap_matrix.flags & VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV)
|
||||||
|
virNodeDeviceCapMdevTypesFormat(&buf,
|
||||||
|
data->ap_matrix.mdev_types,
|
||||||
|
data->ap_matrix.nmdev_types);
|
||||||
|
|
||||||
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
case VIR_NODE_DEV_CAP_VPORTS:
|
case VIR_NODE_DEV_CAP_VPORTS:
|
||||||
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -861,6 +866,33 @@ virNodeDevCapMdevTypesParseXML(xmlXPathContextPtr ctxt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNodeDevAPMatrixCapabilityParseXML(xmlXPathContextPtr ctxt,
|
||||||
|
xmlNodePtr node,
|
||||||
|
virNodeDevCapAPMatrixPtr apm_dev)
|
||||||
|
{
|
||||||
|
g_autofree char *type = virXMLPropString(node, "type");
|
||||||
|
VIR_XPATH_NODE_AUTORESTORE(ctxt)
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing capability type"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STREQ(type, "mdev_types")) {
|
||||||
|
if (virNodeDevCapMdevTypesParseXML(ctxt,
|
||||||
|
&apm_dev->mdev_types,
|
||||||
|
&apm_dev->nmdev_types) < 0)
|
||||||
|
return -1;
|
||||||
|
apm_dev->flags |= VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virNodeDevCSSCapabilityParseXML(xmlXPathContextPtr ctxt,
|
virNodeDevCSSCapabilityParseXML(xmlXPathContextPtr ctxt,
|
||||||
xmlNodePtr node,
|
xmlNodePtr node,
|
||||||
@ -1033,6 +1065,31 @@ virNodeDevCapAPQueueParseXML(xmlXPathContextPtr ctxt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNodeDevCapAPMatrixParseXML(xmlXPathContextPtr ctxt,
|
||||||
|
virNodeDeviceDefPtr def G_GNUC_UNUSED,
|
||||||
|
xmlNodePtr node,
|
||||||
|
virNodeDevCapAPMatrixPtr ap_matrix)
|
||||||
|
{
|
||||||
|
VIR_XPATH_NODE_AUTORESTORE(ctxt)
|
||||||
|
g_autofree xmlNodePtr *nodes = NULL;
|
||||||
|
int n = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
if ((n = virXPathNodeSet("./capability", ctxt, &nodes)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
if (virNodeDevAPMatrixCapabilityParseXML(ctxt, nodes[i], ap_matrix) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
|
virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
|
||||||
virNodeDeviceDefPtr def,
|
virNodeDeviceDefPtr def,
|
||||||
@ -2080,7 +2137,8 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
|
|||||||
&caps->data.ap_queue);
|
&caps->data.ap_queue);
|
||||||
break;
|
break;
|
||||||
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
||||||
ret = 0;
|
ret = virNodeDevCapAPMatrixParseXML(ctxt, def, node,
|
||||||
|
&caps->data.ap_matrix);
|
||||||
break;
|
break;
|
||||||
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
@ -2405,6 +2463,9 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
|
|||||||
break;
|
break;
|
||||||
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
||||||
VIR_FREE(data->ap_matrix.addr);
|
VIR_FREE(data->ap_matrix.addr);
|
||||||
|
for (i = 0; i < data->ap_matrix.nmdev_types; i++)
|
||||||
|
virMediatedDeviceTypeFree(data->ap_matrix.mdev_types[i]);
|
||||||
|
VIR_FREE(data->ap_matrix.mdev_types);
|
||||||
break;
|
break;
|
||||||
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
||||||
case VIR_NODE_DEV_CAP_DRM:
|
case VIR_NODE_DEV_CAP_DRM:
|
||||||
@ -2456,6 +2517,11 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def)
|
|||||||
&cap->data.ccw_dev) < 0)
|
&cap->data.ccw_dev) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
||||||
|
if (virNodeDeviceGetAPMatrixDynamicCaps(def->sysfs_path,
|
||||||
|
&cap->data.ap_matrix) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
/* all types that (supposedly) don't require any updates
|
/* all types that (supposedly) don't require any updates
|
||||||
* relative to what's in the cache.
|
* relative to what's in the cache.
|
||||||
@ -2475,7 +2541,6 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def)
|
|||||||
case VIR_NODE_DEV_CAP_VDPA:
|
case VIR_NODE_DEV_CAP_VDPA:
|
||||||
case VIR_NODE_DEV_CAP_AP_CARD:
|
case VIR_NODE_DEV_CAP_AP_CARD:
|
||||||
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
||||||
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2558,6 +2623,15 @@ virNodeDeviceCapsListExport(virNodeDeviceDefPtr def,
|
|||||||
ncaps++;
|
ncaps++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (caps->data.type == VIR_NODE_DEV_CAP_AP_MATRIX) {
|
||||||
|
flags = caps->data.ap_matrix.flags;
|
||||||
|
|
||||||
|
if (flags & VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV) {
|
||||||
|
MAYBE_ADD_CAP(VIR_NODE_DEV_CAP_MDEV_TYPES);
|
||||||
|
ncaps++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MAYBE_ADD_CAP
|
#undef MAYBE_ADD_CAP
|
||||||
@ -2845,6 +2919,27 @@ virNodeDeviceGetCSSDynamicCaps(const char *sysfsPath,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* virNodeDeviceGetAPMatrixDynamicCaps() 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
|
||||||
|
virNodeDeviceGetAPMatrixDynamicCaps(const char *sysfsPath,
|
||||||
|
virNodeDevCapAPMatrixPtr ap_matrix)
|
||||||
|
{
|
||||||
|
ap_matrix->flags &= ~VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV;
|
||||||
|
if (virNodeDeviceGetMdevTypesCaps(sysfsPath,
|
||||||
|
&ap_matrix->mdev_types,
|
||||||
|
&ap_matrix->nmdev_types) < 0)
|
||||||
|
return -1;
|
||||||
|
if (ap_matrix->nmdev_types > 0)
|
||||||
|
ap_matrix->flags |= VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -2874,4 +2969,11 @@ virNodeDeviceGetCSSDynamicCaps(const char *sysfsPath G_GNUC_UNUSED,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virNodeDeviceGetAPMatrixDynamicCaps(const char *sysfsPath G_GNUC_UNUSED,
|
||||||
|
virNodeDevCapAPMatrixPtr ap_matrix G_GNUC_UNUSED)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
@ -109,6 +109,10 @@ typedef enum {
|
|||||||
VIR_NODE_DEV_CAP_FLAG_CSS_MDEV = (1 << 0),
|
VIR_NODE_DEV_CAP_FLAG_CSS_MDEV = (1 << 0),
|
||||||
} virNodeDevCCWCapFlags;
|
} virNodeDevCCWCapFlags;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV = (1 << 0),
|
||||||
|
} virNodeDevAPMatrixCapFlags;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
|
/* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
|
||||||
VIR_NODE_DEV_DRM_PRIMARY,
|
VIR_NODE_DEV_DRM_PRIMARY,
|
||||||
@ -309,6 +313,9 @@ typedef struct _virNodeDevCapAPMatrix virNodeDevCapAPMatrix;
|
|||||||
typedef virNodeDevCapAPMatrix *virNodeDevCapAPMatrixPtr;
|
typedef virNodeDevCapAPMatrix *virNodeDevCapAPMatrixPtr;
|
||||||
struct _virNodeDevCapAPMatrix {
|
struct _virNodeDevCapAPMatrix {
|
||||||
char *addr;
|
char *addr;
|
||||||
|
unsigned int flags; /* enum virNodeDevAPMatrixCapFlags */
|
||||||
|
virMediatedDeviceTypePtr *mdev_types;
|
||||||
|
size_t nmdev_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _virNodeDevCapData virNodeDevCapData;
|
typedef struct _virNodeDevCapData virNodeDevCapData;
|
||||||
@ -430,6 +437,10 @@ int
|
|||||||
virNodeDeviceGetCSSDynamicCaps(const char *sysfsPath,
|
virNodeDeviceGetCSSDynamicCaps(const char *sysfsPath,
|
||||||
virNodeDevCapCCWPtr ccw_dev);
|
virNodeDevCapCCWPtr ccw_dev);
|
||||||
|
|
||||||
|
int
|
||||||
|
virNodeDeviceGetAPMatrixDynamicCaps(const char *sysfsPath,
|
||||||
|
virNodeDevCapAPMatrixPtr ap_matrix);
|
||||||
|
|
||||||
int
|
int
|
||||||
virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def);
|
virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def);
|
||||||
|
|
||||||
|
@ -702,6 +702,12 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj,
|
|||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
||||||
|
if (type == VIR_NODE_DEV_CAP_MDEV_TYPES &&
|
||||||
|
(cap->data.ap_matrix.flags & VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_NODE_DEV_CAP_SYSTEM:
|
case VIR_NODE_DEV_CAP_SYSTEM:
|
||||||
case VIR_NODE_DEV_CAP_USB_DEV:
|
case VIR_NODE_DEV_CAP_USB_DEV:
|
||||||
case VIR_NODE_DEV_CAP_USB_INTERFACE:
|
case VIR_NODE_DEV_CAP_USB_INTERFACE:
|
||||||
@ -719,7 +725,6 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj,
|
|||||||
case VIR_NODE_DEV_CAP_VDPA:
|
case VIR_NODE_DEV_CAP_VDPA:
|
||||||
case VIR_NODE_DEV_CAP_AP_CARD:
|
case VIR_NODE_DEV_CAP_AP_CARD:
|
||||||
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
||||||
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -823,6 +823,7 @@ virNodeDeviceDefFree;
|
|||||||
virNodeDeviceDefParseFile;
|
virNodeDeviceDefParseFile;
|
||||||
virNodeDeviceDefParseNode;
|
virNodeDeviceDefParseNode;
|
||||||
virNodeDeviceDefParseString;
|
virNodeDeviceDefParseString;
|
||||||
|
virNodeDeviceGetAPMatrixDynamicCaps;
|
||||||
virNodeDeviceGetCSSDynamicCaps;
|
virNodeDeviceGetCSSDynamicCaps;
|
||||||
virNodeDeviceGetPCIDynamicCaps;
|
virNodeDeviceGetPCIDynamicCaps;
|
||||||
virNodeDeviceGetSCSIHostCaps;
|
virNodeDeviceGetSCSIHostCaps;
|
||||||
|
@ -1247,6 +1247,10 @@ udevProcessAPMatrix(struct udev_device *device,
|
|||||||
data->ap_matrix.addr = g_strdup(udev_device_get_sysname(device));
|
data->ap_matrix.addr = g_strdup(udev_device_get_sysname(device));
|
||||||
def->name = g_strdup("ap_matrix");
|
def->name = g_strdup("ap_matrix");
|
||||||
|
|
||||||
|
if (virNodeDeviceGetAPMatrixDynamicCaps(def->sysfs_path,
|
||||||
|
&data->ap_matrix) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
tests/nodedevschemadata/ap_matrix_mdev_types.xml
Normal file
14
tests/nodedevschemadata/ap_matrix_mdev_types.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<device>
|
||||||
|
<name>ap_matrix</name>
|
||||||
|
<path>/sys/devices/vfio_ap/matrix</path>
|
||||||
|
<parent>computer</parent>
|
||||||
|
<capability type='ap_matrix'>
|
||||||
|
<capability type='mdev_types'>
|
||||||
|
<type id='vfio_ap-passthrough'>
|
||||||
|
<name>VFIO AP Passthrough Device</name>
|
||||||
|
<deviceAPI>vfio-ap</deviceAPI>
|
||||||
|
<availableInstances>65536</availableInstances>
|
||||||
|
</type>
|
||||||
|
</capability>
|
||||||
|
</capability>
|
||||||
|
</device>
|
@ -128,6 +128,7 @@ mymain(void)
|
|||||||
DO_TEST("ap_card07");
|
DO_TEST("ap_card07");
|
||||||
DO_TEST("ap_07_0038");
|
DO_TEST("ap_07_0038");
|
||||||
DO_TEST("ap_matrix");
|
DO_TEST("ap_matrix");
|
||||||
|
DO_TEST("ap_matrix_mdev_types");
|
||||||
DO_TEST("mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad");
|
DO_TEST("mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad");
|
||||||
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
Loading…
Reference in New Issue
Block a user