From: Akio Kakuno <fj333...@aa.jp.fujitsu.com> - Add ARM CCA support in domain schema files.
Signed-off-by: Kazuhiro Abe <fj107...@aa.jp.fujitsu.com> --- src/conf/schemas/domaincaps.rng | 36 ++++++++++ src/conf/schemas/domaincommon.rng | 26 +++++++ src/qemu/qemu_capabilities.c | 113 ++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 3 + 4 files changed, 178 insertions(+) diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng index 595dbcd634..d8f88d20c3 100644 --- a/src/conf/schemas/domaincaps.rng +++ b/src/conf/schemas/domaincaps.rng @@ -363,6 +363,9 @@ <optional> <ref name="sgx"/> </optional> + <optional> + <ref name="cca"/> + </optional> <optional> <ref name="hyperv"/> </optional> @@ -486,6 +489,39 @@ </element> </define> + <define name="cca"> + <element name="cca"> + <ref name="supported"/> + <interleave> + <optional> + <attribute name="measurement-log"> + <ref name="virYesNo"/> + </attribute> + </optional> + <optional> + <element name="enum"> + <attribute name="name"> + <value>measurement-algo</value> + </attribute> + <group> + <element name="value"> + <value>sha256</value> + </element> + <element name="value"> + <value>sha512</value> + </element> + </group> + </element> + </optional> + <optional> + <element name="personalization-value"> + <text/> + </element> + </optional> + </interleave> + </element> + </define> + <define name="hyperv"> <element name="hyperv"> <ref name="supported"/> diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 5597d5a66b..50889297df 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -549,6 +549,9 @@ <value>s390-pv</value> </attribute> </group> + <group> + <ref name="launchSecurityCCA"/> + </group> </choice> </element> </define> @@ -644,6 +647,29 @@ </optional> </interleave> </define> + + <define name="launchSecurityCCA"> + <attribute name="type"> + <value>cca</value> + </attribute> + <interleave> + <optional> + <attribute name="measurement-log"> + <ref name="virYesNo"/> + </attribute> + </optional> + <optional> + <element name="measurement-algo"> + <data type="string"/> + </element> + </optional> + <optional> + <element name="personalization-value"> + <data type="string"/> + </element> + </optional> + </interleave> + </define> <!-- Enable or disable perf events for the domain. For each of the events the following rules apply: diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 8805e4a741..e6419f05af 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1970,6 +1970,34 @@ virQEMUCapsSGXInfoCopy(virSGXCapability **dst, } +static void +virQEMUCapsCCAInfoCopy(virCCACapability **dst, + virCCACapability *src) +{ + g_autoptr(virCCACapability) tmp = NULL; + size_t i; + + if (!src) { + *dst = NULL; + return; + } + + tmp = g_new0(virCCACapability, 1); + + tmp->nCcaMeasurementAlgo = src->nCcaMeasurementAlgo; + + if (tmp->nCcaMeasurementAlgo != 0) { + tmp->ccaMeasurementAlgo = g_new0(char *, tmp->nCcaMeasurementAlgo); + + for (i = 0; i < tmp->nCcaMeasurementAlgo; i++) { + tmp->ccaMeasurementAlgo[i] = g_strdup(src->ccaMeasurementAlgo[i]); + } + } + + *dst = g_steal_pointer(&tmp); +} + + static void virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccel *dst, virQEMUCapsAccel *src) @@ -2045,6 +2073,9 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps) if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC)) virQEMUCapsSGXInfoCopy(&ret->sgxCapabilities, qemuCaps->sgxCapabilities); + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCA_GUEST)) + virQEMUCapsCCAInfoCopy(&ret->ccaCapabilities, qemuCaps->ccaCapabilities); + ret->hypervCapabilities = g_memdup(qemuCaps->hypervCapabilities, sizeof(virDomainCapsFeatureHyperv)); @@ -2686,6 +2717,13 @@ virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps) } +virCCACapability * +virQEMUCapsGetCCACapabilities(virQEMUCaps *qemuCaps) +{ + return qemuCaps->ccaCapabilities; +} + + static int virQEMUCapsProbeQMPObjectTypes(virQEMUCaps *qemuCaps, qemuMonitor *mon) @@ -4572,6 +4610,38 @@ virQEMUCapsParseSGXInfo(virQEMUCaps *qemuCaps, } +static int +virQEMUCapsParseCCAInfo(virQEMUCaps *qemuCaps, + xmlXPathContextPtr ctxt) +{ + g_autofree xmlNodePtr *nodes = NULL; + size_t i; + int n; + + if ((n = virXPathNodeSet("./cca", ctxt, &nodes)) < 0) + return -1; + + if (n > 0) { + g_autoptr(virCCACapability) tmp = g_new0(virCCACapability, 1); + tmp->ccaMeasurementAlgo = g_new0(char *, n); + + for (i = 0; i < n; i++) { + char *malgo = NULL; + if (!(malgo = virXMLPropString(nodes[i], "measurement-algo"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing CCA measurement-algo in QEMU capabilities cache")); + return -1; + } + + tmp->ccaMeasurementAlgo[i] = g_strdup(malgo); + } + tmp->nCcaMeasurementAlgo = n; + qemuCaps->ccaCapabilities = g_steal_pointer(&tmp); + } + return 0; +} + + static int virQEMUCapsParseHypervCapabilities(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt) @@ -4892,6 +4962,9 @@ virQEMUCapsLoadCache(virArch hostArch, if (virQEMUCapsParseSGXInfo(qemuCaps, ctxt) < 0) return -1; + if (virQEMUCapsParseCCAInfo(qemuCaps, ctxt) < 0) + return -1; + if (virQEMUCapsParseHypervCapabilities(qemuCaps, ctxt) < 0) return -1; @@ -5132,6 +5205,23 @@ virQEMUCapsFormatSGXInfo(virQEMUCaps *qemuCaps, } +static void +virQEMUCapsFormatCCAInfo(virQEMUCaps *qemuCaps, virBuffer *buf) +{ + virCCACapability *cca = virQEMUCapsGetCCACapabilities(qemuCaps); + size_t i; + size_t n; + + n = cca->nCcaMeasurementAlgo; + + if (n != 0) { + for (i = 0; i < n; i++) { + virBufferAsprintf(buf, "<cca measurement-algo='%s'/>\n", cca->ccaMeasurementAlgo[i]); + } + } +} + + static void virQEMUCapsFormatHypervCapabilities(virQEMUCaps *qemuCaps, virBuffer *buf) @@ -5240,6 +5330,9 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps) if (qemuCaps->sgxCapabilities) virQEMUCapsFormatSGXInfo(qemuCaps, &buf); + if (qemuCaps->ccaCapabilities) + virQEMUCapsFormatCCAInfo(qemuCaps, &buf); + if (qemuCaps->hypervCapabilities) virQEMUCapsFormatHypervCapabilities(qemuCaps, &buf); @@ -6763,6 +6856,8 @@ virQEMUCapsFillDomainLaunchSecurity(virQEMUCaps *qemuCaps, if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_S390_PV_GUEST) && virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT)) VIR_DOMAIN_CAPS_ENUM_SET(launchSecurity->sectype, VIR_DOMAIN_LAUNCH_SECURITY_PV); + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCA_GUEST)) + VIR_DOMAIN_CAPS_ENUM_SET(launchSecurity->sectype, VIR_DOMAIN_LAUNCH_SECURITY_CCA); if (launchSecurity->sectype.values == 0) { launchSecurity->supported = VIR_TRISTATE_BOOL_NO; @@ -6960,6 +7055,23 @@ virQEMUCapsFillDomainFeatureSGXCaps(virQEMUCaps *qemuCaps, } +/** + * virQEMUCapsFillDomainFeatureCCACaps: + * @qemuCaps: QEMU capabilities + * @domCaps: domain capabilities + * + * Take the information about CCA capabilities that has been obtained + * using the 'query-cca-capabilities' QMP command and stored in @qemuCaps + * and convert it to a form suitable for @domCaps. + */ +static void +virQEMUCapsFillDomainFeatureCCACaps(virQEMUCaps *qemuCaps, + virDomainCaps *domCaps) +{ + virQEMUCapsCCAInfoCopy(&domCaps->cca, qemuCaps->ccaCapabilities); +} + + static void virQEMUCapsFillDomainFeatureHypervCaps(virQEMUCaps *qemuCaps, virDomainCaps *domCaps) @@ -7031,6 +7143,7 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg, virQEMUCapsFillDomainFeatureS390PVCaps(qemuCaps, domCaps); virQEMUCapsFillDomainFeaturePS2Caps(qemuCaps, domCaps); virQEMUCapsFillDomainFeatureSGXCaps(qemuCaps, domCaps); + virQEMUCapsFillDomainFeatureCCACaps(qemuCaps, domCaps); virQEMUCapsFillDomainFeatureHypervCaps(qemuCaps, domCaps); virQEMUCapsFillDomainDeviceCryptoCaps(qemuCaps, crypto); virQEMUCapsFillDomainLaunchSecurity(qemuCaps, launchSecurity); diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 90ba9a2eed..e517368351 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -940,6 +940,9 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps); virSGXCapability * virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps); +virCCACapability * +virQEMUCapsGetCCACapabilities(virQEMUCaps *qemuCaps); + bool virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) ATTRIBUTE_MOCKABLE; -- 2.43.5