[PATCH libvirt v1 0/7] Support AP card, AP queues and AP matrix

Add support for AP card devices, AP queues and AP matrix devices in libvirt node device driver. Farhan Ali (3): nodedev: Detect AP Card device nodedev: Detect AP Queues virsh: nodedev: Filter by AP Card and AP Queue capabilities Shalini Chellathurai Saroja (4): nodedev: detect AP Matrix device virsh: nodedev: filter by AP Matrix capability node_device: refactor address retrieval of node device node_device: mdev matrix support docs/formatnode.html.in | 21 ++++ docs/manpages/virsh.rst | 2 +- docs/schemas/nodedev.rng | 66 ++++++++++- include/libvirt/libvirt-nodedev.h | 3 + src/conf/node_device_conf.c | 111 +++++++++++++++++- src/conf/node_device_conf.h | 30 ++++- src/conf/virnodedeviceobj.c | 8 +- src/libvirt-nodedev.c | 3 + src/node_device/node_device_driver.c | 32 ++++- src/node_device/node_device_udev.c | 80 +++++++++++++ tests/nodedevschemadata/ap_07_0038.xml | 9 ++ tests/nodedevschemadata/ap_card07.xml | 8 ++ tests/nodedevschemadata/ap_matrix.xml | 7 ++ ...v_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml | 9 ++ tests/nodedevxml2xmltest.c | 4 + tools/virsh-nodedev.c | 9 ++ 16 files changed, 390 insertions(+), 12 deletions(-) create mode 100644 tests/nodedevschemadata/ap_07_0038.xml create mode 100644 tests/nodedevschemadata/ap_card07.xml create mode 100644 tests/nodedevschemadata/ap_matrix.xml create mode 100644 tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml -- 2.26.2

From: Farhan Ali <alifm@linux.ibm.com> Introduce support for the Adjunct Processor (AP) Crypto Card device. Udev already detects the device, so add support for libvirt nodedev driver. Signed-off-by: Farhan Ali <alifm@linux.ibm.com> Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/formatnode.html.in | 7 +++++ docs/schemas/nodedev.rng | 34 ++++++++++++++++++---- src/conf/node_device_conf.c | 42 +++++++++++++++++++++++++++ src/conf/node_device_conf.h | 8 +++++ src/conf/virnodedeviceobj.c | 1 + src/node_device/node_device_udev.c | 30 +++++++++++++++++++ tests/nodedevschemadata/ap_card07.xml | 8 +++++ tests/nodedevxml2xmltest.c | 1 + tools/virsh-nodedev.c | 1 + 9 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 tests/nodedevschemadata/ap_card07.xml diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in index 59442746..300ddf21 100644 --- a/docs/formatnode.html.in +++ b/docs/formatnode.html.in @@ -432,6 +432,13 @@ <dd>The device number.</dd> </dl> </dd> + <dt><code>ap_card</code></dt> + <dd>Describes the AP Card device on a S390 host. Sub-elements include: + <dl> + <dt><code>ap-adapter</code></dt> + <dd>AP Card identifier.</dd> + </dl> + </dd> </dl> </dd> </dl> diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index 166e278c..06ccb9c8 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -86,6 +86,7 @@ <ref name="capmdev"/> <ref name="capccwdev"/> <ref name="capcssdev"/> + <ref name="capapcard"/> </choice> </element> </define> @@ -675,12 +676,21 @@ </element> </define> - <define name="address"> - <element name="address"> - <attribute name="domain"><ref name="hexuint"/></attribute> - <attribute name="bus"><ref name="hexuint"/></attribute> - <attribute name="slot"><ref name="hexuint"/></attribute> - <attribute name="function"><ref name="hexuint"/></attribute> + <define name='capapcard'> + <attribute name='type'> + <value>ap_card</value> + </attribute> + <element name='ap-adapter'> + <ref name='apAdapterRange'/> + </element> + </define> + + <define name='address'> + <element name='address'> + <attribute name='domain'><ref name='hexuint'/></attribute> + <attribute name='bus'><ref name='hexuint'/></attribute> + <attribute name='slot'><ref name='hexuint'/></attribute> + <attribute name='function'><ref name='hexuint'/></attribute> </element> </define> @@ -696,4 +706,16 @@ </data> </define> + <define name="apAdapterRange"> + <choice> + <data type="string"> + <param name="pattern">(0x)?[0-9a-fA-F]{1,2}</param> + </data> + <data type="int"> + <param name="minInclusive">0</param> + <param name="maxInclusive">255</param> + </data> + </choice> + </define> + </grammar> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 4adfdef5..88c00b5b 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -66,6 +66,7 @@ VIR_ENUM_IMPL(virNodeDevCap, "mdev", "ccw", "css", + "ap_card", ); VIR_ENUM_IMPL(virNodeDevNetCap, @@ -611,6 +612,10 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) virBufferAsprintf(&buf, "<devno>0x%04x</devno>\n", data->ccw_dev.devno); break; + case VIR_NODE_DEV_CAP_AP_CARD: + virBufferAsprintf(&buf, "<ap-adapter>0x%02x</ap-adapter>\n", + data->ap_card.ap_adapter); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -803,6 +808,37 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, } +static int +virNodeDevCapAPCardParseXML(xmlXPathContextPtr ctxt, + virNodeDeviceDefPtr def, + xmlNodePtr node, + virNodeDevCapAPCardPtr ap_card) +{ + xmlNodePtr orig; + int ret = 0; + g_autofree char *adapter = NULL; + + orig = ctxt->node; + ctxt->node = node; + + if (!(adapter = virXPathString("string(./ap-adapter[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ap-adapter value for '%s'"), def->name); + return -1; + } + + if (virStrToLong_uip(adapter, NULL, 0, &ap_card->ap_adapter) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-adapter value '%s' for '%s'"), + adapter, def->name); + ret = -1; + } + + ctxt->node = orig; + return ret; +} + + static int virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, @@ -1898,6 +1934,10 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, case VIR_NODE_DEV_CAP_CSS_DEV: ret = virNodeDevCapCCWParseXML(ctxt, def, node, &caps->data.ccw_dev); break; + case VIR_NODE_DEV_CAP_AP_CARD: + ret = virNodeDevCapAPCardParseXML(ctxt, def, node, + &caps->data.ap_card); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2219,6 +2259,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: /* This case is here to shutup the compiler */ break; @@ -2273,6 +2314,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) case VIR_NODE_DEV_CAP_MDEV: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 5484bc34..aa2dac43 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -65,6 +65,7 @@ typedef enum { VIR_NODE_DEV_CAP_MDEV, /* Mediated device */ VIR_NODE_DEV_CAP_CCW_DEV, /* s390 CCW device */ VIR_NODE_DEV_CAP_CSS_DEV, /* s390 channel subsystem device */ + VIR_NODE_DEV_CAP_AP_CARD, /* s390 AP Card device */ VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -275,6 +276,12 @@ struct _virNodeDevCapCCW { unsigned int devno; }; +typedef struct _virNodeDevCapAPCard virNodeDevCapAPCard; +typedef virNodeDevCapAPCard *virNodeDevCapAPCardPtr; +struct _virNodeDevCapAPCard { + unsigned int ap_adapter; +}; + typedef struct _virNodeDevCapData virNodeDevCapData; typedef virNodeDevCapData *virNodeDevCapDataPtr; struct _virNodeDevCapData { @@ -293,6 +300,7 @@ struct _virNodeDevCapData { virNodeDevCapDRM drm; virNodeDevCapMdev mdev; virNodeDevCapCCW ccw_dev; + virNodeDevCapAPCard ap_card; }; }; diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 9af80b80..8d3e5a43 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -711,6 +711,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_MDEV: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 29a7eaa0..c513b4cc 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1142,6 +1142,32 @@ udevProcessCSS(struct udev_device *device, return 0; } + +static int +udevProcessAPCard(struct udev_device *device, + virNodeDeviceDefPtr def) +{ + char *c; + virNodeDevCapDataPtr data = &def->caps->data; + + /* The sysfs path would be in the format /sys/bus/ap/devices/cardXX, + where XX is the ap adapter id */ + if ((c = strrchr(def->sysfs_path, '/')) == NULL || + virStrToLong_ui(c + 1 + strlen("card"), NULL, 16, + &data->ap_card.ap_adapter) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse the AP Card from sysfs path: '%s'"), + def->sysfs_path); + return -1; + } + + if (udevGenerateDeviceName(device, def, NULL) != 0) + return -1; + + return 0; +} + + static int udevGetDeviceNodes(struct udev_device *device, virNodeDeviceDefPtr def) @@ -1196,6 +1222,8 @@ udevGetDeviceType(struct udev_device *device, *type = VIR_NODE_DEV_CAP_NET; else if (STREQ(devtype, "drm_minor")) *type = VIR_NODE_DEV_CAP_DRM; + else if (STREQ(devtype, "ap_card")) + *type = VIR_NODE_DEV_CAP_AP_CARD; } else { /* PCI devices don't set the DEVTYPE property. */ if (udevHasDeviceProperty(device, "PCI_CLASS")) @@ -1267,6 +1295,8 @@ udevGetDeviceDetails(struct udev_device *device, return udevProcessCCW(device, def); case VIR_NODE_DEV_CAP_CSS_DEV: return udevProcessCSS(device, def); + case VIR_NODE_DEV_CAP_AP_CARD: + return udevProcessAPCard(device, def); case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_FC_HOST: diff --git a/tests/nodedevschemadata/ap_card07.xml b/tests/nodedevschemadata/ap_card07.xml new file mode 100644 index 00000000..14a845fd --- /dev/null +++ b/tests/nodedevschemadata/ap_card07.xml @@ -0,0 +1,8 @@ +<device> + <name>ap_card07</name> + <path>/sys/devices/ap/card07</path> + <parent>computer</parent> + <capability type='ap_card'> + <ap-adapter>0x07</ap-adapter> + </capability> +</device> diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index 3cb23b1d..7990f6cd 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -124,6 +124,7 @@ mymain(void) DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b"); DO_TEST("ccw_0_0_ffff"); DO_TEST("css_0_0_ffff"); + DO_TEST("ap_card07"); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 483e36bd..98268916 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -464,6 +464,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) case VIR_NODE_DEV_CAP_CSS_DEV: flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV; break; + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; } -- 2.26.2

On 10/21/20 12:59 PM, Shalini Chellathurai Saroja wrote:
From: Farhan Ali <alifm@linux.ibm.com>
Introduce support for the Adjunct Processor (AP) Crypto Card device. Udev already detects the device, so add support for libvirt nodedev driver.
Signed-off-by: Farhan Ali <alifm@linux.ibm.com> Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/formatnode.html.in | 7 +++++ docs/schemas/nodedev.rng | 34 ++++++++++++++++++---- src/conf/node_device_conf.c | 42 +++++++++++++++++++++++++++ src/conf/node_device_conf.h | 8 +++++ src/conf/virnodedeviceobj.c | 1 + src/node_device/node_device_udev.c | 30 +++++++++++++++++++ tests/nodedevschemadata/ap_card07.xml | 8 +++++ tests/nodedevxml2xmltest.c | 1 + tools/virsh-nodedev.c | 1 + 9 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 tests/nodedevschemadata/ap_card07.xml
diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in index 59442746..300ddf21 100644 --- a/docs/formatnode.html.in +++ b/docs/formatnode.html.in @@ -432,6 +432,13 @@ <dd>The device number.</dd> </dl> </dd> + <dt><code>ap_card</code></dt> + <dd>Describes the AP Card device on a S390 host. Sub-elements include: + <dl> + <dt><code>ap-adapter</code></dt> + <dd>AP Card identifier.</dd> + </dl> + </dd> </dl> </dd> </dl> diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index 166e278c..06ccb9c8 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -86,6 +86,7 @@ <ref name="capmdev"/> <ref name="capccwdev"/> <ref name="capcssdev"/> + <ref name="capapcard"/> </choice> </element> </define> @@ -675,12 +676,21 @@ </element> </define>
- <define name="address"> - <element name="address"> - <attribute name="domain"><ref name="hexuint"/></attribute> - <attribute name="bus"><ref name="hexuint"/></attribute> - <attribute name="slot"><ref name="hexuint"/></attribute> - <attribute name="function"><ref name="hexuint"/></attribute> + <define name='capapcard'> + <attribute name='type'> + <value>ap_card</value> + </attribute> + <element name='ap-adapter'> + <ref name='apAdapterRange'/> + </element> + </define> + + <define name='address'> + <element name='address'> + <attribute name='domain'><ref name='hexuint'/></attribute> + <attribute name='bus'><ref name='hexuint'/></attribute> + <attribute name='slot'><ref name='hexuint'/></attribute> + <attribute name='function'><ref name='hexuint'/></attribute> </element> </define>
@@ -696,4 +706,16 @@ </data> </define>
+ <define name="apAdapterRange"> + <choice> + <data type="string"> + <param name="pattern">(0x)?[0-9a-fA-F]{1,2}</param> + </data> + <data type="int"> + <param name="minInclusive">0</param> + <param name="maxInclusive">255</param> + </data> + </choice> + </define> ^ wrong indent
+ </grammar> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 4adfdef5..88c00b5b 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -66,6 +66,7 @@ VIR_ENUM_IMPL(virNodeDevCap, "mdev", "ccw", "css", + "ap_card", );
VIR_ENUM_IMPL(virNodeDevNetCap, @@ -611,6 +612,10 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) virBufferAsprintf(&buf, "<devno>0x%04x</devno>\n", data->ccw_dev.devno); break; + case VIR_NODE_DEV_CAP_AP_CARD: + virBufferAsprintf(&buf, "<ap-adapter>0x%02x</ap-adapter>\n", + data->ap_card.ap_adapter); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -803,6 +808,37 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, }
+static int +virNodeDevCapAPCardParseXML(xmlXPathContextPtr ctxt, + virNodeDeviceDefPtr def, + xmlNodePtr node, + virNodeDevCapAPCardPtr ap_card) +{ + xmlNodePtr orig; + int ret = 0; + g_autofree char *adapter = NULL; + + orig = ctxt->node; + ctxt->node = node; + + if (!(adapter = virXPathString("string(./ap-adapter[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ap-adapter value for '%s'"), def->name); + return -1; + } + + if (virStrToLong_uip(adapter, NULL, 0, &ap_card->ap_adapter) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-adapter value '%s' for '%s'"), + adapter, def->name); + ret = -1; + } + + ctxt->node = orig; + return ret; +} + + static int virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, @@ -1898,6 +1934,10 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, case VIR_NODE_DEV_CAP_CSS_DEV: ret = virNodeDevCapCCWParseXML(ctxt, def, node, &caps->data.ccw_dev); break; + case VIR_NODE_DEV_CAP_AP_CARD: + ret = virNodeDevCapAPCardParseXML(ctxt, def, node, + &caps->data.ap_card); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2219,6 +2259,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: /* This case is here to shutup the compiler */ break; @@ -2273,6 +2314,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) case VIR_NODE_DEV_CAP_MDEV: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 5484bc34..aa2dac43 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -65,6 +65,7 @@ typedef enum { VIR_NODE_DEV_CAP_MDEV, /* Mediated device */ VIR_NODE_DEV_CAP_CCW_DEV, /* s390 CCW device */ VIR_NODE_DEV_CAP_CSS_DEV, /* s390 channel subsystem device */ + VIR_NODE_DEV_CAP_AP_CARD, /* s390 AP Card device */
VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -275,6 +276,12 @@ struct _virNodeDevCapCCW { unsigned int devno; };
+typedef struct _virNodeDevCapAPCard virNodeDevCapAPCard; +typedef virNodeDevCapAPCard *virNodeDevCapAPCardPtr; +struct _virNodeDevCapAPCard { + unsigned int ap_adapter; +}; + typedef struct _virNodeDevCapData virNodeDevCapData; typedef virNodeDevCapData *virNodeDevCapDataPtr; struct _virNodeDevCapData { @@ -293,6 +300,7 @@ struct _virNodeDevCapData { virNodeDevCapDRM drm; virNodeDevCapMdev mdev; virNodeDevCapCCW ccw_dev; + virNodeDevCapAPCard ap_card; }; };
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 9af80b80..8d3e5a43 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -711,6 +711,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_MDEV: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 29a7eaa0..c513b4cc 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1142,6 +1142,32 @@ udevProcessCSS(struct udev_device *device, return 0; }
+ +static int +udevProcessAPCard(struct udev_device *device, + virNodeDeviceDefPtr def) +{ + char *c; + virNodeDevCapDataPtr data = &def->caps->data; + + /* The sysfs path would be in the format /sys/bus/ap/devices/cardXX, + where XX is the ap adapter id */ + if ((c = strrchr(def->sysfs_path, '/')) == NULL || + virStrToLong_ui(c + 1 + strlen("card"), NULL, 16, + &data->ap_card.ap_adapter) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse the AP Card from sysfs path: '%s'"), + def->sysfs_path); + return -1; + } + + if (udevGenerateDeviceName(device, def, NULL) != 0) + return -1; + + return 0; +} + + static int udevGetDeviceNodes(struct udev_device *device, virNodeDeviceDefPtr def) @@ -1196,6 +1222,8 @@ udevGetDeviceType(struct udev_device *device, *type = VIR_NODE_DEV_CAP_NET; else if (STREQ(devtype, "drm_minor")) *type = VIR_NODE_DEV_CAP_DRM; + else if (STREQ(devtype, "ap_card")) + *type = VIR_NODE_DEV_CAP_AP_CARD; } else { /* PCI devices don't set the DEVTYPE property. */ if (udevHasDeviceProperty(device, "PCI_CLASS")) @@ -1267,6 +1295,8 @@ udevGetDeviceDetails(struct udev_device *device, return udevProcessCCW(device, def); case VIR_NODE_DEV_CAP_CSS_DEV: return udevProcessCSS(device, def); + case VIR_NODE_DEV_CAP_AP_CARD: + return udevProcessAPCard(device, def); case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_FC_HOST: diff --git a/tests/nodedevschemadata/ap_card07.xml b/tests/nodedevschemadata/ap_card07.xml new file mode 100644 index 00000000..14a845fd --- /dev/null +++ b/tests/nodedevschemadata/ap_card07.xml @@ -0,0 +1,8 @@ +<device> + <name>ap_card07</name> + <path>/sys/devices/ap/card07</path> + <parent>computer</parent> + <capability type='ap_card'> + <ap-adapter>0x07</ap-adapter> + </capability> +</device> diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index 3cb23b1d..7990f6cd 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -124,6 +124,7 @@ mymain(void) DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b"); DO_TEST("ccw_0_0_ffff"); DO_TEST("css_0_0_ffff"); + DO_TEST("ap_card07");
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 483e36bd..98268916 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -464,6 +464,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) case VIR_NODE_DEV_CAP_CSS_DEV: flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV; break; + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; }
-- Mit freundlichen Grüßen/Kind regards Boris Fiuczynski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Gregor Pillen Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

This patch is doing multiple things in a single punch: - docs/ changes - parse code in src/conf - added logic in node_device_udev.c - test changes I suggest you split this one in at least 3 patches: changes in 'docs', changes in 'src/conf' with nodedevxml2xmltest.c changes, another patch with the remaining logic and tests. More suggestions below: On 10/21/20 7:59 AM, Shalini Chellathurai Saroja wrote:
From: Farhan Ali <alifm@linux.ibm.com>
Introduce support for the Adjunct Processor (AP) Crypto Card device. Udev already detects the device, so add support for libvirt nodedev driver.
Signed-off-by: Farhan Ali <alifm@linux.ibm.com> Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/formatnode.html.in | 7 +++++ docs/schemas/nodedev.rng | 34 ++++++++++++++++++---- src/conf/node_device_conf.c | 42 +++++++++++++++++++++++++++ src/conf/node_device_conf.h | 8 +++++ src/conf/virnodedeviceobj.c | 1 + src/node_device/node_device_udev.c | 30 +++++++++++++++++++ tests/nodedevschemadata/ap_card07.xml | 8 +++++ tests/nodedevxml2xmltest.c | 1 + tools/virsh-nodedev.c | 1 + 9 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 tests/nodedevschemadata/ap_card07.xml
diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in index 59442746..300ddf21 100644 --- a/docs/formatnode.html.in +++ b/docs/formatnode.html.in @@ -432,6 +432,13 @@ <dd>The device number.</dd> </dl> </dd> + <dt><code>ap_card</code></dt> + <dd>Describes the AP Card device on a S390 host. Sub-elements include:
It would be nice to mention here that AP stands for Adjunct Processor.
+ <dl> + <dt><code>ap-adapter</code></dt> + <dd>AP Card identifier.</dd> + </dl> + </dd> </dl> </dd> </dl> diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index 166e278c..06ccb9c8 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -86,6 +86,7 @@ <ref name="capmdev"/> <ref name="capccwdev"/> <ref name="capcssdev"/> + <ref name="capapcard"/> </choice> </element> </define> @@ -675,12 +676,21 @@ </element> </define>
- <define name="address"> - <element name="address"> - <attribute name="domain"><ref name="hexuint"/></attribute> - <attribute name="bus"><ref name="hexuint"/></attribute> - <attribute name="slot"><ref name="hexuint"/></attribute> - <attribute name="function"><ref name="hexuint"/></attribute> + <define name='capapcard'> + <attribute name='type'> + <value>ap_card</value> + </attribute> + <element name='ap-adapter'> + <ref name='apAdapterRange'/> + </element> + </define> + + <define name='address'> + <element name='address'> + <attribute name='domain'><ref name='hexuint'/></attribute> + <attribute name='bus'><ref name='hexuint'/></attribute> + <attribute name='slot'><ref name='hexuint'/></attribute> + <attribute name='function'><ref name='hexuint'/></attribute> </element> </define>
@@ -696,4 +706,16 @@ </data> </define>
+ <define name="apAdapterRange"> + <choice> + <data type="string"> + <param name="pattern">(0x)?[0-9a-fA-F]{1,2}</param> + </data> + <data type="int"> + <param name="minInclusive">0</param> + <param name="maxInclusive">255</param> + </data> + </choice> + </define> + </grammar> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 4adfdef5..88c00b5b 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -66,6 +66,7 @@ VIR_ENUM_IMPL(virNodeDevCap, "mdev", "ccw", "css", + "ap_card", );
VIR_ENUM_IMPL(virNodeDevNetCap, @@ -611,6 +612,10 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) virBufferAsprintf(&buf, "<devno>0x%04x</devno>\n", data->ccw_dev.devno); break; + case VIR_NODE_DEV_CAP_AP_CARD: + virBufferAsprintf(&buf, "<ap-adapter>0x%02x</ap-adapter>\n", + data->ap_card.ap_adapter); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -803,6 +808,37 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, }
+static int +virNodeDevCapAPCardParseXML(xmlXPathContextPtr ctxt, + virNodeDeviceDefPtr def, + xmlNodePtr node, + virNodeDevCapAPCardPtr ap_card) +{ + xmlNodePtr orig; + int ret = 0; + g_autofree char *adapter = NULL; + + orig = ctxt->node; + ctxt->node = node; + + if (!(adapter = virXPathString("string(./ap-adapter[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ap-adapter value for '%s'"), def->name); + return -1; + } + + if (virStrToLong_uip(adapter, NULL, 0, &ap_card->ap_adapter) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-adapter value '%s' for '%s'"), + adapter, def->name); + ret = -1;
You can just 'return -1' as you did in the previous 'if' and 'return 0' in the end of the function. Then you don't need the 'ret' variable.
+ } + + ctxt->node = orig; + return ret; +} + + static int virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, @@ -1898,6 +1934,10 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, case VIR_NODE_DEV_CAP_CSS_DEV: ret = virNodeDevCapCCWParseXML(ctxt, def, node, &caps->data.ccw_dev); break; + case VIR_NODE_DEV_CAP_AP_CARD: + ret = virNodeDevCapAPCardParseXML(ctxt, def, node, + &caps->data.ap_card); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2219,6 +2259,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: /* This case is here to shutup the compiler */ break; @@ -2273,6 +2314,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) case VIR_NODE_DEV_CAP_MDEV: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 5484bc34..aa2dac43 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -65,6 +65,7 @@ typedef enum { VIR_NODE_DEV_CAP_MDEV, /* Mediated device */ VIR_NODE_DEV_CAP_CCW_DEV, /* s390 CCW device */ VIR_NODE_DEV_CAP_CSS_DEV, /* s390 channel subsystem device */ + VIR_NODE_DEV_CAP_AP_CARD, /* s390 AP Card device */
VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -275,6 +276,12 @@ struct _virNodeDevCapCCW { unsigned int devno; };
+typedef struct _virNodeDevCapAPCard virNodeDevCapAPCard; +typedef virNodeDevCapAPCard *virNodeDevCapAPCardPtr; +struct _virNodeDevCapAPCard { + unsigned int ap_adapter; +}; + typedef struct _virNodeDevCapData virNodeDevCapData; typedef virNodeDevCapData *virNodeDevCapDataPtr; struct _virNodeDevCapData { @@ -293,6 +300,7 @@ struct _virNodeDevCapData { virNodeDevCapDRM drm; virNodeDevCapMdev mdev; virNodeDevCapCCW ccw_dev; + virNodeDevCapAPCard ap_card; }; };
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 9af80b80..8d3e5a43 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -711,6 +711,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_MDEV: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 29a7eaa0..c513b4cc 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1142,6 +1142,32 @@ udevProcessCSS(struct udev_device *device, return 0; }
+ +static int +udevProcessAPCard(struct udev_device *device, + virNodeDeviceDefPtr def) +{ + char *c; + virNodeDevCapDataPtr data = &def->caps->data; + + /* The sysfs path would be in the format /sys/bus/ap/devices/cardXX, + where XX is the ap adapter id */ + if ((c = strrchr(def->sysfs_path, '/')) == NULL || + virStrToLong_ui(c + 1 + strlen("card"), NULL, 16, + &data->ap_card.ap_adapter) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse the AP Card from sysfs path: '%s'"), + def->sysfs_path); + return -1; + } + + if (udevGenerateDeviceName(device, def, NULL) != 0) + return -1; + + return 0; +} + + static int udevGetDeviceNodes(struct udev_device *device, virNodeDeviceDefPtr def) @@ -1196,6 +1222,8 @@ udevGetDeviceType(struct udev_device *device, *type = VIR_NODE_DEV_CAP_NET; else if (STREQ(devtype, "drm_minor")) *type = VIR_NODE_DEV_CAP_DRM; + else if (STREQ(devtype, "ap_card")) + *type = VIR_NODE_DEV_CAP_AP_CARD; } else { /* PCI devices don't set the DEVTYPE property. */ if (udevHasDeviceProperty(device, "PCI_CLASS")) @@ -1267,6 +1295,8 @@ udevGetDeviceDetails(struct udev_device *device, return udevProcessCCW(device, def); case VIR_NODE_DEV_CAP_CSS_DEV: return udevProcessCSS(device, def); + case VIR_NODE_DEV_CAP_AP_CARD: + return udevProcessAPCard(device, def); case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_FC_HOST: diff --git a/tests/nodedevschemadata/ap_card07.xml b/tests/nodedevschemadata/ap_card07.xml new file mode 100644 index 00000000..14a845fd --- /dev/null +++ b/tests/nodedevschemadata/ap_card07.xml @@ -0,0 +1,8 @@ +<device> + <name>ap_card07</name> + <path>/sys/devices/ap/card07</path> + <parent>computer</parent> + <capability type='ap_card'> + <ap-adapter>0x07</ap-adapter> + </capability> +</device> diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index 3cb23b1d..7990f6cd 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -124,6 +124,7 @@ mymain(void) DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b"); DO_TEST("ccw_0_0_ffff"); DO_TEST("css_0_0_ffff"); + DO_TEST("ap_card07");
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 483e36bd..98268916 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -464,6 +464,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) case VIR_NODE_DEV_CAP_CSS_DEV: flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV; break; + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; }

From: Farhan Ali <alifm@linux.ibm.com> Each AP Card device can support upto 256 AP Queues. AP Queues are also detected by udev, so add support for libvirt nodedev driver. Signed-off-by: Farhan Ali <alifm@linux.ibm.com> Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/formatnode.html.in | 11 +++++ docs/schemas/nodedev.rng | 25 +++++++++++ src/conf/node_device_conf.c | 59 ++++++++++++++++++++++++++ src/conf/node_device_conf.h | 9 ++++ src/conf/virnodedeviceobj.c | 1 + src/node_device/node_device_udev.c | 27 ++++++++++++ tests/nodedevschemadata/ap_07_0038.xml | 9 ++++ tests/nodedevxml2xmltest.c | 1 + tools/virsh-nodedev.c | 1 + 9 files changed, 143 insertions(+) create mode 100644 tests/nodedevschemadata/ap_07_0038.xml diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in index 300ddf21..16f68f38 100644 --- a/docs/formatnode.html.in +++ b/docs/formatnode.html.in @@ -439,6 +439,17 @@ <dd>AP Card identifier.</dd> </dl> </dd> + <dt><code>ap_queue</code></dt> + <dd>Describes the AP Queue on a S390 host. An AP Queue is + identified by it's ap-adapter and ap-domain id. Sub-elements include: + <dl> + <dt><code>ap-adapter</code></dt> + <dd>The ap-adapter of an AP Queue identifies AP Card to which + this queue belongs.</dd> + <dt><code>ap-domain</code></dt> + <dd>AP Queue identifier.</dd> + </dl> + </dd> </dl> </dd> </dl> diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index 06ccb9c8..5f812c8f 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -87,6 +87,7 @@ <ref name="capccwdev"/> <ref name="capcssdev"/> <ref name="capapcard"/> + <ref name="capapqueue"/> </choice> </element> </define> @@ -685,6 +686,18 @@ </element> </define> + <define name='capapqueue'> + <attribute name='type'> + <value>ap_queue</value> + </attribute> + <element name='ap-adapter'> + <ref name='apAdapterRange'/> + </element> + <element name='ap-domain'> + <ref name='apDomainRange'/> + </element> + </define> + <define name='address'> <element name='address'> <attribute name='domain'><ref name='hexuint'/></attribute> @@ -718,4 +731,16 @@ </choice> </define> + <define name="apDomainRange"> + <choice> + <data type="string"> + <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param> + </data> + <data type="int"> + <param name="minInclusive">0</param> + <param name="maxInclusive">255</param> + </data> + </choice> + </define> + </grammar> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 88c00b5b..d27b0c71 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -67,6 +67,7 @@ VIR_ENUM_IMPL(virNodeDevCap, "ccw", "css", "ap_card", + "ap_queue", ); VIR_ENUM_IMPL(virNodeDevNetCap, @@ -616,6 +617,12 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) virBufferAsprintf(&buf, "<ap-adapter>0x%02x</ap-adapter>\n", data->ap_card.ap_adapter); break; + case VIR_NODE_DEV_CAP_AP_QUEUE: + virBufferAsprintf(&buf, "<ap-adapter>0x%02x</ap-adapter>\n", + data->ap_queue.ap_adapter); + virBufferAsprintf(&buf, "<ap-domain>0x%04x</ap-domain>\n", + data->ap_queue.ap_domain); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -839,6 +846,52 @@ virNodeDevCapAPCardParseXML(xmlXPathContextPtr ctxt, } +static int +virNodeDevCapAPQueueParseXML(xmlXPathContextPtr ctxt, + virNodeDeviceDefPtr def, + xmlNodePtr node, + virNodeDevCapAPQueuePtr ap_queue) +{ + xmlNodePtr orig; + int ret = -1; + g_autofree char *adapter = NULL, *dom = NULL; + + orig = ctxt->node; + ctxt->node = node; + + if (!(adapter = virXPathString("string(./ap-adapter[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ap-adapter value for '%s'"), def->name); + return -1; + } + + if (virStrToLong_uip(adapter, NULL, 0, &ap_queue->ap_adapter) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-adapter value '%s' for '%s'"), + adapter, def->name); + goto out; + } + + if (!(dom = virXPathString("string(./ap-domain[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ap-domain value for '%s'"), def->name); + goto out; + } + + if (virStrToLong_uip(dom, NULL, 0, &ap_queue->ap_domain) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-domain value '%s' for '%s'"), + dom, def->name); + goto out; + } + + ret = 0; + out: + ctxt->node = orig; + return ret; +} + + static int virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, @@ -1938,6 +1991,10 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, ret = virNodeDevCapAPCardParseXML(ctxt, def, node, &caps->data.ap_card); break; + case VIR_NODE_DEV_CAP_AP_QUEUE: + ret = virNodeDevCapAPQueueParseXML(ctxt, def, node, + &caps->data.ap_queue); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2260,6 +2317,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: /* This case is here to shutup the compiler */ break; @@ -2315,6 +2373,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index aa2dac43..c8100c8b 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -66,6 +66,7 @@ typedef enum { VIR_NODE_DEV_CAP_CCW_DEV, /* s390 CCW device */ VIR_NODE_DEV_CAP_CSS_DEV, /* s390 channel subsystem device */ VIR_NODE_DEV_CAP_AP_CARD, /* s390 AP Card device */ + VIR_NODE_DEV_CAP_AP_QUEUE, /* s390 AP Queue */ VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -282,6 +283,13 @@ struct _virNodeDevCapAPCard { unsigned int ap_adapter; }; +typedef struct _virNodeDevCapAPQueue virNodeDevCapAPQueue; +typedef virNodeDevCapAPQueue *virNodeDevCapAPQueuePtr; +struct _virNodeDevCapAPQueue { + unsigned int ap_adapter; + unsigned int ap_domain; +}; + typedef struct _virNodeDevCapData virNodeDevCapData; typedef virNodeDevCapData *virNodeDevCapDataPtr; struct _virNodeDevCapData { @@ -301,6 +309,7 @@ struct _virNodeDevCapData { virNodeDevCapMdev mdev; virNodeDevCapCCW ccw_dev; virNodeDevCapAPCard ap_card; + virNodeDevCapAPQueue ap_queue; }; }; diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 8d3e5a43..0fd44f6f 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -712,6 +712,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index c513b4cc..16a73db2 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1168,6 +1168,29 @@ udevProcessAPCard(struct udev_device *device, } +static int +udevProcessAPQueue(struct udev_device *device, + virNodeDeviceDefPtr def) +{ + char *c; + virNodeDevCapDataPtr data = &def->caps->data; + + if ((c = strrchr(def->sysfs_path, '/')) == NULL || + virStrToLong_ui(c + 1, &c, 16, &data->ap_queue.ap_adapter) < 0 || + virStrToLong_ui(c + 1, &c, 16, &data->ap_queue.ap_domain) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse the AP Queue from sysfs path: '%s'"), + def->sysfs_path); + return -1; + } + + if (udevGenerateDeviceName(device, def, NULL) != 0) + return -1; + + return 0; +} + + static int udevGetDeviceNodes(struct udev_device *device, virNodeDeviceDefPtr def) @@ -1224,6 +1247,8 @@ udevGetDeviceType(struct udev_device *device, *type = VIR_NODE_DEV_CAP_DRM; else if (STREQ(devtype, "ap_card")) *type = VIR_NODE_DEV_CAP_AP_CARD; + else if (STREQ(devtype, "ap_queue")) + *type = VIR_NODE_DEV_CAP_AP_QUEUE; } else { /* PCI devices don't set the DEVTYPE property. */ if (udevHasDeviceProperty(device, "PCI_CLASS")) @@ -1297,6 +1322,8 @@ udevGetDeviceDetails(struct udev_device *device, return udevProcessCSS(device, def); case VIR_NODE_DEV_CAP_AP_CARD: return udevProcessAPCard(device, def); + case VIR_NODE_DEV_CAP_AP_QUEUE: + return udevProcessAPQueue(device, def); case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_FC_HOST: diff --git a/tests/nodedevschemadata/ap_07_0038.xml b/tests/nodedevschemadata/ap_07_0038.xml new file mode 100644 index 00000000..553c68f2 --- /dev/null +++ b/tests/nodedevschemadata/ap_07_0038.xml @@ -0,0 +1,9 @@ +<device> + <name>ap_07_0038</name> + <path>/sys/devices/ap/card07/07.0038</path> + <parent>ap_card07</parent> + <capability type='ap_queue'> + <ap-adapter>0x07</ap-adapter> + <ap-domain>0x0038</ap-domain> + </capability> +</device> diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index 7990f6cd..d6ab25bf 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -125,6 +125,7 @@ mymain(void) DO_TEST("ccw_0_0_ffff"); DO_TEST("css_0_0_ffff"); DO_TEST("ap_card07"); + DO_TEST("ap_07_0038"); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 98268916..f79e0b78 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -465,6 +465,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV; break; case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: break; } -- 2.26.2

On 10/21/20 12:59 PM, Shalini Chellathurai Saroja wrote:
From: Farhan Ali <alifm@linux.ibm.com>
Each AP Card device can support upto 256 AP Queues. AP Queues are also detected by udev, so add support for libvirt nodedev driver.
Signed-off-by: Farhan Ali <alifm@linux.ibm.com> Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/formatnode.html.in | 11 +++++ docs/schemas/nodedev.rng | 25 +++++++++++ src/conf/node_device_conf.c | 59 ++++++++++++++++++++++++++ src/conf/node_device_conf.h | 9 ++++ src/conf/virnodedeviceobj.c | 1 + src/node_device/node_device_udev.c | 27 ++++++++++++ tests/nodedevschemadata/ap_07_0038.xml | 9 ++++ tests/nodedevxml2xmltest.c | 1 + tools/virsh-nodedev.c | 1 + 9 files changed, 143 insertions(+) create mode 100644 tests/nodedevschemadata/ap_07_0038.xml
diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in index 300ddf21..16f68f38 100644 --- a/docs/formatnode.html.in +++ b/docs/formatnode.html.in @@ -439,6 +439,17 @@ <dd>AP Card identifier.</dd> </dl> </dd> + <dt><code>ap_queue</code></dt> + <dd>Describes the AP Queue on a S390 host. An AP Queue is + identified by it's ap-adapter and ap-domain id. Sub-elements include: + <dl> + <dt><code>ap-adapter</code></dt> + <dd>The ap-adapter of an AP Queue identifies AP Card to which + this queue belongs.</dd> + <dt><code>ap-domain</code></dt> + <dd>AP Queue identifier.</dd> + </dl> + </dd> </dl> </dd> </dl> diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index 06ccb9c8..5f812c8f 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -87,6 +87,7 @@ <ref name="capccwdev"/> <ref name="capcssdev"/> <ref name="capapcard"/> + <ref name="capapqueue"/> </choice> </element> </define> @@ -685,6 +686,18 @@ </element> </define>
+ <define name='capapqueue'> + <attribute name='type'> + <value>ap_queue</value> + </attribute> + <element name='ap-adapter'> + <ref name='apAdapterRange'/> + </element> + <element name='ap-domain'> + <ref name='apDomainRange'/> + </element> + </define> + <define name='address'> <element name='address'> <attribute name='domain'><ref name='hexuint'/></attribute> @@ -718,4 +731,16 @@ </choice> </define>
+ <define name="apDomainRange"> + <choice> + <data type="string"> + <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param> + </data> + <data type="int"> + <param name="minInclusive">0</param> + <param name="maxInclusive">255</param> + </data> + </choice> + </define>The complete block has a wrong indent.
+ </grammar> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 88c00b5b..d27b0c71 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -67,6 +67,7 @@ VIR_ENUM_IMPL(virNodeDevCap, "ccw", "css", "ap_card", + "ap_queue", );
VIR_ENUM_IMPL(virNodeDevNetCap, @@ -616,6 +617,12 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) virBufferAsprintf(&buf, "<ap-adapter>0x%02x</ap-adapter>\n", data->ap_card.ap_adapter); break; + case VIR_NODE_DEV_CAP_AP_QUEUE: + virBufferAsprintf(&buf, "<ap-adapter>0x%02x</ap-adapter>\n", + data->ap_queue.ap_adapter); + virBufferAsprintf(&buf, "<ap-domain>0x%04x</ap-domain>\n", + data->ap_queue.ap_domain); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -839,6 +846,52 @@ virNodeDevCapAPCardParseXML(xmlXPathContextPtr ctxt, }
+static int +virNodeDevCapAPQueueParseXML(xmlXPathContextPtr ctxt, + virNodeDeviceDefPtr def, + xmlNodePtr node, + virNodeDevCapAPQueuePtr ap_queue) +{ + xmlNodePtr orig; + int ret = -1; + g_autofree char *adapter = NULL, *dom = NULL; + + orig = ctxt->node; + ctxt->node = node; + + if (!(adapter = virXPathString("string(./ap-adapter[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ap-adapter value for '%s'"), def->name); + return -1; + } + + if (virStrToLong_uip(adapter, NULL, 0, &ap_queue->ap_adapter) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-adapter value '%s' for '%s'"), + adapter, def->name); + goto out; + } + + if (!(dom = virXPathString("string(./ap-domain[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ap-domain value for '%s'"), def->name); + goto out; + } + + if (virStrToLong_uip(dom, NULL, 0, &ap_queue->ap_domain) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-domain value '%s' for '%s'"), + dom, def->name); + goto out; + } + + ret = 0; + out: + ctxt->node = orig; + return ret; +} + + static int virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, @@ -1938,6 +1991,10 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, ret = virNodeDevCapAPCardParseXML(ctxt, def, node, &caps->data.ap_card); break; + case VIR_NODE_DEV_CAP_AP_QUEUE: + ret = virNodeDevCapAPQueueParseXML(ctxt, def, node, + &caps->data.ap_queue); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2260,6 +2317,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: /* This case is here to shutup the compiler */ break; @@ -2315,6 +2373,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index aa2dac43..c8100c8b 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -66,6 +66,7 @@ typedef enum { VIR_NODE_DEV_CAP_CCW_DEV, /* s390 CCW device */ VIR_NODE_DEV_CAP_CSS_DEV, /* s390 channel subsystem device */ VIR_NODE_DEV_CAP_AP_CARD, /* s390 AP Card device */ + VIR_NODE_DEV_CAP_AP_QUEUE, /* s390 AP Queue */
VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -282,6 +283,13 @@ struct _virNodeDevCapAPCard { unsigned int ap_adapter; };
+typedef struct _virNodeDevCapAPQueue virNodeDevCapAPQueue; +typedef virNodeDevCapAPQueue *virNodeDevCapAPQueuePtr; +struct _virNodeDevCapAPQueue { + unsigned int ap_adapter; + unsigned int ap_domain; +}; + typedef struct _virNodeDevCapData virNodeDevCapData; typedef virNodeDevCapData *virNodeDevCapDataPtr; struct _virNodeDevCapData { @@ -301,6 +309,7 @@ struct _virNodeDevCapData { virNodeDevCapMdev mdev; virNodeDevCapCCW ccw_dev; virNodeDevCapAPCard ap_card; + virNodeDevCapAPQueue ap_queue; }; };
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 8d3e5a43..0fd44f6f 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -712,6 +712,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index c513b4cc..16a73db2 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1168,6 +1168,29 @@ udevProcessAPCard(struct udev_device *device, }
+static int +udevProcessAPQueue(struct udev_device *device, + virNodeDeviceDefPtr def) +{ + char *c; + virNodeDevCapDataPtr data = &def->caps->data; + + if ((c = strrchr(def->sysfs_path, '/')) == NULL || + virStrToLong_ui(c + 1, &c, 16, &data->ap_queue.ap_adapter) < 0 || + virStrToLong_ui(c + 1, &c, 16, &data->ap_queue.ap_domain) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse the AP Queue from sysfs path: '%s'"), + def->sysfs_path); + return -1; + } + + if (udevGenerateDeviceName(device, def, NULL) != 0) + return -1; + + return 0; +} + + static int udevGetDeviceNodes(struct udev_device *device, virNodeDeviceDefPtr def) @@ -1224,6 +1247,8 @@ udevGetDeviceType(struct udev_device *device, *type = VIR_NODE_DEV_CAP_DRM; else if (STREQ(devtype, "ap_card")) *type = VIR_NODE_DEV_CAP_AP_CARD; + else if (STREQ(devtype, "ap_queue")) + *type = VIR_NODE_DEV_CAP_AP_QUEUE; } else { /* PCI devices don't set the DEVTYPE property. */ if (udevHasDeviceProperty(device, "PCI_CLASS")) @@ -1297,6 +1322,8 @@ udevGetDeviceDetails(struct udev_device *device, return udevProcessCSS(device, def); case VIR_NODE_DEV_CAP_AP_CARD: return udevProcessAPCard(device, def); + case VIR_NODE_DEV_CAP_AP_QUEUE: + return udevProcessAPQueue(device, def); case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_FC_HOST: diff --git a/tests/nodedevschemadata/ap_07_0038.xml b/tests/nodedevschemadata/ap_07_0038.xml new file mode 100644 index 00000000..553c68f2 --- /dev/null +++ b/tests/nodedevschemadata/ap_07_0038.xml @@ -0,0 +1,9 @@ +<device> + <name>ap_07_0038</name> + <path>/sys/devices/ap/card07/07.0038</path> + <parent>ap_card07</parent> + <capability type='ap_queue'> + <ap-adapter>0x07</ap-adapter> + <ap-domain>0x0038</ap-domain> + </capability> +</device> diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index 7990f6cd..d6ab25bf 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -125,6 +125,7 @@ mymain(void) DO_TEST("ccw_0_0_ffff"); DO_TEST("css_0_0_ffff"); DO_TEST("ap_card07"); + DO_TEST("ap_07_0038");
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 98268916..f79e0b78 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -465,6 +465,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV; break; case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: break; }
-- Mit freundlichen Grüßen/Kind regards Boris Fiuczynski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Gregor Pillen Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

Same thing I mentioned in patch 01 (split the docs, conf and logic in separated patches) applies to this patch and patch 04. Thanks, DHB On 10/21/20 7:59 AM, Shalini Chellathurai Saroja wrote:
From: Farhan Ali <alifm@linux.ibm.com>
Each AP Card device can support upto 256 AP Queues. AP Queues are also detected by udev, so add support for libvirt nodedev driver.
Signed-off-by: Farhan Ali <alifm@linux.ibm.com> Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/formatnode.html.in | 11 +++++ docs/schemas/nodedev.rng | 25 +++++++++++ src/conf/node_device_conf.c | 59 ++++++++++++++++++++++++++ src/conf/node_device_conf.h | 9 ++++ src/conf/virnodedeviceobj.c | 1 + src/node_device/node_device_udev.c | 27 ++++++++++++ tests/nodedevschemadata/ap_07_0038.xml | 9 ++++ tests/nodedevxml2xmltest.c | 1 + tools/virsh-nodedev.c | 1 + 9 files changed, 143 insertions(+) create mode 100644 tests/nodedevschemadata/ap_07_0038.xml
diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in index 300ddf21..16f68f38 100644 --- a/docs/formatnode.html.in +++ b/docs/formatnode.html.in @@ -439,6 +439,17 @@ <dd>AP Card identifier.</dd> </dl> </dd> + <dt><code>ap_queue</code></dt> + <dd>Describes the AP Queue on a S390 host. An AP Queue is + identified by it's ap-adapter and ap-domain id. Sub-elements include: + <dl> + <dt><code>ap-adapter</code></dt> + <dd>The ap-adapter of an AP Queue identifies AP Card to which + this queue belongs.</dd> + <dt><code>ap-domain</code></dt> + <dd>AP Queue identifier.</dd> + </dl> + </dd> </dl> </dd> </dl> diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index 06ccb9c8..5f812c8f 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -87,6 +87,7 @@ <ref name="capccwdev"/> <ref name="capcssdev"/> <ref name="capapcard"/> + <ref name="capapqueue"/> </choice> </element> </define> @@ -685,6 +686,18 @@ </element> </define>
+ <define name='capapqueue'> + <attribute name='type'> + <value>ap_queue</value> + </attribute> + <element name='ap-adapter'> + <ref name='apAdapterRange'/> + </element> + <element name='ap-domain'> + <ref name='apDomainRange'/> + </element> + </define> + <define name='address'> <element name='address'> <attribute name='domain'><ref name='hexuint'/></attribute> @@ -718,4 +731,16 @@ </choice> </define>
+ <define name="apDomainRange"> + <choice> + <data type="string"> + <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param> + </data> + <data type="int"> + <param name="minInclusive">0</param> + <param name="maxInclusive">255</param> + </data> + </choice> + </define> + </grammar> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 88c00b5b..d27b0c71 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -67,6 +67,7 @@ VIR_ENUM_IMPL(virNodeDevCap, "ccw", "css", "ap_card", + "ap_queue", );
VIR_ENUM_IMPL(virNodeDevNetCap, @@ -616,6 +617,12 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) virBufferAsprintf(&buf, "<ap-adapter>0x%02x</ap-adapter>\n", data->ap_card.ap_adapter); break; + case VIR_NODE_DEV_CAP_AP_QUEUE: + virBufferAsprintf(&buf, "<ap-adapter>0x%02x</ap-adapter>\n", + data->ap_queue.ap_adapter); + virBufferAsprintf(&buf, "<ap-domain>0x%04x</ap-domain>\n", + data->ap_queue.ap_domain); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -839,6 +846,52 @@ virNodeDevCapAPCardParseXML(xmlXPathContextPtr ctxt, }
+static int +virNodeDevCapAPQueueParseXML(xmlXPathContextPtr ctxt, + virNodeDeviceDefPtr def, + xmlNodePtr node, + virNodeDevCapAPQueuePtr ap_queue) +{ + xmlNodePtr orig; + int ret = -1; + g_autofree char *adapter = NULL, *dom = NULL; + + orig = ctxt->node; + ctxt->node = node; + + if (!(adapter = virXPathString("string(./ap-adapter[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ap-adapter value for '%s'"), def->name); + return -1; + } + + if (virStrToLong_uip(adapter, NULL, 0, &ap_queue->ap_adapter) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-adapter value '%s' for '%s'"), + adapter, def->name); + goto out; + } + + if (!(dom = virXPathString("string(./ap-domain[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ap-domain value for '%s'"), def->name); + goto out; + } + + if (virStrToLong_uip(dom, NULL, 0, &ap_queue->ap_domain) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-domain value '%s' for '%s'"), + dom, def->name); + goto out; + } + + ret = 0; + out: + ctxt->node = orig; + return ret; +} + + static int virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, @@ -1938,6 +1991,10 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, ret = virNodeDevCapAPCardParseXML(ctxt, def, node, &caps->data.ap_card); break; + case VIR_NODE_DEV_CAP_AP_QUEUE: + ret = virNodeDevCapAPQueueParseXML(ctxt, def, node, + &caps->data.ap_queue); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2260,6 +2317,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: /* This case is here to shutup the compiler */ break; @@ -2315,6 +2373,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index aa2dac43..c8100c8b 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -66,6 +66,7 @@ typedef enum { VIR_NODE_DEV_CAP_CCW_DEV, /* s390 CCW device */ VIR_NODE_DEV_CAP_CSS_DEV, /* s390 channel subsystem device */ VIR_NODE_DEV_CAP_AP_CARD, /* s390 AP Card device */ + VIR_NODE_DEV_CAP_AP_QUEUE, /* s390 AP Queue */
VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -282,6 +283,13 @@ struct _virNodeDevCapAPCard { unsigned int ap_adapter; };
+typedef struct _virNodeDevCapAPQueue virNodeDevCapAPQueue; +typedef virNodeDevCapAPQueue *virNodeDevCapAPQueuePtr; +struct _virNodeDevCapAPQueue { + unsigned int ap_adapter; + unsigned int ap_domain; +}; + typedef struct _virNodeDevCapData virNodeDevCapData; typedef virNodeDevCapData *virNodeDevCapDataPtr; struct _virNodeDevCapData { @@ -301,6 +309,7 @@ struct _virNodeDevCapData { virNodeDevCapMdev mdev; virNodeDevCapCCW ccw_dev; virNodeDevCapAPCard ap_card; + virNodeDevCapAPQueue ap_queue; }; };
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 8d3e5a43..0fd44f6f 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -712,6 +712,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index c513b4cc..16a73db2 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1168,6 +1168,29 @@ udevProcessAPCard(struct udev_device *device, }
+static int +udevProcessAPQueue(struct udev_device *device, + virNodeDeviceDefPtr def) +{ + char *c; + virNodeDevCapDataPtr data = &def->caps->data; + + if ((c = strrchr(def->sysfs_path, '/')) == NULL || + virStrToLong_ui(c + 1, &c, 16, &data->ap_queue.ap_adapter) < 0 || + virStrToLong_ui(c + 1, &c, 16, &data->ap_queue.ap_domain) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse the AP Queue from sysfs path: '%s'"), + def->sysfs_path); + return -1; + } + + if (udevGenerateDeviceName(device, def, NULL) != 0) + return -1; + + return 0; +} + + static int udevGetDeviceNodes(struct udev_device *device, virNodeDeviceDefPtr def) @@ -1224,6 +1247,8 @@ udevGetDeviceType(struct udev_device *device, *type = VIR_NODE_DEV_CAP_DRM; else if (STREQ(devtype, "ap_card")) *type = VIR_NODE_DEV_CAP_AP_CARD; + else if (STREQ(devtype, "ap_queue")) + *type = VIR_NODE_DEV_CAP_AP_QUEUE; } else { /* PCI devices don't set the DEVTYPE property. */ if (udevHasDeviceProperty(device, "PCI_CLASS")) @@ -1297,6 +1322,8 @@ udevGetDeviceDetails(struct udev_device *device, return udevProcessCSS(device, def); case VIR_NODE_DEV_CAP_AP_CARD: return udevProcessAPCard(device, def); + case VIR_NODE_DEV_CAP_AP_QUEUE: + return udevProcessAPQueue(device, def); case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_FC_HOST: diff --git a/tests/nodedevschemadata/ap_07_0038.xml b/tests/nodedevschemadata/ap_07_0038.xml new file mode 100644 index 00000000..553c68f2 --- /dev/null +++ b/tests/nodedevschemadata/ap_07_0038.xml @@ -0,0 +1,9 @@ +<device> + <name>ap_07_0038</name> + <path>/sys/devices/ap/card07/07.0038</path> + <parent>ap_card07</parent> + <capability type='ap_queue'> + <ap-adapter>0x07</ap-adapter> + <ap-domain>0x0038</ap-domain> + </capability> +</device> diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index 7990f6cd..d6ab25bf 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -125,6 +125,7 @@ mymain(void) DO_TEST("ccw_0_0_ffff"); DO_TEST("css_0_0_ffff"); DO_TEST("ap_card07"); + DO_TEST("ap_07_0038");
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 98268916..f79e0b78 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -465,6 +465,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV; break; case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_LAST: break; }

From: Farhan Ali <alifm@linux.ibm.com> Add support to filter by 'ap_card' and 'ap_queue' capabilities. Signed-off-by: Farhan Ali <alifm@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> --- docs/manpages/virsh.rst | 2 +- include/libvirt/libvirt-nodedev.h | 2 ++ src/conf/node_device_conf.h | 4 +++- src/conf/virnodedeviceobj.c | 4 +++- src/libvirt-nodedev.c | 2 ++ tools/virsh-nodedev.c | 4 ++++ 6 files changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index d34a1c86..e4110c45 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -4970,7 +4970,7 @@ List all of the devices available on the node that are known by libvirt. separated by comma, e.g. --cap pci,scsi. Valid capability types include 'system', 'pci', 'usb_device', 'usb', 'net', 'scsi_host', 'scsi_target', 'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev', -'mdev_types', 'ccw', 'css'. +'mdev_types', 'ccw', 'css', 'ap_card', 'ap_queue'. If *--tree* is used, the output is formatted in a tree representing parents of each node. *cap* and *--tree* are mutually exclusive. diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h index dd2ffd57..789f9c86 100644 --- a/include/libvirt/libvirt-nodedev.h +++ b/include/libvirt/libvirt-nodedev.h @@ -82,6 +82,8 @@ typedef enum { VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV = 1 << 14, /* Mediated device */ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV = 1 << 15, /* CCW device */ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV = 1 << 16, /* CSS device */ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_CARD = 1 << 17, /* s390 AP Card device */ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE = 1 << 18, /* s390 AP Queue */ } virConnectListAllNodeDeviceFlags; int virConnectListAllNodeDevices (virConnectPtr conn, diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index c8100c8b..d732efaa 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -386,7 +386,9 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps); VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES | \ VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV | \ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV | \ - VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV) + VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV | \ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_CARD | \ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE) int virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host); diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 0fd44f6f..0ce230db 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -864,7 +864,9 @@ virNodeDeviceObjMatch(virNodeDeviceObjPtr obj, MATCH(MDEV_TYPES) || MATCH(MDEV) || MATCH(CCW_DEV) || - MATCH(CSS_DEV))) + MATCH(CSS_DEV) || + MATCH(AP_CARD) || + MATCH(AP_QUEUE))) return false; } diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c index 28765b9c..762413eb 100644 --- a/src/libvirt-nodedev.c +++ b/src/libvirt-nodedev.c @@ -102,6 +102,8 @@ virNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags) * VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV * VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV * VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_CARD + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE * * Returns the number of node devices found or -1 and sets @devices to NULL in * case of error. On success, the array stored into @devices is guaranteed to diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index f79e0b78..3862d8f3 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -465,7 +465,11 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV; break; case VIR_NODE_DEV_CAP_AP_CARD: + flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_CARD; + break; case VIR_NODE_DEV_CAP_AP_QUEUE: + flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE; + break; case VIR_NODE_DEV_CAP_LAST: break; } -- 2.26.2

Add support for AP matrix device in libvirt nodedev driver. Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/schemas/nodedev.rng | 7 ++++++ src/conf/node_device_conf.c | 10 +++++++- src/conf/node_device_conf.h | 8 +++++++ src/conf/virnodedeviceobj.c | 1 + src/node_device/node_device_udev.c | 23 +++++++++++++++++++ tests/nodedevschemadata/ap_matrix.xml | 7 ++++++ ...v_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml | 9 ++++++++ tests/nodedevxml2xmltest.c | 2 ++ tools/virsh-nodedev.c | 1 + 9 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/nodedevschemadata/ap_matrix.xml create mode 100644 tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index 5f812c8f..7c017ff1 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -88,6 +88,7 @@ <ref name="capcssdev"/> <ref name="capapcard"/> <ref name="capapqueue"/> + <ref name="capapmatrix"/> </choice> </element> </define> @@ -698,6 +699,12 @@ </element> </define> + <define name='capapmatrix'> + <attribute name='type'> + <value>ap_matrix</value> + </attribute> + </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 d27b0c71..33c9a020 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -68,6 +68,7 @@ VIR_ENUM_IMPL(virNodeDevCap, "css", "ap_card", "ap_queue", + "ap_matrix", ); VIR_ENUM_IMPL(virNodeDevNetCap, @@ -626,6 +627,7 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: + case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_LAST: break; } @@ -1995,6 +1997,9 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, ret = virNodeDevCapAPQueueParseXML(ctxt, def, node, &caps->data.ap_queue); break; + case VIR_NODE_DEV_CAP_AP_MATRIX: + ret = 0; + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2310,6 +2315,9 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) virMediatedDeviceAttrFree(data->mdev.attributes[i]); VIR_FREE(data->mdev.attributes); break; + case VIR_NODE_DEV_CAP_AP_MATRIX: + VIR_FREE(data->ap_matrix.addr); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_DRM: case VIR_NODE_DEV_CAP_FC_HOST: @@ -2374,6 +2382,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_AP_QUEUE: + case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_LAST: break; } @@ -2722,7 +2731,6 @@ virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath G_GNUC_UNUSED, return -1; } - int virNodeDeviceGetSCSITargetCaps(const char *sysfsPath G_GNUC_UNUSED, virNodeDevCapSCSITargetPtr scsi_target G_GNUC_UNUSED) { diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index d732efaa..f1e57ad7 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -67,6 +67,7 @@ typedef enum { VIR_NODE_DEV_CAP_CSS_DEV, /* s390 channel subsystem device */ VIR_NODE_DEV_CAP_AP_CARD, /* s390 AP Card device */ VIR_NODE_DEV_CAP_AP_QUEUE, /* s390 AP Queue */ + VIR_NODE_DEV_CAP_AP_MATRIX, /* s390 AP Matrix device */ VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -290,6 +291,12 @@ struct _virNodeDevCapAPQueue { unsigned int ap_domain; }; +typedef struct _virNodeDevCapAPMatrix virNodeDevCapAPMatrix; +typedef virNodeDevCapAPMatrix *virNodeDevCapAPMatrixPtr; +struct _virNodeDevCapAPMatrix { + char *addr; +}; + typedef struct _virNodeDevCapData virNodeDevCapData; typedef virNodeDevCapData *virNodeDevCapDataPtr; struct _virNodeDevCapData { @@ -310,6 +317,7 @@ struct _virNodeDevCapData { virNodeDevCapCCW ccw_dev; virNodeDevCapAPCard ap_card; virNodeDevCapAPQueue ap_queue; + virNodeDevCapAPMatrix ap_matrix; }; }; diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 0ce230db..a19017b8 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -713,6 +713,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_AP_QUEUE: + case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 16a73db2..ea983726 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1191,6 +1191,25 @@ udevProcessAPQueue(struct udev_device *device, } +static int +udevProcessAPMatrix(struct udev_device *device, + virNodeDeviceDefPtr def) +{ + size_t i; + virNodeDevCapDataPtr data = &def->caps->data; + + data->ap_matrix.addr = g_strdup(udev_device_get_sysname(device)); + def->name = g_strdup_printf("ap_%s", data->ap_matrix.addr); + + for (i = 0; i < strlen(def->name); i++) { + if (!(g_ascii_isalnum(*(def->name + i)))) + *(def->name + i) = '_'; + } + + return 0; +} + + static int udevGetDeviceNodes(struct udev_device *device, virNodeDeviceDefPtr def) @@ -1274,6 +1293,8 @@ udevGetDeviceType(struct udev_device *device, *type = VIR_NODE_DEV_CAP_CCW_DEV; else if (STREQ_NULLABLE(subsystem, "css")) *type = VIR_NODE_DEV_CAP_CSS_DEV; + else if (STREQ_NULLABLE(subsystem, "matrix")) + *type = VIR_NODE_DEV_CAP_AP_MATRIX; VIR_FREE(subsystem); } @@ -1324,6 +1345,8 @@ udevGetDeviceDetails(struct udev_device *device, return udevProcessAPCard(device, def); case VIR_NODE_DEV_CAP_AP_QUEUE: return udevProcessAPQueue(device, def); + case VIR_NODE_DEV_CAP_AP_MATRIX: + return udevProcessAPMatrix(device, def); case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_FC_HOST: diff --git a/tests/nodedevschemadata/ap_matrix.xml b/tests/nodedevschemadata/ap_matrix.xml new file mode 100644 index 00000000..30dab9cf --- /dev/null +++ b/tests/nodedevschemadata/ap_matrix.xml @@ -0,0 +1,7 @@ +<device> + <name>ap_matrix</name> + <path>/sys/devices/vfio_ap/matrix</path> + <parent>computer</parent> + <capability type='ap_matrix'> + </capability> +</device> diff --git a/tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml b/tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml new file mode 100644 index 00000000..106f7593 --- /dev/null +++ b/tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml @@ -0,0 +1,9 @@ +<device> + <name>mdev_ee0b88c4-f554-4dc1-809d-b2a01e8e48ad</name> + <path>/sys/devices/vfio_ap/matrix/mdev_ee0b88c4-f554-4dc1-809d-b2a01e8e48ad</path> + <parent>ap_matrix</parent> + <capability type='mdev'> + <type id='vfio_ap-passthrough'/> + <iommuGroup number='0'/> + </capability> +</device> diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index d6ab25bf..69d72ff0 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -126,6 +126,8 @@ mymain(void) DO_TEST("css_0_0_ffff"); DO_TEST("ap_card07"); DO_TEST("ap_07_0038"); + DO_TEST("ap_matrix"); + DO_TEST("mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad"); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 3862d8f3..d39d87c7 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -470,6 +470,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) case VIR_NODE_DEV_CAP_AP_QUEUE: flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE; break; + case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_LAST: break; } -- 2.26.2

On 10/21/20 12:59 PM, Shalini Chellathurai Saroja wrote:
Add support for AP matrix device in libvirt nodedev driver.
Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/schemas/nodedev.rng | 7 ++++++ src/conf/node_device_conf.c | 10 +++++++- src/conf/node_device_conf.h | 8 +++++++ src/conf/virnodedeviceobj.c | 1 + src/node_device/node_device_udev.c | 23 +++++++++++++++++++ tests/nodedevschemadata/ap_matrix.xml | 7 ++++++ ...v_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml | 9 ++++++++ tests/nodedevxml2xmltest.c | 2 ++ tools/virsh-nodedev.c | 1 + 9 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/nodedevschemadata/ap_matrix.xml create mode 100644 tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml
diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index 5f812c8f..7c017ff1 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -88,6 +88,7 @@ <ref name="capcssdev"/> <ref name="capapcard"/> <ref name="capapqueue"/> + <ref name="capapmatrix"/> </choice> </element> </define> @@ -698,6 +699,12 @@ </element> </define>
+ <define name='capapmatrix'> + <attribute name='type'> + <value>ap_matrix</value> + </attribute> + </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 d27b0c71..33c9a020 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -68,6 +68,7 @@ VIR_ENUM_IMPL(virNodeDevCap, "css", "ap_card", "ap_queue", + "ap_matrix", );
VIR_ENUM_IMPL(virNodeDevNetCap, @@ -626,6 +627,7 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: + case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_LAST: break; } @@ -1995,6 +1997,9 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, ret = virNodeDevCapAPQueueParseXML(ctxt, def, node, &caps->data.ap_queue); break; + case VIR_NODE_DEV_CAP_AP_MATRIX: + ret = 0; + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2310,6 +2315,9 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) virMediatedDeviceAttrFree(data->mdev.attributes[i]); VIR_FREE(data->mdev.attributes); break; + case VIR_NODE_DEV_CAP_AP_MATRIX: + VIR_FREE(data->ap_matrix.addr); + break; case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_DRM: case VIR_NODE_DEV_CAP_FC_HOST: @@ -2374,6 +2382,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_AP_QUEUE: + case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_LAST: break; } @@ -2722,7 +2731,6 @@ virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath G_GNUC_UNUSED, return -1; }
-
This change is irrelevant. Please remove it.
int virNodeDeviceGetSCSITargetCaps(const char *sysfsPath G_GNUC_UNUSED, virNodeDevCapSCSITargetPtr scsi_target G_GNUC_UNUSED) { diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index d732efaa..f1e57ad7 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -67,6 +67,7 @@ typedef enum { VIR_NODE_DEV_CAP_CSS_DEV, /* s390 channel subsystem device */ VIR_NODE_DEV_CAP_AP_CARD, /* s390 AP Card device */ VIR_NODE_DEV_CAP_AP_QUEUE, /* s390 AP Queue */ + VIR_NODE_DEV_CAP_AP_MATRIX, /* s390 AP Matrix device */
VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -290,6 +291,12 @@ struct _virNodeDevCapAPQueue { unsigned int ap_domain; };
+typedef struct _virNodeDevCapAPMatrix virNodeDevCapAPMatrix; +typedef virNodeDevCapAPMatrix *virNodeDevCapAPMatrixPtr; +struct _virNodeDevCapAPMatrix { + char *addr; +}; + typedef struct _virNodeDevCapData virNodeDevCapData; typedef virNodeDevCapData *virNodeDevCapDataPtr; struct _virNodeDevCapData { @@ -310,6 +317,7 @@ struct _virNodeDevCapData { virNodeDevCapCCW ccw_dev; virNodeDevCapAPCard ap_card; virNodeDevCapAPQueue ap_queue; + virNodeDevCapAPMatrix ap_matrix; }; };
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 0ce230db..a19017b8 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -713,6 +713,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_CSS_DEV: case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_AP_QUEUE: + case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 16a73db2..ea983726 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1191,6 +1191,25 @@ udevProcessAPQueue(struct udev_device *device, }
+static int +udevProcessAPMatrix(struct udev_device *device, + virNodeDeviceDefPtr def) +{ + size_t i; + virNodeDevCapDataPtr data = &def->caps->data; + + data->ap_matrix.addr = g_strdup(udev_device_get_sysname(device)); + def->name = g_strdup_printf("ap_%s", data->ap_matrix.addr); + + for (i = 0; i < strlen(def->name); i++) { + if (!(g_ascii_isalnum(*(def->name + i)))) + *(def->name + i) = '_'; + } + + return 0; +} + + static int udevGetDeviceNodes(struct udev_device *device, virNodeDeviceDefPtr def) @@ -1274,6 +1293,8 @@ udevGetDeviceType(struct udev_device *device, *type = VIR_NODE_DEV_CAP_CCW_DEV; else if (STREQ_NULLABLE(subsystem, "css")) *type = VIR_NODE_DEV_CAP_CSS_DEV; + else if (STREQ_NULLABLE(subsystem, "matrix")) + *type = VIR_NODE_DEV_CAP_AP_MATRIX;
VIR_FREE(subsystem); } @@ -1324,6 +1345,8 @@ udevGetDeviceDetails(struct udev_device *device, return udevProcessAPCard(device, def); case VIR_NODE_DEV_CAP_AP_QUEUE: return udevProcessAPQueue(device, def); + case VIR_NODE_DEV_CAP_AP_MATRIX: + return udevProcessAPMatrix(device, def); case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_FC_HOST: diff --git a/tests/nodedevschemadata/ap_matrix.xml b/tests/nodedevschemadata/ap_matrix.xml new file mode 100644 index 00000000..30dab9cf --- /dev/null +++ b/tests/nodedevschemadata/ap_matrix.xml @@ -0,0 +1,7 @@ +<device> + <name>ap_matrix</name> + <path>/sys/devices/vfio_ap/matrix</path> + <parent>computer</parent> + <capability type='ap_matrix'> + </capability> +</device> diff --git a/tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml b/tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml new file mode 100644 index 00000000..106f7593 --- /dev/null +++ b/tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml @@ -0,0 +1,9 @@ +<device> + <name>mdev_ee0b88c4-f554-4dc1-809d-b2a01e8e48ad</name> + <path>/sys/devices/vfio_ap/matrix/mdev_ee0b88c4-f554-4dc1-809d-b2a01e8e48ad</path> + <parent>ap_matrix</parent> + <capability type='mdev'> + <type id='vfio_ap-passthrough'/> + <iommuGroup number='0'/> + </capability> +</device> diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index d6ab25bf..69d72ff0 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -126,6 +126,8 @@ mymain(void) DO_TEST("css_0_0_ffff"); DO_TEST("ap_card07"); DO_TEST("ap_07_0038"); + DO_TEST("ap_matrix"); + DO_TEST("mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad");
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 3862d8f3..d39d87c7 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -470,6 +470,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) case VIR_NODE_DEV_CAP_AP_QUEUE: flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE; break; + case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_LAST: break; }
-- Mit freundlichen Grüßen/Kind regards Boris Fiuczynski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Gregor Pillen Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

Add support to filter by 'ap_matrix' capability. Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/formatnode.html.in | 3 +++ docs/manpages/virsh.rst | 2 +- include/libvirt/libvirt-nodedev.h | 1 + src/conf/node_device_conf.h | 3 ++- src/conf/virnodedeviceobj.c | 3 ++- src/libvirt-nodedev.c | 1 + tools/virsh-nodedev.c | 2 ++ 7 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in index 16f68f38..db621bcf 100644 --- a/docs/formatnode.html.in +++ b/docs/formatnode.html.in @@ -450,6 +450,9 @@ <dd>AP Queue identifier.</dd> </dl> </dd> + <dt><code>ap_matrix</code></dt> + <dd>Describes an AP Matrix device on a S390 architecture providing + cryptographic host resources usable for virtualization.</dd> </dl> </dd> </dl> diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index e4110c45..ff7e8812 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -4970,7 +4970,7 @@ List all of the devices available on the node that are known by libvirt. separated by comma, e.g. --cap pci,scsi. Valid capability types include 'system', 'pci', 'usb_device', 'usb', 'net', 'scsi_host', 'scsi_target', 'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev', -'mdev_types', 'ccw', 'css', 'ap_card', 'ap_queue'. +'mdev_types', 'ccw', 'css', 'ap_card', 'ap_queue', 'ap_matrix'. If *--tree* is used, the output is formatted in a tree representing parents of each node. *cap* and *--tree* are mutually exclusive. diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h index 789f9c86..0d7f33e0 100644 --- a/include/libvirt/libvirt-nodedev.h +++ b/include/libvirt/libvirt-nodedev.h @@ -84,6 +84,7 @@ typedef enum { VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV = 1 << 16, /* CSS device */ VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_CARD = 1 << 17, /* s390 AP Card device */ VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE = 1 << 18, /* s390 AP Queue */ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX = 1 << 19, /* s390 AP Matrix */ } virConnectListAllNodeDeviceFlags; int virConnectListAllNodeDevices (virConnectPtr conn, diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index f1e57ad7..6daef571 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -396,7 +396,8 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps); VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV | \ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV | \ VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_CARD | \ - VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE) + VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE | \ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX) int virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host); diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index a19017b8..33dab6da 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -867,7 +867,8 @@ virNodeDeviceObjMatch(virNodeDeviceObjPtr obj, MATCH(CCW_DEV) || MATCH(CSS_DEV) || MATCH(AP_CARD) || - MATCH(AP_QUEUE))) + MATCH(AP_QUEUE) || + MATCH(AP_MATRIX))) return false; } diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c index 762413eb..eb8c735a 100644 --- a/src/libvirt-nodedev.c +++ b/src/libvirt-nodedev.c @@ -104,6 +104,7 @@ virNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags) * VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV * VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_CARD * VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX * * Returns the number of node devices found or -1 and sets @devices to NULL in * case of error. On success, the array stored into @devices is guaranteed to diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index d39d87c7..d5a8514e 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -471,6 +471,8 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE; break; case VIR_NODE_DEV_CAP_AP_MATRIX: + flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX; + break; case VIR_NODE_DEV_CAP_LAST: break; } -- 2.26.2

Use switch statements instead of if-else condition in the method nodeDeviceFindAddressByName to retrieve address of a node device. Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/node_device/node_device_driver.c | 29 ++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index f5ea973c..d77b47c6 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -638,7 +638,8 @@ nodeDeviceFindAddressByName(const char *name) def = virNodeDeviceObjGetDef(dev); for (caps = def->caps; caps != NULL; caps = caps->next) { - if (caps->data.type == VIR_NODE_DEV_CAP_PCI_DEV) { + switch (caps->data.type) { + case VIR_NODE_DEV_CAP_PCI_DEV: { virPCIDeviceAddress pci_addr = { .domain = caps->data.pci_dev.domain, .bus = caps->data.pci_dev.bus, @@ -648,7 +649,9 @@ nodeDeviceFindAddressByName(const char *name) addr = virPCIDeviceAddressAsString(&pci_addr); break; - } else if (caps->data.type == VIR_NODE_DEV_CAP_CSS_DEV) { + } + + case VIR_NODE_DEV_CAP_CSS_DEV: { virDomainDeviceCCWAddress ccw_addr = { .cssid = caps->data.ccw_dev.cssid, .ssid = caps->data.ccw_dev.ssid, @@ -657,6 +660,28 @@ nodeDeviceFindAddressByName(const char *name) addr = virDomainCCWAddressAsString(&ccw_addr); break; + } + + case VIR_NODE_DEV_CAP_SYSTEM: + case VIR_NODE_DEV_CAP_USB_DEV: + case VIR_NODE_DEV_CAP_USB_INTERFACE: + case VIR_NODE_DEV_CAP_NET: + case VIR_NODE_DEV_CAP_SCSI_HOST: + case VIR_NODE_DEV_CAP_SCSI_TARGET: + case VIR_NODE_DEV_CAP_SCSI: + case VIR_NODE_DEV_CAP_STORAGE: + case VIR_NODE_DEV_CAP_FC_HOST: + case VIR_NODE_DEV_CAP_VPORTS: + case VIR_NODE_DEV_CAP_SCSI_GENERIC: + case VIR_NODE_DEV_CAP_DRM: + case VIR_NODE_DEV_CAP_MDEV_TYPES: + case VIR_NODE_DEV_CAP_MDEV: + case VIR_NODE_DEV_CAP_CCW_DEV: + case VIR_NODE_DEV_CAP_AP_CARD: + case VIR_NODE_DEV_CAP_AP_QUEUE: + case VIR_NODE_DEV_CAP_AP_MATRIX: + case VIR_NODE_DEV_CAP_LAST: + break; } } -- 2.26.2

Allow mdev devices to be created on the matrix device. Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/node_device/node_device_driver.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index d77b47c6..11d50bf6 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -662,6 +662,10 @@ nodeDeviceFindAddressByName(const char *name) break; } + case VIR_NODE_DEV_CAP_AP_MATRIX: + addr = g_strdup(caps->data.ap_matrix.addr); + break; + case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_USB_DEV: case VIR_NODE_DEV_CAP_USB_INTERFACE: @@ -679,7 +683,6 @@ nodeDeviceFindAddressByName(const char *name) case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_AP_QUEUE: - case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_LAST: break; } -- 2.26.2

Ping:-) On 10/21/20 12:59 PM, Shalini Chellathurai Saroja wrote:
Add support for AP card devices, AP queues and AP matrix devices in libvirt node device driver.
Farhan Ali (3): nodedev: Detect AP Card device nodedev: Detect AP Queues virsh: nodedev: Filter by AP Card and AP Queue capabilities
Shalini Chellathurai Saroja (4): nodedev: detect AP Matrix device virsh: nodedev: filter by AP Matrix capability node_device: refactor address retrieval of node device node_device: mdev matrix support
docs/formatnode.html.in | 21 ++++ docs/manpages/virsh.rst | 2 +- docs/schemas/nodedev.rng | 66 ++++++++++- include/libvirt/libvirt-nodedev.h | 3 + src/conf/node_device_conf.c | 111 +++++++++++++++++- src/conf/node_device_conf.h | 30 ++++- src/conf/virnodedeviceobj.c | 8 +- src/libvirt-nodedev.c | 3 + src/node_device/node_device_driver.c | 32 ++++- src/node_device/node_device_udev.c | 80 +++++++++++++ tests/nodedevschemadata/ap_07_0038.xml | 9 ++ tests/nodedevschemadata/ap_card07.xml | 8 ++ tests/nodedevschemadata/ap_matrix.xml | 7 ++ ...v_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml | 9 ++ tests/nodedevxml2xmltest.c | 4 + tools/virsh-nodedev.c | 9 ++ 16 files changed, 390 insertions(+), 12 deletions(-) create mode 100644 tests/nodedevschemadata/ap_07_0038.xml create mode 100644 tests/nodedevschemadata/ap_card07.xml create mode 100644 tests/nodedevschemadata/ap_matrix.xml create mode 100644 tests/nodedevschemadata/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad.xml
participants (3)
-
Boris Fiuczynski
-
Daniel Henrique Barboza
-
Shalini Chellathurai Saroja