On Fri, Jun 18, 2021 at 16:50:48 +0800, Zhenzhong Duan wrote:
The TrustDomain element can be used to define the security model to
use when launching a domain. Only type 'tdx' is supported currently.
When 'tdx' is used, the VM will launched with Intel TDX feature enabled.
TDX feature supports running encrypted VM (Trust Domain, TD) under the
control of KVM. A TD runs in a CPU model which protects the
confidentiality of its memory and its CPU state from other software
There is a child element 'policy' in TrustDomain. In 'policy', bit 0
is used to enable TDX debug, other bits are reserved currently.
For example:
<TrustDomain type='tdx'>
<policy>0x0001</policy>
</TrustDomain>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan(a)intel.com>
---
docs/schemas/domaincommon.rng | 16 ++++
src/conf/domain_conf.c | 84 +++++++++++++++++++
src/conf/domain_conf.h | 15 ++++
src/conf/virconftypes.h | 2 +
src/qemu/qemu_validate.c | 8 ++
.../genericxml2xmlindata/trust-domain-tdx.xml | 21 +++++
tests/genericxml2xmltest.c | 1 +
7 files changed, 147 insertions(+)
create mode 100644 tests/genericxml2xmlindata/trust-domain-tdx.xml
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 5ea14b6dbf..2b39a01e84 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -89,6 +89,9 @@
<optional>
<ref name="launchSecurity"/>
</optional>
+ <optional>
+ <ref name="TrustDomain"/>
All our RNG schema entries ...
+ </optional>
<optional>
<ref name="bhyvecmdline"/>
</optional>
@@ -518,6 +521,19 @@
</element>
</define>
+ <define name="TrustDomain">
+ <element name="TrustDomain">
+ <attribute name="type">
+ <value>tdx</value>
+ </attribute>
+ <interleave>
+ <element name="policy">
+ <ref name="hexuint"/>
+ </element>
+ </interleave>
+ </element>
+ </define>
+
<!--
Enable or disable perf events for the domain. For each
of the events the following rules apply:
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 139cdfc0a7..a51db088c1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1403,6 +1403,12 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
"sev",
);
+VIR_ENUM_IMPL(virDomainTrustDomain,
+ VIR_DOMAIN_TRUST_DOMAIN_LAST,
+ "",
+ "tdx",
+);
+
static virClass *virDomainObjClass;
static virClass *virDomainXMLOptionClass;
static void virDomainObjDispose(void *obj);
[...]
@@ -14793,6 +14810,53 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode,
return NULL;
}
+static virDomainTDXDef *
+virDomainTDXDefParseXML(xmlNodePtr tdxNode,
+ xmlXPathContextPtr ctxt)
+{
+ VIR_XPATH_NODE_AUTORESTORE(ctxt)
+ virDomainTDXDef *def;
+ unsigned long policy;
+ g_autofree char *type = NULL;
+
+ def = g_new0(virDomainTDXDef, 1);
+
+ ctxt->node = tdxNode;
+
+ if (!(type = virXMLPropString(tdxNode, "type"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing trust domain type"));
+ goto error;
+ }
+
+ def->sectype = virDomainTrustDomainTypeFromString(type);
+ switch ((virDomainTrustDomain) def->sectype) {
+ case VIR_DOMAIN_TRUST_DOMAIN_TDX:
+ break;
+ case VIR_DOMAIN_TRUST_DOMAIN_NONE:
+ case VIR_DOMAIN_TRUST_DOMAIN_LAST:
+ default:
+ virReportError(VIR_ERR_XML_ERROR,
+ _("unsupported trust domain type '%s'"),
+ type);
+ goto error;
+ }
+
+ if (virXPathULongHex("string(./policy)", ctxt, &policy) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("failed to get trust domain policy"));
+ goto error;
+ }
+
+ def->policy = policy;
+
+ return def;
+
+ error:
+ virDomainTDXDefFree(def);
If you register an autoptr cleanup function for this type you'll be able
to avoid the whole 'error' label.
+ return NULL;
+}
[...]
@@ -26870,6 +26941,18 @@ virDomainSEVDefFormat(virBuffer *buf,
virDomainSEVDef *sev)
virBufferAddLit(buf, "</launchSecurity>\n");
}
+static void
+virDomainTDXDefFormat(virBuffer *buf, virDomainTDXDef *tdx)
+{
+ if (!tdx)
+ return;
+
+ virBufferAsprintf(buf, "<TrustDomain type='tdx'>\n");
... as well as XML element names don't start with capital letter, so
this one shouldn't either.
+ virBufferAdjustIndent(buf, 2);
+ virBufferAsprintf(buf, "<policy>0x%04x</policy>\n",
tdx->policy);
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</TrustDomain>\n");
+}
static void
[...]
virDomainPerfDefFormat(virBuffer *buf, virDomainPerfDef *perf)
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index b21068486e..dbd2eb984c 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -202,6 +202,8 @@ typedef struct _virDomainResourceDef virDomainResourceDef;
typedef struct _virDomainSEVDef virDomainSEVDef;
+typedef struct _virDomainTDXDef virDomainTDXDef;
+
Plase don't mix generic (conf/) changes ...
typedef struct _virDomainShmemDef virDomainShmemDef;
typedef struct _virDomainSmartcardDef virDomainSmartcardDef;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 382473d03b..2efd011cc0 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1222,6 +1222,14 @@ qemuValidateDomainDef(const virDomainDef *def,
return -1;
}
+ if (def->tdx &&
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("TDX trust domain is not supported with "
+ "this QEMU binary"));
+ return -1;
+ }
... with targetted qemu changes like this.
+
if (def->naudios > 1 &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_AUDIODEV)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
[...]