[PATCH v2 1/5] conf: introduce crypto device

zhenwei pi pizhenwei at bytedance.com
Tue Jan 17 01:46:50 UTC 2023


Introduce crypto device like:

  <crypto model='virtio' type='qemu'>
    <backend model='builtin' queues='1'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
  </crypto>

  <crypto model='virtio' type='qemu'>
    <backend model='lkcf'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/>
  </crypto>

Currently, crypto model supports virtio only, type supports qemu only
(vhost-user in the plan). For the qemu type, backend supports modle
builtin/lkcf, and the queues is optional.

Changes in this commit:
- docs: formatdomain.rst
- schemas: domaincommon.rng
- conf: crypto related domain conf
- qemu: crypto related
- tests: crypto related test

Signed-off-by: zhenwei pi <pizhenwei at bytedance.com>
---
 docs/formatdomain.rst                         |  21 +++
 src/ch/ch_domain.c                            |   1 +
 src/conf/domain_conf.c                        | 158 ++++++++++++++++++
 src/conf/domain_conf.h                        |  39 +++++
 src/conf/domain_postparse.c                   |   1 +
 src/conf/domain_validate.c                    |  18 ++
 src/conf/schemas/domaincommon.rng             |  58 +++++++
 src/conf/virconftypes.h                       |   2 +
 src/libvirt_private.syms                      |   1 +
 src/qemu/qemu_command.c                       |   1 +
 src/qemu/qemu_domain.c                        |   3 +
 src/qemu/qemu_domain_address.c                |  26 +++
 src/qemu/qemu_driver.c                        |   5 +
 src/qemu/qemu_hotplug.c                       |   3 +
 src/qemu/qemu_validate.c                      |  22 +++
 tests/qemuxml2argvdata/crypto-builtin.xml     |  51 ++++++
 .../crypto-builtin.x86_64-latest.xml          |   1 +
 tests/qemuxml2xmltest.c                       |   2 +
 18 files changed, 413 insertions(+)
 create mode 100644 tests/qemuxml2argvdata/crypto-builtin.xml
 create mode 120000 tests/qemuxml2xmloutdata/crypto-builtin.x86_64-latest.xml

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 490a954745..dadcbc631a 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -8305,6 +8305,27 @@ The optional ``driver`` element allows to specify virtio options, see
    ...
 
 
+Crypto
+~~~~~~
+
+A crypto device. The ``model`` attribute defaults to ``virtio``.
+:since:`Since v9.0.0` ``model`` supports ``virtio`` only. The ``type`` attribute
+defaults to ``qemu``. :since:`Since v9.0.0` ``type`` supports ``qemu`` only.
+The optional attribute ``backend`` is required if the ``type`` is ``qemu``, the
+``model`` attribute can be ``builtint`` and ``lkcf``, the optional attribute
+``queues`` specifies the number of virt queues for virtio crypto.
+
+::
+
+   ...
+   <devices>
+     <crypto model='virtio' type='qemu'>
+       <backend model='builtin' queues='1'/>
+     </crypto>
+   </devices>
+   ...
+
+
 Security label
 --------------
 
diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index dc666243a4..83defbb416 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -174,6 +174,7 @@ chValidateDomainDeviceDef(const virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Cloud-Hypervisor doesn't support '%s' device"),
                        virDomainDeviceTypeToString(dev->type));
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 45965fa0fa..7f6a55185e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -332,6 +332,7 @@ VIR_ENUM_IMPL(virDomainDevice,
               "iommu",
               "vsock",
               "audio",
+              "crypto",
 );
 
 VIR_ENUM_IMPL(virDomainDiskDevice,
@@ -1327,6 +1328,22 @@ VIR_ENUM_IMPL(virDomainVsockModel,
               "virtio-non-transitional",
 );
 
+VIR_ENUM_IMPL(virDomainCryptoModel,
+              VIR_DOMAIN_CRYPTO_MODEL_LAST,
+              "virtio",
+);
+
+VIR_ENUM_IMPL(virDomainCryptoType,
+              VIR_DOMAIN_CRYPTO_TYPE_LAST,
+              "qemu",
+);
+
+VIR_ENUM_IMPL(virDomainCryptoBackend,
+              VIR_DOMAIN_CRYPTO_BACKEND_LAST,
+              "builtin",
+              "lkcf",
+);
+
 VIR_ENUM_IMPL(virDomainDiskDiscard,
               VIR_DOMAIN_DISK_DISCARD_LAST,
               "default",
@@ -3510,6 +3527,9 @@ void virDomainDeviceDefFree(virDomainDeviceDef *def)
     case VIR_DOMAIN_DEVICE_AUDIO:
         virDomainAudioDefFree(def->data.audio);
         break;
+    case VIR_DOMAIN_DEVICE_CRYPTO:
+        virDomainCryptoDefFree(def->data.crypto);
+        break;
     case VIR_DOMAIN_DEVICE_LAST:
     case VIR_DOMAIN_DEVICE_NONE:
         break;
@@ -3853,6 +3873,10 @@ void virDomainDefFree(virDomainDef *def)
         virDomainPanicDefFree(def->panics[i]);
     g_free(def->panics);
 
+    for (i = 0; i < def->ncryptos; i++)
+        virDomainCryptoDefFree(def->cryptos[i]);
+    g_free(def->cryptos);
+
     virDomainIOMMUDefFree(def->iommu);
 
     g_free(def->idmap.uidmap);
@@ -4411,6 +4435,8 @@ virDomainDeviceGetInfo(const virDomainDeviceDef *device)
         return &device->data.iommu->info;
     case VIR_DOMAIN_DEVICE_VSOCK:
         return &device->data.vsock->info;
+    case VIR_DOMAIN_DEVICE_CRYPTO:
+        return &device->data.crypto->info;
 
     /* The following devices do not contain virDomainDeviceInfo */
     case VIR_DOMAIN_DEVICE_LEASE:
@@ -4513,6 +4539,9 @@ virDomainDeviceSetData(virDomainDeviceDef *device,
     case VIR_DOMAIN_DEVICE_AUDIO:
         device->data.audio = devicedata;
         break;
+    case VIR_DOMAIN_DEVICE_CRYPTO:
+        device->data.crypto = devicedata;
+        break;
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_LAST:
         break;
@@ -4724,6 +4753,13 @@ virDomainDeviceInfoIterateFlags(virDomainDef *def,
             return rc;
     }
 
+    device.type = VIR_DOMAIN_DEVICE_CRYPTO;
+    for (i = 0; i < def->ncryptos; i++) {
+        device.data.crypto = def->cryptos[i];
+        if ((rc = cb(def, &device, &def->cryptos[i]->info, opaque)) != 0)
+            return rc;
+    }
+
     /* If the flag below is set, make sure @cb can handle @info being NULL */
     if (iteratorFlags & DOMAIN_DEVICE_ITERATE_MISSING_INFO) {
         device.type = VIR_DOMAIN_DEVICE_GRAPHICS;
@@ -4782,6 +4818,7 @@ virDomainDeviceInfoIterateFlags(virDomainDef *def,
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
         break;
     }
 #endif
@@ -13610,6 +13647,64 @@ virDomainVsockDefParseXML(virDomainXMLOption *xmlopt,
     return g_steal_pointer(&vsock);
 }
 
+
+static virDomainCryptoDef *
+virDomainCryptoDefParseXML(virDomainXMLOption *xmlopt,
+                           xmlNodePtr node,
+                           xmlXPathContextPtr ctxt,
+                           unsigned int flags)
+{
+    g_autoptr(virDomainCryptoDef) def = NULL;
+    int nbackends;
+    g_autofree xmlNodePtr *backends = NULL;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt)
+
+    def = g_new0(virDomainCryptoDef, 1);
+
+    if (virXMLPropEnum(node, "model", virDomainCryptoModelTypeFromString,
+                       VIR_XML_PROP_REQUIRED, &def->model) < 0) {
+        return NULL;
+    }
+
+
+    if (virXMLPropEnum(node, "type", virDomainCryptoTypeTypeFromString,
+                       VIR_XML_PROP_REQUIRED, &def->type) < 0) {
+        return NULL;
+    }
+
+    ctxt->node = node;
+
+    if ((nbackends = virXPathNodeSet("./backend", ctxt, &backends)) < 0)
+        return NULL;
+
+    if (nbackends != 1) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("only one crypto backend is supported"));
+        return NULL;
+    }
+
+    if (virXMLPropEnum(backends[0], "model",
+                       virDomainCryptoBackendTypeFromString,
+                       VIR_XML_PROP_REQUIRED, &def->backend) < 0) {
+        return NULL;
+    }
+
+    if (virXMLPropUInt(backends[0], "queues", 10,
+                       VIR_XML_PROP_NONE, &def->queues) < 0) {
+        return NULL;
+    }
+
+    if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, &def->info, flags) < 0)
+        return NULL;
+
+    if (virDomainVirtioOptionsParseXML(virXPathNode("./driver", ctxt),
+                                       &def->virtio) < 0)
+        return NULL;
+
+    return g_steal_pointer(&def);
+}
+
+
 virDomainDeviceDef *
 virDomainDeviceDefParse(const char *xmlStr,
                         const virDomainDef *def,
@@ -13771,6 +13866,11 @@ virDomainDeviceDefParse(const char *xmlStr,
                                                           flags)))
             return NULL;
         break;
+    case VIR_DOMAIN_DEVICE_CRYPTO:
+        if (!(dev->data.crypto = virDomainCryptoDefParseXML(xmlopt, node, ctxt,
+                                                            flags)))
+            return NULL;
+        break;
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_LAST:
         break;
@@ -18863,6 +18963,21 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
     }
     VIR_FREE(nodes);
 
+    /* Parse the crypto devices */
+    if ((n = virXPathNodeSet("./devices/crypto", ctxt, &nodes)) < 0)
+        return NULL;
+    if (n)
+        def->cryptos = g_new0(virDomainCryptoDef *, n);
+    for (i = 0; i < n; i++) {
+        virDomainCryptoDef *crypto = virDomainCryptoDefParseXML(xmlopt, nodes[i],
+                                                                ctxt, flags);
+        if (!crypto)
+            return NULL;
+
+        def->cryptos[def->ncryptos++] = crypto;
+    }
+    VIR_FREE(nodes);
+
     /* Parse the TPM devices */
     if ((n = virXPathNodeSet("./devices/tpm", ctxt, &nodes)) < 0)
         return NULL;
@@ -21403,6 +21518,7 @@ virDomainDefCheckABIStabilityFlags(virDomainDef *src,
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
         break;
     }
 #endif
@@ -24843,6 +24959,45 @@ virDomainRNGDefFree(virDomainRNGDef *def)
 }
 
 
+static void
+virDomainCryptoDefFormat(virBuffer *buf,
+                         virDomainCryptoDef *def,
+                         unsigned int flags)
+{
+    const char *model = virDomainCryptoModelTypeToString(def->model);
+    const char *type = virDomainCryptoTypeTypeToString(def->model);
+    const char *backend = virDomainCryptoBackendTypeToString(def->backend);
+    g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER;
+    g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+    g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
+
+    virBufferAsprintf(&attrBuf, " model='%s' type='%s'", model, type);
+    virBufferAsprintf(&childBuf, "<backend model='%s'", backend);
+    if (def->queues)
+        virBufferAsprintf(&childBuf, " queues='%d'", def->queues);
+    virBufferAddLit(&childBuf, "/>\n");
+
+    virDomainVirtioOptionsFormat(&driverAttrBuf, def->virtio);
+
+    virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL);
+
+    virDomainDeviceInfoFormat(&childBuf, &def->info, flags);
+
+    virXMLFormatElement(buf, "crypto", &attrBuf, &childBuf);
+}
+
+void
+virDomainCryptoDefFree(virDomainCryptoDef *def)
+{
+    if (!def)
+        return;
+
+    virDomainDeviceInfoClear(&def->info);
+    g_free(def->virtio);
+    g_free(def);
+}
+
+
 static int
 virDomainMemorySourceDefFormat(virBuffer *buf,
                                virDomainMemoryDef *def)
@@ -27542,6 +27697,9 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
             return -1;
     }
 
+    for (n = 0; n < def->ncryptos; n++) {
+        virDomainCryptoDefFormat(buf, def->cryptos[n], flags);
+    }
     if (def->iommu)
         virDomainIOMMUDefFormat(buf, def->iommu);
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3e4985a67d..d99bbbc3ff 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -86,6 +86,7 @@ typedef enum {
     VIR_DOMAIN_DEVICE_IOMMU,
     VIR_DOMAIN_DEVICE_VSOCK,
     VIR_DOMAIN_DEVICE_AUDIO,
+    VIR_DOMAIN_DEVICE_CRYPTO,
 
     VIR_DOMAIN_DEVICE_LAST
 } virDomainDeviceType;
@@ -118,6 +119,7 @@ struct _virDomainDeviceDef {
         virDomainIOMMUDef *iommu;
         virDomainVsockDef *vsock;
         virDomainAudioDef *audio;
+        virDomainCryptoDef *crypto;
     } data;
 };
 
@@ -2897,6 +2899,34 @@ struct _virDomainVsockDef {
     virDomainVirtioOptions *virtio;
 };
 
+typedef enum {
+    VIR_DOMAIN_CRYPTO_MODEL_VIRTIO,
+
+    VIR_DOMAIN_CRYPTO_MODEL_LAST
+} virDomainCryptoModel;
+
+typedef enum {
+    VIR_DOMAIN_CRYPTO_TYPE_QEMU,
+
+    VIR_DOMAIN_CRYPTO_TYPE_LAST
+} virDomainCryptoType;
+
+typedef enum {
+    VIR_DOMAIN_CRYPTO_BACKEND_BUILTIN,
+    VIR_DOMAIN_CRYPTO_BACKEND_LKCF,
+
+    VIR_DOMAIN_CRYPTO_BACKEND_LAST
+} virDomainCryptoBackend;
+
+struct _virDomainCryptoDef {
+    virDomainCryptoModel model;
+    virDomainCryptoType type;
+    virDomainCryptoBackend backend;
+    unsigned int queues;
+    virDomainDeviceInfo info;
+    virDomainVirtioOptions *virtio;
+};
+
 struct _virDomainVirtioOptions {
     virTristateSwitch iommu;
     virTristateSwitch ats;
@@ -3062,6 +3092,9 @@ struct _virDomainDef {
     size_t nsysinfo;
     virSysinfoDef **sysinfo;
 
+    size_t ncryptos;
+    virDomainCryptoDef **cryptos;
+
     /* At maximum 2 TPMs on the domain if a TPM Proxy is present. */
     size_t ntpms;
     virDomainTPMDef **tpms;
@@ -3331,6 +3364,7 @@ struct _virDomainXMLPrivateDataCallbacks {
     virDomainXMLPrivateDataNewFunc    vcpuNew;
     virDomainXMLPrivateDataNewFunc    chrSourceNew;
     virDomainXMLPrivateDataNewFunc    vsockNew;
+    virDomainXMLPrivateDataNewFunc    cryptoNew;
     virDomainXMLPrivateDataNewFunc    graphicsNew;
     virDomainXMLPrivateDataNewFunc    networkNew;
     virDomainXMLPrivateDataNewFunc    videoNew;
@@ -3505,6 +3539,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainIOMMUDef, virDomainIOMMUDefFree);
 virDomainVsockDef *virDomainVsockDefNew(virDomainXMLOption *xmlopt);
 void virDomainVsockDefFree(virDomainVsockDef *vsock);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVsockDef, virDomainVsockDefFree);
+void virDomainCryptoDefFree(virDomainCryptoDef *def);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainCryptoDef, virDomainCryptoDefFree);
 void virDomainNetTeamingInfoFree(virDomainNetTeamingInfo *teaming);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainNetTeamingInfo, virDomainNetTeamingInfoFree);
 void virDomainNetPortForwardFree(virDomainNetPortForward *pf);
@@ -4159,6 +4195,9 @@ VIR_ENUM_DECL(virDomainMemorySource);
 VIR_ENUM_DECL(virDomainMemoryAllocation);
 VIR_ENUM_DECL(virDomainIOMMUModel);
 VIR_ENUM_DECL(virDomainVsockModel);
+VIR_ENUM_DECL(virDomainCryptoModel);
+VIR_ENUM_DECL(virDomainCryptoType);
+VIR_ENUM_DECL(virDomainCryptoBackend);
 VIR_ENUM_DECL(virDomainShmemModel);
 VIR_ENUM_DECL(virDomainShmemRole);
 VIR_ENUM_DECL(virDomainLaunchSecurity);
diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c
index d1f0b80338..22eb603b3b 100644
--- a/src/conf/domain_postparse.c
+++ b/src/conf/domain_postparse.c
@@ -730,6 +730,7 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
         ret = 0;
         break;
 
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 5a9bf20d3f..3ba41e4c00 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2442,6 +2442,21 @@ virDomainVsockDefValidate(const virDomainVsockDef *vsock)
 }
 
 
+static int
+virDomainCryptoDefValidate(const virDomainCryptoDef *crypto)
+{
+    switch (crypto->model) {
+    case VIR_DOMAIN_CRYPTO_MODEL_VIRTIO:
+        break;
+    case VIR_DOMAIN_CRYPTO_MODEL_LAST:
+    default:
+        return -1;
+    }
+
+    return 0;
+}
+
+
 static int
 virDomainInputDefValidate(const virDomainInputDef *input,
                           const virDomainDef *def)
@@ -2866,6 +2881,9 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_VSOCK:
         return virDomainVsockDefValidate(dev->data.vsock);
 
+    case VIR_DOMAIN_DEVICE_CRYPTO:
+        return virDomainCryptoDefValidate(dev->data.crypto);
+
     case VIR_DOMAIN_DEVICE_INPUT:
         return virDomainInputDefValidate(dev->data.input, def);
 
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 6cb0a20e1e..14044811c0 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6426,6 +6426,7 @@
             <ref name="tpm"/>
             <ref name="shmem"/>
             <ref name="memorydev"/>
+            <ref name="crypto"/>
           </choice>
         </zeroOrMore>
         <optional>
@@ -7196,6 +7197,63 @@
     </element>
   </define>
 
+  <define name="crypto">
+    <element name="crypto">
+      <attribute name="model">
+        <choice>
+          <value>virtio</value>
+        </choice>
+      </attribute>
+      <attribute name="type">
+        <choice>
+          <value>qemu</value>
+        </choice>
+      </attribute>
+      <interleave>
+        <ref name="crypto-backend"/>
+        <optional>
+          <element name="driver">
+            <ref name="virtioOptions"/>
+          </element>
+        </optional>
+        <optional>
+          <ref name="alias"/>
+        </optional>
+        <optional>
+          <ref name="address"/>
+        </optional>
+      </interleave>
+    </element>
+  </define>
+
+  <define name="crypto-backend">
+    <element name="backend">
+      <choice>
+        <group>
+          <attribute name="model">
+            <value>builtin</value>
+          </attribute>
+          <optional>
+            <attribute name="queues">
+              <ref name="positiveInteger"/>
+            </attribute>
+          </optional>
+        </group>
+        <group>
+          <attribute name="model">
+            <value>lkcf</value>
+          </attribute>
+          <optional>
+            <attribute name="queues">
+              <ref name="positiveInteger"/>
+            </attribute>
+          </optional>
+        </group>
+      </choice>
+    </element>
+  </define>
+
+
   <define name="virtioOptions">
     <optional>
       <attribute name="iommu">
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index adb2496cba..d03d1d132e 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -254,6 +254,8 @@ typedef struct _virDomainVirtioSerialOpts virDomainVirtioSerialOpts;
 
 typedef struct _virDomainVsockDef virDomainVsockDef;
 
+typedef struct _virDomainCryptoDef virDomainCryptoDef;
+
 typedef struct _virDomainWatchdogDef virDomainWatchdogDef;
 
 typedef struct _virDomainXMLOption virDomainXMLOption;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 576ec8f95f..8b9efe106c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -301,6 +301,7 @@ virDomainControllerRemove;
 virDomainControllerTypeToString;
 virDomainCpuPlacementModeTypeFromString;
 virDomainCpuPlacementModeTypeToString;
+virDomainCryptoDefFree;
 virDomainDefAddController;
 virDomainDefAddImplicitDevices;
 virDomainDefAddUSBController;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b96f2d33c1..bb7031f66d 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -942,6 +942,7 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device,
         case VIR_DOMAIN_DEVICE_MEMORY:
         case VIR_DOMAIN_DEVICE_IOMMU:
         case VIR_DOMAIN_DEVICE_AUDIO:
+        case VIR_DOMAIN_DEVICE_CRYPTO:
         case VIR_DOMAIN_DEVICE_LAST:
         default:
             break;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2eb5653254..b6ad118f1f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5945,6 +5945,7 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_RNG:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
         ret = 0;
         break;
 
@@ -9983,6 +9984,7 @@ qemuDomainPrepareChardevSourceOne(virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
         break;
     }
 
@@ -11783,6 +11785,7 @@ qemuDomainDeviceBackendChardevForeachOne(virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
         /* no chardev backend */
         break;
     }
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index b8d1969fbe..9529bd9a8d 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -405,6 +405,12 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDef *def,
             def->vsock->info.type = type;
         }
     }
+
+    for (i = 0; i < def->ncryptos; i++) {
+        /* All <crypto> devices accepted by the qemu driver are virtio */
+        if (def->cryptos[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            def->cryptos[i]->info.type = type;
+    }
 }
 
 
@@ -544,6 +550,7 @@ qemuDomainDeviceSupportZPCI(virDomainDeviceDef *device)
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
         break;
 
     case VIR_DOMAIN_DEVICE_NONE:
@@ -1045,6 +1052,15 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev,
         }
         break;
 
+    case VIR_DOMAIN_DEVICE_CRYPTO:
+        switch (dev->data.crypto->model) {
+        case VIR_DOMAIN_CRYPTO_MODEL_VIRTIO:
+            return pciFlags;
+        case VIR_DOMAIN_CRYPTO_MODEL_LAST:
+            return 0;
+        }
+        break;
+
         /* These devices don't ever connect with PCI */
     case VIR_DOMAIN_DEVICE_NVRAM:
     case VIR_DOMAIN_DEVICE_TPM:
@@ -2428,6 +2444,16 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def,
         }
     }
 
+    /* the qemu driver only accepts virtio crypto devices */
+    for (i = 0; i < def->ncryptos; i++) {
+        if (!virDeviceInfoPCIAddressIsWanted(&def->cryptos[i]->info))
+            continue;
+
+        if (qemuDomainPCIAddressReserveNextAddr(addrs, &def->cryptos[i]->info) < 0)
+            return -1;
+    }
+
+
     return 0;
 }
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d6879175fe..f88f44170a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6768,6 +6768,7 @@ qemuDomainAttachDeviceLive(virDomainObj *vm,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live attach of device '%s' is not supported"),
@@ -7079,6 +7080,7 @@ qemuDomainUpdateDeviceLive(virDomainObj *vm,
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("live update of device '%s' is not supported"),
@@ -7290,6 +7292,7 @@ qemuDomainAttachDeviceConfig(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_LAST:
          virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                         _("persistent attach of device '%s' is not supported"),
@@ -7495,6 +7498,7 @@ qemuDomainDetachDeviceConfig(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("persistent detach of device '%s' is not supported"),
@@ -7620,6 +7624,7 @@ qemuDomainUpdateDeviceConfig(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("persistent update of device '%s' is not supported"),
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 026e1ee5ad..49ef49fb15 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -5037,6 +5037,7 @@ qemuDomainRemoveAuditDevice(virDomainObj *vm,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_LAST:
         /* libvirt doesn't yet support detaching these devices */
         break;
@@ -5140,6 +5141,7 @@ qemuDomainRemoveDevice(virQEMUDriver *driver,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("don't know how to remove a %s device"),
@@ -5993,6 +5995,7 @@ qemuDomainDetachDeviceLive(virDomainObj *vm,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live detach of device '%s' is not supported"),
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 6e04b22da4..5daf7d31c7 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -4511,6 +4511,25 @@ qemuValidateDomainDeviceDefAudio(virDomainAudioDef *audio,
 }
 
 
+static int
+qemuValidateDomainDeviceDefCrypto(virDomainCryptoDef *crypto,
+                                  const virDomainDef *def G_GNUC_UNUSED,
+                                  virQEMUCaps *qemuCaps G_GNUC_UNUSED)
+{
+    switch (crypto->type) {
+    case VIR_DOMAIN_CRYPTO_TYPE_QEMU:
+        break;
+
+    case VIR_DOMAIN_CRYPTO_TYPE_LAST:
+    default:
+        virReportEnumRangeError(virDomainCryptoType, crypto->type);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 static int
 qemuSoundCodecTypeToCaps(int type)
 {
@@ -5218,6 +5237,9 @@ qemuValidateDomainDeviceDef(const virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_AUDIO:
         return qemuValidateDomainDeviceDefAudio(dev->data.audio, def, qemuCaps);
 
+    case VIR_DOMAIN_DEVICE_CRYPTO:
+        return qemuValidateDomainDeviceDefCrypto(dev->data.crypto, def, qemuCaps);
+
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_NONE:
diff --git a/tests/qemuxml2argvdata/crypto-builtin.xml b/tests/qemuxml2argvdata/crypto-builtin.xml
new file mode 100644
index 0000000000..51049888f6
--- /dev/null
+++ b/tests/qemuxml2argvdata/crypto-builtin.xml
@@ -0,0 +1,51 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <maxMemory slots='16' unit='KiB'>1130496</maxMemory>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc-q35-7.0'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <cpu mode='custom' match='exact' check='none'>
+    <model fallback='forbid'>qemu64</model>
+    <numa>
+      <cell id='0' cpus='0' memory='524288' unit='KiB'/>
+      <cell id='1' cpus='1' memory='524288' unit='KiB'/>
+    </numa>
+  </cpu>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <controller type='pci' index='0' model='pcie-root'/>
+    <controller type='pci' index='1' model='pcie-root-port'>
+      <model name='pcie-root-port'/>
+      <target chassis='1' port='0x8'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
+    </controller>
+    <controller type='pci' index='2' model='pcie-root-port'>
+      <model name='pcie-root-port'/>
+      <target chassis='2' port='0x9'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='usb' index='0' model='none'/>
+    <controller type='sata' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+    </controller>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <audio id='1' type='none'/>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+    </memballoon>
+    <crypto model='virtio' type='qemu'>
+      <backend model='builtin' queues='1'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
+    </crypto>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/crypto-builtin.x86_64-latest.xml b/tests/qemuxml2xmloutdata/crypto-builtin.x86_64-latest.xml
new file mode 120000
index 0000000000..fc0a6331f2
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/crypto-builtin.x86_64-latest.xml
@@ -0,0 +1 @@
+../qemuxml2argvdata/crypto-builtin.xml
\ No newline at end of file
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 72f724bfce..9ab49b822c 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -1300,6 +1300,8 @@ mymain(void)
 
     DO_TEST_CAPS_VER("sgx-epc", "7.0.0");
 
+    DO_TEST_CAPS_LATEST("crypto-builtin");
+
  cleanup:
     if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
         virFileDeleteTree(fakerootdir);
-- 
2.34.1



More information about the libvir-list mailing list