]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: Add Intel TDX Quote Generation Service(QGS) support
authorZhenzhong Duan <zhenzhong.duan@intel.com>
Thu, 10 Jul 2025 07:21:16 +0000 (03:21 -0400)
committerDaniel P. Berrangé <berrange@redhat.com>
Fri, 25 Jul 2025 10:36:10 +0000 (11:36 +0100)
Add element "quoteGenerationService" to tdx launch security type.
It contains only an optional unix socket address attribute,
when omitted, libvirt will use default QGS server address
"/var/run/tdx-qgs/qgs.socket".

UNIX sockets offer the required functionality with greater
security than vsock, so libvirt only provides support for unix
socket.

XML example:

  <launchSecurity type='tdx'>
    <policy>0x10000001</policy>
    <mrConfigId>xxx</mrConfigId>
    <mrOwner>xxx</mrOwner>
    <mrOwnerConfig>xxx</mrOwnerConfig>
    <quoteGenerationService path='/var/run/tdx-qgs/qgs.socket'/>
  </launchSecurity>

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/schemas/domaincommon.rng

index 37d9e2bf72a9a150f10757af97faf5f5be3489c9..59958c2f08dfe50151cf68d692c96d3435ed1f49 100644 (file)
@@ -3963,6 +3963,7 @@ virDomainSecDefFree(virDomainSecDef *def)
         g_free(def->data.tdx.mrconfigid);
         g_free(def->data.tdx.mrowner);
         g_free(def->data.tdx.mrownerconfig);
+        g_free(def->data.tdx.qgs_unix_path);
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
@@ -14173,6 +14174,33 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def,
 }
 
 
+static int
+virDomainTDXQGSDefParseXML(virDomainTDXDef *def, xmlXPathContextPtr ctxt)
+{
+    g_autofree xmlNodePtr *nodes = NULL;
+    xmlNodePtr node;
+    int n;
+
+    if ((n = virXPathNodeSet("./quoteGenerationService", ctxt, &nodes)) < 0)
+        return -1;
+
+    if (!n)
+        return 0;
+
+    if (n > 1) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("only a single QGS element is supported"));
+        return -1;
+    }
+    node = nodes[0];
+
+    def->haveQGS = true;
+    def->qgs_unix_path = virXMLPropString(node, "path");
+
+    return 0;
+}
+
+
 static int
 virDomainTDXDefParseXML(virDomainTDXDef *def,
                         xmlXPathContextPtr ctxt)
@@ -14192,7 +14220,7 @@ virDomainTDXDefParseXML(virDomainTDXDef *def,
     def->mrowner = virXPathString("string(./mrOwner)", ctxt);
     def->mrownerconfig = virXPathString("string(./mrOwnerConfig)", ctxt);
 
-    return 0;
+    return virDomainTDXQGSDefParseXML(def, ctxt);
 }
 
 
@@ -27705,6 +27733,11 @@ virDomainTDXDefFormat(virBuffer *childBuf, virDomainTDXDef *def)
     virBufferEscapeString(childBuf, "<mrConfigId>%s</mrConfigId>\n", def->mrconfigid);
     virBufferEscapeString(childBuf, "<mrOwner>%s</mrOwner>\n", def->mrowner);
     virBufferEscapeString(childBuf, "<mrOwnerConfig>%s</mrOwnerConfig>\n", def->mrownerconfig);
+    if (def->haveQGS) {
+        virBufferAddLit(childBuf, "<quoteGenerationService");
+        virBufferEscapeString(childBuf, " path='%s'", def->qgs_unix_path);
+        virBufferAddLit(childBuf, "/>\n");
+    }
 }
 
 
index 46fea544c4b4a07623057cb18d6115d6610366ae..c2111597a9d93b34cd3a284468d109d936140ba4 100644 (file)
@@ -3006,6 +3006,8 @@ struct _virDomainTDXDef {
     char *mrconfigid;
     char *mrowner;
     char *mrownerconfig;
+    bool haveQGS;
+    char *qgs_unix_path;
 };
 
 
index bb40e1d439394c767380373916e9ca04c520c76d..a714c3fcc5717e4b19cb38ae56bc1759a7ccbe73 100644 (file)
           <data type="string"/>
         </element>
       </optional>
+      <optional>
+        <element name="quoteGenerationService">
+          <optional>
+            <attribute name="path">
+              <ref name="absFilePath"/>
+            </attribute>
+          </optional>
+        </element>
+      </optional>
     </interleave>
   </define>