377 lines
13 KiB
Diff
377 lines
13 KiB
Diff
From c7f940ba807d0d4883adb9a110839bea704278e2 Mon Sep 17 00:00:00 2001
|
|
Message-ID: <c7f940ba807d0d4883adb9a110839bea704278e2.1759908360.git.jdenemar@redhat.com>
|
|
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
|
Date: Thu, 10 Jul 2025 03:21:09 -0400
|
|
Subject: [PATCH] conf: Add tdx as launch security type
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
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>
|
|
(cherry picked from commit e919a4dd374535511d962bee2cd64f22f1ac3fa1)
|
|
Resolves: https://issues.redhat.com/browse/RHEL-111863
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.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 25e42ebfc6..f10976c2b0 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 662d6299f8..5a52014c23 100644
|
|
--- a/src/qemu/qemu_command.c
|
|
+++ b/src/qemu/qemu_command.c
|
|
@@ -7189,6 +7189,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:
|
|
@@ -9968,6 +9969,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 4dbd5ec2fc..514fc372ac 100644
|
|
--- a/src/qemu/qemu_driver.c
|
|
+++ b/src/qemu/qemu_driver.c
|
|
@@ -19273,6 +19273,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.51.0
|