This patch parse the domain XML with virtio-crypto
support, the virtio-crypto XML looks like this:
<crypto model='virtio'>
<backend type='builtin' queues='1'/>
</crypto>
Signed-off-by: Longpeng(Mike) <longpeng2(a)huawei.com>
---
src/conf/domain_conf.c | 213 ++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 32 +++++++
src/libvirt_private.syms | 2 +
src/qemu/qemu_domain.c | 2 +
src/qemu/qemu_domain_address.c | 1 +
src/qemu/qemu_driver.c | 6 ++
src/qemu/qemu_hotplug.c | 1 +
7 files changed, 256 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 52aee2b..ef44930 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -244,7 +244,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
"tpm",
"panic",
"memory",
- "iommu")
+ "iommu",
+ "crypto")
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"none",
@@ -811,6 +812,14 @@ VIR_ENUM_IMPL(virDomainRNGBackend,
"random",
"egd");
+VIR_ENUM_IMPL(virDomainCryptoModel,
+ VIR_DOMAIN_CRYPTO_MODEL_LAST,
+ "virtio");
+
+VIR_ENUM_IMPL(virDomainCryptoBackend,
+ VIR_DOMAIN_CRYPTO_BACKEND_LAST,
+ "builtin");
+
VIR_ENUM_IMPL(virDomainTPMModel, VIR_DOMAIN_TPM_MODEL_LAST,
"tpm-tis")
@@ -2487,6 +2496,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
case VIR_DOMAIN_DEVICE_IOMMU:
VIR_FREE(def->data.iommu);
break;
+ case VIR_DOMAIN_DEVICE_CRYPTO:
+ virDomainCryptoDefFree(def->data.crypto);
+ break;
case VIR_DOMAIN_DEVICE_LAST:
case VIR_DOMAIN_DEVICE_NONE:
break;
@@ -2735,6 +2747,10 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->iommu);
+ for (i = 0; i < def->ncryptos; i++)
+ virDomainCryptoDefFree(def->cryptos[i]);
+ VIR_FREE(def->cryptos);
+
VIR_FREE(def->idmap.uidmap);
VIR_FREE(def->idmap.gidmap);
@@ -3322,6 +3338,8 @@ virDomainDeviceGetInfo(virDomainDeviceDefPtr device)
return &device->data.panic->info;
case VIR_DOMAIN_DEVICE_MEMORY:
return &device->data.memory->info;
+ case VIR_DOMAIN_DEVICE_CRYPTO:
+ return &device->data.crypto->info;
/* The following devices do not contain virDomainDeviceInfo */
case VIR_DOMAIN_DEVICE_LEASE:
@@ -3620,6 +3638,13 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
return -1;
}
+ device.type = VIR_DOMAIN_DEVICE_CRYPTO;
+ for (i = 0; i < def->ncryptos; i++) {
+ device.data.crypto = def->cryptos[i];
+ if (cb(def, &device, &def->cryptos[i]->info, opaque) < 0)
+ return -1;
+ }
+
/* Coverity is not very happy with this - all dead_error_condition */
#if !STATIC_ANALYSIS
/* This switch statement is here to trigger compiler warning when adding
@@ -3654,6 +3679,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
case VIR_DOMAIN_DEVICE_RNG:
case VIR_DOMAIN_DEVICE_MEMORY:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
break;
}
#endif
@@ -4839,6 +4865,7 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_MEMORY:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LAST:
break;
@@ -12501,6 +12528,88 @@ virDomainRNGDefParseXML(virDomainXMLOptionPtr xmlopt,
}
+static virDomainCryptoDefPtr
+virDomainCryptoDefParseXML(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ unsigned int flags)
+{
+ char *model = NULL;
+ char *backend = NULL;
+ char *queues = NULL;
+ virDomainCryptoDefPtr def;
+ xmlNodePtr save = ctxt->node;
+ xmlNodePtr *backends = NULL;
+ int nbackends;
+
+ if (VIR_ALLOC(def) < 0)
+ return NULL;
+
+ if (!(model = virXMLPropString(node, "model"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing Crypto device model"));
+ goto error;
+ }
+
+ if ((def->model = virDomainCryptoModelTypeFromString(model)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown Crypto model '%s'"), model);
+ goto error;
+ }
+
+ ctxt->node = node;
+
+ if ((nbackends = virXPathNodeSet("./backend", ctxt, &backends)) <
0)
+ goto error;
+
+ if (nbackends != 1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one Crypto backend is supported"));
+ goto error;
+ }
+
+ if (!(backend = virXMLPropString(backends[0], "type"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing Crypto device backend type"));
+ goto error;
+ }
+
+ if ((def->backend = virDomainCryptoBackendTypeFromString(backend)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown Crypto backend model '%s'"),
backend);
+ goto error;
+ }
+
+ switch ((virDomainCryptoBackend) def->backend) {
+ case VIR_DOMAIN_CRYPTO_BACKEND_BUILTIN:
+ queues = virXMLPropString(backends[0], "queues");
+ if (queues && virStrToLong_ui(queues, NULL, 10, &def->queues) <
0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Malformed 'queues' value '%s'"),
queues);
+ }
+ break;
+
+ case VIR_DOMAIN_CRYPTO_BACKEND_LAST:
+ break;
+ }
+
+ if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0)
+ goto error;
+
+cleanup:
+ VIR_FREE(model);
+ VIR_FREE(backend);
+ VIR_FREE(queues);
+ VIR_FREE(backends);
+ ctxt->node = save;
+ return def;
+
+error:
+ virDomainCryptoDefFree(def);
+ def = NULL;
+ goto cleanup;
+}
+
+
static virDomainMemballoonDefPtr
virDomainMemballoonDefParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt,
@@ -13957,6 +14066,10 @@ virDomainDeviceDefParse(const char *xmlStr,
if (!(dev->data.iommu = virDomainIOMMUDefParseXML(node)))
goto error;
break;
+ case VIR_DOMAIN_DEVICE_CRYPTO:
+ if (!(dev->data.crypto = virDomainCryptoDefParseXML(node, ctxt, flags)))
+ goto error;
+ break;
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LAST:
break;
@@ -17854,6 +17967,22 @@ virDomainDefParseXML(xmlDocPtr xml,
VIR_FREE(nodes);
}
+ /* Parse the crypto devices */
+ if ((n = virXPathNodeSet("./devices/crypto", ctxt, &nodes)) < 0)
+ goto error;
+ if (n && VIR_ALLOC_N(def->cryptos, n) < 0)
+ goto error;
+ for (i = 0; i < n; i++) {
+ virDomainCryptoDefPtr crypto = virDomainCryptoDefParseXML(nodes[i],
+ ctxt,
+ flags);
+ if (!crypto)
+ goto error;
+
+ def->cryptos[def->ncryptos++] = crypto;
+ }
+ VIR_FREE(nodes);
+
/* analysis of the hub devices */
if ((n = virXPathNodeSet("./devices/hub", ctxt, &nodes)) < 0)
goto error;
@@ -18967,6 +19096,25 @@ virDomainRNGDefCheckABIStability(virDomainRNGDefPtr src,
static bool
+virDomainCryptoDefCheckABIStability(virDomainCryptoDefPtr src,
+ virDomainCryptoDefPtr dst)
+{
+ if (src->model != dst->model) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target Crypto model '%s' does not match source
'%s'"),
+ virDomainCryptoModelTypeToString(dst->model),
+ virDomainCryptoModelTypeToString(src->model));
+ return false;
+ }
+
+ if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
+ return false;
+
+ return true;
+}
+
+
+static bool
virDomainHubDefCheckABIStability(virDomainHubDefPtr src,
virDomainHubDefPtr dst)
{
@@ -19782,6 +19930,17 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src,
goto error;
}
+ if (src->ncryptos != dst->ncryptos) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target domain crypto device count %zu "
+ "does not match source %zu"), dst->ncryptos,
src->ncryptos);
+ goto error;
+ }
+
+ for (i = 0; i < src->ncryptos; i++)
+ if (!virDomainCryptoDefCheckABIStability(src->cryptos[i],
dst->cryptos[i]))
+ goto error;
+
/* Coverity is not very happy with this - all dead_error_condition */
#if !STATIC_ANALYSIS
/* This switch statement is here to trigger compiler warning when adding
@@ -19815,6 +19974,7 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src,
case VIR_DOMAIN_DEVICE_SHMEM:
case VIR_DOMAIN_DEVICE_MEMORY:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
break;
}
#endif
@@ -22404,6 +22564,49 @@ virDomainRNGDefFree(virDomainRNGDefPtr def)
static int
+virDomainCryptoDefFormat(virBufferPtr buf,
+ virDomainCryptoDefPtr def,
+ unsigned int flags)
+{
+ const char *model = virDomainCryptoModelTypeToString(def->model);
+ const char *backend = virDomainCryptoBackendTypeToString(def->backend);
+
+ virBufferAsprintf(buf, "<crypto model='%s'>\n", model);
+ virBufferAdjustIndent(buf, 2);
+ virBufferAsprintf(buf, "<backend type='%s'", backend);
+
+ switch ((virDomainCryptoBackend) def->backend) {
+ case VIR_DOMAIN_CRYPTO_BACKEND_BUILTIN:
+ if (def->queues)
+ virBufferAsprintf(buf, " queues='%u'", def->queues);
+
+ virBufferAddLit(buf, "/>\n");
+ break;
+
+ case VIR_DOMAIN_CRYPTO_BACKEND_LAST:
+ break;
+ }
+
+ if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+ return -1;
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</crypto>\n");
+ return 0;
+}
+
+void
+virDomainCryptoDefFree(virDomainCryptoDefPtr def)
+{
+ if (!def)
+ return;
+
+ virDomainDeviceInfoClear(&def->info);
+ VIR_FREE(def);
+}
+
+
+static int
virDomainMemorySourceDefFormat(virBufferPtr buf,
virDomainMemoryDefPtr def)
{
@@ -24292,6 +24495,11 @@ virDomainDefFormatInternal(virDomainDefPtr def,
goto error;
}
+ for (n = 0; n < def->ncryptos; n++) {
+ if (virDomainCryptoDefFormat(buf, def->cryptos[n], flags))
+ goto error;
+ }
+
if (def->iommu) {
virBufferAsprintf(buf, "<iommu model='%s'/>\n",
virDomainIOMMUModelTypeToString(def->iommu->model));
@@ -25413,6 +25621,9 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
case VIR_DOMAIN_DEVICE_SHMEM:
rc = virDomainShmemDefFormat(&buf, src->data.shmem, flags);
break;
+ case VIR_DOMAIN_DEVICE_CRYPTO:
+ rc = virDomainCryptoDefFormat(&buf, src->data.crypto, flags);
+ break;
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_SMARTCARD:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 78a3db4..d0c7ba1 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -154,6 +154,9 @@ typedef virDomainTPMDef *virDomainTPMDefPtr;
typedef struct _virDomainIOMMUDef virDomainIOMMUDef;
typedef virDomainIOMMUDef *virDomainIOMMUDefPtr;
+typedef struct _virDomainCryptoDef virDomainCryptoDef;
+typedef virDomainCryptoDef *virDomainCryptoDefPtr;
+
/* Flags for the 'type' field in virDomainDeviceDef */
typedef enum {
VIR_DOMAIN_DEVICE_NONE = 0,
@@ -180,6 +183,7 @@ typedef enum {
VIR_DOMAIN_DEVICE_PANIC,
VIR_DOMAIN_DEVICE_MEMORY,
VIR_DOMAIN_DEVICE_IOMMU,
+ VIR_DOMAIN_DEVICE_CRYPTO,
VIR_DOMAIN_DEVICE_LAST
} virDomainDeviceType;
@@ -212,6 +216,7 @@ struct _virDomainDeviceDef {
virDomainPanicDefPtr panic;
virDomainMemoryDefPtr memory;
virDomainIOMMUDefPtr iommu;
+ virDomainCryptoDefPtr crypto;
} data;
};
@@ -1976,6 +1981,26 @@ struct _virDomainRNGDef {
};
typedef enum {
+ VIR_DOMAIN_CRYPTO_MODEL_VIRTIO,
+
+ VIR_DOMAIN_CRYPTO_MODEL_LAST
+} virDomainCryptoModel;
+
+typedef enum {
+ VIR_DOMAIN_CRYPTO_BACKEND_BUILTIN,
+
+ VIR_DOMAIN_CRYPTO_BACKEND_LAST
+} virDomainCryptoBackend;
+
+struct _virDomainCryptoDef {
+ int model;
+ int backend;
+ unsigned int queues; /* Multiqueue virtio-crypto */
+
+ virDomainDeviceInfo info;
+};
+
+typedef enum {
VIR_DOMAIN_MEMORY_MODEL_NONE,
VIR_DOMAIN_MEMORY_MODEL_DIMM, /* dimm hotpluggable memory device */
@@ -2294,6 +2319,9 @@ struct _virDomainDef {
size_t npanics;
virDomainPanicDefPtr *panics;
+ size_t ncryptos;
+ virDomainCryptoDefPtr *cryptos;
+
/* Only 1 */
virDomainWatchdogDefPtr watchdog;
virDomainMemballoonDefPtr memballoon;
@@ -2801,6 +2829,8 @@ int virDomainDefCompatibleDevice(virDomainDefPtr def,
void virDomainRNGDefFree(virDomainRNGDefPtr def);
+void virDomainCryptoDefFree(virDomainCryptoDefPtr def);
+
int virDomainDiskIndexByAddress(virDomainDefPtr def,
virPCIDeviceAddressPtr pci_controller,
unsigned int bus, unsigned int target,
@@ -3116,6 +3146,8 @@ VIR_ENUM_DECL(virDomainMemoryModel)
VIR_ENUM_DECL(virDomainMemoryBackingModel)
VIR_ENUM_DECL(virDomainIOMMUModel)
VIR_ENUM_DECL(virDomainShmemModel)
+VIR_ENUM_DECL(virDomainCryptoModel)
+VIR_ENUM_DECL(virDomainCryptoBackend)
/* from libvirt.h */
VIR_ENUM_DECL(virDomainState)
VIR_ENUM_DECL(virDomainNostateReason)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4d16620..cceb576 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -228,6 +228,8 @@ virDomainControllerRemove;
virDomainControllerTypeToString;
virDomainCpuPlacementModeTypeFromString;
virDomainCpuPlacementModeTypeToString;
+virDomainCryptoBackendTypeFromString;
+virDomainCryptoModelTypeFromString;
virDomainDefAddController;
virDomainDefAddImplicitDevices;
virDomainDefAddUSBController;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b26c02b..6eec915 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7581,6 +7581,7 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED,
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_MEMORY:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unexpected device type %d"),
@@ -7717,6 +7718,7 @@ qemuDomainDetachDeviceUnlink(virQEMUDriverPtr driver,
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_MEMORY:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unexpected device type %d"),
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index d2f7953..e17476a 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -784,6 +784,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
case VIR_DOMAIN_DEVICE_LEASE:
case VIR_DOMAIN_DEVICE_GRAPHICS:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
case VIR_DOMAIN_DEVICE_NONE:
return 0;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 42f9889..1807c5f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7653,6 +7653,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("live attach of device '%s' is not
supported"),
@@ -7746,6 +7747,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("live detach of device '%s' is not
supported"),
@@ -7862,6 +7864,7 @@ qemuDomainUpdateDeviceLive(virConnectPtr conn,
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("live update of device '%s' is not
supported"),
@@ -8037,6 +8040,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("persistent attach of device '%s' is not
supported"),
@@ -8203,6 +8207,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("persistent detach of device '%s' is not
supported"),
@@ -8290,6 +8295,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
+ 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 f2e9846..a818775 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4244,6 +4244,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("don't know how to remove a %s device"),
--
1.8.3.1