[RFC PATCH 3/7] conf: introduce TrustDomain element in domain

Zhenzhong Duan zhenzhong.duan at intel.com
Fri Jun 18 08:50:48 UTC 2021


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 at 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"/>
+        </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);
@@ -3502,6 +3508,16 @@ virDomainSEVDefFree(virDomainSEVDef *def)
     g_free(def);
 }
 
+
+static void
+virDomainTDXDefFree(virDomainTDXDef *def)
+{
+    if (!def)
+        return;
+
+    g_free(def);
+}
+
 static void
 virDomainOSDefClear(virDomainOSDef *os)
 {
@@ -3704,6 +3720,7 @@ void virDomainDefFree(virDomainDef *def)
         (def->ns.free)(def->namespaceData);
 
     virDomainSEVDefFree(def->sev);
+    virDomainTDXDefFree(def->tdx);
 
     xmlFreeNode(def->metadata);
 
@@ -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);
+    return NULL;
+}
+
 
 static virDomainMemoryDef *
 virDomainMemoryDefParseXML(virDomainXMLOption *xmlopt,
@@ -20117,6 +20181,13 @@ virDomainDefParseXML(xmlDocPtr xml,
             goto error;
     }
 
+    /* Check for TDX feature */
+    if ((node = virXPathNode("./TrustDomain", ctxt)) != NULL) {
+        def->tdx = virDomainTDXDefParseXML(node, ctxt);
+        if (!def->tdx)
+            goto error;
+    }
+
     /* analysis of memory devices */
     if ((n = virXPathNodeSet("./devices/memory", ctxt, &nodes)) < 0)
         goto error;
@@ -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");
+    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)
@@ -28277,6 +28360,7 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
         virDomainKeyWrapDefFormat(buf, def->keywrap);
 
     virDomainSEVDefFormat(buf, def->sev);
+    virDomainTDXDefFormat(buf, def->tdx);
 
     if (def->namespaceData && def->ns.format) {
         if ((def->ns.format)(buf, def->namespaceData) < 0)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index f706c498ff..7cb5061c8c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2661,6 +2661,17 @@ struct _virDomainSEVDef {
     unsigned int reduced_phys_bits;
 };
 
+typedef enum {
+    VIR_DOMAIN_TRUST_DOMAIN_NONE,
+    VIR_DOMAIN_TRUST_DOMAIN_TDX,
+
+    VIR_DOMAIN_TRUST_DOMAIN_LAST,
+} virDomainTrustDomain;
+
+struct _virDomainTDXDef {
+    int sectype; /* enum virDomainTrustDomain */
+    unsigned int policy; /* bit 0 set hint debug enabled, other bit reserved */
+};
 
 typedef enum {
     VIR_DOMAIN_IOMMU_MODEL_INTEL,
@@ -2874,6 +2885,9 @@ struct _virDomainDef {
     /* SEV-specific domain */
     virDomainSEVDef *sev;
 
+    /* TDX-specific domain */
+    virDomainTDXDef *tdx;
+
     /* Application-specific custom metadata */
     xmlNodePtr metadata;
 
@@ -3888,6 +3902,7 @@ VIR_ENUM_DECL(virDomainVsockModel);
 VIR_ENUM_DECL(virDomainShmemModel);
 VIR_ENUM_DECL(virDomainShmemRole);
 VIR_ENUM_DECL(virDomainLaunchSecurity);
+VIR_ENUM_DECL(virDomainTrustDomain);
 /* from libvirt.h */
 VIR_ENUM_DECL(virDomainState);
 VIR_ENUM_DECL(virDomainNostateReason);
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;
+
 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;
+    }
+
     if (def->naudios > 1 &&
         !virQEMUCapsGet(qemuCaps, QEMU_CAPS_AUDIODEV)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
diff --git a/tests/genericxml2xmlindata/trust-domain-tdx.xml b/tests/genericxml2xmlindata/trust-domain-tdx.xml
new file mode 100644
index 0000000000..7a56cf0e92
--- /dev/null
+++ b/tests/genericxml2xmlindata/trust-domain-tdx.xml
@@ -0,0 +1,21 @@
+<domain type='kvm'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc-1.0'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+  </devices>
+  <TrustDomain type='tdx'>
+    <policy>0x0001</policy>
+  </TrustDomain>
+</domain>
+
diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c
index ac89422a32..0bd7717953 100644
--- a/tests/genericxml2xmltest.c
+++ b/tests/genericxml2xmltest.c
@@ -233,6 +233,7 @@ mymain(void)
     DO_TEST("tseg");
 
     DO_TEST("launch-security-sev");
+    DO_TEST("trust-domain-tdx");
 
     DO_TEST_DIFFERENT("cputune");
     DO_TEST("device-backenddomain");
-- 
2.25.1




More information about the libvir-list mailing list