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.d...@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 c724638180..458852854b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1538,6 +1538,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity, "sev", "sev-snp", "s390-pv", + "tdx", ); VIR_ENUM_IMPL(virDomainPstoreBackend, @@ -3949,6 +3950,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: @@ -14174,6 +14180,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) @@ -14197,6 +14226,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: @@ -27597,6 +27630,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) { @@ -27618,6 +27663,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 8dfadbb98d..f838f39aee 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2956,6 +2956,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; @@ -2990,11 +2991,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 d0d4bc0bf4..1902a0544a 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1934,6 +1934,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 5597d5a66b..4581a7288d 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 c70437bc05..3f8b6a801a 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 e6d308534f..7b788cdd30 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7040,6 +7040,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: @@ -9805,6 +9806,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 6ce949dd07..10e8700d08 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -19268,6 +19268,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 015a98d035..870b089024 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6999,6 +6999,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: @@ -7071,6 +7072,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 b2c3c9e2f6..52d688fe34 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