Enable building for ppc64le

This commit is contained in:
Eduard Abdullin 2025-12-22 07:34:47 +00:00 committed by root
commit b083240f0a
54 changed files with 58530 additions and 2 deletions

View File

@ -0,0 +1,141 @@
From e3233ee7847c0b51267b511038724a0ab8a54484 Mon Sep 17 00:00:00 2001
Message-ID: <e3233ee7847c0b51267b511038724a0ab8a54484.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:16 -0400
Subject: [PATCH] conf: Add Intel TDX Quote Generation Service(QGS) support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add element "quoteGenerationService" to tdx launch security type.
It contains only an optional unix socket address attribute,
when omitted, libvirt will use default QGS server address
"/var/run/tdx-qgs/qgs.socket".
UNIX sockets offer the required functionality with greater
security than vsock, so libvirt only provides support for unix
socket.
XML example:
<launchSecurity type='tdx'>
<policy>0x10000001</policy>
<mrConfigId>xxx</mrConfigId>
<mrOwner>xxx</mrOwner>
<mrOwnerConfig>xxx</mrOwnerConfig>
<quoteGenerationService path='/var/run/tdx-qgs/qgs.socket'/>
</launchSecurity>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
(cherry picked from commit 8214980432191138f052c2e32d12ae284597c8b8)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/conf/domain_conf.c | 35 ++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 2 ++
src/conf/schemas/domaincommon.rng | 9 ++++++++
3 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 92185080a9..38179a7e59 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3895,6 +3895,7 @@ virDomainSecDefFree(virDomainSecDef *def)
g_free(def->data.tdx.mrconfigid);
g_free(def->data.tdx.mrowner);
g_free(def->data.tdx.mrownerconfig);
+ g_free(def->data.tdx.qgs_unix_path);
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
@@ -13911,6 +13912,33 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def,
}
+static int
+virDomainTDXQGSDefParseXML(virDomainTDXDef *def, xmlXPathContextPtr ctxt)
+{
+ g_autofree xmlNodePtr *nodes = NULL;
+ xmlNodePtr node;
+ int n;
+
+ if ((n = virXPathNodeSet("./quoteGenerationService", ctxt, &nodes)) < 0)
+ return -1;
+
+ if (!n)
+ return 0;
+
+ if (n > 1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only a single QGS element is supported"));
+ return -1;
+ }
+ node = nodes[0];
+
+ def->haveQGS = true;
+ def->qgs_unix_path = virXMLPropString(node, "path");
+
+ return 0;
+}
+
+
static int
virDomainTDXDefParseXML(virDomainTDXDef *def,
xmlXPathContextPtr ctxt)
@@ -13930,7 +13958,7 @@ virDomainTDXDefParseXML(virDomainTDXDef *def,
def->mrowner = virXPathString("string(./mrOwner)", ctxt);
def->mrownerconfig = virXPathString("string(./mrOwnerConfig)", ctxt);
- return 0;
+ return virDomainTDXQGSDefParseXML(def, ctxt);
}
@@ -27261,6 +27289,11 @@ virDomainTDXDefFormat(virBuffer *childBuf, virDomainTDXDef *def)
virBufferEscapeString(childBuf, "<mrConfigId>%s</mrConfigId>\n", def->mrconfigid);
virBufferEscapeString(childBuf, "<mrOwner>%s</mrOwner>\n", def->mrowner);
virBufferEscapeString(childBuf, "<mrOwnerConfig>%s</mrOwnerConfig>\n", def->mrownerconfig);
+ if (def->haveQGS) {
+ virBufferAddLit(childBuf, "<quoteGenerationService");
+ virBufferEscapeString(childBuf, " path='%s'", def->qgs_unix_path);
+ virBufferAddLit(childBuf, "/>\n");
+ }
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0ea88e013b..85ef6fbf2c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2965,6 +2965,8 @@ struct _virDomainTDXDef {
char *mrconfigid;
char *mrowner;
char *mrownerconfig;
+ bool haveQGS;
+ char *qgs_unix_path;
};
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 552b2f4ced..93bc128dec 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -652,6 +652,15 @@
<data type="string"/>
</element>
</optional>
+ <optional>
+ <element name="quoteGenerationService">
+ <optional>
+ <attribute name="path">
+ <ref name="absFilePath"/>
+ </attribute>
+ </optional>
+ </element>
+ </optional>
</interleave>
</define>
--
2.51.0

View File

@ -0,0 +1,379 @@
From 3f4f38e2f1f05b0484035f96e61ee0de130d3050 Mon Sep 17 00:00:00 2001
Message-ID: <3f4f38e2f1f05b0484035f96e61ee0de130d3050.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:09 -0400
Subject: [PATCH] conf: Add tdx as launch security type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When 'tdx' is used, the VM will be launched with Intel TDX feature enabled.
TDX feature supports running encrypted VM (Trust Domain, TD) under the
control of KVM. A TD runs in a CPU model which protects the confidentiality
of its memory and its CPU state from other software.
There are four optional child elements. Element policy is 64bit hex, bit 0
is set to enable TDX debug, bit 28 is set to enable sept-ve-disable, other
bits are reserved currently. When policy isn't specified, QEMU will use its
own default value 0x10000000. mrConfigId, mrOwner and mrOwnerConfig are
base64 encoded SHA384 digest string.
For example:
<launchSecurity type='tdx'>
<policy>0x10000001</policy>
<mrConfigId>xxx</mrConfigId>
<mrOwner>xxx</mrOwner>
<mrOwnerConfig>xxx</mrOwnerConfig>
</launchSecurity>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit e919a4dd374535511d962bee2cd64f22f1ac3fa1)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
RHEL: context
---
src/conf/domain_conf.c | 49 +++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 11 +++++++
src/conf/domain_validate.c | 1 +
src/conf/schemas/domaincommon.rng | 32 ++++++++++++++++++++
src/conf/virconftypes.h | 2 ++
src/qemu/qemu_cgroup.c | 1 +
src/qemu/qemu_command.c | 3 ++
src/qemu/qemu_driver.c | 1 +
src/qemu/qemu_firmware.c | 1 +
src/qemu/qemu_namespace.c | 1 +
src/qemu/qemu_process.c | 2 ++
src/qemu/qemu_validate.c | 1 +
src/security/security_dac.c | 2 ++
13 files changed, 107 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 286e59a4c7..92185080a9 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1538,6 +1538,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
"sev",
"sev-snp",
"s390-pv",
+ "tdx",
);
VIR_ENUM_IMPL(virDomainPstoreBackend,
@@ -3890,6 +3891,11 @@ virDomainSecDefFree(virDomainSecDef *def)
g_free(def->data.sev_snp.id_auth);
g_free(def->data.sev_snp.host_data);
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ g_free(def->data.tdx.mrconfigid);
+ g_free(def->data.tdx.mrowner);
+ g_free(def->data.tdx.mrownerconfig);
+ break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -13905,6 +13911,29 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def,
}
+static int
+virDomainTDXDefParseXML(virDomainTDXDef *def,
+ xmlXPathContextPtr ctxt)
+{
+ int rc;
+
+ rc = virXPathULongLongBase("string(./policy)", ctxt, 16, &def->policy);
+ if (rc == 0) {
+ def->havePolicy = true;
+ } else if (rc == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("failed to get launch security policy for launch security type TDX"));
+ return -1;
+ }
+
+ def->mrconfigid = virXPathString("string(./mrConfigId)", ctxt);
+ def->mrowner = virXPathString("string(./mrOwner)", ctxt);
+ def->mrownerconfig = virXPathString("string(./mrOwnerConfig)", ctxt);
+
+ return 0;
+}
+
+
static virDomainSecDef *
virDomainSecDefParseXML(xmlNodePtr lsecNode,
xmlXPathContextPtr ctxt)
@@ -13928,6 +13957,10 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
if (virDomainSEVSNPDefParseXML(&sec->data.sev_snp, ctxt) < 0)
return NULL;
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ if (virDomainTDXDefParseXML(&sec->data.tdx, ctxt) < 0)
+ return NULL;
+ break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
@@ -27219,6 +27252,18 @@ virDomainSEVSNPDefFormat(virBuffer *attrBuf,
}
+static void
+virDomainTDXDefFormat(virBuffer *childBuf, virDomainTDXDef *def)
+{
+ if (def->havePolicy)
+ virBufferAsprintf(childBuf, "<policy>0x%llx</policy>\n", def->policy);
+
+ virBufferEscapeString(childBuf, "<mrConfigId>%s</mrConfigId>\n", def->mrconfigid);
+ virBufferEscapeString(childBuf, "<mrOwner>%s</mrOwner>\n", def->mrowner);
+ virBufferEscapeString(childBuf, "<mrOwnerConfig>%s</mrOwnerConfig>\n", def->mrownerconfig);
+}
+
+
static void
virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec)
{
@@ -27240,6 +27285,10 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec)
virDomainSEVSNPDefFormat(&attrBuf, &childBuf, &sec->data.sev_snp);
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ virDomainTDXDefFormat(&childBuf, &sec->data.tdx);
+ break;
+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e59d2e6c5f..1238f2001f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2924,6 +2924,7 @@ typedef enum {
VIR_DOMAIN_LAUNCH_SECURITY_SEV,
VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP,
VIR_DOMAIN_LAUNCH_SECURITY_PV,
+ VIR_DOMAIN_LAUNCH_SECURITY_TDX,
VIR_DOMAIN_LAUNCH_SECURITY_LAST,
} virDomainLaunchSecurity;
@@ -2958,11 +2959,21 @@ struct _virDomainSEVSNPDef {
};
+struct _virDomainTDXDef {
+ bool havePolicy;
+ unsigned long long policy;
+ char *mrconfigid;
+ char *mrowner;
+ char *mrownerconfig;
+};
+
+
struct _virDomainSecDef {
virDomainLaunchSecurity sectype;
union {
virDomainSEVDef sev;
virDomainSEVSNPDef sev_snp;
+ virDomainTDXDef tdx;
} data;
};
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 522fd0174f..2d4b79032b 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1860,6 +1860,7 @@ virDomainDefLaunchSecurityValidate(const virDomainDef *def)
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
break;
}
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 1b153acc48..552b2f4ced 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -528,6 +528,9 @@
<value>s390-pv</value>
</attribute>
</group>
+ <group>
+ <ref name="launchSecurityTDX"/>
+ </group>
</choice>
</element>
</define>
@@ -623,6 +626,35 @@
</optional>
</interleave>
</define>
+
+ <define name="launchSecurityTDX">
+ <attribute name="type">
+ <value>tdx</value>
+ </attribute>
+ <interleave>
+ <optional>
+ <element name="policy">
+ <ref name="hexuint"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="mrConfigId">
+ <data type="string"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="mrOwner">
+ <data type="string"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="mrOwnerConfig">
+ <data type="string"/>
+ </element>
+ </optional>
+ </interleave>
+ </define>
+
<!--
Enable or disable perf events for the domain. For each
of the events the following rules apply:
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index 59be61cea4..d46da4bdda 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -216,6 +216,8 @@ typedef struct _virDomainSEVDef virDomainSEVDef;
typedef struct _virDomainSEVSNPDef virDomainSEVSNPDef;
+typedef struct _virDomainTDXDef virDomainTDXDef;
+
typedef struct _virDomainSecDef virDomainSecDef;
typedef struct _virDomainShmemDef virDomainShmemDef;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index f3c85d65e8..03c1c76ec4 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -865,6 +865,7 @@ qemuSetupDevicesCgroup(virDomainObj *vm)
return -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 243729800b..6c5e1926a5 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6990,6 +6990,7 @@ qemuBuildMachineCommandLine(virCommand *cmd,
}
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
virBufferAddLit(&buf, ",confidential-guest-support=lsec0");
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
@@ -9766,6 +9767,8 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
return qemuBuildPVCommandLine(vm, cmd);
break;
+
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 13e2838f19..7d0c39c89f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19174,6 +19174,7 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
goto cleanup;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index 2d0ec0b4fa..6c65a2751b 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -1371,6 +1371,7 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
}
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index 59421ec9d1..f72da83929 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -665,6 +665,7 @@ qemuDomainSetupLaunchSecurity(virDomainObj *vm,
VIR_DEBUG("Set up launch security for SEV");
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a78aa8569d..7586248329 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6856,6 +6856,7 @@ qemuProcessPrepareDomain(virQEMUDriver *driver,
return -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -6928,6 +6929,7 @@ qemuProcessPrepareLaunchSecurityGuestInput(virDomainObj *vm)
case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
return 0;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index ddfb14399a..34bb7e45c7 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1391,6 +1391,7 @@ qemuValidateDomainDef(const virDomainDef *def,
return -1;
}
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, def->sec->sectype);
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index b4d61bc576..bf849090a7 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -2017,6 +2017,7 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr,
rc = -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -2259,6 +2260,7 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr,
return -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
--
2.51.0

View File

@ -0,0 +1,35 @@
From 9e481e4b77d05a8951845272ec4ee51013b245ee Mon Sep 17 00:00:00 2001
Message-ID: <9e481e4b77d05a8951845272ec4ee51013b245ee.1763133104.git.jdenemar@redhat.com>
From: Martin Kletzander <mkletzan@redhat.com>
Date: Fri, 10 Jan 2025 15:56:34 +0100
Subject: [PATCH] conf: Do not parse hyperv features with passthrough mode
The schema does not allow that anyway and we then format them all back
which leads to libvirt producing an invalid XML.
Resolves: https://issues.redhat.com/browse/RHEL-70656
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit a4def2eb9597b83c7c6a4b9f8b08c995cbf7ee1a)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 38179a7e59..8c69feda6e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -16735,6 +16735,9 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
def->features[VIR_DOMAIN_FEATURE_HYPERV] = mode;
+ if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH)
+ return 0;
+
node = xmlFirstElementChild(node);
while (node != NULL) {
int feature;
--
2.51.1

View File

@ -0,0 +1,164 @@
From dec132c0a7598d1d5dfd50e380cf988ac4e0b321 Mon Sep 17 00:00:00 2001
Message-ID: <dec132c0a7598d1d5dfd50e380cf988ac4e0b321.1759835599.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:08 -0400
Subject: [PATCH] conf: Expose TDX feature in domain capabilities
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Extend qemu TDX capability to domain capabilities.
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit f87397488337ed596b0961855ccdea81de0e161c)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
RHEL: missing 10.1 data files
---
docs/formatdomaincaps.rst | 1 +
src/conf/domain_capabilities.c | 1 +
src/conf/domain_capabilities.h | 1 +
src/conf/schemas/domaincaps.rng | 9 +++++++++
src/qemu/qemu_capabilities.c | 13 +++++++++++++
.../qemu_10.1.0-q35.x86_64+inteltdx.xml | 1 +
.../domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml | 1 +
tests/domaincapsmock.c | 3 ++-
8 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index ed95af4fee..664194b16d 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -720,6 +720,7 @@ capabilities. All features occur as children of the main ``features`` element.
<backingStoreInput supported='yes'/>
<backup supported='yes'/>
<async-teardown supported='yes'/>
+ <tdx supported='yes'/>
<sev>
<cbitpos>47</cbitpos>
<reduced-phys-bits>1</reduced-phys-bits>
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index ab715b19d8..b8f17e6d2f 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -44,6 +44,7 @@ VIR_ENUM_IMPL(virDomainCapsFeature,
"async-teardown",
"s390-pv",
"ps2",
+ "tdx",
);
static virClass *virDomainCapsClass;
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 69dd1a15c1..eacbd6b6b3 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -274,6 +274,7 @@ typedef enum {
VIR_DOMAIN_CAPS_FEATURE_ASYNC_TEARDOWN,
VIR_DOMAIN_CAPS_FEATURE_S390_PV,
VIR_DOMAIN_CAPS_FEATURE_PS2,
+ VIR_DOMAIN_CAPS_FEATURE_TDX,
VIR_DOMAIN_CAPS_FEATURE_LAST
} virDomainCapsFeature;
diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng
index 3559d2ae05..850e7d63a0 100644
--- a/src/conf/schemas/domaincaps.rng
+++ b/src/conf/schemas/domaincaps.rng
@@ -357,6 +357,9 @@
<optional>
<ref name="ps2"/>
</optional>
+ <optional>
+ <ref name="tdx"/>
+ </optional>
<optional>
<ref name="sev"/>
</optional>
@@ -421,6 +424,12 @@
</element>
</define>
+ <define name="tdx">
+ <element name="tdx">
+ <ref name="supported"/>
+ </element>
+ </define>
+
<define name="sev">
<element name="sev">
<ref name="supported"/>
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f912b4cf9d..dbec00c99d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6968,6 +6968,18 @@ virQEMUCapsFillDomainFeatureHypervCaps(virQEMUCaps *qemuCaps,
}
+static void
+virQEMUCapsFillDomainFeatureTDXCaps(virQEMUCaps *qemuCaps,
+ virDomainCaps *domCaps)
+{
+ if (domCaps->arch == VIR_ARCH_X86_64 &&
+ domCaps->virttype == VIR_DOMAIN_VIRT_KVM &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST) &&
+ virQEMUCapsGetKVMSupportsSecureGuest(qemuCaps))
+ domCaps->features[VIR_DOMAIN_CAPS_FEATURE_TDX] = VIR_TRISTATE_BOOL_YES;
+}
+
+
int
virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps,
virArch hostarch,
@@ -7030,6 +7042,7 @@ virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps,
virQEMUCapsFillDomainFeaturePS2Caps(qemuCaps, domCaps);
virQEMUCapsFillDomainFeatureSGXCaps(qemuCaps, domCaps);
virQEMUCapsFillDomainFeatureHypervCaps(qemuCaps, domCaps);
+ virQEMUCapsFillDomainFeatureTDXCaps(qemuCaps, domCaps);
virQEMUCapsFillDomainDeviceCryptoCaps(qemuCaps, crypto);
virQEMUCapsFillDomainLaunchSecurity(qemuCaps, launchSecurity);
virQEMUCapsFillDomainDeviceNetCaps(qemuCaps, net);
diff --git a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
index 385a828d43..1d0f9f1362 100644
--- a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
@@ -722,6 +722,7 @@
<backup supported='yes'/>
<async-teardown supported='yes'/>
<ps2 supported='yes'/>
+ <tdx supported='yes'/>
<sev supported='no'/>
<sgx supported='yes'>
<flc>yes</flc>
diff --git a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
index f689021a96..a5c781c67c 100644
--- a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
@@ -722,6 +722,7 @@
<backup supported='yes'/>
<async-teardown supported='yes'/>
<ps2 supported='yes'/>
+ <tdx supported='yes'/>
<sev supported='no'/>
<sgx supported='yes'>
<flc>yes</flc>
diff --git a/tests/domaincapsmock.c b/tests/domaincapsmock.c
index 6ae0c4ad45..cb6e98dbb8 100644
--- a/tests/domaincapsmock.c
+++ b/tests/domaincapsmock.c
@@ -54,7 +54,8 @@ bool
virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps)
{
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT) &&
- virQEMUCapsGet(qemuCaps, QEMU_CAPS_S390_PV_GUEST))
+ (virQEMUCapsGet(qemuCaps, QEMU_CAPS_S390_PV_GUEST) ||
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST)))
return true;
if (!real_virQEMUCapsGetKVMSupportsSecureGuest)
--
2.51.0

View File

@ -0,0 +1,90 @@
From 2e0bf808c6d2543b2279a365f3175d1a9c384617 Mon Sep 17 00:00:00 2001
Message-ID: <2e0bf808c6d2543b2279a365f3175d1a9c384617.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:12 -0400
Subject: [PATCH] conf: Expose TDX type in domain launch security capability
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As the tdx launch security type support is added, expose it in domain
capabilities so that domain definition validation check can take
effect.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 0a825f910bb863ddc46c23e8a98834d1903dc526)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
RHEL: missing 10.1 data files
---
src/qemu/qemu_capabilities.c | 2 ++
tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml | 6 +++++-
tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml | 6 +++++-
tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml | 6 +++++-
4 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index dbec00c99d..4f239ae77b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6762,6 +6762,8 @@ virQEMUCapsFillDomainLaunchSecurity(virQEMUCaps *qemuCaps,
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_S390_PV_GUEST) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT))
VIR_DOMAIN_CAPS_ENUM_SET(launchSecurity->sectype, VIR_DOMAIN_LAUNCH_SECURITY_PV);
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST))
+ VIR_DOMAIN_CAPS_ENUM_SET(launchSecurity->sectype, VIR_DOMAIN_LAUNCH_SECURITY_TDX);
if (launchSecurity->sectype.values == 0) {
launchSecurity->supported = VIR_TRISTATE_BOOL_NO;
diff --git a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
index 1d0f9f1362..fedf50a52a 100644
--- a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
@@ -757,6 +757,10 @@
<value>xmm_input</value>
</enum>
</hyperv>
- <launchSecurity supported='no'/>
+ <launchSecurity supported='yes'>
+ <enum name='sectype'>
+ <value>tdx</value>
+ </enum>
+ </launchSecurity>
</features>
</domainCapabilities>
diff --git a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml
index ea79280179..c9913316b8 100644
--- a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml
@@ -1804,6 +1804,10 @@
<value>xmm_input</value>
</enum>
</hyperv>
- <launchSecurity supported='no'/>
+ <launchSecurity supported='yes'>
+ <enum name='sectype'>
+ <value>tdx</value>
+ </enum>
+ </launchSecurity>
</features>
</domainCapabilities>
diff --git a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
index a5c781c67c..c1aebf16b2 100644
--- a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
@@ -757,6 +757,10 @@
<value>xmm_input</value>
</enum>
</hyperv>
- <launchSecurity supported='no'/>
+ <launchSecurity supported='yes'>
+ <enum name='sectype'>
+ <value>tdx</value>
+ </enum>
+ </launchSecurity>
</features>
</domainCapabilities>
--
2.51.0

View File

@ -0,0 +1,251 @@
From d90f7c57e9cd6a146788726a5a0d1c6ba3de4a19 Mon Sep 17 00:00:00 2001
Message-ID: <d90f7c57e9cd6a146788726a5a0d1c6ba3de4a19.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 10:20:41 +0200
Subject: [PATCH] conf: Introduce hyperv host-model mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So far we have two modes for hyperv features:
1) custom, where users have to enable features explicitly, and
2) passthrough, where hypervisor enables features automagically.
Problem with 'custom' mode is that some features are not plain
on/off switches but expect int/string value. Until very recently,
these were not reported in domcaps. And even if they were it's a
bit cumbersome.
Problem with 'passthrough' mode is that users don't get to see
the expanded list of enlightenments enabled.
Therefore, mimic what we're already doing with CPUs: have
'host-model' which gets expanded at domain startup and is fixed
throughout domain's run.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c181c7dd1358ee1a2d125a869a44f46eee393452)
Conflicts:
src/libxl/libxl_conf.c: Not enabled in RHEL, so nobody cares.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
docs/formatdomain.rst | 6 ++++
src/conf/domain_conf.c | 4 ++-
src/conf/domain_conf.h | 1 +
src/conf/schemas/domaincommon.rng | 3 ++
src/qemu/qemu_command.c | 1 +
.../hyperv-host-model.x86_64-latest.args | 32 ++++++++++++++++++
.../hyperv-host-model.x86_64-latest.xml | 33 +++++++++++++++++++
tests/qemuxmlconfdata/hyperv-host-model.xml | 27 +++++++++++++++
tests/qemuxmlconftest.c | 1 +
9 files changed, 107 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/hyperv-host-model.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index bfe28759e7..3dba9e3073 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -2126,6 +2126,12 @@ are:
virtual CPU may or may not contain features which may block migration
even to an identical host.
+ ``host-model``
+ Similar to the ``passthrough`` mode, except libvirt detects which
+ enlightenments are supported by hypervisor and expands them on domain
+ startup into the live XML. In a sense, this is similar to ``host-model``
+ CPU mode (See `CPU model and topology`_). :since:`Since 11.9.0`
+
The ``mode`` attribute can be omitted and will default to ``custom``.
``pvspinlock``
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 67f8ef4676..b869ac885b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -145,6 +145,7 @@ VIR_ENUM_IMPL(virDomainHyperVMode,
"none",
"custom",
"passthrough",
+ "host-model",
);
VIR_ENUM_IMPL(virDomainBoot,
@@ -16742,7 +16743,8 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
def->features[VIR_DOMAIN_FEATURE_HYPERV] = mode;
- if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH)
+ if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH ||
+ mode == VIR_DOMAIN_HYPERV_MODE_HOST_MODEL)
return 0;
node = xmlFirstElementChild(node);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 643deefec2..abb50dd5cf 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -164,6 +164,7 @@ typedef enum {
VIR_DOMAIN_HYPERV_MODE_NONE = 0,
VIR_DOMAIN_HYPERV_MODE_CUSTOM,
VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH,
+ VIR_DOMAIN_HYPERV_MODE_HOST_MODEL,
VIR_DOMAIN_HYPERV_MODE_LAST
} virDomainHyperVMode;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 93bc128dec..58dbe478af 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -8038,6 +8038,9 @@
<attribute name="mode">
<value>passthrough</value>
</attribute>
+ <attribute name="mode">
+ <value>host-model</value>
+ </attribute>
<group>
<optional>
<attribute name="mode">
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3f290931a1..61aeb14757 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6289,6 +6289,7 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
switch ((virDomainHyperVMode) def->features[VIR_DOMAIN_FEATURE_HYPERV]) {
case VIR_DOMAIN_HYPERV_MODE_CUSTOM:
+ case VIR_DOMAIN_HYPERV_MODE_HOST_MODEL:
break;
case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
new file mode 100644
index 0000000000..2ed72fcd1b
--- /dev/null
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
@@ -0,0 +1,32 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
+-accel tcg \
+-cpu qemu64 \
+-m size=219136k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
+-overcommit mem-lock=off \
+-smp 6,sockets=6,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
new file mode 100644
index 0000000000..453a43b3c9
--- /dev/null
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>6</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <acpi/>
+ <hyperv mode='host-model'/>
+ </features>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <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>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.xml b/tests/qemuxmlconfdata/hyperv-host-model.xml
new file mode 100644
index 0000000000..fae00d86dd
--- /dev/null
+++ b/tests/qemuxmlconfdata/hyperv-host-model.xml
@@ -0,0 +1,27 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>6</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <acpi/>
+ <hyperv mode='host-model'/>
+ </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>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 5683e76599..009849950a 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1507,6 +1507,7 @@ mymain(void)
DO_TEST_CAPS_VER("hyperv-passthrough", "6.1.0");
DO_TEST_CAPS_LATEST("hyperv-passthrough");
DO_TEST_CAPS_LATEST("hyperv-stimer-direct");
+ DO_TEST_CAPS_LATEST("hyperv-host-model");
DO_TEST_CAPS_LATEST("kvm-features");
DO_TEST_CAPS_LATEST("kvm-features-off");
--
2.51.1

View File

@ -0,0 +1,79 @@
From 44eca2ab460f77453733a0c3403ba440f8ecec9c Mon Sep 17 00:00:00 2001
Message-ID: <44eca2ab460f77453733a0c3403ba440f8ecec9c.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 7 Oct 2025 13:42:03 +0200
Subject: [PATCH] conf: Introduce virDomainDefHasTimer()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a simple helper to tell whether domain definition has
certain type of timer or not.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 359909749ae9af9d23a916b9906e97d69945fc81)
Conflicts:
- src/conf/domain_conf.h:
- src/libvirt_private.syms: Both context.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 17 +++++++++++++++++
src/conf/domain_conf.h | 4 ++++
src/libvirt_private.syms | 1 +
3 files changed, 22 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8c69feda6e..7fd5f76fb6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -31927,3 +31927,20 @@ virDomainWatchdogDefFind(const virDomainDef *def,
return -1;
}
+
+
+bool
+virDomainDefHasTimer(const virDomainDef *def,
+ virDomainTimerNameType name)
+{
+ size_t i;
+
+ for (i = 0; i < def->clock.ntimers; i++) {
+ if (def->clock.timers[i]->name == name &&
+ def->clock.timers[i]->present == VIR_TRISTATE_BOOL_YES) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 15aacc71c1..24a1089552 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4641,3 +4641,7 @@ virDomainObjGetMessages(virDomainObj *vm,
bool
virDomainDefHasSpiceGraphics(const virDomainDef *def);
+
+bool
+virDomainDefHasTimer(const virDomainDef *def,
+ virDomainTimerNameType name);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index be313ad67b..0a1235e6d8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -344,6 +344,7 @@ virDomainDefHasOldStyleROUEFI;
virDomainDefHasOldStyleUEFI;
virDomainDefHasPCIHostdev;
virDomainDefHasSpiceGraphics;
+virDomainDefHasTimer;
virDomainDefHasUSB;
virDomainDefHasVcpusOffline;
virDomainDefHasVDPANet;
--
2.51.1

View File

@ -0,0 +1,439 @@
From 99abc9c66f605ca907a6291dd1918ec7112db18c Mon Sep 17 00:00:00 2001
Message-ID: <99abc9c66f605ca907a6291dd1918ec7112db18c.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 30 Sep 2025 10:27:27 +0200
Subject: [PATCH] conf: More hyperv related members into a single struct
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So far, we have an array of integers (hyperv_features), an uint
(hyperv_spinlocks), a string (hyperv_vendor_id) and some tristate
switches scattered across virDomainDef. Soon, new knobs will be
introduced and keeping the current state would only worsen
readability.
Introduce virDomainHypervFeatures struct to place hyperv related
features there.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 47271c204e5471f1cbd22cf34c0166455affc095)
Conflicts:
- src/libxl/libxl_conf.c: Original commit changed this file, but
because 064682ab330535bb1559045b5900398ae7a8d91d is not
backported, then the change doesn't make sense. The libxl
driver is not enabled in RHEL anyway.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 77 ++++++++++++++++++++++------------------
src/conf/domain_conf.h | 15 ++++----
src/conf/virconftypes.h | 2 ++
src/qemu/qemu_command.c | 16 ++++-----
src/qemu/qemu_process.c | 8 ++---
src/qemu/qemu_validate.c | 12 +++----
6 files changed, 71 insertions(+), 59 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f02efaca4e..67f8ef4676 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3949,6 +3949,13 @@ virDomainOSDefClear(virDomainOSDef *os)
}
+static void
+virDomainHypervFeaturesClear(virDomainHypervFeatures *hv)
+{
+ g_free(hv->vendor_id);
+}
+
+
void virDomainDefFree(virDomainDef *def)
{
size_t i;
@@ -4076,8 +4083,8 @@ void virDomainDefFree(virDomainDef *def)
g_free(def->emulator);
g_free(def->description);
g_free(def->title);
+ virDomainHypervFeaturesClear(&def->hyperv);
g_free(def->kvm_features);
- g_free(def->hyperv_vendor_id);
g_free(def->tcg_features);
virBlkioDeviceArrayClear(def->blkio.devices,
@@ -16756,7 +16763,7 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
&value) < 0)
return -1;
- def->hyperv_features[feature] = value;
+ def->hyperv.features[feature] = value;
switch ((virDomainHyperv) feature) {
case VIR_DOMAIN_HYPERV_RELAXED:
@@ -16782,11 +16789,11 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
while (child) {
if (STREQ((const char *)child->name, "direct")) {
if (virXMLPropTristateSwitch(child, "state", VIR_XML_PROP_REQUIRED,
- &def->hyperv_tlbflush_direct) < 0)
+ &def->hyperv.tlbflush_direct) < 0)
return -1;
} else if (STREQ((const char *)child->name, "extended")) {
if (virXMLPropTristateSwitch(child, "state", VIR_XML_PROP_REQUIRED,
- &def->hyperv_tlbflush_extended) < 0)
+ &def->hyperv.tlbflush_extended) < 0)
return -1;
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -16813,7 +16820,7 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
}
if (virXMLPropTristateSwitch(child, "state", VIR_XML_PROP_REQUIRED,
- &def->hyperv_stimer_direct) < 0)
+ &def->hyperv.stimer_direct) < 0)
return -1;
child = xmlNextElementSibling(child);
@@ -16825,10 +16832,10 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
break;
if (virXMLPropUInt(node, "retries", 0, VIR_XML_PROP_REQUIRED,
- &def->hyperv_spinlocks) < 0)
+ &def->hyperv.spinlocks) < 0)
return -1;
- if (def->hyperv_spinlocks < 0xFFF) {
+ if (def->hyperv.spinlocks < 0xFFF) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("HyperV spinlock retry count must be at least 4095"));
return -1;
@@ -16839,15 +16846,15 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
if (value != VIR_TRISTATE_SWITCH_ON)
break;
- g_clear_pointer(&def->hyperv_vendor_id, g_free);
+ g_clear_pointer(&def->hyperv.vendor_id, g_free);
- if (!(def->hyperv_vendor_id = virXMLPropString(node, "value"))) {
+ if (!(def->hyperv.vendor_id = virXMLPropString(node, "value"))) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing 'value' attribute for HyperV feature 'vendor_id'"));
return -1;
}
- if (!STRLIM(def->hyperv_vendor_id, VIR_DOMAIN_HYPERV_VENDOR_ID_MAX)) {
+ if (!STRLIM(def->hyperv.vendor_id, VIR_DOMAIN_HYPERV_VENDOR_ID_MAX)) {
virReportError(VIR_ERR_XML_ERROR,
_("HyperV vendor_id value must not be more than %1$d characters."),
VIR_DOMAIN_HYPERV_VENDOR_ID_MAX);
@@ -16855,7 +16862,7 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
}
/* ensure that the string can be passed to qemu */
- if (strchr(def->hyperv_vendor_id, ',')) {
+ if (strchr(def->hyperv.vendor_id, ',')) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("HyperV vendor_id value is invalid"));
return -1;
@@ -21296,12 +21303,12 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
case VIR_DOMAIN_HYPERV_AVIC:
case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
case VIR_DOMAIN_HYPERV_XMM_INPUT:
- if (src->hyperv_features[i] != dst->hyperv_features[i]) {
+ if (src->hyperv.features[i] != dst->hyperv.features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of HyperV enlightenment feature '%1$s' differs: source: '%2$s', destination: '%3$s'"),
virDomainHypervTypeToString(i),
- virTristateSwitchTypeToString(src->hyperv_features[i]),
- virTristateSwitchTypeToString(dst->hyperv_features[i]));
+ virTristateSwitchTypeToString(src->hyperv.features[i]),
+ virTristateSwitchTypeToString(dst->hyperv.features[i]));
return false;
}
@@ -21309,21 +21316,21 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
case VIR_DOMAIN_HYPERV_SPINLOCKS:
/* spinlock count matters! */
- if (src->hyperv_spinlocks != dst->hyperv_spinlocks) {
+ if (src->hyperv.spinlocks != dst->hyperv.spinlocks) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("HyperV spinlock retry count differs: source: '%1$u', destination: '%2$u'"),
- src->hyperv_spinlocks,
- dst->hyperv_spinlocks);
+ src->hyperv.spinlocks,
+ dst->hyperv.spinlocks);
return false;
}
break;
case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (STRNEQ_NULLABLE(src->hyperv_vendor_id, dst->hyperv_vendor_id)) {
+ if (STRNEQ_NULLABLE(src->hyperv.vendor_id, dst->hyperv.vendor_id)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("HyperV vendor_id differs: source: '%1$s', destination: '%2$s'"),
- src->hyperv_vendor_id,
- dst->hyperv_vendor_id);
+ src->hyperv.vendor_id,
+ dst->hyperv.vendor_id);
return false;
}
break;
@@ -21334,12 +21341,12 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
}
}
- if (src->hyperv_features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
- if (src->hyperv_stimer_direct != dst->hyperv_stimer_direct) {
+ if (src->hyperv.features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+ if (src->hyperv.stimer_direct != dst->hyperv.stimer_direct) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of HyperV stimer direct feature differs: source: '%1$s', destination: '%2$s'"),
- virTristateSwitchTypeToString(src->hyperv_stimer_direct),
- virTristateSwitchTypeToString(dst->hyperv_stimer_direct));
+ virTristateSwitchTypeToString(src->hyperv.stimer_direct),
+ virTristateSwitchTypeToString(dst->hyperv.stimer_direct));
return false;
}
}
@@ -28040,11 +28047,11 @@ virDomainFeaturesHyperVDefFormat(virBuffer *buf,
g_auto(virBuffer) hypervAttrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf);
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ABSENT)
+ if (def->hyperv.features[j] == VIR_TRISTATE_SWITCH_ABSENT)
continue;
virBufferAsprintf(&hypervAttrBuf, " state='%s'",
- virTristateSwitchTypeToString(def->hyperv_features[j]));
+ virTristateSwitchTypeToString(def->hyperv.features[j]));
switch ((virDomainHyperv) j) {
case VIR_DOMAIN_HYPERV_RELAXED:
@@ -28063,34 +28070,34 @@ virDomainFeaturesHyperVDefFormat(virBuffer *buf,
break;
case VIR_DOMAIN_HYPERV_SPINLOCKS:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[j] == VIR_TRISTATE_SWITCH_ON) {
virBufferAsprintf(&hypervAttrBuf,
- " retries='%d'", def->hyperv_spinlocks);
+ " retries='%d'", def->hyperv.spinlocks);
}
break;
case VIR_DOMAIN_HYPERV_STIMER:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON &&
- def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[j] == VIR_TRISTATE_SWITCH_ON &&
+ def->hyperv.stimer_direct == VIR_TRISTATE_SWITCH_ON) {
virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
}
break;
case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[j] == VIR_TRISTATE_SWITCH_ON) {
virBufferEscapeString(&hypervAttrBuf, " value='%s'",
- def->hyperv_vendor_id);
+ def->hyperv.vendor_id);
}
break;
case VIR_DOMAIN_HYPERV_TLBFLUSH:
- if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.features[j] != VIR_TRISTATE_SWITCH_ON)
break;
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&hypervChildBuf, "<extended state='on'/>\n");
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 24a1089552..643deefec2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3080,6 +3080,14 @@ struct _virDomainPstoreDef {
virDomainDeviceInfo info;
};
+struct _virDomainHypervFeatures {
+ int features[VIR_DOMAIN_HYPERV_LAST];
+ unsigned int spinlocks;
+ virTristateSwitch stimer_direct;
+ virTristateSwitch tlbflush_direct;
+ virTristateSwitch tlbflush_extended;
+ char *vendor_id;
+};
#define SCSI_SUPER_WIDE_BUS_MAX_CONT_UNIT 64
#define SCSI_WIDE_BUS_MAX_CONT_UNIT 16
@@ -3147,19 +3155,14 @@ struct _virDomainDef {
* See virDomainDefFeaturesCheckABIStability() for details. */
int features[VIR_DOMAIN_FEATURE_LAST];
int caps_features[VIR_DOMAIN_PROCES_CAPS_FEATURE_LAST];
- int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
+ virDomainHypervFeatures hyperv;
virDomainFeatureKVM *kvm_features;
int msrs_features[VIR_DOMAIN_MSRS_LAST];
int xen_features[VIR_DOMAIN_XEN_LAST];
virDomainXenPassthroughMode xen_passthrough_mode;
- unsigned int hyperv_spinlocks;
- virTristateSwitch hyperv_stimer_direct;
- virTristateSwitch hyperv_tlbflush_direct;
- virTristateSwitch hyperv_tlbflush_extended;
virGICVersion gic_version;
virDomainHPTResizing hpt_resizing;
unsigned long long hpt_maxpagesize; /* Stored in KiB */
- char *hyperv_vendor_id;
virTristateSwitch apic_eoi;
virDomainFeatureTCG *tcg_features;
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index d46da4bdda..e93d260d37 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -138,6 +138,8 @@ typedef struct _virDomainHubDef virDomainHubDef;
typedef struct _virDomainHugePage virDomainHugePage;
+typedef struct _virDomainHypervFeatures virDomainHypervFeatures;
+
typedef struct _virDomainIOMMUDef virDomainIOMMUDef;
typedef struct _virDomainIOThreadIDDef virDomainIOThreadIDDef;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 13e23c7ee3..3f290931a1 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6320,7 +6320,7 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
case VIR_DOMAIN_HYPERV_AVIC:
case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
case VIR_DOMAIN_HYPERV_XMM_INPUT:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ON) {
const char *name = virDomainHypervTypeToString(i);
g_autofree char *full_name = g_strdup_printf("hv-%s", name);
const char *qemu_name = virQEMUCapsCPUFeatureToQEMU(def->os.arch,
@@ -6328,27 +6328,27 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
virBufferAsprintf(buf, ",%s=on", qemu_name);
}
if ((i == VIR_DOMAIN_HYPERV_STIMER) &&
- (def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON))
+ (def->hyperv.stimer_direct == VIR_TRISTATE_SWITCH_ON))
virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_STIMER_DIRECT);
if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_DIRECT);
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_EXT);
}
break;
case VIR_DOMAIN_HYPERV_SPINLOCKS:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(buf, ",%s=0x%x",
VIR_CPU_x86_HV_SPINLOCKS,
- def->hyperv_spinlocks);
+ def->hyperv.spinlocks);
break;
case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(buf, ",hv-vendor-id=%s",
- def->hyperv_vendor_id);
+ def->hyperv.vendor_id);
break;
case VIR_DOMAIN_HYPERV_LAST:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7b6c02bc27..798dabaf0a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4381,7 +4381,7 @@ qemuProcessVerifyHypervFeatures(virDomainDef *def,
i == VIR_DOMAIN_HYPERV_SPINLOCKS)
continue;
- if (def->hyperv_features[i] != VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.features[i] != VIR_TRISTATE_SWITCH_ON)
continue;
cpuFeature = g_strdup_printf("hv-%s", virDomainHypervTypeToString(i));
@@ -4392,7 +4392,7 @@ qemuProcessVerifyHypervFeatures(virDomainDef *def,
return -1;
} else if (rc == 1) {
if (i == VIR_DOMAIN_HYPERV_STIMER) {
- if (def->hyperv_stimer_direct != VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.stimer_direct != VIR_TRISTATE_SWITCH_ON)
continue;
rc = virCPUDataCheckFeature(cpu, VIR_CPU_x86_HV_STIMER_DIRECT);
@@ -4407,7 +4407,7 @@ qemuProcessVerifyHypervFeatures(virDomainDef *def,
return -1;
}
if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
rc = virCPUDataCheckFeature(cpu, VIR_CPU_x86_HV_TLBFLUSH_DIRECT);
if (rc < 0)
return -1;
@@ -4418,7 +4418,7 @@ qemuProcessVerifyHypervFeatures(virDomainDef *def,
return -1;
}
}
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.tlbflush_extended == VIR_TRISTATE_SWITCH_ON) {
rc = virCPUDataCheckFeature(cpu, VIR_CPU_x86_HV_TLBFLUSH_EXT);
if (rc < 0)
return -1;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 22565d9e36..ed769efc7c 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -89,8 +89,8 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
#define CHECK_HV_FEAT(feat, requires) \
- if (def->hyperv_features[feat] == VIR_TRISTATE_SWITCH_ON && \
- def->hyperv_features[requires] != VIR_TRISTATE_SWITCH_ON) { \
+ if (def->hyperv.features[feat] == VIR_TRISTATE_SWITCH_ON && \
+ def->hyperv.features[requires] != VIR_TRISTATE_SWITCH_ON) { \
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
_("'%1$s' hyperv feature requires '%2$s' feature"), \
virDomainHypervTypeToString(feat), \
@@ -114,7 +114,7 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_SYNIC, VIR_DOMAIN_HYPERV_VPINDEX);
- if (def->hyperv_features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
if (!virDomainDefHasTimer(def, VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("'%1$s' hyperv feature requires '%2$s' timer"),
@@ -133,9 +133,9 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_EVMCS, VIR_DOMAIN_HYPERV_VAPIC);
- if (def->hyperv_features[VIR_DOMAIN_HYPERV_TLBFLUSH] == VIR_TRISTATE_SWITCH_ON &&
- def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
- if (def->hyperv_features[VIR_DOMAIN_HYPERV_VAPIC] != VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[VIR_DOMAIN_HYPERV_TLBFLUSH] == VIR_TRISTATE_SWITCH_ON &&
+ def->hyperv.tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[VIR_DOMAIN_HYPERV_VAPIC] != VIR_TRISTATE_SWITCH_ON) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("'%1$s' hyperv feature requires '%2$s' feature"),
VIR_CPU_x86_HV_TLBFLUSH_DIRECT,
--
2.51.1

View File

@ -0,0 +1,285 @@
From 7dc415a0708f4389bfb470c36cfaa3886882419f Mon Sep 17 00:00:00 2001
Message-ID: <7dc415a0708f4389bfb470c36cfaa3886882419f.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 30 Sep 2025 15:05:10 +0200
Subject: [PATCH] conf: Report default hyperv values in domain capabilities
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So far the set of available Hyper-V enlightenments are reported
in domain capabilities. Well, some enlightenments are more than
just simple on/off switch. For instance, the 'spinlocks'
enlightenment expects a number, or 'vendor_id' expects a string.
All of these have some default values (at least in QEMU) and are
used when the passthrough mode is set.
Allow querying these defaults in domain capabilities XML.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 57d2f4a0f0cbdb8006e99a3271bf363582843e91)
Conflicts:
- src/qemu/qemu_capabilities.c: Since
48f04627c8faf505a98e07e542729c135a615dcc is not backported yet,
the original code had g_memdup() but the bacported patch
expected g_memdup2().
Additionally, virDomainCapsFeatureHypervCopy() inside of
domain_capabilities.c had to be changed to use g_memdup() since
g_memdup2() wasn't introduced until glib-2.68.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
docs/formatdomaincaps.rst | 5 ++-
src/conf/domain_capabilities.c | 61 ++++++++++++++++++++++++++++++++-
src/conf/domain_capabilities.h | 11 ++++++
src/conf/schemas/domaincaps.rng | 29 ++++++++++++++++
src/libvirt_private.syms | 2 ++
src/qemu/qemu_capabilities.c | 12 +++----
6 files changed, 111 insertions(+), 9 deletions(-)
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index 664194b16d..aee0af1045 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -869,7 +869,10 @@ Hyper-V Enlightenments
Report which features improving behavior of guests running Microsoft Windows
are supported. The ``features`` enum corresponds to the ``<hyperv/>`` element
(well, its children) as documented in `Hypervisor features
-<formatdomain.html#hypervisor-features>`__.
+<formatdomain.html#hypervisor-features>`__. The ``defaults`` element then
+contains child elements describing default values as reported by hypervisor,
+e.h. whether direct or extended TLB flushes are available. :since:`(since
+11.9.0)`
Please note that depending on the QEMU version some capabilities might be
missing even though QEMU does support them. This is because prior to QEMU-6.1.0
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index b8f17e6d2f..5f1e1e7100 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -91,6 +91,32 @@ virSGXCapabilitiesFree(virSGXCapability *cap)
}
+void
+virDomainCapsFeatureHypervFree(virDomainCapsFeatureHyperv *cap)
+{
+ if (!cap)
+ return;
+
+ g_free(cap->vendor_id);
+ g_free(cap);
+}
+
+
+virDomainCapsFeatureHyperv *
+virDomainCapsFeatureHypervCopy(virDomainCapsFeatureHyperv *cap)
+{
+ virDomainCapsFeatureHyperv *ret = NULL;
+
+ if (!cap)
+ return NULL;
+
+ ret = g_memdup(cap, sizeof(virDomainCapsFeatureHyperv));
+ ret->vendor_id = g_strdup(cap->vendor_id);
+
+ return ret;
+}
+
+
static void
virDomainCapsDispose(void *obj)
{
@@ -104,7 +130,7 @@ virDomainCapsDispose(void *obj)
virCPUDefFree(caps->cpu.hostModel);
virSEVCapabilitiesFree(caps->sev);
virSGXCapabilitiesFree(caps->sgx);
- g_free(caps->hyperv);
+ virDomainCapsFeatureHypervFree(caps->hyperv);
values = &caps->os.loader.values;
for (i = 0; i < values->nvalues; i++)
@@ -779,6 +805,8 @@ static void
virDomainCapsFeatureHypervFormat(virBuffer *buf,
const virDomainCapsFeatureHyperv *hyperv)
{
+ virBuffer defaults = VIR_BUFFER_INIT_CHILD(buf);
+
if (!hyperv)
return;
@@ -786,6 +814,37 @@ virDomainCapsFeatureHypervFormat(virBuffer *buf,
ENUM_PROCESS(hyperv, features, virDomainHypervTypeToString);
+ virBufferAdjustIndent(&defaults, 2);
+
+ if (VIR_DOMAIN_CAPS_ENUM_IS_SET(hyperv->features, VIR_DOMAIN_HYPERV_SPINLOCKS) &&
+ hyperv->spinlocks != 0) {
+ virBufferAsprintf(&defaults, "<spinlocks>%u</spinlocks>\n", hyperv->spinlocks);
+ }
+
+ if (VIR_DOMAIN_CAPS_ENUM_IS_SET(hyperv->features, VIR_DOMAIN_HYPERV_STIMER) &&
+ hyperv->stimer_direct != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&defaults, "<stimer_direct>%s</stimer_direct>\n",
+ virTristateSwitchTypeToString(hyperv->stimer_direct));
+ }
+
+ if (VIR_DOMAIN_CAPS_ENUM_IS_SET(hyperv->features, VIR_DOMAIN_HYPERV_TLBFLUSH)) {
+ if (hyperv->tlbflush_direct != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&defaults, "<tlbflush_direct>%s</tlbflush_direct>\n",
+ virTristateSwitchTypeToString(hyperv->tlbflush_direct));
+ }
+
+ if (hyperv->tlbflush_extended != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&defaults, "<tlbflush_extended>%s</tlbflush_extended>\n",
+ virTristateSwitchTypeToString(hyperv->tlbflush_extended));
+ }
+ }
+
+ if (VIR_DOMAIN_CAPS_ENUM_IS_SET(hyperv->features, VIR_DOMAIN_HYPERV_VENDOR_ID)) {
+ virBufferEscapeString(&defaults, "<vendor_id>%s</vendor_id>\n", hyperv->vendor_id);
+ }
+
+ virXMLFormatElement(buf, "defaults", NULL, &defaults);
+
FORMAT_EPILOGUE(hyperv);
}
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index eacbd6b6b3..5421c8cfce 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -163,6 +163,11 @@ typedef struct _virDomainCapsFeatureHyperv virDomainCapsFeatureHyperv;
struct _virDomainCapsFeatureHyperv {
virTristateBool supported;
virDomainCapsEnum features; /* Info about supported virDomainHyperv features */
+ unsigned int spinlocks;
+ virTristateSwitch stimer_direct;
+ virTristateSwitch tlbflush_direct;
+ virTristateSwitch tlbflush_extended;
+ char *vendor_id;
};
STATIC_ASSERT_ENUM(VIR_DOMAIN_LAUNCH_SECURITY_LAST);
@@ -370,3 +375,9 @@ void
virSGXCapabilitiesFree(virSGXCapability *capabilities);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSGXCapability, virSGXCapabilitiesFree);
+
+void virDomainCapsFeatureHypervFree(virDomainCapsFeatureHyperv *capabilities);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainCapsFeatureHyperv, virDomainCapsFeatureHypervFree);
+
+virDomainCapsFeatureHyperv *
+virDomainCapsFeatureHypervCopy(virDomainCapsFeatureHyperv *cap);
diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng
index 850e7d63a0..9e1a80e22e 100644
--- a/src/conf/schemas/domaincaps.rng
+++ b/src/conf/schemas/domaincaps.rng
@@ -494,6 +494,35 @@
<element name="hyperv">
<ref name="supported"/>
<ref name="enum"/>
+ <optional>
+ <element name="defaults">
+ <optional>
+ <element name="spinlocks">
+ <ref name="unsignedInt"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="stimer_direct">
+ <ref name="virOnOff"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="tlbflush_direct">
+ <ref name="virOnOff"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="tlbflush_extended">
+ <ref name="virOnOff"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="vendor_id">
+ <text/>
+ </element>
+ </optional>
+ </element>
+ </optional>
</element>
</define>
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index bbe1e252af..d609064a19 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -217,6 +217,8 @@ virDomainCapsCPUUsableTypeFromString;
virDomainCapsCPUUsableTypeToString;
virDomainCapsEnumClear;
virDomainCapsEnumSet;
+virDomainCapsFeatureHypervCopy;
+virDomainCapsFeatureHypervFree;
virDomainCapsFormat;
virDomainCapsNew;
virSEVCapabilitiesFree;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 28d3a78d8c..b54bcbd527 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2051,8 +2051,7 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps)
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC))
virQEMUCapsSGXInfoCopy(&ret->sgxCapabilities, qemuCaps->sgxCapabilities);
- ret->hypervCapabilities = g_memdup(qemuCaps->hypervCapabilities,
- sizeof(virDomainCapsFeatureHyperv));
+ ret->hypervCapabilities = virDomainCapsFeatureHypervCopy(qemuCaps->hypervCapabilities);
return g_steal_pointer(&ret);
}
@@ -2094,7 +2093,7 @@ void virQEMUCapsDispose(void *obj)
virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
virSGXCapabilitiesFree(qemuCaps->sgxCapabilities);
- g_free(qemuCaps->hypervCapabilities);
+ virDomainCapsFeatureHypervFree(qemuCaps->hypervCapabilities);
virQEMUCapsAccelClear(&qemuCaps->kvm);
virQEMUCapsAccelClear(&qemuCaps->hvf);
@@ -3116,7 +3115,7 @@ static int
virQEMUCapsProbeHypervCapabilities(virQEMUCaps *qemuCaps,
qemuMonitorCPUModelInfo *fullQEMU)
{
- g_autofree virDomainCapsFeatureHyperv *hvcaps = NULL;
+ g_autoptr(virDomainCapsFeatureHyperv) hvcaps = NULL;
size_t i;
if (!fullQEMU)
@@ -4555,7 +4554,7 @@ static int
virQEMUCapsParseHypervCapabilities(virQEMUCaps *qemuCaps,
xmlXPathContextPtr ctxt)
{
- g_autofree virDomainCapsFeatureHyperv *hvcaps = NULL;
+ g_autoptr(virDomainCapsFeatureHyperv) hvcaps = NULL;
xmlNodePtr n = NULL;
g_autofree xmlNodePtr *capNodes = NULL;
int ncapNodes;
@@ -6965,8 +6964,7 @@ static void
virQEMUCapsFillDomainFeatureHypervCaps(virQEMUCaps *qemuCaps,
virDomainCaps *domCaps)
{
- domCaps->hyperv = g_memdup(qemuCaps->hypervCapabilities,
- sizeof(virDomainCapsFeatureHyperv));
+ domCaps->hyperv = virDomainCapsFeatureHypervCopy(qemuCaps->hypervCapabilities);
}
--
2.51.1

View File

@ -0,0 +1,63 @@
From 889ea0ba62e2c51b8dc7d75c0f59ba757d57bdce Mon Sep 17 00:00:00 2001
Message-ID: <889ea0ba62e2c51b8dc7d75c0f59ba757d57bdce.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:10 -0400
Subject: [PATCH] conf: Validate TDX launchSecurity element
mrConfigId/mrOwner/mrOwnerConfig
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
mrConfigId/mrOwner/mrOwnerConfig are base64 encoded SHA384 digest,
can be provided for TDX attestation.
Check their decoded lengths to ensure they are 48 bytes.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit ea625cb60b6c829d96c67a4ac99f6ccb96a15257)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/conf/domain_validate.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 2d4b79032b..2878b210c7 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1839,10 +1839,13 @@ virDomainDefValidateIOThreads(const virDomainDef *def)
} \
}
+#define SHA384_DIGEST_SIZE 48
+
static int
virDomainDefLaunchSecurityValidate(const virDomainDef *def)
{
virDomainSEVSNPDef *sev_snp;
+ virDomainTDXDef *tdx;
if (!def->sec)
return 0;
@@ -1857,10 +1860,17 @@ virDomainDefLaunchSecurityValidate(const virDomainDef *def)
CHECK_BASE64_LEN(sev_snp->host_data, "hostData", 32);
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ tdx = &def->sec->data.tdx;
+
+ CHECK_BASE64_LEN(tdx->mrconfigid, "mrConfigId", SHA384_DIGEST_SIZE);
+ CHECK_BASE64_LEN(tdx->mrowner, "mrOwner", SHA384_DIGEST_SIZE);
+ CHECK_BASE64_LEN(tdx->mrownerconfig, "mrOwnerConfig", SHA384_DIGEST_SIZE);
+ break;
+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
- case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
break;
}
--
2.51.0

View File

@ -0,0 +1,138 @@
From 2da81198df9206a69c368a29da1771e9bce94583 Mon Sep 17 00:00:00 2001
Message-ID: <2da81198df9206a69c368a29da1771e9bce94583.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 15:07:45 +0200
Subject: [PATCH] cpu_conf: Make virCPUDefFilterFeatures return void
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The only thing that can fail inside virCPUDefFilterFeatures is
VIR_DELETE_ELEMENT_INPLACE macro. The macro just calls
virDeleteElementsN, which reports a warning when all elements to be
removed are not within the array bounds and returns -1. The function
succeeds otherwise. But since VIR_DELETE_ELEMENT_INPLACE sets the number
of elements to be removed to 1 and we call it with i < cpu->nfeatures,
the safety check in virDeleteElementsN will never fail. And even if we
theoretically called it with wrong arguments, it just wouldn't do
anything.
Thus we can safely assume VIR_DELETE_ELEMENT_INPLACE always succeeds in
virCPUDefFilterFeatures and avoid reporting any errors to simplify
callers.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit fd6cf1b44accd1856a4611933ad51c0e04221aaa)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/conf/cpu_conf.c | 9 ++++-----
src/conf/cpu_conf.h | 2 +-
src/qemu/qemu_capabilities.c | 15 ++++++---------
src/qemu/qemu_domain.c | 3 +--
src/qemu/qemu_process.c | 5 ++---
5 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 31425783ba..7aeedf64f5 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -1017,7 +1017,7 @@ virCPUDefListExplicitFeatures(const virCPUDef *def)
}
-int
+void
virCPUDefFilterFeatures(virCPUDef *cpu,
virCPUDefFeatureFilter filter,
void *opaque)
@@ -1031,11 +1031,10 @@ virCPUDefFilterFeatures(virCPUDef *cpu,
}
VIR_FREE(cpu->features[i].name);
- if (VIR_DELETE_ELEMENT_INPLACE(cpu->features, i, cpu->nfeatures) < 0)
- return -1;
- }
- return 0;
+ /* Safe to ignore as an error is returned only for invalid arguments */
+ ignore_value(VIR_DELETE_ELEMENT_INPLACE(cpu->features, i, cpu->nfeatures));
+ }
}
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index 28e26303ef..cfb8f1a461 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -260,7 +260,7 @@ virCPUFeatureDef *
virCPUDefFindFeature(const virCPUDef *def,
const char *name);
-int
+void
virCPUDefFilterFeatures(virCPUDef *cpu,
virCPUDefFeatureFilter filter,
void *opaque);
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 7273f59175..6e79bd98c8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4085,17 +4085,14 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
if (ARCH_IS_X86(qemuCaps->arch) &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES)) {
- if (cpu &&
- virCPUDefFilterFeatures(cpu, virCPUx86FeatureFilterDropMSR, NULL) < 0)
- goto error;
+ if (cpu)
+ virCPUDefFilterFeatures(cpu, virCPUx86FeatureFilterDropMSR, NULL);
- if (migCPU &&
- virCPUDefFilterFeatures(migCPU, virCPUx86FeatureFilterDropMSR, NULL) < 0)
- goto error;
+ if (migCPU)
+ virCPUDefFilterFeatures(migCPU, virCPUx86FeatureFilterDropMSR, NULL);
- if (fullCPU &&
- virCPUDefFilterFeatures(fullCPU, virCPUx86FeatureFilterDropMSR, NULL) < 0)
- goto error;
+ if (fullCPU)
+ virCPUDefFilterFeatures(fullCPU, virCPUx86FeatureFilterDropMSR, NULL);
}
if (virQEMUCapsTypeIsAccelerated(type))
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 56d8bb4827..21a4169c58 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5101,8 +5101,7 @@ qemuDomainMakeCPUMigratable(virArch arch,
g_auto(GStrv) keep = virCPUDefListExplicitFeatures(origCPU);
data.keep = keep;
- if (virCPUDefFilterFeatures(cpu, qemuDomainDropAddedCPUFeatures, &data) < 0)
- return -1;
+ virCPUDefFilterFeatures(cpu, qemuDomainDropAddedCPUFeatures, &data);
}
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e2e2822013..f5f9d4a348 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6516,9 +6516,8 @@ qemuProcessUpdateGuestCPU(virDomainDef *def,
def->cpu->fallback = VIR_CPU_FALLBACK_FORBID;
}
- if (virCPUDefFilterFeatures(def->cpu, virQEMUCapsCPUFilterFeatures,
- &def->os.arch) < 0)
- return -1;
+ virCPUDefFilterFeatures(def->cpu, virQEMUCapsCPUFilterFeatures,
+ &def->os.arch);
if (def->cpu->deprecated_feats &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS)) {
--
2.51.1

View File

@ -0,0 +1,94 @@
From 81832cba9c026511ccf3fecbff894f9db48fbd33 Mon Sep 17 00:00:00 2001
Message-ID: <81832cba9c026511ccf3fecbff894f9db48fbd33.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:25 -0400
Subject: [PATCH] docs: domain: Add documentation for Intel TDX guest
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
(cherry picked from commit 5e5528ef14b600a43070c7efc3877e3840725dec)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
docs/formatdomain.rst | 63 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 847c9ebc6e..bfe28759e7 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9294,6 +9294,69 @@ The ``<launchSecurity/>`` element then accepts the following child elements:
the SNP_LAUNCH_FINISH command in the SEV-SNP firmware ABI.
+The contents of the ``<launchSecurity type='tdx'>`` element is used to provide
+the guest owners input used for creating an encrypted VM using the Intel TDX
+(Trusted Domain eXtensions). Intel TDX refers to an Intel technology that
+extends Virtual Machine Extensions (VMX) and Multi-Key Total Memory Encryption
+(MKTME) with a new kind of virtual machine guest called a Trust Domain (TD).
+A TD runs in a CPU mode that is designed to protect 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.
+Example configuration:
+
+::
+
+ <domain>
+ ...
+ <launchSecurity type='tdx'>
+ <policy>0x10000001</policy>
+ <mrConfigId>xxx</mrConfigId>
+ <mrOwner>xxx</mrOwner>
+ <mrOwnerConfig>xxx</mrOwnerConfig>
+ <quoteGenerationService path="/var/run/tdx-qgs/qgs.socket"/>
+ </launchSecurity>
+ ...
+ </domain>
+
+``policy``
+ The optional ``policy`` element provides the guest TD attributes which is
+ passed by the host VMM as a guest TD initialization parameter as part of
+ TD_PARAMS, it exactly matches the definition of TD_PARAMS.ATTRIBUTES in
+ (Intel TDX Module Spec Table 22.2: ATTRIBUTES Definition). It is reported
+ to the guest TD by TDG.VP.INFO and as part of TDREPORT_STRUCT returned by
+ TDG.MR.REPORT. The guest policy is 64bit unsigned with the fields shown
+ in Table:
+
+ ====== ====================================================================================
+ Bit(s) Description
+ ====== ====================================================================================
+ 0 Guest TD runs in off-TD debug mode when set
+ 1:27 reserved
+ 28 Disable EPT violation conversion to #VE on guest TD access of PENDING pages when set
+ 29:63 reserved
+ ====== ====================================================================================
+
+``mrConfigId``
+ The optional ``mrConfigId`` element provides ID for non-owner-defined
+ configuration of the guest TD, e.g., run-time or OS configuration
+ (base64 encoded SHA384 digest).
+
+``@mrOwner``
+ The optional ``@mrOwner`` element provides ID for the guest TDs owner
+ (base64 encoded SHA384 digest).
+
+``mrOwnerConfig``
+ The optional ``mrOwnerConfig`` element provides ID for owner-defined
+ configuration of the guest TD, e.g., specific to the workload rather than
+ the run-time or OS (base64 encoded SHA384 digest).
+
+``quoteGenerationService``
+ The optional ``quoteGenerationService`` subelement provides Quote Generation
+ Service(QGS) daemon socket address configuration. It includes an optional
+ ``path`` attribute to determine the UNIX socket address, when omitted,
+ ``/var/run/tdx-qgs/qgs.socket`` is used as default. User in TD guest cannot
+ get TD quoting for attestation if this subelement is not provided.
+
Example configs
===============
--
2.51.0

View File

@ -0,0 +1,196 @@
From e270ac04c7b49177d342b9aa425741a4b748ca2b Mon Sep 17 00:00:00 2001
Message-ID: <e270ac04c7b49177d342b9aa425741a4b748ca2b.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 16:20:17 +0200
Subject: [PATCH] domain_conf: Move format of hyperv features into a function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 78aa096ae21668c14efa30a23876f07ca3f49a6c)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 158 ++++++++++++++++++++++-------------------
1 file changed, 84 insertions(+), 74 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7fd5f76fb6..0b42c283bb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -28022,6 +28022,89 @@ virDomainFeatureTCGFormat(virBuffer *buf,
}
+static void
+virDomainFeaturesHyperVDefFormat(virBuffer *buf,
+ const virDomainDef *def)
+{
+ virBuffer tmpChildBuf = VIR_BUFFER_INIT_CHILD(buf);
+ size_t j;
+
+ if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_HYPERV_MODE_NONE)
+ return;
+
+ virBufferAsprintf(buf, "<hyperv mode='%s'>\n",
+ virDomainHyperVModeTypeToString(def->features[VIR_DOMAIN_FEATURE_HYPERV]));
+
+ for (j = 0; j < VIR_DOMAIN_HYPERV_LAST; j++) {
+ g_auto(virBuffer) hypervAttrBuf = VIR_BUFFER_INITIALIZER;
+ g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&tmpChildBuf);
+
+ if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ABSENT)
+ continue;
+
+ virBufferAsprintf(&hypervAttrBuf, " state='%s'",
+ virTristateSwitchTypeToString(def->hyperv_features[j]));
+
+ switch ((virDomainHyperv) j) {
+ case VIR_DOMAIN_HYPERV_RELAXED:
+ case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_RESET:
+ case VIR_DOMAIN_HYPERV_FREQUENCIES:
+ case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
+ case VIR_DOMAIN_HYPERV_IPI:
+ case VIR_DOMAIN_HYPERV_EVMCS:
+ case VIR_DOMAIN_HYPERV_AVIC:
+ case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
+ case VIR_DOMAIN_HYPERV_XMM_INPUT:
+ break;
+
+ case VIR_DOMAIN_HYPERV_SPINLOCKS:
+ if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
+ virBufferAsprintf(&hypervAttrBuf,
+ " retries='%d'", def->hyperv_spinlocks);
+ }
+ break;
+
+ case VIR_DOMAIN_HYPERV_STIMER:
+ if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON &&
+ def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON) {
+ virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
+ }
+
+ break;
+
+ case VIR_DOMAIN_HYPERV_VENDOR_ID:
+ if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
+ virBufferEscapeString(&hypervAttrBuf, " value='%s'",
+ def->hyperv_vendor_id);
+ }
+ break;
+
+ case VIR_DOMAIN_HYPERV_TLBFLUSH:
+ if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON)
+ break;
+
+ if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
+ virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
+ if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
+ virBufferAddLit(&hypervChildBuf, "<extended state='on'/>\n");
+ break;
+
+ case VIR_DOMAIN_HYPERV_LAST:
+ break;
+ }
+
+ virXMLFormatElement(&tmpChildBuf, virDomainHypervTypeToString(j),
+ &hypervAttrBuf, &hypervChildBuf);
+ }
+
+ virBufferAddBuffer(buf, &tmpChildBuf);
+ virBufferAddLit(buf, "</hyperv>\n");
+}
+
static int
virDomainDefFormatFeatures(virBuffer *buf,
virDomainDef *def)
@@ -28119,80 +28202,7 @@ virDomainDefFormatFeatures(virBuffer *buf,
break;
case VIR_DOMAIN_FEATURE_HYPERV:
- if (def->features[i] == VIR_DOMAIN_HYPERV_MODE_NONE)
- break;
-
- virBufferAsprintf(&childBuf, "<hyperv mode='%s'>\n",
- virDomainHyperVModeTypeToString(def->features[i]));
-
- for (j = 0; j < VIR_DOMAIN_HYPERV_LAST; j++) {
- g_auto(virBuffer) hypervAttrBuf = VIR_BUFFER_INITIALIZER;
- g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&tmpChildBuf);
-
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ABSENT)
- continue;
-
- virBufferAsprintf(&hypervAttrBuf, " state='%s'",
- virTristateSwitchTypeToString(def->hyperv_features[j]));
-
- switch ((virDomainHyperv) j) {
- case VIR_DOMAIN_HYPERV_RELAXED:
- case VIR_DOMAIN_HYPERV_VAPIC:
- case VIR_DOMAIN_HYPERV_VPINDEX:
- case VIR_DOMAIN_HYPERV_RUNTIME:
- case VIR_DOMAIN_HYPERV_SYNIC:
- case VIR_DOMAIN_HYPERV_RESET:
- case VIR_DOMAIN_HYPERV_FREQUENCIES:
- case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
- case VIR_DOMAIN_HYPERV_IPI:
- case VIR_DOMAIN_HYPERV_EVMCS:
- case VIR_DOMAIN_HYPERV_AVIC:
- case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
- case VIR_DOMAIN_HYPERV_XMM_INPUT:
- break;
-
- case VIR_DOMAIN_HYPERV_SPINLOCKS:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
- virBufferAsprintf(&hypervAttrBuf,
- " retries='%d'", def->hyperv_spinlocks);
- }
- break;
-
- case VIR_DOMAIN_HYPERV_STIMER:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON &&
- def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON) {
- virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
- }
-
- break;
-
- case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
- virBufferEscapeString(&hypervAttrBuf, " value='%s'",
- def->hyperv_vendor_id);
- }
- break;
-
- case VIR_DOMAIN_HYPERV_TLBFLUSH:
- if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON)
- break;
-
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
- virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
- virBufferAddLit(&hypervChildBuf, "<extended state='on'/>\n");
- break;
-
- case VIR_DOMAIN_HYPERV_LAST:
- break;
- }
-
- virXMLFormatElement(&tmpChildBuf, virDomainHypervTypeToString(j),
- &hypervAttrBuf, &hypervChildBuf);
- }
-
- virBufferAddBuffer(&childBuf, &tmpChildBuf);
- virBufferAddLit(&childBuf, "</hyperv>\n");
+ virDomainFeaturesHyperVDefFormat(&childBuf, def);
break;
case VIR_DOMAIN_FEATURE_KVM:
--
2.51.1

View File

@ -0,0 +1,105 @@
From d0c72934e0922d19eca8ed0cd812fb56f9222ec6 Mon Sep 17 00:00:00 2001
Message-ID: <d0c72934e0922d19eca8ed0cd812fb56f9222ec6.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 16:05:31 +0200
Subject: [PATCH] domain_conf: Use virXMLFormatElement() to format hyperv
features
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Not only is it more modern that old virBufferAsprintf() of
opening and closing tag, it's also aware of child elements buffer
and thus formats a singleton properly.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c9716c0e0904c86d7e1c9258bc6e808ba7bc8262)
Additionally, hyperv-passthrough.x86_64-6.1.0.xml was modified
too, since the file doesn't exist upstream anymore (see
v11.2.0-rc1~225), but downstream it does.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 13 +++++++------
.../hyperv-passthrough.x86_64-6.1.0.xml | 3 +--
.../hyperv-passthrough.x86_64-latest.xml | 3 +--
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0b42c283bb..f02efaca4e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -28026,18 +28026,19 @@ static void
virDomainFeaturesHyperVDefFormat(virBuffer *buf,
const virDomainDef *def)
{
- virBuffer tmpChildBuf = VIR_BUFFER_INIT_CHILD(buf);
+ virBuffer childBuf = VIR_BUFFER_INIT_CHILD(buf);
+ virBuffer attrBuf = VIR_BUFFER_INITIALIZER;
size_t j;
if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_HYPERV_MODE_NONE)
return;
- virBufferAsprintf(buf, "<hyperv mode='%s'>\n",
+ virBufferAsprintf(&attrBuf, " mode='%s'",
virDomainHyperVModeTypeToString(def->features[VIR_DOMAIN_FEATURE_HYPERV]));
for (j = 0; j < VIR_DOMAIN_HYPERV_LAST; j++) {
g_auto(virBuffer) hypervAttrBuf = VIR_BUFFER_INITIALIZER;
- g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&tmpChildBuf);
+ g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf);
if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ABSENT)
continue;
@@ -28097,14 +28098,14 @@ virDomainFeaturesHyperVDefFormat(virBuffer *buf,
break;
}
- virXMLFormatElement(&tmpChildBuf, virDomainHypervTypeToString(j),
+ virXMLFormatElement(&childBuf, virDomainHypervTypeToString(j),
&hypervAttrBuf, &hypervChildBuf);
}
- virBufferAddBuffer(buf, &tmpChildBuf);
- virBufferAddLit(buf, "</hyperv>\n");
+ virXMLFormatElement(buf, "hyperv", &attrBuf, &childBuf);
}
+
static int
virDomainDefFormatFeatures(virBuffer *buf,
virDomainDef *def)
diff --git a/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-6.1.0.xml b/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-6.1.0.xml
index 02410a403e..d2130dc5c0 100644
--- a/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-6.1.0.xml
+++ b/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-6.1.0.xml
@@ -10,8 +10,7 @@
</os>
<features>
<acpi/>
- <hyperv mode='passthrough'>
- </hyperv>
+ <hyperv mode='passthrough'/>
</features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
diff --git a/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-latest.xml
index 2cfae8fa4c..0ce5bab605 100644
--- a/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-latest.xml
@@ -10,8 +10,7 @@
</os>
<features>
<acpi/>
- <hyperv mode='passthrough'>
- </hyperv>
+ <hyperv mode='passthrough'/>
</features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
--
2.51.1

View File

@ -0,0 +1,139 @@
From 30e83bf71626ce8a180982feb974ac4592b0303c Mon Sep 17 00:00:00 2001
Message-ID: <30e83bf71626ce8a180982feb974ac4592b0303c.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:18 -0400
Subject: [PATCH] qemu: Add FakeReboot support for TDX guest
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Utilize the existing fake reboot mechanism to do reboot for TDX guest.
Different from normal guest, TDX guest doesn't support system_reset,
so have to kill the old guest and start a new one to simulate the reboot.
Co-developed-by: Chenyi Qiang <chenyi.qiang@intel.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 4f733348212b3bb4de491aeaab4ac32f0335673d)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
RHEL: fix arguments to qemuProcessStart, qemuProcessStop, qemuDomainRemoveInactive
---
src/qemu/qemu_process.c | 80 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 77 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7586248329..caf63b0ae3 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -446,6 +446,67 @@ qemuProcessHandleReset(qemuMonitor *mon G_GNUC_UNUSED,
}
+/*
+ * Secure guest doesn't support fake reboot via machine CPU reset.
+ * We thus fake reboot via QEMU re-creation.
+ */
+static void
+qemuProcessFakeRebootViaRecreate(virDomainObj *vm)
+{
+ qemuDomainObjPrivate *priv = vm->privateData;
+ virQEMUDriver *driver = priv->driver;
+ int ret = -1;
+
+ VIR_DEBUG("Handle secure guest reboot: destroy phase");
+
+ virObjectLock(vm);
+ if (qemuProcessBeginStopJob(vm, VIR_JOB_DESTROY, 0) < 0)
+ goto cleanup;
+
+ if (virDomainObjCheckActive(vm) < 0) {
+ qemuProcessEndStopJob(vm);
+ goto cleanup;
+ }
+
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED, VIR_ASYNC_JOB_NONE, 0);
+ virDomainAuditStop(vm, "destroyed");
+
+ /* skip remove inactive domain from active list */
+ qemuProcessEndStopJob(vm);
+
+ VIR_DEBUG("Handle secure guest reboot: boot phase");
+
+ if (qemuProcessBeginJob(vm, VIR_DOMAIN_JOB_OPERATION_START, 0) < 0) {
+ qemuDomainRemoveInactive(driver, vm, 0, false);
+ goto cleanup;
+ }
+
+ if (qemuProcessStart(NULL, driver, vm, NULL, VIR_ASYNC_JOB_START,
+ NULL, -1, NULL, NULL,
+ VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
+ 0) < 0) {
+ virDomainAuditStart(vm, "booted", false);
+ qemuDomainRemoveInactive(driver, vm, 0, false);
+ goto endjob;
+ }
+
+ virDomainAuditStart(vm, "booted", true);
+
+ qemuDomainSaveStatus(vm);
+ ret = 0;
+
+ endjob:
+ qemuProcessEndJob(vm);
+
+ cleanup:
+ priv->pausedShutdown = false;
+ qemuDomainSetFakeReboot(vm, false);
+ if (ret == -1)
+ ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE));
+ virDomainObjEndAPI(&vm);
+}
+
+
/*
* Since we have the '-no-shutdown' flag set, the
* QEMU process will currently have guest OS shutdown
@@ -455,15 +516,13 @@ qemuProcessHandleReset(qemuMonitor *mon G_GNUC_UNUSED,
* guest OS booting up again
*/
static void
-qemuProcessFakeReboot(void *opaque)
+qemuProcessFakeRebootViaReset(virDomainObj *vm)
{
- virDomainObj *vm = opaque;
qemuDomainObjPrivate *priv = vm->privateData;
virQEMUDriver *driver = priv->driver;
virDomainRunningReason reason = VIR_DOMAIN_RUNNING_BOOTED;
int ret = -1, rc;
- VIR_DEBUG("vm=%p", vm);
virObjectLock(vm);
if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0)
goto cleanup;
@@ -509,6 +568,21 @@ qemuProcessFakeReboot(void *opaque)
}
+static void
+qemuProcessFakeReboot(void *opaque)
+{
+ virDomainObj *vm = opaque;
+
+ VIR_DEBUG("vm=%p", vm);
+
+ if (vm->def->sec &&
+ vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX)
+ qemuProcessFakeRebootViaRecreate(vm);
+ else
+ qemuProcessFakeRebootViaReset(vm);
+}
+
+
void
qemuProcessShutdownOrReboot(virDomainObj *vm)
{
--
2.51.0

View File

@ -0,0 +1,72 @@
From b4b30bd7eebc51bbc4b3de23db6cf3b494a8f60f Mon Sep 17 00:00:00 2001
Message-ID: <b4b30bd7eebc51bbc4b3de23db6cf3b494a8f60f.1759835599.git.jdenemar@redhat.com>
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 24 Sep 2025 13:11:50 +0200
Subject: [PATCH] qemu: Add QEMU_CAPS_TDX_GUEST capability
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
QEMU_CAPS_TDX_GUEST set means TDX supported with this QEMU.
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 121fd199420e0f3f645177de78e285dfa3502935)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
RHEL: context
---
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml | 1 +
3 files changed, 4 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index ea0c42d624..f912b4cf9d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -728,6 +728,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"blockdev-set-active", /* QEMU_CAPS_BLOCKDEV_SET_ACTIVE */
"amd-iommu", /* QEMU_CAPS_AMD_IOMMU */
"amd-iommu.pci-id", /* QEMU_CAPS_AMD_IOMMU_PCI_ID */
+ "tdx-guest", /* QEMU_CAPS_TDX_GUEST */
);
@@ -1419,6 +1420,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "acpi-erst", QEMU_CAPS_DEVICE_ACPI_ERST },
{ "virtio-mem-ccw", QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW },
{ "amd-iommu", QEMU_CAPS_AMD_IOMMU },
+ { "tdx-guest", QEMU_CAPS_TDX_GUEST},
};
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 8918e8dfc4..1334a668f0 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -707,6 +707,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_BLOCKDEV_SET_ACTIVE, /* blockdev-set-active QMP command supported */
QEMU_CAPS_AMD_IOMMU, /* -device amd-iommu */
QEMU_CAPS_AMD_IOMMU_PCI_ID, /* amd-iommu.pci-id */
+ QEMU_CAPS_TDX_GUEST, /* -object tdx-guest,... */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
index 584d515d8c..54b09813a8 100644
--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
+++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
@@ -194,6 +194,7 @@
<flag name='blockdev-set-active'/>
<flag name='amd-iommu'/>
<flag name='amd-iommu.pci-id'/>
+ <flag name='tdx-guest'/>
<version>10000050</version>
<microcodeVersion>43100286</microcodeVersion>
<package>v10.0.0-1724-gf9a3def17b</package>
--
2.51.0

View File

@ -0,0 +1,118 @@
From 2fa4ab6a8a776f41e64bcd7a3f1bf0f76e54f8db Mon Sep 17 00:00:00 2001
Message-ID: <2fa4ab6a8a776f41e64bcd7a3f1bf0f76e54f8db.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:11 -0400
Subject: [PATCH] qemu: Add command line and validation for TDX type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
QEMU will provides 'tdx-guest' object which is used to launch encrypted
VMs on Intel platform using TDX feature.
Command line looks like:
$QEMU ... \
-object '{"qom-type":"tdx-guest","id":"lsec0","mrconfigid":"xxx","mrowner":"xxx","mrownerconfig":"xxx","attributes":268435457}' \
-machine pc-q35-6.0,confidential-guest-support=lsec0
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 67b0720d2f2a16ab59a11aa8ecccfe11c73d8727)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
RHEL: pass priv->qemuCaps to qemuBuildObjectCommandlineFromJSON
---
src/conf/domain_conf.h | 5 +++++
src/qemu/qemu_command.c | 29 +++++++++++++++++++++++++++++
src/qemu/qemu_validate.c | 12 ++++++++++++
3 files changed, 46 insertions(+)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1238f2001f..0ea88e013b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2968,6 +2968,11 @@ struct _virDomainTDXDef {
};
+#define VIR_DOMAIN_TDX_POLICY_DEBUG 0x1
+#define VIR_DOMAIN_TDX_POLICY_SEPT_VE_DISABLE 0x10000000
+#define VIR_DOMAIN_TDX_POLICY_ALLOWED_MASK (VIR_DOMAIN_TDX_POLICY_DEBUG | \
+ VIR_DOMAIN_TDX_POLICY_SEPT_VE_DISABLE)
+
struct _virDomainSecDef {
virDomainLaunchSecurity sectype;
union {
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6c5e1926a5..c2183d332e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9750,6 +9750,34 @@ qemuBuildPVCommandLine(virDomainObj *vm, virCommand *cmd)
}
+static int
+qemuBuildTDXCommandLine(virDomainObj *vm, virCommand *cmd,
+ virDomainTDXDef *tdx)
+{
+ g_autoptr(virJSONValue) props = NULL;
+ qemuDomainObjPrivate *priv = vm->privateData;
+
+ if (tdx->havePolicy)
+ VIR_DEBUG("policy=0x%llx", tdx->policy);
+
+ if (qemuMonitorCreateObjectProps(&props, "tdx-guest", "lsec0",
+ "S:mrconfigid", tdx->mrconfigid,
+ "S:mrowner", tdx->mrowner,
+ "S:mrownerconfig", tdx->mrownerconfig,
+ NULL) < 0)
+ return -1;
+
+ if (tdx->havePolicy &&
+ virJSONValueObjectAdd(&props, "U:attributes", tdx->policy, NULL) < 0)
+ return -1;
+
+ if (qemuBuildObjectCommandlineFromJSON(cmd, props, priv->qemuCaps) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static int
qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
virDomainSecDef *sec)
@@ -9769,6 +9797,7 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
break;
case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ return qemuBuildTDXCommandLine(vm, cmd, &sec->data.tdx);
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 34bb7e45c7..80aa2529f2 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1392,6 +1392,18 @@ qemuValidateDomainDef(const virDomainDef *def,
}
break;
case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Intel TDX launch security is not supported with this QEMU binary"));
+ return -1;
+ }
+ if (def->sec->data.tdx.havePolicy &&
+ def->sec->data.tdx.policy & ~VIR_DOMAIN_TDX_POLICY_ALLOWED_MASK) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Only bit0(debug) and bit28(sept-ve-disable) are supported intel TDX launch security policy"));
+ return -1;
+ }
+ break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, def->sec->sectype);
--
2.51.0

View File

@ -0,0 +1,84 @@
From ed45ed36365fd14833c74d6143678afdf8448dc7 Mon Sep 17 00:00:00 2001
Message-ID: <ed45ed36365fd14833c74d6143678afdf8448dc7.1759835600.git.jdenemar@redhat.com>
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 24 Sep 2025 12:41:09 +0200
Subject: [PATCH] qemu: Add command line for TDX Quote Generation Service(QGS)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
'tdx-guest' object supports a "quote-generation-socket" property for
attestation purpose. When "quote-generation-socket" is configured in
guest xml, libvirt generates unix socket format cmdline for QEMU.
'Path' element can be omitted, default path "/var/run/tdx-qgs/qgs.socket"
is used in this case.
QEMU command line example:
qemu-system-x86_64 \
-object '{"qom-type":"tdx-guest","id":"lsec0","mrconfigid":"xxx","mrowner":"xxx","mrownerconfig":"xxx","quote-generation-socket":{"type":"unix","path":"/var/run/tdx-qgs/qgs.socket"},"attributes":268435457}' \
-machine pc-q35-6.0,confidential-guest-support=lsec0
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 61c4c1b538eed608315c21126b4bd1d26f972512)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
RHEL: context
---
src/conf/domain_conf.h | 3 +++
src/qemu/qemu_command.c | 14 ++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 85ef6fbf2c..15aacc71c1 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2959,6 +2959,9 @@ struct _virDomainSEVSNPDef {
};
+/* Copied from QGS source code */
+#define QGS_UNIX_SOCKET_FILE "/var/run/tdx-qgs/qgs.socket"
+
struct _virDomainTDXDef {
bool havePolicy;
unsigned long long policy;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c2183d332e..c6b826a007 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9754,16 +9754,30 @@ static int
qemuBuildTDXCommandLine(virDomainObj *vm, virCommand *cmd,
virDomainTDXDef *tdx)
{
+ g_autoptr(virJSONValue) addr = NULL;
g_autoptr(virJSONValue) props = NULL;
qemuDomainObjPrivate *priv = vm->privateData;
+ const char *path = QGS_UNIX_SOCKET_FILE;
if (tdx->havePolicy)
VIR_DEBUG("policy=0x%llx", tdx->policy);
+ if (tdx->haveQGS) {
+ if (tdx->qgs_unix_path)
+ path = tdx->qgs_unix_path;
+
+ if (virJSONValueObjectAdd(&addr,
+ "s:type", "unix",
+ "s:path", path,
+ NULL) < 0)
+ return -1;
+ }
+
if (qemuMonitorCreateObjectProps(&props, "tdx-guest", "lsec0",
"S:mrconfigid", tdx->mrconfigid,
"S:mrowner", tdx->mrowner,
"S:mrownerconfig", tdx->mrownerconfig,
+ "A:quote-generation-socket", &addr,
NULL) < 0)
return -1;
--
2.51.0

View File

@ -0,0 +1,48 @@
From 80e6f292a501cc9bc8b2d5197c339326ecff0323 Mon Sep 17 00:00:00 2001
Message-ID: <80e6f292a501cc9bc8b2d5197c339326ecff0323.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:20 -0400
Subject: [PATCH] qemu: Avoid duplicate FakeReboot for secure guest
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
For secure guest, FakeReboot kills original QEMU instance and
create new one. During this process, QEMU send SHUTDOWN event
with "host-signal" reason which can trigger another FakeReboot.
Check if a FakeReboot is ongoing and bypass "host-signal"
processing which originally comes from FakeReboot.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 194a36f4fe14b489b4697396d908c2a2c578ca5c)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/qemu/qemu_monitor.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 40f15c88a8..6d19b675d5 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1076,6 +1076,16 @@ qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest,
* with it here. */
if (vm->def->sec &&
vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX) {
+ qemuDomainObjPrivate *priv = vm->privateData;
+
+ /* For secure guest, FakeReboot kills original QEMU instance and
+ * create new one. During this process, QEMU send SHUTDOWN event
+ * with "host-signal" reason which can trigger another FakeReboot.
+ * Check if a FakeReboot is ongoing and bypass "host-signal"
+ * processing which is originally come from FakeReboot. */
+ if (priv->fakeReboot && STREQ_NULLABLE(reason, "host-signal"))
+ return;
+
if ((STREQ_NULLABLE(reason, "guest-shutdown") &&
vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART) ||
(STREQ_NULLABLE(reason, "guest-reset") &&
--
2.51.0

View File

@ -0,0 +1,68 @@
From 7eff4d32f92fa15ffa3705b977cf8e29d41f6d26 Mon Sep 17 00:00:00 2001
Message-ID: <7eff4d32f92fa15ffa3705b977cf8e29d41f6d26.1759835599.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:04 -0400
Subject: [PATCH] qemu: Check if INTEL Trust Domain Extention support is
enabled
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implement TDX check in order to generate domain feature capability
correctly 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>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
(cherry picked from commit d7c96e809d2c446830930790db5206168aedef81)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/qemu/qemu_capabilities.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d60d2d95cc..ea0c42d624 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -5308,6 +5308,24 @@ virQEMUCapsKVMSupportsSecureGuestAMD(void)
}
+/*
+ * Check whether INTEL Trust Domain Extention (x86) is enabled
+ */
+static bool
+virQEMUCapsKVMSupportsSecureGuestTDX(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.
@@ -5321,7 +5339,8 @@ virQEMUCapsKVMSupportsSecureGuest(void)
return virQEMUCapsKVMSupportsSecureGuestS390();
if (ARCH_IS_X86(arch))
- return virQEMUCapsKVMSupportsSecureGuestAMD();
+ return virQEMUCapsKVMSupportsSecureGuestAMD() ||
+ virQEMUCapsKVMSupportsSecureGuestTDX();
return false;
}
--
2.51.0

View File

@ -0,0 +1,73 @@
From 809c8b4ebb569d283e02b869580914a6c7d9edd5 Mon Sep 17 00:00:00 2001
Message-ID: <809c8b4ebb569d283e02b869580914a6c7d9edd5.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:13 -0400
Subject: [PATCH] qemu: Force special parameters enabled for TDX guest
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
TDX guest requires some special parameters to boot, currently:
"kernel_irqchip=split"
"pmu!=on"
"smm!=on"
"-bios"
If not specified explicitly, QEMU should configure this option implicitly
when start a TDX guest.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 626b9ca84650966de266ff41e9df59aba948f65e)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/qemu/qemu_validate.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 80aa2529f2..bbd838c7f0 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1403,6 +1403,38 @@ qemuValidateDomainDef(const virDomainDef *def,
_("Only bit0(debug) and bit28(sept-ve-disable) are supported intel TDX launch security policy"));
return -1;
}
+ if (def->features[VIR_DOMAIN_FEATURE_IOAPIC] == VIR_DOMAIN_IOAPIC_KVM) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Intel TDX launch security needs split kernel irqchip"));
+ return -1;
+ }
+ /* Current KVM doesn't support PMU for TD guest. It returns
+ * error if TD is created with PMU bit being set in attributes.
+ * By default, QEMU disable PMU for TD guest.
+ */
+ if (def->features[VIR_DOMAIN_FEATURE_PMU] == VIR_TRISTATE_SWITCH_ON) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Intel TDX launch security is not supported with PMU enabled"));
+ return -1;
+ }
+ /* TDX doesn't support SMM and VMM cannot emulate SMM for TDX VMs
+ * because VMM cannot manipulate TDX VM's memory.
+ * By default, QEMU disable SMM for TD guest.
+ */
+ if (def->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Intel TDX launch security is not supported with SMM enabled"));
+ return -1;
+ }
+ /* TDVF(OVMF) needs to run at private memory for TD guest. TDX cannot
+ * support pflash device since it doesn't support read-only private memory.
+ * Thus load TDVF(OVMF) with -bios option for TDs.
+ */
+ if (def->os.loader && def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_PFLASH) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Intel TDX launch security is not supported with pflash loader"));
+ return -1;
+ }
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
--
2.51.0

View File

@ -0,0 +1,290 @@
From b9646a88096cda2840560b907ce8c68f0de2f36b Mon Sep 17 00:00:00 2001
Message-ID: <b9646a88096cda2840560b907ce8c68f0de2f36b.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 14:17:56 +0200
Subject: [PATCH] qemu: Ignore "ht" CPU feature
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The feature does not do anything, QEMU will always set it according to
the CPU topology completely ignoring what we asked for. Unfortunately,
the way the state of "ht" is reported changed in QEMU 10.0.0 (commit
c6bd2dd634208).
QEMU older than 10.0.0 would just report whatever was specified on the
command line totally ignoring the actual state of the feature visible to
a guest. But after the change QEMU reports ht=on in case it enabled "ht"
based on the CPU topology. In all other cases QEMU still reports the
state requested on the command line.
As a result of this change a domain with multiple CPU threads started on
QEMU < 10.0.0 could not be migrated to QEMU >= 10.0.0 unless "ht" was
explicitly enabled in the domain XML because libvirt would see "ht"
enabled on the destination, but disabled on the source (the guest would
see "ht" enabled in both cases anyway). Outgoing migration of domains
started on QEMU >= 10.0.0 is not affected.
To fix this issue we can completely ignore "ht" both in the domain XML
and in the CPU properties reported by QEMU. With this fix incoming
migration to QEMU >= 10.0.0 works again.
Fixes: https://gitlab.com/libvirt/libvirt/-/issues/821
Fixes: https://issues.redhat.com/browse/RHEL-104216
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit ba16113c76050a10bbccaae0192a0d30f97de5ae)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 1 +
tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args | 2 +-
.../cpu-check-default-partial.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml | 1 -
tests/qemuxmlconfdata/cpu-exact2-nofallback.xml | 1 -
tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml | 1 -
tests/qemuxmlconfdata/cpu-exact2.xml | 1 -
tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml | 1 -
tests/qemuxmlconfdata/cpu-strict1.xml | 1 -
tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args | 2 +-
18 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6e79bd98c8..b75ecd5046 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3725,6 +3725,7 @@ const char *ignoredFeatures[] = {
"osxsave", "ospke", /* dropped from QEMU */
"vmx-ept-uc", "vmx-ept-wb", /* never supported by QEMU */
"vmx-invvpid-single-context", /* never supported by QEMU */
+ "ht", /* ignored by QEMU, set according to topology */
};
bool
diff --git a/tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args
index 4adf20b55a..1e962589c9 100644
--- a/tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-foo/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,l3-cache=off \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,l3-cache=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-check-default-partial.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-check-default-partial.x86_64-latest.args
index a92da44bd8..fe553fd31b 100644
--- a/tests/qemuxmlconfdata/cpu-check-default-partial.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-check-default-partial.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args
index 20b0306268..7464609aba 100644
--- a/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu core2duo,ds=on,ht=on,tm=on,ds-cpl=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off \
+-cpu core2duo,ds=on,tm=on,ds-cpl=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml b/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml
index d66d0a182b..05c78334ab 100644
--- a/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml
@@ -11,7 +11,6 @@
<cpu mode='custom' match='exact' check='partial'>
<model fallback='forbid'>core2duo</model>
<feature policy='require' name='ds'/>
- <feature policy='require' name='ht'/>
<feature policy='optional' name='tm'/>
<feature policy='require' name='ds_cpl'/>
<feature policy='require' name='xtpr'/>
diff --git a/tests/qemuxmlconfdata/cpu-exact2-nofallback.xml b/tests/qemuxmlconfdata/cpu-exact2-nofallback.xml
index 4cd1d18216..d7c3e4f40f 100644
--- a/tests/qemuxmlconfdata/cpu-exact2-nofallback.xml
+++ b/tests/qemuxmlconfdata/cpu-exact2-nofallback.xml
@@ -11,7 +11,6 @@
<cpu match='exact'>
<model fallback='forbid'>core2duo</model>
<feature name='ds' policy='require'/>
- <feature name='ht' policy='require'/>
<feature name='tm' policy='optional'/>
<feature name='ds_cpl' policy='require'/>
<feature name='xtpr' policy='require'/>
diff --git a/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args
index 20b0306268..7464609aba 100644
--- a/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu core2duo,ds=on,ht=on,tm=on,ds-cpl=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off \
+-cpu core2duo,ds=on,tm=on,ds-cpl=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml b/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml
index 7dccf6902c..cf9d241372 100644
--- a/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml
@@ -11,7 +11,6 @@
<cpu mode='custom' match='exact' check='partial'>
<model fallback='allow'>core2duo</model>
<feature policy='require' name='ds'/>
- <feature policy='require' name='ht'/>
<feature policy='optional' name='tm'/>
<feature policy='require' name='ds_cpl'/>
<feature policy='require' name='xtpr'/>
diff --git a/tests/qemuxmlconfdata/cpu-exact2.xml b/tests/qemuxmlconfdata/cpu-exact2.xml
index 4239796f31..b4800262f6 100644
--- a/tests/qemuxmlconfdata/cpu-exact2.xml
+++ b/tests/qemuxmlconfdata/cpu-exact2.xml
@@ -11,7 +11,6 @@
<cpu match='exact'>
<model>core2duo</model>
<feature name='ds' policy='require'/>
- <feature name='ht' policy='require'/>
<feature name='tm' policy='optional'/>
<feature name='ds_cpl' policy='require'/>
<feature name='xtpr' policy='require'/>
diff --git a/tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args
index 510e19bba6..d6b57d40a3 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel tcg \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args
index c258a1ab36..ef7d442d5b 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel tcg \
--cpu 'Haswell,vendor=Libvirt QEMU,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on' \
+-cpu 'Haswell,vendor=Libvirt QEMU,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on' \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args
index a92da44bd8..fe553fd31b 100644
--- a/tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args
index 62e0101568..ddd0c64080 100644
--- a/tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,syscall=off,nx=off,lm=off,svm=off \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,syscall=off,nx=off,lm=off,svm=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args
index 92c719b553..3808af7399 100644
--- a/tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-foo/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,phys-bits=42 \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,phys-bits=42 \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args
index 3f9c3516bb..7e870db393 100644
--- a/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,ds=on,acpi=on,ht=on,tm=on,ds-cpl=on,vmx=on,est=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off,vme=off,invtsc=off,abm=off,pdpe1gb=off,rdrand=off,f16c=off,pdcm=off,smx=off,monitor=off,dtes64=off \
+-cpu Haswell,ds=on,acpi=on,tm=on,ds-cpl=on,vmx=on,est=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off,vme=off,invtsc=off,abm=off,pdpe1gb=off,rdrand=off,f16c=off,pdcm=off,smx=off,monitor=off,dtes64=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml b/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml
index beeaf5c682..9c5e083aee 100644
--- a/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml
@@ -12,7 +12,6 @@
<model fallback='allow'>Haswell</model>
<feature policy='require' name='ds'/>
<feature policy='optional' name='acpi'/>
- <feature policy='require' name='ht'/>
<feature policy='optional' name='tm'/>
<feature policy='require' name='ds_cpl'/>
<feature policy='optional' name='vmx'/>
diff --git a/tests/qemuxmlconfdata/cpu-strict1.xml b/tests/qemuxmlconfdata/cpu-strict1.xml
index 63db54ecad..c0548b3dca 100644
--- a/tests/qemuxmlconfdata/cpu-strict1.xml
+++ b/tests/qemuxmlconfdata/cpu-strict1.xml
@@ -12,7 +12,6 @@
<model>Haswell</model>
<feature name='ds' policy='require'/>
<feature name='acpi' policy='optional'/>
- <feature name='ht' policy='require'/>
<feature name='tm' policy='optional'/>
<feature name='ds_cpl' policy='require'/>
<feature name='vmx' policy='optional'/>
diff --git a/tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args
index 4353d65ac2..e926d309f5 100644
--- a/tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,invtsc=on,tsc-frequency=4567890000 \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,invtsc=on,tsc-frequency=4567890000 \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
--
2.51.1

View File

@ -0,0 +1,138 @@
From dbeae7c9d470143a0c23195d1880ad302bce78ab Mon Sep 17 00:00:00 2001
Message-ID: <dbeae7c9d470143a0c23195d1880ad302bce78ab.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:21 -0400
Subject: [PATCH] qemu: Send event VIR_DOMAIN_EVENT_[STOPPED|STARTED] during
recreation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
For secure guest, FakeReboot kills original QEMU instance and
create new one which is quite different from normal guest.
To reflect this fact, VIR_DOMAIN_EVENT_[STOPPED|STARTED]
are sent to control plane with new introduced reasons
VIR_DOMAIN_EVENT_[STOPPED|STARTED]_RECREATION.
That would let control plane software understand that these
events are from a fake reboot.
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
(cherry picked from commit 1af740c5012bb45dfe96c77bcd6b20c28b6bb45d)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
examples/c/misc/event-test.c | 6 ++++++
include/libvirt/libvirt-domain.h | 2 ++
src/qemu/qemu_process.c | 10 ++++++++++
tools/virsh-domain-event.c | 6 ++++--
4 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/examples/c/misc/event-test.c b/examples/c/misc/event-test.c
index 88d99dff56..04d74670e7 100644
--- a/examples/c/misc/event-test.c
+++ b/examples/c/misc/event-test.c
@@ -143,6 +143,9 @@ eventDetailToString(int event,
case VIR_DOMAIN_EVENT_STARTED_WAKEUP:
return "Event wakeup";
+ case VIR_DOMAIN_EVENT_STARTED_RECREATION:
+ return "Recreation";
+
case VIR_DOMAIN_EVENT_STARTED_LAST:
break;
}
@@ -227,6 +230,9 @@ eventDetailToString(int event,
case VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT:
return "Snapshot";
+ case VIR_DOMAIN_EVENT_STOPPED_RECREATION:
+ return "Recreation";
+
case VIR_DOMAIN_EVENT_STOPPED_LAST:
break;
}
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index df13b72f7b..7759ddeaad 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -3873,6 +3873,7 @@ typedef enum {
VIR_DOMAIN_EVENT_STARTED_RESTORED = 2, /* Restored from a state file (Since: 0.5.0) */
VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT = 3, /* Restored from snapshot (Since: 0.8.0) */
VIR_DOMAIN_EVENT_STARTED_WAKEUP = 4, /* Started due to wakeup event (Since: 0.9.11) */
+ VIR_DOMAIN_EVENT_STARTED_RECREATION = 5, /* Secure guest recreation (Since: 10.1.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_STARTED_LAST /* (Since: 0.9.10) */
@@ -3937,6 +3938,7 @@ typedef enum {
VIR_DOMAIN_EVENT_STOPPED_SAVED = 4, /* Saved to a state file (Since: 0.5.0) */
VIR_DOMAIN_EVENT_STOPPED_FAILED = 5, /* Host emulator/mgmt failed (Since: 0.5.0) */
VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT = 6, /* offline snapshot loaded (Since: 0.8.0) */
+ VIR_DOMAIN_EVENT_STOPPED_RECREATION = 7, /* Secure guest recreation (Since: 10.1.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_STOPPED_LAST /* (Since: 0.9.10) */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index caf63b0ae3..0d4fdf6960 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -455,6 +455,7 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
virQEMUDriver *driver = priv->driver;
+ virObjectEvent *event = NULL;
int ret = -1;
VIR_DEBUG("Handle secure guest reboot: destroy phase");
@@ -471,6 +472,11 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm)
qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED, VIR_ASYNC_JOB_NONE, 0);
virDomainAuditStop(vm, "destroyed");
+ event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_RECREATION);
+ virObjectEventStateQueue(driver->domainEventState, event);
+
/* skip remove inactive domain from active list */
qemuProcessEndStopJob(vm);
@@ -491,6 +497,10 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm)
}
virDomainAuditStart(vm, "booted", true);
+ event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STARTED,
+ VIR_DOMAIN_EVENT_STARTED_RECREATION);
+ virObjectEventStateQueue(driver->domainEventState, event);
qemuDomainSaveStatus(vm);
ret = 0;
diff --git a/tools/virsh-domain-event.c b/tools/virsh-domain-event.c
index cd33d4d938..1b42ed706d 100644
--- a/tools/virsh-domain-event.c
+++ b/tools/virsh-domain-event.c
@@ -70,7 +70,8 @@ VIR_ENUM_IMPL(virshDomainEventStarted,
N_("Migrated"),
N_("Restored"),
N_("Snapshot"),
- N_("Event wakeup"));
+ N_("Event wakeup"),
+ N_("Recreation"));
VIR_ENUM_DECL(virshDomainEventSuspended);
VIR_ENUM_IMPL(virshDomainEventSuspended,
@@ -103,7 +104,8 @@ VIR_ENUM_IMPL(virshDomainEventStopped,
N_("Migrated"),
N_("Saved"),
N_("Failed"),
- N_("Snapshot"));
+ N_("Snapshot"),
+ N_("Recreation"));
VIR_ENUM_DECL(virshDomainEventShutdown);
VIR_ENUM_IMPL(virshDomainEventShutdown,
--
2.51.0

View File

@ -0,0 +1,150 @@
From 9a47f88f06ca6c1274c2bb5ca723057faf33e86e Mon Sep 17 00:00:00 2001
Message-ID: <9a47f88f06ca6c1274c2bb5ca723057faf33e86e.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:23 -0400
Subject: [PATCH] qemu: Support domain reset command for TDX guest
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
TDX guest doesn't support system_reset, so have to kill the old QEMU and
start a new one to simulate the reset. This can be achieved by calling
qemuProcessFakeRebootViaRecreate().
Simiar as FakeReboot, QEMU sends SHUTDOWN event with "host-signal" reason
which can trigger another FakeReset. Check if a FakeReset is ongoing and
bypass "host-signal" processing which originally comes from FakeReset.
Domain lock is already hold in qemuDomainReset() before calling
qemuProcessFakeRebootViaRecreate(), so bypass locking in it.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit fcc12f217e7a45ec6049642c2707917bb290d58c)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_driver.c | 10 +++++++++-
src/qemu/qemu_monitor.c | 6 ++++++
src/qemu/qemu_process.c | 14 +++++++++-----
src/qemu/qemu_process.h | 2 ++
5 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 3f16f86da8..d787d2a065 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -128,6 +128,7 @@ struct _qemuDomainObjPrivate {
char *lockState;
bool fakeReboot;
+ bool fakeReset;
bool pausedShutdown;
/* allowReboot:
*
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7d0c39c89f..98bfe8124d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2008,13 +2008,21 @@ qemuDomainReset(virDomainPtr dom, unsigned int flags)
if (virDomainResetEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
+ priv = vm->privateData;
+
+ if (vm->def->sec &&
+ vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX) {
+ priv->fakeReset = true;
+ ret = qemuProcessFakeRebootViaRecreate(vm, true);
+ goto cleanup;
+ }
+
if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0)
goto cleanup;
if (virDomainObjCheckActive(vm) < 0)
goto endjob;
- priv = vm->privateData;
qemuDomainObjEnterMonitor(vm);
ret = qemuMonitorSystemReset(priv->mon);
qemuDomainObjExitMonitor(vm);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 6d19b675d5..a9fe4f2f6b 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1086,6 +1086,12 @@ qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest,
if (priv->fakeReboot && STREQ_NULLABLE(reason, "host-signal"))
return;
+ /* Similar as FakeReboot for FakeReset. */
+ if (priv->fakeReset && STREQ_NULLABLE(reason, "host-signal")) {
+ priv->fakeReset = false;
+ return;
+ }
+
if ((STREQ_NULLABLE(reason, "guest-shutdown") &&
vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART) ||
(STREQ_NULLABLE(reason, "guest-reset") &&
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0d4fdf6960..7b6c02bc27 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -450,8 +450,8 @@ qemuProcessHandleReset(qemuMonitor *mon G_GNUC_UNUSED,
* Secure guest doesn't support fake reboot via machine CPU reset.
* We thus fake reboot via QEMU re-creation.
*/
-static void
-qemuProcessFakeRebootViaRecreate(virDomainObj *vm)
+int
+qemuProcessFakeRebootViaRecreate(virDomainObj *vm, bool locked)
{
qemuDomainObjPrivate *priv = vm->privateData;
virQEMUDriver *driver = priv->driver;
@@ -460,7 +460,9 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm)
VIR_DEBUG("Handle secure guest reboot: destroy phase");
- virObjectLock(vm);
+ if (!locked)
+ virObjectLock(vm);
+
if (qemuProcessBeginStopJob(vm, VIR_JOB_DESTROY, 0) < 0)
goto cleanup;
@@ -513,7 +515,9 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm)
qemuDomainSetFakeReboot(vm, false);
if (ret == -1)
ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE));
- virDomainObjEndAPI(&vm);
+ if (!locked)
+ virDomainObjEndAPI(&vm);
+ return ret;
}
@@ -587,7 +591,7 @@ qemuProcessFakeReboot(void *opaque)
if (vm->def->sec &&
vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX)
- qemuProcessFakeRebootViaRecreate(vm);
+ ignore_value(qemuProcessFakeRebootViaRecreate(vm, false));
else
qemuProcessFakeRebootViaReset(vm);
}
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index fee00ce53b..3074f27b64 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -184,6 +184,8 @@ typedef enum {
int qemuProcessKill(virDomainObj *vm, unsigned int flags);
+int qemuProcessFakeRebootViaRecreate(virDomainObj *vm, bool locked);
+
void qemuProcessShutdownOrReboot(virDomainObj *vm);
void qemuProcessAutoDestroy(virDomainObj *dom,
--
2.51.0

View File

@ -0,0 +1,96 @@
From ae1ff9ae8b699e4be8b482d7dee32b3fe27767c7 Mon Sep 17 00:00:00 2001
Message-ID: <ae1ff9ae8b699e4be8b482d7dee32b3fe27767c7.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:19 -0400
Subject: [PATCH] qemu: Support reboot command in guest
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We can reboot a TDX guest with 'virsh reboot' or 'virsh shutdown' if action
for onPoweroff is 'restart'. But running reboot command in guest shell will
always lead to shutdown.
This behavior is not consistent with normal guest, fix it by checking
shutdown reason and action configuration to trigger FakeReboot.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 312c3afa48936c7a9676408abdd5a44cb9ad2baa)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/qemu/qemu_monitor.c | 18 +++++++++++++++++-
src/qemu/qemu_monitor.h | 2 +-
src/qemu/qemu_monitor_json.c | 6 +++++-
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 18b877ce29..40f15c88a8 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1063,10 +1063,26 @@ qemuMonitorEmitEvent(qemuMonitor *mon, const char *event,
void
-qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest)
+qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest,
+ const char *reason)
{
+ virDomainObj *vm = mon->vm;
+
VIR_DEBUG("mon=%p guest=%u", mon, guest);
+ /* This isn't best place to set FakeReboot but we need to access
+ * mon->vm which is defined in this file. Reboot command in guest
+ * will trigger SHUTDOWN event for TDX guest, so we has to deal
+ * with it here. */
+ if (vm->def->sec &&
+ vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX) {
+ if ((STREQ_NULLABLE(reason, "guest-shutdown") &&
+ vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART) ||
+ (STREQ_NULLABLE(reason, "guest-reset") &&
+ vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART))
+ qemuDomainSetFakeReboot(vm, true);
+ }
+
QEMU_MONITOR_CALLBACK(mon, domainShutdown, mon->vm, guest);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index bf44c96057..d4730162ca 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -460,7 +460,7 @@ int qemuMonitorUpdateVideoVram64Size(qemuMonitor *mon,
void qemuMonitorEmitEvent(qemuMonitor *mon, const char *event,
long long seconds, unsigned int micros,
const char *details);
-void qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest);
+void qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest, const char *reason);
void qemuMonitorEmitReset(qemuMonitor *mon);
void qemuMonitorEmitStop(qemuMonitor *mon);
void qemuMonitorEmitResume(qemuMonitor *mon);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index db46bcc741..cbe10ad907 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -548,12 +548,16 @@ qemuMonitorJSONMakeCommand(const char *cmdname,
static void qemuMonitorJSONHandleShutdown(qemuMonitor *mon, virJSONValue *data)
{
bool guest = false;
+ const char *reason = NULL;
virTristateBool guest_initiated = VIR_TRISTATE_BOOL_ABSENT;
if (data && virJSONValueObjectGetBoolean(data, "guest", &guest) == 0)
guest_initiated = virTristateBoolFromBool(guest);
- qemuMonitorEmitShutdown(mon, guest_initiated);
+ if (data)
+ reason = virJSONValueObjectGetString(data, "reason");
+
+ qemuMonitorEmitShutdown(mon, guest_initiated, reason);
}
static void qemuMonitorJSONHandleReset(qemuMonitor *mon, virJSONValue *data G_GNUC_UNUSED)
--
2.51.0

View File

@ -0,0 +1,52 @@
From 21dece5adb14014a8f8e6cc1c1b82fd98082fe75 Mon Sep 17 00:00:00 2001
Message-ID: <21dece5adb14014a8f8e6cc1c1b82fd98082fe75.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 2 Oct 2025 09:38:04 +0200
Subject: [PATCH] qemu: Use virXPathTristateBool()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There are two places in our code base which can use freshly
introduced virXPathTristateBool():
qemuStorageSourcePrivateDataParse() and
qemuDomainObjPrivateXMLParseBlockjobs().
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 5369f071e40cb91a8b7ee79efda078eca7b15035)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_domain.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8879a45ffb..56d8bb4827 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2072,7 +2072,7 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
g_autofree char *authalias = NULL;
g_autofree char *httpcookiealias = NULL;
g_autofree char *tlskeyalias = NULL;
- g_autofree char *thresholdEventWithIndex = NULL;
+ virTristateBool thresholdEventWithIndex;
bool fdsetPresent = false;
unsigned int fdSetID;
int enccount;
@@ -2138,9 +2138,10 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
if (virStorageSourcePrivateDataParseRelPath(ctxt, src) < 0)
return -1;
- if ((thresholdEventWithIndex = virXPathString("string(./thresholdEvent/@indexUsed)", ctxt)) &&
- virTristateBoolTypeFromString(thresholdEventWithIndex) == VIR_TRISTATE_BOOL_YES)
- src->thresholdEventWithIndex = true;
+ if (virXPathTristateBool("string(./thresholdEvent/@indexUsed)",
+ ctxt, &thresholdEventWithIndex) >= 0) {
+ virTristateBoolToBool(thresholdEventWithIndex, &src->thresholdEventWithIndex);
+ }
if ((nbdkitnode = virXPathNode("nbdkit", ctxt))) {
if (qemuStorageSourcePrivateDataParseNbdkit(nbdkitnode, ctxt, src) < 0)
--
2.51.1

View File

@ -0,0 +1,165 @@
From 052fb2f399b0fd750421ae0451f9bc17d5660147 Mon Sep 17 00:00:00 2001
Message-ID: <052fb2f399b0fd750421ae0451f9bc17d5660147.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:14 -0400
Subject: [PATCH] qemu: log the crash information for TDX
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since QEMU 10.1.0 commit id '6e250463b08b' guest crash information for
TDX is available in the QEMU monitor, e.g.:
{
"timestamp": {
"seconds": 1752118704,
"microseconds": 27480
},
"event": "GUEST_PANICKED",
"data": {
"action": "pause",
"info": {
"error-code": 0,
"message": "TD misconfiguration: SEPT #VE has to be disabled",
"type": "tdx"
}
}
}
Let's log this information into the domain log file, e.g.:
2025-07-10 03:39:18.243+0000: panic tdx: error_code='0x0' message='TD misconfiguration: SEPT #VE has to be disabled'
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
(cherry picked from commit 9df19f60f64f77f51b1bc1a632dfb0d30334b2dd)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/qemu/qemu_monitor.c | 16 ++++++++++++++++
src/qemu/qemu_monitor.h | 11 +++++++++++
src/qemu/qemu_monitor_json.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 59 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 3945aa92e5..18b877ce29 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3916,6 +3916,19 @@ qemuMonitorGuestPanicEventInfoFormatMsg(qemuMonitorEventPanicInfo *info)
info->data.s390.psw_addr,
info->data.s390.reason);
break;
+ case QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_TDX:
+ if (info->data.tdx.has_gpa)
+ ret = g_strdup_printf("tdx: error_code='0x%x' message='%s' "
+ "additional error information can be found "
+ "at gpa page: '0x%016llx'",
+ info->data.tdx.error_code,
+ info->data.tdx.message,
+ info->data.tdx.gpa);
+ else
+ ret = g_strdup_printf("tdx: error_code='0x%x' message='%s'",
+ info->data.tdx.error_code,
+ info->data.tdx.message);
+ break;
case QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_NONE:
case QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_LAST:
break;
@@ -3935,6 +3948,9 @@ qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicInfo *info)
case QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_S390:
g_free(info->data.s390.reason);
break;
+ case QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_TDX:
+ g_free(info->data.tdx.message);
+ break;
case QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_NONE:
case QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_HYPERV:
case QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_LAST:
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index acb3279e45..bf44c96057 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -38,6 +38,7 @@ typedef enum {
QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_NONE = 0,
QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_HYPERV,
QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_S390,
+ QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_TDX,
QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_LAST
} qemuMonitorEventPanicInfoType;
@@ -61,12 +62,22 @@ struct _qemuMonitorEventPanicInfoS390 {
char *reason;
};
+typedef struct _qemuMonitorEventPanicInfoTDX qemuMonitorEventPanicInfoTDX;
+struct _qemuMonitorEventPanicInfoTDX {
+ /* TDX specific guest panic information */
+ int error_code;
+ char *message;
+ bool has_gpa;
+ unsigned long long gpa;
+};
+
typedef struct _qemuMonitorEventPanicInfo qemuMonitorEventPanicInfo;
struct _qemuMonitorEventPanicInfo {
qemuMonitorEventPanicInfoType type;
union {
qemuMonitorEventPanicInfoHyperv hyperv;
qemuMonitorEventPanicInfoS390 s390;
+ qemuMonitorEventPanicInfoTDX tdx;
} data;
};
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index edf6fac76e..db46bcc741 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -621,6 +621,36 @@ qemuMonitorJSONGuestPanicExtractInfoS390(virJSONValue *data)
return g_steal_pointer(&ret);
}
+static qemuMonitorEventPanicInfo *
+qemuMonitorJSONGuestPanicExtractInfoTDX(virJSONValue *data)
+{
+ g_autoptr(qemuMonitorEventPanicInfo) ret = NULL;
+ int error_code;
+ unsigned long long gpa = 0;
+ const char *message = NULL;
+ bool has_gpa;
+
+ ret = g_new0(qemuMonitorEventPanicInfo, 1);
+
+ ret->type = QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_TDX;
+ has_gpa = virJSONValueObjectHasKey(data, "gpa");
+
+ if (virJSONValueObjectGetNumberInt(data, "error-code", &error_code) < 0 ||
+ !(message = virJSONValueObjectGetString(data, "message")) ||
+ (has_gpa && virJSONValueObjectGetNumberUlong(data, "gpa", &gpa) < 0)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed TDX panic data"));
+ return NULL;
+ }
+
+ ret->data.tdx.error_code = error_code;
+ ret->data.tdx.gpa = gpa;
+ ret->data.tdx.has_gpa = has_gpa;
+
+ ret->data.tdx.message = g_strdup(message);
+
+ return g_steal_pointer(&ret);
+}
+
static qemuMonitorEventPanicInfo *
qemuMonitorJSONGuestPanicExtractInfo(virJSONValue *data)
{
@@ -630,6 +660,8 @@ qemuMonitorJSONGuestPanicExtractInfo(virJSONValue *data)
return qemuMonitorJSONGuestPanicExtractInfoHyperv(data);
else if (STREQ_NULLABLE(type, "s390"))
return qemuMonitorJSONGuestPanicExtractInfoS390(data);
+ else if (STREQ_NULLABLE(type, "tdx"))
+ return qemuMonitorJSONGuestPanicExtractInfoTDX(data);
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown panic info type '%1$s'"), NULLSTR(type));
--
2.51.0

View File

@ -0,0 +1,684 @@
From 64f14820e423b85d5af0ffffe87f43f2332b023e Mon Sep 17 00:00:00 2001
Message-ID: <64f14820e423b85d5af0ffffe87f43f2332b023e.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 30 Sep 2025 15:37:24 +0200
Subject: [PATCH] qemu_capabilities: Fetch new hyperv domcaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Now that everything is prepared, we can start storing the default
values for some hyperv features that are reported in domain
capabilities XML later.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit ba011bebd9a13d4926aeb56d4c88f0e03ef22c50)
Conflicts:
tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml
tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml
tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml
tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
tests/domaincapsdata/qemu_6.0.0.x86_64.xml
tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
tests/domaincapsdata/qemu_6.1.0.x86_64.xml
tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml
tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml
tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml
tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml
tests/qemucapabilitiesdata/caps_5.2.0_x86_64.xml
tests/qemucapabilitiesdata/caps_6.0.0_x86_64.xml
tests/qemucapabilitiesdata/caps_6.1.0_x86_64.xml: Some files
don't exist downstream yet, others have context issues.
Regenerated with VIR_TEST_REGENERATE_OUTPUT=1.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_capabilities.c | 44 +++++++++++++++++++
.../domaincapsdata/qemu_10.0.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_10.0.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_10.0.0.x86_64.xml | 7 +++
.../qemu_10.1.0-q35.x86_64+inteltdx.xml | 7 +++
.../qemu_10.1.0-tcg.x86_64+inteltdx.xml | 7 +++
.../qemu_10.1.0.x86_64+inteltdx.xml | 7 +++
.../domaincapsdata/qemu_8.0.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_8.0.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.1.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_8.1.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.2.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_8.2.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.0.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.0.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_9.0.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.1.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.1.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_9.1.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.2.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.2.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_9.2.0.x86_64.xml | 7 +++
.../caps_10.0.0_x86_64.xml | 5 +++
.../caps_10.1.0_x86_64+inteltdx.xml | 5 +++
.../caps_8.0.0_x86_64.xml | 5 +++
.../caps_8.1.0_x86_64.xml | 5 +++
.../caps_8.2.0_x86_64.xml | 5 +++
.../caps_9.0.0_x86_64.xml | 5 +++
.../caps_9.1.0_x86_64.xml | 5 +++
.../caps_9.2.0_x86_64.xml | 5 +++
33 files changed, 252 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0452600195..edd4494fa1 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3133,6 +3133,50 @@ virQEMUCapsProbeHypervCapabilities(virQEMUCaps *qemuCaps,
if (!(name = STRSKIP(prop.name, "hv-")))
continue;
+ if (STREQ(prop.name, VIR_CPU_x86_HV_SPINLOCKS)) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_NUMBER) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ continue;
+ }
+
+ if ((uint32_t)prop.value.number != (uint32_t)-1)
+ hvcaps->spinlocks = prop.value.number;
+ } else if (STREQ(prop.name, VIR_CPU_x86_HV_STIMER_DIRECT)) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ } else {
+ hvcaps->stimer_direct = virTristateSwitchFromBool(prop.value.boolean);
+ }
+ continue;
+ } else if (STREQ(prop.name, VIR_CPU_x86_HV_TLBFLUSH_DIRECT)) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ } else {
+ hvcaps->tlbflush_direct = virTristateSwitchFromBool(prop.value.boolean);
+ }
+ continue;
+ } else if (STREQ(prop.name, VIR_CPU_x86_HV_TLBFLUSH_EXT)) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ } else {
+ hvcaps->tlbflush_extended = virTristateSwitchFromBool(prop.value.boolean);
+ }
+ continue;
+ } else if (STREQ(prop.name, "hv-vendor-id")) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_STRING) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ continue;
+ }
+
+ if (STRNEQ(prop.value.string, ""))
+ hvcaps->vendor_id = g_strdup(prop.value.string);
+ }
+
hvprop = virDomainHypervTypeFromString(name);
if (hvprop < 0) {
diff --git a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml
index f1a7963d34..d730151180 100644
--- a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml
@@ -1695,6 +1695,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml
index 9a7d39c1f8..5a7a574009 100644
--- a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml
@@ -1804,6 +1804,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_10.0.0.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0.x86_64.xml
index 64dc451eda..ee22265745 100644
--- a/tests/domaincapsdata/qemu_10.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_10.0.0.x86_64.xml
@@ -1695,6 +1695,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
index fedf50a52a..a3f337d95b 100644
--- a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
@@ -756,6 +756,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='yes'>
<enum name='sectype'>
diff --git a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml
index c9913316b8..9a841c114c 100644
--- a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml
@@ -1803,6 +1803,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='yes'>
<enum name='sectype'>
diff --git a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
index c1aebf16b2..b2937414d4 100644
--- a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
@@ -756,6 +756,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='yes'>
<enum name='sectype'>
diff --git a/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml
index b8c376cb14..84a200e572 100644
--- a/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml
@@ -1242,6 +1242,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>off</tlbflush_direct>
+ <tlbflush_extended>off</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml
index d3c9830a1a..92d4d85c95 100644
--- a/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml
@@ -1735,6 +1735,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>off</tlbflush_direct>
+ <tlbflush_extended>off</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.0.0.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0.x86_64.xml
index e8df30ae07..bca6510b5d 100644
--- a/tests/domaincapsdata/qemu_8.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.0.0.x86_64.xml
@@ -1242,6 +1242,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>off</tlbflush_direct>
+ <tlbflush_extended>off</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml
index e80e175376..e9455d302c 100644
--- a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml
@@ -1500,6 +1500,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml
index 62ffabb3e2..adfd3f67ac 100644
--- a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml
@@ -1756,6 +1756,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml
index 4117d926cb..a0b2e72b03 100644
--- a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml
@@ -1500,6 +1500,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml
index dfa88bcf96..b95bcb4716 100644
--- a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml
@@ -1502,6 +1502,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml
index 327cad253e..f4c775f4e6 100644
--- a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml
@@ -1723,6 +1723,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml
index f8dbb717f1..6f80d7e852 100644
--- a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml
@@ -1502,6 +1502,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml
index c5a653f57b..d01c6734be 100644
--- a/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml
@@ -1502,6 +1502,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml
index 30876c5fef..09625af704 100644
--- a/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml
@@ -1652,6 +1652,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.0.0.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0.x86_64.xml
index 6c141e1cb9..bfb75d5346 100644
--- a/tests/domaincapsdata/qemu_9.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.0.0.x86_64.xml
@@ -1502,6 +1502,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml
index 9445d999b5..e1b93389fc 100644
--- a/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml
@@ -1638,6 +1638,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml
index 61d92550c1..91479bf34f 100644
--- a/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml
@@ -1757,6 +1757,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.1.0.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0.x86_64.xml
index 5e87efe5e8..67f643bc1a 100644
--- a/tests/domaincapsdata/qemu_9.1.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.1.0.x86_64.xml
@@ -1638,6 +1638,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml
index d5db9af49e..ec3db76484 100644
--- a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml
@@ -1695,6 +1695,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml
index 7ccdc11412..b3af908680 100644
--- a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml
@@ -1804,6 +1804,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.2.0.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0.x86_64.xml
index 05a5ce4bee..39a7b6eed5 100644
--- a/tests/domaincapsdata/qemu_9.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.2.0.x86_64.xml
@@ -1695,6 +1695,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
index 432d60b02b..18977d63da 100644
--- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
@@ -4158,5 +4158,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
index 54b09813a8..09bff5f829 100644
--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
+++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
@@ -3584,5 +3584,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml
index f28b8df68e..d805b9ec9a 100644
--- a/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml
@@ -3460,5 +3460,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>off</tlbflush_direct>
+ <tlbflush_extended>off</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml
index d6fbb11064..14ce16bcc8 100644
--- a/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml
@@ -3789,5 +3789,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml
index 27ecaee290..8c7ed8c91b 100644
--- a/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml
@@ -3763,5 +3763,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml
index 452e7384c0..009025a255 100644
--- a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml
@@ -3698,5 +3698,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml
index 26883bd672..0482a6feb9 100644
--- a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml
@@ -3954,5 +3954,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml
index 1353761fab..be8718defb 100644
--- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml
@@ -3935,5 +3935,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
--
2.51.1

View File

@ -0,0 +1,92 @@
From 4f855a934bc9649b96734db69197b26d9995cede Mon Sep 17 00:00:00 2001
Message-ID: <4f855a934bc9649b96734db69197b26d9995cede.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 1 Oct 2025 15:50:39 +0200
Subject: [PATCH] qemu_capabilities: Format and parse new hyperv domcaps
members
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
After previous commit the virDomainCapsFeatureHyperv struct
gained new members. Since virQEMUCaps struct holds a pointer to
such struct we must format and parse it to/from capabilities XML.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 0141f6544cda75d47eb35b95c10878793c22c187)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_capabilities.c | 42 ++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b54bcbd527..0452600195 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4557,6 +4557,7 @@ virQEMUCapsParseHypervCapabilities(virQEMUCaps *qemuCaps,
g_autoptr(virDomainCapsFeatureHyperv) hvcaps = NULL;
xmlNodePtr n = NULL;
g_autofree xmlNodePtr *capNodes = NULL;
+ int rc;
int ncapNodes;
size_t i;
@@ -4592,6 +4593,28 @@ virQEMUCapsParseHypervCapabilities(virQEMUCaps *qemuCaps,
VIR_DOMAIN_CAPS_ENUM_SET(hvcaps->features, val);
}
+ rc = virXPathUInt("string(./hypervCapabilities/spinlocks)",
+ ctxt, &hvcaps->spinlocks);
+ if (rc == -2)
+ return -1;
+
+ rc = virXPathTristateSwitch("string(./hypervCapabilities/stimer_direct)",
+ ctxt, &hvcaps->stimer_direct);
+ if (rc == -2)
+ return -1;
+
+ rc = virXPathTristateSwitch("string(./hypervCapabilities/tlbflush_direct)",
+ ctxt, &hvcaps->tlbflush_direct);
+ if (rc == -2)
+ return -1;
+
+ rc = virXPathTristateSwitch("string(./hypervCapabilities/tlbflush_extended)",
+ ctxt, &hvcaps->tlbflush_extended);
+ if (rc == -2)
+ return -1;
+
+ hvcaps->vendor_id = virXPathString("string(./hypervCapabilities/vendor_id)", ctxt);
+
qemuCaps->hypervCapabilities = g_steal_pointer(&hvcaps);
return 0;
}
@@ -5131,6 +5154,25 @@ virQEMUCapsFormatHypervCapabilities(virQEMUCaps *qemuCaps,
virBufferAsprintf(&childBuf, "<cap name='%s'/>\n",
virDomainHypervTypeToString(i));
}
+
+ if (hvcaps->spinlocks != 0) {
+ virBufferAsprintf(&childBuf, "<spinlocks>%u</spinlocks>\n",
+ hvcaps->spinlocks);
+ }
+ if (hvcaps->stimer_direct != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&childBuf, "<stimer_direct>%s</stimer_direct>\n",
+ virTristateSwitchTypeToString(hvcaps->stimer_direct));
+ }
+ if (hvcaps->tlbflush_direct != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&childBuf, "<tlbflush_direct>%s</tlbflush_direct>\n",
+ virTristateSwitchTypeToString(hvcaps->tlbflush_direct));
+ }
+ if (hvcaps->tlbflush_extended != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&childBuf, "<tlbflush_extended>%s</tlbflush_extended>\n",
+ virTristateSwitchTypeToString(hvcaps->tlbflush_extended));
+ }
+ virBufferEscapeString(&childBuf, "<vendor_id>%s</vendor_id>\n",
+ hvcaps->vendor_id);
}
return virXMLFormatElement(buf, "hypervCapabilities", &attrBuf, &childBuf);
--
2.51.1

View File

@ -0,0 +1,56 @@
From c07935fbeaef24de98089398b800c86afb84d0c4 Mon Sep 17 00:00:00 2001
Message-ID: <c07935fbeaef24de98089398b800c86afb84d0c4.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 14:53:58 +0200
Subject: [PATCH] qemu_caps: Introduce virQEMUCapsGetHypervCapabilities()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We'll need to access hypervCapabilities memeber later on.
Introduce a getter function.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 4545827ba39b61b4c206576b8381fe455635291f)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_capabilities.c | 7 +++++++
src/qemu/qemu_capabilities.h | 3 +++
2 files changed, 10 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index edd4494fa1..7273f59175 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2691,6 +2691,13 @@ virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps)
}
+virDomainCapsFeatureHyperv *
+virQEMUCapsGetHypervCapabilities(virQEMUCaps *qemuCaps)
+{
+ return qemuCaps->hypervCapabilities;
+}
+
+
static int
virQEMUCapsProbeQMPObjectTypes(virQEMUCaps *qemuCaps,
qemuMonitor *mon)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 1334a668f0..9cce91d643 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -934,6 +934,9 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps);
virSGXCapability *
virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps);
+virDomainCapsFeatureHyperv *
+virQEMUCapsGetHypervCapabilities(virQEMUCaps *qemuCaps);
+
bool
virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_NO_INLINE;
--
2.51.1

View File

@ -0,0 +1,37 @@
From 3ccbf88062419dc604e9e98e44287fdc65c94bbc Mon Sep 17 00:00:00 2001
Message-ID: <3ccbf88062419dc604e9e98e44287fdc65c94bbc.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 14:54:17 +0200
Subject: [PATCH] qemu_caps: Prefer VIR_DOMAIN_CAPS_ENUM_IS_SET()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
While virDomainCapsEnum is in fact a bitmap, we also have a macro
to manipulate/query individual bits. Prefer it to make the code
more readable.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 727c858d6a837bd26f8cedc7e24c54dbff301e29)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_capabilities.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 4f239ae77b..28d3a78d8c 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -5126,7 +5126,7 @@ virQEMUCapsFormatHypervCapabilities(virQEMUCaps *qemuCaps,
size_t i;
for (i = 0; i < sizeof(hvcaps->features.values) * CHAR_BIT; i++) {
- if (!(hvcaps->features.values & (1U << i)))
+ if (!VIR_DOMAIN_CAPS_ENUM_IS_SET(hvcaps->features, i))
continue;
virBufferAsprintf(&childBuf, "<cap name='%s'/>\n",
--
2.51.1

View File

@ -0,0 +1,193 @@
From 156bc1d762fa4441d9bb5252670a8421e58a3338 Mon Sep 17 00:00:00 2001
Message-ID: <156bc1d762fa4441d9bb5252670a8421e58a3338.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 10:20:20 +0200
Subject: [PATCH] qemu_command: Move hyperv cmd line generation into a function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 8b316fac497dc2a121788fef9d91b22bfd4e343c)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_command.c | 155 ++++++++++++++++++++++------------------
1 file changed, 85 insertions(+), 70 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5fe39f45ff..705d5ab1a1 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6277,6 +6277,89 @@ qemuBuildCpuModelArgStr(virQEMUDriver *driver,
return 0;
}
+
+static int
+qemuBuildCpuHypervCommandLine(virBuffer *buf,
+ const virDomainDef *def)
+{
+ size_t i;
+
+ if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_HYPERV_MODE_NONE)
+ return 0;
+
+ switch ((virDomainHyperVMode) def->features[VIR_DOMAIN_FEATURE_HYPERV]) {
+ case VIR_DOMAIN_HYPERV_MODE_CUSTOM:
+ break;
+
+ case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
+ virBufferAsprintf(buf, ",hv-%s=on", "passthrough");
+ break;
+
+ case VIR_DOMAIN_HYPERV_MODE_NONE:
+ case VIR_DOMAIN_HYPERV_MODE_LAST:
+ default:
+ virReportEnumRangeError(virDomainHyperVMode,
+ def->features[VIR_DOMAIN_FEATURE_HYPERV]);
+ return -1;
+ }
+
+ for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
+ switch ((virDomainHyperv) i) {
+ case VIR_DOMAIN_HYPERV_RELAXED:
+ case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
+ case VIR_DOMAIN_HYPERV_RESET:
+ case VIR_DOMAIN_HYPERV_FREQUENCIES:
+ case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
+ case VIR_DOMAIN_HYPERV_TLBFLUSH:
+ case VIR_DOMAIN_HYPERV_IPI:
+ case VIR_DOMAIN_HYPERV_EVMCS:
+ case VIR_DOMAIN_HYPERV_AVIC:
+ case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
+ case VIR_DOMAIN_HYPERV_XMM_INPUT:
+ if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
+ const char *name = virDomainHypervTypeToString(i);
+ g_autofree char *full_name = g_strdup_printf("hv-%s", name);
+ const char *qemu_name = virQEMUCapsCPUFeatureToQEMU(def->os.arch,
+ full_name);
+ virBufferAsprintf(buf, ",%s=on", qemu_name);
+ }
+ if ((i == VIR_DOMAIN_HYPERV_STIMER) &&
+ (def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON))
+ virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_STIMER_DIRECT);
+ if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
+ if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
+ virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_DIRECT);
+ if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
+ virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_EXT);
+ }
+ break;
+
+ case VIR_DOMAIN_HYPERV_SPINLOCKS:
+ if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+ virBufferAsprintf(buf, ",%s=0x%x",
+ VIR_CPU_x86_HV_SPINLOCKS,
+ def->hyperv_spinlocks);
+ break;
+
+ case VIR_DOMAIN_HYPERV_VENDOR_ID:
+ if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+ virBufferAsprintf(buf, ",hv-vendor-id=%s",
+ def->hyperv_vendor_id);
+ break;
+
+ case VIR_DOMAIN_HYPERV_LAST:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
static int
qemuBuildCpuCommandLine(virCommand *cmd,
virQEMUDriver *driver,
@@ -6373,76 +6456,8 @@ qemuBuildCpuCommandLine(virCommand *cmd,
VIR_TRISTATE_SWITCH_ON ? "on" : "off");
}
- if (def->features[VIR_DOMAIN_FEATURE_HYPERV] != VIR_DOMAIN_HYPERV_MODE_NONE) {
- switch ((virDomainHyperVMode) def->features[VIR_DOMAIN_FEATURE_HYPERV]) {
- case VIR_DOMAIN_HYPERV_MODE_CUSTOM:
- break;
-
- case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
- virBufferAsprintf(&buf, ",hv-%s=on", "passthrough");
- break;
-
- case VIR_DOMAIN_HYPERV_MODE_NONE:
- case VIR_DOMAIN_HYPERV_MODE_LAST:
- default:
- virReportEnumRangeError(virDomainHyperVMode,
- def->features[VIR_DOMAIN_FEATURE_HYPERV]);
- return -1;
- }
-
- for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
- switch ((virDomainHyperv) i) {
- case VIR_DOMAIN_HYPERV_RELAXED:
- case VIR_DOMAIN_HYPERV_VAPIC:
- case VIR_DOMAIN_HYPERV_VPINDEX:
- case VIR_DOMAIN_HYPERV_RUNTIME:
- case VIR_DOMAIN_HYPERV_SYNIC:
- case VIR_DOMAIN_HYPERV_STIMER:
- case VIR_DOMAIN_HYPERV_RESET:
- case VIR_DOMAIN_HYPERV_FREQUENCIES:
- case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
- case VIR_DOMAIN_HYPERV_TLBFLUSH:
- case VIR_DOMAIN_HYPERV_IPI:
- case VIR_DOMAIN_HYPERV_EVMCS:
- case VIR_DOMAIN_HYPERV_AVIC:
- case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
- case VIR_DOMAIN_HYPERV_XMM_INPUT:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
- const char *name = virDomainHypervTypeToString(i);
- g_autofree char *full_name = g_strdup_printf("hv-%s", name);
- const char *qemu_name = virQEMUCapsCPUFeatureToQEMU(def->os.arch,
- full_name);
- virBufferAsprintf(&buf, ",%s=on", qemu_name);
- }
- if ((i == VIR_DOMAIN_HYPERV_STIMER) &&
- (def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON))
- virBufferAsprintf(&buf, ",%s=on", VIR_CPU_x86_HV_STIMER_DIRECT);
- if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
- virBufferAsprintf(&buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_DIRECT);
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
- virBufferAsprintf(&buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_EXT);
- }
- break;
-
- case VIR_DOMAIN_HYPERV_SPINLOCKS:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
- virBufferAsprintf(&buf, ",%s=0x%x",
- VIR_CPU_x86_HV_SPINLOCKS,
- def->hyperv_spinlocks);
- break;
-
- case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
- virBufferAsprintf(&buf, ",hv-vendor-id=%s",
- def->hyperv_vendor_id);
- break;
-
- case VIR_DOMAIN_HYPERV_LAST:
- break;
- }
- }
- }
+ if (qemuBuildCpuHypervCommandLine(&buf, def) < 0)
+ return -1;
for (i = 0; i < def->npanics; i++) {
if (def->panics[i]->model == VIR_DOMAIN_PANIC_MODEL_HYPERV) {
--
2.51.1

View File

@ -0,0 +1,37 @@
From f8b5688caf50edd2b6a07948032ec30f6b3e2b7c Mon Sep 17 00:00:00 2001
Message-ID: <f8b5688caf50edd2b6a07948032ec30f6b3e2b7c.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 13:50:18 +0200
Subject: [PATCH] qemu_command: Prefer virBufferAddLit() in
qemuBuildCpuHypervCommandLine()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Using virBufferAsprintf() just to concatenate two literal strings
is excessive. Use virBufferAddLit().
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c66bbac8d56df24674ab15202e4b5611766524d7)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_command.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 705d5ab1a1..13e23c7ee3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6292,7 +6292,7 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
break;
case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
- virBufferAsprintf(buf, ",hv-%s=on", "passthrough");
+ virBufferAddLit(buf, ",hv-passthrough=on");
break;
case VIR_DOMAIN_HYPERV_MODE_NONE:
--
2.51.1

View File

@ -0,0 +1,74 @@
From 331e4aed19e8693b41aafb2397d135ab0e8edcab Mon Sep 17 00:00:00 2001
Message-ID: <331e4aed19e8693b41aafb2397d135ab0e8edcab.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 15:27:03 +0200
Subject: [PATCH] qemu_domain: Fix qemuDomainFixupCPUs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The function was apparently created when the list of ignored CPU
features contained just cmt and related features. The list grew quite a
bit since then and this function stopped making sense as it would remove
all ignored features from CPU definitions but only if cmt was present.
The issue with cmt is long gone and this function was not really doing
anything. Surprisingly this didn't cause any real issues as we don't
update CPU definitions with features unknown to QEMU. But we may still
want to remove ignored features even though QEMU knows about them for
compatibility reasons.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 2ab6925218df7298c17f0186425624aa792a5e84)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_domain.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 5f96e34866..ba89015a55 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9430,15 +9430,20 @@ qemuDomainUpdateCPU(virDomainObj *vm,
/**
- * qemuDomainFixupCPUS:
+ * qemuDomainFixupCPUs:
* @vm: domain object
* @origCPU: original CPU used when the domain was started
*
* Libvirt older than 3.9.0 could have messed up the expansion of host-model
* CPU when reconnecting to a running domain by adding features QEMU does not
- * support (such as cmt). This API fixes both the actual CPU provided by QEMU
- * (stored in the domain object) and the @origCPU used when starting the
- * domain.
+ * support (such as cmt).
+ *
+ * Newer libvirt would not include feature unknown to QEMU, but the CPU
+ * definitions could contain features that were removed from QEMU and added to
+ * our list of ignored features as they were not actually doing anything.
+ *
+ * This API fixes both the actual CPU provided by QEMU (stored in the domain
+ * object) and the @origCPU used when starting the domain.
*
* This is safe even if the original CPU definition used mode='custom' (rather
* than host-model) since we know QEMU was able to start the domain and thus
@@ -9468,11 +9473,8 @@ qemuDomainFixupCPUs(virDomainObj *vm,
if (!origCPU)
return;
- if (virCPUDefFindFeature(vm->def->cpu, "cmt"))
- virCPUDefFilterFeatures(vm->def->cpu, virQEMUCapsCPUFilterFeatures, &arch);
-
- if (virCPUDefFindFeature(origCPU, "cmt"))
- virCPUDefFilterFeatures(origCPU, virQEMUCapsCPUFilterFeatures, &arch);
+ virCPUDefFilterFeatures(vm->def->cpu, virQEMUCapsCPUFilterFeatures, &arch);
+ virCPUDefFilterFeatures(origCPU, virQEMUCapsCPUFilterFeatures, &arch);
}
--
2.51.1

View File

@ -0,0 +1,108 @@
From 6efbe939d36af3dfe530d40723323ff13331450a Mon Sep 17 00:00:00 2001
Message-ID: <6efbe939d36af3dfe530d40723323ff13331450a.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 15:13:49 +0200
Subject: [PATCH] qemu_domain: Simplify qemuDomainFixupCPUs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since virCPUDefFilterFeatures never fails, we can use it for in-place
modifications instead of modifying a temporary virCPUDef copy.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit fbf44bc8cf63ab5c7641f1aa04aaf7fb5eaab62e)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_domain.c | 26 ++++++--------------------
src/qemu/qemu_domain.h | 2 +-
src/qemu/qemu_process.c | 4 ++--
3 files changed, 9 insertions(+), 23 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 21a4169c58..5f96e34866 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9449,7 +9449,7 @@ qemuDomainUpdateCPU(virDomainObj *vm,
*/
void
qemuDomainFixupCPUs(virDomainObj *vm,
- virCPUDef **origCPU)
+ virCPUDef *origCPU)
{
virArch arch = vm->def->os.arch;
@@ -9465,28 +9465,14 @@ qemuDomainFixupCPUs(virDomainObj *vm,
* we asked for or libvirt was too old to mess up the translation from
* host-model.
*/
- if (!*origCPU)
+ if (!origCPU)
return;
- if (virCPUDefFindFeature(vm->def->cpu, "cmt")) {
- g_autoptr(virCPUDef) fixedCPU = virCPUDefCopyWithoutModel(vm->def->cpu);
+ if (virCPUDefFindFeature(vm->def->cpu, "cmt"))
+ virCPUDefFilterFeatures(vm->def->cpu, virQEMUCapsCPUFilterFeatures, &arch);
- virCPUDefCopyModelFilter(fixedCPU, vm->def->cpu, false,
- virQEMUCapsCPUFilterFeatures, &arch);
-
- virCPUDefFree(vm->def->cpu);
- vm->def->cpu = g_steal_pointer(&fixedCPU);
- }
-
- if (virCPUDefFindFeature(*origCPU, "cmt")) {
- g_autoptr(virCPUDef) fixedOrig = virCPUDefCopyWithoutModel(*origCPU);
-
- virCPUDefCopyModelFilter(fixedOrig, *origCPU, false,
- virQEMUCapsCPUFilterFeatures, &arch);
-
- virCPUDefFree(*origCPU);
- *origCPU = g_steal_pointer(&fixedOrig);
- }
+ if (virCPUDefFindFeature(origCPU, "cmt"))
+ virCPUDefFilterFeatures(origCPU, virQEMUCapsCPUFilterFeatures, &arch);
}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index d787d2a065..41daea01d7 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1002,7 +1002,7 @@ qemuDomainUpdateCPU(virDomainObj *vm,
void
qemuDomainFixupCPUs(virDomainObj *vm,
- virCPUDef **origCPU);
+ virCPUDef *origCPU);
char *
qemuDomainGetMachineName(virDomainObj *vm);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f5f9d4a348..7c16390e8f 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8640,7 +8640,7 @@ qemuProcessStartWithMemoryState(virConnectPtr conn,
* the CPU definitions.
*/
if (cookie)
- qemuDomainFixupCPUs(vm, &cookie->cpu);
+ qemuDomainFixupCPUs(vm, cookie->cpu);
if (cookie && !cookie->slirpHelper)
priv->disableSlirp = true;
@@ -9453,7 +9453,7 @@ qemuProcessRefreshCPU(virQEMUDriver *driver,
* case the host-model is known to not contain features which QEMU
* doesn't know about.
*/
- qemuDomainFixupCPUs(vm, &priv->origCPU);
+ qemuDomainFixupCPUs(vm, priv->origCPU);
}
return 0;
--
2.51.1

View File

@ -0,0 +1,122 @@
From 53970ee6e429594f696f6e8056a7f5240c825974 Mon Sep 17 00:00:00 2001
Message-ID: <53970ee6e429594f696f6e8056a7f5240c825974.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:15 -0400
Subject: [PATCH] qemu_firmware: Pick the right firmware for TDX guests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The firmware descriptors have 'intel-tdx' feature which
describes whether firmware is suitable for TDX guests.
Provide necessary implementation to detect the feature and pick
the right firmware if guest is TDX enabled.
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
(cherry picked from commit 2dec0d9ede0546f5db9d36c2baddb9d94c83a435)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/qemu/qemu_firmware.c | 21 ++++++++++++++++++-
.../firmware/60-edk2-ovmf-x64-inteltdx.json | 1 +
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index 6c65a2751b..f10137144e 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -149,6 +149,7 @@ typedef enum {
QEMU_FIRMWARE_FEATURE_AMD_SEV,
QEMU_FIRMWARE_FEATURE_AMD_SEV_ES,
QEMU_FIRMWARE_FEATURE_AMD_SEV_SNP,
+ QEMU_FIRMWARE_FEATURE_INTEL_TDX,
QEMU_FIRMWARE_FEATURE_ENROLLED_KEYS,
QEMU_FIRMWARE_FEATURE_REQUIRES_SMM,
QEMU_FIRMWARE_FEATURE_SECURE_BOOT,
@@ -167,6 +168,7 @@ VIR_ENUM_IMPL(qemuFirmwareFeature,
"amd-sev",
"amd-sev-es",
"amd-sev-snp",
+ "intel-tdx",
"enrolled-keys",
"requires-smm",
"secure-boot",
@@ -1158,6 +1160,7 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
bool supportsSEV = false;
bool supportsSEVES = false;
bool supportsSEVSNP = false;
+ bool supportsTDX = false;
bool supportsSecureBoot = false;
bool hasEnrolledKeys = false;
int reqSecureBoot;
@@ -1209,6 +1212,10 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
supportsSEVSNP = true;
break;
+ case QEMU_FIRMWARE_FEATURE_INTEL_TDX:
+ supportsTDX = true;
+ break;
+
case QEMU_FIRMWARE_FEATURE_REQUIRES_SMM:
requiresSMM = true;
break;
@@ -1370,9 +1377,18 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
return false;
}
break;
- case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+
case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ if (!supportsTDX) {
+ VIR_DEBUG("Domain requires TDX, firmware '%s' doesn't support it",
+ path);
+ return false;
+ }
break;
+
+ case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ break;
+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, def->sec->sectype);
@@ -1490,6 +1506,7 @@ qemuFirmwareEnableFeaturesModern(virDomainDef *def,
case QEMU_FIRMWARE_FEATURE_AMD_SEV:
case QEMU_FIRMWARE_FEATURE_AMD_SEV_ES:
case QEMU_FIRMWARE_FEATURE_AMD_SEV_SNP:
+ case QEMU_FIRMWARE_FEATURE_INTEL_TDX:
case QEMU_FIRMWARE_FEATURE_VERBOSE_DYNAMIC:
case QEMU_FIRMWARE_FEATURE_VERBOSE_STATIC:
case QEMU_FIRMWARE_FEATURE_NONE:
@@ -1541,6 +1558,7 @@ qemuFirmwareSanityCheck(const qemuFirmware *fw,
case QEMU_FIRMWARE_FEATURE_AMD_SEV:
case QEMU_FIRMWARE_FEATURE_AMD_SEV_ES:
case QEMU_FIRMWARE_FEATURE_AMD_SEV_SNP:
+ case QEMU_FIRMWARE_FEATURE_INTEL_TDX:
case QEMU_FIRMWARE_FEATURE_VERBOSE_DYNAMIC:
case QEMU_FIRMWARE_FEATURE_VERBOSE_STATIC:
case QEMU_FIRMWARE_FEATURE_LAST:
@@ -1981,6 +1999,7 @@ qemuFirmwareGetSupported(const char *machine,
case QEMU_FIRMWARE_FEATURE_AMD_SEV:
case QEMU_FIRMWARE_FEATURE_AMD_SEV_ES:
case QEMU_FIRMWARE_FEATURE_AMD_SEV_SNP:
+ case QEMU_FIRMWARE_FEATURE_INTEL_TDX:
case QEMU_FIRMWARE_FEATURE_ENROLLED_KEYS:
case QEMU_FIRMWARE_FEATURE_SECURE_BOOT:
case QEMU_FIRMWARE_FEATURE_VERBOSE_DYNAMIC:
diff --git a/tests/qemufirmwaredata/out/usr/share/qemu/firmware/60-edk2-ovmf-x64-inteltdx.json b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/60-edk2-ovmf-x64-inteltdx.json
index d002ec7386..2630b57b05 100644
--- a/tests/qemufirmwaredata/out/usr/share/qemu/firmware/60-edk2-ovmf-x64-inteltdx.json
+++ b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/60-edk2-ovmf-x64-inteltdx.json
@@ -16,6 +16,7 @@
],
"features": [
"enrolled-keys",
+ "intel-tdx",
"secure-boot",
"verbose-dynamic"
]
--
2.51.0

View File

@ -0,0 +1,182 @@
From fd576f22b2c25d086b73f6e3798d81f03bbc609d Mon Sep 17 00:00:00 2001
Message-ID: <fd576f22b2c25d086b73f6e3798d81f03bbc609d.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 17:16:32 +0200
Subject: [PATCH] qemu_monitor: Filter CPU features reported by QEMU
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some features may be on our ignore list because they do nothing even
though QEMU still supports them and reports their state. But as the
features do nothing, the state reported by QEMU may not correspond to
what the guest sees. To avoid possible confusion we may just pretend
QEMU did not report any of the features on our ignore list.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 4d5c1bc24119e90dfbcdae6a120027e5c1ede608)
https://issues.redhat.com/browse/RHEL-126096
Conflicts:
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_process.c
tests/qemumonitorjsontest.c
- the qom-list-get series optimizing CPU feature probing was
not backported
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_monitor.c | 6 ++++--
src/qemu/qemu_monitor.h | 1 +
src/qemu/qemu_monitor_json.c | 18 +++++++++++++++---
src/qemu/qemu_monitor_json.h | 1 +
src/qemu/qemu_process.c | 1 +
5 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index a9fe4f2f6b..ecf54a5dda 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3735,7 +3735,8 @@ qemuMonitorGetGuestCPUx86(qemuMonitor *mon,
* @arch: CPU architecture
* @cpuQOMPath: QOM path of a CPU to probe
* @translate: callback for translating CPU feature names from QEMU to libvirt
- * @opaque: data for @translate callback
+ * @filter: callback for filtering ignored features, a pointer to @arch is
+ * passed as opaque pointer to the callback
* @enabled: returns the CPU data for all enabled features
* @disabled: returns the CPU data for features which we asked for
* (either explicitly or via a named CPU model) but QEMU disabled them
@@ -3749,6 +3750,7 @@ qemuMonitorGetGuestCPU(qemuMonitor *mon,
virArch arch,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData **enabled,
virCPUData **disabled)
{
@@ -3762,7 +3764,7 @@ qemuMonitorGetGuestCPU(qemuMonitor *mon,
*disabled = NULL;
return qemuMonitorJSONGetGuestCPU(mon, arch, cpuQOMPath, translate,
- enabled, disabled);
+ filter, enabled, disabled);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d4730162ca..12e5388e0b 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1273,6 +1273,7 @@ int qemuMonitorGetGuestCPU(qemuMonitor *mon,
virArch arch,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData **enabled,
virCPUData **disabled);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index cbe10ad907..cedf761018 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6769,6 +6769,7 @@ static int
qemuMonitorJSONGetCPUData(qemuMonitor *mon,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData *data)
{
qemuMonitorJSONObjectProperty prop = { .type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN };
@@ -6790,6 +6791,9 @@ qemuMonitorJSONGetCPUData(qemuMonitor *mon,
if (translate)
name = translate(data->arch, name);
+ if (filter && !filter(name, VIR_CPU_FEATURE_REQUIRE, &data->arch))
+ continue;
+
if (virCPUDataAddFeature(data, name) < 0)
return -1;
}
@@ -6802,6 +6806,7 @@ static int
qemuMonitorJSONGetCPUDataDisabled(qemuMonitor *mon,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData *data)
{
g_auto(GStrv) props = NULL;
@@ -6817,6 +6822,9 @@ qemuMonitorJSONGetCPUDataDisabled(qemuMonitor *mon,
if (translate)
name = translate(data->arch, name);
+ if (filter && !filter(name, VIR_CPU_FEATURE_REQUIRE, &data->arch))
+ continue;
+
if (virCPUDataAddFeature(data, name) < 0)
return -1;
}
@@ -6831,7 +6839,8 @@ qemuMonitorJSONGetCPUDataDisabled(qemuMonitor *mon,
* @arch: CPU architecture
* @cpuQOMPath: QOM path of a CPU to probe
* @translate: callback for translating CPU feature names from QEMU to libvirt
- * @opaque: data for @translate callback
+ * @filter: callback for filtering ignored features, a pointer to @arch is
+ * passed as opaque pointer to the callback
* @enabled: returns the CPU data for all enabled features
* @disabled: returns the CPU data for features which we asked for
* (either explicitly or via a named CPU model) but QEMU disabled them
@@ -6845,6 +6854,7 @@ qemuMonitorJSONGetGuestCPU(qemuMonitor *mon,
virArch arch,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData **enabled,
virCPUData **disabled)
{
@@ -6855,11 +6865,13 @@ qemuMonitorJSONGetGuestCPU(qemuMonitor *mon,
!(cpuDisabled = virCPUDataNew(arch)))
return -1;
- if (qemuMonitorJSONGetCPUData(mon, cpuQOMPath, translate, cpuEnabled) < 0)
+ if (qemuMonitorJSONGetCPUData(mon, cpuQOMPath, translate, filter,
+ cpuEnabled) < 0)
return -1;
if (disabled &&
- qemuMonitorJSONGetCPUDataDisabled(mon, cpuQOMPath, translate, cpuDisabled) < 0)
+ qemuMonitorJSONGetCPUDataDisabled(mon, cpuQOMPath, translate, filter,
+ cpuDisabled) < 0)
return -1;
*enabled = g_steal_pointer(&cpuEnabled);
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 68f60aec61..fb1a3cef44 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -576,6 +576,7 @@ qemuMonitorJSONGetGuestCPU(qemuMonitor *mon,
virArch arch,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData **enabled,
virCPUData **disabled);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 561c04f879..f24f5c8b92 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4561,6 +4561,7 @@ qemuProcessFetchGuestCPU(virDomainObj *vm,
vm->def->os.arch,
cpuQOMPath,
virQEMUCapsCPUFeatureFromQEMU,
+ virQEMUCapsCPUFilterFeatures,
&dataEnabled, &dataDisabled);
} else {
rc = qemuMonitorGetGuestCPUx86(priv->mon, cpuQOMPath, &dataEnabled, &dataDisabled);
--
2.51.1

View File

@ -0,0 +1,46 @@
From 132d30089ba007c53098f4b381dfd38db07ad1a0 Mon Sep 17 00:00:00 2001
Message-ID: <132d30089ba007c53098f4b381dfd38db07ad1a0.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 15:36:18 +0200
Subject: [PATCH] qemu_process: Always fix CPUs on reconnect
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We fix CPUs (i.e., remove ignored CPU features) only when libvirt/QEMU
combo used to start the domain is very old and doesn't support
query-cpu-model-expansion, in which case the CPU definition may contain
features that are unknown to QEMU. But even if both libvirt and QEMU are
new enough, we still want to remove features that do nothing to minimize
confusion or to avoid false migration issues.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c15ae99dab903004b82f8447f44df09973696f72)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_process.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7c16390e8f..561c04f879 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -9447,12 +9447,7 @@ qemuProcessRefreshCPU(virQEMUDriver *driver,
if (qemuProcessUpdateCPU(vm, VIR_ASYNC_JOB_NONE) < 0)
return -1;
- } else if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) {
- /* We only try to fix CPUs when the libvirt/QEMU combo used to start
- * the domain did not know about query-cpu-model-expansion in which
- * case the host-model is known to not contain features which QEMU
- * doesn't know about.
- */
+ } else {
qemuDomainFixupCPUs(vm, priv->origCPU);
}
--
2.51.1

View File

@ -0,0 +1,150 @@
From edf171344cf52ab53e1bf5672badf5d621d3aa79 Mon Sep 17 00:00:00 2001
Message-ID: <edf171344cf52ab53e1bf5672badf5d621d3aa79.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 14:54:23 +0200
Subject: [PATCH] qemu_process: Populate hyperv features for host-model
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Pretty straightforward. The only "weird" thing here is that
'hv-time' enlightenment is exposed as a <timer/> under <clock/>
element. Since it's required by 'hv-stimer' and
'hv-stimer-direct' it needs to be enabled too.
Resolves: https://issues.redhat.com/browse/RHEL-114003
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 8458bb521ea4bb7b50d8d5f6ffea4e2d2fe8f0f5)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_process.c | 72 +++++++++++++++++++
.../hyperv-host-model.x86_64-latest.args | 2 +-
3 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 61aeb14757..a9e1f7a8f8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6289,13 +6289,13 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
switch ((virDomainHyperVMode) def->features[VIR_DOMAIN_FEATURE_HYPERV]) {
case VIR_DOMAIN_HYPERV_MODE_CUSTOM:
- case VIR_DOMAIN_HYPERV_MODE_HOST_MODEL:
break;
case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
virBufferAddLit(buf, ",hv-passthrough=on");
break;
+ case VIR_DOMAIN_HYPERV_MODE_HOST_MODEL:
case VIR_DOMAIN_HYPERV_MODE_NONE:
case VIR_DOMAIN_HYPERV_MODE_LAST:
default:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 798dabaf0a..e2e2822013 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6795,6 +6795,75 @@ qemuProcessPrepareChardevSource(virDomainDef *def,
}
+static void
+qemuProcessMaybeAddHypervTimer(virDomainDef *def)
+{
+ g_autofree virDomainTimerDef *timer = NULL;
+
+ if (virDomainDefHasTimer(def, VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK))
+ return;
+
+ timer = g_new0(virDomainTimerDef, 1);
+ timer->name = VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK;
+ timer->present = VIR_TRISTATE_BOOL_YES;
+
+ VIR_APPEND_ELEMENT(def->clock.timers, def->clock.ntimers, timer);
+}
+
+
+static int
+qemuProcessEnableDomainFeatures(virDomainObj *vm)
+{
+ virDomainCapsFeatureHyperv *hv = NULL;
+ qemuDomainObjPrivate *priv = vm->privateData;
+ size_t i;
+
+ if (vm->def->features[VIR_DOMAIN_FEATURE_HYPERV] != VIR_DOMAIN_HYPERV_MODE_HOST_MODEL)
+ return 0;
+
+ hv = virQEMUCapsGetHypervCapabilities(priv->qemuCaps);
+ if (!hv || hv->supported != VIR_TRISTATE_BOOL_YES) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("host-model hyperv mode unsupported, no hyperv capabilities found"));
+ return -1;
+ }
+
+ for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
+ if (!VIR_DOMAIN_CAPS_ENUM_IS_SET(hv->features, i))
+ continue;
+
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
+
+ if (i == VIR_DOMAIN_HYPERV_SPINLOCKS) {
+ if (hv->spinlocks != 0) {
+ vm->def->hyperv.spinlocks = hv->spinlocks;
+ } else {
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ABSENT;
+ }
+ } else if (i == VIR_DOMAIN_HYPERV_STIMER) {
+ vm->def->hyperv.stimer_direct = hv->stimer_direct;
+ /* Both hv-stimer and hv-stimer-direct require hv-time which is
+ * expose as a timer. Enable it. */
+ qemuProcessMaybeAddHypervTimer(vm->def);
+ } else if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
+ vm->def->hyperv.tlbflush_direct = hv->tlbflush_direct;
+ vm->def->hyperv.tlbflush_extended = hv->tlbflush_extended;
+ } else if (i == VIR_DOMAIN_HYPERV_VENDOR_ID) {
+ if (hv->vendor_id) {
+ vm->def->hyperv.vendor_id = g_strdup(hv->vendor_id);
+ } else {
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ABSENT;
+ }
+ }
+ }
+
+ vm->def->features[VIR_DOMAIN_FEATURE_HYPERV] = VIR_DOMAIN_HYPERV_MODE_CUSTOM;
+
+ return 0;
+}
+
+
+
/**
* qemuProcessPrepareDomain:
* @driver: qemu driver
@@ -6908,6 +6977,9 @@ qemuProcessPrepareDomain(virQEMUDriver *driver,
VIR_DEBUG("Aligning guest memory");
if (qemuDomainAlignMemorySizes(vm->def) < 0)
return -1;
+
+ if (qemuProcessEnableDomainFeatures(vm) < 0)
+ return -1;
}
for (i = 0; i < vm->def->nchannels; i++) {
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
index 2ed72fcd1b..58502ff51e 100644
--- a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
-accel tcg \
--cpu qemu64 \
+-cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0xfff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on,hv-reset=on,hv-vendor-id=Linux KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-avic=on,hv-emsr-bitmap=on,hv-xmm-input=on' \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
--
2.51.1

View File

@ -0,0 +1,42 @@
From 552bba4e9631fd324b061d2405d0ae3a49f116e3 Mon Sep 17 00:00:00 2001
Message-ID: <552bba4e9631fd324b061d2405d0ae3a49f116e3.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 10:51:53 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-evmcs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-evmcs``
The enlightenment is nested specific, it targets Hyper-V on KVM guests. <snip/>
Requires: ``hv-vapic``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c6114de13c473bfd131fd64863ad9ccd18238ae5)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 8e8c9c5c1d..3d07c23ea5 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -131,6 +131,8 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_IPI, VIR_DOMAIN_HYPERV_VPINDEX);
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_EVMCS, VIR_DOMAIN_HYPERV_VAPIC);
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,42 @@
From 26f42f59d3ab109e2f9390b18339fe5a9c62a1b5 Mon Sep 17 00:00:00 2001
Message-ID: <26f42f59d3ab109e2f9390b18339fe5a9c62a1b5.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 10:50:32 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-ipi
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-ipi``
Enables paravirtualized IPI send mechanism. <snip/>
Requires: ``hv-vpindex``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit f4557315f32747d45cf2da78af6e009f513892f4)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 33fec89134..8e8c9c5c1d 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -129,6 +129,8 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_TLBFLUSH, VIR_DOMAIN_HYPERV_VPINDEX);
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_IPI, VIR_DOMAIN_HYPERV_VPINDEX);
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,53 @@
From edef2af6d026dd6293f9acec5581851554825ed4 Mon Sep 17 00:00:00 2001
Message-ID: <edef2af6d026dd6293f9acec5581851554825ed4.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 7 Oct 2025 13:42:19 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-stimer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-stimer``
Enables Hyper-V synthetic timers. <snip/>
Requires: ``hv-vpindex``, ``hv-synic``, ``hv-time``
Reflect these dependencies when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit da261327ea94300d1aa2d3b76ba9dcd4de6160f6)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index f7543cbc14..4cbbc59f2c 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -114,6 +114,19 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_SYNIC, VIR_DOMAIN_HYPERV_VPINDEX);
+ if (def->hyperv_features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+ if (!virDomainDefHasTimer(def, VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("'%1$s' hyperv feature requires '%2$s' timer"),
+ virDomainHypervTypeToString(VIR_DOMAIN_HYPERV_STIMER),
+ virDomainTimerNameTypeToString(VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK));
+ return -1;
+ }
+ }
+
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_STIMER, VIR_DOMAIN_HYPERV_VPINDEX);
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_STIMER, VIR_DOMAIN_HYPERV_SYNIC);
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,89 @@
From a8ad71a626a29d6c8b855d32132a5a5f1cfee941 Mon Sep 17 00:00:00 2001
Message-ID: <a8ad71a626a29d6c8b855d32132a5a5f1cfee941.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 09:56:50 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-synic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-synic``
Enables Hyper-V Synthetic interrupt controller <snip/>
Requires: ``hv-vpindex``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 1822d030c32d9857020ee8385b0a8808a29a472f)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 42 ++++++++++++++++++++++++++++++++--------
1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 6c711444eb..f7543cbc14 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -88,6 +88,38 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
}
+#define CHECK_HV_FEAT(feat, requires) \
+ if (def->hyperv_features[feat] == VIR_TRISTATE_SWITCH_ON && \
+ def->hyperv_features[requires] != VIR_TRISTATE_SWITCH_ON) { \
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
+ _("'%1$s' hyperv feature requires '%2$s' feature"), \
+ virDomainHypervTypeToString(feat), \
+ virDomainHypervTypeToString(requires)); \
+ return -1; \
+ }
+
+static int
+qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
+{
+ if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_HYPERV_MODE_NONE)
+ return 0;
+
+ if (!ARCH_IS_X86(def->os.arch) && !qemuDomainIsARMVirt(def)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Hyperv features are not supported for architecture '%1$s' or machine type '%2$s'"),
+ virArchToString(def->os.arch),
+ def->os.machine);
+ return -1;
+ }
+
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_SYNIC, VIR_DOMAIN_HYPERV_VPINDEX);
+
+ return 0;
+}
+
+#undef CHECK_HV_FEAT
+
+
static int
qemuValidateDomainDefFeatures(const virDomainDef *def,
virQEMUCaps *qemuCaps)
@@ -187,14 +219,8 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
break;
case VIR_DOMAIN_FEATURE_HYPERV:
- if (def->features[i] != VIR_DOMAIN_HYPERV_MODE_NONE &&
- !ARCH_IS_X86(def->os.arch) && !qemuDomainIsARMVirt(def)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Hyperv features are not supported for architecture '%1$s' or machine type '%2$s'"),
- virArchToString(def->os.arch),
- def->os.machine);
- return -1;
- }
+ if (qemuValidateDomainDefHypervFeatures(def) < 0)
+ return -1;
break;
case VIR_DOMAIN_FEATURE_PMU:
--
2.51.1

View File

@ -0,0 +1,51 @@
From 2e6abea3a9ab2e6c32279d9513bab291d4095d94 Mon Sep 17 00:00:00 2001
Message-ID: <2e6abea3a9ab2e6c32279d9513bab291d4095d94.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 12:24:12 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-tlbflush-direct
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-tlbflush-direct``
The enlightenment is nested specific, it targets Hyper-V on KVM guests. <snip/>
Requires: ``hv-vapic``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 1d2873f9c6f8de24b47183249cc137861413ea56)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 3d07c23ea5..22565d9e36 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -133,6 +133,17 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_EVMCS, VIR_DOMAIN_HYPERV_VAPIC);
+ if (def->hyperv_features[VIR_DOMAIN_HYPERV_TLBFLUSH] == VIR_TRISTATE_SWITCH_ON &&
+ def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv_features[VIR_DOMAIN_HYPERV_VAPIC] != VIR_TRISTATE_SWITCH_ON) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("'%1$s' hyperv feature requires '%2$s' feature"),
+ VIR_CPU_x86_HV_TLBFLUSH_DIRECT,
+ virDomainHypervTypeToString(VIR_DOMAIN_HYPERV_VAPIC));
+ return -1;
+ }
+ }
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,42 @@
From 95ac8bf578f14bb95d80eb663c4683897d909dcd Mon Sep 17 00:00:00 2001
Message-ID: <95ac8bf578f14bb95d80eb663c4683897d909dcd.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 10:48:07 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-tlbflush
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-tlbflush``
Enables paravirtualized TLB shoot-down mechanism. <snip/>
Requires: ``hv-vpindex``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 941af83360d1aa57d8dec1b0af85d8cde18c7c04)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 4cbbc59f2c..33fec89134 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -127,6 +127,8 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_STIMER, VIR_DOMAIN_HYPERV_VPINDEX);
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_STIMER, VIR_DOMAIN_HYPERV_SYNIC);
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_TLBFLUSH, VIR_DOMAIN_HYPERV_VPINDEX);
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,36 @@
From 14406d5398bab0cde8e340964e13f992a179d4ac Mon Sep 17 00:00:00 2001
Message-ID: <14406d5398bab0cde8e340964e13f992a179d4ac.1759835599.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:05 -0400
Subject: [PATCH] qemucapabilitiesdata: Document '+inteltdx' variant
Upcoming patch will introduce test data from an TDX-enabled host.
Document the new variant.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 4c59ff7783d1672b872cc4190df3e89ae8d4130a)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
tests/qemucapabilitiesdata/README.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/qemucapabilitiesdata/README.rst b/tests/qemucapabilitiesdata/README.rst
index f65f07cfca..f87bbda52b 100644
--- a/tests/qemucapabilitiesdata/README.rst
+++ b/tests/qemucapabilitiesdata/README.rst
@@ -58,6 +58,11 @@ Known test variants
for qemu.
+``+inteltdx``
+
+ Variant of the test data captured on hosts supporting INTEL TDX security
+ framework.
+
Usage in tests
==============
--
2.51.0

View File

@ -0,0 +1,114 @@
From ee8d4bd99dcfbd853d066cda904b989a0c8156c7 Mon Sep 17 00:00:00 2001
Message-ID: <ee8d4bd99dcfbd853d066cda904b989a0c8156c7.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 7 Oct 2025 11:54:21 +0200
Subject: [PATCH] qemuxmlconfdata: Adjust hv-stimer related tests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In QEMU, hv-stimer and hv-stimer-direct require hv-time. Reflect
this fact in our tests.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit da76c1e8fe40ee2bb0b6f0176fd14908e6a21fb6)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml | 4 +++-
tests/qemuxmlconfdata/hyperv-stimer-direct.xml | 4 +++-
tests/qemuxmlconfdata/hyperv.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/hyperv.x86_64-latest.xml | 4 +++-
tests/qemuxmlconfdata/hyperv.xml | 4 +++-
6 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args
index b665e5365d..0a6d84fbd2 100644
--- a/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
-accel tcg \
--cpu qemu64,hv-vpindex=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on \
+-cpu qemu64,hv-time=on,hv-vpindex=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml
index efb9d0072e..5f6223bf3e 100644
--- a/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml
@@ -21,7 +21,9 @@
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
</cpu>
- <clock offset='utc'/>
+ <clock offset='utc'>
+ <timer name='hypervclock' present='yes'/>
+ </clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
diff --git a/tests/qemuxmlconfdata/hyperv-stimer-direct.xml b/tests/qemuxmlconfdata/hyperv-stimer-direct.xml
index 21163b41ad..4116b7a450 100644
--- a/tests/qemuxmlconfdata/hyperv-stimer-direct.xml
+++ b/tests/qemuxmlconfdata/hyperv-stimer-direct.xml
@@ -18,7 +18,9 @@
</stimer>
</hyperv>
</features>
- <clock offset='utc'/>
+ <clock offset='utc'>
+ <timer name='hypervclock' present='yes'/>
+ </clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
diff --git a/tests/qemuxmlconfdata/hyperv.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv.x86_64-latest.args
index 5a32b80e71..30d63bae6b 100644
--- a/tests/qemuxmlconfdata/hyperv.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hyperv.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
-accel tcg \
--cpu 'qemu64,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x2fff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-reset=on,hv-vendor-id=KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-evmcs=on,hv-avic=on,hv-emsr-bitmap=on,hv-xmm-input=on' \
+-cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x2fff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-reset=on,hv-vendor-id=KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-evmcs=on,hv-avic=on,hv-emsr-bitmap=on,hv-xmm-input=on' \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml
index 49537188af..ee412164ed 100644
--- a/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml
@@ -36,7 +36,9 @@
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
</cpu>
- <clock offset='utc'/>
+ <clock offset='utc'>
+ <timer name='hypervclock' present='yes'/>
+ </clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
diff --git a/tests/qemuxmlconfdata/hyperv.xml b/tests/qemuxmlconfdata/hyperv.xml
index 8c323f6578..44aec004a8 100644
--- a/tests/qemuxmlconfdata/hyperv.xml
+++ b/tests/qemuxmlconfdata/hyperv.xml
@@ -33,7 +33,9 @@
<xmm_input state='on'/>
</hyperv>
</features>
- <clock offset='utc'/>
+ <clock offset='utc'>
+ <timer name='hypervclock' present='yes'/>
+ </clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
--
2.51.1

View File

@ -0,0 +1,211 @@
From c8561a94d58c4b90ab67f49cc963e6b431972aee Mon Sep 17 00:00:00 2001
Message-ID: <c8561a94d58c4b90ab67f49cc963e6b431972aee.1759835600.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:24 -0400
Subject: [PATCH] qemuxmlconftest: Add latest version of 'launch-security-tdx*'
test data
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We now have the '+inteltdx' variant dumped from a modern qemu with tdx support,
add qemuxmlconftest data for that variant.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
(cherry picked from commit 798f748210ff7a43702adadd6037220b713d998e)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
RHEL: rename the files to not include +inteltdx
---
.../launch-security-tdx.x86_64-latest.args | 44 +++++++++++
.../launch-security-tdx.x86_64-latest.xml | 75 +++++++++++++++++++
tests/qemuxmlconfdata/launch-security-tdx.xml | 28 +++++++
tests/qemuxmlconftest.c | 3 +
4 files changed, 150 insertions(+)
create mode 100644 tests/qemuxmlconfdata/launch-security-tdx.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/launch-security-tdx.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/launch-security-tdx.xml
diff --git a/tests/qemuxmlconfdata/launch-security-tdx.x86_64-latest.args b/tests/qemuxmlconfdata/launch-security-tdx.x86_64-latest.args
new file mode 100644
index 0000000000..366d553c93
--- /dev/null
+++ b/tests/qemuxmlconfdata/launch-security-tdx.x86_64-latest.args
@@ -0,0 +1,44 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-guest \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=guest,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \
+-machine q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,confidential-guest-support=lsec0,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=4194304k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":4294967296}' \
+-overcommit mem-lock=off \
+-smp 4,sockets=4,cores=1,threads=1 \
+-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"}' \
+-device '{"driver":"pcie-pci-bridge","id":"pci.2","bus":"pci.1","addr":"0x0"}' \
+-device '{"driver":"pcie-root-port","port":17,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x2.0x1"}' \
+-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.2","addr":"0x2"}' \
+-device '{"driver":"lsi","id":"scsi0","bus":"pci.2","addr":"0x3"}' \
+-netdev '{"type":"user","id":"hostnet0"}' \
+-device '{"driver":"rtl8139","netdev":"hostnet0","id":"net0","mac":"52:54:00:09:a4:37","bus":"pci.2","addr":"0x1"}' \
+-chardev pty,id=charserial0 \
+-device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"cirrus-vga","id":"video0","bus":"pcie.0","addr":"0x1"}' \
+-global ICH9-LPC.noreboot=off \
+-watchdog-action reset \
+-object '{"qom-type":"tdx-guest","id":"lsec0","mrconfigid":"ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v","mrowner":"ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v","mrownerconfig":"ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v","quote-generation-socket":{"type":"unix","path":"/var/run/tdx-qgs/qgs.socket"},"attributes":268435456}' \
+-device '{"driver":"pvpanic"}' \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/launch-security-tdx.x86_64-latest.xml b/tests/qemuxmlconfdata/launch-security-tdx.x86_64-latest.xml
new file mode 100644
index 0000000000..757fbdabbb
--- /dev/null
+++ b/tests/qemuxmlconfdata/launch-security-tdx.x86_64-latest.xml
@@ -0,0 +1,75 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid>
+ <memory unit='KiB'>4194304</memory>
+ <currentMemory unit='KiB'>4194304</currentMemory>
+ <vcpu placement='static'>4</vcpu>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <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>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x0'/>
+ </controller>
+ <controller type='scsi' index='0' model='lsilogic'>
+ <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0'/>
+ </controller>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='1' port='0x10'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-to-pci-bridge'>
+ <model name='pcie-pci-bridge'/>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='pci' index='3' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='3' port='0x11'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
+ </controller>
+ <interface type='user'>
+ <mac address='52:54:00:09:a4:37'/>
+ <model type='rtl8139'/>
+ <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
+ </interface>
+ <serial type='pty'>
+ <target type='isa-serial' port='0'>
+ <model name='isa-serial'/>
+ </target>
+ </serial>
+ <console type='pty'>
+ <target type='serial' port='0'/>
+ </console>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='cirrus' vram='16384' heads='1' primary='yes'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+ </video>
+ <watchdog model='itco' action='reset'/>
+ <memballoon model='none'/>
+ <panic model='isa'/>
+ </devices>
+ <launchSecurity type='tdx'>
+ <policy>0x10000000</policy>
+ <mrConfigId>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrConfigId>
+ <mrOwner>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrOwner>
+ <mrOwnerConfig>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrOwnerConfig>
+ <quoteGenerationService path='/var/run/tdx-qgs/qgs.socket'/>
+ </launchSecurity>
+</domain>
diff --git a/tests/qemuxmlconfdata/launch-security-tdx.xml b/tests/qemuxmlconfdata/launch-security-tdx.xml
new file mode 100644
index 0000000000..07e3ae6db8
--- /dev/null
+++ b/tests/qemuxmlconfdata/launch-security-tdx.xml
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid>
+ <memory>4194304</memory>
+ <vcpu>4</vcpu>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='usb'/>
+ <controller type='scsi'/>
+ <interface type='user'>
+ <mac address='52:54:00:09:a4:37'/>
+ </interface>
+ <serial type='pty'/>
+ <video/>
+ <memballoon model='none'/>
+ <panic/>
+ </devices>
+ <launchSecurity type='tdx'>
+ <policy>0x10000000</policy>
+ <mrConfigId>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrConfigId>
+ <mrOwner>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrOwner>
+ <mrOwnerConfig>ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v</mrOwnerConfig>
+ <quoteGenerationService path='/var/run/tdx-qgs/qgs.socket'/>
+ </launchSecurity>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index a0af6429d1..5683e76599 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2893,6 +2893,9 @@ mymain(void)
DO_TEST_CAPS_ARCH_LATEST("launch-security-s390-pv", "s390x");
+ DO_TEST_CAPS_ARCH_LATEST_FULL("launch-security-tdx", "x86_64",
+ ARG_CAPS_VARIANT, "+inteltdx", ARG_END);
+
DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory");
DO_TEST_CAPS_LATEST("vhost-user-fs-fd-openfiles");
DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages");
--
2.51.0

View File

@ -0,0 +1,125 @@
From b8d1da3b78332fca2555c125c0510a70c7df8d7b Mon Sep 17 00:00:00 2001
Message-ID: <b8d1da3b78332fca2555c125c0510a70c7df8d7b.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 7 Oct 2025 09:32:47 +0200
Subject: [PATCH] src: Drop needless typecast to virDomainTimerNameType
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This was missed in v8.10.0-rc1~229 which switched the 'name'
member of _virDomainTimerDef struct from int to
virDomainTimerNameType.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 6b71d327793bbd6d31c953ad33365c160899cc2b)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/libxl/libxl_conf.c | 2 +-
src/libxl/xen_common.c | 2 +-
src/lxc/lxc_cgroup.c | 2 +-
src/lxc/lxc_controller.c | 2 +-
src/qemu/qemu_command.c | 6 +++---
src/qemu/qemu_validate.c | 2 +-
6 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 7d845b97ec..7fe681f1fd 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -397,7 +397,7 @@ libxlMakeDomBuildInfo(virDomainDef *def,
}
for (i = 0; i < clock.ntimers; i++) {
- switch ((virDomainTimerNameType) clock.timers[i]->name) {
+ switch (clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_TSC:
switch (clock.timers[i]->mode) {
case VIR_DOMAIN_TIMER_MODE_NATIVE:
diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c
index 3a64f565f7..0e98b6f9c1 100644
--- a/src/libxl/xen_common.c
+++ b/src/libxl/xen_common.c
@@ -2097,7 +2097,7 @@ xenFormatHypervisorFeatures(virConf *conf, virDomainDef *def)
}
for (i = 0; i < def->clock.ntimers; i++) {
- switch ((virDomainTimerNameType)def->clock.timers[i]->name) {
+ switch (def->clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_TSC:
switch (def->clock.timers[i]->mode) {
case VIR_DOMAIN_TIMER_MODE_NATIVE:
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 7c889667ba..02e44441b0 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -335,7 +335,7 @@ static int virLXCCgroupSetupDeviceACL(virDomainDef *def,
if (timer->present == VIR_TRISTATE_BOOL_NO)
continue;
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
case VIR_DOMAIN_TIMER_NAME_TSC:
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 7b432a1160..d45e023645 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -1504,7 +1504,7 @@ virLXCControllerSetupTimers(virLXCController *ctrl)
if (timer->present == VIR_TRISTATE_BOOL_NO)
continue;
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
case VIR_DOMAIN_TIMER_NAME_TSC:
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c6b826a007..5fe39f45ff 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5878,7 +5878,7 @@ qemuBuildClockCommandLine(virCommand *cmd,
}
for (i = 0; i < def->clock.ntimers; i++) {
- switch ((virDomainTimerNameType)def->clock.timers[i]->name) {
+ switch (def->clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
/* qemuDomainDefValidateClockTimers will handle this
* error condition */
@@ -6319,7 +6319,7 @@ qemuBuildCpuCommandLine(virCommand *cmd,
for (i = 0; i < def->clock.ntimers; i++) {
virDomainTimerDef *timer = def->clock.timers[i];
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
if (timer->present != VIR_TRISTATE_BOOL_ABSENT) {
/* QEMU expects on/off -> virTristateSwitch. */
@@ -7023,7 +7023,7 @@ qemuBuildMachineCommandLine(virCommand *cmd,
}
for (i = 0; i < def->clock.ntimers; i++) {
- switch ((virDomainTimerNameType)def->clock.timers[i]->name) {
+ switch (def->clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_HPET:
/* qemuBuildClockCommandLine handles the old-style config via '-no-hpet' */
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_HPET) &&
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index bbd838c7f0..6c711444eb 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -462,7 +462,7 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def,
for (i = 0; i < def->clock.ntimers; i++) {
virDomainTimerDef *timer = def->clock.timers[i];
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported timer type (name) '%1$s'"),
--
2.51.1

View File

@ -0,0 +1,107 @@
From c0c1b6b0c424c5c9e030e688d8c9dc20e9aa0ea4 Mon Sep 17 00:00:00 2001
Message-ID: <c0c1b6b0c424c5c9e030e688d8c9dc20e9aa0ea4.1759835599.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:03 -0400
Subject: [PATCH] tools: Secure guest check for Intel in virt-host-validate
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add check in virt-host-validate for secure guest support
on x86 for Intel Trust Domain Extentions.
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
(cherry picked from commit 908bb55724837e66778e6a2c264c9e92b51d7eb6)
Resolves: https://issues.redhat.com/browse/RHEL-111840
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
tools/virt-host-validate-common.c | 31 ++++++++++++++++++++++++++++++-
tools/virt-host-validate-common.h | 1 +
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
index 63cc3dbe7b..59f6ac3319 100644
--- a/tools/virt-host-validate-common.c
+++ b/tools/virt-host-validate-common.c
@@ -44,7 +44,8 @@ VIR_ENUM_IMPL(virHostValidateCPUFlag,
"svm",
"sie",
"158",
- "sev");
+ "sev",
+ "tdx_host_platform");
int virHostValidateDeviceExists(const char *hvname,
@@ -434,12 +435,36 @@ virHostValidateAMDSev(const char *hvname,
}
+static int virHostValidateIntelTDX(virValidateLevel level)
+{
+ g_autofree char *mod_value = NULL;
+
+ if (virFileReadValueString(&mod_value, "/sys/module/kvm_intel/parameters/tdx") < 0) {
+ virValidateFail(level, "Intel Trust Domain Extentions not "
+ "supported by the currently used kernel");
+ return VIR_VALIDATE_FAILURE(level);
+ }
+
+ if (mod_value[0] != 'Y') {
+ virValidateFail(level,
+ "Intel Trust Domain Extentions appears to be "
+ "disabled in kernel. Add kvm_intel.tdx=Y "
+ "to the kernel cmdline arguments");
+ return VIR_VALIDATE_FAILURE(level);
+ }
+
+ virValidatePass();
+ return 1;
+}
+
+
int virHostValidateSecureGuests(const char *hvname,
virValidateLevel level)
{
g_autoptr(virBitmap) flags = NULL;
bool hasFac158 = false;
bool hasAMDSev = false;
+ bool hasIntelTDX = false;
virArch arch = virArchFromHost();
g_autofree char *cmdline = NULL;
static const char *kIBMValues[] = {"y", "Y", "on", "ON", "oN", "On", "1"};
@@ -450,6 +475,8 @@ int virHostValidateSecureGuests(const char *hvname,
hasFac158 = true;
else if (flags && virBitmapIsBitSet(flags, VIR_HOST_VALIDATE_CPU_FLAG_SEV))
hasAMDSev = true;
+ else if (flags && virBitmapIsBitSet(flags, VIR_HOST_VALIDATE_CPU_FLAG_TDX))
+ hasIntelTDX = true;
virValidateCheck(hvname, "%s", _("Checking for secure guest support"));
if (ARCH_IS_S390(arch)) {
@@ -485,6 +512,8 @@ int virHostValidateSecureGuests(const char *hvname,
}
} else if (hasAMDSev) {
return virHostValidateAMDSev(hvname, level);
+ } else if (hasIntelTDX) {
+ return virHostValidateIntelTDX(level);
}
virValidateFail(level,
diff --git a/tools/virt-host-validate-common.h b/tools/virt-host-validate-common.h
index 7fb3545fe3..c81d203933 100644
--- a/tools/virt-host-validate-common.h
+++ b/tools/virt-host-validate-common.h
@@ -32,6 +32,7 @@ typedef enum {
VIR_HOST_VALIDATE_CPU_FLAG_SIE,
VIR_HOST_VALIDATE_CPU_FLAG_FACILITY_158,
VIR_HOST_VALIDATE_CPU_FLAG_SEV,
+ VIR_HOST_VALIDATE_CPU_FLAG_TDX,
VIR_HOST_VALIDATE_CPU_FLAG_LAST,
} virHostValidateCPUFlag;
--
2.51.0

View File

@ -0,0 +1,94 @@
From 85152cf8dd0fe044d3831746e2f5d693778d8da0 Mon Sep 17 00:00:00 2001
Message-ID: <85152cf8dd0fe044d3831746e2f5d693778d8da0.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 2 Oct 2025 09:29:19 +0200
Subject: [PATCH] virxml: Introduce virXPathTristateBool()
Similarly to other virXPath* functions, let's have a helper that
evaluates an XPath and stores the value into virTristateBool.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit e3e4c620f1af03c35c4f0dc7c8a65ea5464df687)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virxml.c | 34 ++++++++++++++++++++++++++++++++++
src/util/virxml.h | 5 +++++
3 files changed, 40 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0edd526a68..bbe1e252af 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3796,6 +3796,7 @@ virXPathLongLong;
virXPathNode;
virXPathNodeSet;
virXPathString;
+virXPathTristateBool;
virXPathTristateSwitch;
virXPathUInt;
virXPathUIntBase;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index cb0a59ffda..6917253ac0 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -292,6 +292,40 @@ virXPathTristateSwitch(const char *xpath,
}
+/**
+ * virXPathTristateBool:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned virTristateBool value
+ *
+ * Convenience function to evaluate an XPath tristate value. The @xpath
+ * expression must ensure that the evaluated value is returned as a
+ * string (use the 'string()' conversion in the expression).
+ *
+ * Returns 0 in case of success in which case @value is set,
+ * or -1 if the XPath evaluation failed or -2 if the
+ * value isn't of a virTristateBool value.
+ */
+int
+virXPathTristateBool(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ virTristateBool *value)
+{
+ g_autoptr(xmlXPathObject) obj = NULL;
+ int rc;
+
+ if (!(obj = virXPathEvalString(xpath, ctxt)))
+ return -1;
+
+ rc = virTristateBoolTypeFromString((char *)obj->stringval);
+ if (rc < 0)
+ return -2;
+
+ *value = rc;
+ return 0;
+}
+
+
/**
* virXMLCheckIllegalChars:
* @nodeName: Name of checked node
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 3d2de4f976..4d7eb4d25c 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -78,6 +78,11 @@ virXPathTristateSwitch(const char *xpath,
xmlXPathContextPtr ctxt,
virTristateSwitch *value);
+int
+virXPathTristateBool(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ virTristateBool *value);
+
xmlNodePtr
virXMLNodeGetSubelement(xmlNodePtr node,
const char *name);
--
2.51.1

View File

@ -0,0 +1,98 @@
From 712964c94adb60b390c283d997e398d1c9cd9930 Mon Sep 17 00:00:00 2001
Message-ID: <712964c94adb60b390c283d997e398d1c9cd9930.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 2 Oct 2025 09:26:59 +0200
Subject: [PATCH] virxml: Introduce virXPathTristateSwitch()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Similarly to other virXPath* functions, let's have a helper that
evaluates an XPath and stores the value into virTristateSwitch.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c689aa80c10242b9c1c4633089ba7ee3f7c1f801)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virxml.c | 34 ++++++++++++++++++++++++++++++++++
src/util/virxml.h | 5 +++++
3 files changed, 40 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0a1235e6d8..0edd526a68 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3796,6 +3796,7 @@ virXPathLongLong;
virXPathNode;
virXPathNodeSet;
virXPathString;
+virXPathTristateSwitch;
virXPathUInt;
virXPathUIntBase;
virXPathULongLong;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index 51173303fe..cb0a59ffda 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -258,6 +258,40 @@ virXPathLongLong(const char *xpath,
}
+/**
+ * virXPathTristateSwitch:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned virTristateSwitch value
+ *
+ * Convenience function to evaluate an XPath tristate value. The @xpath
+ * expression must ensure that the evaluated value is returned as a
+ * string (use the 'string()' conversion in the expression).
+ *
+ * Returns 0 in case of success in which case @value is set,
+ * or -1 if the XPath evaluation failed or -2 if the
+ * value isn't of a virTristateSwitch value.
+ */
+int
+virXPathTristateSwitch(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ virTristateSwitch *value)
+{
+ g_autoptr(xmlXPathObject) obj = NULL;
+ int rc;
+
+ if (!(obj = virXPathEvalString(xpath, ctxt)))
+ return -1;
+
+ rc = virTristateSwitchTypeFromString((char *)obj->stringval);
+ if (rc < 0)
+ return -2;
+
+ *value = rc;
+ return 0;
+}
+
+
/**
* virXMLCheckIllegalChars:
* @nodeName: Name of checked node
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 06ba324df0..3d2de4f976 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -73,6 +73,11 @@ virXPathLongLong(const char *xpath,
xmlXPathContextPtr ctxt,
long long *value);
+int
+virXPathTristateSwitch(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ virTristateSwitch *value);
+
xmlNodePtr
virXMLNodeGetSubelement(xmlNodePtr node,
const char *name);
--
2.51.1

View File

@ -293,7 +293,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 10.10.0
Release: 15%{?dist}%{?extra_release}.alma.1
Release: 15.4%{?dist}%{?extra_release}.alma.1
License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1
URL: https://libvirt.org/
@ -455,6 +455,59 @@ Patch151: libvirt-esx-Allow-specifying-different-CA-bundle-for-remote-connection
Patch152: libvirt-qemu-fix-order-of-VNC-TLS-config-entries.patch
Patch153: libvirt-qemu-sanitize-blank-lines-in-config-file.patch
Patch154: libvirt-qemu-add-ability-to-set-TLS-priority-string-with-QEMU.patch
Patch155: libvirt-tools-Secure-guest-check-for-Intel-in-virt-host-validate.patch
Patch156: libvirt-qemu-Check-if-INTEL-Trust-Domain-Extention-support-is-enabled.patch
Patch157: libvirt-qemucapabilitiesdata-Document-inteltdx-variant.patch
Patch158: libvirt-qemucapabilitiestest-Add-data-for-the-qemu-10.1.0-dev-cycle-on-x86_64-for-the-inteltdx-variant.patch
Patch159: libvirt-qemu-Add-QEMU_CAPS_TDX_GUEST-capability.patch
Patch160: libvirt-conf-Expose-TDX-feature-in-domain-capabilities.patch
Patch161: libvirt-conf-Add-tdx-as-launch-security-type.patch
Patch162: libvirt-conf-Validate-TDX-launchSecurity-element-mrConfigId-mrOwner-mrOwnerConfig.patch
Patch163: libvirt-qemu-Add-command-line-and-validation-for-TDX-type.patch
Patch164: libvirt-conf-Expose-TDX-type-in-domain-launch-security-capability.patch
Patch165: libvirt-qemu-Force-special-parameters-enabled-for-TDX-guest.patch
Patch166: libvirt-qemu-log-the-crash-information-for-TDX.patch
Patch167: libvirt-qemu_firmware-Pick-the-right-firmware-for-TDX-guests.patch
Patch168: libvirt-conf-Add-Intel-TDX-Quote-Generation-Service-QGS-support.patch
Patch169: libvirt-qemu-Add-command-line-for-TDX-Quote-Generation-Service-QGS.patch
Patch170: libvirt-qemu-Add-FakeReboot-support-for-TDX-guest.patch
Patch171: libvirt-qemu-Support-reboot-command-in-guest.patch
Patch172: libvirt-qemu-Avoid-duplicate-FakeReboot-for-secure-guest.patch
Patch173: libvirt-qemu-Send-event-VIR_DOMAIN_EVENT_-STOPPED-STARTED-during-recreation.patch
Patch174: libvirt-qemu-Support-domain-reset-command-for-TDX-guest.patch
Patch175: libvirt-qemuxmlconftest-Add-latest-version-of-launch-security-tdx-test-data.patch
Patch176: libvirt-docs-domain-Add-documentation-for-Intel-TDX-guest.patch
Patch177: libvirt-conf-Do-not-parse-hyperv-features-with-passthrough-mode.patch
Patch178: libvirt-src-Drop-needless-typecast-to-virDomainTimerNameType.patch
Patch179: libvirt-conf-Introduce-virDomainDefHasTimer.patch
Patch180: libvirt-qemuxmlconfdata-Adjust-hv-stimer-related-tests.patch
Patch181: libvirt-qemu_validate-Reflect-dependencies-of-hv-synic.patch
Patch182: libvirt-qemu_validate-Reflect-dependencies-of-hv-stimer.patch
Patch183: libvirt-qemu_validate-Reflect-dependencies-of-hv-tlbflush.patch
Patch184: libvirt-qemu_validate-Reflect-dependencies-of-hv-ipi.patch
Patch185: libvirt-qemu_validate-Reflect-dependencies-of-hv-evmcs.patch
Patch186: libvirt-qemu_validate-Reflect-dependencies-of-hv-tlbflush-direct.patch
Patch187: libvirt-virxml-Introduce-virXPathTristateSwitch.patch
Patch188: libvirt-virxml-Introduce-virXPathTristateBool.patch
Patch189: libvirt-qemu-Use-virXPathTristateBool.patch
Patch190: libvirt-domain_conf-Move-format-of-hyperv-features-into-a-function.patch
Patch191: libvirt-domain_conf-Use-virXMLFormatElement-to-format-hyperv-features.patch
Patch192: libvirt-qemu_caps-Prefer-VIR_DOMAIN_CAPS_ENUM_IS_SET.patch
Patch193: libvirt-qemu_command-Move-hyperv-cmd-line-generation-into-a-function.patch
Patch194: libvirt-qemu_command-Prefer-virBufferAddLit-in-qemuBuildCpuHypervCommandLine.patch
Patch195: libvirt-conf-More-hyperv-related-members-into-a-single-struct.patch
Patch196: libvirt-conf-Report-default-hyperv-values-in-domain-capabilities.patch
Patch197: libvirt-qemu_capabilities-Format-and-parse-new-hyperv-domcaps-members.patch
Patch198: libvirt-qemu_capabilities-Fetch-new-hyperv-domcaps.patch
Patch199: libvirt-qemu_caps-Introduce-virQEMUCapsGetHypervCapabilities.patch
Patch200: libvirt-conf-Introduce-hyperv-host-model-mode.patch
Patch201: libvirt-qemu_process-Populate-hyperv-features-for-host-model.patch
Patch202: libvirt-cpu_conf-Make-virCPUDefFilterFeatures-return-void.patch
Patch203: libvirt-qemu_domain-Simplify-qemuDomainFixupCPUs.patch
Patch204: libvirt-qemu_domain-Fix-qemuDomainFixupCPUs.patch
Patch205: libvirt-qemu_process-Always-fix-CPUs-on-reconnect.patch
Patch206: libvirt-qemu_monitor-Filter-CPU-features-reported-by-QEMU.patch
Patch207: libvirt-qemu-Ignore-ht-CPU-feature.patch
Requires: libvirt-daemon = %{version}-%{release}
@ -2780,9 +2833,79 @@ exit 0
%endif
%changelog
* Mon Sep 15 2025 Eduard Abdullin <eabdullin@almalinux.org> - 10.10.0-15.alma.1
* Mon Dec 22 2025 Eduard Abdullin <eabdullin@almalinux.org> - 10.10.0-15.4.alma.1
- Enable building for ppc64le
* Fri Nov 21 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-15.4.el9_7
- cpu_conf: Make virCPUDefFilterFeatures return void (RHEL-126096)
- qemu_domain: Simplify qemuDomainFixupCPUs (RHEL-126096)
- qemu_domain: Fix qemuDomainFixupCPUs (RHEL-126096)
- qemu_process: Always fix CPUs on reconnect (RHEL-126096)
- qemu_monitor: Filter CPU features reported by QEMU (RHEL-126096)
- qemu: Ignore "ht" CPU feature (RHEL-126096)
* Fri Nov 14 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-15.3.el9_7
- conf: Do not parse hyperv features with passthrough mode (RHEL-122930)
- src: Drop needless typecast to virDomainTimerNameType (RHEL-122930)
- conf: Introduce virDomainDefHasTimer() (RHEL-122930)
- qemuxmlconfdata: Adjust hv-stimer related tests (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-synic (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-stimer (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-tlbflush (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-ipi (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-evmcs (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-tlbflush-direct (RHEL-122930)
- virxml: Introduce virXPathTristateSwitch() (RHEL-122930)
- virxml: Introduce virXPathTristateBool() (RHEL-122930)
- qemu: Use virXPathTristateBool() (RHEL-122930)
- domain_conf: Move format of hyperv features into a function (RHEL-122930)
- domain_conf: Use virXMLFormatElement() to format hyperv features (RHEL-122930)
- qemu_caps: Prefer VIR_DOMAIN_CAPS_ENUM_IS_SET() (RHEL-122930)
- qemu_command: Move hyperv cmd line generation into a function (RHEL-122930)
- qemu_command: Prefer virBufferAddLit() in qemuBuildCpuHypervCommandLine() (RHEL-122930)
- conf: More hyperv related members into a single struct (RHEL-122930)
- conf: Report default hyperv values in domain capabilities (RHEL-122930)
- qemu_capabilities: Format and parse new hyperv domcaps members (RHEL-122930)
- qemu_capabilities: Fetch new hyperv domcaps (RHEL-122930)
- qemu_caps: Introduce virQEMUCapsGetHypervCapabilities() (RHEL-122930)
- conf: Introduce hyperv host-model mode (RHEL-122930)
- qemu_process: Populate hyperv features for host-model (RHEL-122930)
- RHEL: Remove patches from invalid 10.10.0-15.2.el9_7 build (RHEL-122930)
* Wed Nov 12 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-15.2.el9_7
- virBitmapFormat: Don't check return value (RHEL-122930)
- domain_conf: Make virDomainMemoryDefFormat() return void (RHEL-122930)
- domain_conf: Switch to virXMLFormatElement() in virDomainMemoryDefFormat() (RHEL-122930)
- conf: Introduce virDomainMemoryIsVirtioModel() (RHEL-122930)
- qemu: Use virDomainMemoryIsVirtioModel() (RHEL-122930)
- conf: Introduce virtio options for virtio memory models (RHEL-122930)
- qemu_command: Generate virtio options for memory device (RHEL-122930)
- domain_conf: Avoid memory leak in virDomainMemoryDefFree() (RHEL-122930)
* Tue Oct 7 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-15.1.el9_7
- tools: Secure guest check for Intel in virt-host-validate (RHEL-111840)
- qemu: Check if INTEL Trust Domain Extention support is enabled (RHEL-111840)
- qemucapabilitiesdata: Document '+inteltdx' variant (RHEL-111840)
- qemucapabilitiestest: Add data for the qemu-10.1.0 dev cycle on x86_64 for the '+inteltdx' variant (RHEL-111840)
- qemu: Add QEMU_CAPS_TDX_GUEST capability (RHEL-111840)
- conf: Expose TDX feature in domain capabilities (RHEL-111840)
- conf: Add tdx as launch security type (RHEL-111840)
- conf: Validate TDX launchSecurity element mrConfigId/mrOwner/mrOwnerConfig (RHEL-111840)
- qemu: Add command line and validation for TDX type (RHEL-111840)
- conf: Expose TDX type in domain launch security capability (RHEL-111840)
- qemu: Force special parameters enabled for TDX guest (RHEL-111840)
- qemu: log the crash information for TDX (RHEL-111840)
- qemu_firmware: Pick the right firmware for TDX guests (RHEL-111840)
- conf: Add Intel TDX Quote Generation Service(QGS) support (RHEL-111840)
- qemu: Add command line for TDX Quote Generation Service(QGS) (RHEL-111840)
- qemu: Add FakeReboot support for TDX guest (RHEL-111840)
- qemu: Support reboot command in guest (RHEL-111840)
- qemu: Avoid duplicate FakeReboot for secure guest (RHEL-111840)
- qemu: Send event VIR_DOMAIN_EVENT_[STOPPED|STARTED] during recreation (RHEL-111840)
- qemu: Support domain reset command for TDX guest (RHEL-111840)
- qemuxmlconftest: Add latest version of 'launch-security-tdx*' test data (RHEL-111840)
- docs: domain: Add documentation for Intel TDX guest (RHEL-111840)
* Mon Aug 18 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-15
- qemu: fix order of VNC TLS config entries (RHEL-106276)
- qemu: sanitize blank lines in config file (RHEL-106276)