From: Farhan Ali <alifm@xxxxxxxxxxxxx> 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@xxxxxxxxxxxxx> Signed-off-by: Shalini Chellathurai Saroja <shalini@xxxxxxxxxxxxx> Reviewed-by: Bjoern Walk <bwalk@xxxxxxxxxxxxx> Reviewed-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxx> --- 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