[PATCH libvirt v2 11/11] node_device: detecting mdev_types capability on ap_matrix device

Jonathon Jongsma jjongsma at redhat.com
Thu Nov 12 21:08:39 UTC 2020


On Thu, 12 Nov 2020 13:15:19 +0100
Shalini Chellathurai Saroja <shalini at linux.ibm.com> wrote:

> From: Boris Fiuczynski <fiuczy at linux.ibm.com>
> 
> Add detection of mdev_types capability to Adjunct Processor Matrix
> device.
> 
> Signed-off-by: Boris Fiuczynski <fiuczy at linux.ibm.com>
> Signed-off-by: Shalini Chellathurai Saroja <shalini at linux.ibm.com>
> ---
>  docs/formatnode.html.in                       |  24 +++-
>  docs/schemas/nodedev.rng                      |   4 +
>  src/conf/node_device_conf.c                   | 108
> +++++++++++++++++- src/conf/node_device_conf.h                   |
> 11 ++ src/conf/virnodedeviceobj.c                   |   7 +-
>  src/libvirt_private.syms                      |   1 +
>  src/node_device/node_device_udev.c            |   4 +
>  .../ap_matrix_mdev_types.xml                  |  14 +++
>  tests/nodedevxml2xmltest.c                    |   1 +
>  9 files changed, 168 insertions(+), 6 deletions(-)
>  create mode 100644 tests/nodedevschemadata/ap_matrix_mdev_types.xml
> 
> diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in
> index 8a84d0dc..66f38c51 100644
> --- a/docs/formatnode.html.in
> +++ b/docs/formatnode.html.in
> @@ -452,7 +452,26 @@
>            </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>
> +              cryptographic host resources usable for virtualization.
> +              Sub-elements include:
> +            <dl>
> +              <dt><code>capability</code></dt>
> +              <dd>
> +                This optional element can occur multiple times. If it
> +                exists, it has a mandatory <code>type</code>
> attribute
> +                which will be set to:
> +                <dl>
> +                  <dt><code><a
> id="MDEVTypesCapAP">mdev_types</a></code></dt>
> +                  <dd>
> +                    <span class="since">Since 6.10.0</span>
> +                    This device is capable of creating mediated
> devices.
> +                    The sub-elements are summarized in
> +                    <a href="#MDEVTypesCap">mdev_types
> capability</a>.
> +                  </dd>
> +                </dl>
> +              </dd>
> +            </dl>
> +          </dd>
>          </dl>
>        </dd>
>      </dl>
> @@ -460,7 +479,8 @@
>      <h3><a id="MDEVTypesCap">mdev_types capability</a></h3>
>  
>      <p>
> -      <a href="#MDEVTypesCapPCI">PCI</a> and <a
> href="#MDEVTypesCapCSS">CSS</a>
> +      <a href="#MDEVTypesCapPCI">PCI</a>, <a
> href="#MDEVTypesCapCSS">CSS</a>
> +      and <a href="#MDEVTypesCapAP">AP Matrix</a>
>        devices can be capable of creating mediated devices.
>        If they indeed are capable, then the parent
> <code>capability</code> element for <code>mdev_types</code> type will
> contain a list of diff --git a/docs/schemas/nodedev.rng
> b/docs/schemas/nodedev.rng index 5be21145..8ea74f23 100644
> --- a/docs/schemas/nodedev.rng
> +++ b/docs/schemas/nodedev.rng
> @@ -696,6 +696,9 @@
>      <attribute name='type'>
>        <value>ap_matrix</value>
>      </attribute>
> +    <optional>
> +      <ref name="mdev_types"/>
> +    </optional>
>    </define>
>  
>    <define name='address'>
> @@ -736,6 +739,7 @@
>              <choice>
>                <value>vfio-pci</value>
>                <value>vfio-ccw</value>
> +              <value>vfio-ap</value>
>              </choice>
>            </element>
>            <element name="availableInstances">
> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
> index f3d146a5..01a4d5cd 100644
> --- a/src/conf/node_device_conf.c
> +++ b/src/conf/node_device_conf.c
> @@ -663,10 +663,15 @@ virNodeDeviceDefFormat(const virNodeDeviceDef
> *def) virBufferAsprintf(&buf, "<ap-domain>0x%04x</ap-domain>\n",
>                                data->ap_queue.ap_domain);
>              break;
> +        case VIR_NODE_DEV_CAP_AP_MATRIX:
> +            if (data->ap_matrix.flags &
> VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV)
> +                virNodeDeviceCapMdevTypesFormat(&buf,
> +
> data->ap_matrix.mdev_types,
> +
> data->ap_matrix.nmdev_types); +
>          case VIR_NODE_DEV_CAP_MDEV_TYPES:
>          case VIR_NODE_DEV_CAP_FC_HOST:
>          case VIR_NODE_DEV_CAP_VPORTS:
> -        case VIR_NODE_DEV_CAP_AP_MATRIX:
>          case VIR_NODE_DEV_CAP_LAST:
>              break;
>          }
> @@ -861,6 +866,33 @@
> virNodeDevCapMdevTypesParseXML(xmlXPathContextPtr ctxt, }
>  
>  
> +static int
> +virNodeDevAPMatrixCapabilityParseXML(xmlXPathContextPtr ctxt,
> +                                     xmlNodePtr node,
> +                                     virNodeDevCapAPMatrixPtr
> apm_dev) +{
> +    g_autofree char *type = virXMLPropString(node, "type");
> +    VIR_XPATH_NODE_AUTORESTORE(ctxt)
> +
> +    ctxt->node = node;
> +
> +    if (!type) {
> +        virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing
> capability type"));
> +        return -1;
> +    }
> +
> +    if (STREQ(type, "mdev_types")) {
> +        if (virNodeDevCapMdevTypesParseXML(ctxt,
> +                                           &apm_dev->mdev_types,
> +                                           &apm_dev->nmdev_types) <
> 0)
> +            return -1;
> +        apm_dev->flags |= VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV;
> +    }
> +
> +    return 0;
> +}
> +
> +
>  static int
>  virNodeDevCSSCapabilityParseXML(xmlXPathContextPtr ctxt,
>                                  xmlNodePtr node,
> @@ -1031,6 +1063,31 @@
> virNodeDevCapAPQueueParseXML(xmlXPathContextPtr ctxt, }
>  
>  
> +static int
> +virNodeDevCapAPMatrixParseXML(xmlXPathContextPtr ctxt,
> +                              virNodeDeviceDefPtr def G_GNUC_UNUSED,
> +                              xmlNodePtr node,
> +                              virNodeDevCapAPMatrixPtr ap_matrix)
> +{
> +    VIR_XPATH_NODE_AUTORESTORE(ctxt)
> +    g_autofree xmlNodePtr *nodes = NULL;
> +    int n = 0;
> +    size_t i = 0;
> +
> +    ctxt->node = node;
> +
> +    if ((n = virXPathNodeSet("./capability", ctxt, &nodes)) < 0)
> +        return -1;
> +
> +    for (i = 0; i < n; i++) {
> +        if (virNodeDevAPMatrixCapabilityParseXML(ctxt, nodes[i],
> ap_matrix) < 0)
> +            return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +
>  static int
>  virNodeDevCapStorageParseXML(xmlXPathContextPtr ctxt,
>                               virNodeDeviceDefPtr def,
> @@ -2078,7 +2135,8 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr
> ctxt, &caps->data.ap_queue);
>          break;
>      case VIR_NODE_DEV_CAP_AP_MATRIX:
> -        ret = 0;
> +        ret = virNodeDevCapAPMatrixParseXML(ctxt, def, node,
> +                                            &caps->data.ap_matrix);
>          break;
>      case VIR_NODE_DEV_CAP_MDEV_TYPES:
>      case VIR_NODE_DEV_CAP_FC_HOST:
> @@ -2403,6 +2461,9 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
>          break;
>      case VIR_NODE_DEV_CAP_AP_MATRIX:
>          VIR_FREE(data->ap_matrix.addr);
> +        for (i = 0; i < data->ap_matrix.nmdev_types; i++)
> +            virMediatedDeviceTypeFree(data->ap_matrix.mdev_types[i]);
> +        VIR_FREE(data->ap_matrix.mdev_types);
>          break;
>      case VIR_NODE_DEV_CAP_MDEV_TYPES:
>      case VIR_NODE_DEV_CAP_DRM:
> @@ -2454,6 +2515,11 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr
> def) &cap->data.ccw_dev) < 0)
>                  return -1;
>              break;
> +        case VIR_NODE_DEV_CAP_AP_MATRIX:
> +            if (virNodeDeviceGetAPMatrixDynamicCaps(def->sysfs_path,
> +
> &cap->data.ap_matrix) < 0)
> +                return -1;
> +            break;
>  
>              /* all types that (supposedly) don't require any updates
>               * relative to what's in the cache.
> @@ -2473,7 +2539,6 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def)
>          case VIR_NODE_DEV_CAP_VDPA:
>          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;
>          }
> @@ -2556,6 +2621,15 @@
> virNodeDeviceCapsListExport(virNodeDeviceDefPtr def, ncaps++;
>              }
>          }
> +
> +        if (caps->data.type == VIR_NODE_DEV_CAP_AP_MATRIX) {
> +            flags = caps->data.ap_matrix.flags;
> +
> +            if (flags & VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV) {
> +                MAYBE_ADD_CAP(VIR_NODE_DEV_CAP_MDEV_TYPES);
> +                ncaps++;
> +            }
> +        }
>      }
>  
>  #undef MAYBE_ADD_CAP
> @@ -2844,6 +2918,27 @@ virNodeDeviceGetCSSDynamicCaps(const char
> *sysfsPath, return 0;
>  }
>  
> +/* virNodeDeviceGetAPMatrixDynamicCaps() get info that is stored in
> sysfs
> + * about devices related to this device, i.e. things that can change
> + * without this device itself changing. These must be refreshed
> + * anytime full XML of the device is requested, because they can
> + * change with no corresponding notification from the kernel/udev.
> + */
> +int
> +virNodeDeviceGetAPMatrixDynamicCaps(const char *sysfsPath,
> +                                    virNodeDevCapAPMatrixPtr
> ap_matrix) +{
> +    ap_matrix->flags &= ~VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV;
> +    if (virNodeDeviceGetMdevTypesCaps(sysfsPath,
> +                                      &ap_matrix->mdev_types,
> +                                      &ap_matrix->nmdev_types) < 0)
> +        return -1;
> +    if (ap_matrix->nmdev_types > 0)
> +        ap_matrix->flags |= VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV;
> +
> +    return 0;
> +}
> +
>  #else
>  
>  int
> @@ -2872,4 +2967,11 @@ virNodeDeviceGetCSSDynamicCaps(const char
> *sysfsPath G_GNUC_UNUSED, return -1;
>  }
>  
> +int
> +virNodeDeviceGetAPMatrixDynamicCaps(const char *sysfsPath
> G_GNUC_UNUSED,
> +                                    virNodeDevCapAPMatrixPtr
> ap_matrix G_GNUC_UNUSED) +{
> +    return -1;
> +}
> +
>  #endif /* __linux__ */
> diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
> index b8397128..c67b8e2a 100644
> --- a/src/conf/node_device_conf.h
> +++ b/src/conf/node_device_conf.h
> @@ -109,6 +109,10 @@ typedef enum {
>      VIR_NODE_DEV_CAP_FLAG_CSS_MDEV                  = (1 << 0),
>  } virNodeDevCCWCapFlags;
>  
> +typedef enum {
> +    VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV            = (1 << 0),
> +} virNodeDevAPMatrixCapFlags;
> +
>  typedef enum {
>      /* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
>      VIR_NODE_DEV_DRM_PRIMARY,
> @@ -309,6 +313,9 @@ typedef struct _virNodeDevCapAPMatrix
> virNodeDevCapAPMatrix; typedef virNodeDevCapAPMatrix
> *virNodeDevCapAPMatrixPtr; struct _virNodeDevCapAPMatrix {
>      char *addr;
> +    unsigned int flags; /* enum virNodeDevAPMatrixCapFlags */
> +    virMediatedDeviceTypePtr *mdev_types;
> +    size_t nmdev_types;
>  };
>  
>  typedef struct _virNodeDevCapData virNodeDevCapData;
> @@ -430,6 +437,10 @@ int
>  virNodeDeviceGetCSSDynamicCaps(const char *sysfsPath,
>                                 virNodeDevCapCCWPtr ccw_dev);
>  
> +int
> +virNodeDeviceGetAPMatrixDynamicCaps(const char *sysfsPath,
> +                                    virNodeDevCapAPMatrixPtr
> ap_matrix); +
>  int
>  virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def);
>  
> diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
> index 25d12776..c9bda77b 100644
> --- a/src/conf/virnodedeviceobj.c
> +++ b/src/conf/virnodedeviceobj.c
> @@ -702,6 +702,12 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj
> *obj, return true;
>              break;
>  
> +        case VIR_NODE_DEV_CAP_AP_MATRIX:
> +            if (type == VIR_NODE_DEV_CAP_MDEV_TYPES &&
> +                (cap->data.ap_matrix.flags &
> VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV))
> +                return true;
> +            break;
> +
>          case VIR_NODE_DEV_CAP_SYSTEM:
>          case VIR_NODE_DEV_CAP_USB_DEV:
>          case VIR_NODE_DEV_CAP_USB_INTERFACE:
> @@ -719,7 +725,6 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj
> *obj, case VIR_NODE_DEV_CAP_VDPA:
>          case VIR_NODE_DEV_CAP_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/libvirt_private.syms b/src/libvirt_private.syms
> index 491bd5bd..25c3456a 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -824,6 +824,7 @@ virNodeDeviceDefFree;
>  virNodeDeviceDefParseFile;
>  virNodeDeviceDefParseNode;
>  virNodeDeviceDefParseString;
> +virNodeDeviceGetAPMatrixDynamicCaps;
>  virNodeDeviceGetCSSDynamicCaps;
>  virNodeDeviceGetPCIDynamicCaps;
>  virNodeDeviceGetSCSIHostCaps;
> diff --git a/src/node_device/node_device_udev.c
> b/src/node_device/node_device_udev.c index 5f57000e..53f3c24b 100644
> --- a/src/node_device/node_device_udev.c
> +++ b/src/node_device/node_device_udev.c
> @@ -1256,6 +1256,10 @@ udevProcessAPMatrix(struct udev_device *device,
>              *(def->name + i) = '_';
>      }
>  
> +    if (virNodeDeviceGetAPMatrixDynamicCaps(def->sysfs_path,
> +                                            &data->ap_matrix) < 0)
> +        return -1;
> +
>      return 0;
>  }
>  
> diff --git a/tests/nodedevschemadata/ap_matrix_mdev_types.xml
> b/tests/nodedevschemadata/ap_matrix_mdev_types.xml new file mode
> 100644 index 00000000..0ca83680
> --- /dev/null
> +++ b/tests/nodedevschemadata/ap_matrix_mdev_types.xml
> @@ -0,0 +1,14 @@
> +<device>
> +  <name>ap_matrix</name>
> +  <path>/sys/devices/vfio_ap/matrix</path>
> +  <parent>computer</parent>
> +  <capability type='ap_matrix'>
> +    <capability type='mdev_types'>
> +      <type id='vfio_api-passthrough'>

nit: I guess this is just an arbitrary string representing an mdev
type, but I would guess that you intended it to say vfio_ap- instead
of vfio_api-?

> +        <name>VFIO AP Passthrough Device</name>
> +        <deviceAPI>vfio-ap</deviceAPI>
> +        <availableInstances>65536</availableInstances>
> +      </type>
> +    </capability>
> +  </capability>
> +</device>
> diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c
> index dc8cb04f..a2321d13 100644
> --- a/tests/nodedevxml2xmltest.c
> +++ b/tests/nodedevxml2xmltest.c
> @@ -128,6 +128,7 @@ mymain(void)
>      DO_TEST("ap_card07");
>      DO_TEST("ap_07_0038");
>      DO_TEST("ap_matrix");
> +    DO_TEST("ap_matrix_mdev_types");
>      DO_TEST("mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad");
>  
>      return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;


Reviewed-by: Jonathon Jongsma <jjongsma at redhat.com>




More information about the libvir-list mailing list