From: Shalini Chellathurai Saroja Date: Thu, 3 Dec 2020 17:59:33 +0000 (+0100) Subject: nodedev: detect AP card device X-Git-Tag: v7.0.0-rc1~242 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a2b8988951b814a7ed3858304d7157bae0afa12;p=thirdparty%2Flibvirt.git nodedev: detect AP card device Introduce support for the Adjunct Processor (AP) crypto card device. Udev already detects the device, so add support for libvirt nodedev driver. https://www.kernel.org/doc/html/latest/s390/vfio-ap.html#ap-architectural-overview Signed-off-by: Farhan Ali Signed-off-by: Shalini Chellathurai Saroja Reviewed-by: Bjoern Walk Reviewed-by: Boris Fiuczynski Reviewed-by: Erik Skultety --- diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in index c7df69c901..d10a79e37d 100644 --- a/docs/formatnode.html.in +++ b/docs/formatnode.html.in @@ -431,6 +431,14 @@ device. +
ap_card
+
Describes the Adjunct Processor (AP) Card device on a S390 host. + Sub-elements include: +
+
ap-adapter
+
AP Card identifier.
+
+
diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index b3e986659e..d2f9dac6d9 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -87,6 +87,7 @@ + @@ -668,6 +669,15 @@ + + + ap_card + + + + + + diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index cac4243b50..5df0b25df7 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", "vdpa", + "ap_card", ); VIR_ENUM_IMPL(virNodeDevNetCap, @@ -650,6 +651,10 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) case VIR_NODE_DEV_CAP_VDPA: virNodeDeviceCapVDPADefFormat(&buf, data); break; + case VIR_NODE_DEV_CAP_AP_CARD: + virBufferAsprintf(&buf, "0x%02x\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: @@ -941,6 +946,43 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, } +static int +virNodeDevCapAPAdapterParseXML(xmlXPathContextPtr ctxt, + virNodeDeviceDefPtr def, + unsigned int *ap_adapter) +{ + g_autofree char *adapter = NULL; + + 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_adapter) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ap-adapter value '%s' for '%s'"), + adapter, def->name); + return -1; + } + + return 0; +} + + +static int +virNodeDevCapAPCardParseXML(xmlXPathContextPtr ctxt, + virNodeDeviceDefPtr def, + xmlNodePtr node, + virNodeDevCapAPCardPtr ap_card) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt) + ctxt->node = node; + + return virNodeDevCapAPAdapterParseXML(ctxt, def, &ap_card->ap_adapter); +} + + static int virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, @@ -1979,6 +2021,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: @@ -2306,6 +2352,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_VDPA: + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: /* This case is here to shutup the compiler */ break; @@ -2365,6 +2412,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) case VIR_NODE_DEV_CAP_MDEV: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_VDPA: + 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 262524fc87..f86f880c40 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_VDPA, /* vDPA device */ + VIR_NODE_DEV_CAP_AP_CARD, /* s390 AP Card device */ VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -289,6 +290,12 @@ struct _virNodeDevCapVDPA { char *chardev; }; +typedef struct _virNodeDevCapAPCard virNodeDevCapAPCard; +typedef virNodeDevCapAPCard *virNodeDevCapAPCardPtr; +struct _virNodeDevCapAPCard { + unsigned int ap_adapter; +}; + typedef struct _virNodeDevCapData virNodeDevCapData; typedef virNodeDevCapData *virNodeDevCapDataPtr; struct _virNodeDevCapData { @@ -308,6 +315,7 @@ struct _virNodeDevCapData { virNodeDevCapMdev mdev; virNodeDevCapCCW ccw_dev; virNodeDevCapVDPA vdpa; + virNodeDevCapAPCard ap_card; }; }; diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 9e46d22a2f..0aa5928981 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -717,6 +717,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_MDEV: case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_VDPA: + 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 17051fd013..deee85329c 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1183,6 +1183,31 @@ udevProcessVDPA(struct udev_device *device, } +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) @@ -1237,6 +1262,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")) @@ -1312,6 +1339,8 @@ udevGetDeviceDetails(struct udev_device *device, return udevProcessCSS(device, def); case VIR_NODE_DEV_CAP_VDPA: return udevProcessVDPA(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/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 527bf49fc3..32c12553a9 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -467,6 +467,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) case VIR_NODE_DEV_CAP_VDPA: flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA; break; + case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_LAST: break; }