- Add ARM CCA support in domain schema files. Signed-off-by: Akio Kakuno <fj3333bs@xxxxxxxxxxx> --- src/conf/domain_conf.c | 9 +++ src/conf/schemas/domaincaps.rng | 14 ++++ src/conf/schemas/domaincommon.rng | 14 ++++ src/qemu/qemu_capabilities.c | 113 ++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 3 + 5 files changed, 153 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 231073e472..91cc8a5869 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -13883,6 +13883,14 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def, } +static void +virDomainCCADefParseXML(virDomainCCADef *def, + xmlXPathContextPtr ctxt) +{ + def->measurement_algo = virXPathString("string(./measurement-algo)", ctxt); +} + + static virDomainSecDef * virDomainSecDefParseXML(xmlNodePtr lsecNode, xmlXPathContextPtr ctxt) @@ -13909,6 +13917,7 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode, case VIR_DOMAIN_LAUNCH_SECURITY_PV: break; case VIR_DOMAIN_LAUNCH_SECURITY_CCA: + virDomainCCADefParseXML(&sec->data.cca, ctxt); break; case VIR_DOMAIN_LAUNCH_SECURITY_NONE: case VIR_DOMAIN_LAUNCH_SECURITY_LAST: diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng index 3559d2ae05..4826900258 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> @@ -481,6 +484,17 @@ </element> </define> + <define name="cca"> + <element name="cca"> + <ref name="supported"/> + <optional> + <element name="measurement-algo"> + <text/> + </element> + </optional> + </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 7121519ca3..b340381295 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -528,6 +528,9 @@ <value>s390-pv</value> </attribute> </group> + <group> + <ref name="launchSecurityCCA"/> + </group> </choice> </element> </define> @@ -623,6 +626,17 @@ </optional> </interleave> </define> + + <define name="launchSecurityCCA"> + <attribute name="type"> + <value>cca</value> + </attribute> + <optional> + <element name="measurement-algo"> + <data type="string"/> + </element> + </optional> + </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 4534f18a24..523fe05289 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1962,6 +1962,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) @@ -2037,6 +2065,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)); @@ -2678,6 +2709,13 @@ virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps) } +virCCACapability * +virQEMUCapsGetCCACapabilities(virQEMUCaps *qemuCaps) +{ + return qemuCaps->ccaCapabilities; +} + + static int virQEMUCapsProbeQMPObjectTypes(virQEMUCaps *qemuCaps, qemuMonitor *mon) @@ -4563,6 +4601,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) @@ -4883,6 +4953,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; @@ -5123,6 +5196,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) @@ -5231,6 +5321,9 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps) if (qemuCaps->sgxCapabilities) virQEMUCapsFormatSGXInfo(qemuCaps, &buf); + if (qemuCaps->ccaCapabilities) + virQEMUCapsFormatCCAInfo(qemuCaps, &buf); + if (qemuCaps->hypervCapabilities) virQEMUCapsFormatHypervCapabilities(qemuCaps, &buf); @@ -6757,6 +6850,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; @@ -6954,6 +7049,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) @@ -7024,6 +7136,7 @@ virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps, 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 21081d5fbc..effee475f6 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -931,6 +931,9 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps); virSGXCapability * virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps); +virCCACapability * +virQEMUCapsGetCCACapabilities(virQEMUCaps *qemuCaps); + bool virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_NO_INLINE; -- 2.34.1