[RFC PATCH 0/7] LIBVIRT: X86: TDX support

* What's TDX? TDX stands for Trust Domain Extensions which isolates VMs from the virtual-machine manager (VMM)/hypervisor and any other software on the platform. To support TDX, multiple software components, not only KVM but also QEMU, guest Linux and virtual bios, need to be updated. For more details, please check link[1], there are TDX spec links and public repository link at github for each software component. This patchset is another software component to extend libvirt to support TDX, with which one can start a VM from high level rather than running qemu directly. * The goal of this RFC patch The purpose of this post is to get feedback early on high level design issue of libvirt enhancement for TDX. Referenced much on AMD SEV implemention at link[2]. * Patch organization - patch 1-2: Support query of TDX capabilities. - patch 3-6: Add a new xml element 'TrustDomain' for TDX support. - patch 7: Sure kvmSupportsSecureGuest cache updated. Using these patches we have succesfully booted and tested a guest both with and without TDX enabled. [1] https://lkml.org/lkml/2020/11/16/1106 [2] https://github.com/codomania/libvirt/commits/v9 Zhenzhong Duan (7): qemu: provide support to query the TDX capabilities conf: expose TDX feature in domain capabilities conf: introduce TrustDomain element in domain qemu: add support to launch TDX guest qemu: add support to TDVF firmware loader qemu: force special features enabled for TDX guest qemu: Check if INTEL Trust Domain Extention support is enabled docs/formatdomaincaps.html.in | 16 ++++ docs/schemas/domaincaps.rng | 9 ++ docs/schemas/domaincommon.rng | 19 ++++ src/conf/domain_capabilities.c | 22 +++++ src/conf/domain_capabilities.h | 11 +++ src/conf/domain_conf.c | 90 ++++++++++++++++++ src/conf/domain_conf.h | 16 ++++ src/conf/virconftypes.h | 2 + src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 63 ++++++++++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 39 ++++++++ src/qemu/qemu_monitor.c | 8 ++ src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 53 +++++++++++ src/qemu/qemu_monitor_json.h | 3 + src/qemu/qemu_validate.c | 14 +++ tests/domaincapsdata/bhyve_basic.x86_64.xml | 1 + tests/domaincapsdata/bhyve_fbuf.x86_64.xml | 1 + tests/domaincapsdata/bhyve_uefi.x86_64.xml | 1 + tests/domaincapsdata/empty.xml | 1 + tests/domaincapsdata/libxl-xenfv.xml | 1 + tests/domaincapsdata/libxl-xenpv.xml | 1 + .../domaincapsdata/qemu_2.11.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.11.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.11.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.11.0.x86_64.xml | 1 + .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml | 1 + .../qemu_2.12.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.12.0.x86_64.xml | 1 + .../domaincapsdata/qemu_2.4.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.4.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.4.0.x86_64.xml | 1 + .../domaincapsdata/qemu_2.5.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.5.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.5.0.x86_64.xml | 1 + .../domaincapsdata/qemu_2.6.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.6.0-tcg.x86_64.xml | 1 + .../qemu_2.6.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.6.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.6.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_2.6.0.x86_64.xml | 1 + .../domaincapsdata/qemu_2.7.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.7.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.7.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.7.0.x86_64.xml | 1 + .../domaincapsdata/qemu_2.8.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.8.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.8.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.8.0.x86_64.xml | 1 + .../domaincapsdata/qemu_2.9.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.9.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.9.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_2.9.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.9.0.x86_64.xml | 1 + .../domaincapsdata/qemu_3.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_3.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_3.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_3.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_3.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_3.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.1.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_3.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_4.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_4.0.0-tcg.x86_64.xml | 1 + .../qemu_4.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_4.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_4.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_4.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_4.2.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml | 1 + .../qemu_4.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_4.2.0.x86_64.xml | 1 + .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 1 + .../qemu_5.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.1.0.sparc.xml | 1 + tests/domaincapsdata/qemu_5.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 1 + .../qemu_5.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_5.2.0.x86_64.xml | 1 + .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_6.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.1.0.x86_64.xml | 1 + .../genericxml2xmlindata/trust-domain-tdx.xml | 22 +++++ tests/genericxml2xmltest.c | 1 + .../.trust-domain-tdx.xml.swo | Bin 0 -> 12288 bytes tests/qemuxml2argvdata/trust-domain-tdx.args | 32 +++++++ tests/qemuxml2argvdata/trust-domain-tdx.xml | 37 +++++++ tests/qemuxml2argvtest.c | 3 + 115 files changed, 557 insertions(+) create mode 100644 tests/genericxml2xmlindata/trust-domain-tdx.xml create mode 100644 tests/qemuxml2argvdata/.trust-domain-tdx.xml.swo create mode 100644 tests/qemuxml2argvdata/trust-domain-tdx.args create mode 100644 tests/qemuxml2argvdata/trust-domain-tdx.xml -- 2.25.1

QEMU provides support for launching an encrypted VMs on Intel x86 platform using Trust Domain Extension (TDX) feature. This patch adds support to query the TDX capabilities from the QEMU. Currently there is no elements in TDX capabilities except a placeholder. Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/conf/domain_capabilities.c | 8 +++++ src/conf/domain_capabilities.h | 10 +++++++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 30 +++++++++++++++++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_monitor.c | 8 +++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 53 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 ++ 9 files changed, 117 insertions(+) diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index cb90ae0176..31577095e9 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -76,6 +76,14 @@ virSEVCapabilitiesFree(virSEVCapability *cap) g_free(cap); } +void +virTDXCapabilitiesFree(virTDXCapability *cap) +{ + if (!cap) + return; + + VIR_FREE(cap); +} static void virDomainCapsDispose(void *obj) diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index b6433b20c9..e099788da9 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -173,6 +173,12 @@ struct _virSEVCapability { unsigned int reduced_phys_bits; }; +typedef struct _virTDXCapability virTDXCapability; +struct _virTDXCapability { + /* no elements for Intel TDX for now, just put a placeholder */ + uint64_t placeholder; +}; + typedef enum { VIR_DOMAIN_CAPS_FEATURE_IOTHREADS = 0, VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO, @@ -254,3 +260,7 @@ void virSEVCapabilitiesFree(virSEVCapability *capabilities); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSEVCapability, virSEVCapabilitiesFree); + +void virTDXCapabilitiesFree(virTDXCapability *capabilities); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virTDXCapability, virTDXCapabilitiesFree); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2efa787664..8cbb60b577 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -218,6 +218,7 @@ virDomainCapsEnumSet; virDomainCapsFormat; virDomainCapsNew; virSEVCapabilitiesFree; +virTDXCapabilitiesFree; # conf/domain_conf.h diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 059d6badf2..a143e453f4 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -636,6 +636,7 @@ VIR_ENUM_IMPL(virQEMUCaps, /* 405 */ "confidential-guest-support", "query-display-options", + "tdx-guest", ); @@ -716,6 +717,8 @@ struct _virQEMUCaps { virSEVCapability *sevCapabilities; + virTDXCapability *tdxCapabilities; + /* Capabilities which may differ depending on the accelerator. */ virQEMUCapsAccel kvm; virQEMUCapsAccel tcg; @@ -1354,6 +1357,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "input-linux", QEMU_CAPS_INPUT_LINUX }, { "virtio-gpu-gl-pci", QEMU_CAPS_VIRTIO_GPU_GL_PCI }, { "virtio-vga-gl", QEMU_CAPS_VIRTIO_VGA_GL }, + { "tdx-guest", QEMU_CAPS_TDX_GUEST}, }; @@ -2027,6 +2031,7 @@ void virQEMUCapsDispose(void *obj) g_free(qemuCaps->gicCapabilities); virSEVCapabilitiesFree(qemuCaps->sevCapabilities); + virTDXCapabilitiesFree(qemuCaps->tdxCapabilities); virQEMUCapsAccelClear(&qemuCaps->kvm); virQEMUCapsAccelClear(&qemuCaps->tcg); @@ -3354,6 +3359,29 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps, return 0; } +static int +virQEMUCapsProbeQMPTDXCapabilities(virQEMUCaps *qemuCaps, + qemuMonitor *mon) +{ + int rc = -1; + virTDXCapability *caps = NULL; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST)) + return 0; + + if ((rc = qemuMonitorGetTDXCapabilities(mon, &caps)) < 0) + return -1; + + /* TDX isn't actually supported */ + if (rc == 0) { + virQEMUCapsClear(qemuCaps, QEMU_CAPS_TDX_GUEST); + return 0; + } + + virTDXCapabilitiesFree(qemuCaps->tdxCapabilities); + qemuCaps->tdxCapabilities = caps; + return 0; +} /* * Filter for features which should never be passed to QEMU. Either because @@ -5316,6 +5344,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps, return -1; if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0) return -1; + if (virQEMUCapsProbeQMPTDXCapabilities(qemuCaps, mon) < 0) + return -1; virQEMUCapsInitProcessCaps(qemuCaps); diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index b2878312ac..a51bd9a256 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -616,6 +616,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ /* 405 */ QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT, /* -machine confidential-guest-support */ QEMU_CAPS_QUERY_DISPLAY_OPTIONS, /* 'query-display-options' qmp command present */ + QEMU_CAPS_TDX_GUEST, /* -object tdx-guest,... */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 8f35b4240f..f2a3badeec 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3946,6 +3946,14 @@ qemuMonitorNBDServerStart(qemuMonitor *mon, return qemuMonitorJSONNBDServerStart(mon, server, tls_alias); } +int +qemuMonitorGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities) +{ + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONGetTDXCapabilities(mon, capabilities); +} int qemuMonitorNBDServerAdd(qemuMonitor *mon, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6a25def78b..48c18c5220 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -859,6 +859,9 @@ int qemuMonitorGetGICCapabilities(qemuMonitor *mon, int qemuMonitorGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities); +int qemuMonitorGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities); + typedef enum { QEMU_MONITOR_MIGRATE_BACKGROUND = 1 << 0, QEMU_MONITOR_MIGRATE_NON_SHARED_DISK = 1 << 1, /* migration with non-shared storage with full disk copy */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 223777739d..c58152e86f 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -7028,6 +7028,59 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon, return ret; } +/** + * qemuMonitorJSONGetTDXCapabilities: + * @mon: qemu monitor object + * @capabilities: pointer to pointer to a TDX capability structure to be filled + * + * Returns -1 on error, 0 if TDX is not supported, and 1 if TDX is supported on + * the platform. + */ +int +qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities) +{ + int ret = -1; + virJSONValue *cmd; + virJSONValue *reply = NULL; + g_autoptr(virTDXCapability) capability = NULL; + + *capabilities = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("query-tdx-capabilities", + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + /* QEMU has only compiled-in support of TDX */ + if (qemuMonitorJSONHasError(reply, "GenericError")) { + ret = 0; + goto cleanup; + } + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + if (!virJSONValueObjectGetObject(reply, "return")) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-tdx-capabilities reply was missing return")); + return -1; + } + + capability = g_new0(virTDXCapability, 1); + + *capabilities = g_steal_pointer(&capability); + + ret = 1; + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + + return ret; +} + static virJSONValue * qemuMonitorJSONBuildInetSocketAddress(const char *host, const char *port) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 01a3ba25f1..3fe6a34c4c 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -157,6 +157,9 @@ int qemuMonitorJSONGetGICCapabilities(qemuMonitor *mon, int qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities); +int qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities); + int qemuMonitorJSONMigrate(qemuMonitor *mon, unsigned int flags, const char *uri); -- 2.25.1

On Fri, Jun 18, 2021 at 04:50:46PM +0800, Zhenzhong Duan wrote:
QEMU provides support for launching an encrypted VMs on Intel x86 platform using Trust Domain Extension (TDX) feature. This patch adds support to query the TDX capabilities from the QEMU.
Currently there is no elements in TDX capabilities except a placeholder.
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/conf/domain_capabilities.c | 8 +++++ src/conf/domain_capabilities.h | 10 +++++++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 30 +++++++++++++++++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_monitor.c | 8 +++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 53 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 ++ 9 files changed, 117 insertions(+)
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index cb90ae0176..31577095e9 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -76,6 +76,14 @@ virSEVCapabilitiesFree(virSEVCapability *cap) g_free(cap); }
+void +virTDXCapabilitiesFree(virTDXCapability *cap) +{ + if (!cap) + return; + + VIR_FREE(cap); +}
static void virDomainCapsDispose(void *obj) diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index b6433b20c9..e099788da9 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -173,6 +173,12 @@ struct _virSEVCapability { unsigned int reduced_phys_bits; };
+typedef struct _virTDXCapability virTDXCapability; +struct _virTDXCapability { + /* no elements for Intel TDX for now, just put a placeholder */ + uint64_t placeholder; +}; +
There is no need to add unused code into libvirt especially if the impact is only internal and it is not exposed to users. It can be added in the future if needed. Because this patch series doesn't add any TDX specific capability into this structure please drop all related code to this placeholder. Pavel
typedef enum { VIR_DOMAIN_CAPS_FEATURE_IOTHREADS = 0, VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO, @@ -254,3 +260,7 @@ void virSEVCapabilitiesFree(virSEVCapability *capabilities);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSEVCapability, virSEVCapabilitiesFree); + +void virTDXCapabilitiesFree(virTDXCapability *capabilities); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virTDXCapability, virTDXCapabilitiesFree); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2efa787664..8cbb60b577 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -218,6 +218,7 @@ virDomainCapsEnumSet; virDomainCapsFormat; virDomainCapsNew; virSEVCapabilitiesFree; +virTDXCapabilitiesFree;
# conf/domain_conf.h diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 059d6badf2..a143e453f4 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -636,6 +636,7 @@ VIR_ENUM_IMPL(virQEMUCaps, /* 405 */ "confidential-guest-support", "query-display-options", + "tdx-guest", );
@@ -716,6 +717,8 @@ struct _virQEMUCaps {
virSEVCapability *sevCapabilities;
+ virTDXCapability *tdxCapabilities; + /* Capabilities which may differ depending on the accelerator. */ virQEMUCapsAccel kvm; virQEMUCapsAccel tcg; @@ -1354,6 +1357,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "input-linux", QEMU_CAPS_INPUT_LINUX }, { "virtio-gpu-gl-pci", QEMU_CAPS_VIRTIO_GPU_GL_PCI }, { "virtio-vga-gl", QEMU_CAPS_VIRTIO_VGA_GL }, + { "tdx-guest", QEMU_CAPS_TDX_GUEST}, };
@@ -2027,6 +2031,7 @@ void virQEMUCapsDispose(void *obj) g_free(qemuCaps->gicCapabilities);
virSEVCapabilitiesFree(qemuCaps->sevCapabilities); + virTDXCapabilitiesFree(qemuCaps->tdxCapabilities);
virQEMUCapsAccelClear(&qemuCaps->kvm); virQEMUCapsAccelClear(&qemuCaps->tcg); @@ -3354,6 +3359,29 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps, return 0; }
+static int +virQEMUCapsProbeQMPTDXCapabilities(virQEMUCaps *qemuCaps, + qemuMonitor *mon) +{ + int rc = -1; + virTDXCapability *caps = NULL; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST)) + return 0; + + if ((rc = qemuMonitorGetTDXCapabilities(mon, &caps)) < 0) + return -1; + + /* TDX isn't actually supported */ + if (rc == 0) { + virQEMUCapsClear(qemuCaps, QEMU_CAPS_TDX_GUEST); + return 0; + } + + virTDXCapabilitiesFree(qemuCaps->tdxCapabilities); + qemuCaps->tdxCapabilities = caps; + return 0; +}
/* * Filter for features which should never be passed to QEMU. Either because @@ -5316,6 +5344,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps, return -1; if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0) return -1; + if (virQEMUCapsProbeQMPTDXCapabilities(qemuCaps, mon) < 0) + return -1;
virQEMUCapsInitProcessCaps(qemuCaps);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index b2878312ac..a51bd9a256 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -616,6 +616,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ /* 405 */ QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT, /* -machine confidential-guest-support */ QEMU_CAPS_QUERY_DISPLAY_OPTIONS, /* 'query-display-options' qmp command present */ + QEMU_CAPS_TDX_GUEST, /* -object tdx-guest,... */
QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 8f35b4240f..f2a3badeec 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3946,6 +3946,14 @@ qemuMonitorNBDServerStart(qemuMonitor *mon, return qemuMonitorJSONNBDServerStart(mon, server, tls_alias); }
+int +qemuMonitorGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities) +{ + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONGetTDXCapabilities(mon, capabilities); +}
int qemuMonitorNBDServerAdd(qemuMonitor *mon, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6a25def78b..48c18c5220 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -859,6 +859,9 @@ int qemuMonitorGetGICCapabilities(qemuMonitor *mon, int qemuMonitorGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities);
+int qemuMonitorGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities); + typedef enum { QEMU_MONITOR_MIGRATE_BACKGROUND = 1 << 0, QEMU_MONITOR_MIGRATE_NON_SHARED_DISK = 1 << 1, /* migration with non-shared storage with full disk copy */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 223777739d..c58152e86f 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -7028,6 +7028,59 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon, return ret; }
+/** + * qemuMonitorJSONGetTDXCapabilities: + * @mon: qemu monitor object + * @capabilities: pointer to pointer to a TDX capability structure to be filled + * + * Returns -1 on error, 0 if TDX is not supported, and 1 if TDX is supported on + * the platform. + */ +int +qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities) +{ + int ret = -1; + virJSONValue *cmd; + virJSONValue *reply = NULL; + g_autoptr(virTDXCapability) capability = NULL; + + *capabilities = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("query-tdx-capabilities", + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + /* QEMU has only compiled-in support of TDX */ + if (qemuMonitorJSONHasError(reply, "GenericError")) { + ret = 0; + goto cleanup; + } + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + if (!virJSONValueObjectGetObject(reply, "return")) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-tdx-capabilities reply was missing return")); + return -1; + } + + capability = g_new0(virTDXCapability, 1); + + *capabilities = g_steal_pointer(&capability); + + ret = 1; + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + + return ret; +} + static virJSONValue * qemuMonitorJSONBuildInetSocketAddress(const char *host, const char *port) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 01a3ba25f1..3fe6a34c4c 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -157,6 +157,9 @@ int qemuMonitorJSONGetGICCapabilities(qemuMonitor *mon, int qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities);
+int qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities); + int qemuMonitorJSONMigrate(qemuMonitor *mon, unsigned int flags, const char *uri); -- 2.25.1

-----Original Message----- From: Pavel Hrdina <phrdina@redhat.com> Sent: Friday, June 18, 2021 8:41 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 1/7] qemu: provide support to query the TDX capabilities
On Fri, Jun 18, 2021 at 04:50:46PM +0800, Zhenzhong Duan wrote:
QEMU provides support for launching an encrypted VMs on Intel x86 platform using Trust Domain Extension (TDX) feature. This patch adds support to query the TDX capabilities from the QEMU.
Currently there is no elements in TDX capabilities except a placeholder.
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/conf/domain_capabilities.c | 8 +++++ src/conf/domain_capabilities.h | 10 +++++++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 30 +++++++++++++++++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_monitor.c | 8 +++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 53 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 ++ 9 files changed, 117 insertions(+)
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index cb90ae0176..31577095e9 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -76,6 +76,14 @@ virSEVCapabilitiesFree(virSEVCapability *cap) g_free(cap); }
+void +virTDXCapabilitiesFree(virTDXCapability *cap) { + if (!cap) + return; + + VIR_FREE(cap); +}
static void virDomainCapsDispose(void *obj) diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index b6433b20c9..e099788da9 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -173,6 +173,12 @@ struct _virSEVCapability { unsigned int reduced_phys_bits; };
+typedef struct _virTDXCapability virTDXCapability; struct +_virTDXCapability { + /* no elements for Intel TDX for now, just put a placeholder */ + uint64_t placeholder; +}; +
There is no need to add unused code into libvirt especially if the impact is only internal and it is not exposed to users. It can be added in the future if needed. Because this patch series doesn't add any TDX specific capability into this structure please drop all related code to this placeholder.
Sorry, I didn't fully understand which part to preserve. Do you mean removing placeholder from struct virTDXCapability or removing virTDXCapability as it's empty? virDomainCapsFeatureTDXFormat(virTDXCapability *tdx) shows '<tdx supported='yes'/>' based on the value of tdx. If virTDXCapability is empty, tdx is always NULL and '<tdx supported='no'/>' showed. Thanks Zhenzhong
Pavel
typedef enum { VIR_DOMAIN_CAPS_FEATURE_IOTHREADS = 0, VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO, @@ -254,3 +260,7 @@ void virSEVCapabilitiesFree(virSEVCapability *capabilities);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSEVCapability, virSEVCapabilitiesFree); + +void virTDXCapabilitiesFree(virTDXCapability *capabilities); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virTDXCapability, +virTDXCapabilitiesFree); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2efa787664..8cbb60b577 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -218,6 +218,7 @@ virDomainCapsEnumSet; virDomainCapsFormat; virDomainCapsNew; virSEVCapabilitiesFree; +virTDXCapabilitiesFree;
# conf/domain_conf.h diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 059d6badf2..a143e453f4 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -636,6 +636,7 @@ VIR_ENUM_IMPL(virQEMUCaps, /* 405 */ "confidential-guest-support", "query-display-options", + "tdx-guest", );
@@ -716,6 +717,8 @@ struct _virQEMUCaps {
virSEVCapability *sevCapabilities;
+ virTDXCapability *tdxCapabilities; + /* Capabilities which may differ depending on the accelerator. */ virQEMUCapsAccel kvm; virQEMUCapsAccel tcg; @@ -1354,6 +1357,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "input-linux", QEMU_CAPS_INPUT_LINUX }, { "virtio-gpu-gl-pci", QEMU_CAPS_VIRTIO_GPU_GL_PCI }, { "virtio-vga-gl", QEMU_CAPS_VIRTIO_VGA_GL }, + { "tdx-guest", QEMU_CAPS_TDX_GUEST}, };
@@ -2027,6 +2031,7 @@ void virQEMUCapsDispose(void *obj) g_free(qemuCaps->gicCapabilities);
virSEVCapabilitiesFree(qemuCaps->sevCapabilities); + virTDXCapabilitiesFree(qemuCaps->tdxCapabilities);
virQEMUCapsAccelClear(&qemuCaps->kvm); virQEMUCapsAccelClear(&qemuCaps->tcg); @@ -3354,6 +3359,29 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps, return 0; }
+static int +virQEMUCapsProbeQMPTDXCapabilities(virQEMUCaps *qemuCaps, + qemuMonitor *mon) { + int rc = -1; + virTDXCapability *caps = NULL; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST)) + return 0; + + if ((rc = qemuMonitorGetTDXCapabilities(mon, &caps)) < 0) + return -1; + + /* TDX isn't actually supported */ + if (rc == 0) { + virQEMUCapsClear(qemuCaps, QEMU_CAPS_TDX_GUEST); + return 0; + } + + virTDXCapabilitiesFree(qemuCaps->tdxCapabilities); + qemuCaps->tdxCapabilities = caps; + return 0; +}
/* * Filter for features which should never be passed to QEMU. Either because @@ -5316,6 +5344,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps, return -1; if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0) return -1; + if (virQEMUCapsProbeQMPTDXCapabilities(qemuCaps, mon) < 0) + return -1;
virQEMUCapsInitProcessCaps(qemuCaps);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index b2878312ac..a51bd9a256 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -616,6 +616,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ /* 405 */ QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT, /* -machine confidential-guest-support */ QEMU_CAPS_QUERY_DISPLAY_OPTIONS, /* 'query-display-options' qmp command present */ + QEMU_CAPS_TDX_GUEST, /* -object tdx-guest,... */
QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 8f35b4240f..f2a3badeec 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3946,6 +3946,14 @@ qemuMonitorNBDServerStart(qemuMonitor *mon, return qemuMonitorJSONNBDServerStart(mon, server, tls_alias); }
+int +qemuMonitorGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities) { + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONGetTDXCapabilities(mon, capabilities); }
int qemuMonitorNBDServerAdd(qemuMonitor *mon, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6a25def78b..48c18c5220 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -859,6 +859,9 @@ int qemuMonitorGetGICCapabilities(qemuMonitor *mon, int qemuMonitorGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities);
+int qemuMonitorGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities); + typedef enum { QEMU_MONITOR_MIGRATE_BACKGROUND = 1 << 0, QEMU_MONITOR_MIGRATE_NON_SHARED_DISK = 1 << 1, /* migration with non-shared storage with full disk copy */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 223777739d..c58152e86f 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -7028,6 +7028,59 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon, return ret; }
+/** + * qemuMonitorJSONGetTDXCapabilities: + * @mon: qemu monitor object + * @capabilities: pointer to pointer to a TDX capability structure to +be filled + * + * Returns -1 on error, 0 if TDX is not supported, and 1 if TDX is +supported on + * the platform. + */ +int +qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities) { + int ret = -1; + virJSONValue *cmd; + virJSONValue *reply = NULL; + g_autoptr(virTDXCapability) capability = NULL; + + *capabilities = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("query-tdx-capabilities", + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + /* QEMU has only compiled-in support of TDX */ + if (qemuMonitorJSONHasError(reply, "GenericError")) { + ret = 0; + goto cleanup; + } + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + if (!virJSONValueObjectGetObject(reply, "return")) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-tdx-capabilities reply was missing return")); + return -1; + } + + capability = g_new0(virTDXCapability, 1); + + *capabilities = g_steal_pointer(&capability); + + ret = 1; + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + + return ret; +} + static virJSONValue * qemuMonitorJSONBuildInetSocketAddress(const char *host, const char *port) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 01a3ba25f1..3fe6a34c4c 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -157,6 +157,9 @@ int qemuMonitorJSONGetGICCapabilities(qemuMonitor *mon, int qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities);
+int qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability +**capabilities); + int qemuMonitorJSONMigrate(qemuMonitor *mon, unsigned int flags, const char *uri); -- 2.25.1

On Mon, Jun 21, 2021 at 06:04:15AM +0000, Duan, Zhenzhong wrote:
-----Original Message----- From: Pavel Hrdina <phrdina@redhat.com> Sent: Friday, June 18, 2021 8:41 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 1/7] qemu: provide support to query the TDX capabilities
On Fri, Jun 18, 2021 at 04:50:46PM +0800, Zhenzhong Duan wrote:
QEMU provides support for launching an encrypted VMs on Intel x86 platform using Trust Domain Extension (TDX) feature. This patch adds support to query the TDX capabilities from the QEMU.
Currently there is no elements in TDX capabilities except a placeholder.
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/conf/domain_capabilities.c | 8 +++++ src/conf/domain_capabilities.h | 10 +++++++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 30 +++++++++++++++++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_monitor.c | 8 +++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 53 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 ++ 9 files changed, 117 insertions(+)
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index cb90ae0176..31577095e9 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -76,6 +76,14 @@ virSEVCapabilitiesFree(virSEVCapability *cap) g_free(cap); }
+void +virTDXCapabilitiesFree(virTDXCapability *cap) { + if (!cap) + return; + + VIR_FREE(cap); +}
static void virDomainCapsDispose(void *obj) diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index b6433b20c9..e099788da9 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -173,6 +173,12 @@ struct _virSEVCapability { unsigned int reduced_phys_bits; };
+typedef struct _virTDXCapability virTDXCapability; struct +_virTDXCapability { + /* no elements for Intel TDX for now, just put a placeholder */ + uint64_t placeholder; +}; +
There is no need to add unused code into libvirt especially if the impact is only internal and it is not exposed to users. It can be added in the future if needed. Because this patch series doesn't add any TDX specific capability into this structure please drop all related code to this placeholder.
Sorry, I didn't fully understand which part to preserve. Do you mean removing placeholder from struct virTDXCapability or removing virTDXCapability as it's empty?
No problem, should have been more explicit about that. I meant the whole structure and code related to the structure.
virDomainCapsFeatureTDXFormat(virTDXCapability *tdx) shows '<tdx supported='yes'/>' based on the value of tdx. If virTDXCapability is empty, tdx is always NULL and '<tdx supported='no'/>' showed.
Right, I missed that part during review. I see that it copies what we do with AMD SEV where we also have a struct with capabilities. Currently for Intel TDX there are no extra capabilities and I was not able to find any patches posted to QEMU devel list which would implement the QMP command 'query-tdx-capabilities' so right now all of this looks useless. Unless there is a plan to add some capabilities and introduce that command we should use boolean value for now. Pavel
Thanks Zhenzhong
Pavel
typedef enum { VIR_DOMAIN_CAPS_FEATURE_IOTHREADS = 0, VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO, @@ -254,3 +260,7 @@ void virSEVCapabilitiesFree(virSEVCapability *capabilities);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSEVCapability, virSEVCapabilitiesFree); + +void virTDXCapabilitiesFree(virTDXCapability *capabilities); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virTDXCapability, +virTDXCapabilitiesFree); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2efa787664..8cbb60b577 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -218,6 +218,7 @@ virDomainCapsEnumSet; virDomainCapsFormat; virDomainCapsNew; virSEVCapabilitiesFree; +virTDXCapabilitiesFree;
# conf/domain_conf.h diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 059d6badf2..a143e453f4 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -636,6 +636,7 @@ VIR_ENUM_IMPL(virQEMUCaps, /* 405 */ "confidential-guest-support", "query-display-options", + "tdx-guest", );
@@ -716,6 +717,8 @@ struct _virQEMUCaps {
virSEVCapability *sevCapabilities;
+ virTDXCapability *tdxCapabilities; + /* Capabilities which may differ depending on the accelerator. */ virQEMUCapsAccel kvm; virQEMUCapsAccel tcg; @@ -1354,6 +1357,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "input-linux", QEMU_CAPS_INPUT_LINUX }, { "virtio-gpu-gl-pci", QEMU_CAPS_VIRTIO_GPU_GL_PCI }, { "virtio-vga-gl", QEMU_CAPS_VIRTIO_VGA_GL }, + { "tdx-guest", QEMU_CAPS_TDX_GUEST}, };
@@ -2027,6 +2031,7 @@ void virQEMUCapsDispose(void *obj) g_free(qemuCaps->gicCapabilities);
virSEVCapabilitiesFree(qemuCaps->sevCapabilities); + virTDXCapabilitiesFree(qemuCaps->tdxCapabilities);
virQEMUCapsAccelClear(&qemuCaps->kvm); virQEMUCapsAccelClear(&qemuCaps->tcg); @@ -3354,6 +3359,29 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps, return 0; }
+static int +virQEMUCapsProbeQMPTDXCapabilities(virQEMUCaps *qemuCaps, + qemuMonitor *mon) { + int rc = -1; + virTDXCapability *caps = NULL; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST)) + return 0; + + if ((rc = qemuMonitorGetTDXCapabilities(mon, &caps)) < 0) + return -1; + + /* TDX isn't actually supported */ + if (rc == 0) { + virQEMUCapsClear(qemuCaps, QEMU_CAPS_TDX_GUEST); + return 0; + } + + virTDXCapabilitiesFree(qemuCaps->tdxCapabilities); + qemuCaps->tdxCapabilities = caps; + return 0; +}
/* * Filter for features which should never be passed to QEMU. Either because @@ -5316,6 +5344,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps, return -1; if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0) return -1; + if (virQEMUCapsProbeQMPTDXCapabilities(qemuCaps, mon) < 0) + return -1;
virQEMUCapsInitProcessCaps(qemuCaps);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index b2878312ac..a51bd9a256 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -616,6 +616,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ /* 405 */ QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT, /* -machine confidential-guest-support */ QEMU_CAPS_QUERY_DISPLAY_OPTIONS, /* 'query-display-options' qmp command present */ + QEMU_CAPS_TDX_GUEST, /* -object tdx-guest,... */
QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 8f35b4240f..f2a3badeec 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3946,6 +3946,14 @@ qemuMonitorNBDServerStart(qemuMonitor *mon, return qemuMonitorJSONNBDServerStart(mon, server, tls_alias); }
+int +qemuMonitorGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities) { + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONGetTDXCapabilities(mon, capabilities); }
int qemuMonitorNBDServerAdd(qemuMonitor *mon, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6a25def78b..48c18c5220 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -859,6 +859,9 @@ int qemuMonitorGetGICCapabilities(qemuMonitor *mon, int qemuMonitorGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities);
+int qemuMonitorGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities); + typedef enum { QEMU_MONITOR_MIGRATE_BACKGROUND = 1 << 0, QEMU_MONITOR_MIGRATE_NON_SHARED_DISK = 1 << 1, /* migration with non-shared storage with full disk copy */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 223777739d..c58152e86f 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -7028,6 +7028,59 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon, return ret; }
+/** + * qemuMonitorJSONGetTDXCapabilities: + * @mon: qemu monitor object + * @capabilities: pointer to pointer to a TDX capability structure to +be filled + * + * Returns -1 on error, 0 if TDX is not supported, and 1 if TDX is +supported on + * the platform. + */ +int +qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability **capabilities) { + int ret = -1; + virJSONValue *cmd; + virJSONValue *reply = NULL; + g_autoptr(virTDXCapability) capability = NULL; + + *capabilities = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("query-tdx-capabilities", + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + /* QEMU has only compiled-in support of TDX */ + if (qemuMonitorJSONHasError(reply, "GenericError")) { + ret = 0; + goto cleanup; + } + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + if (!virJSONValueObjectGetObject(reply, "return")) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-tdx-capabilities reply was missing return")); + return -1; + } + + capability = g_new0(virTDXCapability, 1); + + *capabilities = g_steal_pointer(&capability); + + ret = 1; + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + + return ret; +} + static virJSONValue * qemuMonitorJSONBuildInetSocketAddress(const char *host, const char *port) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 01a3ba25f1..3fe6a34c4c 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -157,6 +157,9 @@ int qemuMonitorJSONGetGICCapabilities(qemuMonitor *mon, int qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities);
+int qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon, + virTDXCapability +**capabilities); + int qemuMonitorJSONMigrate(qemuMonitor *mon, unsigned int flags, const char *uri); -- 2.25.1

Extend hypervisor capabilities to include tdx feature. When available, hypervisor can launch an encrypted VM on Intel platform. Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- docs/formatdomaincaps.html.in | 16 ++++++++++++++++ docs/schemas/domaincaps.rng | 9 +++++++++ src/conf/domain_capabilities.c | 14 ++++++++++++++ src/conf/domain_capabilities.h | 1 + src/qemu/qemu_capabilities.c | 12 ++++++++++++ tests/domaincapsdata/bhyve_basic.x86_64.xml | 1 + tests/domaincapsdata/bhyve_fbuf.x86_64.xml | 1 + tests/domaincapsdata/bhyve_uefi.x86_64.xml | 1 + tests/domaincapsdata/empty.xml | 1 + tests/domaincapsdata/libxl-xenfv.xml | 1 + tests/domaincapsdata/libxl-xenpv.xml | 1 + tests/domaincapsdata/qemu_2.11.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.11.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.11.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml | 1 + .../domaincapsdata/qemu_2.12.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.12.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.4.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.4.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.4.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.5.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.5.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.5.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.6.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.6.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.6.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.6.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.6.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_2.6.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.7.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.7.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.7.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.7.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.8.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.8.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.8.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.8.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.9.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.9.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_2.9.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.9.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.0.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_3.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_3.0.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.1.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.1.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_3.1.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.0.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_4.0.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.1.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_4.2.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.1.0.sparc.xml | 1 + tests/domaincapsdata/qemu_5.1.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_5.2.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_6.0.0.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.1.0.x86_64.xml | 1 + 97 files changed, 144 insertions(+) diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in index 62f1940e6a..0e679b19b7 100644 --- a/docs/formatdomaincaps.html.in +++ b/docs/formatdomaincaps.html.in @@ -566,6 +566,7 @@ <genid supported='yes'/> <backingStoreInput supported='yes'/> <backup supported='yes'/> + <tdx supported='yes'/> <sev> <cbitpos>47</cbitpos> <reduced-phys-bits>1</reduced-phys-bits> @@ -620,6 +621,21 @@ <code>virDomainUndefine</code> is supported. </p> + <h4><a id="featureTDX">TDX capabilities</a></h4> + <p>Trust Domain Extensions(TDX) capabilities are exposed under the + <code>tdx</code> element. + TDX is an Intel technology that extends Virtual Machines Extensions (VMX) + to with a new kind of virtual machine guest called Trust Domain (TD). A TD + runs in a CPU model which protects the confidentiality of its memory contents + and its CPU state from any other software, including the hosting Virtual Machine + Monitor (VMM), unless explicitly shared by the TD itself.</p> + + <p> + For more details on the TDX feature, please follow resources in the + Intel developer's document. In order to use TDX with libvirt have + a look at <a href="formatdomain.html#launchSecurity">TDX in domain XML</a> + </p> + <h4><a id="elementsSEV">SEV capabilities</a></h4> <p>AMD Secure Encrypted Virtualization (SEV) capabilities are exposed under diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng index fc668e0c78..0e61d38923 100644 --- a/docs/schemas/domaincaps.rng +++ b/docs/schemas/domaincaps.rng @@ -250,6 +250,9 @@ <optional> <ref name="sev"/> </optional> + <optional> + <ref name="tdx"/> + </optional> </element> </define> @@ -298,6 +301,12 @@ </element> </define> + <define name="tdx"> + <element name="tdx"> + <ref name="supported"/> + </element> + </define> + <define name="value"> <zeroOrMore> <element name="value"> diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index 31577095e9..709ef6ab9e 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -97,6 +97,7 @@ virDomainCapsDispose(void *obj) virObjectUnref(caps->cpu.custom); virCPUDefFree(caps->cpu.hostModel); virSEVCapabilitiesFree(caps->sev); + virTDXCapabilitiesFree(caps->tdx); values = &caps->os.loader.values; for (i = 0; i < values->nvalues; i++) @@ -590,6 +591,17 @@ virDomainCapsFeatureSEVFormat(virBuffer *buf, return; } +static void +virDomainCapsFeatureTDXFormat(virBuffer *buf, + const virTDXCapability *tdx) +{ + if (tdx) + virBufferAddLit(buf, "<tdx supported='yes'/>\n"); + else + virBufferAddLit(buf, "<tdx supported='no'/>\n"); + + return; +} static void virDomainCapsFormatFeatures(const virDomainCaps *caps, @@ -611,6 +623,8 @@ virDomainCapsFormatFeatures(const virDomainCaps *caps, virDomainCapsFeatureSEVFormat(&childBuf, caps->sev); + virDomainCapsFeatureTDXFormat(&childBuf, caps->tdx); + virXMLFormatElement(buf, "features", NULL, &childBuf); } diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index e099788da9..17b59b699a 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -213,6 +213,7 @@ struct _virDomainCaps { virDomainCapsFeatureGIC gic; virSEVCapability *sev; /* add new domain features here */ + virTDXCapability *tdx; virTristateBool features[VIR_DOMAIN_CAPS_FEATURE_LAST]; }; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index a143e453f4..5e54d7e306 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -6332,6 +6332,17 @@ virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCaps *qemuCaps, domCaps->sev->reduced_phys_bits = cap->reduced_phys_bits; } +static void +virQEMUCapsFillDomainFeatureTDXCaps(virQEMUCaps *qemuCaps, + virDomainCaps *domCaps) +{ + virTDXCapability *cap = qemuCaps->tdxCapabilities; + + if (!cap) + return; + + domCaps->tdx = g_new0(virTDXCapability, 1); +} int virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps, @@ -6379,6 +6390,7 @@ virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps, virQEMUCapsFillDomainDeviceFSCaps(qemuCaps, filesystem); virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps); virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps); + virQEMUCapsFillDomainFeatureTDXCaps(qemuCaps, domCaps); return 0; } diff --git a/tests/domaincapsdata/bhyve_basic.x86_64.xml b/tests/domaincapsdata/bhyve_basic.x86_64.xml index 745f325531..40e853c560 100644 --- a/tests/domaincapsdata/bhyve_basic.x86_64.xml +++ b/tests/domaincapsdata/bhyve_basic.x86_64.xml @@ -33,5 +33,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/bhyve_fbuf.x86_64.xml b/tests/domaincapsdata/bhyve_fbuf.x86_64.xml index bb11c02ae9..87f98b6bba 100644 --- a/tests/domaincapsdata/bhyve_fbuf.x86_64.xml +++ b/tests/domaincapsdata/bhyve_fbuf.x86_64.xml @@ -50,5 +50,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/bhyve_uefi.x86_64.xml b/tests/domaincapsdata/bhyve_uefi.x86_64.xml index dfd2360d74..9409257887 100644 --- a/tests/domaincapsdata/bhyve_uefi.x86_64.xml +++ b/tests/domaincapsdata/bhyve_uefi.x86_64.xml @@ -42,5 +42,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/empty.xml b/tests/domaincapsdata/empty.xml index d3e2d89b60..ba47d8c5be 100644 --- a/tests/domaincapsdata/empty.xml +++ b/tests/domaincapsdata/empty.xml @@ -13,5 +13,6 @@ </devices> <features> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/libxl-xenfv.xml b/tests/domaincapsdata/libxl-xenfv.xml index cc5b3847e2..4c335ab7ee 100644 --- a/tests/domaincapsdata/libxl-xenfv.xml +++ b/tests/domaincapsdata/libxl-xenfv.xml @@ -76,5 +76,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/libxl-xenpv.xml b/tests/domaincapsdata/libxl-xenpv.xml index 325f1e50b3..c2fa55472b 100644 --- a/tests/domaincapsdata/libxl-xenpv.xml +++ b/tests/domaincapsdata/libxl-xenpv.xml @@ -66,5 +66,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.11.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.11.0-q35.x86_64.xml index f5714298c1..6eb612ea05 100644 --- a/tests/domaincapsdata/qemu_2.11.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.11.0-q35.x86_64.xml @@ -172,5 +172,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml index 1392f7c50e..2bce2140e7 100644 --- a/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml @@ -185,5 +185,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.11.0.s390x.xml b/tests/domaincapsdata/qemu_2.11.0.s390x.xml index cd3ab38bc4..c6f1d26d8f 100644 --- a/tests/domaincapsdata/qemu_2.11.0.s390x.xml +++ b/tests/domaincapsdata/qemu_2.11.0.s390x.xml @@ -207,5 +207,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.11.0.x86_64.xml b/tests/domaincapsdata/qemu_2.11.0.x86_64.xml index 0dde7c65c6..1e86efe77d 100644 --- a/tests/domaincapsdata/qemu_2.11.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.11.0.x86_64.xml @@ -172,5 +172,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml index f7db0b4cc7..b85b1b3ada 100644 --- a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml @@ -189,5 +189,6 @@ <cbitpos>47</cbitpos> <reducedPhysBits>1</reducedPhysBits> </sev> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml index cb26512256..20201dd795 100644 --- a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml @@ -199,5 +199,6 @@ <cbitpos>47</cbitpos> <reducedPhysBits>1</reducedPhysBits> </sev> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_2.12.0-virt.aarch64.xml index de41f9c859..27c66b49d6 100644 --- a/tests/domaincapsdata/qemu_2.12.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_2.12.0-virt.aarch64.xml @@ -160,5 +160,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0.aarch64.xml b/tests/domaincapsdata/qemu_2.12.0.aarch64.xml index 0d2ed1058e..bc99972431 100644 --- a/tests/domaincapsdata/qemu_2.12.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_2.12.0.aarch64.xml @@ -154,5 +154,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0.ppc64.xml b/tests/domaincapsdata/qemu_2.12.0.ppc64.xml index e01f2c6fec..0598a24191 100644 --- a/tests/domaincapsdata/qemu_2.12.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_2.12.0.ppc64.xml @@ -124,5 +124,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0.s390x.xml b/tests/domaincapsdata/qemu_2.12.0.s390x.xml index 418db98294..5c6f3f7e93 100644 --- a/tests/domaincapsdata/qemu_2.12.0.s390x.xml +++ b/tests/domaincapsdata/qemu_2.12.0.s390x.xml @@ -206,5 +206,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml index 1ce380cea7..761b436f0a 100644 --- a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml @@ -189,5 +189,6 @@ <cbitpos>47</cbitpos> <reducedPhysBits>1</reducedPhysBits> </sev> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.4.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.4.0-q35.x86_64.xml index 3ae03de391..608bed8bdd 100644 --- a/tests/domaincapsdata/qemu_2.4.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.4.0-q35.x86_64.xml @@ -147,5 +147,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.4.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.4.0-tcg.x86_64.xml index 461cc4c102..0afd91ea7b 100644 --- a/tests/domaincapsdata/qemu_2.4.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.4.0-tcg.x86_64.xml @@ -143,5 +143,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.4.0.x86_64.xml b/tests/domaincapsdata/qemu_2.4.0.x86_64.xml index e1af5b6622..cafa271e87 100644 --- a/tests/domaincapsdata/qemu_2.4.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.4.0.x86_64.xml @@ -147,5 +147,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.5.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.5.0-q35.x86_64.xml index f46991ca27..a361bc3343 100644 --- a/tests/domaincapsdata/qemu_2.5.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.5.0-q35.x86_64.xml @@ -147,5 +147,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.5.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.5.0-tcg.x86_64.xml index 82edcbfac6..182814b589 100644 --- a/tests/domaincapsdata/qemu_2.5.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.5.0-tcg.x86_64.xml @@ -143,5 +143,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.5.0.x86_64.xml b/tests/domaincapsdata/qemu_2.5.0.x86_64.xml index 57f9f9b41b..86edf760cb 100644 --- a/tests/domaincapsdata/qemu_2.5.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.5.0.x86_64.xml @@ -147,5 +147,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.6.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.6.0-q35.x86_64.xml index 8bcd8f92ab..dcbff499f1 100644 --- a/tests/domaincapsdata/qemu_2.6.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.6.0-q35.x86_64.xml @@ -147,5 +147,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.6.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.6.0-tcg.x86_64.xml index 2a7b46f775..bdfbf4b5de 100644 --- a/tests/domaincapsdata/qemu_2.6.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.6.0-tcg.x86_64.xml @@ -143,5 +143,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.6.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_2.6.0-virt.aarch64.xml index 14cab3f557..3af9d4d305 100644 --- a/tests/domaincapsdata/qemu_2.6.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_2.6.0-virt.aarch64.xml @@ -145,5 +145,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.6.0.aarch64.xml b/tests/domaincapsdata/qemu_2.6.0.aarch64.xml index f84e648a15..44bc9f74e4 100644 --- a/tests/domaincapsdata/qemu_2.6.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_2.6.0.aarch64.xml @@ -139,5 +139,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.6.0.ppc64.xml b/tests/domaincapsdata/qemu_2.6.0.ppc64.xml index 7f9372a359..b9a18e64be 100644 --- a/tests/domaincapsdata/qemu_2.6.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_2.6.0.ppc64.xml @@ -112,5 +112,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.6.0.x86_64.xml b/tests/domaincapsdata/qemu_2.6.0.x86_64.xml index 4eeec1a22b..c03140a147 100644 --- a/tests/domaincapsdata/qemu_2.6.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.6.0.x86_64.xml @@ -147,5 +147,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.7.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.7.0-q35.x86_64.xml index 537941561b..63cfb38d65 100644 --- a/tests/domaincapsdata/qemu_2.7.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.7.0-q35.x86_64.xml @@ -148,5 +148,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.7.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.7.0-tcg.x86_64.xml index 79f5fba212..4d35f5d249 100644 --- a/tests/domaincapsdata/qemu_2.7.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.7.0-tcg.x86_64.xml @@ -144,5 +144,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.7.0.s390x.xml b/tests/domaincapsdata/qemu_2.7.0.s390x.xml index f76564a9bc..0b6310751b 100644 --- a/tests/domaincapsdata/qemu_2.7.0.s390x.xml +++ b/tests/domaincapsdata/qemu_2.7.0.s390x.xml @@ -104,5 +104,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.7.0.x86_64.xml b/tests/domaincapsdata/qemu_2.7.0.x86_64.xml index 1dd19dfc37..5a54c5290a 100644 --- a/tests/domaincapsdata/qemu_2.7.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.7.0.x86_64.xml @@ -148,5 +148,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.8.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.8.0-q35.x86_64.xml index e0bb1b1eee..1fba86335b 100644 --- a/tests/domaincapsdata/qemu_2.8.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.8.0-q35.x86_64.xml @@ -148,5 +148,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.8.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.8.0-tcg.x86_64.xml index 1829fbda60..0c3f5b55cc 100644 --- a/tests/domaincapsdata/qemu_2.8.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.8.0-tcg.x86_64.xml @@ -144,5 +144,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.8.0.s390x.xml b/tests/domaincapsdata/qemu_2.8.0.s390x.xml index 2c075d7cdb..9a01625f53 100644 --- a/tests/domaincapsdata/qemu_2.8.0.s390x.xml +++ b/tests/domaincapsdata/qemu_2.8.0.s390x.xml @@ -185,5 +185,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.8.0.x86_64.xml b/tests/domaincapsdata/qemu_2.8.0.x86_64.xml index 5f55b0730d..d828088d3d 100644 --- a/tests/domaincapsdata/qemu_2.8.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.8.0.x86_64.xml @@ -148,5 +148,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.9.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.9.0-q35.x86_64.xml index 797b970040..ef36127e42 100644 --- a/tests/domaincapsdata/qemu_2.9.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.9.0-q35.x86_64.xml @@ -162,5 +162,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml index b47c426f1b..79f5fe264f 100644 --- a/tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.9.0-tcg.x86_64.xml @@ -181,5 +181,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.9.0.ppc64.xml b/tests/domaincapsdata/qemu_2.9.0.ppc64.xml index 2523d6ec6b..ad4a226c17 100644 --- a/tests/domaincapsdata/qemu_2.9.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_2.9.0.ppc64.xml @@ -112,5 +112,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.9.0.s390x.xml b/tests/domaincapsdata/qemu_2.9.0.s390x.xml index d5b58a786d..abefc63400 100644 --- a/tests/domaincapsdata/qemu_2.9.0.s390x.xml +++ b/tests/domaincapsdata/qemu_2.9.0.s390x.xml @@ -186,5 +186,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.9.0.x86_64.xml b/tests/domaincapsdata/qemu_2.9.0.x86_64.xml index 7716e9d381..410fb1ad1a 100644 --- a/tests/domaincapsdata/qemu_2.9.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.9.0.x86_64.xml @@ -162,5 +162,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_3.0.0-q35.x86_64.xml index 6dfb6135b3..bdc93a8055 100644 --- a/tests/domaincapsdata/qemu_3.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.0.0-q35.x86_64.xml @@ -187,5 +187,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml index 3c12f79f3a..c1248a8135 100644 --- a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml @@ -199,5 +199,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0.ppc64.xml b/tests/domaincapsdata/qemu_3.0.0.ppc64.xml index 86dd4a0c39..2227523c5c 100644 --- a/tests/domaincapsdata/qemu_3.0.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_3.0.0.ppc64.xml @@ -126,5 +126,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0.s390x.xml b/tests/domaincapsdata/qemu_3.0.0.s390x.xml index d4443bde20..9d8e356c67 100644 --- a/tests/domaincapsdata/qemu_3.0.0.s390x.xml +++ b/tests/domaincapsdata/qemu_3.0.0.s390x.xml @@ -213,5 +213,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0.x86_64.xml b/tests/domaincapsdata/qemu_3.0.0.x86_64.xml index 1abdc89c38..aa40eb31ff 100644 --- a/tests/domaincapsdata/qemu_3.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.0.0.x86_64.xml @@ -187,5 +187,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_3.1.0-q35.x86_64.xml index fd7fe4794a..07fccfee25 100644 --- a/tests/domaincapsdata/qemu_3.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.1.0-q35.x86_64.xml @@ -190,5 +190,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml index 424c3e4e51..4fab773a8a 100644 --- a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml @@ -202,5 +202,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.1.0.ppc64.xml b/tests/domaincapsdata/qemu_3.1.0.ppc64.xml index 65dc3fbd72..521c426ee7 100644 --- a/tests/domaincapsdata/qemu_3.1.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_3.1.0.ppc64.xml @@ -126,5 +126,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.1.0.x86_64.xml b/tests/domaincapsdata/qemu_3.1.0.x86_64.xml index 409fd223bd..726a284b57 100644 --- a/tests/domaincapsdata/qemu_3.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.1.0.x86_64.xml @@ -190,5 +190,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.0.0-q35.x86_64.xml index 89440e9312..572691bb48 100644 --- a/tests/domaincapsdata/qemu_4.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.0.0-q35.x86_64.xml @@ -190,5 +190,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml index 43eaa1c6aa..d6ddc8a46c 100644 --- a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml @@ -203,5 +203,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_4.0.0-virt.aarch64.xml index 7f8a3ef8cd..de6b2f0f44 100644 --- a/tests/domaincapsdata/qemu_4.0.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_4.0.0-virt.aarch64.xml @@ -167,5 +167,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0.aarch64.xml b/tests/domaincapsdata/qemu_4.0.0.aarch64.xml index 3570d5eec2..5dd7908379 100644 --- a/tests/domaincapsdata/qemu_4.0.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_4.0.0.aarch64.xml @@ -161,5 +161,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0.ppc64.xml b/tests/domaincapsdata/qemu_4.0.0.ppc64.xml index c33967e51f..43958b8dcc 100644 --- a/tests/domaincapsdata/qemu_4.0.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_4.0.0.ppc64.xml @@ -127,5 +127,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0.s390x.xml b/tests/domaincapsdata/qemu_4.0.0.s390x.xml index e0ff109ead..0401f50e64 100644 --- a/tests/domaincapsdata/qemu_4.0.0.s390x.xml +++ b/tests/domaincapsdata/qemu_4.0.0.s390x.xml @@ -223,5 +223,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0.x86_64.xml b/tests/domaincapsdata/qemu_4.0.0.x86_64.xml index a4739c721a..51213283a0 100644 --- a/tests/domaincapsdata/qemu_4.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.0.0.x86_64.xml @@ -190,5 +190,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml index 4d3659bce9..fc077b4ce6 100644 --- a/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml @@ -196,5 +196,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml index 887c07d28f..545ec5a3e8 100644 --- a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml @@ -205,5 +205,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.1.0.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0.x86_64.xml index 4e07afd3d9..25a39b430b 100644 --- a/tests/domaincapsdata/qemu_4.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.1.0.x86_64.xml @@ -196,5 +196,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml index 39646c7d1e..58a0ad469e 100644 --- a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml @@ -204,5 +204,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml index 5d7cea0f41..8102c2621d 100644 --- a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml @@ -212,5 +212,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_4.2.0-virt.aarch64.xml index 740dc1f15e..d3f219a105 100644 --- a/tests/domaincapsdata/qemu_4.2.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_4.2.0-virt.aarch64.xml @@ -169,5 +169,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0.aarch64.xml b/tests/domaincapsdata/qemu_4.2.0.aarch64.xml index a923d30e76..ecfccc6110 100644 --- a/tests/domaincapsdata/qemu_4.2.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_4.2.0.aarch64.xml @@ -163,5 +163,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0.ppc64.xml b/tests/domaincapsdata/qemu_4.2.0.ppc64.xml index b09e401d5c..ed41c9835c 100644 --- a/tests/domaincapsdata/qemu_4.2.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_4.2.0.ppc64.xml @@ -128,5 +128,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0.s390x.xml b/tests/domaincapsdata/qemu_4.2.0.s390x.xml index a610c417f7..79f3cf2930 100644 --- a/tests/domaincapsdata/qemu_4.2.0.s390x.xml +++ b/tests/domaincapsdata/qemu_4.2.0.s390x.xml @@ -238,5 +238,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml index 36e8bd2ff3..dc1c11a58a 100644 --- a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml @@ -204,5 +204,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml index 4f7d1bdbbc..c98efaa0c9 100644 --- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml @@ -206,5 +206,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml index 97d1819482..36d39541e1 100644 --- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml @@ -213,5 +213,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml index dcad3b3833..b53a80e437 100644 --- a/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml @@ -170,5 +170,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0.aarch64.xml b/tests/domaincapsdata/qemu_5.0.0.aarch64.xml index ada3ebdb2b..6c4d4679c1 100644 --- a/tests/domaincapsdata/qemu_5.0.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_5.0.0.aarch64.xml @@ -164,5 +164,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0.ppc64.xml b/tests/domaincapsdata/qemu_5.0.0.ppc64.xml index 650188606c..18313f57f0 100644 --- a/tests/domaincapsdata/qemu_5.0.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_5.0.0.ppc64.xml @@ -129,5 +129,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml index 2bb72027ba..3c1b73e111 100644 --- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml @@ -206,5 +206,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml index 95d44575fd..84c5395ef5 100644 --- a/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml @@ -207,5 +207,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml index 3a4ec231f3..36bab4379f 100644 --- a/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml @@ -213,5 +213,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.1.0.sparc.xml b/tests/domaincapsdata/qemu_5.1.0.sparc.xml index 6f85a768e2..ef61bf8c13 100644 --- a/tests/domaincapsdata/qemu_5.1.0.sparc.xml +++ b/tests/domaincapsdata/qemu_5.1.0.sparc.xml @@ -105,5 +105,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.1.0.x86_64.xml b/tests/domaincapsdata/qemu_5.1.0.x86_64.xml index 98dfb971a2..882ceb73de 100644 --- a/tests/domaincapsdata/qemu_5.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.1.0.x86_64.xml @@ -207,5 +207,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml index 1712c2113b..a7df147e44 100644 --- a/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml @@ -207,5 +207,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml index 754046fb6d..2a71d94ec8 100644 --- a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml @@ -213,5 +213,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml index 27776a667b..b5ddfdbbf7 100644 --- a/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml @@ -170,5 +170,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0.aarch64.xml b/tests/domaincapsdata/qemu_5.2.0.aarch64.xml index ada3ebdb2b..6c4d4679c1 100644 --- a/tests/domaincapsdata/qemu_5.2.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_5.2.0.aarch64.xml @@ -164,5 +164,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0.ppc64.xml b/tests/domaincapsdata/qemu_5.2.0.ppc64.xml index 211f7b8ac6..105f9bd3c5 100644 --- a/tests/domaincapsdata/qemu_5.2.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_5.2.0.ppc64.xml @@ -129,5 +129,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0.s390x.xml b/tests/domaincapsdata/qemu_5.2.0.s390x.xml index 43905a6a85..f2e756fc23 100644 --- a/tests/domaincapsdata/qemu_5.2.0.s390x.xml +++ b/tests/domaincapsdata/qemu_5.2.0.s390x.xml @@ -240,5 +240,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0.x86_64.xml index daf43d222c..fef5abef40 100644 --- a/tests/domaincapsdata/qemu_5.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.2.0.x86_64.xml @@ -207,5 +207,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml index 98edd3e37d..580f0a6778 100644 --- a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml @@ -211,5 +211,6 @@ <cbitpos>47</cbitpos> <reducedPhysBits>1</reducedPhysBits> </sev> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml index 7b4cd0160a..f8c552a1be 100644 --- a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml @@ -217,5 +217,6 @@ <cbitpos>47</cbitpos> <reducedPhysBits>1</reducedPhysBits> </sev> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0.s390x.xml b/tests/domaincapsdata/qemu_6.0.0.s390x.xml index d384f0859b..d69ac0c9f3 100644 --- a/tests/domaincapsdata/qemu_6.0.0.s390x.xml +++ b/tests/domaincapsdata/qemu_6.0.0.s390x.xml @@ -241,5 +241,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml index 7122c89497..f4b4a2bf25 100644 --- a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml @@ -211,5 +211,6 @@ <cbitpos>47</cbitpos> <reducedPhysBits>1</reducedPhysBits> </sev> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml index 057824d795..d8d6ac64f7 100644 --- a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml @@ -211,5 +211,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml index 6c84207231..d5938428d7 100644 --- a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml @@ -214,5 +214,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.1.0.x86_64.xml b/tests/domaincapsdata/qemu_6.1.0.x86_64.xml index 1934035547..2ab68a6bd4 100644 --- a/tests/domaincapsdata/qemu_6.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.1.0.x86_64.xml @@ -211,5 +211,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <tdx supported='no'/> </features> </domainCapabilities> -- 2.25.1

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@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

On Fri, Jun 18, 2021 at 16:50:48 +0800, Zhenzhong Duan wrote:
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@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"/>
All our RNG schema entries ...
+ </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);
[...]
@@ -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);
If you register an autoptr cleanup function for this type you'll be able to avoid the whole 'error' label.
+ return NULL; +}
[...]
@@ -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");
... as well as XML element names don't start with capital letter, so this one shouldn't either.
+ 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) 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; +
Plase don't mix generic (conf/) changes ...
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; + }
... with targetted qemu changes like this.
+ if (def->naudios > 1 && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_AUDIODEV)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
[...]

-----Original Message----- From: Peter Krempa <pkrempa@redhat.com> Sent: Friday, June 18, 2021 7:17 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 3/7] conf: introduce TrustDomain element in domain
On Fri, Jun 18, 2021 at 16:50:48 +0800, Zhenzhong Duan wrote:
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@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"/>
All our RNG schema entries ...
+ </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);
[...]
@@ -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);
If you register an autoptr cleanup function for this type you'll be able to avoid the whole 'error' label. Good suggestion, will do.
+ return NULL; +}
[...]
@@ -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");
... as well as XML element names don't start with capital letter, so this one shouldn't either.
Will fix.
+ 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) 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; +
Plase don't mix generic (conf/) changes ...
Will refactor. Thanks Zhenzhong
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; + }
... with targetted qemu changes like this.
+ if (def->naudios > 1 && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_AUDIODEV)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
[...]

On Fri, Jun 18, 2021 at 04:50:48PM +0800, Zhenzhong Duan wrote:
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>
Any reason why you are adding a new element that basically copies exactly what <launchSecurity> is doing? In libvirt it will essentially use `confidential-guest-support` which is used for launchSecurity so there is no need to duplicate the code and the XML element. It could look like this: <launchSecurity type='tdx'> <policy>0x0001</policy> </launchSecurity> We would have to reorganize the <launchSecurity> documentation a little bit but otherwise there is nothing blocking us to have single element to specify different type of encrypted/confidential/secure/... VMs. We already have patches for similar feature for s390 which will also reuse this element and in the future any other CPU architecture can reuse it. Pavel
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@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

-----Original Message----- From: Pavel Hrdina <phrdina@redhat.com> Sent: Friday, June 18, 2021 8:09 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 3/7] conf: introduce TrustDomain element in domain
On Fri, Jun 18, 2021 at 04:50:48PM +0800, Zhenzhong Duan wrote:
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>
Any reason why you are adding a new element that basically copies exactly what <launchSecurity> is doing?
In libvirt it will essentially use `confidential-guest-support` which is used for launchSecurity so there is no need to duplicate the code and the XML element.
It could look like this:
<launchSecurity type='tdx'> <policy>0x0001</policy> </launchSecurity>
We would have to reorganize the <launchSecurity> documentation a little bit but otherwise there is nothing blocking us to have single element to specify different type of encrypted/confidential/secure/... VMs.
We had ever made a patch working as you suggested. It has advantage of only using one element for all. The main reason I chose the other way is because this way having quite less code change, as it avoid many mux and branch code. See below: Using < launchSecurity>: docs/schemas/domaincommon.rng | 90 +++++---- src/conf/domain_conf.c | 182 +++++++++++++++--- src/conf/domain_conf.h | 19 +- src/conf/virconftypes.h | 6 + src/qemu/qemu_cgroup.c | 3 +- src/qemu/qemu_command.c | 5 +- src/qemu/qemu_driver.c | 4 +- src/qemu/qemu_firmware.c | 5 +- src/qemu/qemu_namespace.c | 4 +- src/qemu/qemu_process.c | 12 +- src/qemu/qemu_validate.c | 30 ++- src/security/security_dac.c | 4 +- vs. Using <TrustDomain>: 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 ++ I'm also irresolute on which to choose, I'll use <launchSecurity> if you think it's better.
We already have patches for similar feature for s390 which will also reuse this element and in the future any other CPU architecture can reuse it.
Hmm, I didn’t find those patches for s390, aren't they upstream yet? Appreciate if you could show me a link for reference. Thanks Zhenzhong

On Mon, Jun 21, 2021 at 04:14:40AM +0000, Duan, Zhenzhong wrote:
-----Original Message----- From: Pavel Hrdina <phrdina@redhat.com> Sent: Friday, June 18, 2021 8:09 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 3/7] conf: introduce TrustDomain element in domain
On Fri, Jun 18, 2021 at 04:50:48PM +0800, Zhenzhong Duan wrote:
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>
Any reason why you are adding a new element that basically copies exactly what <launchSecurity> is doing?
In libvirt it will essentially use `confidential-guest-support` which is used for launchSecurity so there is no need to duplicate the code and the XML element.
It could look like this:
<launchSecurity type='tdx'> <policy>0x0001</policy> </launchSecurity>
We would have to reorganize the <launchSecurity> documentation a little bit but otherwise there is nothing blocking us to have single element to specify different type of encrypted/confidential/secure/... VMs.
We had ever made a patch working as you suggested. It has advantage of only using one element for all. The main reason I chose the other way is because this way having quite less code change, as it avoid many mux and branch code. See below:
Using < launchSecurity>:
docs/schemas/domaincommon.rng | 90 +++++---- src/conf/domain_conf.c | 182 +++++++++++++++--- src/conf/domain_conf.h | 19 +- src/conf/virconftypes.h | 6 + src/qemu/qemu_cgroup.c | 3 +- src/qemu/qemu_command.c | 5 +- src/qemu/qemu_driver.c | 4 +- src/qemu/qemu_firmware.c | 5 +- src/qemu/qemu_namespace.c | 4 +- src/qemu/qemu_process.c | 12 +- src/qemu/qemu_validate.c | 30 ++- src/security/security_dac.c | 4 +-
This is not an issue and most likely some of these changes would be required with new <TrustDomain> element as well so we would definitely prefer reusing <launchSecurity> element.
vs. Using <TrustDomain>:
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 ++
I'm also irresolute on which to choose, I'll use <launchSecurity> if you think it's better.
We already have patches for similar feature for s390 which will also reuse this element and in the future any other CPU architecture can reuse it.
Hmm, I didn’t find those patches for s390, aren't they upstream yet? Appreciate if you could show me a link for reference.
v1 series: https://listman.redhat.com/archives/libvir-list/2021-May/msg00570.html v2 series: https://listman.redhat.com/archives/libvir-list/2021-June/msg00583.html Pavel

On Mon, Jun 21, 2021 at 04:14:40AM +0000, Duan, Zhenzhong wrote:
-----Original Message----- From: Pavel Hrdina <phrdina@redhat.com> Sent: Friday, June 18, 2021 8:09 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 3/7] conf: introduce TrustDomain element in domain
On Fri, Jun 18, 2021 at 04:50:48PM +0800, Zhenzhong Duan wrote:
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>
Any reason why you are adding a new element that basically copies exactly what <launchSecurity> is doing?
In libvirt it will essentially use `confidential-guest-support` which is used for launchSecurity so there is no need to duplicate the code and the XML element.
It could look like this:
<launchSecurity type='tdx'> <policy>0x0001</policy> </launchSecurity>
We would have to reorganize the <launchSecurity> documentation a little bit but otherwise there is nothing blocking us to have single element to specify different type of encrypted/confidential/secure/... VMs.
We had ever made a patch working as you suggested. It has advantage of only using one element for all. The main reason I chose the other way is because this way having quite less code change, as it avoid many mux and branch code. See below:
Using < launchSecurity>:
docs/schemas/domaincommon.rng | 90 +++++---- src/conf/domain_conf.c | 182 +++++++++++++++--- src/conf/domain_conf.h | 19 +- src/conf/virconftypes.h | 6 + src/qemu/qemu_cgroup.c | 3 +- src/qemu/qemu_command.c | 5 +- src/qemu/qemu_driver.c | 4 +- src/qemu/qemu_firmware.c | 5 +- src/qemu/qemu_namespace.c | 4 +- src/qemu/qemu_process.c | 12 +- src/qemu/qemu_validate.c | 30 ++- src/security/security_dac.c | 4 +-
vs. Using <TrustDomain>:
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 ++
I'm also irresolute on which to choose, I'll use <launchSecurity> if you think it's better.
Reusing <launchSecurity> is likely to be better for downstream consumers of libvirt too. So the extra code in libvirt is not a big deal. 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 :|

QEMU will provides 'tdx-guest' object which is used to launch encrypted VMs on Intel platform using TDX feature. The tag <TrustDomain> can be used to launch a TDX guest. A typical TDX guest launch command line looks like: $QEMU ... \ -object tdx-guest,id=tdx0,debug=on \ -machine q35, confidential-guest-support=tdx0,kvm-type=tdx,pic=no,kernel_irqchip=split Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/qemu/qemu_command.c | 31 +++++++++++++++ .../.trust-domain-tdx.xml.swo | Bin 0 -> 12288 bytes tests/qemuxml2argvdata/trust-domain-tdx.args | 32 ++++++++++++++++ tests/qemuxml2argvdata/trust-domain-tdx.xml | 36 ++++++++++++++++++ tests/qemuxml2argvtest.c | 3 ++ 5 files changed, 102 insertions(+) create mode 100644 tests/qemuxml2argvdata/.trust-domain-tdx.xml.swo create mode 100644 tests/qemuxml2argvdata/trust-domain-tdx.args create mode 100644 tests/qemuxml2argvdata/trust-domain-tdx.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ea513693f7..1e14c95a49 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6974,6 +6974,9 @@ qemuBuildMachineCommandLine(virCommand *cmd, } } + if (def->tdx) + virBufferAddLit(&buf, ",confidential-guest-support=tdx0,kvm-type=tdx"); + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) { if (priv->pflash0) virBufferAsprintf(&buf, ",pflash0=%s", priv->pflash0->nodeformat); @@ -9860,6 +9863,31 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, return 0; } +static int +qemuBuildTDXCommandLine(virDomainObj *vm, virCommand *cmd, + virDomainTDXDef *tdx) +{ + g_autoptr(virJSONValue) props = NULL; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + qemuDomainObjPrivate *priv = vm->privateData; + + if (!tdx) + return 0; + + VIR_DEBUG("policy=0x%x", tdx->policy); + + if (qemuMonitorCreateObjectProps(&props, "tdx-guest", "tdx0", + "B:debug", !!(tdx->policy & 1)) < 0) + return -1; + + if (qemuBuildObjectCommandlineFromJSON(&buf, props, priv->qemuCaps) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); + virCommandAddArgBuffer(cmd, &buf); + return 0; +} + static int qemuBuildVMCoreInfoCommandLine(virCommand *cmd, const virDomainDef *def) @@ -10562,6 +10590,9 @@ qemuBuildCommandLine(virQEMUDriver *driver, if (qemuBuildSEVCommandLine(vm, cmd, def->sev) < 0) return NULL; + if (qemuBuildTDXCommandLine(vm, cmd, def->tdx) < 0) + return NULL; + if (snapshot) virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL); diff --git a/tests/qemuxml2argvdata/.trust-domain-tdx.xml.swo b/tests/qemuxml2argvdata/.trust-domain-tdx.xml.swo new file mode 100644 index 0000000000000000000000000000000000000000..2835d4a14342651d239657fb1531318de3eff8e8 GIT binary patch literal 12288 zcmeI2zmMER6vrpfAcgR=Ok<8>D&N?f+~!X5x<KKQ2%P{axq{{x&&*~=XM4=dc(Ysa z4<J#~&=4dF#J>Rasc7k;p+lmDH)HSK<#Gt6jChv5^7+kop5J_CeA4M&l^x$ZO7?ei z0@oXa+$f)X`sOEB$#-AALaZ@9g#YW3J#SM{Yt{Pn!_MoEYPCvlW&7EMiA=3JV?C>N zwba(1^d0lcdB;9eO}}dD3AYcIl6%g)?VV4hX}E4vFIT%TdLbD;A^{}uoCL0s8<RYK zmhbMolf3=bgXf%&b|ioVkN^@u0!RP}AOR$R1YTqUzPmy`hXuSeE@EfAU%7A}AMu6+ zkN^@u0!RP}AOR$R1dsp{Kmter3A}&=xP+pw67m=n{{O%E`~Q#E3Hb%|HE0bw1nq#X zgMNRFke@-{gC2vv06hd9f+*-Z=(lTx`~><6RD<q<{(hB^KS57G-+~&@J<ty5Wzb(x z!>^zpK|g>(P2Yg<LIOwt2_OL^fCP{L5<mj~Cjtc<I$=waBn7)4dSh?L*4Pk$P-ki_ z)@8QJvMevy_!!LRyoq0TYDS@%mJWHOT56%(n4?im#p~LbHffAh^^CTrRg{gxy6t*D zrZ`pW%5W=bQuS^|J2$!1)|lR@OFY7~-kQ2rcFflaO%vTpwVKh4Ze9=3G&CS@b3Zdr zOGv++x2g0QTkon%Y)oo*IxG%2aVf2GZY)Szy@b?fnPOdWu~46fE@kCosBd-rVSG0v z8U_<!JEIH9$K{7g&pgibR;a<lz{&0!=a28OkKaFfaHofc==_{H)?$;EH?Vo3PZ|n{ z8)^BYjjaf48N*d=#3>EQVRL6RjKuwh+F)|cy|E?hon@77W8Zb^*3PRYUF}a#rZ)?= zb%pbD?u-<sJrS0>MJb^~Yt{wZMuHU{tg2wcN+1asd>kJ`qoFg8lr{7DQz^E=U=pGH z1S~Ef?!6e+2)Q-~HN0ZOcMG64Tq;;t$NhqN!|vZcKHQzlf{g=^8j=Ta3AbV~qr+<9 zuyL`_Er9Aon(t<`Tr8V{1!Me3hPM_=(e+7JbD<jOai39GpVxwx@UexVXcfJ+FnFXI zW7o-WGCt7n(Q=X><XKj*rwnlld~^Te9Y&(5@3kz&ExtFGl}wf7^Yq~6-d=hznetRl l_e4IGRlc7c6f9Z;#c*26v*T2-7$C*)Yh*krr^^OT#y{J@p5y=k literal 0 HcmV?d00001 diff --git a/tests/qemuxml2argvdata/trust-domain-tdx.args b/tests/qemuxml2argvdata/trust-domain-tdx.args new file mode 100644 index 0000000000..45c8ed595f --- /dev/null +++ b/tests/qemuxml2argvdata/trust-domain-tdx.args @@ -0,0 +1,32 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name QEMUGuest1 \ +-S \ +-machine pc-q35-3.0,accel=kvm,usb=off,dump-guest-core=off,confidential-guest-support=tdx0,\ +kvm-type=tdx,pic=no,kernel_irqchip=split \ +-device loader,file=/path/to/TDVF.fd,id=fd0 \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-object tdx-guest,policy=0x1,id=tdx0 diff --git a/tests/qemuxml2argvdata/trust-domain-tdx.xml b/tests/qemuxml2argvdata/trust-domain-tdx.xml new file mode 100644 index 0000000000..e0f0b77866 --- /dev/null +++ b/tests/qemuxml2argvdata/trust-domain-tdx.xml @@ -0,0 +1,36 @@ +<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-q35-3.0'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <ioapic driver='qemu'/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> + <TrustDomain type='tdx'> + <policy>0x0001</policy> + </TrustDomain> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 7fed871c9e..ac5dc6b40b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3456,6 +3456,9 @@ mymain(void) DO_TEST_CAPS_VER("launch-security-sev", "2.12.0"); DO_TEST_CAPS_VER("launch-security-sev", "6.0.0"); DO_TEST_CAPS_VER("launch-security-sev-missing-platform-info", "2.12.0"); + DO_TEST("trust-domain-tdx", + QEMU_CAPS_KVM, + QEMU_CAPS_TDX_GUEST); DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory"); DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages"); -- 2.25.1

TDX guest need a specific firmware TDVF to bootup, add a new element in TrustDomain element for that purpose, like below: <TrustDomain type='tdx'> <policy>0x0001</policy> <loader>/path/to/TDVF-binary</loader> </TrustDomain> Qemu command line looks like: $QEMU ... \ -device loader,file= /path/to/TDVF-binary,id=fd0 Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- docs/schemas/domaincommon.rng | 3 +++ src/conf/domain_conf.c | 6 ++++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 4 ++++ tests/genericxml2xmlindata/trust-domain-tdx.xml | 1 + tests/qemuxml2argvdata/trust-domain-tdx.xml | 1 + 6 files changed, 16 insertions(+) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 2b39a01e84..b439012648 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -530,6 +530,9 @@ <element name="policy"> <ref name="hexuint"/> </element> + <element name="loader"> + <data type="string"/> + </element> </interleave> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a51db088c1..0513d6d016 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3515,6 +3515,7 @@ virDomainTDXDefFree(virDomainTDXDef *def) if (!def) return; + g_free(def->loader); g_free(def); } @@ -14849,6 +14850,7 @@ virDomainTDXDefParseXML(xmlNodePtr tdxNode, } def->policy = policy; + def->loader = virXPathString("string(./loader)", ctxt); return def; @@ -26950,6 +26952,10 @@ virDomainTDXDefFormat(virBuffer *buf, virDomainTDXDef *tdx) virBufferAsprintf(buf, "<TrustDomain type='tdx'>\n"); virBufferAdjustIndent(buf, 2); virBufferAsprintf(buf, "<policy>0x%04x</policy>\n", tdx->policy); + + if (tdx->loader) + virBufferEscapeString(buf, "<loader>%s</loader>\n", tdx->loader); + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</TrustDomain>\n"); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7cb5061c8c..cabfc80b4b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2671,6 +2671,7 @@ typedef enum { struct _virDomainTDXDef { int sectype; /* enum virDomainTrustDomain */ unsigned int policy; /* bit 0 set hint debug enabled, other bit reserved */ + char *loader; /* patch for TDX TDVF firmware */ }; typedef enum { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1e14c95a49..891d795b02 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9885,6 +9885,10 @@ qemuBuildTDXCommandLine(virDomainObj *vm, virCommand *cmd, virCommandAddArg(cmd, "-object"); virCommandAddArgBuffer(cmd, &buf); + + virCommandAddArg(cmd, "-device"); + virCommandAddArgFormat(cmd, "loader,id=fd0,file=%s", tdx->loader); + return 0; } diff --git a/tests/genericxml2xmlindata/trust-domain-tdx.xml b/tests/genericxml2xmlindata/trust-domain-tdx.xml index 7a56cf0e92..7422f0c06f 100644 --- a/tests/genericxml2xmlindata/trust-domain-tdx.xml +++ b/tests/genericxml2xmlindata/trust-domain-tdx.xml @@ -16,6 +16,7 @@ </devices> <TrustDomain type='tdx'> <policy>0x0001</policy> + <loader>/path/to/TDVF-binary</loader> </TrustDomain> </domain> diff --git a/tests/qemuxml2argvdata/trust-domain-tdx.xml b/tests/qemuxml2argvdata/trust-domain-tdx.xml index e0f0b77866..1d8ad45c4c 100644 --- a/tests/qemuxml2argvdata/trust-domain-tdx.xml +++ b/tests/qemuxml2argvdata/trust-domain-tdx.xml @@ -32,5 +32,6 @@ </devices> <TrustDomain type='tdx'> <policy>0x0001</policy> + <loader>/path/to/TDVF-binary</loader> </TrustDomain> </domain> -- 2.25.1

On Fri, Jun 18, 2021 at 16:50:50 +0800, Zhenzhong Duan wrote:
TDX guest need a specific firmware TDVF to bootup, add a new element in TrustDomain element for that purpose, like below:
<TrustDomain type='tdx'> <policy>0x0001</policy> <loader>/path/to/TDVF-binary</loader> </TrustDomain>
Qemu command line looks like:
$QEMU ... \ -device loader,file= /path/to/TDVF-binary,id=fd0
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- docs/schemas/domaincommon.rng | 3 +++ src/conf/domain_conf.c | 6 ++++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 4 ++++ tests/genericxml2xmlindata/trust-domain-tdx.xml | 1 + tests/qemuxml2argvdata/trust-domain-tdx.xml | 1 + 6 files changed, 16 insertions(+)
[...]
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7cb5061c8c..cabfc80b4b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2671,6 +2671,7 @@ typedef enum { struct _virDomainTDXDef { int sectype; /* enum virDomainTrustDomain */ unsigned int policy; /* bit 0 set hint debug enabled, other bit reserved */ + char *loader; /* patch for TDX TDVF firmware */ };
typedef enum { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1e14c95a49..891d795b02 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9885,6 +9885,10 @@ qemuBuildTDXCommandLine(virDomainObj *vm, virCommand *cmd,
virCommandAddArg(cmd, "-object"); virCommandAddArgBuffer(cmd, &buf); + + virCommandAddArg(cmd, "-device"); + virCommandAddArgFormat(cmd, "loader,id=fd0,file=%s", tdx->loader); + return 0; }
This again mixes config changes with qemu-specific changes.

On Fri, Jun 18, 2021 at 04:50:50PM +0800, Zhenzhong Duan wrote:
TDX guest need a specific firmware TDVF to bootup, add a new element in TrustDomain element for that purpose, like below:
<TrustDomain type='tdx'> <policy>0x0001</policy> <loader>/path/to/TDVF-binary</loader> </TrustDomain>
Looking into QEMU patches and if I understand it correctly this loader is supposed to be used instead of UEFI or BIOS? If that's true I don't think it should be here as we already have XML bits to specify VM loader. We could use something like this: <os> <loader type='generic'>/path/to/TDVF-binary</loader> </os> Currently supported types are: - `rom` which is translated to -bios /path/to/bios.bin - `pflash` which is translated to -drive file=/path/to/uefi.fd,if=pflash,format=raw,... And we could add a new type called 'generic', 'device', 'binary' or something else which would be translated to: -device loader,file=/path/to/TDVF-binary,... Pavel
Qemu command line looks like:
$QEMU ... \ -device loader,file= /path/to/TDVF-binary,id=fd0
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- docs/schemas/domaincommon.rng | 3 +++ src/conf/domain_conf.c | 6 ++++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 4 ++++ tests/genericxml2xmlindata/trust-domain-tdx.xml | 1 + tests/qemuxml2argvdata/trust-domain-tdx.xml | 1 + 6 files changed, 16 insertions(+)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 2b39a01e84..b439012648 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -530,6 +530,9 @@ <element name="policy"> <ref name="hexuint"/> </element> + <element name="loader"> + <data type="string"/> + </element> </interleave> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a51db088c1..0513d6d016 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3515,6 +3515,7 @@ virDomainTDXDefFree(virDomainTDXDef *def) if (!def) return;
+ g_free(def->loader); g_free(def); }
@@ -14849,6 +14850,7 @@ virDomainTDXDefParseXML(xmlNodePtr tdxNode, }
def->policy = policy; + def->loader = virXPathString("string(./loader)", ctxt);
return def;
@@ -26950,6 +26952,10 @@ virDomainTDXDefFormat(virBuffer *buf, virDomainTDXDef *tdx) virBufferAsprintf(buf, "<TrustDomain type='tdx'>\n"); virBufferAdjustIndent(buf, 2); virBufferAsprintf(buf, "<policy>0x%04x</policy>\n", tdx->policy); + + if (tdx->loader) + virBufferEscapeString(buf, "<loader>%s</loader>\n", tdx->loader); + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</TrustDomain>\n"); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7cb5061c8c..cabfc80b4b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2671,6 +2671,7 @@ typedef enum { struct _virDomainTDXDef { int sectype; /* enum virDomainTrustDomain */ unsigned int policy; /* bit 0 set hint debug enabled, other bit reserved */ + char *loader; /* patch for TDX TDVF firmware */ };
typedef enum { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1e14c95a49..891d795b02 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9885,6 +9885,10 @@ qemuBuildTDXCommandLine(virDomainObj *vm, virCommand *cmd,
virCommandAddArg(cmd, "-object"); virCommandAddArgBuffer(cmd, &buf); + + virCommandAddArg(cmd, "-device"); + virCommandAddArgFormat(cmd, "loader,id=fd0,file=%s", tdx->loader); + return 0; }
diff --git a/tests/genericxml2xmlindata/trust-domain-tdx.xml b/tests/genericxml2xmlindata/trust-domain-tdx.xml index 7a56cf0e92..7422f0c06f 100644 --- a/tests/genericxml2xmlindata/trust-domain-tdx.xml +++ b/tests/genericxml2xmlindata/trust-domain-tdx.xml @@ -16,6 +16,7 @@ </devices> <TrustDomain type='tdx'> <policy>0x0001</policy> + <loader>/path/to/TDVF-binary</loader> </TrustDomain> </domain>
diff --git a/tests/qemuxml2argvdata/trust-domain-tdx.xml b/tests/qemuxml2argvdata/trust-domain-tdx.xml index e0f0b77866..1d8ad45c4c 100644 --- a/tests/qemuxml2argvdata/trust-domain-tdx.xml +++ b/tests/qemuxml2argvdata/trust-domain-tdx.xml @@ -32,5 +32,6 @@ </devices> <TrustDomain type='tdx'> <policy>0x0001</policy> + <loader>/path/to/TDVF-binary</loader> </TrustDomain> </domain> -- 2.25.1

-----Original Message----- From: Pavel Hrdina <phrdina@redhat.com> Sent: Friday, June 18, 2021 8:34 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 5/7] qemu: add support to TDVF firmware loader
On Fri, Jun 18, 2021 at 04:50:50PM +0800, Zhenzhong Duan wrote:
TDX guest need a specific firmware TDVF to bootup, add a new element in TrustDomain element for that purpose, like below:
<TrustDomain type='tdx'> <policy>0x0001</policy> <loader>/path/to/TDVF-binary</loader> </TrustDomain>
Looking into QEMU patches and if I understand it correctly this loader is supposed to be used instead of UEFI or BIOS? Yes.
If that's true I don't think it should be here as we already have XML bits to specify VM loader.
We could use something like this:
<os> <loader type='generic'>/path/to/TDVF-binary</loader> </os>
Currently supported types are:
- `rom` which is translated to
-bios /path/to/bios.bin
- `pflash` which is translated to
-drive file=/path/to/uefi.fd,if=pflash,format=raw,...
And we could add a new type called 'generic', 'device', 'binary' or something else which would be translated to:
-device loader,file=/path/to/TDVF-binary,...
Thanks for your suggestion, the main reason is I see only TDX guest using firmware in such a special way, So I move <loader> in TDX specific element <TrustDomain>. I'll change to <os>.<loader> if you think it's better. Thanks Zhenzhong

On Mon, Jun 21, 2021 at 03:19:55AM +0000, Duan, Zhenzhong wrote:
-----Original Message----- From: Pavel Hrdina <phrdina@redhat.com> Sent: Friday, June 18, 2021 8:34 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 5/7] qemu: add support to TDVF firmware loader
On Fri, Jun 18, 2021 at 04:50:50PM +0800, Zhenzhong Duan wrote:
TDX guest need a specific firmware TDVF to bootup, add a new element in TrustDomain element for that purpose, like below:
<TrustDomain type='tdx'> <policy>0x0001</policy> <loader>/path/to/TDVF-binary</loader> </TrustDomain>
Looking into QEMU patches and if I understand it correctly this loader is supposed to be used instead of UEFI or BIOS? Yes.
If that's true I don't think it should be here as we already have XML bits to specify VM loader.
We could use something like this:
<os> <loader type='generic'>/path/to/TDVF-binary</loader> </os>
Currently supported types are:
- `rom` which is translated to
-bios /path/to/bios.bin
- `pflash` which is translated to
-drive file=/path/to/uefi.fd,if=pflash,format=raw,...
And we could add a new type called 'generic', 'device', 'binary' or something else which would be translated to:
-device loader,file=/path/to/TDVF-binary,...
Thanks for your suggestion, the main reason is I see only TDX guest using firmware in such a special way, So I move <loader> in TDX specific element <TrustDomain>. I'll change to <os>.<loader> if you think it's better.
I understand your original motivation but it would just create a confusion for users of libvirt and management application as they would have to look at two different places in the XML to figure out if and what firmware is used for VM. So yes, we would prefer to use <os>.<loader>. Pavel

On Mon, Jun 21, 2021 at 03:19:55AM +0000, Duan, Zhenzhong wrote:
-----Original Message----- From: Pavel Hrdina <phrdina@redhat.com> Sent: Friday, June 18, 2021 8:34 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 5/7] qemu: add support to TDVF firmware loader
On Fri, Jun 18, 2021 at 04:50:50PM +0800, Zhenzhong Duan wrote:
TDX guest need a specific firmware TDVF to bootup, add a new element in TrustDomain element for that purpose, like below:
<TrustDomain type='tdx'> <policy>0x0001</policy> <loader>/path/to/TDVF-binary</loader> </TrustDomain>
Looking into QEMU patches and if I understand it correctly this loader is supposed to be used instead of UEFI or BIOS? Yes.
If that's true I don't think it should be here as we already have XML bits to specify VM loader.
We could use something like this:
<os> <loader type='generic'>/path/to/TDVF-binary</loader> </os>
Currently supported types are:
- `rom` which is translated to
-bios /path/to/bios.bin
- `pflash` which is translated to
-drive file=/path/to/uefi.fd,if=pflash,format=raw,...
And we could add a new type called 'generic', 'device', 'binary' or something else which would be translated to:
-device loader,file=/path/to/TDVF-binary,...
Thanks for your suggestion, the main reason is I see only TDX guest using firmware in such a special way, So I move <loader> in TDX specific element <TrustDomain>. I'll change to <os>.<loader> if you think it's better.
Note that SEV does actually need a special loader too. The standard UEFI builds don't support SEV, so we need to pick a special UEFI build just for SEV. QEMU has a concept of firmware descriptors that let the host tell libvirt what features each firmware supports. This lets libvirt automatically pick the right firmware binary to use. Even if the TDX firmware is not a normal UEFI / EDK2 binary, I think we really ought to figure out a way to use the firmware descriptors in QEMU to report the existsance of the TDX firmware inary on the host. This would let libvirt automatically pick a TDX loader. 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 :|

TDX guest requires some special parameters in qemu command line. They are "pic=no,kernel_irqchip=split" without which guest fails to bootup. PMU has a big impact to the performance of TDX guest. So always disable PMU except it's forcely enabled. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/qemu/qemu_command.c | 6 +++++- src/qemu/qemu_validate.c | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 891d795b02..bffa3fdf10 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6599,6 +6599,10 @@ qemuBuildCpuCommandLine(virCommand *cmd, virTristateSwitch pmu = def->features[VIR_DOMAIN_FEATURE_PMU]; virBufferAsprintf(&buf, ",pmu=%s", virTristateSwitchTypeToString(pmu)); + } else if (!def->features[VIR_DOMAIN_FEATURE_PMU] && def->tdx) { + /* PMU lead to performance drop if TDX enabled, disable PMU by default */ + virBufferAsprintf(&buf, ",pmu=%s", + virTristateSwitchTypeToString(VIR_TRISTATE_SWITCH_OFF)); } if (def->cpu && def->cpu->cache) { @@ -6975,7 +6979,7 @@ qemuBuildMachineCommandLine(virCommand *cmd, } if (def->tdx) - virBufferAddLit(&buf, ",confidential-guest-support=tdx0,kvm-type=tdx"); + virBufferAddLit(&buf, ",confidential-guest-support=tdx0,kvm-type=tdx,pic=no"); if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) { if (priv->pflash0) diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 2efd011cc0..3c3a00c7e8 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -202,6 +202,12 @@ qemuValidateDomainDefFeatures(const virDomainDef *def, return -1; } } + if (def->tdx && (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP) + || def->features[i] != VIR_DOMAIN_IOAPIC_QEMU)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("TDX guest needs split kernel irqchip")); + return -1; + } break; case VIR_DOMAIN_FEATURE_HPT: -- 2.25.1

On Fri, Jun 18, 2021 at 16:50:51 +0800, Zhenzhong Duan wrote:
TDX guest requires some special parameters in qemu command line. They are "pic=no,kernel_irqchip=split" without which guest fails to bootup.
PMU has a big impact to the performance of TDX guest. So always disable PMU except it's forcely enabled.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/qemu/qemu_command.c | 6 +++++- src/qemu/qemu_validate.c | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 891d795b02..bffa3fdf10 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6599,6 +6599,10 @@ qemuBuildCpuCommandLine(virCommand *cmd, virTristateSwitch pmu = def->features[VIR_DOMAIN_FEATURE_PMU]; virBufferAsprintf(&buf, ",pmu=%s", virTristateSwitchTypeToString(pmu)); + } else if (!def->features[VIR_DOMAIN_FEATURE_PMU] && def->tdx) { + /* PMU lead to performance drop if TDX enabled, disable PMU by default */ + virBufferAsprintf(&buf, ",pmu=%s", + virTristateSwitchTypeToString(VIR_TRISTATE_SWITCH_OFF)); }
This must be done in a way that will be visible in the XML rather than silently hiding it in the command line generator code. Also it feels very unjustified, it's bad for performance, but is it guaranteed to always be like this?
if (def->cpu && def->cpu->cache) {
[...]
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 2efd011cc0..3c3a00c7e8 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -202,6 +202,12 @@ qemuValidateDomainDefFeatures(const virDomainDef *def, return -1; } } + if (def->tdx && (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP) + || def->features[i] != VIR_DOMAIN_IOAPIC_QEMU)) {
Our coding style usually has boolean operators at the end of the previous line in multi-line statements.
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("TDX guest needs split kernel irqchip")); + return -1; + } break;
case VIR_DOMAIN_FEATURE_HPT: -- 2.25.1

-----Original Message----- From: Peter Krempa <pkrempa@redhat.com> Sent: Friday, June 18, 2021 7:22 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 6/7] qemu: force special features enabled for TDX guest
On Fri, Jun 18, 2021 at 16:50:51 +0800, Zhenzhong Duan wrote:
TDX guest requires some special parameters in qemu command line. They are "pic=no,kernel_irqchip=split" without which guest fails to bootup.
PMU has a big impact to the performance of TDX guest. So always disable PMU except it's forcely enabled.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/qemu/qemu_command.c | 6 +++++- src/qemu/qemu_validate.c | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 891d795b02..bffa3fdf10 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6599,6 +6599,10 @@ qemuBuildCpuCommandLine(virCommand *cmd, virTristateSwitch pmu = def->features[VIR_DOMAIN_FEATURE_PMU]; virBufferAsprintf(&buf, ",pmu=%s", virTristateSwitchTypeToString(pmu)); + } else if (!def->features[VIR_DOMAIN_FEATURE_PMU] && def->tdx) { + /* PMU lead to performance drop if TDX enabled, disable PMU by default */ + virBufferAsprintf(&buf, ",pmu=%s", + + virTristateSwitchTypeToString(VIR_TRISTATE_SWITCH_OFF)); }
This must be done in a way that will be visible in the XML rather than silently hiding it in the command line generator code. Thanks for your suggestion, we will drop this chunk.
Also it feels very unjustified, it's bad for performance, but is it guaranteed to always be like this?
No, we are optimizing the performance continuously, I believe the performance will be better and better.
if (def->cpu && def->cpu->cache) {
[...]
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 2efd011cc0..3c3a00c7e8 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -202,6 +202,12 @@ qemuValidateDomainDefFeatures(const virDomainDef *def, return -1; } } + if (def->tdx && (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP) + || def->features[i] != + VIR_DOMAIN_IOAPIC_QEMU)) {
Our coding style usually has boolean operators at the end of the previous line in multi-line statements.
Will fix. Thanks Zhenzhong

Implement trust domain check for INTEL TDX (Trust Domain eXtention) in order to invalidate the qemu capabilities cache in case the availability of the feature changed. For INTEL TDX the verification is: - checking if /sys/module/kvm_intel/parameters/tdx contains the value 'Y': meaning TDX is enabled in the host kernel. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/qemu/qemu_capabilities.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 5e54d7e306..8f8802c121 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -4767,6 +4767,24 @@ virQEMUCapsKVMSupportsSecureGuestAMD(void) } +/* + * Check whether INTEL Trust Domain Extention (x86) is enabled + */ +static bool +virQEMUCapsKVMSupportsSecureGuestINTEL(void) +{ + g_autofree char *modValue = NULL; + + if (virFileReadValueString(&modValue, "/sys/module/kvm_intel/parameters/tdx") < 0) + return false; + + if (modValue[0] != 'Y') + return false; + + return true; +} + + /* * Check whether the secure guest functionality is enabled. * See the specific architecture function for details on the verifications made. @@ -4782,6 +4800,9 @@ virQEMUCapsKVMSupportsSecureGuest(void) if (ARCH_IS_X86(arch)) return virQEMUCapsKVMSupportsSecureGuestAMD(); + if (ARCH_IS_X86(arch)) + return virQEMUCapsKVMSupportsSecureGuestINTEL(); + return false; } -- 2.25.1

On Fri, Jun 18, 2021 at 16:50:45 +0800, Zhenzhong Duan wrote:
* What's TDX? TDX stands for Trust Domain Extensions which isolates VMs from the virtual-machine manager (VMM)/hypervisor and any other software on the platform.
To support TDX, multiple software components, not only KVM but also QEMU, guest Linux and virtual bios, need to be updated. For more details, please check link[1], there are TDX spec links and public repository link at github for each software component.
This patchset is another software component to extend libvirt to support TDX, with which one can start a VM from high level rather than running qemu directly.
* The goal of this RFC patch The purpose of this post is to get feedback early on high level design issue of libvirt enhancement for TDX. Referenced much on AMD SEV implemention at link[2].
* Patch organization
- patch 1-2: Support query of TDX capabilities. - patch 3-6: Add a new xml element 'TrustDomain' for TDX support. - patch 7: Sure kvmSupportsSecureGuest cache updated.
Using these patches we have succesfully booted and tested a guest both with and without TDX enabled.
[1] https://lkml.org/lkml/2020/11/16/1106 [2] https://github.com/codomania/libvirt/commits/v9
Could you please also point to the relevant qemu patches? The first commit mentions 'query-tdx-capabilities' which is not in qemu upstream yet.

-----Original Message----- From: Peter Krempa <pkrempa@redhat.com> Sent: Friday, June 18, 2021 7:07 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 0/7] LIBVIRT: X86: TDX support
On Fri, Jun 18, 2021 at 16:50:45 +0800, Zhenzhong Duan wrote:
* What's TDX? TDX stands for Trust Domain Extensions which isolates VMs from the virtual-machine manager (VMM)/hypervisor and any other software on the platform.
To support TDX, multiple software components, not only KVM but also QEMU, guest Linux and virtual bios, need to be updated. For more details, please check link[1], there are TDX spec links and public repository link at github for each software component.
This patchset is another software component to extend libvirt to support TDX, with which one can start a VM from high level rather than running qemu directly.
* The goal of this RFC patch The purpose of this post is to get feedback early on high level design issue of libvirt enhancement for TDX. Referenced much on AMD SEV implemention at link[2].
* Patch organization
- patch 1-2: Support query of TDX capabilities. - patch 3-6: Add a new xml element 'TrustDomain' for TDX support. - patch 7: Sure kvmSupportsSecureGuest cache updated.
Using these patches we have succesfully booted and tested a guest both with and without TDX enabled.
[1] https://lkml.org/lkml/2020/11/16/1106 [2] https://github.com/codomania/libvirt/commits/v9
Could you please also point to the relevant qemu patches?
The first commit mentions 'query-tdx-capabilities' which is not in qemu upstream yet. Hi Peter,
Sorry, seems qemu patches link is missed in [1]. List all links below for your reference. kvm TDX branch: https://github.com/intel/tdx/tree/kvm TDX guest branch: https://github.com/intel/tdx/tree/guest TDVF branch: https://github.com/tianocore/edk2-staging/tree/TDVF qemu TDX branch: https://github.com/intel/qemu-tdx/tree/tdx Thanks Zhenzhong

On Mon, Jun 21, 2021 at 02:14:32 +0000, Duan, Zhenzhong wrote:
-----Original Message----- From: Peter Krempa <pkrempa@redhat.com> Sent: Friday, June 18, 2021 7:07 PM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 0/7] LIBVIRT: X86: TDX support
On Fri, Jun 18, 2021 at 16:50:45 +0800, Zhenzhong Duan wrote:
* What's TDX? TDX stands for Trust Domain Extensions which isolates VMs from the virtual-machine manager (VMM)/hypervisor and any other software on the platform.
To support TDX, multiple software components, not only KVM but also QEMU, guest Linux and virtual bios, need to be updated. For more details, please check link[1], there are TDX spec links and public repository link at github for each software component.
This patchset is another software component to extend libvirt to support TDX, with which one can start a VM from high level rather than running qemu directly.
* The goal of this RFC patch The purpose of this post is to get feedback early on high level design issue of libvirt enhancement for TDX. Referenced much on AMD SEV implemention at link[2].
* Patch organization
- patch 1-2: Support query of TDX capabilities. - patch 3-6: Add a new xml element 'TrustDomain' for TDX support. - patch 7: Sure kvmSupportsSecureGuest cache updated.
Using these patches we have succesfully booted and tested a guest both with and without TDX enabled.
[1] https://lkml.org/lkml/2020/11/16/1106 [2] https://github.com/codomania/libvirt/commits/v9
Could you please also point to the relevant qemu patches?
The first commit mentions 'query-tdx-capabilities' which is not in qemu upstream yet. Hi Peter,
Sorry, seems qemu patches link is missed in [1]. List all links below for your reference.
kvm TDX branch: https://github.com/intel/tdx/tree/kvm TDX guest branch: https://github.com/intel/tdx/tree/guest TDVF branch: https://github.com/tianocore/edk2-staging/tree/TDVF qemu TDX branch: https://github.com/intel/qemu-tdx/tree/tdx
In my quick search I didn't find any reference to those patches on the qemu-devel mailing list. Please note that libvirt accepts only features which are supported by the upstream releases [1] of the hypervisor in question. Thus if the qemu part indeed wasn't yet posted for review to qemu-devel you should do so if you want this series to be accepted in libvirt. [1] Pushed upstream waiting for the next release is okay.

-----Original Message----- From: Peter Krempa <pkrempa@redhat.com> Sent: Monday, June 21, 2021 1:06 AM To: Duan, Zhenzhong <zhenzhong.duan@intel.com> Cc: libvir-list@redhat.com; Yamahata, Isaku <isaku.yamahata@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Qiang, Chenyi <chenyi.qiang@intel.com> Subject: Re: [RFC PATCH 0/7] LIBVIRT: X86: TDX support ...
Using these patches we have succesfully booted and tested a guest both with and without TDX enabled.
[1] https://lkml.org/lkml/2020/11/16/1106 [2] https://github.com/codomania/libvirt/commits/v9
Could you please also point to the relevant qemu patches?
The first commit mentions 'query-tdx-capabilities' which is not in qemu upstream yet. Hi Peter,
Sorry, seems qemu patches link is missed in [1]. List all links below for your reference.
kvm TDX branch: https://github.com/intel/tdx/tree/kvm TDX guest branch: https://github.com/intel/tdx/tree/guest TDVF branch: https://github.com/tianocore/edk2-staging/tree/TDVF qemu TDX branch: https://github.com/intel/qemu-tdx/tree/tdx
In my quick search I didn't find any reference to those patches on the qemu-devel mailing list. Please note that libvirt accepts only features which are supported by the upstream releases [1] of the hypervisor in question.
Thus if the qemu part indeed wasn't yet posted for review to qemu-devel you should do so if you want this series to be accepted in libvirt.
[1] Pushed upstream waiting for the next release is okay.
For qemu-devel, here is the reference. https://lore.kernel.org/qemu-devel/cover.1613188118.git.isaku.yamahata@intel... I'm not sure why lists.nongnu.org search doesn't show result with TDX keyword. Thanks, Isaku Yamahata

On Mon, Jun 21, 2021 at 19:28:26 +0000, Yamahata, Isaku wrote: [...]
Sorry, seems qemu patches link is missed in [1]. List all links below for your reference.
kvm TDX branch: https://github.com/intel/tdx/tree/kvm TDX guest branch: https://github.com/intel/tdx/tree/guest TDVF branch: https://github.com/tianocore/edk2-staging/tree/TDVF qemu TDX branch: https://github.com/intel/qemu-tdx/tree/tdx
In my quick search I didn't find any reference to those patches on the qemu-devel mailing list. Please note that libvirt accepts only features which are supported by the upstream releases [1] of the hypervisor in question.
Thus if the qemu part indeed wasn't yet posted for review to qemu-devel you should do so if you want this series to be accepted in libvirt.
[1] Pushed upstream waiting for the next release is okay.
For qemu-devel, here is the reference. https://lore.kernel.org/qemu-devel/cover.1613188118.git.isaku.yamahata@intel... I'm not sure why lists.nongnu.org search doesn't show result with TDX keyword.
The qemu patchset you've mentioned doesn't seem to correspond entirely to what this libvirt patchset is adding. I was looking for the 'query-tdx-capabilities' QMP command which is used in patch 1 of the libvirt series, but the patchset you've mentioned doesn't add it at all. As noted libvirt requires that the features exposed by libvirt are accepted by upstream qemu before adding support for them, to prevent maintenance of diverged or non-existing features.
participants (6)
-
Daniel P. Berrangé
-
Duan, Zhenzhong
-
Pavel Hrdina
-
Peter Krempa
-
Yamahata, Isaku
-
Zhenzhong Duan