[PATCH v3 07/21] conf: Add tdx as launch security type

Zhenzhong Duan posted 21 patches 5 months, 2 weeks ago
There is a newer version of this series
[PATCH v3 07/21] conf: Add tdx as launch security type
Posted by Zhenzhong Duan 5 months, 2 weeks ago
When 'tdx' is used, the VM will be 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 are four optional child elements. Element policy is 64bit hex, bit 0
is set to enable TDX debug, bit 28 is set to enable sept-ve-disable, other
bits are reserved currently. When policy isn't specified, QEMU will use its
own default value 0x10000000. mrConfigId, mrOwner and mrOwnerConfig are
base64 encoded SHA384 digest string.

For example:

 <launchSecurity type='tdx'>
   <policy>0x10000001</policy>
   <mrConfigId>xxx</mrConfigId>
   <mrOwner>xxx</mrOwner>
   <mrOwnerConfig>xxx</mrOwnerConfig>
 </launchSecurity>

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
---
 src/conf/domain_conf.c            | 49 +++++++++++++++++++++++++++++++
 src/conf/domain_conf.h            | 11 +++++++
 src/conf/domain_validate.c        |  1 +
 src/conf/schemas/domaincommon.rng | 32 ++++++++++++++++++++
 src/conf/virconftypes.h           |  2 ++
 src/qemu/qemu_cgroup.c            |  1 +
 src/qemu/qemu_command.c           |  2 ++
 src/qemu/qemu_driver.c            |  1 +
 src/qemu/qemu_firmware.c          |  1 +
 src/qemu/qemu_namespace.c         |  1 +
 src/qemu/qemu_process.c           |  2 ++
 src/qemu/qemu_validate.c          |  1 +
 src/security/security_dac.c       |  2 ++
 13 files changed, 106 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1e24e41a48..d2f01a9397 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1543,6 +1543,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
               "sev",
               "sev-snp",
               "s390-pv",
+              "tdx",
 );
 
 VIR_ENUM_IMPL(virDomainPstoreBackend,
@@ -3958,6 +3959,11 @@ virDomainSecDefFree(virDomainSecDef *def)
         g_free(def->data.sev_snp.id_auth);
         g_free(def->data.sev_snp.host_data);
         break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+        g_free(def->data.tdx.mrconfigid);
+        g_free(def->data.tdx.mrowner);
+        g_free(def->data.tdx.mrownerconfig);
+        break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -14204,6 +14210,29 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def,
 }
 
 
+static int
+virDomainTDXDefParseXML(virDomainTDXDef *def,
+                        xmlXPathContextPtr ctxt)
+{
+    int rc;
+
+    rc = virXPathULongLongBase("string(./policy)", ctxt, 16, &def->policy);
+    if (rc == 0) {
+        def->havePolicy = true;
+    } else if (rc == -2) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("failed to get launch security policy for launch security type TDX"));
+        return -1;
+    }
+
+    def->mrconfigid = virXPathString("string(./mrConfigId)", ctxt);
+    def->mrowner = virXPathString("string(./mrOwner)", ctxt);
+    def->mrownerconfig = virXPathString("string(./mrOwnerConfig)", ctxt);
+
+    return 0;
+}
+
+
 static virDomainSecDef *
 virDomainSecDefParseXML(xmlNodePtr lsecNode,
                         xmlXPathContextPtr ctxt)
@@ -14227,6 +14256,10 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
         if (virDomainSEVSNPDefParseXML(&sec->data.sev_snp, ctxt) < 0)
             return NULL;
         break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+        if (virDomainTDXDefParseXML(&sec->data.tdx, ctxt) < 0)
+            return NULL;
+        break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
@@ -27704,6 +27737,18 @@ virDomainSEVSNPDefFormat(virBuffer *attrBuf,
 }
 
 
+static void
+virDomainTDXDefFormat(virBuffer *childBuf, virDomainTDXDef *def)
+{
+    if (def->havePolicy)
+        virBufferAsprintf(childBuf, "<policy>0x%llx</policy>\n", def->policy);
+
+    virBufferEscapeString(childBuf, "<mrConfigId>%s</mrConfigId>\n", def->mrconfigid);
+    virBufferEscapeString(childBuf, "<mrOwner>%s</mrOwner>\n", def->mrowner);
+    virBufferEscapeString(childBuf, "<mrOwnerConfig>%s</mrOwnerConfig>\n", def->mrownerconfig);
+}
+
+
 static void
 virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec)
 {
@@ -27725,6 +27770,10 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec)
         virDomainSEVSNPDefFormat(&attrBuf, &childBuf, &sec->data.sev_snp);
         break;
 
+    case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+        virDomainTDXDefFormat(&childBuf, &sec->data.tdx);
+        break;
+
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
         break;
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6997cf7c09..e216c63018 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2964,6 +2964,7 @@ typedef enum {
     VIR_DOMAIN_LAUNCH_SECURITY_SEV,
     VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP,
     VIR_DOMAIN_LAUNCH_SECURITY_PV,
+    VIR_DOMAIN_LAUNCH_SECURITY_TDX,
 
     VIR_DOMAIN_LAUNCH_SECURITY_LAST,
 } virDomainLaunchSecurity;
@@ -2998,11 +2999,21 @@ struct _virDomainSEVSNPDef {
 };
 
 
+struct _virDomainTDXDef {
+    bool havePolicy;
+    unsigned long long policy;
+    char *mrconfigid;
+    char *mrowner;
+    char *mrownerconfig;
+};
+
+
 struct _virDomainSecDef {
     virDomainLaunchSecurity sectype;
     union {
         virDomainSEVDef sev;
         virDomainSEVSNPDef sev_snp;
+        virDomainTDXDef tdx;
     } data;
 };
 
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index b28af7fa56..7d68ea2478 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1936,6 +1936,7 @@ virDomainDefLaunchSecurityValidate(const virDomainDef *def)
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+    case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
         break;
     }
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 183dd5db5e..56dbddcb43 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="launchSecurityTDX"/>
+        </group>
       </choice>
     </element>
   </define>
@@ -644,6 +647,35 @@
       </optional>
     </interleave>
   </define>
+
+  <define name="launchSecurityTDX">
+    <attribute name="type">
+      <value>tdx</value>
+    </attribute>
+    <interleave>
+      <optional>
+        <element name="policy">
+          <ref name="hexuint"/>
+        </element>
+      </optional>
+      <optional>
+        <element name="mrConfigId">
+          <data type="string"/>
+        </element>
+      </optional>
+      <optional>
+        <element name="mrOwner">
+          <data type="string"/>
+        </element>
+      </optional>
+      <optional>
+        <element name="mrOwnerConfig">
+          <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/conf/virconftypes.h b/src/conf/virconftypes.h
index 8c6fcdbeaa..93fc9c9217 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -220,6 +220,8 @@ typedef struct _virDomainSEVDef virDomainSEVDef;
 
 typedef struct _virDomainSEVSNPDef virDomainSEVSNPDef;
 
+typedef struct _virDomainTDXDef virDomainTDXDef;
+
 typedef struct _virDomainSecDef virDomainSecDef;
 
 typedef struct _virDomainShmemDef virDomainShmemDef;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 48af467bf9..d6fa006a98 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -863,6 +863,7 @@ qemuSetupDevicesCgroup(virDomainObj *vm)
                 return -1;
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+        case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 202f2dfaca..363bee5c8c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7183,6 +7183,7 @@ qemuBuildMachineCommandLine(virCommand *cmd,
             }
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+        case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
             virBufferAddLit(&buf, ",confidential-guest-support=lsec0");
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
@@ -9961,6 +9962,7 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
         return qemuBuildPVCommandLine(cmd);
 
+    case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
         virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9b583ad7aa..a75e09b6de 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19279,6 +19279,7 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
             goto cleanup;
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+    case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index 2d0ec0b4fa..6c65a2751b 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -1371,6 +1371,7 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
             }
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+        case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index 59421ec9d1..f72da83929 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -665,6 +665,7 @@ qemuDomainSetupLaunchSecurity(virDomainObj *vm,
         VIR_DEBUG("Set up launch security for SEV");
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+    case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 82cab3f76e..529c65b9b0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6872,6 +6872,7 @@ qemuProcessPrepareDomain(virQEMUDriver *driver,
                 return -1;
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+        case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -6944,6 +6945,7 @@ qemuProcessPrepareLaunchSecurityGuestInput(virDomainObj *vm)
     case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP:
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+    case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
         return 0;
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 57dc4171fe..93e191dd13 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1413,6 +1413,7 @@ qemuValidateDomainDef(const virDomainDef *def,
                 return -1;
             }
             break;
+        case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
             virReportEnumRangeError(virDomainLaunchSecurity, def->sec->sectype);
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 3ecbc7277d..2f788b872a 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -2017,6 +2017,7 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr,
                 rc = -1;
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+        case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -2263,6 +2264,7 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr,
                 return -1;
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+        case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
-- 
2.34.1
Re: [PATCH v3 07/21] conf: Add tdx as launch security type
Posted by Daniel P. Berrangé via Devel 5 months, 1 week ago
On Mon, Jun 30, 2025 at 02:17:18PM +0800, Zhenzhong Duan wrote:
> When 'tdx' is used, the VM will be 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 are four optional child elements. Element policy is 64bit hex, bit 0
> is set to enable TDX debug, bit 28 is set to enable sept-ve-disable, other
> bits are reserved currently. When policy isn't specified, QEMU will use its
> own default value 0x10000000. mrConfigId, mrOwner and mrOwnerConfig are
> base64 encoded SHA384 digest string.
> 
> For example:
> 
>  <launchSecurity type='tdx'>
>    <policy>0x10000001</policy>
>    <mrConfigId>xxx</mrConfigId>
>    <mrOwner>xxx</mrOwner>
>    <mrOwnerConfig>xxx</mrOwnerConfig>
>  </launchSecurity>
> 
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> ---
>  src/conf/domain_conf.c            | 49 +++++++++++++++++++++++++++++++
>  src/conf/domain_conf.h            | 11 +++++++
>  src/conf/domain_validate.c        |  1 +
>  src/conf/schemas/domaincommon.rng | 32 ++++++++++++++++++++
>  src/conf/virconftypes.h           |  2 ++
>  src/qemu/qemu_cgroup.c            |  1 +
>  src/qemu/qemu_command.c           |  2 ++
>  src/qemu/qemu_driver.c            |  1 +
>  src/qemu/qemu_firmware.c          |  1 +
>  src/qemu/qemu_namespace.c         |  1 +
>  src/qemu/qemu_process.c           |  2 ++
>  src/qemu/qemu_validate.c          |  1 +
>  src/security/security_dac.c       |  2 ++
>  13 files changed, 106 insertions(+)


> diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
> index 2d0ec0b4fa..6c65a2751b 100644
> --- a/src/qemu/qemu_firmware.c
> +++ b/src/qemu/qemu_firmware.c
> @@ -1371,6 +1371,7 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
>              }
>              break;
>          case VIR_DOMAIN_LAUNCH_SECURITY_PV:
> +        case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
>              break;
>          case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
>          case VIR_DOMAIN_LAUNCH_SECURITY_LAST:

We need a patch in this series that updates qemuFirmwareMatchDomain
to handle TDX guests.

Currently with

  <os firmware="efi">
    <type arch="x86_64" machine="q35">hvm</type>
    <boot dev="hd"/>
  </os>

we are *not* matching the right firmware imagte

qemuFirmwareMatchDomain:1383 : Firmware '/usr/share/qemu/firmware/30-edk2-ovmf-4m-qcow2-x64-sb-enrolled.json' matches domain requirements
qemuFirmwareFillDomainModern:1743 : Found matching firmware (description path '/usr/share/qemu/firmware/30-edk2-ovmf-4m-qcow2-x64-sb-enrolled.json')
qemuFirmwareEnableFeaturesModern:1439 : decided on firmware '/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2' template '/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2'
qemuFirmwareEnableFeaturesModern:1473 : Enabling SMM feature
qemuFirmwareEnableFeaturesModern:1476 : Enabling secure loader

and so we fail to boot as SMM is incompatible with TDX, as
well as incorrectly setting up separate NVRAM.

The file we should have matched is

  /usr/share/qemu/firmware/60-edk2-ovmf-x64-inteltdx.json

Which has the right feature for TDX launch security:

    "features": [
        "enrolled-keys",
        "intel-tdx",
        "secure-boot",
        "verbose-dynamic"
    ],

there is already logic in qemu_firmware.c for SEV/SNP,
and the same design pattern should work for TDX too.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
RE: [PATCH v3 07/21] conf: Add tdx as launch security type
Posted by Duan, Zhenzhong 5 months, 1 week ago

>-----Original Message-----
>From: Daniel P. Berrangé <berrange@redhat.com>
>Subject: Re: [PATCH v3 07/21] conf: Add tdx as launch security type
>
>On Mon, Jun 30, 2025 at 02:17:18PM +0800, Zhenzhong Duan wrote:
>> When 'tdx' is used, the VM will be 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 are four optional child elements. Element policy is 64bit hex, bit 0
>> is set to enable TDX debug, bit 28 is set to enable sept-ve-disable, other
>> bits are reserved currently. When policy isn't specified, QEMU will use its
>> own default value 0x10000000. mrConfigId, mrOwner and mrOwnerConfig
>are
>> base64 encoded SHA384 digest string.
>>
>> For example:
>>
>>  <launchSecurity type='tdx'>
>>    <policy>0x10000001</policy>
>>    <mrConfigId>xxx</mrConfigId>
>>    <mrOwner>xxx</mrOwner>
>>    <mrOwnerConfig>xxx</mrOwnerConfig>
>>  </launchSecurity>
>>
>> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>> ---
>>  src/conf/domain_conf.c            | 49
>+++++++++++++++++++++++++++++++
>>  src/conf/domain_conf.h            | 11 +++++++
>>  src/conf/domain_validate.c        |  1 +
>>  src/conf/schemas/domaincommon.rng | 32 ++++++++++++++++++++
>>  src/conf/virconftypes.h           |  2 ++
>>  src/qemu/qemu_cgroup.c            |  1 +
>>  src/qemu/qemu_command.c           |  2 ++
>>  src/qemu/qemu_driver.c            |  1 +
>>  src/qemu/qemu_firmware.c          |  1 +
>>  src/qemu/qemu_namespace.c         |  1 +
>>  src/qemu/qemu_process.c           |  2 ++
>>  src/qemu/qemu_validate.c          |  1 +
>>  src/security/security_dac.c       |  2 ++
>>  13 files changed, 106 insertions(+)
>
>
>> diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
>> index 2d0ec0b4fa..6c65a2751b 100644
>> --- a/src/qemu/qemu_firmware.c
>> +++ b/src/qemu/qemu_firmware.c
>> @@ -1371,6 +1371,7 @@ qemuFirmwareMatchDomain(const
>virDomainDef *def,
>>              }
>>              break;
>>          case VIR_DOMAIN_LAUNCH_SECURITY_PV:
>> +        case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
>>              break;
>>          case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
>>          case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
>
>We need a patch in this series that updates qemuFirmwareMatchDomain
>to handle TDX guests.
>
>Currently with
>
>  <os firmware="efi">
>    <type arch="x86_64" machine="q35">hvm</type>
>    <boot dev="hd"/>
>  </os>
>
>we are *not* matching the right firmware imagte
>
>qemuFirmwareMatchDomain:1383 : Firmware
>'/usr/share/qemu/firmware/30-edk2-ovmf-4m-qcow2-x64-sb-enrolled.json'
>matches domain requirements
>qemuFirmwareFillDomainModern:1743 : Found matching firmware
>(description path
>'/usr/share/qemu/firmware/30-edk2-ovmf-4m-qcow2-x64-sb-enrolled.json')
>qemuFirmwareEnableFeaturesModern:1439 : decided on firmware
>'/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2' template
>'/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2'
>qemuFirmwareEnableFeaturesModern:1473 : Enabling SMM feature
>qemuFirmwareEnableFeaturesModern:1476 : Enabling secure loader
>
>and so we fail to boot as SMM is incompatible with TDX, as
>well as incorrectly setting up separate NVRAM.
>
>The file we should have matched is
>
>  /usr/share/qemu/firmware/60-edk2-ovmf-x64-inteltdx.json
>
>Which has the right feature for TDX launch security:
>
>    "features": [
>        "enrolled-keys",
>        "intel-tdx",
>        "secure-boot",
>        "verbose-dynamic"
>    ],
>
>there is already logic in qemu_firmware.c for SEV/SNP,
>and the same design pattern should work for TDX too.

Got it, will do.

Thanks
Zhenzhong
Re: [PATCH v3 07/21] conf: Add tdx as launch security type
Posted by Daniel P. Berrangé via Devel 5 months, 1 week ago
On Mon, Jun 30, 2025 at 02:17:18PM +0800, Zhenzhong Duan wrote:
> When 'tdx' is used, the VM will be 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 are four optional child elements. Element policy is 64bit hex, bit 0
> is set to enable TDX debug, bit 28 is set to enable sept-ve-disable, other
> bits are reserved currently. When policy isn't specified, QEMU will use its
> own default value 0x10000000. mrConfigId, mrOwner and mrOwnerConfig are
> base64 encoded SHA384 digest string.
> 
> For example:
> 
>  <launchSecurity type='tdx'>
>    <policy>0x10000001</policy>
>    <mrConfigId>xxx</mrConfigId>
>    <mrOwner>xxx</mrOwner>
>    <mrOwnerConfig>xxx</mrOwnerConfig>
>  </launchSecurity>
> 
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|