Enable building for ppc64le

This commit is contained in:
Eduard Abdullin 2026-08-11 12:41:38 +00:00 committed by root
commit 0870102d34
249 changed files with 88033 additions and 58725 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
libvirt-11.5.0.tar.xz
libvirt-11.10.0.tar.xz

View File

@ -0,0 +1,248 @@
From 48f5933f6cd6f53997823cfe2a277b822b00264f Mon Sep 17 00:00:00 2001
Message-ID: <48f5933f6cd6f53997823cfe2a277b822b00264f.1771336681.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 29 Jan 2026 18:10:26 +0100
Subject: [PATCH] Expose latency histograms via 'virConnectGetAllDomainStats'
Add documentation and constants for constructing the stats field names
for latency histograms and expose them in the qemu driver:
Example:
block.1.latency_histogram.read.bin.count=9
block.1.latency_histogram.read.bin.0.start=0
block.1.latency_histogram.read.bin.0.value=0
block.1.latency_histogram.read.bin.1.start=10
block.1.latency_histogram.read.bin.1.value=0
block.1.latency_histogram.read.bin.2.start=100
block.1.latency_histogram.read.bin.2.value=0
block.1.latency_histogram.read.bin.3.start=1000
block.1.latency_histogram.read.bin.3.value=1047
block.1.latency_histogram.read.bin.4.start=10000
block.1.latency_histogram.read.bin.4.value=2131
block.1.latency_histogram.read.bin.5.start=100000
block.1.latency_histogram.read.bin.5.value=0
block.1.latency_histogram.read.bin.6.start=1000000
block.1.latency_histogram.read.bin.6.value=0
block.1.latency_histogram.read.bin.7.start=10000000
block.1.latency_histogram.read.bin.7.value=0
block.1.latency_histogram.read.bin.8.start=100000000
block.1.latency_histogram.read.bin.8.value=0
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 237e49127a9390f054e33e689ba9db1587cdc9f1)
https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2]
---
docs/manpages/virsh.rst | 7 ++
include/libvirt/libvirt-domain.h | 113 +++++++++++++++++++++++++++++++
src/qemu/qemu_driver.c | 43 ++++++++++++
3 files changed, 163 insertions(+)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index a9d691824e..ff0cf1a715 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -2811,6 +2811,13 @@ Information listed includes:
pending write operations in the defined interval
* ``block.<num>.timed_group.<num>.zone_append_queue_depth_avg`` - average number
of pending zone append operations in the defined interval
+* ``block.<num>.latency_histogram.<type>.bin.count`` - number of bins in
+ latency histogram. <type> is one of ``read``, ``write``, ``zone_append``, or
+ ``flush``
+* ``block.<num>.latency_histogram.<type>.bin.<num>.start`` start boundary of
+ a latency histogram bin in nanoseconds of given operation duration
+* ``block.<num>.latency_histogram.<type>.bin.<num>.value`` current number of
+ events corresponding to the given bin and type
*--iothread* returns information about IOThreads on the running guest
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 16fac6b085..8e62bd23d4 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -3815,6 +3815,119 @@ struct _virDomainStatsRecord {
*/
# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_TIMED_GROUP_SUFFIX_ZONE_APPEND_QUEUE_DEPTH_AVG ".zone_append_queue_depth_avg"
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX:
+ *
+ * The parameter name prefix to access 'read' latency histograms. Concatenate
+ * the prefix with either:
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT
+ * to get the number of bins in given histogram
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and
+ * entry number formatted as an unsigned integer and one of the latency
+ * histogram suffix parameters to compelte a full bin parameter name
+ *
+ * Since: 12.1.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX ".latency_histogram.read."
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX:
+ *
+ * The parameter name prefix to access 'write' latency histograms. Concatenate
+ * the prefix with either:
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT
+ * to get the number of bins in given histogram
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and
+ * entry number formatted as an unsigned integer and one of the latency
+ * histogram suffix parameters to compelte a full bin parameter name
+ *
+ * Since: 12.1.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX ".latency_histogram.write."
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX:
+ *
+ * The parameter name prefix to access 'zone_append' latency histograms. Concatenate
+ * the prefix with either:
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT
+ * to get the number of bins in given histogram
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and
+ * entry number formatted as an unsigned integer and one of the latency
+ * histogram suffix parameters to compelte a full bin parameter name
+ *
+ * Since: 12.1.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX ".latency_histogram.zone_append."
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX:
+ *
+ * The parameter name prefix to access 'flush' latency histograms. Concatenate
+ * the prefix with either:
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT
+ * to get the number of bins in given histogram
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and
+ * entry number formatted as an unsigned integer and one of the latency
+ * histogram suffix parameters to compelte a full bin parameter name
+ *
+ * Since: 12.1.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX ".latency_histogram.flush."
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT:
+ *
+ * The parameter name suffix to access number of bins in one of the following
+ * latency histogram types:
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX
+ *
+ * Number of bins in latency histogram as unsigned long long.
+ *
+ * Since: 12.1.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT "bin.count"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX:
+ *
+ * The parameter name suffix to access a latency histogram bin in one of the
+ * following latency histogram types:
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX
+ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX
+ *
+ * Concatenate with a bin number as unsigned int and one of the other field
+ * suffixes to access bin parameters.
+ *
+ * Since: 12.1.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX "bin."
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_START:
+ *
+ * Start of the current latency histogram bin in nanoseconds as unsigned long long.
+ *
+ * Since: 12.1.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_START ".start"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_VALUE:
+ *
+ * Current value of the number of occurences of the latency within this bin
+ * as unsigned long long.
+ *
+ * Since: 12.1.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_VALUE ".value"
+
+
/**
* VIR_DOMAIN_STATS_PERF_CMT:
*
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 08a547c546..f3e7410f9e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17597,6 +17597,36 @@ qemuDomainGetStatsBlockExportBackendStorage(const char *entryname,
}
+static void
+qemuDomainGetStatsBlockExportFrontendLatencyHistogram(struct qemuBlockStatsLatencyHistogram *h,
+ size_t disk_idx,
+ const char *prefix_hist,
+ virTypedParamList *par)
+{
+ size_t i;
+
+ if (!h)
+ return;
+
+ virTypedParamListAddULLong(par, h->nbins,
+ VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu%s" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT,
+ disk_idx, prefix_hist);
+
+ for (i = 0; i < h->nbins; i++) {
+ virTypedParamListAddULLong(par, h->bins[i].start,
+ VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu%s"
+ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX "%zu"
+ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_START,
+ disk_idx, prefix_hist, i);
+ virTypedParamListAddULLong(par, h->bins[i].value,
+ VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu%s"
+ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX "%zu"
+ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_VALUE,
+ disk_idx, prefix_hist, i);
+ }
+}
+
+
static void
qemuDomainGetStatsBlockExportFrontend(const char *frontendname,
GHashTable *stats,
@@ -17721,6 +17751,19 @@ qemuDomainGetStatsBlockExportFrontend(const char *frontendname,
idx, i);
}
}
+
+ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_read, idx,
+ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX,
+ par);
+ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_write, idx,
+ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX,
+ par);
+ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_zone, idx,
+ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX,
+ par);
+ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_flush, idx,
+ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX,
+ par);
}
--
2.53.0

View File

@ -0,0 +1,73 @@
From d3c5e531b0798c384c944896194548d89f130452 Mon Sep 17 00:00:00 2001
Message-ID: <d3c5e531b0798c384c944896194548d89f130452.1781277506.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 26 May 2026 15:38:59 +0200
Subject: [PATCH] Fix documentation of
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES
The flag is designed for expanding the CPU model used by host-model. But
the documentation was sometimes describing it as showing all CPU
features supported on the host, which is wrong as the host may support
features that would not be enabled in host-model.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 090183a7dc4a64cca83937eff9a4e93a45b4d712)
https://redhat.atlassian.net/browse/RHEL-180449
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
docs/manpages/virsh.rst | 5 +++--
src/libvirt-domain.c | 6 +++---
tools/virsh-host.c | 2 +-
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 591c47a7ce..cd26425212 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -640,8 +640,9 @@ flagged as deprecated for the CPU model by the hypervisor. These
features will be paired with the "disable" policy.
The **--expand-cpu-features** option will cause the host-model CPU definition
-to contain all CPU features supported on the host including those implicitly
-enabled by the selected CPU model.
+to contain all required CPU features including those implicitly enabled by the
+selected CPU model. Without this flag features that are part of the CPU model
+itself will not be listed.
pool-capabilities
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 034f126dd5..e146fa7e82 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12331,9 +12331,9 @@ virDomainSetUserPassword(virDomainPtr dom,
* passthrough and so on.
*
* If @flags includes VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
- * libvirt will explicitly list all CPU features (in host-model CPU definition)
- * that are supported on the host. Without this flag features that are part of
- * the CPU model itself will not be listed.
+ * libvirt will explicitly list all CPU features that will be enabled for
+ * host-model CPU mode. Without this flag features that are part of the CPU
+ * model itself will not be listed.
*
* Returns NULL in case of error or an XML string
* defining the capabilities.
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index dd98917fa8..5dbeb54ae5 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -120,7 +120,7 @@ static const vshCmdOptDef opts_domcapabilities[] = {
},
{.name = "expand-cpu-features",
.type = VSH_OT_BOOL,
- .help = N_("show all features in host CPU model"),
+ .help = N_("expand 'host-model' CPU to also show features enabled by the CPU model"),
},
{.name = NULL}
};
--
2.54.0

View File

@ -0,0 +1,54 @@
From 0b61675df4b585e61f911ed953bbbac76c5cfc73 Mon Sep 17 00:00:00 2001
Message-ID: <0b61675df4b585e61f911ed953bbbac76c5cfc73.1774618368.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 11 Mar 2026 11:31:06 +0100
Subject: [PATCH] Introduce EXPAND_CPU_FEATURES flag for domain capabilities
The new VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flag for
virConnectGetDomainCapabilities can be used to request the host-model
CPU definition to include all supported features (normally only extra
features relative to the selected CPU model are listed).
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 8aa13d1b16b08feea37ecacc85540671e7995bb8)
https://issues.redhat.com/browse/RHEL-154553
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
include/libvirt/libvirt-domain.h | 2 ++
src/libvirt-domain.c | 5 +++++
2 files changed, 7 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 221e22443e..0da0a399fe 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1517,6 +1517,8 @@ int virDomainMigrateStartPostCopy(virDomainPtr domain,
typedef enum {
/* Report host model with deprecated features disabled. (Since: 11.0.0) */
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES = (1 << 0),
+ /* Report all host model CPU features. (Since: 12.2.0) */
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES = (1 << 1),
} virConnectGetDomainCapabilitiesFlags;
char * virConnectGetDomainCapabilities(virConnectPtr conn,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index c7451fee05..034f126dd5 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12330,6 +12330,11 @@ virDomainSetUserPassword(virDomainPtr dom,
* instance, if host, libvirt and qemu is capable of VFIO
* passthrough and so on.
*
+ * If @flags includes VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
+ * libvirt will explicitly list all CPU features (in host-model CPU definition)
+ * that are supported on the host. Without this flag features that are part of
+ * the CPU model itself will not be listed.
+ *
* Returns NULL in case of error or an XML string
* defining the capabilities.
*
--
2.53.0

View File

@ -0,0 +1,59 @@
From 2ad60e82218ad8cb7cb333482e143441591b8b4f Mon Sep 17 00:00:00 2001
Message-ID: <2ad60e82218ad8cb7cb333482e143441591b8b4f.1781277506.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 29 May 2026 12:52:39 +0200
Subject: [PATCH] Introduce
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag
Some CPU features may be enabled explicitly, but should not
automatically become part of a host-model CPU. Users can now request
such features to be shown in the host-model CPU in domain capabilities
by VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit e1efd79e837456d209115c536fc7e5f14abcbc63)
https://redhat.atlassian.net/browse/RHEL-180449
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
include/libvirt/libvirt-domain.h | 3 +++
src/libvirt-domain.c | 8 ++++++++
2 files changed, 11 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 0da0a399fe..7f02a48021 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1519,6 +1519,9 @@ typedef enum {
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES = (1 << 0),
/* Report all host model CPU features. (Since: 12.2.0) */
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES = (1 << 1),
+ /* Report all CPU features supported on the host, even those that will not
+ * be enabled by host-model CPU mode. (Since: 12.5.0) */
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES = (1 << 2),
} virConnectGetDomainCapabilitiesFlags;
char * virConnectGetDomainCapabilities(virConnectPtr conn,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index e146fa7e82..0ae48654df 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12335,6 +12335,14 @@ virDomainSetUserPassword(virDomainPtr dom,
* host-model CPU mode. Without this flag features that are part of the CPU
* model itself will not be listed.
*
+ * Adding VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES to @flags
+ * tells libvirt to update the host-model CPU definition with features that are
+ * supported on the host, but will not be enabled by default when starting a
+ * domain with host-model CPU. Use both
+ * VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES and
+ * VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flags to get a
+ * complete list of features that can be enabled on the host.
+ *
* Returns NULL in case of error or an XML string
* defining the capabilities.
*
--
2.54.0

View File

@ -0,0 +1,422 @@
From 8fbea435edb1635ec98c9419e9249223e5c3b2b6 Mon Sep 17 00:00:00 2001
Message-ID: <8fbea435edb1635ec98c9419e9249223e5c3b2b6.1771336682.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 23 Jan 2026 17:09:27 +0100
Subject: [PATCH] Introduce support for disk operation latency histogram
collection
Add config and docs allowing enabling latency histogram collection for
block device operations.
This patch sets up the docs, schema and XML infrastructure.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit b874c944bd8c4ffa6c51394557587c8c203f1656)
https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2]
---
docs/formatdomain.rst | 41 ++++++
src/conf/domain_conf.c | 133 +++++++++++++++++-
src/conf/domain_conf.h | 7 +
src/conf/schemas/domaincommon.rng | 37 ++++-
...isk-statistics-intervals.x86_64-latest.xml | 29 ++++
.../disk-statistics-intervals.xml | 25 ++++
6 files changed, 262 insertions(+), 10 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 70882c6820..31232deb3c 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -3628,6 +3628,47 @@ paravirtualized driver is specified via the ``disk`` element.
:since:`Since 11.9.0 (QEMU 10.2, virtio, ide, scsi disks only)`.
+ Block operation latency histogram collection can be configured using
+ ``<latency-histogram>`` sub-element. The histogram is collected for
+ the whole runtime of the VM, but can be re-started or reconfigured using
+ the `virDomainUpdateDeviceFlags <html/libvirt-libvirt-domain.html#virDomainUpdateDeviceFlags>`__
+ API. Using the same config re-starts histogram collection.
+
+ The optional ``type`` attribute configures specific operation to collect
+ the histogram for. Supported types are ``read``, ``write``, ``zone``, and
+ ``flush``. If the ``type`` attribute is omitted the histogram collection
+ bins bins apply to all of the aforementioned types, which can be overriden
+ with specific config.
+
+ The ``<latency-histogram>`` has multiple mandatory ``<bin>`` sub-elements
+ with mandatory ``start`` attribute configuring the starting boundary of
+ the histogram bin configured in nanosecods of the operation duration and
+ the intervals must be properly ordered and non-duplicate.
+
+ Example::
+
+ <driver name='qemu'>
+ <statistics>
+
+ <latency-histogram>
+ <bin start='0'/>
+ <bin start='1000'/>
+ <bin start='100000'/>
+ </latency-histogram>
+
+ [or for specific operation types]
+
+ <latency-histogram type='read'>
+ <bin start='0'/>
+ <bin start='1000'/>
+ <bin start='100000'/>
+ </latency-histogram>
+
+ </statistics>
+ </driver>
+
+ :since:`Since 12.1.0`.
+
- The optional ``queues`` attribute specifies the number of virt queues for
virtio-blk ( :since:`Since 3.9.0` ) or vhost-user-blk
( :since:`Since 7.1.0` )
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f5c4d135a9..83c58ab5ff 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2445,6 +2445,11 @@ virDomainDiskDefFree(virDomainDiskDef *def)
virObjectUnref(def->privateData);
g_slist_free_full(def->iothreads, (GDestroyNotify) virDomainIothreadMappingDefFree);
g_free(def->statistics);
+ g_free(def->histogram_boundaries);
+ g_free(def->histogram_boundaries_read);
+ g_free(def->histogram_boundaries_write);
+ g_free(def->histogram_boundaries_zone);
+ g_free(def->histogram_boundaries_flush);
if (def->throttlefilters) {
size_t i;
@@ -8307,6 +8312,91 @@ virDomainIothreadMappingDefParse(xmlNodePtr driverNode,
}
+static int
+virDomainDiskDefDriverParseXMLHistogramOne(virDomainDiskDef *def,
+ xmlNodePtr cur)
+{
+ g_autofree char *histogram_type = NULL;
+ unsigned int **histogram_config = NULL;
+ g_autoptr(GPtrArray) binNodes = virXMLNodeGetSubelementList(cur, "bin");
+ size_t nbins = 0;
+ size_t i;
+
+ if ((histogram_type = virXMLPropString(cur, "type"))) {
+ if (STREQ(histogram_type, "read")) {
+ histogram_config = &def->histogram_boundaries_read;
+ } else if (STREQ(histogram_type, "write")) {
+ histogram_config = &def->histogram_boundaries_write;
+ } else if (STREQ(histogram_type, "zone")) {
+ histogram_config = &def->histogram_boundaries_zone;
+ } else if (STREQ(histogram_type, "flush")) {
+ histogram_config = &def->histogram_boundaries_flush;
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown latency_histogram type '%1$s'"),
+ histogram_type);
+ return -1;
+ }
+ } else {
+ histogram_config = &def->histogram_boundaries;
+ }
+
+ if (*histogram_config) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("only one latency-histogram of a given type is supported"));
+ return -1;
+ }
+
+ if (binNodes->len == 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing 'bin' elements for 'latency-histogram'"));
+ return -1;
+ }
+
+ *histogram_config = g_new0(unsigned int, binNodes->len + 1);
+
+ for (i = 0; i < binNodes->len; i++) {
+ unsigned int val;
+
+ if (virXMLPropUInt(g_ptr_array_index(binNodes, i),
+ "start", 10,
+ VIR_XML_PROP_REQUIRED,
+ &val) < 0)
+ return -1;
+
+ if (nbins > 0 &&
+ (val == 0 ||
+ val <= (*histogram_config)[nbins-1])) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("the values of 'start' attribute of a 'latency-histogram' 'bin' configuration must be sorted and non-overlapping"));
+ return -1;
+ }
+
+ if (val > 0)
+ (*histogram_config)[nbins++] = val;
+ }
+
+ return 0;
+}
+
+
+static int
+virDomainDiskDefDriverParseXMLHistograms(virDomainDiskDef *def,
+ xmlNodePtr cur)
+{
+ g_autoptr(GPtrArray) histogramNodes = virXMLNodeGetSubelementList(cur, "latency-histogram");
+ size_t i;
+
+ for (i = 0; i < histogramNodes->len; i++) {
+ if (virDomainDiskDefDriverParseXMLHistogramOne(def,
+ g_ptr_array_index(histogramNodes, i)) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
virDomainDiskDefDriverParseXML(virDomainDiskDef *def,
xmlNodePtr cur)
@@ -8380,6 +8470,9 @@ virDomainDiskDefDriverParseXML(virDomainDiskDef *def,
return -1;
}
}
+
+ if (virDomainDiskDefDriverParseXMLHistograms(def, statisticsNode) < 0)
+ return -1;
}
if (virXMLPropEnum(cur, "detect_zeroes",
@@ -23961,12 +24054,37 @@ virDomainDiskDefFormatThrottleFilters(virBuffer *buf,
}
+static void
+virDomainDiskDefFormatDriverHistogram(virBuffer *buf,
+ const char *type,
+ unsigned int *bins)
+{
+ g_auto(virBuffer) histogramAttrBuf = VIR_BUFFER_INITIALIZER;
+ g_auto(virBuffer) histogramChildBuf = VIR_BUFFER_INIT_CHILD(buf);
+
+ if (!bins || bins[0] == 0)
+ return;
+
+ if (type)
+ virBufferAsprintf(&histogramAttrBuf, " type='%s'", type);
+
+ /* we dont store the start boundary of the first bin but it's always there */
+ virBufferAddLit(&histogramChildBuf, "<bin start='0'/>\n");
+
+ for (; *bins > 0; bins++)
+ virBufferAsprintf(&histogramChildBuf, "<bin start='%u'/>\n", *bins);
+
+ virXMLFormatElement(buf, "latency-histogram", &histogramAttrBuf, &histogramChildBuf);
+}
+
+
static void
virDomainDiskDefFormatDriver(virBuffer *buf,
virDomainDiskDef *disk)
{
g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
+ g_auto(virBuffer) statisticsChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf);
virBufferEscapeString(&attrBuf, " name='%s'", virDomainDiskGetDriver(disk));
@@ -24038,16 +24156,25 @@ virDomainDiskDefFormatDriver(virBuffer *buf,
virDomainIothreadMappingDefFormat(&childBuf, disk->iothreads);
if (disk->statistics) {
- g_auto(virBuffer) statisticsChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf);
size_t i;
for (i = 0; disk->statistics[i] > 0; i++)
virBufferAsprintf(&statisticsChildBuf, "<statistic interval='%u'/>\n",
disk->statistics[i]);
-
- virXMLFormatElement(&childBuf, "statistics", NULL, &statisticsChildBuf);
}
+ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, NULL,
+ disk->histogram_boundaries);
+ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "read",
+ disk->histogram_boundaries_read);
+ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "write",
+ disk->histogram_boundaries_write);
+ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "zone",
+ disk->histogram_boundaries_zone);
+ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "flush",
+ disk->histogram_boundaries_flush);
+
+ virXMLFormatElement(&childBuf, "statistics", NULL, &statisticsChildBuf);
virXMLFormatElement(buf, "driver", &attrBuf, &childBuf);
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8f53ed96c0..b120d4a68e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -596,6 +596,13 @@ struct _virDomainDiskDef {
GSList *iothreads; /* List of virDomainIothreadMappingDef */
unsigned int *statistics; /* Optional, zero terminated list of intervals to
collect statistics for */
+ /* optional zero terminated lists of bin boundaries for latency histograms */
+ unsigned int *histogram_boundaries;
+ unsigned int *histogram_boundaries_read;
+ unsigned int *histogram_boundaries_write;
+ unsigned int *histogram_boundaries_zone;
+ unsigned int *histogram_boundaries_flush;
+
virDomainDiskDetectZeroes detect_zeroes;
virTristateSwitch discard_no_unref;
char *domain_name; /* backend domain name */
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 1f9ac102a0..441328a08e 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -2728,13 +2728,36 @@
</optional>
<optional>
<element name="statistics">
- <zeroOrMore>
- <element name="statistic">
- <attribute name="interval">
- <ref name="unsignedInt"/>
- </attribute>
- </element>
- </zeroOrMore>
+ <interleave>
+ <zeroOrMore>
+ <element name="statistic">
+ <attribute name="interval">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </element>
+ </zeroOrMore>
+ <zeroOrMore>
+ <element name="latency-histogram">
+ <optional>
+ <attribute name='type'>
+ <choice>
+ <value>read</value>
+ <value>write</value>
+ <value>zone</value>
+ <value>flush</value>
+ </choice>
+ </attribute>
+ </optional>
+ <oneOrMore>
+ <element name='bin'>
+ <attribute name='start'>
+ <ref name="unsignedInt"/>
+ </attribute>
+ </element>
+ </oneOrMore>
+ </element>
+ </zeroOrMore>
+ </interleave>
</element>
</optional>
</interleave>
diff --git a/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml b/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml
index 4c55c50ef5..d02f954073 100644
--- a/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml
@@ -22,6 +22,11 @@
<statistics>
<statistic interval='3'/>
<statistic interval='10'/>
+ <latency-histogram>
+ <bin start='0'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
</statistics>
</driver>
<source file='/var/lib/libvirt/images/iothrtest1.img'/>
@@ -33,6 +38,30 @@
<statistics>
<statistic interval='5'/>
<statistic interval='15'/>
+ <latency-histogram type='read'>
+ <bin start='0'/>
+ <bin start='10'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
+ <latency-histogram type='write'>
+ <bin start='0'/>
+ <bin start='10'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
+ <latency-histogram type='zone'>
+ <bin start='0'/>
+ <bin start='10'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
+ <latency-histogram type='flush'>
+ <bin start='0'/>
+ <bin start='10'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
</statistics>
</driver>
<source file='/var/lib/libvirt/images/iothrtest2.img'/>
diff --git a/tests/qemuxmlconfdata/disk-statistics-intervals.xml b/tests/qemuxmlconfdata/disk-statistics-intervals.xml
index f5e801f5a8..5f9e9470d7 100644
--- a/tests/qemuxmlconfdata/disk-statistics-intervals.xml
+++ b/tests/qemuxmlconfdata/disk-statistics-intervals.xml
@@ -19,6 +19,11 @@
<statistics>
<statistic interval='3'/>
<statistic interval='10'/>
+ <latency-histogram>
+ <bin start='0'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
</statistics>
</driver>
<source file='/var/lib/libvirt/images/iothrtest1.img'/>
@@ -29,6 +34,26 @@
<statistics>
<statistic interval='5'/>
<statistic interval='15'/>
+ <latency-histogram type='read'>
+ <bin start='10'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
+ <latency-histogram type='write'>
+ <bin start='10'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
+ <latency-histogram type='zone'>
+ <bin start='10'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
+ <latency-histogram type='flush'>
+ <bin start='10'/>
+ <bin start='20'/>
+ <bin start='30'/>
+ </latency-histogram>
</statistics>
</driver>
<source file='/var/lib/libvirt/images/iothrtest2.img'/>
--
2.53.0

View File

@ -0,0 +1,125 @@
From c2eb6d70891d9be5ce13f07946841239a81c3ed9 Mon Sep 17 00:00:00 2001
Message-ID: <c2eb6d70891d9be5ce13f07946841239a81c3ed9.1771336681.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 16 Feb 2026 15:08:54 +0100
Subject: [PATCH] RHEL-ONLY: backport test data for 'migrate-pr' capability of
'scsi-block'
In upstream qemu the capability is present starting with qemu-11.0. We
don't have the test data downstream and backporting them would be too
invasive. Backport the relevant capability detection as a
downstream-only fix.
https://issues.redhat.com/browse/RHEL-140614 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-135115 [rhel-10.2]
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
---
.../caps_10.2.0_x86_64.replies | 79 ++++++++++++++++++-
.../caps_10.2.0_x86_64.xml | 1 +
2 files changed, 76 insertions(+), 4 deletions(-)
diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies
index cb4abb4533..10db9baca1 100644
--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies
@@ -33081,10 +33081,81 @@
}
{
- "error": {
- "class": "DeviceNotFound",
- "desc": "The libvirt device dump was not collected for this version+device tuple"
- },
+ "return": [
+ {
+ "default-value": 4294967295,
+ "name": "scsi-id",
+ "type": "uint32"
+ },
+ {
+ "default-value": 4294967295,
+ "name": "lun",
+ "type": "uint32"
+ },
+ {
+ "default-value": 0,
+ "name": "channel",
+ "type": "uint32"
+ },
+ {
+ "default-value": "auto",
+ "name": "rerror",
+ "description": "Error handling policy (report/ignore/enospc/stop/auto)",
+ "type": "BlockdevOnError"
+ },
+ {
+ "default-value": 2147483647,
+ "name": "max_io_size",
+ "type": "uint64"
+ },
+ {
+ "default-value": false,
+ "name": "share-rw",
+ "description": "on/off",
+ "type": "bool"
+ },
+ {
+ "default-value": true,
+ "name": "migrate-pr",
+ "description": "on/off",
+ "type": "bool"
+ },
+ {
+ "default-value": "auto",
+ "name": "werror",
+ "description": "Error handling policy (report/ignore/enospc/stop/auto)",
+ "type": "BlockdevOnError"
+ },
+ {
+ "default-value": 1073741824,
+ "name": "max_unmap_size",
+ "type": "uint64"
+ },
+ {
+ "default-value": -1,
+ "name": "scsi_version",
+ "type": "int32"
+ },
+ {
+ "default-value": 0,
+ "name": "rotation_rate",
+ "type": "uint16"
+ },
+ {
+ "name": "drive",
+ "description": "Node name or ID of a block device to use as a backend",
+ "type": "str"
+ },
+ {
+ "default-value": 30,
+ "name": "io_timeout",
+ "type": "uint32"
+ },
+ {
+ "name": "bootindex",
+ "type": "int32"
+ }
+ ],
"id": "libvirt-37"
}
diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml
index 7cff2c2291..7d5a75ce88 100644
--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml
@@ -215,6 +215,7 @@
<flag name='acpi-generic-initiator'/>
<flag name='disk-timed-stats'/>
<flag name='query-accelerators'/>
+ <flag name='scsi-block.migrate-pr'/>
<version>10001091</version>
<microcodeVersion>43100287</microcodeVersion>
<package>v10.2.0-rc1-38-gfb241d0a1f</package>
--
2.53.0

View File

@ -1,176 +0,0 @@
From 5ef229b0035c34fd9b67183d6f0a2b810cc47907 Mon Sep 17 00:00:00 2001
Message-ID: <5ef229b0035c34fd9b67183d6f0a2b810cc47907.1752837271.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 27 Jun 2025 14:47:10 +0200
Subject: [PATCH] cgroup: Plumb the 'daemonDomainShutdown' parameter of
'virSystemdCreateMachine' to drivers
Plumb the new argument across the cgroup helpers up to the domain driver
code.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit fe57a6deaa8ab83ffdb8ed73104196e4b1421893)
https://issues.redhat.com/browse/RHEL-95361
---
src/ch/ch_process.c | 2 ++
src/hypervisor/domain_cgroup.c | 4 ++++
src/hypervisor/domain_cgroup.h | 1 +
src/lxc/lxc_cgroup.c | 1 +
src/qemu/qemu_cgroup.c | 1 +
src/util/vircgroup.c | 6 +++++-
src/util/vircgroup.h | 1 +
7 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c
index 95c808cb41..cc84823fdc 100644
--- a/src/ch/ch_process.c
+++ b/src/ch/ch_process.c
@@ -973,6 +973,7 @@ virCHProcessStart(virCHDriver *driver,
cfg->cgroupControllers,
0, /*maxThreadsPerProc*/
priv->driver->privileged,
+ false,
priv->machineName) < 0)
goto cleanup;
@@ -1147,6 +1148,7 @@ virCHProcessStartRestore(virCHDriver *driver, virDomainObj *vm, const char *from
cfg->cgroupControllers,
0, /*maxThreadsPerProc*/
priv->driver->privileged,
+ false,
priv->machineName) < 0)
goto cleanup;
diff --git a/src/hypervisor/domain_cgroup.c b/src/hypervisor/domain_cgroup.c
index fecc0f7966..8787165f48 100644
--- a/src/hypervisor/domain_cgroup.c
+++ b/src/hypervisor/domain_cgroup.c
@@ -351,6 +351,7 @@ virDomainCgroupInitCgroup(const char *prefix,
int cgroupControllers,
unsigned int maxThreadsPerProc,
bool privileged,
+ bool daemonDomainShutdown,
char *machineName)
{
if (!privileged)
@@ -384,6 +385,7 @@ virDomainCgroupInitCgroup(const char *prefix,
vm->def->resource->partition,
cgroupControllers,
maxThreadsPerProc,
+ daemonDomainShutdown,
cgroup) < 0) {
if (virCgroupNewIgnoreError())
return 0;
@@ -513,6 +515,7 @@ virDomainCgroupSetupCgroup(const char *prefix,
int cgroupControllers,
unsigned int maxThreadsPerProc,
bool privileged,
+ bool daemonDomainShutdown,
char *machineName)
{
if (vm->pid == 0) {
@@ -529,6 +532,7 @@ virDomainCgroupSetupCgroup(const char *prefix,
cgroupControllers,
maxThreadsPerProc,
privileged,
+ daemonDomainShutdown,
machineName) < 0)
return -1;
diff --git a/src/hypervisor/domain_cgroup.h b/src/hypervisor/domain_cgroup.h
index 6e5c98004e..7769572a2c 100644
--- a/src/hypervisor/domain_cgroup.h
+++ b/src/hypervisor/domain_cgroup.h
@@ -71,6 +71,7 @@ virDomainCgroupSetupCgroup(const char *prefix,
int cgroupControllers,
unsigned int maxThreadsPerProc,
bool privileged,
+ bool daemonDomainShutdown,
char *machineName);
void
virDomainCgroupEmulatorAllNodesDataFree(virCgroupEmulatorAllNodesData *data);
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 7c889667ba..f566a5468e 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -400,6 +400,7 @@ virCgroup *virLXCCgroupCreate(virDomainDef *def,
def->resource->partition,
-1,
0,
+ false,
&cgroup) < 0)
return NULL;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 48af467bf9..04d6370011 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -919,6 +919,7 @@ qemuSetupCgroup(virDomainObj *vm,
cfg->cgroupControllers,
cfg->maxThreadsPerProc,
priv->driver->privileged,
+ false,
priv->machineName) < 0)
return -1;
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index fc5dca4858..532a7e5690 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1274,6 +1274,7 @@ virCgroupNewMachineSystemd(const char *name,
const char *partition,
int controllers,
unsigned int maxthreads,
+ bool daemonDomainShutdown,
virCgroup **group)
{
int rv;
@@ -1294,7 +1295,7 @@ virCgroupNewMachineSystemd(const char *name,
nicindexes,
partition,
maxthreads,
- false)) < 0)
+ daemonDomainShutdown)) < 0)
return rv;
if (controllers != -1)
@@ -1407,6 +1408,7 @@ virCgroupNewMachine(const char *name,
const char *partition,
int controllers,
unsigned int maxthreads,
+ bool daemonDomainShutdown,
virCgroup **group)
{
int rv;
@@ -1424,6 +1426,7 @@ virCgroupNewMachine(const char *name,
partition,
controllers,
maxthreads,
+ daemonDomainShutdown,
group)) == 0)
return 0;
@@ -3144,6 +3147,7 @@ virCgroupNewMachine(const char *name G_GNUC_UNUSED,
const char *partition G_GNUC_UNUSED,
int controllers G_GNUC_UNUSED,
unsigned int maxthreads G_GNUC_UNUSED,
+ bool daemonDomainShutdown G_GNUC_UNUSED,
virCgroup **group G_GNUC_UNUSED)
{
virReportSystemError(ENXIO, "%s",
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index adf3850b22..2a7aa3306c 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -101,6 +101,7 @@ int virCgroupNewMachine(const char *name,
const char *partition,
int controllers,
unsigned int maxthreads,
+ bool daemonDomainShutdown,
virCgroup **group)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
ATTRIBUTE_NONNULL(3);
--
2.50.1

View File

@ -1,68 +0,0 @@
From c7889487359bff14c6d4b236055acfee68da66ae Mon Sep 17 00:00:00 2001
Message-ID: <c7889487359bff14c6d4b236055acfee68da66ae.1752837271.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 26 Jun 2025 18:24:06 +0200
Subject: [PATCH] cgroup: Unexport 'virDomainCgroupInitCgroup'
The function is called just from one place within the module where it's
defined.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 3e0859566a164f640e75889d08241844b5e61bf8)
https://issues.redhat.com/browse/RHEL-95361
---
src/hypervisor/domain_cgroup.c | 2 +-
src/hypervisor/domain_cgroup.h | 10 ----------
src/libvirt_private.syms | 1 -
3 files changed, 1 insertion(+), 12 deletions(-)
diff --git a/src/hypervisor/domain_cgroup.c b/src/hypervisor/domain_cgroup.c
index fda495faf5..fecc0f7966 100644
--- a/src/hypervisor/domain_cgroup.c
+++ b/src/hypervisor/domain_cgroup.c
@@ -342,7 +342,7 @@ virDomainCgroupSetupCpuCgroup(virDomainObj *vm,
}
-int
+static int
virDomainCgroupInitCgroup(const char *prefix,
virDomainObj *vm,
size_t nnicindexes,
diff --git a/src/hypervisor/domain_cgroup.h b/src/hypervisor/domain_cgroup.h
index f8d261a080..6e5c98004e 100644
--- a/src/hypervisor/domain_cgroup.h
+++ b/src/hypervisor/domain_cgroup.h
@@ -52,16 +52,6 @@ virDomainCgroupSetupCpusetCgroup(virCgroup *cgroup);
int
virDomainCgroupSetupCpuCgroup(virDomainObj *vm,
virCgroup *cgroup);
-int
-virDomainCgroupInitCgroup(const char *prefix,
- virDomainObj *vm,
- size_t nnicindexes,
- int *nicindexes,
- virCgroup **cgroup,
- int cgroupControllers,
- unsigned int maxThreadsPerProc,
- bool privileged,
- char *machineName);
void
virDomainCgroupRestoreCgroupState(virDomainObj *vm,
virCgroup *cgroup);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a8ebf9efd8..8f1489ecc8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1641,7 +1641,6 @@ virSetConnectStorage;
virDomainCgroupConnectCgroup;
virDomainCgroupEmulatorAllNodesAllow;
virDomainCgroupEmulatorAllNodesRestore;
-virDomainCgroupInitCgroup;
virDomainCgroupRemoveCgroup;
virDomainCgroupSetMemoryLimitParameters;
virDomainCgroupSetupBlkio;
--
2.50.1

View File

@ -1,141 +0,0 @@
From 19ca835c960b1b391d7926a5c860b73d2751a555 Mon Sep 17 00:00:00 2001
Message-ID: <19ca835c960b1b391d7926a5c860b73d2751a555.1759908360.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-111863
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 d2f01a9397..3eb3ab35f1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3963,6 +3963,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:
@@ -14210,6 +14211,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)
@@ -14229,7 +14257,7 @@ virDomainTDXDefParseXML(virDomainTDXDef *def,
def->mrowner = virXPathString("string(./mrOwner)", ctxt);
def->mrownerconfig = virXPathString("string(./mrOwnerConfig)", ctxt);
- return 0;
+ return virDomainTDXQGSDefParseXML(def, ctxt);
}
@@ -27746,6 +27774,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 51c05a3f18..cf5437f642 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3005,6 +3005,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 56dbddcb43..0e13f79e99 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -673,6 +673,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,85 @@
From 271cfe0d7954d5398af307b24fc5b601977975b8 Mon Sep 17 00:00:00 2001
Message-ID: <271cfe0d7954d5398af307b24fc5b601977975b8.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Mon, 9 Feb 2026 21:28:50 +0100
Subject: [PATCH] conf: Add firmwareFeatures element for domaincaps
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 928bdc3e67b29ff2314ff538905703e299b1e47e)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/conf/domain_capabilities.c | 15 +++++++++++++++
src/conf/domain_capabilities.h | 8 ++++++++
2 files changed, 23 insertions(+)
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index 49179b97ab..9b3577cd08 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -422,6 +422,19 @@ virDomainCapsFeatureFormatSimple(virBuffer *buf,
}
+static void
+virDomainCapsFirmwareFeaturesFormat(virBuffer *buf,
+ const virDomainCapsFirmwareFeatures *firmwareFeatures)
+{
+ FORMAT_PROLOGUE(firmwareFeatures);
+
+ ENUM_PROCESS(firmwareFeatures, secureBoot, virTristateBoolTypeToString);
+ ENUM_PROCESS(firmwareFeatures, enrolledKeys, virTristateBoolTypeToString);
+
+ FORMAT_EPILOGUE(firmwareFeatures);
+}
+
+
static void
virDomainCapsLoaderFormat(virBuffer *buf,
const virDomainCapsLoader *loader)
@@ -440,12 +453,14 @@ static void
virDomainCapsOSFormat(virBuffer *buf,
const virDomainCapsOS *os)
{
+ const virDomainCapsFirmwareFeatures *firmwareFeatures = &os->firmwareFeatures;
const virDomainCapsLoader *loader = &os->loader;
FORMAT_PROLOGUE(os);
ENUM_PROCESS(os, firmware, virDomainOsDefFirmwareTypeToString);
+ virDomainCapsFirmwareFeaturesFormat(&childBuf, firmwareFeatures);
virDomainCapsLoaderFormat(&childBuf, loader);
FORMAT_EPILOGUE(os);
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index b10370db8f..a68fafe235 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -43,6 +43,13 @@ struct _virDomainCapsStringValues {
size_t nvalues; /* number of strings */
};
+typedef struct _virDomainCapsFirmwareFeatures virDomainCapsFirmwareFeatures;
+struct _virDomainCapsFirmwareFeatures {
+ virTristateBool supported;
+ virDomainCapsEnum secureBoot;
+ virDomainCapsEnum enrolledKeys;
+};
+
STATIC_ASSERT_ENUM(VIR_DOMAIN_LOADER_TYPE_LAST);
STATIC_ASSERT_ENUM(VIR_TRISTATE_BOOL_LAST);
typedef struct _virDomainCapsLoader virDomainCapsLoader;
@@ -59,6 +66,7 @@ typedef struct _virDomainCapsOS virDomainCapsOS;
struct _virDomainCapsOS {
virTristateBool supported;
virDomainCapsEnum firmware; /* Info about virDomainOsDefFirmware */
+ virDomainCapsFirmwareFeatures firmwareFeatures;
virDomainCapsLoader loader; /* Info about virDomainLoaderDef */
};
--
2.53.0

View File

@ -0,0 +1,160 @@
From e16fe9c7fa885a36df0be1967d248808a5bc1fb5 Mon Sep 17 00:00:00 2001
Message-ID: <e16fe9c7fa885a36df0be1967d248808a5bc1fb5.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 15:28:17 +0100
Subject: [PATCH] conf: Add iommufd fdgroup support
This will allow management applications running libvirt without
necessary permissions to pass FD for /dev/iommu with per-process
locked memory accounting enabled.
Kernel uses per-user locked memory accounting by default which may
cause error while starting multiple VMs with host devices using IOMMUFD.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 58875a6df679c5272f61028d33bf1380c51b0d5b)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
docs/formatdomain.rst | 8 +++++++-
src/conf/domain_conf.c | 6 ++++++
src/conf/domain_conf.h | 1 +
src/conf/domain_validate.c | 16 ++++++++++++++++
src/conf/schemas/domaincommon.rng | 3 +++
tests/genericxml2xmlindata/iommufd.xml | 2 +-
6 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 20ea10bd35..cdcf164253 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1389,7 +1389,7 @@ Host Device IOMMUFD
<domain>
...
- <iommufd enabled='yes'/>
+ <iommufd enabled='yes' fdgroup='iommu'/>
...
</domain>
@@ -1403,6 +1403,12 @@ Host Device IOMMUFD
This controls IOMMUFD usage for all host devices, each device can change this
global default by setting ``iommufd`` attribute for ``driver`` element.
+ Optional ``fdgroup`` attribute can be used together with
+ `virDomainFDAssociate <html/libvirt-libvirt-domain.html#virDomainFDAssociate>`__
+ to pass /dev/iommu FD instead of letting libvirt to open it. Caller is
+ responsible for setting per-process locked memory accounting otherwise
+ starting multiple VMs with host devices using IOMMUFD may fail.
+
Resource partitioning
---------------------
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 59908d9da6..452985c9ba 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4214,6 +4214,8 @@ void virDomainDefFree(virDomainDef *def)
g_free(def->kvm_features);
g_free(def->tcg_features);
+ g_free(def->iommufd_fdgroup);
+
virBlkioDeviceArrayClear(def->blkio.devices,
def->blkio.ndevices);
g_free(def->blkio.devices);
@@ -19795,6 +19797,8 @@ virDomainDefIommufdParse(virDomainDef *def,
if (virXMLPropTristateBool(nodes[0], "enabled", VIR_XML_PROP_REQUIRED, &def->iommufd) < 0)
return -1;
+ def->iommufd_fdgroup = virXMLPropString(nodes[0], "fdgroup");
+
return 0;
}
@@ -28028,6 +28032,8 @@ virDomainDefIommufdFormat(virBuffer *buf,
virBufferAsprintf(&attrBuf, " enabled='%s'",
virTristateBoolTypeToString(def->iommufd));
+ virBufferEscapeString(&attrBuf, " fdgroup='%s'", def->iommufd_fdgroup);
+
virXMLFormatElement(buf, "iommufd", &attrBuf, NULL);
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 145084e4fd..ba22fc347d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3241,6 +3241,7 @@ struct _virDomainDef {
virDomainFeatureTCG *tcg_features;
virTristateBool iommufd;
+ char *iommufd_fdgroup;
bool tseg_specified;
unsigned long long tseg_size;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 163095d55c..e400f80da3 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2003,6 +2003,19 @@ virDomainDefValidateThrottleGroups(const virDomainDef *def)
}
+static int
+virDomainDefValidateIommufd(const virDomainDef *def)
+{
+ if (def->iommufd == VIR_TRISTATE_BOOL_NO && def->iommufd_fdgroup) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Setting 'fdgroup' when 'iommufd' is disabled is not supported."));
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
virDomainDefValidateInternal(const virDomainDef *def,
virDomainXMLOption *xmlopt)
@@ -2064,6 +2077,9 @@ virDomainDefValidateInternal(const virDomainDef *def,
if (virDomainDefValidateThrottleGroups(def) < 0)
return -1;
+ if (virDomainDefValidateIommufd(def) < 0)
+ return -1;
+
return 0;
}
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index de505e6c49..3c3013baec 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1377,6 +1377,9 @@
<attribute name="enabled">
<ref name="virYesNo"/>
</attribute>
+ <optional>
+ <attribute name="fdgroup"/>
+ </optional>
</element>
</define>
diff --git a/tests/genericxml2xmlindata/iommufd.xml b/tests/genericxml2xmlindata/iommufd.xml
index 63ea839383..10d59ca548 100644
--- a/tests/genericxml2xmlindata/iommufd.xml
+++ b/tests/genericxml2xmlindata/iommufd.xml
@@ -4,7 +4,7 @@
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
- <iommufd enabled='yes'/>
+ <iommufd enabled='yes' fdgroup='iommu'/>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
--
2.53.0

View File

@ -1,376 +0,0 @@
From c7f940ba807d0d4883adb9a110839bea704278e2 Mon Sep 17 00:00:00 2001
Message-ID: <c7f940ba807d0d4883adb9a110839bea704278e2.1759908360.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:09 -0400
Subject: [PATCH] conf: Add tdx as launch security type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When 'tdx' is used, the VM will be launched with Intel TDX feature enabled.
TDX feature supports running encrypted VM (Trust Domain, TD) under the
control of KVM. A TD runs in a CPU model which protects the confidentiality
of its memory and its CPU state from other software.
There are four optional child elements. Element policy is 64bit hex, bit 0
is set to enable TDX debug, bit 28 is set to enable sept-ve-disable, other
bits are reserved currently. When policy isn't specified, QEMU will use its
own default value 0x10000000. mrConfigId, mrOwner and mrOwnerConfig are
base64 encoded SHA384 digest string.
For example:
<launchSecurity type='tdx'>
<policy>0x10000001</policy>
<mrConfigId>xxx</mrConfigId>
<mrOwner>xxx</mrOwner>
<mrOwnerConfig>xxx</mrOwnerConfig>
</launchSecurity>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit e919a4dd374535511d962bee2cd64f22f1ac3fa1)
Resolves: https://issues.redhat.com/browse/RHEL-111863
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/conf/domain_conf.c | 49 +++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 11 +++++++
src/conf/domain_validate.c | 1 +
src/conf/schemas/domaincommon.rng | 32 ++++++++++++++++++++
src/conf/virconftypes.h | 2 ++
src/qemu/qemu_cgroup.c | 1 +
src/qemu/qemu_command.c | 2 ++
src/qemu/qemu_driver.c | 1 +
src/qemu/qemu_firmware.c | 1 +
src/qemu/qemu_namespace.c | 1 +
src/qemu/qemu_process.c | 2 ++
src/qemu/qemu_validate.c | 1 +
src/security/security_dac.c | 2 ++
13 files changed, 106 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1e24e41a48..d2f01a9397 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1543,6 +1543,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
"sev",
"sev-snp",
"s390-pv",
+ "tdx",
);
VIR_ENUM_IMPL(virDomainPstoreBackend,
@@ -3958,6 +3959,11 @@ virDomainSecDefFree(virDomainSecDef *def)
g_free(def->data.sev_snp.id_auth);
g_free(def->data.sev_snp.host_data);
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ g_free(def->data.tdx.mrconfigid);
+ g_free(def->data.tdx.mrowner);
+ g_free(def->data.tdx.mrownerconfig);
+ break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -14204,6 +14210,29 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def,
}
+static int
+virDomainTDXDefParseXML(virDomainTDXDef *def,
+ xmlXPathContextPtr ctxt)
+{
+ int rc;
+
+ rc = virXPathULongLongBase("string(./policy)", ctxt, 16, &def->policy);
+ if (rc == 0) {
+ def->havePolicy = true;
+ } else if (rc == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("failed to get launch security policy for launch security type TDX"));
+ return -1;
+ }
+
+ def->mrconfigid = virXPathString("string(./mrConfigId)", ctxt);
+ def->mrowner = virXPathString("string(./mrOwner)", ctxt);
+ def->mrownerconfig = virXPathString("string(./mrOwnerConfig)", ctxt);
+
+ return 0;
+}
+
+
static virDomainSecDef *
virDomainSecDefParseXML(xmlNodePtr lsecNode,
xmlXPathContextPtr ctxt)
@@ -14227,6 +14256,10 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
if (virDomainSEVSNPDefParseXML(&sec->data.sev_snp, ctxt) < 0)
return NULL;
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ if (virDomainTDXDefParseXML(&sec->data.tdx, ctxt) < 0)
+ return NULL;
+ break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
@@ -27704,6 +27737,18 @@ virDomainSEVSNPDefFormat(virBuffer *attrBuf,
}
+static void
+virDomainTDXDefFormat(virBuffer *childBuf, virDomainTDXDef *def)
+{
+ if (def->havePolicy)
+ virBufferAsprintf(childBuf, "<policy>0x%llx</policy>\n", def->policy);
+
+ virBufferEscapeString(childBuf, "<mrConfigId>%s</mrConfigId>\n", def->mrconfigid);
+ virBufferEscapeString(childBuf, "<mrOwner>%s</mrOwner>\n", def->mrowner);
+ virBufferEscapeString(childBuf, "<mrOwnerConfig>%s</mrOwnerConfig>\n", def->mrownerconfig);
+}
+
+
static void
virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec)
{
@@ -27725,6 +27770,10 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec)
virDomainSEVSNPDefFormat(&attrBuf, &childBuf, &sec->data.sev_snp);
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ virDomainTDXDefFormat(&childBuf, &sec->data.tdx);
+ break;
+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6997cf7c09..e216c63018 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2964,6 +2964,7 @@ typedef enum {
VIR_DOMAIN_LAUNCH_SECURITY_SEV,
VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP,
VIR_DOMAIN_LAUNCH_SECURITY_PV,
+ VIR_DOMAIN_LAUNCH_SECURITY_TDX,
VIR_DOMAIN_LAUNCH_SECURITY_LAST,
} virDomainLaunchSecurity;
@@ -2998,11 +2999,21 @@ struct _virDomainSEVSNPDef {
};
+struct _virDomainTDXDef {
+ bool havePolicy;
+ unsigned long long policy;
+ char *mrconfigid;
+ char *mrowner;
+ char *mrownerconfig;
+};
+
+
struct _virDomainSecDef {
virDomainLaunchSecurity sectype;
union {
virDomainSEVDef sev;
virDomainSEVSNPDef sev_snp;
+ virDomainTDXDef tdx;
} data;
};
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index b28af7fa56..7d68ea2478 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1936,6 +1936,7 @@ virDomainDefLaunchSecurityValidate(const virDomainDef *def)
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
break;
}
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 183dd5db5e..56dbddcb43 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -549,6 +549,9 @@
<value>s390-pv</value>
</attribute>
</group>
+ <group>
+ <ref name="launchSecurityTDX"/>
+ </group>
</choice>
</element>
</define>
@@ -644,6 +647,35 @@
</optional>
</interleave>
</define>
+
+ <define name="launchSecurityTDX">
+ <attribute name="type">
+ <value>tdx</value>
+ </attribute>
+ <interleave>
+ <optional>
+ <element name="policy">
+ <ref name="hexuint"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="mrConfigId">
+ <data type="string"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="mrOwner">
+ <data type="string"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="mrOwnerConfig">
+ <data type="string"/>
+ </element>
+ </optional>
+ </interleave>
+ </define>
+
<!--
Enable or disable perf events for the domain. For each
of the events the following rules apply:
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index 8c6fcdbeaa..93fc9c9217 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -220,6 +220,8 @@ typedef struct _virDomainSEVDef virDomainSEVDef;
typedef struct _virDomainSEVSNPDef virDomainSEVSNPDef;
+typedef struct _virDomainTDXDef virDomainTDXDef;
+
typedef struct _virDomainSecDef virDomainSecDef;
typedef struct _virDomainShmemDef virDomainShmemDef;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 25e42ebfc6..f10976c2b0 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -863,6 +863,7 @@ qemuSetupDevicesCgroup(virDomainObj *vm)
return -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 662d6299f8..5a52014c23 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7189,6 +7189,7 @@ qemuBuildMachineCommandLine(virCommand *cmd,
}
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
virBufferAddLit(&buf, ",confidential-guest-support=lsec0");
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
@@ -9968,6 +9969,7 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
return qemuBuildPVCommandLine(cmd);
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4dbd5ec2fc..514fc372ac 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19273,6 +19273,7 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
goto cleanup;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index 2d0ec0b4fa..6c65a2751b 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -1371,6 +1371,7 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
}
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index 59421ec9d1..f72da83929 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -665,6 +665,7 @@ qemuDomainSetupLaunchSecurity(virDomainObj *vm,
VIR_DEBUG("Set up launch security for SEV");
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 82cab3f76e..529c65b9b0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6872,6 +6872,7 @@ qemuProcessPrepareDomain(virQEMUDriver *driver,
return -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -6944,6 +6945,7 @@ qemuProcessPrepareLaunchSecurityGuestInput(virDomainObj *vm)
case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
return 0;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 57dc4171fe..93e191dd13 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1413,6 +1413,7 @@ qemuValidateDomainDef(const virDomainDef *def,
return -1;
}
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, def->sec->sectype);
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 3ecbc7277d..2f788b872a 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -2017,6 +2017,7 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr,
rc = -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -2263,6 +2264,7 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr,
return -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
--
2.51.0

View File

@ -1,162 +0,0 @@
From 1a961ed1747a4f40923005fd5b13c86908266a24 Mon Sep 17 00:00:00 2001
Message-ID: <1a961ed1747a4f40923005fd5b13c86908266a24.1759908360.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-111863
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 f7cce92ca1..f29c4e0515 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 60d5fe77de..43141dbdd5 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -281,6 +281,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 8bc34691c7..7edae54931 100644
--- a/src/conf/schemas/domaincaps.rng
+++ b/src/conf/schemas/domaincaps.rng
@@ -367,6 +367,9 @@
<optional>
<ref name="ps2"/>
</optional>
+ <optional>
+ <ref name="tdx"/>
+ </optional>
<optional>
<ref name="sev"/>
</optional>
@@ -431,6 +434,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 3def894a22..f4f77a491c 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -7012,6 +7012,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(virQEMUDriverConfig *cfg,
virQEMUCaps *qemuCaps,
@@ -7076,6 +7088,7 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
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 2bca47b8b1..61aa1aafd0 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
@@ -739,6 +739,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 ffa95830f4..6048a66b87 100644
--- a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
@@ -739,6 +739,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

@ -1,90 +0,0 @@
From b349d91f45f77f2936ea9461ac221b672261e2a7 Mon Sep 17 00:00:00 2001
Message-ID: <b349d91f45f77f2936ea9461ac221b672261e2a7.1759908360.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-111863
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
RHEL: missing 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 f4f77a491c..d2b59ba1f4 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6776,6 +6776,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 61aa1aafd0..fafa28ecbe 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
@@ -774,6 +774,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 1d2795c4df..eba8023fc8 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
@@ -1821,6 +1821,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 6048a66b87..9ea7d779b5 100644
--- a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
@@ -774,6 +774,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,140 @@
From af94300604718604a70a5d587e56187ffe5e6557 Mon Sep 17 00:00:00 2001
Message-ID: <af94300604718604a70a5d587e56187ffe5e6557.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 30 Jan 2026 17:46:30 +0100
Subject: [PATCH] conf: Include varstore element in domcaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We want to advertise whether the element is usable when
defining new domains.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 3d6987914bb10beb11b9eb5e83ec2194dfab1659)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
docs/formatdomaincaps.rst | 7 +++++++
src/conf/domain_capabilities.c | 10 ++++++++++
src/conf/domain_capabilities.h | 6 ++++++
src/conf/schemas/domaincaps.rng | 9 +++++++++
4 files changed, 32 insertions(+)
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index 3426b7c9cd..5a1d3f2670 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -141,6 +141,7 @@ domains.
<value>no</value>
</enum>
</loader>
+ <varstore supported='yes'/>
</os>
...
<domainCapabilities>
@@ -227,6 +228,12 @@ are the following:
possible to enforce Secure Boot, look at the ``enrolledKeys`` enum inside
the ``<firmwareFeatures/>`` element instead.
+The ``<varstore/>`` element :since:`(since 12.1.0)` indicates whether UEFI
+variable storage backed by the ``uefi-vars`` QEMU device can be used as an
+alternative to pflash-based NVRAM storage. This is the only type of variable
+storage compatible with Secure Boot on non-x86 architectures, but it can be
+used on x86 too.
+
CPU configuration
~~~~~~~~~~~~~~~~~
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index 9b3577cd08..78b8e6e6e1 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -449,12 +449,21 @@ virDomainCapsLoaderFormat(virBuffer *buf,
FORMAT_EPILOGUE(loader);
}
+static void
+virDomainCapsVarstoreFormat(virBuffer *buf,
+ const virDomainCapsVarstore *varstore)
+{
+ FORMAT_PROLOGUE(varstore);
+ FORMAT_EPILOGUE(varstore);
+}
+
static void
virDomainCapsOSFormat(virBuffer *buf,
const virDomainCapsOS *os)
{
const virDomainCapsFirmwareFeatures *firmwareFeatures = &os->firmwareFeatures;
const virDomainCapsLoader *loader = &os->loader;
+ const virDomainCapsVarstore *varstore = &os->varstore;
FORMAT_PROLOGUE(os);
@@ -462,6 +471,7 @@ virDomainCapsOSFormat(virBuffer *buf,
virDomainCapsFirmwareFeaturesFormat(&childBuf, firmwareFeatures);
virDomainCapsLoaderFormat(&childBuf, loader);
+ virDomainCapsVarstoreFormat(&childBuf, varstore);
FORMAT_EPILOGUE(os);
}
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index a68fafe235..02344fd9b6 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -61,6 +61,11 @@ struct _virDomainCapsLoader {
virDomainCapsEnum secure; /* Info about secure:virTristateBool */
};
+typedef struct _virDomainCapsVarstore virDomainCapsVarstore;
+struct _virDomainCapsVarstore {
+ virTristateBool supported;
+};
+
STATIC_ASSERT_ENUM(VIR_DOMAIN_OS_DEF_FIRMWARE_LAST);
typedef struct _virDomainCapsOS virDomainCapsOS;
struct _virDomainCapsOS {
@@ -68,6 +73,7 @@ struct _virDomainCapsOS {
virDomainCapsEnum firmware; /* Info about virDomainOsDefFirmware */
virDomainCapsFirmwareFeatures firmwareFeatures;
virDomainCapsLoader loader; /* Info about virDomainLoaderDef */
+ virDomainCapsVarstore varstore;
};
STATIC_ASSERT_ENUM(VIR_DOMAIN_MEMORY_SOURCE_LAST);
diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng
index 3b24caeca6..4682abbf41 100644
--- a/src/conf/schemas/domaincaps.rng
+++ b/src/conf/schemas/domaincaps.rng
@@ -87,6 +87,12 @@
</element>
</define>
+ <define name="varstore">
+ <element name="varstore">
+ <ref name="supported"/>
+ </element>
+ </define>
+
<define name="os">
<element name="os">
<interleave>
@@ -98,6 +104,9 @@
<optional>
<ref name="loader"/>
</optional>
+ <optional>
+ <ref name="varstore"/>
+ </optional>
</interleave>
</element>
</define>
--
2.53.0

View File

@ -0,0 +1,218 @@
From fdb3a965d8cea1b1fcaf91504d1e5447ae7b6358 Mon Sep 17 00:00:00 2001
Message-ID: <fdb3a965d8cea1b1fcaf91504d1e5447ae7b6358.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 11:57:57 +0100
Subject: [PATCH] conf: Introduce domain iommufd element
In addition to configuring IOMMUFD for each host device add
configuration for the whole VM. This will be extended to add support for
passing FD to libvirt from management applications.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit c03b8f0804f648a2bbc2eb7e957f2f8821b8e167)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
docs/formatdomain.rst | 21 ++++++++++++
src/conf/domain_conf.c | 46 ++++++++++++++++++++++++++
src/conf/domain_conf.h | 2 ++
src/conf/schemas/domaincommon.rng | 12 +++++++
tests/genericxml2xmlindata/iommufd.xml | 18 ++++++++++
tests/genericxml2xmltest.c | 2 ++
6 files changed, 101 insertions(+)
create mode 100644 tests/genericxml2xmlindata/iommufd.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index ff07f2fc17..20ea10bd35 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1382,6 +1382,27 @@ Block I/O Tuning
``write_iops_sec``
Write I/O operations per second limit. :since:`Since 1.2.2`
+Host Device IOMMUFD
+-------------------
+
+::
+
+ <domain>
+ ...
+ <iommufd enabled='yes'/>
+ ...
+ </domain>
+
+``iommufd``
+ :since:`Since 12.2.0 (QEMU/KVM only)` The optional ``iommufd`` element with
+ mandatory ``enabled`` attribute can be used to enable IOMMUFD backend for
+ VFIO host devices. This provides an interface to propagate DMA mappings to
+ kernel for assigned devices. Libvirt will open the /dev/iommu and VFIO device
+ cdev and pass associated file descriptors to QEMU.
+
+ This controls IOMMUFD usage for all host devices, each device can change this
+ global default by setting ``iommufd`` attribute for ``driver`` element.
+
Resource partitioning
---------------------
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d029fc01ea..59908d9da6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19773,6 +19773,31 @@ virDomainDefControllersParse(virDomainDef *def,
return 0;
}
+static int
+virDomainDefIommufdParse(virDomainDef *def,
+ xmlXPathContextPtr ctxt)
+{
+ int n;
+ g_autofree xmlNodePtr *nodes = NULL;
+
+ if ((n = virXPathNodeSet("./iommufd", ctxt, &nodes)) < 0)
+ return -1;
+
+ if (n > 1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one 'iommufd' element is supported"));
+ return -1;
+ }
+
+ if (n == 0)
+ return 0;
+
+ if (virXMLPropTristateBool(nodes[0], "enabled", VIR_XML_PROP_REQUIRED, &def->iommufd) < 0)
+ return -1;
+
+ return 0;
+}
+
static virDomainDef *
virDomainDefParseXML(xmlXPathContextPtr ctxt,
virDomainXMLOption *xmlopt,
@@ -19851,6 +19876,9 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
!virDomainIOThreadIDArrayHasPin(def))
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
+ if (virDomainDefIommufdParse(def, ctxt) < 0)
+ return NULL;
+
if ((n = virXPathNodeSet("./resource", ctxt, &nodes)) < 0)
return NULL;
@@ -27988,6 +28016,22 @@ virDomainHubDefFormat(virBuffer *buf,
}
+static void
+virDomainDefIommufdFormat(virBuffer *buf,
+ virDomainDef *def)
+{
+ g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+
+ if (def->iommufd == VIR_TRISTATE_BOOL_ABSENT)
+ return;
+
+ virBufferAsprintf(&attrBuf, " enabled='%s'",
+ virTristateBoolTypeToString(def->iommufd));
+
+ virXMLFormatElement(buf, "iommufd", &attrBuf, NULL);
+}
+
+
static void
virDomainResourceDefFormat(virBuffer *buf,
virDomainResourceDef *def)
@@ -29526,6 +29570,8 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
if (virDomainNumatuneFormatXML(buf, def->numa) < 0)
return -1;
+ virDomainDefIommufdFormat(buf, def);
+
virDomainResourceDefFormat(buf, def->resource);
for (i = 0; i < def->nsysinfo; i++) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a1cc2f05ac..145084e4fd 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3240,6 +3240,8 @@ struct _virDomainDef {
virTristateSwitch apic_eoi;
virDomainFeatureTCG *tcg_features;
+ virTristateBool iommufd;
+
bool tseg_specified;
unsigned long long tseg_size;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index fa7220deae..de505e6c49 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1025,6 +1025,10 @@
<ref name="numatune"/>
</optional>
+ <optional>
+ <ref name="iommufd"/>
+ </optional>
+
<optional>
<ref name="respartition"/>
</optional>
@@ -1368,6 +1372,14 @@
</element>
</define>
+ <define name="iommufd">
+ <element name="iommufd">
+ <attribute name="enabled">
+ <ref name="virYesNo"/>
+ </attribute>
+ </element>
+ </define>
+
<define name="respartition">
<element name="resource">
<optional>
diff --git a/tests/genericxml2xmlindata/iommufd.xml b/tests/genericxml2xmlindata/iommufd.xml
new file mode 100644
index 0000000000..63ea839383
--- /dev/null
+++ b/tests/genericxml2xmlindata/iommufd.xml
@@ -0,0 +1,18 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <iommufd enabled='yes'/>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c
index 6757fc44de..6be694cac5 100644
--- a/tests/genericxml2xmltest.c
+++ b/tests/genericxml2xmltest.c
@@ -263,6 +263,8 @@ mymain(void)
DO_TEST("iothreadids");
+ DO_TEST("iommufd");
+
virObjectUnref(caps);
virObjectUnref(xmlopt);
--
2.53.0

View File

@ -0,0 +1,69 @@
From c0fbd0d516a2c4457789d158bfdea839255d0854 Mon Sep 17 00:00:00 2001
Message-ID: <c0fbd0d516a2c4457789d158bfdea839255d0854.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sat, 14 Feb 2026 06:14:20 +0100
Subject: [PATCH] conf: Introduce iommufd enum for domaincaps
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 855f8fe9e2454555ba84696750e0e1501dd5ba80)
Resolves: https://issues.redhat.com/browse/RHEL-148135
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
docs/formatdomaincaps.rst | 7 +++++++
src/conf/domain_capabilities.c | 1 +
src/conf/domain_capabilities.h | 1 +
3 files changed, 9 insertions(+)
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index 8b4f0ecff3..6ba7f84f96 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -461,6 +461,10 @@ Well, only if the following is enabled:
<value>vfio</value>
<value>xen</value>
</enum>
+ <enum name='iommufd'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
</hostdev>
</devices>
</domainCapabilities>
@@ -477,6 +481,9 @@ Well, only if the following is enabled:
``mode="capabilities"``.
``pciBackend``
Options for the ``name`` attribute of the <driver/> element.
+``iommufd``
+ Options for the ``iommufd`` attribute of the <driver/> element.
+ :since:`Since 12.1.0`
RNG device
^^^^^^^^^^
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index f843124695..49179b97ab 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -620,6 +620,7 @@ virDomainCapsDeviceHostdevFormat(virBuffer *buf,
ENUM_PROCESS(hostdev, subsysType, virDomainHostdevSubsysTypeToString);
ENUM_PROCESS(hostdev, capsType, virDomainHostdevCapsTypeToString);
ENUM_PROCESS(hostdev, pciBackend, virDeviceHostdevPCIDriverNameTypeToString);
+ ENUM_PROCESS(hostdev, iommufd, virTristateBoolTypeToString);
FORMAT_EPILOGUE(hostdev);
}
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 437981c711..b10370db8f 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -108,6 +108,7 @@ struct _virDomainCapsDeviceHostdev {
virDomainCapsEnum subsysType; /* Info about virDomainHostdevSubsysType */
virDomainCapsEnum capsType; /* Info about virDomainHostdevCapsType */
virDomainCapsEnum pciBackend; /* Info about virDomainHostdevSubsysPCIBackendType */
+ virDomainCapsEnum iommufd; /* Info about iommufd:virTristateBool */
/* add new fields here */
};
--
2.53.0

View File

@ -0,0 +1,132 @@
From 4e8fe2eb42b47a55e491a63e2600a24e0501fd1f Mon Sep 17 00:00:00 2001
Message-ID: <4e8fe2eb42b47a55e491a63e2600a24e0501fd1f.1771423658.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 18:19:56 +0100
Subject: [PATCH] conf: Introduce virDomainDefHasPCIHostdevWithIOMMUFD
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 4b176cfc3877cca882d63ab4ed446794d7a05722)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/domain_conf.c | 14 ++++++++++++++
src/conf/domain_conf.h | 3 +++
src/libvirt_private.syms | 1 +
src/qemu/qemu_command.c | 42 ++++++++++++----------------------------
4 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9ae48e9abc..cb047e5a3e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32482,6 +32482,20 @@ virDomainDefHasPCIHostdev(const virDomainDef *def)
}
+bool
+virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def)
+{
+ size_t i;
+
+ for (i = 0; i < def->nhostdevs; i++) {
+ if (virHostdevIsPCIDeviceWithIOMMUFD(def->hostdevs[i]))
+ return true;
+ }
+
+ return false;
+}
+
+
bool
virDomainDefHasMdevHostdev(const virDomainDef *def)
{
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d958ed04f9..69a8e79c6d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4655,6 +4655,9 @@ virDomainDefHasNVMeDisk(const virDomainDef *def);
bool
virDomainDefHasPCIHostdev(const virDomainDef *def);
+bool
+virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def);
+
bool
virDomainDefHasMdevHostdev(const virDomainDef *def);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 863e50ec4f..effe44fe57 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -348,6 +348,7 @@ virDomainDefHasNVMeDisk;
virDomainDefHasOldStyleROUEFI;
virDomainDefHasOldStyleUEFI;
virDomainDefHasPCIHostdev;
+virDomainDefHasPCIHostdevWithIOMMUFD;
virDomainDefHasTimer;
virDomainDefHasUSB;
virDomainDefHasVcpusOffline;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c8626e6d49..3119191413 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5349,43 +5349,25 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd,
const virDomainDef *def,
virDomainObj *vm)
{
- size_t i;
qemuDomainObjPrivate *priv = vm->privateData;
g_autofree char *fdstr = g_strdup_printf("%d", priv->iommufd);
+ g_autoptr(virJSONValue) props = NULL;
+ if (!virDomainDefHasPCIHostdevWithIOMMUFD(def))
+ return 0;
- for (i = 0; i < def->nhostdevs; i++) {
- virDomainHostdevDef *hostdev = def->hostdevs[i];
- virDomainHostdevSubsys *subsys = &hostdev->source.subsys;
- g_autoptr(virJSONValue) props = NULL;
+ virCommandPassFD(cmd, priv->iommufd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- continue;
+ priv->iommufd = -1;
- if (subsys->type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
- continue;
+ if (qemuMonitorCreateObjectProps(&props, "iommufd",
+ "iommufd0",
+ "S:fd", fdstr,
+ NULL) < 0)
+ return -1;
- if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED)
- continue;
-
- if (subsys->u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES)
- continue;
-
- virCommandPassFD(cmd, priv->iommufd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
-
- priv->iommufd = -1;
-
- if (qemuMonitorCreateObjectProps(&props, "iommufd",
- "iommufd0",
- "S:fd", fdstr,
- NULL) < 0)
- return -1;
-
- if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
- return -1;
-
- break;
- }
+ if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
+ return -1;
return 0;
}
--
2.53.0

View File

@ -0,0 +1,89 @@
From 615f11792c8988cfd6a30717dcc8d5d9174ea508 Mon Sep 17 00:00:00 2001
Message-ID: <615f11792c8988cfd6a30717dcc8d5d9174ea508.1771423658.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 18:19:23 +0100
Subject: [PATCH] conf: Introduce virHostdevIsPCIDeviceWithIOMMUFD
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 97eed30948e980be8b7552fff637e828768854e4)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/domain_conf.c | 15 +++++++++++++++
src/conf/domain_conf.h | 3 +++
src/libvirt_private.syms | 1 +
src/qemu/qemu_process.c | 5 +----
4 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 83c58ab5ff..9ae48e9abc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32758,6 +32758,21 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
}
+/**
+ * virHostdevIsPCIDeviceWithIOMMUFD:
+ * @hostdev: host device to check
+ *
+ * Returns true if @hostdev is a PCI device with IOMMUFD enabled, false otherwise.
+ */
+bool
+virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev)
+{
+ return virHostdevIsPCIDevice(hostdev) &&
+ hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
+ hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES;
+}
+
+
static void
virDomainObjGetMessagesIOErrorsSrc(virStorageSource *src,
const char *diskdst,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index b120d4a68e..d958ed04f9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4713,6 +4713,9 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev)
bool
virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
ATTRIBUTE_NONNULL(1);
+bool
+virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev)
+ ATTRIBUTE_NONNULL(1);
void
virDomainObjGetMessagesIOErrorsChain(virStorageSource *src,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9ae44e31b8..863e50ec4f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -812,6 +812,7 @@ virDomainQemuMonitorEventNew;
virDomainQemuMonitorEventStateRegisterID;
virHostdevIsMdevDevice;
virHostdevIsPCIDevice;
+virHostdevIsPCIDeviceWithIOMMUFD;
virHostdevIsSCSIDevice;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7e32325fa0..3bd81c55b3 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7732,10 +7732,7 @@ qemuProcessOpenVfioFds(virDomainObj *vm)
for (i = 0; i < vm->def->nhostdevs; i++) {
virDomainHostdevDef *hostdev = vm->def->hostdevs[i];
- if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
- hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
- hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
/* Open VFIO device FD */
if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
return -1;
--
2.53.0

View File

@ -0,0 +1,330 @@
From b7d7c4776180166108657519527e9036fb9f26d9 Mon Sep 17 00:00:00 2001
Message-ID: <b7d7c4776180166108657519527e9036fb9f26d9.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 16:59:01 +0100
Subject: [PATCH] conf: Move and rename virStorageSourceFDTuple object
Associating FD can be used by other parts of VM so rename it to generic
virDomainFDTuple.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit f89e3dbce809f64246a8fe5ef0d05a63a28a05c0)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/meson.build | 1 +
src/conf/storage_source_conf.c | 42 ---------------------------
src/conf/storage_source_conf.h | 24 ++--------------
src/conf/virdomainfd.c | 52 ++++++++++++++++++++++++++++++++++
src/conf/virdomainfd.h | 27 ++++++++++++++++++
src/libvirt_private.syms | 5 +++-
src/qemu/qemu_backup.c | 2 +-
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_driver.c | 6 ++--
tests/testutilsqemu.c | 2 +-
10 files changed, 92 insertions(+), 71 deletions(-)
create mode 100644 src/conf/virdomainfd.c
create mode 100644 src/conf/virdomainfd.h
diff --git a/src/conf/meson.build b/src/conf/meson.build
index 5116c23fe3..6f95b23cce 100644
--- a/src/conf/meson.build
+++ b/src/conf/meson.build
@@ -20,6 +20,7 @@ domain_conf_sources = [
'numa_conf.c',
'snapshot_conf.c',
'virdomaincheckpointobjlist.c',
+ 'virdomainfd.c',
'virdomainjob.c',
'virdomainmomentobjlist.c',
'virdomainobjlist.c',
diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c
index 24d4b0de6a..493b1411b3 100644
--- a/src/conf/storage_source_conf.c
+++ b/src/conf/storage_source_conf.c
@@ -1413,48 +1413,6 @@ virStorageSourceInitiatorClear(virStorageSourceInitiatorDef *initiator)
VIR_FREE(initiator->iqn);
}
-G_DEFINE_TYPE(virStorageSourceFDTuple, vir_storage_source_fd_tuple, G_TYPE_OBJECT);
-
-static void
-vir_storage_source_fd_tuple_init(virStorageSourceFDTuple *fdt G_GNUC_UNUSED)
-{
-}
-
-
-static void
-virStorageSourceFDTupleFinalize(GObject *object)
-{
- virStorageSourceFDTuple *fdt = VIR_STORAGE_SOURCE_FD_TUPLE(object);
- size_t i;
-
- if (!fdt)
- return;
-
- for (i = 0; i < fdt->nfds; i++)
- VIR_FORCE_CLOSE(fdt->fds[i]);
-
- g_free(fdt->fds);
- g_free(fdt->testfds);
- g_free(fdt->selinuxLabel);
- G_OBJECT_CLASS(vir_storage_source_fd_tuple_parent_class)->finalize(object);
-}
-
-
-static void
-vir_storage_source_fd_tuple_class_init(virStorageSourceFDTupleClass *klass)
-{
- GObjectClass *obj = G_OBJECT_CLASS(klass);
-
- obj->finalize = virStorageSourceFDTupleFinalize;
-}
-
-
-virStorageSourceFDTuple *
-virStorageSourceFDTupleNew(void)
-{
- return g_object_new(vir_storage_source_fd_tuple_get_type(), NULL);
-}
-
/**
* virStorageSourceNetworkProtocolPathSplit:
diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h
index 5a4b088eeb..b47313bae5 100644
--- a/src/conf/storage_source_conf.h
+++ b/src/conf/storage_source_conf.h
@@ -24,6 +24,7 @@
#include "storage_encryption_conf.h"
#include "virbitmap.h"
#include "virconftypes.h"
+#include "virdomainfd.h"
#include "virenum.h"
#include "virobject.h"
#include "virpci.h"
@@ -268,27 +269,6 @@ struct _virStorageSourceSlice {
void
virStorageSourceSliceFree(virStorageSourceSlice *slice);
-struct _virStorageSourceFDTuple {
- GObject parent;
- int *fds;
- size_t nfds;
- int *testfds; /* populated by tests to ensure stable FDs */
-
- bool writable;
- bool tryRestoreLabel;
-
- /* connection this FD tuple is associated with for auto-closing */
- virConnect *conn;
-
- /* original selinux label when we relabel the image */
- char *selinuxLabel;
-};
-G_DECLARE_FINAL_TYPE(virStorageSourceFDTuple, vir_storage_source_fd_tuple, VIR, STORAGE_SOURCE_FD_TUPLE, GObject);
-
-virStorageSourceFDTuple *
-virStorageSourceFDTupleNew(void);
-
-
typedef struct _virStorageSource virStorageSource;
/* Stores information related to a host resource. In the case of backing
@@ -441,7 +421,7 @@ struct _virStorageSource {
* one event for it */
bool thresholdEventWithIndex;
- virStorageSourceFDTuple *fdtuple;
+ virDomainFDTuple *fdtuple;
/* Setting 'seclabelSkipRemember' to true will cause the security driver to
* not remember the security label even if it otherwise were to be
diff --git a/src/conf/virdomainfd.c b/src/conf/virdomainfd.c
new file mode 100644
index 0000000000..13c3161e6a
--- /dev/null
+++ b/src/conf/virdomainfd.c
@@ -0,0 +1,52 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include <config.h>
+
+#include "virdomainfd.h"
+
+#include "virfile.h"
+
+G_DEFINE_TYPE(virDomainFDTuple, vir_domain_fd_tuple, G_TYPE_OBJECT);
+
+
+static void
+vir_domain_fd_tuple_init(virDomainFDTuple *fdt G_GNUC_UNUSED)
+{
+}
+
+
+static void
+virDomainFDTupleFinalize(GObject *object)
+{
+ virDomainFDTuple *fdt = VIR_DOMAIN_FD_TUPLE(object);
+ size_t i;
+
+ if (!fdt)
+ return;
+
+ for (i = 0; i < fdt->nfds; i++)
+ VIR_FORCE_CLOSE(fdt->fds[i]);
+
+ g_free(fdt->fds);
+ g_free(fdt->testfds);
+ g_free(fdt->selinuxLabel);
+ G_OBJECT_CLASS(vir_domain_fd_tuple_parent_class)->finalize(object);
+}
+
+
+static void
+vir_domain_fd_tuple_class_init(virDomainFDTupleClass *klass)
+{
+ GObjectClass *obj = G_OBJECT_CLASS(klass);
+
+ obj->finalize = virDomainFDTupleFinalize;
+}
+
+
+virDomainFDTuple *
+virDomainFDTupleNew(void)
+{
+ return g_object_new(vir_domain_fd_tuple_get_type(), NULL);
+}
diff --git a/src/conf/virdomainfd.h b/src/conf/virdomainfd.h
new file mode 100644
index 0000000000..0c0d475ed6
--- /dev/null
+++ b/src/conf/virdomainfd.h
@@ -0,0 +1,27 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#include "internal.h"
+
+struct _virDomainFDTuple {
+ GObject parent;
+ int *fds;
+ size_t nfds;
+ int *testfds; /* populated by tests to ensure stable FDs */
+
+ bool writable;
+ bool tryRestoreLabel;
+
+ /* connection this FD tuple is associated with for auto-closing */
+ virConnect *conn;
+
+ /* original selinux label when we relabel the image */
+ char *selinuxLabel;
+};
+G_DECLARE_FINAL_TYPE(virDomainFDTuple, vir_domain_fd_tuple, VIR, DOMAIN_FD_TUPLE, GObject);
+
+virDomainFDTuple *
+virDomainFDTupleNew(void);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1308fa2e51..9b46e1ea1a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1179,7 +1179,6 @@ virStorageSourceChainHasManagedPR;
virStorageSourceChainHasNVMe;
virStorageSourceClear;
virStorageSourceCopy;
-virStorageSourceFDTupleNew;
virStorageSourceGetActualType;
virStorageSourceGetSecurityLabelDef;
virStorageSourceHasBacking;
@@ -1232,6 +1231,10 @@ virDomainCheckpointUpdateRelations;
virDomainListCheckpoints;
+# conf/virdomainfd.h
+virDomainFDTupleNew;
+
+
#conf/virdomainjob.h
virDomainAgentJobTypeToString;
virDomainAsyncJobTypeFromString;
diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index c3566bcd57..eebf6cdc06 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -876,7 +876,7 @@ qemuBackupBegin(virDomainObj *vm,
priv->backup = g_steal_pointer(&def);
if (pull && priv->backup->server->fdgroup) {
- virStorageSourceFDTuple *fdt = NULL;
+ virDomainFDTuple *fdt = NULL;
VIR_AUTOCLOSE fdcopy = -1;
if (!(fdt = virHashLookup(priv->fds, priv->backup->server->fdgroup))) {
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index ccbfc8bac7..5c9f4831fd 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9835,7 +9835,7 @@ qemuDomainPrepareStorageSourceFDs(virStorageSource *src,
{
qemuDomainStorageSourcePrivate *srcpriv = NULL;
virStorageType actualType = virStorageSourceGetActualType(src);
- virStorageSourceFDTuple *fdt = NULL;
+ virDomainFDTuple *fdt = NULL;
size_t i;
if (actualType != VIR_STORAGE_TYPE_FILE &&
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 92b94bb830..15bbd0c5b0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20257,7 +20257,7 @@ qemuDomainFDHashCloseConnect(virDomainObj *vm,
virConnectPtr conn)
{
qemuDomainObjPrivate *priv = QEMU_DOMAIN_PRIVATE(vm);
- virStorageSourceFDTuple *data;
+ virDomainFDTuple *data;
GHashTableIter htitr;
if (!priv->fds)
@@ -20281,7 +20281,7 @@ qemuDomainFDAssociate(virDomainPtr domain,
{
virDomainObj *vm = NULL;
qemuDomainObjPrivate *priv;
- g_autoptr(virStorageSourceFDTuple) new = NULL;
+ g_autoptr(virDomainFDTuple) new = NULL;
size_t i;
int ret = -1;
@@ -20299,7 +20299,7 @@ qemuDomainFDAssociate(virDomainPtr domain,
priv = vm->privateData;
- new = virStorageSourceFDTupleNew();
+ new = virDomainFDTupleNew();
new->nfds = nfds;
new->fds = g_new0(int, new->nfds);
for (i = 0; i < new->nfds; i++) {
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index 21dfd3141d..f7e3e112fe 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -715,7 +715,7 @@ testQemuInfoSetArgs(testQemuInfo *info,
break;
case ARG_FD_GROUP: {
- virStorageSourceFDTuple *new = virStorageSourceFDTupleNew();
+ virDomainFDTuple *new = virDomainFDTupleNew();
const char *fdname = va_arg(argptr, char *);
VIR_AUTOCLOSE fakefd = open("/dev/zero", O_RDWR);
bool writable = va_arg(argptr, int);
--
2.53.0

View File

@ -0,0 +1,104 @@
From 08ff36546b810ae14135c19c99fb1dc1aa5fcbb2 Mon Sep 17 00:00:00 2001
Message-ID: <08ff36546b810ae14135c19c99fb1dc1aa5fcbb2.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Tue, 3 Feb 2026 15:18:39 +0100
Subject: [PATCH] conf: Move type=rom default for loader to drivers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Right now we set this default in the common parsing code, which
is not a big problem per se but would get in the way of some
upcoming changes.
Leave this choice to individual drivers instead. Only the QEMU
and Xen drivers use the value for anything, so we can limit the
amount of code duplication this change causes.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 1504b7f687bdfc679377e605d076776b18533468)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/conf/domain_postparse.c | 19 -------------------
src/libxl/libxl_domain.c | 6 ++++++
src/qemu/qemu_firmware.c | 5 +++++
3 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c
index 38e731348d..cbaae75c02 100644
--- a/src/conf/domain_postparse.c
+++ b/src/conf/domain_postparse.c
@@ -89,22 +89,6 @@ virDomainDefPostParseMemory(virDomainDef *def,
}
-static int
-virDomainDefPostParseOs(virDomainDef *def)
-{
- if (!def->os.loader)
- return 0;
-
- if (def->os.loader->path &&
- def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_NONE) {
- /* By default, loader is type of 'rom' */
- def->os.loader->type = VIR_DOMAIN_LOADER_TYPE_ROM;
- }
-
- return 0;
-}
-
-
static void
virDomainDefPostParseMemtune(virDomainDef *def)
{
@@ -1251,9 +1235,6 @@ virDomainDefPostParseCommon(virDomainDef *def,
if (virDomainDefPostParseMemory(def, data->parseFlags) < 0)
return -1;
- if (virDomainDefPostParseOs(def) < 0)
- return -1;
-
virDomainDefPostParseMemtune(def);
if (virDomainDefRejectDuplicateControllers(def) < 0)
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 9842d6fece..c6717e31cf 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -279,6 +279,12 @@ libxlDomainDefPostParse(virDomainDef *def,
def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ON;
}
+ if (def->os.loader &&
+ def->os.loader->path &&
+ !def->os.loader->type) {
+ def->os.loader->type = VIR_DOMAIN_LOADER_TYPE_ROM;
+ }
+
/* add implicit balloon device */
if (def->memballoon == NULL) {
virDomainMemballoonDef *memballoon;
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index 519828f6f9..6a074055ca 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -1662,6 +1662,11 @@ qemuFirmwareFillDomainCustom(virDomainDef *def)
if (!loader)
return;
+ if (loader->path &&
+ !loader->type) {
+ loader->type = VIR_DOMAIN_LOADER_TYPE_ROM;
+ }
+
if (loader->path &&
!loader->format) {
loader->format = VIR_STORAGE_FILE_RAW;
--
2.53.0

View File

@ -0,0 +1,385 @@
From 50a7a37ea4d6c8ffab8110a58db1b16b9d1d7b84 Mon Sep 17 00:00:00 2001
Message-ID: <50a7a37ea4d6c8ffab8110a58db1b16b9d1d7b84.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Mon, 19 Jan 2026 14:20:06 +0100
Subject: [PATCH] conf: Parse and format varstore element
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This will be used to configure the backing storage used by the
uefi-vars QEMU device.
Dealing with the element itself is trivial, however we have to
refactor the existing code which deals with the loader and nvram
elements slightly: in particular, we can no longer perform an
early exit if those elements are absent.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 3feee6d0aba5abf5e69d69b0022c08ea6bd5af3e)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
docs/formatdomain.rst | 23 +++++++--
docs/kbase/secureboot.rst | 46 ++++++++++++------
src/conf/domain_conf.c | 81 ++++++++++++++++++++++++++++---
src/conf/domain_conf.h | 9 ++++
src/conf/schemas/domaincommon.rng | 22 ++++++++-
src/conf/virconftypes.h | 2 +
src/libvirt_private.syms | 2 +
7 files changed, 157 insertions(+), 28 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 152fd7f530..7d6cc45efd 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -196,9 +196,9 @@ harddisk, cdrom, network) determining where to obtain/find the boot image.
``firmware``
The ``firmware`` attribute allows management applications to automatically
- fill ``<loader/>`` and ``<nvram/>`` elements and possibly enable some
- features required by selected firmware. Accepted values are ``bios`` and
- ``efi``.
+ fill ``<loader/>`` and ``<nvram/>`` or ``<varstore/>`` elements and possibly
+ enable some features required by selected firmware. Accepted values are
+ ``bios`` and ``efi``.
The selection process scans for files describing installed firmware images in
specified location and uses the most specific one which fulfills domain
requirements. The locations in order of preference (from generic to most
@@ -311,6 +311,23 @@ harddisk, cdrom, network) determining where to obtain/find the boot image.
It is not valid to provide this element if the loader is marked as
stateless.
+``varstore``
+ This works much the same way as the ``<nvram/>`` element described above,
+ except that variable storage is handled by the ``uefi-vars`` QEMU device
+ instead of being backed by a pflash device. :since:`Since 12.1.0 (QEMU only)`
+
+ The ``path`` attribute contains the path of the domain-specific file where
+ variables are stored, while the ``template`` attribute points to a template
+ that the domain-specific file can be (re)generated from. Assuming that the
+ necessary JSON firmware descriptor files are present, both attributes will
+ be filled in automatically by libvirt.
+
+ Using ``<varstore/>`` instead of ``<nvram/>`` is particularly useful on
+ non-x86 architectures such as aarch64, where it represents the only way to
+ get Secure Boot working. It can be used on x86 too, and doing so will make
+ it possible to keep UEFI authenticated variables safe from tampering without
+ requiring the use of SMM emulation.
+
``boot``
The ``dev`` attribute takes one of the values "fd", "hd", "cdrom" or
"network" and is used to specify the next boot device to consider. The
diff --git a/docs/kbase/secureboot.rst b/docs/kbase/secureboot.rst
index 6c22b08d22..b411b65f00 100644
--- a/docs/kbase/secureboot.rst
+++ b/docs/kbase/secureboot.rst
@@ -74,8 +74,8 @@ Changing an existing VM
When a VM is defined, libvirt will pick the firmware that best
satisfies the provided criteria and record this information for use
-on subsequent boots. The resulting XML configuration will look like
-this:
+on subsequent boots. The resulting XML configuration will look either
+like this:
::
@@ -88,14 +88,28 @@ this:
<nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd'>/var/lib/libvirt/qemu/nvram/vm_VARS.fd</nvram>
</os>
+or like this:
+
+::
+
+ <os firmware='efi'>
+ <firmware>
+ <feature enabled='yes' name='enrolled-keys'/>
+ <feature enabled='yes' name='secure-boot'/>
+ </firmware>
+ <loader type='rom' format='raw'>/usr/share/edk2/aarch64/QEMU_EFI.qemuvars.fd</loader>
+ <varstore template='/usr/share/edk2/aarch64/vars.secboot.json' path='/var/lib/libvirt/qemu/varstore/vm.json'/>
+ </os>
+
In order to force libvirt to repeat the firmware autoselection
-process, it's necessary to remove the ``<loader>`` and ``<nvram>``
-elements. Failure to do so will likely result in an error.
+process, it's necessary to remove the ``<loader>`` as well as the
+``<nvram>`` or ``<varstore>`` elements, depending on what's
+applicable. Failure to do so will likely result in an error.
Note that updating the XML configuration as described above is
-**not** enough to change the Secure Boot status: the NVRAM file
-associated with the VM has to be regenerated from its template as
-well.
+**not** enough to change the Secure Boot status: the NVRAM/varstore
+file associated with the VM has to be regenerated from its template
+as well.
In order to do that, update the XML and then start the VM with
@@ -107,9 +121,9 @@ This option is only available starting with libvirt 8.1.0, so if your
version of libvirt is older than that you will have to delete the
NVRAM file manually before starting the VM.
-Most guest operating systems will be able to cope with the NVRAM file
-being reinitialized, but in some cases the VM will be unable to boot
-after the change.
+Most guest operating systems will be able to cope with the
+NVRAM/varstore file being reinitialized, but in some cases the VM
+will be unable to boot after the change.
Additional information
@@ -126,15 +140,15 @@ can be used to validate the operating system signature need to be
provided as well.
Asking for the ``enrolled-keys`` firmware feature to be enabled will
-cause libvirt to initialize the NVRAM file associated with the VM
-from a template that contains a suitable set of keys. These keys
-being present will cause the firmware to enforce the Secure Boot
+cause libvirt to initialize the NVRAM/varstore file associated with
+the VM from a template that contains a suitable set of keys. These
+keys being present will cause the firmware to enforce the Secure Boot
signing requirements.
The opposite configuration, where the feature is explicitly disabled,
-will result in no keys being present in the NVRAM file. Unable to
-verify signatures, the firmware will allow even unsigned operating
-systems to run.
+will result in no keys being present in the NVRAM/varstore file.
+Unable to verify signatures, the firmware will allow even unsigned
+operating systems to run.
If running unsigned code is desired, it's also possible to ask for
the ``secure-boot`` feature to be disabled, which will cause libvirt
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e72cda0048..16ea9f0b2e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3932,6 +3932,27 @@ virDomainLoaderDefFree(virDomainLoaderDef *loader)
g_free(loader);
}
+virDomainVarstoreDef *
+virDomainVarstoreDefNew(void)
+{
+ virDomainVarstoreDef *def = NULL;
+
+ def = g_new0(virDomainVarstoreDef, 1);
+
+ return def;
+}
+
+void
+virDomainVarstoreDefFree(virDomainVarstoreDef *varstore)
+{
+ if (!varstore)
+ return;
+
+ g_free(varstore->path);
+ g_free(varstore->template);
+ g_free(varstore);
+}
+
static void
virDomainResctrlMonDefFree(virDomainResctrlMonDef *domresmon)
@@ -4034,6 +4055,7 @@ virDomainOSDefClear(virDomainOSDef *os)
virDomainOSACPITableDefFree(os->acpiTables[i]);
g_free(os->acpiTables);
virDomainLoaderDefFree(os->loader);
+ virDomainVarstoreDefFree(os->varstore);
g_free(os->bootloader);
g_free(os->bootloaderArgs);
}
@@ -17983,6 +18005,17 @@ virDomainLoaderDefParseXMLLoader(virDomainLoaderDef *loader,
}
+static int
+virDomainVarstoreDefParseXML(virDomainVarstoreDef *varstore,
+ xmlNodePtr varstoreNode)
+{
+ varstore->path = virXMLPropString(varstoreNode, "path");
+ varstore->template = virXMLPropString(varstoreNode, "template");
+
+ return 0;
+}
+
+
static int
virDomainLoaderDefParseXML(virDomainLoaderDef *loader,
xmlNodePtr loaderNode,
@@ -18430,16 +18463,29 @@ virDomainDefParseBootLoaderOptions(virDomainDef *def,
xmlNodePtr loaderNode = virXPathNode("./os/loader[1]", ctxt);
xmlNodePtr nvramNode = virXPathNode("./os/nvram[1]", ctxt);
xmlNodePtr nvramSourceNode = virXPathNode("./os/nvram/source[1]", ctxt);
+ xmlNodePtr varstoreNode = virXPathNode("./os/varstore[1]", ctxt);
- if (!loaderNode && !nvramNode)
- return 0;
-
- def->os.loader = virDomainLoaderDefNew();
-
- if (virDomainLoaderDefParseXML(def->os.loader,
- loaderNode, nvramNode, nvramSourceNode,
- ctxt, xmlopt, flags) < 0)
+ if (nvramNode && varstoreNode) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Cannot have both <nvram> and <varstore>"));
return -1;
+ }
+
+ if (loaderNode || nvramNode) {
+ def->os.loader = virDomainLoaderDefNew();
+
+ if (virDomainLoaderDefParseXML(def->os.loader,
+ loaderNode, nvramNode, nvramSourceNode,
+ ctxt, xmlopt, flags) < 0)
+ return -1;
+ }
+
+ if (varstoreNode) {
+ def->os.varstore = virDomainVarstoreDefNew();
+
+ if (virDomainVarstoreDefParseXML(def->os.varstore, varstoreNode) < 0)
+ return -1;
+ }
return 0;
}
@@ -28062,6 +28108,20 @@ virDomainLoaderDefFormat(virBuffer *buf,
return 0;
}
+static int
+virDomainVarstoreDefFormat(virBuffer *buf,
+ virDomainVarstoreDef *varstore)
+{
+ g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+
+ virBufferEscapeString(&attrBuf, " template='%s'", varstore->template);
+ virBufferEscapeString(&attrBuf, " path='%s'", varstore->path);
+
+ virXMLFormatElementEmpty(buf, "varstore", &attrBuf, NULL);
+
+ return 0;
+}
+
static void
virDomainKeyWrapDefFormat(virBuffer *buf, virDomainKeyWrapDef *keywrap)
{
@@ -29523,6 +29583,11 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
if (def->os.loader &&
virDomainLoaderDefFormat(buf, def->os.loader, xmlopt, flags) < 0)
return -1;
+
+ if (def->os.varstore &&
+ virDomainVarstoreDefFormat(buf, def->os.varstore) < 0)
+ return -1;
+
virBufferEscapeString(buf, "<kernel>%s</kernel>\n",
def->os.kernel);
virBufferEscapeString(buf, "<initrd>%s</initrd>\n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 69a8e79c6d..ead3b07475 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2420,6 +2420,14 @@ struct _virDomainLoaderDef {
virDomainLoaderDef *virDomainLoaderDefNew(void);
void virDomainLoaderDefFree(virDomainLoaderDef *loader);
+struct _virDomainVarstoreDef {
+ char *path;
+ char *template;
+};
+
+virDomainVarstoreDef *virDomainVarstoreDefNew(void);
+void virDomainVarstoreDefFree(virDomainVarstoreDef *varstore);
+
typedef enum {
VIR_DOMAIN_IOAPIC_NONE = 0,
VIR_DOMAIN_IOAPIC_QEMU,
@@ -2573,6 +2581,7 @@ struct _virDomainOSDef {
size_t nacpiTables;
virDomainOSACPITableDef **acpiTables;
virDomainLoaderDef *loader;
+ virDomainVarstoreDef *varstore;
char *bootloader;
char *bootloaderArgs;
int smbios_mode;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 92f82c8fbf..7215db3fc1 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -349,7 +349,10 @@
</element>
</optional>
<optional>
- <ref name="osnvram"/>
+ <choice>
+ <ref name="osnvram"/>
+ <ref name="osvarstore"/>
+ </choice>
</optional>
<optional>
<ref name="osbootkernel"/>
@@ -456,6 +459,23 @@
</element>
</define>
+ <define name="osvarstore">
+ <element name="varstore">
+ <interleave>
+ <optional>
+ <attribute name="template">
+ <ref name="absFilePath"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="path">
+ <ref name="absFilePath"/>
+ </attribute>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+
<define name="osexe">
<element name="os">
<interleave>
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index 6e2573035a..0596791a4d 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -164,6 +164,8 @@ typedef struct _virDomainLeaseDef virDomainLeaseDef;
typedef struct _virDomainLoaderDef virDomainLoaderDef;
+typedef struct _virDomainVarstoreDef virDomainVarstoreDef;
+
typedef struct _virDomainMemballoonDef virDomainMemballoonDef;
typedef struct _virDomainMemoryDef virDomainMemoryDef;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index effe44fe57..1308fa2e51 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -718,6 +718,8 @@ virDomainTPMProfileRemoveDisabledTypeToString;
virDomainTPMVersionTypeFromString;
virDomainTPMVersionTypeToString;
virDomainUSBDeviceDefForeach;
+virDomainVarstoreDefFree;
+virDomainVarstoreDefNew;
virDomainVideoDefaultRAM;
virDomainVideoDefClear;
virDomainVideoDefFree;
--
2.53.0

View File

@ -0,0 +1,113 @@
From 52b7d88693b71c455ab0a86feb707537c7bf8e54 Mon Sep 17 00:00:00 2001
Message-ID: <52b7d88693b71c455ab0a86feb707537c7bf8e54.1773324140.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 11 Feb 2026 10:16:28 +0100
Subject: [PATCH] conf: Parse hyperv features even for host-model
As it turns out, some users of the hyperv "host-model" mode might
want to override the hypervisor defaults. For instance disable a
feature that's on by default, or vice versa. Currently, this is
not possible because as soon as our XML parser sees the
"host-model" mode it exits early and skips parsing of individual
features (for "custom" mode). Well, do not return early and parse
the rest.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 380fb8939009a420f598175e63994a5bf197fd56)
Resolves: https://issues.redhat.com/browse/RHEL-153576
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
docs/formatdomain.rst | 3 +++
src/conf/domain_conf.c | 3 +--
src/conf/schemas/domaincommon.rng | 8 ++++----
tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml | 6 +++++-
tests/qemuxmlconfdata/hyperv-host-model.xml | 6 +++++-
5 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 7d6cc45efd..ff07f2fc17 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -2218,6 +2218,9 @@ are:
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`
+ It is also possible to set features, like in ``custom`` mode. These are
+ then left untouched and no expansion is done for them. :since:`Since
+ 12.1.0`
The ``mode`` attribute can be omitted and will default to ``custom``.
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8877aefb7c..c1ed0a5406 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -17291,8 +17291,7 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
def->features[VIR_DOMAIN_FEATURE_HYPERV] = mode;
- if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH ||
- mode == VIR_DOMAIN_HYPERV_MODE_HOST_MODEL)
+ if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH)
return 0;
node = xmlFirstElementChild(node);
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 7215db3fc1..fa7220deae 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -8087,13 +8087,13 @@
<attribute name="mode">
<value>passthrough</value>
</attribute>
- <attribute name="mode">
- <value>host-model</value>
- </attribute>
<group>
<optional>
<attribute name="mode">
- <value>custom</value>
+ <choice>
+ <value>custom</value>
+ <value>host-model</value>
+ </choice>
</attribute>
</optional>
<interleave>
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
index 453a43b3c9..9535cee02a 100644
--- a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
@@ -10,7 +10,11 @@
</os>
<features>
<acpi/>
- <hyperv mode='host-model'/>
+ <hyperv mode='host-model'>
+ <relaxed state='on'/>
+ <spinlocks state='on' retries='8192'/>
+ <xmm_input state='off'/>
+ </hyperv>
</features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.xml b/tests/qemuxmlconfdata/hyperv-host-model.xml
index fae00d86dd..473a41892d 100644
--- a/tests/qemuxmlconfdata/hyperv-host-model.xml
+++ b/tests/qemuxmlconfdata/hyperv-host-model.xml
@@ -10,7 +10,11 @@
</os>
<features>
<acpi/>
- <hyperv mode='host-model'/>
+ <hyperv mode='host-model'>
+ <relaxed state='on'/>
+ <spinlocks state='on' retries='8192'/>
+ <xmm_input state='off'/>
+ </hyperv>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
--
2.53.0

View File

@ -0,0 +1,80 @@
From 8347e0900ee5eb8fc01f0d90271bb3cb70a49f59 Mon Sep 17 00:00:00 2001
Message-ID: <8347e0900ee5eb8fc01f0d90271bb3cb70a49f59.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 11:47:21 +0100
Subject: [PATCH] conf: Refactor virHostdevIsPCIDevice
Future patches will need to check if the host device uses IOMMUFD or not
but we also need to keep a function that will check only if it is PCI device.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit d0afa0a842ce8a6dcb3f881d7dccdf5198f78fa7)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/domain_conf.c | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c1ed0a5406..cddb7181f9 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32825,6 +32825,33 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev)
}
+static bool
+virHostdevPCIDevHasIOMMUFD(const virDomainHostdevDef *hostdev)
+{
+ return hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
+ hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES;
+}
+
+
+static bool
+virHostdevIsPCIDeviceImpl(const virDomainHostdevDef *hostdev,
+ virTristateBool iommufd)
+{
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ return false;
+
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ return false;
+
+ if (iommufd != VIR_TRISTATE_BOOL_ABSENT) {
+ bool hasIOMMUFD = iommufd == VIR_TRISTATE_BOOL_YES;
+ return hasIOMMUFD == virHostdevPCIDevHasIOMMUFD(hostdev);
+ }
+
+ return true;
+}
+
+
/**
* virHostdevIsPCIDevice:
* @hostdev: host device to check
@@ -32834,8 +32861,7 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev)
bool
virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
{
- return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
+ return virHostdevIsPCIDeviceImpl(hostdev, VIR_TRISTATE_BOOL_ABSENT);
}
@@ -32848,9 +32874,7 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
bool
virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev)
{
- return virHostdevIsPCIDevice(hostdev) &&
- hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
- hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES;
+ return virHostdevIsPCIDeviceImpl(hostdev, VIR_TRISTATE_BOOL_YES);
}
--
2.53.0

View File

@ -0,0 +1,378 @@
From f47031d4e6439d1daf5711d4117c0fa647196944 Mon Sep 17 00:00:00 2001
Message-ID: <f47031d4e6439d1daf5711d4117c0fa647196944.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Thu, 22 Jan 2026 19:27:03 +0100
Subject: [PATCH] conf: Update validation to consider varstore element
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The code is reworked quite significantly, but most of the
existing checks are preserved. Those that aren't, notably the
one that allowed pflash as the only acceptable non-stateless
firmware type, are intentionally removed because they will no
longer reflect reality once support for the uefi-vars QEMU
device is introduced.
As a side effect, reworking the function in this fashion
resolves a subtle bug: due to the early exits that were being
performed when the loader element was missing, the checks at
the bottom of the function (related to the shim and kernel
elements) were effectively never performed. This is no longer
the case.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 1c2dbdf3ac5bed84caeacf585d5143dcf32df75e)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/conf/domain_validate.c | 100 +++++++-----------
...-auto-bios-not-stateless.x86_64-latest.err | 2 +-
...-auto-bios-not-stateless.x86_64-latest.xml | 35 ++++++
...firmware-auto-bios-nvram.x86_64-latest.err | 2 +-
...nual-bios-not-stateless.x86_64-latest.args | 32 ++++++
...anual-bios-not-stateless.x86_64-latest.err | 1 -
...anual-bios-not-stateless.x86_64-latest.xml | 28 +++++
...nual-efi-nvram-stateless.x86_64-latest.err | 2 +-
...nvram-template-stateless.x86_64-latest.err | 2 +-
...ware-manual-efi-rw-nvram.x86_64-latest.err | 2 +-
tests/qemuxmlconftest.c | 7 +-
11 files changed, 144 insertions(+), 69 deletions(-)
create mode 100644 tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.args
delete mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.err
create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.xml
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 7346a61731..163095d55c 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1723,95 +1723,46 @@ virDomainDefOSValidate(const virDomainDef *def,
virDomainXMLOption *xmlopt)
{
virDomainLoaderDef *loader = def->os.loader;
+ virDomainVarstoreDef *varstore = def->os.varstore;
+ virDomainOsDefFirmware firmware = def->os.firmware;
+ int *firmwareFeatures = def->os.firmwareFeatures;
+ bool usesNvram = loader && (loader->nvram || loader->nvramTemplate || loader->nvramTemplateFormat);
- if (def->os.firmware) {
+ if (firmware) {
if (xmlopt && !(xmlopt->config.features & VIR_DOMAIN_DEF_FEATURE_FW_AUTOSELECT)) {
virReportError(VIR_ERR_XML_DETAIL, "%s",
_("firmware auto selection not implemented for this driver"));
return -1;
}
- if (def->os.firmwareFeatures &&
- def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS] == VIR_TRISTATE_BOOL_YES &&
- def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT] == VIR_TRISTATE_BOOL_NO) {
+ if (firmwareFeatures &&
+ firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS] == VIR_TRISTATE_BOOL_YES &&
+ firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT] == VIR_TRISTATE_BOOL_NO) {
virReportError(VIR_ERR_XML_DETAIL, "%s",
_("firmware feature 'enrolled-keys' cannot be enabled when firmware feature 'secure-boot' is disabled"));
return -1;
}
-
- if (!loader)
- return 0;
-
- if (loader->nvram && def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("firmware type '%1$s' does not support nvram"),
- virDomainOsDefFirmwareTypeToString(def->os.firmware));
- return -1;
- }
} else {
- if (def->os.firmwareFeatures) {
+ if (firmwareFeatures) {
virReportError(VIR_ERR_XML_DETAIL, "%s",
_("cannot use feature-based firmware autoselection when firmware autoselection is disabled"));
return -1;
}
- if (!loader)
- return 0;
-
- if (!loader->path) {
+ if (loader && !loader->path) {
virReportError(VIR_ERR_XML_DETAIL, "%s",
_("no loader path specified and firmware auto selection disabled"));
return -1;
}
}
- if (loader->readonly == VIR_TRISTATE_BOOL_NO) {
- if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) {
+ if (loader && loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) {
+ if (loader->readonly == VIR_TRISTATE_BOOL_NO) {
virReportError(VIR_ERR_XML_DETAIL, "%s",
_("ROM loader type cannot be used as read/write"));
return -1;
}
- if (loader->nvramTemplate) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("NVRAM template is not permitted when loader is read/write"));
- return -1;
- }
-
- if (loader->nvram) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("NVRAM is not permitted when loader is read/write"));
- return -1;
- }
- }
-
- if (loader->stateless == VIR_TRISTATE_BOOL_YES) {
- if (loader->nvramTemplate) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("NVRAM template is not permitted when loader is stateless"));
- return -1;
- }
-
- if (loader->nvram) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("NVRAM is not permitted when loader is stateless"));
- return -1;
- }
- } else if (loader->stateless == VIR_TRISTATE_BOOL_NO) {
- if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) {
- if (def->os.loader->type != VIR_DOMAIN_LOADER_TYPE_PFLASH) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("Only pflash loader type permits NVRAM"));
- return -1;
- }
- } else if (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("Only EFI firmware permits NVRAM"));
- return -1;
- }
- }
-
- if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) {
if (loader->format &&
loader->format != VIR_STORAGE_FILE_RAW) {
virReportError(VIR_ERR_XML_DETAIL,
@@ -1821,6 +1772,33 @@ virDomainDefOSValidate(const virDomainDef *def,
}
}
+ if (usesNvram && varstore) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("Only one of NVRAM/varstore can be used"));
+ return -1;
+ }
+
+ if (usesNvram || varstore) {
+ if (firmware && firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("Firmware type '%1$s' does not support variable storage (NVRAM/varstore)"),
+ virDomainOsDefFirmwareTypeToString(firmware));
+ return -1;
+ }
+
+ if (loader && loader->stateless == VIR_TRISTATE_BOOL_YES) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("Variable storage (NVRAM/varstore) is not permitted when loader is stateless"));
+ return -1;
+ }
+
+ if (loader && loader->readonly == VIR_TRISTATE_BOOL_NO) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("Variable storage (NVRAM/varstore) is not permitted when loader is read/write"));
+ return -1;
+ }
+ }
+
if (def->os.shim && !def->os.kernel) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("shim only allowed with kernel option"));
diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err
index b058f970a4..743fe27a97 100644
--- a/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err
+++ b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err
@@ -1 +1 @@
-Only EFI firmware permits NVRAM
+operation failed: Unable to find 'bios' firmware that is compatible with the current configuration
diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml
new file mode 100644
index 0000000000..062835e351
--- /dev/null
+++ b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml
@@ -0,0 +1,35 @@
+<domain type='kvm'>
+ <name>guest</name>
+ <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os firmware='bios'>
+ <type arch='x86_64' machine='pc-q35-10.0'>hvm</type>
+ <loader stateless='no' format='raw'/>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ </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='none'/>
+ <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'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <watchdog model='itco' action='reset'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-nvram.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-bios-nvram.x86_64-latest.err
index 772beb49e2..c4eeb92788 100644
--- a/tests/qemuxmlconfdata/firmware-auto-bios-nvram.x86_64-latest.err
+++ b/tests/qemuxmlconfdata/firmware-auto-bios-nvram.x86_64-latest.err
@@ -1 +1 @@
-firmware type 'bios' does not support nvram
+Firmware type 'bios' does not support variable storage (NVRAM/varstore)
diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.args
new file mode 100644
index 0000000000..969c7ad68c
--- /dev/null
+++ b/tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.args
@@ -0,0 +1,32 @@
+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 pc-i440fx-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-bios /usr/share/seabios/bios.bin \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \
+-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 \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.err
deleted file mode 100644
index 188a5a4180..0000000000
--- a/tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.err
+++ /dev/null
@@ -1 +0,0 @@
-Only pflash loader type permits NVRAM
diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.xml
new file mode 100644
index 0000000000..075da36d00
--- /dev/null
+++ b/tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.xml
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-i440fx-10.0'>hvm</type>
+ <loader type='rom' stateless='no' format='raw'>/usr/share/seabios/bios.bin</loader>
+ <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='none'/>
+ <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/firmware-manual-efi-nvram-stateless.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-stateless.x86_64-latest.err
index de8db3763d..9bfd4465ab 100644
--- a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-stateless.x86_64-latest.err
+++ b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-stateless.x86_64-latest.err
@@ -1 +1 @@
-NVRAM is not permitted when loader is stateless
+Variable storage (NVRAM/varstore) is not permitted when loader is stateless
diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-stateless.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-stateless.x86_64-latest.err
index 95ec794c17..9bfd4465ab 100644
--- a/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-stateless.x86_64-latest.err
+++ b/tests/qemuxmlconfdata/firmware-manual-efi-nvram-template-stateless.x86_64-latest.err
@@ -1 +1 @@
-NVRAM template is not permitted when loader is stateless
+Variable storage (NVRAM/varstore) is not permitted when loader is stateless
diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err
index d0cf62061a..708b4838d4 100644
--- a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err
+++ b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err
@@ -1 +1 @@
-NVRAM is not permitted when loader is read/write
+Variable storage (NVRAM/varstore) is not permitted when loader is read/write
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 822e29b888..a3d4d2de5c 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1575,7 +1575,10 @@ mymain(void)
DO_TEST_CAPS_LATEST("firmware-manual-bios");
DO_TEST_CAPS_LATEST("firmware-manual-bios-stateless");
- DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-bios-not-stateless");
+ /* This combination doesn't make sense (BIOS is stateless by definition)
+ * but unfortunately there's no way for libvirt to report an error in this
+ * scenario. The stateless=no attribute will effectively be ignored */
+ DO_TEST_CAPS_LATEST("firmware-manual-bios-not-stateless");
DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-bios-rw");
DO_TEST_CAPS_LATEST("firmware-manual-efi");
DO_TEST_CAPS_LATEST("firmware-manual-efi-features");
@@ -1628,7 +1631,7 @@ mymain(void)
DO_TEST_CAPS_LATEST("firmware-auto-bios");
DO_TEST_CAPS_LATEST("firmware-auto-bios-stateless");
DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-bios-rw");
- DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-auto-bios-not-stateless");
+ DO_TEST_CAPS_LATEST_FAILURE("firmware-auto-bios-not-stateless");
DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-auto-bios-nvram");
DO_TEST_CAPS_LATEST("firmware-auto-efi");
DO_TEST_CAPS_LATEST_ABI_UPDATE("firmware-auto-efi");
--
2.53.0

View File

@ -1,63 +0,0 @@
From 3a08985417c36691e5b9e2808fec421a19e08f09 Mon Sep 17 00:00:00 2001
Message-ID: <3a08985417c36691e5b9e2808fec421a19e08f09.1759908360.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-111863
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 7d68ea2478..14c00f3d1b 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1915,10 +1915,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;
@@ -1933,10 +1936,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,158 @@
From 38199dbe3ba0f56ed5cc8df92a181ed0a2c1226d Mon Sep 17 00:00:00 2001
Message-ID: <38199dbe3ba0f56ed5cc8df92a181ed0a2c1226d.1781277506.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 25 May 2026 14:22:58 +0200
Subject: [PATCH] cpu: Introduce virCPUUpdateFeatures
This new API can be used to update an existing CPU definition with
features described by CPU data.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 6be1be4938338477bff14ff24c7ed2a05bc1dadc)
https://redhat.atlassian.net/browse/RHEL-180449
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/cpu/cpu.c | 34 ++++++++++++++++++++++++++++++++++
src/cpu/cpu.h | 12 ++++++++++++
src/cpu/cpu_x86.c | 23 +++++++++++++++++++++++
src/libvirt_private.syms | 1 +
4 files changed, 70 insertions(+)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index d81e620a1d..3e9affa1cd 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -1359,6 +1359,40 @@ virCPUGetCanonicalModel(virArch arch,
}
+/** virCPUUpdateFeatures:
+ *
+ * @arch: CPU architecture
+ * @cpu: CPU definition to update
+ * @cpuData: CPU data describing features
+ * @policy: to be used by the updated features
+ *
+ * Updates features described in @cpuData to use the specified @policy. Missing
+ * features will be automatically added to the CPU definition.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int
+virCPUUpdateFeatures(virArch arch,
+ virCPUDef *cpu,
+ virCPUData *cpuData,
+ virCPUFeaturePolicy policy)
+{
+ struct cpuArchDriver *driver;
+
+ VIR_DEBUG("arch=%s, cpu=%p, model=%s, policy=%s",
+ virArchToString(arch), cpu, NULLSTR(cpu->model),
+ virCPUFeaturePolicyTypeToString(policy));
+
+ if (!(driver = cpuGetSubDriver(arch)))
+ return -1;
+
+ if (!driver->updateFeatures)
+ return 0;
+
+ return driver->updateFeatures(cpu, cpuData, policy);
+}
+
+
/**
* virCPUArchIsSupported:
*
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 36fd123675..65711ac085 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -143,6 +143,11 @@ typedef int
typedef const char *
(*virCPUArchGetCanonicalModel)(const char *model);
+typedef int
+(*virCPUArchUpdateFeatures)(virCPUDef *cpu,
+ virCPUData *cpuData,
+ virCPUFeaturePolicy policy);
+
struct cpuArchDriver {
const char *name;
const virArch *arch;
@@ -172,6 +177,7 @@ struct cpuArchDriver {
virCPUArchDataGetHost dataGetHost;
virCPUArchGetCheckMode getCheckMode;
virCPUArchGetCanonicalModel getCanonicalModel;
+ virCPUArchUpdateFeatures updateFeatures;
};
@@ -332,6 +338,12 @@ const char *
virCPUGetCanonicalModel(virArch arch,
const char *model);
+int
+virCPUUpdateFeatures(virArch arch,
+ virCPUDef *cpu,
+ virCPUData *cpuData,
+ virCPUFeaturePolicy policy);
+
bool
virCPUArchIsSupported(virArch arch);
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index e5825fbb4d..6e860de458 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -3790,6 +3790,28 @@ virCPUx86GetCanonicalModel(const char *modelName)
}
+static int
+virCPUx86UpdateFeatures(virCPUDef *cpu,
+ virCPUData *cpuData,
+ virCPUFeaturePolicy policy)
+{
+ virCPUx86Data *data = &cpuData->data.x86;
+ virCPUx86Map *map;
+ size_t i;
+
+ if (!(map = virCPUx86GetMap()))
+ return -1;
+
+ for (i = 0; i < map->nfeatures; i++) {
+ virCPUx86Feature *feature = map->features[i];
+ if (x86DataIsSubset(data, &feature->data))
+ virCPUDefUpdateFeature(cpu, feature->name, policy);
+ }
+
+ return 0;
+}
+
+
struct cpuArchDriver cpuDriverX86 = {
.name = "x86",
.arch = archs,
@@ -3824,4 +3846,5 @@ struct cpuArchDriver cpuDriverX86 = {
#endif
.getCheckMode = virCPUx86GetCheckMode,
.getCanonicalModel = virCPUx86GetCanonicalModel,
+ .updateFeatures = virCPUx86UpdateFeatures,
};
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8d23b5607f..f4036abef9 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1588,6 +1588,7 @@ virCPUGetVendorForModel;
virCPUProbeHost;
virCPUTranslate;
virCPUUpdate;
+virCPUUpdateFeatures;
virCPUUpdateLive;
virCPUValidateFeatures;
--
2.54.0

View File

@ -0,0 +1,109 @@
From 70ba62fbe0ea201a33209cc716462c5b2489585a Mon Sep 17 00:00:00 2001
Message-ID: <70ba62fbe0ea201a33209cc716462c5b2489585a.1781277506.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 29 May 2026 13:00:10 +0200
Subject: [PATCH] cpu_conf: Introduce virCPUDefSortFeatures
Separate the sorting code from virCPUExpandFeatures into a standalone
function.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 0900cc4f2dca2c17e8854330d45dffa4cc7952c4)
https://redhat.atlassian.net/browse/RHEL-180449
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/conf/cpu_conf.c | 20 ++++++++++++++++++++
src/conf/cpu_conf.h | 3 +++
src/cpu/cpu.c | 15 +--------------
src/libvirt_private.syms | 1 +
4 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 7aeedf64f5..f5a2004ee6 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -1277,3 +1277,23 @@ virCPUDefListFree(virCPUDef **cpus)
g_free(cpus);
}
+
+
+static int
+virCPUFeatureDefCompare(const void *p1,
+ const void *p2,
+ void *opaque G_GNUC_UNUSED)
+{
+ const virCPUFeatureDef *f1 = p1;
+ const virCPUFeatureDef *f2 = p2;
+
+ return strcmp(f1->name, f2->name);
+}
+
+
+void
+virCPUDefSortFeatures(virCPUDef *cpu)
+{
+ g_qsort_with_data(cpu->features, cpu->nfeatures, sizeof(*cpu->features),
+ virCPUFeatureDefCompare, NULL);
+}
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index cfb8f1a461..0cac1a1489 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -280,3 +280,6 @@ virCPUDefListParse(const char **xmlCPUs,
virCPUType cpuType);
void
virCPUDefListFree(virCPUDef **cpus);
+
+void
+virCPUDefSortFeatures(virCPUDef *cpu);
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 233686485d..d81e620a1d 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -1125,18 +1125,6 @@ virCPUConvertLegacy(virArch arch,
}
-static int
-virCPUFeatureCompare(const void *p1,
- const void *p2,
- void *opaque G_GNUC_UNUSED)
-{
- const virCPUFeatureDef *f1 = p1;
- const virCPUFeatureDef *f2 = p2;
-
- return strcmp(f1->name, f2->name);
-}
-
-
/**
* virCPUExpandFeatures:
*
@@ -1168,8 +1156,7 @@ virCPUExpandFeatures(virArch arch,
driver->expandFeatures(cpu) < 0)
return -1;
- g_qsort_with_data(cpu->features, cpu->nfeatures, sizeof(*cpu->features),
- virCPUFeatureCompare, NULL);
+ virCPUDefSortFeatures(cpu);
VIR_DEBUG("nfeatures=%zu", cpu->nfeatures);
return 0;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 765c55f3b2..fa2b68cee1 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -118,6 +118,7 @@ virCPUDefNew;
virCPUDefParseXML;
virCPUDefParseXMLString;
virCPUDefRef;
+virCPUDefSortFeatures;
virCPUDefStealModel;
virCPUDefUpdateFeature;
virCPUMaxPhysAddrModeTypeFromString;
--
2.54.0

View File

@ -1,138 +0,0 @@
From 252b9913dc3e15696e89ce10ad3b61f78fe3c63a Mon Sep 17 00:00:00 2001
Message-ID: <252b9913dc3e15696e89ce10ad3b61f78fe3c63a.1763729878.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-126094
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 d2b59ba1f4..a394bae754 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4048,17 +4048,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 ddc065d8f4..852ff34303 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5169,8 +5169,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 3a6ea44c8b..24af907afb 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6532,9 +6532,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,109 @@
From a84c94a30e200847f00bbadaa532abf94584f74f Mon Sep 17 00:00:00 2001
Message-ID: <a84c94a30e200847f00bbadaa532abf94584f74f.1781277506.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 25 May 2026 13:17:47 +0200
Subject: [PATCH] cpu_x86: Introduce virCPUx86DataAddMSR
This just makes the relevant part of virCPUx86GetHost reusable in other
places.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit a8952076d8e5062a2fac08e11597ad47871c2236)
https://redhat.atlassian.net/browse/RHEL-180449
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/cpu/cpu_x86.c | 40 ++++++++++++++++++++++++++++------------
src/cpu/cpu_x86.h | 4 ++++
src/libvirt_private.syms | 1 +
3 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 0f7eb8f48b..e5825fbb4d 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2912,18 +2912,8 @@ virCPUx86GetHost(virCPUDef *cpu,
/* This is best effort since there might be no way to read the MSR
* when we are not running as root. */
for (i = 0; i < nmsrs; i++) {
- if (virHostCPUGetMSR(msrs[i], &msr) == 0) {
- virCPUx86DataItem item = {
- .type = VIR_CPU_X86_DATA_MSR,
- .data.msr = {
- .index = msrs[i],
- .eax = msr & 0xffffffff,
- .edx = msr >> 32,
- },
- };
-
- virCPUx86DataAdd(cpuData, &item);
- }
+ if (virHostCPUGetMSR(msrs[i], &msr) == 0)
+ virCPUx86DataAddMSR(cpuData, msrs[i], msr);
}
ret = x86DecodeCPUData(cpu, cpuData, models);
@@ -3461,6 +3451,32 @@ virCPUx86DataAdd(virCPUData *cpuData,
}
+/**
+ * virCPUx86DataAddMSR:
+ * @cpuData: CPU data to update
+ * @index: MSR index
+ * @value: content of the @index MSR
+ *
+ * Adds the specified MSR content to CPU data.
+ */
+void
+virCPUx86DataAddMSR(virCPUData *cpuData,
+ uint32_t index,
+ uint64_t value)
+{
+ virCPUx86DataItem item = {
+ .type = VIR_CPU_X86_DATA_MSR,
+ .data.msr = {
+ .index = index,
+ .eax = value & 0xffffffff,
+ .edx = value >> 32,
+ },
+ };
+
+ virCPUx86DataAdd(cpuData, &item);
+}
+
+
void
virCPUx86DataSetSignature(virCPUData *cpuData,
unsigned int family,
diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h
index 2cd965fea4..bbc2a16447 100644
--- a/src/cpu/cpu_x86.h
+++ b/src/cpu/cpu_x86.h
@@ -28,6 +28,10 @@ extern struct cpuArchDriver cpuDriverX86;
void virCPUx86DataAdd(virCPUData *cpuData,
const virCPUx86DataItem *cpuid);
+void virCPUx86DataAddMSR(virCPUData *cpuData,
+ uint32_t index,
+ uint64_t value);
+
void virCPUx86DataSetSignature(virCPUData *cpuData,
unsigned int family,
unsigned int model,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1650f19cd9..8d23b5607f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1594,6 +1594,7 @@ virCPUValidateFeatures;
# cpu/cpu_x86.h
virCPUx86DataAdd;
+virCPUx86DataAddMSR;
virCPUx86DataGetSignature;
virCPUx86DataSetSignature;
virCPUx86DataSetVendor;
--
2.54.0

View File

@ -0,0 +1,34 @@
From 4297671a317becdc0ba21c338b5190ca8d014947 Mon Sep 17 00:00:00 2001
Message-ID: <4297671a317becdc0ba21c338b5190ca8d014947.1774618368.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 11 Mar 2026 12:13:45 +0100
Subject: [PATCH] docs: Clarify host-model description in domain capabilities
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 0b54c9d535b9b7c832ff8422dca28c84eb75ed2e)
https://issues.redhat.com/browse/RHEL-154553
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
docs/formatdomaincaps.rst | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index 5a1d3f2670..ed935c704d 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -316,6 +316,10 @@ more details about it:
reports physical address size of the host CPU if this value is available and
applicable for the requested domain type. This is useful for computing
baseline CPU definition which should be compatible with several hosts.
+ Consistently with all other CPU definitions used by libvirt, features
+ implicitly enabled by the selected CPU model (in ``model`` sub element) are
+ not listed. Use ``--expand-cpu-features`` virsh option or the equivalent API
+ flag to request all supported features to be listed in the CPU definition.
``custom``
The ``mode`` element contains a list of supported CPU models, each described
by a dedicated ``model`` element. The ``usable`` attribute specifies whether
--
2.53.0

View File

@ -0,0 +1,88 @@
From 8754c491f66e5d13290aaf221a29b19bd855a171 Mon Sep 17 00:00:00 2001
Message-ID: <8754c491f66e5d13290aaf221a29b19bd855a171.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Wed, 11 Feb 2026 00:48:18 +0100
Subject: [PATCH] docs: Document firmwareFeature element for domaincaps
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit cf4dfcf7951779a815324adebcdaa8a845d4c0e1)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
docs/formatdomaincaps.rst | 51 +++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index 6ba7f84f96..cca827923c 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -111,6 +111,16 @@ be passed to its children.
<value>bios</value>
<value>efi</value>
</enum>
+ <firmwareFeatures supported='yes'>
+ <enum name='secureBoot'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ <enum name='enrolledKeys'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ </firmwareFeatures>
<loader supported='yes'>
<value>/usr/share/OVMF/OVMF_CODE.fd</value>
<enum name='type'>
@@ -140,6 +150,47 @@ about a given BIOS or UEFI binary on the host, e.g. the firmware binary path,
its architecture, supported machine types, NVRAM template, etc. This ensures
that the reported values won't cause a failure on guest boot.
+The ``<firmwareFeatures/>`` element :since:`(since 12.1.0)` contains one
+enum for each of the features that can be used to fine-tune the firmware
+autoselection process. For example:
+
+::
+
+ <firmwareFeatures supported='yes'>
+ <enum name='secureBoot'>
+ <value>yes</value>
+ </enum>
+ <enum name='enrolledKeys'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ </firmwareFeatures>
+
+indicates that a domain XML such as:
+
+::
+
+ <os firmware='efi'>
+ <firmware>
+ <feature name='secure-boot' enabled='yes'/>
+ <feature name='enrolled-keys' enabled='no'/>
+ </firmware>
+ </os>
+
+can be used to allow unsigned operating system to run, whereas a domain XML
+such as:
+
+::
+
+ <os firmware='efi'>
+ <firmware>
+ <feature name='secure-boot' enabled='no'/>
+ </firmware>
+ </os>
+
+would not work, since ``no`` is not one of the valid values advertised by
+the ``secureBoot`` enum.
+
For the ``loader`` element, the following can occur:
``value``
--
2.53.0

View File

@ -0,0 +1,109 @@
From 495763256a6e10ff90210d54efd53f1d4f9e2544 Mon Sep 17 00:00:00 2001
Message-ID: <495763256a6e10ff90210d54efd53f1d4f9e2544.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Mon, 23 Feb 2026 14:58:15 +0100
Subject: [PATCH] docs: Improvement related to firmware selection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Recommend that users take advantage of firmware autoselection
and discourage providing paths manually.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit a03a8205725efec69b1fc7cc0318fa6ce79b6aa9)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
docs/formatdomaincaps.rst | 59 ++++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index 22a6d5d067..3426b7c9cd 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -145,15 +145,17 @@ domains.
...
<domainCapabilities>
-The ``firmware`` enum corresponds to the ``firmware`` attribute of the ``os``
-element in the domain XML. The presence of this enum means libvirt is capable of
-the so-called firmware auto-selection feature. And the listed firmware values
-represent the accepted input in the domain XML. Note that the ``firmware`` enum
-reports only those values for which a firmware "descriptor file" exists on the
-host. Firmware descriptor file is a small JSON document that describes details
-about a given BIOS or UEFI binary on the host, e.g. the firmware binary path,
-its architecture, supported machine types, NVRAM template, etc. This ensures
-that the reported values won't cause a failure on guest boot.
+The presence of the ``firmware`` enum means that libvirt can perform firmware
+autoselection, and each of the values is guaranteed to be usable. In the
+domain XML, firmware autoselection is enabled as follows:
+
+::
+
+ <os firmware='efi'>
+ ...
+
+Autoselection is the recommended mechanism for configuring the guest firmware.
+Providing paths and other information manually is discouraged.
The ``<firmwareFeatures/>`` element :since:`(since 12.1.0)` contains one
enum for each of the features that can be used to fine-tune the firmware
@@ -196,27 +198,34 @@ such as:
would not work, since ``no`` is not one of the valid values advertised by
the ``secureBoot`` enum.
-For the ``loader`` element, the following can occur:
+The information contained in the ``<loader/>`` element is not relevant when
+using firmware autoselection, which is the recommended approach to guest
+firmware configuration, and as such can largely be ignored. Its subelements
+are the following:
``value``
- List of known firmware binary paths. Currently this is used only to advertise
- the known location of OVMF binaries for QEMU. OVMF binaries will only be
- listed if they actually exist on host.
+ One element for each known firmware binary present on the system.
+
+ Note that a binary being present here indicates that the file exists and it
+ is compatible with the architecture/machine type, but does not provide any
+ insight into which mechanism (see ``type`` below) should be used to load it.
``type``
- Whether the boot loader is a typical BIOS (``rom``) or a UEFI firmware
- (``pflash``). Each ``value`` sub-element under the ``type`` enum represents a
- possible value for the ``type`` attribute for the <loader/> element in the
- domain XML. E.g. the presence of ``pfalsh`` under the ``type`` enum means
- that a domain XML can use UEFI firmware via: <loader/> type="pflash"
- ...>/path/to/the/firmware/binary/</loader>.
+ Whether firmware can be loaded using a ``pflash`` device (UEFI only) or as
+ a ``rom`` (either UEFI or BIOS).
``readonly``
- Options for the ``readonly`` attribute of the <loader/> element in the domain
- XML.
+ Supported values for the ``readonly`` attribute of the ``<loader/>`` element
+ in the domain XML.
``secure``
- Options for the ``secure`` attribute of the <loader/> element in the domain
- XML. Note that the value ``yes`` is listed only if libvirt detects a firmware
- descriptor file that has path to an OVMF binary that supports Secure boot,
- and lists its architecture and supported machine type.
+ Supported values for the ``secure`` attribute of the ``<loader/>`` element
+ in the domain XML.
+
+ Note that the value ``yes`` is listed if libvirt detects a firmware
+ descriptor file that points to a firmware binary that implements Secure
+ Boot and is compatible with the architecture/machine type, but the UEFI
+ variable store template associated with it might not have the usual set of
+ Secure Boot certificates enrolled. To figure out whether it's actually
+ possible to enforce Secure Boot, look at the ``enrolledKeys`` enum inside
+ the ``<firmwareFeatures/>`` element instead.
CPU configuration
~~~~~~~~~~~~~~~~~
--
2.53.0

View File

@ -0,0 +1,159 @@
From 807dfc5b7ce3d77d7343b896082d2ae3395b3fdc Mon Sep 17 00:00:00 2001
Message-ID: <807dfc5b7ce3d77d7343b896082d2ae3395b3fdc.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Mon, 23 Feb 2026 14:55:20 +0100
Subject: [PATCH] docs: Rename "BIOS bootloader" section to "guest firmware"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The new name is much more accurate since the documentation is
applicable to firmware other than BIOS, notably UEFI.
An empty container is used to keep old links working.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 38379f59c0d26d006414a1fd92bdf332dadd1ddd)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
docs/formatcaps.rst | 2 +-
docs/formatdomain.rst | 24 ++++++++++++++----------
docs/formatdomaincaps.rst | 19 ++++++++++++-------
3 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/docs/formatcaps.rst b/docs/formatcaps.rst
index fa8ab5197f..9458e1289a 100644
--- a/docs/formatcaps.rst
+++ b/docs/formatcaps.rst
@@ -172,7 +172,7 @@ The ``<guest/>`` element will typically wrap up the following elements:
Emulator (device model) path, for use in
`emulator <formatdomain.html#devices>`__ element of domain XML.
``loader``
- Loader path, for use in `loader <formatdomain.html#bios-bootloader>`__
+ Loader path, for use in `loader <formatdomain.html#guest-firmware>`__
element of domain XML.
``machine``
Machine type, for use in
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 31232deb3c..152fd7f530 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -103,12 +103,16 @@ Operating system booting
There are a number of different ways to boot virtual machines each with their
own pros and cons.
+Guest firmware
+~~~~~~~~~~~~~~
-BIOS bootloader
-~~~~~~~~~~~~~~~
+.. container::
+ :name: bios-bootloader
-Booting via the BIOS is available for hypervisors supporting full
-virtualization. In this case the BIOS has a boot order priority (floppy,
+ .. this container only exists to keep old links working
+
+Booting via a guest firmware is available for hypervisors supporting full
+virtualization. In this case the firmware has a boot order priority (floppy,
harddisk, cdrom, network) determining where to obtain/find the boot image.
::
@@ -411,10 +415,10 @@ and full virtualized guests.
``type``
This element has the same semantics as described earlier in the
- `BIOS bootloader`_ section.
+ `guest firmware`_ section.
``loader``
This element has the same semantics as described earlier in the
- `BIOS bootloader`_ section.
+ `guest firmware`_ section.
``kernel``
The contents of this element specify the fully-qualified path to the kernel
image in the host OS.
@@ -3732,7 +3736,7 @@ paravirtualized driver is specified via the ``disk`` element.
attribute is an 8 character string which can be queried by guests on S390 via
sclp or diag 308. Linux guests on S390 can use ``loadparm`` to select a boot
entry. :since:`Since 3.5.0` The per-device ``boot`` elements cannot be used
- together with general boot elements in `BIOS bootloader`_
+ together with general boot elements in `guest firmware`_
section. :since:`Since 0.8.8`
``encryption``
since:`Since 3.9.0` the ``encryption`` element is preferred
@@ -4897,7 +4901,7 @@ or:
Specifies that the device is bootable. The ``order`` attribute determines the
order in which devices will be tried during boot sequence. The per-device
``boot`` elements cannot be used together with general boot elements in
- `BIOS bootloader`_ section. :since:`Since 0.8.8` for PCI
+ `guest firmware`_ section. :since:`Since 0.8.8` for PCI
devices, :since:`Since 1.0.1` for USB devices.
``rom``
The ``rom`` element is used to change how a PCI device's ROM is presented to
@@ -5121,7 +5125,7 @@ USB device redirection through a character device is supported
Specifies that the device is bootable. The ``order`` attribute determines the
order in which devices will be tried during boot sequence. The per-device
``boot`` elements cannot be used together with general boot elements in
- `BIOS bootloader`_ section. ( :since:`Since 1.0.1` )
+ `guest firmware`_ section. ( :since:`Since 1.0.1` )
``redirfilter``
The\ ``redirfilter``\ element is used for creating the filter rule to filter
out certain devices from redirection. It uses sub-element ``<usbdev>`` to
@@ -6377,7 +6381,7 @@ Specifying boot order
For hypervisors which support this, you can set a specific NIC to be used for
network boot. The ``order`` attribute determines the order in which devices will
be tried during boot sequence. The per-device ``boot`` elements cannot be used
-together with general boot elements in `BIOS bootloader`_
+together with general boot elements in `guest firmware`_
section. :since:`Since 0.8.8`
Interface ROM BIOS configuration
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index cca827923c..22a6d5d067 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -72,11 +72,11 @@ The root element that emulator capability XML document starts with has name
Describes the `virtualization type <formatdomain.html#element-and-attribute-overview>`__ (or so
called domain type).
``machine``
- The domain's `machine type <formatdomain.html#bios-bootloader>`__. Since not
+ The domain's `machine type <formatdomain.html#guest-firmware>`__. Since not
every hypervisor has a sense of machine types this element might be omitted
in such drivers.
``arch``
- The domain's `architecture <formatdomain.html#bios-bootloader>`__.
+ The domain's `architecture <formatdomain.html#guest-firmware>`__.
CPU Allocation
~~~~~~~~~~~~~~
@@ -95,12 +95,17 @@ capabilities, e.g. virtual CPUs:
``vcpu``
The maximum number of supported virtual CPUs
-BIOS bootloader
-~~~~~~~~~~~~~~~
+Guest firmware
+~~~~~~~~~~~~~~
-Sometimes users might want to tweak some BIOS knobs or use UEFI. For cases like
-that, `os <formatdomain.html#bios-bootloader>`__ element exposes what values can
-be passed to its children.
+.. container::
+ :name: bios-bootloader
+
+ .. this container only exists to keep old links working
+
+Exposes information about supported
+`guest firmware <formatdomain.html#guest-firmware>`__ configurations for
+domains.
::
--
2.53.0

View File

@ -1,94 +0,0 @@
From 2d16af69f51802c93b2b64b42f63e3daeabb30fe Mon Sep 17 00:00:00 2001
Message-ID: <2d16af69f51802c93b2b64b42f63e3daeabb30fe.1759908360.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-111863
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 9a2f065590..b1cecde947 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9528,6 +9528,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,62 @@
From f6268acd96651ce72014e2ea7ed649caff0b9133 Mon Sep 17 00:00:00 2001
Message-ID: <f6268acd96651ce72014e2ea7ed649caff0b9133.1771336681.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 30 Jan 2026 17:47:46 +0100
Subject: [PATCH] docs: formatdomain: Fix indentation of docs for
<disk><driver><statistics> element
All other paragraphs in this section use 2 spaces after hyphen, fix the
recently added section.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 7da1a83914ca10cc811583d7310bf60e04b70488)
https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2]
---
docs/formatdomain.rst | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 9836837441..45f262113b 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -3605,22 +3605,22 @@ paravirtualized driver is specified via the ``disk`` element.
</iothreads>
</driver>
- - The optional ``statistics`` sub-element allows configuring statistics
- collection in configurable intervals for the given disk. Intervals are
- configured by ``<statistic>`` sub-elements with ``interval`` attribute
- configuring the collection window duration in seconds. The statistics
- are available via the bulk statistics API.
+ - The optional ``statistics`` sub-element allows configuring statistics
+ collection in configurable intervals for the given disk. Intervals are
+ configured by ``<statistic>`` sub-elements with ``interval`` attribute
+ configuring the collection window duration in seconds. The statistics
+ are available via the bulk statistics API.
- Example::
+ Example::
- <driver name='qemu'>
- <statistics>
- <statistic interval='1'/>
- <statistic interval='10'/>
- </statistics>
- </driver>
+ <driver name='qemu'>
+ <statistics>
+ <statistic interval='1'/>
+ <statistic interval='10'/>
+ </statistics>
+ </driver>
- :since:`Since 11.9.0 (QEMU 10.2, virtio, ide, scsi disks only)`.
+ :since:`Since 11.9.0 (QEMU 10.2, virtio, ide, scsi disks only)`.
- The optional ``queues`` attribute specifies the number of virt queues for
virtio-blk ( :since:`Since 3.9.0` ) or vhost-user-blk
--
2.53.0

View File

@ -0,0 +1,51 @@
From ea6f8a96929577416a5cc4f4452f920312aef081 Mon Sep 17 00:00:00 2001
Message-ID: <ea6f8a96929577416a5cc4f4452f920312aef081.1771336682.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 30 Jan 2026 17:37:48 +0100
Subject: [PATCH] docs: formatdomain: Reword section about the '<statistics>'
element under disk driver
Separate the timed statistics group and link to the fields which are
returned by it.
Prepare the wording for more statistics configs in the future.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit ad65b00c1393f7f13e15744e2e1be4fb531e2a17)
https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2]
---
docs/formatdomain.rst | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 45f262113b..70882c6820 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -3605,11 +3605,17 @@ paravirtualized driver is specified via the ``disk`` element.
</iothreads>
</driver>
- - The optional ``statistics`` sub-element allows configuring statistics
- collection in configurable intervals for the given disk. Intervals are
- configured by ``<statistic>`` sub-elements with ``interval`` attribute
- configuring the collection window duration in seconds. The statistics
- are available via the bulk statistics API.
+ - The optional ``statistics`` sub-element allows configuring various optional
+ statistics collection.
+
+ Statistic values returned under
+ `VIR_DOMAIN_STATS_BLOCK_SUFFIX_TIMED_GROUP_PREFIX <html/libvirt-libvirt-domain.html#VIR_DOMAIN_STATS_BLOCK_SUFFIX_TIMED_GROUP_PREFIX>`__
+ typed parameter prefix returned by the
+ `virConnectGetAllDomainStats <html/libvirt-libvirt-domain.html#virConnectGetAllDomainStats>`__
+ API are collected based on one or more configurable intervals. An interval
+ of collection is configured by ``<statistic>`` sub-elements with
+ ``interval`` attribute configuring the collection window duration in
+ seconds.
Example::
--
2.53.0

View File

@ -0,0 +1,94 @@
From 96d171449cb675b48838b955ddd0ba41a783dba1 Mon Sep 17 00:00:00 2001
Message-ID: <96d171449cb675b48838b955ddd0ba41a783dba1.1772815314.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Thu, 26 Feb 2026 10:18:23 +0100
Subject: [PATCH] domain_conf: initialize network hostdev private data
Currently virDomainNetDef and virDomainActualNetDef use
virDomainHostdevDef directly as structure and the code doesn't call
virDomainHostdevDefNew() that would initialize private data.
This is hackish quick fix to solve a crash that happens in two
scenarios:
1. attaching any interface with hostdev backend
0x0000fffbfc0e2a90 in qemuDomainAttachHostPCIDevice (driver=0xfffbb4006750, vm=0xfffbf001f790, hostdev=0xfffbf400b150) at ../src/qemu/qemu_hotplug.c:1652
1652 if ((ret = qemuFDPassDirectTransferMonitor(hostdevPriv->vfioDeviceFd, priv->mon)) < 0)
2. starting VM with interface with hostdev backend using iommufd
0x00007f6638d5b9ca in qemuProcessOpenVfioDeviceFd (hostdev=hostdev@entry=0x7f6634425ee0) at ../src/qemu/qemu_process.c:7719
7719 hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFd);
Proper fix for this issue is to refactor network code to use pointer and to
use virDomainHostdevDefNew().
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit fe782ed334ea0d4373e6dad093f5815fc925a56b)
https://issues.redhat.com/browse/RHEL-151916
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/domain_conf.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 16ea9f0b2e..8877aefb7c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3489,6 +3489,20 @@ void virDomainVideoDefFree(virDomainVideoDef *def)
}
+static int
+virDomainHostdevDefPrivateDataNew(virDomainHostdevDef *def,
+ virDomainXMLOption *xmlopt)
+{
+ if (!xmlopt || !xmlopt->privateData.hostdevNew)
+ return 0;
+
+ if (!(def->privateData = xmlopt->privateData.hostdevNew()))
+ return -1;
+
+ return 0;
+}
+
+
virDomainHostdevDef *
virDomainHostdevDefNew(virDomainXMLOption *xmlopt)
{
@@ -3498,8 +3512,7 @@ virDomainHostdevDefNew(virDomainXMLOption *xmlopt)
def->info = g_new0(virDomainDeviceInfo, 1);
- if (xmlopt && xmlopt->privateData.hostdevNew &&
- !(def->privateData = xmlopt->privateData.hostdevNew())) {
+ if (virDomainHostdevDefPrivateDataNew(def, xmlopt) < 0) {
VIR_FREE(def->info);
VIR_FREE(def);
return NULL;
@@ -9675,6 +9688,9 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
virDomainHostdevDef *hostdev = &actual->data.hostdev.def;
int type;
+ if (virDomainHostdevDefPrivateDataNew(hostdev, xmlopt) < 0)
+ goto error;
+
hostdev->parentnet = parent;
hostdev->info = &parent->info;
/* The helper function expects type to already be found and
@@ -10368,6 +10384,9 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
g_autofree char *addrtype = virXPathString("string(./source/address/@type)", ctxt);
int type;
+ if (virDomainHostdevDefPrivateDataNew(&def->data.hostdev.def, xmlopt) < 0)
+ return NULL;
+
def->data.hostdev.def.parentnet = def;
def->data.hostdev.def.info = &def->info;
def->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
--
2.53.0

View File

@ -0,0 +1,165 @@
From 33766fc329d60ba7fcf467756a442dd83cc00987 Mon Sep 17 00:00:00 2001
Message-ID: <33766fc329d60ba7fcf467756a442dd83cc00987.1772815312.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 5 Dec 2025 18:34:38 +0100
Subject: [PATCH] domain_validate: Reject NVRAM with read/write firmware
The combination doesn't make sense.
After this change the firmware-manual-bios-rw test cases starts
failing, as it should have in the first place.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 46970217a8258538b5dd9d746ec4191ee6d48d98)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/conf/domain_validate.c | 14 +++++++
...are-manual-efi-rw-nvram.x86_64-latest.args | 37 -----------------
...ware-manual-efi-rw-nvram.x86_64-latest.err | 1 +
...ware-manual-efi-rw-nvram.x86_64-latest.xml | 40 -------------------
tests/qemuxmlconftest.c | 2 +-
5 files changed, 16 insertions(+), 78 deletions(-)
delete mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err
delete mode 100644 tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 4558e7b210..09c1b3f13f 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1765,6 +1765,20 @@ virDomainDefOSValidate(const virDomainDef *def,
}
}
+ if (loader->readonly == VIR_TRISTATE_BOOL_NO) {
+ if (loader->nvramTemplate) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("NVRAM template is not permitted when loader is read/write"));
+ return -1;
+ }
+
+ if (loader->nvram) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("NVRAM is not permitted when loader is read/write"));
+ return -1;
+ }
+ }
+
if (loader->stateless == VIR_TRISTATE_BOOL_YES) {
if (loader->nvramTemplate) {
virReportError(VIR_ERR_XML_DETAIL, "%s",
diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args
deleted file mode 100644
index 6b3eec0a27..0000000000
--- a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.args
+++ /dev/null
@@ -1,37 +0,0 @@
-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"}' \
--blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF.combined.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
--blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \
--blockdev '{"driver":"file","filename":"/path/to/guest_VARS.fd","node-name":"libvirt-pflash1-storage","read-only":false}' \
--machine pc-q35-10.0,usb=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-storage,acpi=on \
--accel kvm \
--cpu qemu64 \
--global driver=cfi.pflash01,property=secure,value=on \
--m size=1048576k \
--object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
--overcommit mem-lock=off \
--smp 1,sockets=1,cores=1,threads=1 \
--uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \
--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 \
--audiodev '{"id":"audio1","driver":"none"}' \
--global ICH9-LPC.noreboot=off \
--watchdog-action reset \
--sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
--msg timestamp=on
diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err
new file mode 100644
index 0000000000..d0cf62061a
--- /dev/null
+++ b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.err
@@ -0,0 +1 @@
+NVRAM is not permitted when loader is read/write
diff --git a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml
deleted file mode 100644
index f6436df80f..0000000000
--- a/tests/qemuxmlconfdata/firmware-manual-efi-rw-nvram.x86_64-latest.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<domain type='kvm'>
- <name>guest</name>
- <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
- <memory unit='KiB'>1048576</memory>
- <currentMemory unit='KiB'>1048576</currentMemory>
- <vcpu placement='static'>1</vcpu>
- <os firmware='efi'>
- <type arch='x86_64' machine='pc-q35-10.0'>hvm</type>
- <firmware>
- <feature enabled='yes' name='secure-boot'/>
- </firmware>
- <loader readonly='no' secure='yes' type='pflash' format='raw'>/usr/share/edk2/ovmf/OVMF.combined.fd</loader>
- <nvram format='raw'>/path/to/guest_VARS.fd</nvram>
- <boot dev='hd'/>
- </os>
- <features>
- <acpi/>
- <smm state='on'/>
- </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='none'/>
- <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'/>
- <input type='mouse' bus='ps2'/>
- <input type='keyboard' bus='ps2'/>
- <audio id='1' type='none'/>
- <watchdog model='itco' action='reset'/>
- <memballoon model='none'/>
- </devices>
-</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 726281a4ab..5299f341cf 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1583,7 +1583,7 @@ mymain(void)
DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-legacy-paths");
DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-modern-paths");
DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-implicit");
- DO_TEST_CAPS_LATEST("firmware-manual-efi-rw-nvram");
+ DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-efi-rw-nvram");
DO_TEST_CAPS_LATEST("firmware-manual-efi-loader-secure");
DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-efi-loader-no-path");
DO_TEST_CAPS_LATEST("firmware-manual-efi-loader-path-nonstandard");
--
2.53.0

View File

@ -0,0 +1,157 @@
From 247090edf75839e13a23885a84cf090fbdd42228 Mon Sep 17 00:00:00 2001
Message-ID: <247090edf75839e13a23885a84cf090fbdd42228.1772815312.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 19 Dec 2025 15:19:26 +0100
Subject: [PATCH] domain_validate: Reject ROMs with format other than raw
The combination doesn't make sense.
After this change the firmware-auto-efi-format-loader-qcow2-rom
test case starts failing, as it should have in the first place.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit c74adb33e4d97202e08a53119f463c54370e5816)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/conf/domain_validate.c | 10 +++++
...format-loader-qcow2-rom.x86_64-latest.args | 34 ----------------
...-format-loader-qcow2-rom.x86_64-latest.err | 1 +
...-format-loader-qcow2-rom.x86_64-latest.xml | 39 -------------------
tests/qemuxmlconftest.c | 2 +-
5 files changed, 12 insertions(+), 74 deletions(-)
delete mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.err
delete mode 100644 tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 93a54f8cc7..7346a61731 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1811,6 +1811,16 @@ virDomainDefOSValidate(const virDomainDef *def,
}
}
+ if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) {
+ if (loader->format &&
+ loader->format != VIR_STORAGE_FILE_RAW) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("Invalid format '%1$s' for ROM loader type"),
+ virStorageFileFormatTypeToString(loader->format));
+ return -1;
+ }
+ }
+
if (def->os.shim && !def->os.kernel) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("shim only allowed with kernel option"));
diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args
deleted file mode 100644
index 417084d45e..0000000000
--- a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.args
+++ /dev/null
@@ -1,34 +0,0 @@
-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 pc-q35-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
--accel kvm \
--cpu qemu64 \
--bios /usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd \
--m size=1048576k \
--object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
--overcommit mem-lock=off \
--smp 1,sockets=1,cores=1,threads=1 \
--uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \
--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 \
--audiodev '{"id":"audio1","driver":"none"}' \
--global ICH9-LPC.noreboot=off \
--watchdog-action reset \
--sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
--msg timestamp=on
diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.err
new file mode 100644
index 0000000000..b7b1400f6a
--- /dev/null
+++ b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.err
@@ -0,0 +1 @@
+Invalid format 'qcow2' for ROM loader type
diff --git a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml
deleted file mode 100644
index 862a50ddb4..0000000000
--- a/tests/qemuxmlconfdata/firmware-auto-efi-format-loader-qcow2-rom.x86_64-latest.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<domain type='kvm'>
- <name>guest</name>
- <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
- <memory unit='KiB'>1048576</memory>
- <currentMemory unit='KiB'>1048576</currentMemory>
- <vcpu placement='static'>1</vcpu>
- <os firmware='efi'>
- <type arch='x86_64' machine='pc-q35-10.0'>hvm</type>
- <firmware>
- <feature enabled='yes' name='enrolled-keys'/>
- <feature enabled='yes' name='secure-boot'/>
- </firmware>
- <loader type='rom' format='qcow2'>/usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd</loader>
- <boot dev='hd'/>
- </os>
- <features>
- <acpi/>
- </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='none'/>
- <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'/>
- <input type='mouse' bus='ps2'/>
- <input type='keyboard' bus='ps2'/>
- <audio id='1' type='none'/>
- <watchdog model='itco' action='reset'/>
- <memballoon model='none'/>
- </devices>
-</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 0a4dab9fe0..3296f6f990 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1650,7 +1650,7 @@ mymain(void)
DO_TEST_CAPS_LATEST("firmware-auto-efi-nvram-network-iscsi");
DO_TEST_CAPS_LATEST("firmware-auto-efi-format-loader-qcow2");
- DO_TEST_CAPS_LATEST("firmware-auto-efi-format-loader-qcow2-rom");
+ DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-auto-efi-format-loader-qcow2-rom");
DO_TEST_CAPS_LATEST("firmware-auto-efi-format-loader-qcow2-nvram-path");
DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2");
DO_TEST_CAPS_LATEST("firmware-auto-efi-format-nvram-qcow2-path");
--
2.53.0

View File

@ -0,0 +1,140 @@
From 3872c63fb5af9e6d37f14b157171ab9fead24b83 Mon Sep 17 00:00:00 2001
Message-ID: <3872c63fb5af9e6d37f14b157171ab9fead24b83.1772815312.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 Dec 2025 16:31:09 +0100
Subject: [PATCH] domain_validate: Reject read/write ROMs
The combination doesn't make sense.
After this change the firmware-manual-bios-rw test case starts
failing, as it should have in the first place.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit a5ae34aa74647e06114d85601c146a991323284b)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/conf/domain_validate.c | 6 ++++
...firmware-manual-bios-rw.x86_64-latest.args | 32 -------------------
.../firmware-manual-bios-rw.x86_64-latest.err | 1 +
.../firmware-manual-bios-rw.x86_64-latest.xml | 28 ----------------
tests/qemuxmlconftest.c | 2 +-
5 files changed, 8 insertions(+), 61 deletions(-)
delete mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.err
delete mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 09c1b3f13f..93a54f8cc7 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1766,6 +1766,12 @@ virDomainDefOSValidate(const virDomainDef *def,
}
if (loader->readonly == VIR_TRISTATE_BOOL_NO) {
+ if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("ROM loader type cannot be used as read/write"));
+ return -1;
+ }
+
if (loader->nvramTemplate) {
virReportError(VIR_ERR_XML_DETAIL, "%s",
_("NVRAM template is not permitted when loader is read/write"));
diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args
deleted file mode 100644
index 969c7ad68c..0000000000
--- a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.args
+++ /dev/null
@@ -1,32 +0,0 @@
-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 pc-i440fx-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
--accel tcg \
--cpu qemu64 \
--bios /usr/share/seabios/bios.bin \
--m size=1048576k \
--object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
--overcommit mem-lock=off \
--smp 1,sockets=1,cores=1,threads=1 \
--uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \
--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 \
--audiodev '{"id":"audio1","driver":"none"}' \
--sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
--msg timestamp=on
diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.err
new file mode 100644
index 0000000000..13e9d7c0f1
--- /dev/null
+++ b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.err
@@ -0,0 +1 @@
+ROM loader type cannot be used as read/write
diff --git a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml
deleted file mode 100644
index 65bb8493c9..0000000000
--- a/tests/qemuxmlconfdata/firmware-manual-bios-rw.x86_64-latest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<domain type='qemu'>
- <name>guest</name>
- <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
- <memory unit='KiB'>1048576</memory>
- <currentMemory unit='KiB'>1048576</currentMemory>
- <vcpu placement='static'>1</vcpu>
- <os>
- <type arch='x86_64' machine='pc-i440fx-10.0'>hvm</type>
- <loader readonly='no' type='rom' format='raw'>/usr/share/seabios/bios.bin</loader>
- <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='none'/>
- <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/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index ba33267d4e..a45487b1b5 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1576,7 +1576,7 @@ mymain(void)
DO_TEST_CAPS_LATEST("firmware-manual-bios");
DO_TEST_CAPS_LATEST("firmware-manual-bios-stateless");
DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-bios-not-stateless");
- DO_TEST_CAPS_LATEST("firmware-manual-bios-rw");
+ DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-bios-rw");
DO_TEST_CAPS_LATEST("firmware-manual-efi");
DO_TEST_CAPS_LATEST("firmware-manual-efi-features");
DO_TEST_CAPS_LATEST_ABI_UPDATE_PARSE_ERROR("firmware-manual-efi-features");
--
2.53.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
From 7dd390b47953b389ecabdc62ac3eec3091a8be3d Mon Sep 17 00:00:00 2001
Message-ID: <7dd390b47953b389ecabdc62ac3eec3091a8be3d.1769616662.git.jdenemar@redhat.com>
From 95ff5dcad20269f8e26eda628c85168dd4702285 Mon Sep 17 00:00:00 2001
Message-ID: <95ff5dcad20269f8e26eda628c85168dd4702285.1769699749.git.jdenemar@redhat.com>
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 26 Jan 2026 10:47:01 +0000
Subject: [PATCH] esx: Abstract all URL-creation code into one function
@ -9,17 +9,17 @@ refactoring and should not change the behaviour.
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit e013d5b5cae732ddeae479098165b9331b8ea441)
Resolves: https://issues.redhat.com/browse/RHEL-142863
Resolves: https://issues.redhat.com/browse/RHEL-138300
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/esx/esx_driver.c | 53 +++++++++++++++++++++++++++++++++++---------
1 file changed, 43 insertions(+), 10 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 8614ba3f32..432853c88a 100644
index 9f965811b1..29735e359f 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -589,7 +589,37 @@ esxCapsInit(esxPrivate *priv)
@@ -582,7 +582,37 @@ esxCapsInit(esxPrivate *priv)
return NULL;
}
@ -57,7 +57,7 @@ index 8614ba3f32..432853c88a 100644
static int
esxConnectToHost(esxPrivate *priv,
@@ -626,8 +656,8 @@ esxConnectToHost(esxPrivate *priv,
@@ -619,8 +649,8 @@ esxConnectToHost(esxPrivate *priv,
conn->uri->server)))
goto cleanup;
@ -68,7 +68,7 @@ index 8614ba3f32..432853c88a 100644
if (esxVI_Context_Alloc(&priv->host) < 0 ||
esxVI_Context_Connect(priv->host, url, ipAddress, username, password,
@@ -713,8 +743,8 @@ esxConnectToVCenter(esxPrivate *priv,
@@ -706,8 +736,8 @@ esxConnectToVCenter(esxPrivate *priv,
if (!(password = virAuthGetPassword(conn, auth, "esx", username, hostname)))
return -1;
@ -79,7 +79,7 @@ index 8614ba3f32..432853c88a 100644
if (esxVI_Context_Alloc(&priv->vCenter) < 0 ||
esxVI_Context_Connect(priv->vCenter, url, ipAddress, username,
@@ -2364,8 +2394,9 @@ esxDomainScreenshot(virDomainPtr domain, virStreamPtr stream,
@@ -2357,8 +2387,9 @@ esxDomainScreenshot(virDomainPtr domain, virStreamPtr stream,
}
/* Build URL */
@ -91,7 +91,7 @@ index 8614ba3f32..432853c88a 100644
virBufferURIEncodeString(&buffer, virtualMachine->obj->value);
url = virBufferContentAndReset(&buffer);
@@ -2570,8 +2601,9 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
@@ -2563,8 +2594,9 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
goto cleanup;
}
@ -102,8 +102,8 @@ index 8614ba3f32..432853c88a 100644
+ "/folder/");
virBufferURIEncodeString(&buffer, directoryAndFileName);
virBufferAddLit(&buffer, "?dcPath=");
esxUtil_EscapeInventoryObject(&buffer, priv->primary->datacenterPath);
@@ -2994,8 +3026,9 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
virBufferURIEncodeString(&buffer, priv->primary->datacenterPath);
@@ -2987,8 +3019,9 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
goto cleanup;
}

View File

@ -1,5 +1,5 @@
From 33029bf5194d6562c8ffd20c9cc286ea298fb4b2 Mon Sep 17 00:00:00 2001
Message-ID: <33029bf5194d6562c8ffd20c9cc286ea298fb4b2.1769195688.git.jdenemar@redhat.com>
From 16276aad5c682651e2a5aabe7d5a7258dda251c1 Mon Sep 17 00:00:00 2001
Message-ID: <16276aad5c682651e2a5aabe7d5a7258dda251c1.1769173967.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 20 Jan 2026 10:08:29 +0100
Subject: [PATCH] esx: Allow connecting to IPv6 server
@ -19,14 +19,13 @@ Resolves: https://issues.redhat.com/browse/RHEL-138300
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 845210011a9ffd9d17e30c51cbc81ba67c5d3166)
Resolves: https://issues.redhat.com/browse/RHEL-142863
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/esx/esx_util.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index 9b714d90ba..963bcd0a75 100644
index 7ee0e5f7c0..12a34a2275 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -280,8 +280,8 @@ esxUtil_ResolveHostname(const char *hostname, char **ipAddress)

View File

@ -1,66 +0,0 @@
From 9feb04c572299cd2c31898c8b7deec0c660bcbbc Mon Sep 17 00:00:00 2001
Message-ID: <9feb04c572299cd2c31898c8b7deec0c660bcbbc.1768319110.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 19 Nov 2025 14:28:11 +0100
Subject: [PATCH] esx: Allow disk images in subdirectories
The esxParseVMXFileName() function parses path to a disk image
trying to replace some "known" patterns (e.g. datastore paths).
A simple filename is treated as a path relative to .vmx file. But
disk images (and thus filenames) can be in a subdirectory,
relative to the .vmx file. For instance:
subfolder/disk.vmdk
Adapt our parser to this fact.
Resolves: https://issues.redhat.com/browse/RHEL-122751
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit 07d3cc9d578781ca7335480b371e27f84c6c8db7)
Resolves: https://issues.redhat.com/browse/RHEL-140865
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/esx/esx_driver.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 512ca6c028..875cd076df 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -79,9 +79,11 @@ esxFreePrivate(esxPrivate **priv)
* Parse a file name from a .vmx file and convert it to datastore path format
* if possible. A .vmx file can contain file names in various formats:
*
- * - A single name referencing a file in the same directory as the .vmx file:
+ * - A single name referencing a file in the same directory as the .vmx file,
+ * or in a subdirectory:
*
* test1.vmdk
+ * subdir/test2.vmdk
*
* - An absolute file name referencing a file in a datastore that is mounted at
* /vmfs/volumes/<datastore>:
@@ -113,8 +115,9 @@ esxFreePrivate(esxPrivate **priv)
*
* Firstly this functions checks if the given file name contains a separator.
* If it doesn't then the referenced file is in the same directory as the .vmx
- * file. The datastore name and directory of the .vmx file are passed to this
- * function via the opaque parameter by the caller of virVMXParseConfig.
+ * file, or in a subdirectory. The datastore name and directory of the .vmx
+ * file are passed to this function via the opaque parameter by the caller of
+ * virVMXParseConfig.
*
* Otherwise query for all known datastores and their mount directories. Then
* try to find a datastore with a mount directory that is a prefix to the given
@@ -145,7 +148,7 @@ esxParseVMXFileName(const char *fileName,
*out = NULL;
- if (!strchr(fileName, '/') && !strchr(fileName, '\\')) {
+ if (*fileName != '/' && !strchr(fileName, '\\')) {
/* Plain file name, use same directory as for the .vmx file */
*out = g_strdup_printf("%s/%s", data->datastorePathWithoutFileName,
fileName);
--
2.52.0

View File

@ -1,19 +1,19 @@
From ec2b306dfe705937dd5eab5c136af6fac7525f23 Mon Sep 17 00:00:00 2001
Message-ID: <ec2b306dfe705937dd5eab5c136af6fac7525f23.1769616662.git.jdenemar@redhat.com>
From 0e5f062ba33929bc592fff175a2cd9d043a32b23 Mon Sep 17 00:00:00 2001
Message-ID: <0e5f062ba33929bc592fff175a2cd9d043a32b23.1769699749.git.jdenemar@redhat.com>
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 26 Jan 2026 10:38:02 +0000
Subject: [PATCH] esx: Debug URL just before opening with curl
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 38c952d89317f5b4bd23223f9a9d8be086ef7a40)
Resolves: https://issues.redhat.com/browse/RHEL-142863
Resolves: https://issues.redhat.com/browse/RHEL-138300
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/esx/esx_vi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index d25f819bc5..44b24e3c91 100644
index 3264afc13a..8d2ffb3f8f 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -231,6 +231,8 @@ esxVI_CURL_Perform(esxVI_CURL *curl, const char *url)

View File

@ -1,5 +1,5 @@
From b5ffe47a34a25a72e068ae1595b5d1102c9a980d Mon Sep 17 00:00:00 2001
Message-ID: <b5ffe47a34a25a72e068ae1595b5d1102c9a980d.1769616662.git.jdenemar@redhat.com>
From 1ac21634942d30288dd11005d1d832b8dda86ceb Mon Sep 17 00:00:00 2001
Message-ID: <1ac21634942d30288dd11005d1d832b8dda86ceb.1769699749.git.jdenemar@redhat.com>
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 26 Jan 2026 17:54:57 +0000
Subject: [PATCH] esx: Switch to creating URLs using virURIFormat
@ -21,17 +21,17 @@ Reported-by: Ming Xie <mxie@redhat.com>
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 13889feb14a24fdf7717960aa5331a0b63ce97ed)
Resolves: https://issues.redhat.com/browse/RHEL-142863
Resolves: https://issues.redhat.com/browse/RHEL-138300
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/esx/esx_driver.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 432853c88a..9d1381db6b 100644
index 29735e359f..40b7f793cd 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -595,14 +595,14 @@ esxCreateURL(const char *transport,
@@ -588,14 +588,14 @@ esxCreateURL(const char *transport,
int port,
const char *path)
{

View File

@ -0,0 +1,744 @@
From 0e7f26e483e8ea25b6cb4c8d91a0e155c8576609 Mon Sep 17 00:00:00 2001
Message-ID: <0e7f26e483e8ea25b6cb4c8d91a0e155c8576609.1779180941.git.jdenemar@redhat.com>
From: Martin Kletzander <mkletzan@redhat.com>
Date: Tue, 12 May 2026 12:16:54 +0200
Subject: [PATCH] esx: Track VMs by instanceUuid instead of UUID
The difference is that the usual UUID is supposed to be unique per host
and instanceUuid should be unique across the whole cluster. One could
think of them as HUID and CUID (as the first "U" does apparently mean
something else in the Broadcom world). That _would_ be fine for our
scenario. However, that piece of information turns out to be false as
well and the UUID we were using (`config.uuid`, or in VMX the
`uuid.bios`) can be the same in two machines on the same host.
Fortunately the `FindByUuid()` function can also search for VMs based on
their `instanceUuid`, dictated by the so far omitted third parameter.
Unfortunately that parameter is not parsed (or at least properly) before
vSphere API 4.0 (the documentation says 2.0, but we are not using that
namespace and 4.0 is the lowest we can target), which we are not
specifying in the server returns a 500 HTTP error if we use the
`instanceUuid` parameter.
So this patch adds the `SOAPAction: urn:vim25/4.0` header to the cURL
requests which makes that `FindByUuid()` function work even with the
`instanceUuid` set, but without any extra labor.
After that this patch also changes all UUIDs to be parsed from the
`config.instanceUuid` (or `vc.uuid` in the VMX, but there's a fallback
to the old `uuid.bios`) and adjusts tests accordingly.
To give users (and management applications) the possibility to revert
back to the previous (legacy) behaviour a new URI query parameter is
introduced, called `legacy_uuid` which, if set to `1`, still keeps the
code working as it did before this patch.
Last, but not least it changes the parameter to aforementioned function
to be true (unless the legacy behaviour is requested, of course) and
henceforth all searching ought to be done with the more unique ID.
Resolves: https://redhat.atlassian.net/browse/RHEL-174300
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit ac2d865eda4eb2633f53c7222000e51d09c581e4)
Resolves: https://redhat.atlassian.net/browse/RHEL-177479
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
---
docs/drvesx.rst | 24 ++++++++++++
src/esx/esx_driver.c | 43 +++++++++++++++-------
src/esx/esx_util.c | 11 ++++++
src/esx/esx_util.h | 1 +
src/esx/esx_vi.c | 32 ++++++++++++++--
src/esx/esx_vi.h | 3 ++
src/vmx/vmx.c | 12 +++++-
tests/vmx2xmldata/case-insensitive-1.xml | 1 +
tests/vmx2xmldata/case-insensitive-2.xml | 1 +
tests/vmx2xmldata/esx-in-the-wild-1.xml | 1 +
tests/vmx2xmldata/esx-in-the-wild-10.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-11.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-12.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-13.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-14.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-15.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-16.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-17.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-2.xml | 1 +
tests/vmx2xmldata/esx-in-the-wild-3.xml | 1 +
tests/vmx2xmldata/esx-in-the-wild-4.xml | 1 +
tests/vmx2xmldata/esx-in-the-wild-5.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-6.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-7.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-8.xml | 3 +-
tests/vmx2xmldata/esx-in-the-wild-9.xml | 3 +-
tests/vmx2xmldata/fusion-in-the-wild-1.xml | 1 +
tests/vmx2xmldata/gsx-in-the-wild-1.xml | 1 +
tests/vmx2xmldata/gsx-in-the-wild-2.xml | 1 +
tests/vmx2xmldata/gsx-in-the-wild-3.xml | 1 +
tests/vmx2xmldata/gsx-in-the-wild-4.xml | 1 +
31 files changed, 143 insertions(+), 33 deletions(-)
diff --git a/docs/drvesx.rst b/docs/drvesx.rst
index 84416562ba..dcf9e73678 100644
--- a/docs/drvesx.rst
+++ b/docs/drvesx.rst
@@ -156,6 +156,15 @@ The driver understands the extra parameters shown below.
| | | ``no_verify`` is set |
| | | to ``1``. |
+-----------------+-----------------------------+-----------------------------+
+| ``legacy_uuid`` | ``0`` or ``1`` | If set to ``1``, the driver |
+| | | will track VMs based on |
+| | | their "Host-unique" UUID. |
+| | | If set to ``0`` it will use |
+| | | the "Cluster-unique" UUID |
+| | | instead. The default value |
+| | | is ``0``. |
+| | | :since:`Since 12.4.0`. |
++-----------------+-----------------------------+-----------------------------+
Authentication
~~~~~~~~~~~~~~
@@ -172,6 +181,21 @@ distinguish between requests for ESX server and vCenter.
unrestricted ``root`` account. Problems may occur if you use a restricted
account. Detailed testing with restricted accounts has not been done yet.
+UUID Stability
+~~~~~~~~~~~~~~
+
+:since:`Since 12.4.0` there is a change to which UUIDs a domain can be
+identified with. Before this version there was a possible clash of UUIDs even
+on the same host, leading to unexpected issues. In order to fix this libvirt
+started using a different UUID which might cause issues if any user has a domain
+UUID saved anywhere. The older UUID is still available under ``<hwuuid>`` in
+the `General metadata <formatdomain.html#general-metadata>`__ section of the
+domain XML.
+
+In order to restore the previous behaviour parameter ``legacy_uuid=1`` (see
+`Extra parameters`_) can be appended to the URI, but only if needed as it may
+cause the aforementioned issues.
+
Certificates for HTTPS
~~~~~~~~~~~~~~~~~~~~~~
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 010c62b8e8..3ca171b09a 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -1418,8 +1418,9 @@ esxDomainLookupByID(virConnectPtr conn, int id)
if (esxVI_String_AppendValueListToList(&propertyNameList,
"configStatus\0"
"name\0"
- "runtime.powerState\0"
- "config.uuid\0") < 0 ||
+ "runtime.powerState\0") < 0 ||
+ esxVI_String_AppendValueToList(&propertyNameList,
+ priv->primary->uuid_key) < 0 ||
esxVI_LookupVirtualMachineList(priv->primary, propertyNameList,
&virtualMachineList) < 0) {
goto cleanup;
@@ -1439,6 +1440,7 @@ esxDomainLookupByID(virConnectPtr conn, int id)
continue;
if (esxVI_GetVirtualMachineIdentity(virtualMachine,
+ priv->primary->uuid_key,
&id_candidate, &name_candidate,
uuid_candidate) < 0) {
goto cleanup;
@@ -1486,7 +1488,7 @@ esxDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
esxVI_LookupVirtualMachineByUuid(priv->primary, uuid, propertyNameList,
&virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
- esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, NULL) < 0 ||
+ esxVI_GetVirtualMachineIdentity(virtualMachine, NULL, &id, &name, NULL) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
goto cleanup;
}
@@ -1521,15 +1523,17 @@ esxDomainLookupByName(virConnectPtr conn, const char *name)
if (esxVI_String_AppendValueListToList(&propertyNameList,
"configStatus\0"
- "runtime.powerState\0"
- "config.uuid\0") < 0 ||
+ "runtime.powerState\0") < 0 ||
+ esxVI_String_AppendValueToList(&propertyNameList,
+ priv->primary->uuid_key) < 0 ||
esxVI_LookupVirtualMachineByName(priv->primary, name, propertyNameList,
&virtualMachine,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
- if (esxVI_GetVirtualMachineIdentity(virtualMachine, &id, NULL, uuid) < 0 ||
+ if (esxVI_GetVirtualMachineIdentity(virtualMachine, priv->primary->uuid_key,
+ &id, NULL, uuid) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
goto cleanup;
}
@@ -2583,7 +2587,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachineMORef(virtualMachine, &moref) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0 ||
- esxVI_GetVirtualMachineIdentity(virtualMachine, &id, NULL, NULL) < 0 ||
+ esxVI_GetVirtualMachineIdentity(virtualMachine, NULL, &id, NULL, NULL) < 0 ||
esxVI_GetStringValue(virtualMachine, "config.files.vmPathName",
&vmPathName, esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
@@ -2630,6 +2634,9 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
if (powerState != esxVI_VirtualMachinePowerState_PoweredOff)
def->id = id;
+ if (priv->primary->legacy_uuid)
+ memcpy(def->uuid, def->hw_uuid, VIR_UUID_BUFLEN);
+
xml = virDomainDefFormat(def, priv->xmlopt,
virDomainDefFormatConvertXMLFlags(flags));
}
@@ -2771,7 +2778,7 @@ esxConnectListDefinedDomains(virConnectPtr conn, char **const names, int maxname
names[count] = NULL;
- if (esxVI_GetVirtualMachineIdentity(virtualMachine, NULL, &names[count],
+ if (esxVI_GetVirtualMachineIdentity(virtualMachine, NULL, NULL, &names[count],
NULL) < 0) {
goto cleanup;
}
@@ -2838,7 +2845,7 @@ esxDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
(priv->primary, domain->uuid, propertyNameList, &virtualMachine,
priv->parsedUri->autoAnswer) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0 ||
- esxVI_GetVirtualMachineIdentity(virtualMachine, &id, NULL, NULL) < 0) {
+ esxVI_GetVirtualMachineIdentity(virtualMachine, NULL, &id, NULL, NULL) < 0) {
goto cleanup;
}
@@ -4787,8 +4794,9 @@ esxConnectListAllDomains(virConnectPtr conn,
/* Request required data for esxVI_GetVirtualMachineIdentity */
if (esxVI_String_AppendValueListToList(&propertyNameList,
"configStatus\0"
- "name\0"
- "config.uuid\0") < 0) {
+ "name\0") < 0 ||
+ esxVI_String_AppendValueToList(&propertyNameList,
+ priv->primary->uuid_key) < 0) {
goto cleanup;
}
}
@@ -4827,8 +4835,11 @@ esxConnectListAllDomains(virConnectPtr conn,
/* If the lookup of the required properties fails for some of the machines
* in the list it's preferrable to return the valid objects instead of
* failing outright */
- if ((needIdentity && esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, uuid) < 0) ||
- (needPowerState && esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0)) {
+ if ((needIdentity &&
+ esxVI_GetVirtualMachineIdentity(virtualMachine, priv->primary->uuid_key,
+ &id, &name, uuid) < 0) ||
+ (needPowerState &&
+ esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0)) {
/* Raise error only if we didn't successfuly fill any domain */
if (count == 0 && !virtualMachine->_next)
@@ -4960,9 +4971,13 @@ esxDomainHasManagedSaveImage(virDomainPtr domain, unsigned int flags)
esxPrivate *priv = domain->conn->privateData;
esxVI_ManagedObjectReference *managedObjectReference = NULL;
char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
+ esxVI_Boolean instanceUuid = esxVI_Boolean_True;
virCheckFlags(0, -1);
+ if (priv->primary->legacy_uuid)
+ instanceUuid = esxVI_Boolean_Undefined;
+
if (esxVI_EnsureSession(priv->primary) < 0)
return -1;
@@ -4970,7 +4985,7 @@ esxDomainHasManagedSaveImage(virDomainPtr domain, unsigned int flags)
if (esxVI_FindByUuid(priv->primary, priv->primary->datacenter->_reference,
uuid_string, esxVI_Boolean_True,
- esxVI_Boolean_Undefined,
+ instanceUuid,
&managedObjectReference) < 0) {
return -1;
}
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index 963bcd0a75..56a1932fdd 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -42,6 +42,7 @@ esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURI *uri)
size_t i;
int noVerify;
int autoAnswer;
+ int legacy_uuid;
char *tmp;
ESX_VI_CHECK_ARG_LIST(parsedUri);
@@ -87,6 +88,16 @@ esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURI *uri)
}
(*parsedUri)->autoAnswer = autoAnswer != 0;
+ } else if (STRCASEEQ(queryParam->name, "legacy_uuid")) {
+ if (virStrToLong_i(queryParam->value, NULL, 10, &legacy_uuid) < 0 ||
+ (legacy_uuid != 0 && legacy_uuid != 1)) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("Query parameter 'legacy_uuid' has unexpected value '%1$s' (should be 0 or 1)"),
+ queryParam->value);
+ goto cleanup;
+ }
+
+ (*parsedUri)->legacy_uuid = legacy_uuid != 0;
} else if (STRCASEEQ(queryParam->name, "proxy")) {
/* Expected format: [<type>://]<hostname>[:<port>] */
(*parsedUri)->proxy = true;
diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h
index 29f01e0c15..545bf7f301 100644
--- a/src/esx/esx_util.h
+++ b/src/esx/esx_util.h
@@ -46,6 +46,7 @@ struct _esxUtil_ParsedUri {
int proxy_port;
char *path;
char *cacert;
+ bool legacy_uuid;
};
int esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURI *uri);
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index cfd783622d..79969e6314 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -300,6 +300,17 @@ esxVI_CURL_Connect(esxVI_CURL *curl, esxUtil_ParsedUri *parsedUri)
curl->headers = curl_slist_append(curl->headers,
"Content-Type: text/xml; charset=UTF-8");
+ /*
+ * Testing showed that the 4.0 version is most close to our current types in
+ * esx_vi_generator.input data. We could update the version if new method
+ * parameters or object properties are needed.
+ *
+ * The other option is to drop the "/x.y" suffix completely once
+ * https://gitlab.com/libvirt/libvirt/-/work_items/878 is implemented since
+ * that will not limit the version at all.
+ */
+ curl->headers = curl_slist_append(curl->headers, "SOAPAction: urn:vim25/4.0");
+
/*
* Add an empty expect header to stop CURL from waiting for a response code
* 100 (Continue) from the server before continuing the POST operation.
@@ -933,7 +944,8 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
if (ctx->productLine == esxVI_ProductLine_VPX)
ctx->hasSessionIsActive = true;
-
+ ctx->legacy_uuid = parsedUri->legacy_uuid;
+ ctx->uuid_key = ctx->legacy_uuid ? "config.uuid" : "config.instanceUuid";
if (esxVI_Login(ctx, username, escapedPassword, NULL, &ctx->session) < 0 ||
esxVI_BuildSelectSetCollection(ctx) < 0) {
@@ -2386,6 +2398,7 @@ esxVI_LookupNumberOfDomainsByPowerState(esxVI_Context *ctx,
int
esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine,
+ const char *uuid_key,
int *id, char **name, unsigned char *uuid)
{
const char *uuid_string = NULL;
@@ -2443,6 +2456,12 @@ esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine,
}
if (uuid) {
+ if (!uuid_key) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot get VM's UUID without supplying a VM UUID key"));
+ goto failure;
+ }
+
if (esxVI_GetManagedEntityStatus(virtualMachine, "configStatus",
&configStatus) < 0) {
goto failure;
@@ -2452,7 +2471,8 @@ esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine,
for (dynamicProperty = virtualMachine->propSet;
dynamicProperty;
dynamicProperty = dynamicProperty->_next) {
- if (STREQ(dynamicProperty->name, "config.uuid")) {
+
+ if (STREQ(dynamicProperty->name, uuid_key)) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_String) < 0) {
goto failure;
@@ -2677,13 +2697,17 @@ esxVI_LookupVirtualMachineByUuid(esxVI_Context *ctx, const unsigned char *uuid,
int result = -1;
esxVI_ManagedObjectReference *managedObjectReference = NULL;
char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
+ esxVI_Boolean instanceUuid = esxVI_Boolean_True;
+
+ if (ctx->legacy_uuid)
+ instanceUuid = esxVI_Boolean_Undefined;
ESX_VI_CHECK_ARG_LIST(virtualMachine);
virUUIDFormat(uuid, uuid_string);
if (esxVI_FindByUuid(ctx, ctx->datacenter->_reference, uuid_string,
- esxVI_Boolean_True, esxVI_Boolean_Undefined,
+ esxVI_Boolean_True, instanceUuid,
&managedObjectReference) < 0) {
return -1;
}
@@ -2743,7 +2767,7 @@ esxVI_LookupVirtualMachineByName(esxVI_Context *ctx, const char *name,
candidate = candidate->_next) {
g_autofree char *name_candidate = NULL;
- if (esxVI_GetVirtualMachineIdentity(candidate, NULL, &name_candidate,
+ if (esxVI_GetVirtualMachineIdentity(candidate, NULL, NULL, &name_candidate,
NULL) < 0) {
goto cleanup;
}
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index b083ef2b0c..98f89278a6 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -199,6 +199,8 @@ struct _esxVI_Context {
esxVI_SelectionSpec *selectSet_datacenterToNetwork;
bool hasQueryVirtualDiskUuid;
bool hasSessionIsActive;
+ bool legacy_uuid;
+ const char *uuid_key;
};
int esxVI_Context_Alloc(esxVI_Context **ctx);
@@ -351,6 +353,7 @@ int esxVI_LookupNumberOfDomainsByPowerState
bool inverse);
int esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine,
+ const char *uuid_key,
int *id, char **name, unsigned char *uuid);
int esxVI_GetNumberOfSnapshotTrees
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index 47eabe33c6..a32bed616f 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -1488,11 +1488,19 @@ virVMXParseConfig(virVMXContext *ctx,
def->scsiBusMaxUnit = SCSI_SUPER_WIDE_BUS_MAX_CONT_UNIT;
}
- /* vmx:uuid.bios -> def:uuid */
+ /* vmx:uuid.bios -> def:hwuuid */
/* FIXME: Need to handle 'uuid.action = "create"' */
- if (virVMXGetConfigUUID(conf, "uuid.bios", def->uuid, true) < 0)
+ if (virVMXGetConfigUUID(conf, "uuid.bios", def->hw_uuid, true) < 0)
goto cleanup;
+ /* vmx:vc.uuid -> def:uuid */
+ if (virVMXGetConfigUUID(conf, "vc.uuid", def->uuid, true) < 0)
+ goto cleanup;
+
+ /* Fallback to legacy behaviour if there is no vc.uuid */
+ if (!virUUIDIsValid(def->uuid))
+ memcpy(def->uuid, def->hw_uuid, VIR_UUID_BUFLEN);
+
/* vmx:displayName -> def:name */
if (virVMXGetConfigString(conf, "displayName", &def->name, true) < 0)
goto cleanup;
diff --git a/tests/vmx2xmldata/case-insensitive-1.xml b/tests/vmx2xmldata/case-insensitive-1.xml
index 7cb6413941..de1ee85614 100644
--- a/tests/vmx2xmldata/case-insensitive-1.xml
+++ b/tests/vmx2xmldata/case-insensitive-1.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>FEDORA11</name>
<uuid>50115e16-9bdc-49d7-f171-53c4d7f91710</uuid>
+ <hwuuid>50115e16-9bdc-49d7-f171-53c4d7f91710</hwuuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/case-insensitive-2.xml b/tests/vmx2xmldata/case-insensitive-2.xml
index 188c3f3cd5..08224814c1 100644
--- a/tests/vmx2xmldata/case-insensitive-2.xml
+++ b/tests/vmx2xmldata/case-insensitive-2.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>fedora11</name>
<uuid>50115e16-9bdc-49d7-f171-53c4d7f91710</uuid>
+ <hwuuid>50115e16-9bdc-49d7-f171-53c4d7f91710</hwuuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-1.xml b/tests/vmx2xmldata/esx-in-the-wild-1.xml
index c15275ccb9..0d10e2b954 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-1.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-1.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>Fedora11</name>
<uuid>50115e16-9bdc-49d7-f171-53c4d7f91710</uuid>
+ <hwuuid>50115e16-9bdc-49d7-f171-53c4d7f91710</hwuuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-10.xml b/tests/vmx2xmldata/esx-in-the-wild-10.xml
index 78129682bd..f4657fb2a6 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-10.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-10.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>w2019biosvmware</name>
- <uuid>421a6177-5aa9-abb7-5924-fc376c18a1b4</uuid>
+ <uuid>501af9f2-6d29-1c76-19a9-b208ede5f374</uuid>
+ <hwuuid>421a6177-5aa9-abb7-5924-fc376c18a1b4</hwuuid>
<genid>13c67c91-9f47-526f-b0d6-e4dd2e4bb4f9</genid>
<memory unit='KiB'>4194304</memory>
<currentMemory unit='KiB'>4194304</currentMemory>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-11.xml b/tests/vmx2xmldata/esx-in-the-wild-11.xml
index 8807a057d7..ea4c0cc641 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-11.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-11.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>esx6.7-rhel7.7-x86_64</name>
- <uuid>422c0152-63ab-cd03-9650-4301ae77aefd</uuid>
+ <uuid>502ca229-12eb-24f6-0c37-c025ff5da005</uuid>
+ <hwuuid>422c0152-63ab-cd03-9650-4301ae77aefd</hwuuid>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-12.xml b/tests/vmx2xmldata/esx-in-the-wild-12.xml
index c5aad90677..16d73fed8e 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-12.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-12.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>Auto-esx8.0-rhell9.3-efi-with-empty-cdrom</name>
- <uuid>4220fca7-11dd-d67e-19cc-fcad0a37c342</uuid>
+ <uuid>5020ca5b-7ac1-5c44-cfa1-9e762e2f933b</uuid>
+ <hwuuid>4220fca7-11dd-d67e-19cc-fcad0a37c342</hwuuid>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-13.xml b/tests/vmx2xmldata/esx-in-the-wild-13.xml
index e6ef947d50..a0438c6b04 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-13.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-13.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>Test-Mig-VM-1 (01ce57d0-4e20-41a5-8b6c-bcbf49a032ec)</name>
- <uuid>421eb458-5448-fc12-2074-83d5e419e138</uuid>
+ <uuid>01ce57d0-4e20-41a5-8b6c-bcbf49a032ec</uuid>
+ <hwuuid>421eb458-5448-fc12-2074-83d5e419e138</hwuuid>
<description>name:Test-Mig-VM-1
userid:962314ba515c48388a0e95c0961709ff
username:admin
diff --git a/tests/vmx2xmldata/esx-in-the-wild-14.xml b/tests/vmx2xmldata/esx-in-the-wild-14.xml
index dd5c2434ee..13c8d16cbf 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-14.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-14.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>wild14</name>
- <uuid>421b223a-f2c1-c7c9-a399-34d2d9fde26d</uuid>
+ <uuid>501b831e-75d8-15f8-36fa-b9e225f395aa</uuid>
+ <hwuuid>421b223a-f2c1-c7c9-a399-34d2d9fde26d</hwuuid>
<description>execution env sandbox automation platform</description>
<memory unit='KiB'>33554432</memory>
<currentMemory unit='KiB'>33554432</currentMemory>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-15.xml b/tests/vmx2xmldata/esx-in-the-wild-15.xml
index 77b094e9d5..5f51c3699f 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-15.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-15.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>dokuwiki</name>
- <uuid>420338bd-1c9e-ad50-99a2-59e92ddda8b6</uuid>
+ <uuid>500341d5-fe23-ac46-8cb3-77a8e5a1143d</uuid>
+ <hwuuid>420338bd-1c9e-ad50-99a2-59e92ddda8b6</hwuuid>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>2</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-16.xml b/tests/vmx2xmldata/esx-in-the-wild-16.xml
index 147bc0825a..2773ec743b 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-16.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-16.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>Auto-esx8.0-rhel9.4-efi-nvme-disk</name>
- <uuid>4220df89-e3a8-8513-f611-ad252bfd7047</uuid>
+ <uuid>5020196e-c5c8-7310-fcdb-d2933d0c4b2f</uuid>
+ <hwuuid>4220df89-e3a8-8513-f611-ad252bfd7047</hwuuid>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-17.xml b/tests/vmx2xmldata/esx-in-the-wild-17.xml
index ae66de7431..047885320a 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-17.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-17.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>esx8.0-win11-with-second-disk-in-subfolder</name>
- <uuid>42256ec1-e066-9364-3dd1-36a0b75263dd</uuid>
+ <uuid>50250f27-538b-5091-a43b-a50ce95f2382</uuid>
+ <hwuuid>42256ec1-e066-9364-3dd1-36a0b75263dd</hwuuid>
<genid>3191ed70-eb21-9c71-2478-373fb27fed9b</genid>
<memory unit='KiB'>4194304</memory>
<currentMemory unit='KiB'>4194304</currentMemory>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-2.xml b/tests/vmx2xmldata/esx-in-the-wild-2.xml
index 59071b5d3a..5f4ae10131 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-2.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-2.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>virtDebian1</name>
<uuid>564dcd37-3685-8889-35ea-719fc93c983e</uuid>
+ <hwuuid>564dcd37-3685-8889-35ea-719fc93c983e</hwuuid>
<memory unit='KiB'>1024000</memory>
<currentMemory unit='KiB'>120832</currentMemory>
<vcpu placement='static' cpuset='0-2,5-7'>4</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-3.xml b/tests/vmx2xmldata/esx-in-the-wild-3.xml
index cbe8eceb37..8de543c6ff 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-3.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-3.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>virtDebian2</name>
<uuid>564db768-f332-42ee-6201-06973cf5c30c</uuid>
+ <hwuuid>564db768-f332-42ee-6201-06973cf5c30c</hwuuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static' cpuset='0,3-5'>2</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-4.xml b/tests/vmx2xmldata/esx-in-the-wild-4.xml
index a8a2ac6f97..2a41949f1d 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-4.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-4.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>virtMonServ1</name>
<uuid>564d9bef-acd9-b4e0-c8f0-aea8b9103515</uuid>
+ <hwuuid>564d9bef-acd9-b4e0-c8f0-aea8b9103515</hwuuid>
<memory unit='KiB'>524288</memory>
<currentMemory unit='KiB'>524288</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-5.xml b/tests/vmx2xmldata/esx-in-the-wild-5.xml
index 9eb975afe9..f8c5bb5664 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-5.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-5.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>vmtest.local</name>
- <uuid>423e94a9-a1c7-b31d-7161-76c7586c830e</uuid>
+ <uuid>503e06db-f8d5-458e-a2fb-f9820253a7be</uuid>
+ <hwuuid>423e94a9-a1c7-b31d-7161-76c7586c830e</hwuuid>
<description>Centos 5.5 64bit Server</description>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-6.xml b/tests/vmx2xmldata/esx-in-the-wild-6.xml
index 51c74dd8a1..9abbc32023 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-6.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-6.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>el6-test</name>
- <uuid>564d15d4-d062-fe9a-80f5-eb8e1a2c3afc</uuid>
+ <uuid>5200b69b-8d88-7bdf-a14a-02705d653772</uuid>
+ <hwuuid>564d15d4-d062-fe9a-80f5-eb8e1a2c3afc</hwuuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-7.xml b/tests/vmx2xmldata/esx-in-the-wild-7.xml
index c117bd62e5..c5858646ba 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-7.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-7.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>esx-rhel6-mini-with-scsi-device</name>
- <uuid>564d9176-621f-0239-f5ad-3a002371953b</uuid>
+ <uuid>52409533-33a2-56c5-36ce-80d605f8ecf4</uuid>
+ <hwuuid>564d9176-621f-0239-f5ad-3a002371953b</hwuuid>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-8.xml b/tests/vmx2xmldata/esx-in-the-wild-8.xml
index 47d22ced2a..9842ed591f 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-8.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-8.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>RHEL7_10_NICs</name>
- <uuid>42359420-99dc-4261-5264-ba58ddae20e4</uuid>
+ <uuid>50351de6-7d56-29ab-9d72-c7f9ea3fcfd0</uuid>
+ <hwuuid>42359420-99dc-4261-5264-ba58ddae20e4</hwuuid>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>8</vcpu>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-9.xml b/tests/vmx2xmldata/esx-in-the-wild-9.xml
index ee6be2527f..f3ce068025 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-9.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-9.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>v2v-windows-kkulkarn</name>
- <uuid>42009372-17da-be73-779d-007ccf1bd228</uuid>
+ <uuid>5000d2b0-616e-6129-8c06-82b07440a871</uuid>
+ <hwuuid>42009372-17da-be73-779d-007ccf1bd228</hwuuid>
<description>MIQ GUID=b55c806d-99b9-4fa5-bbcc-a4de04f822e5</description>
<memory unit='KiB'>16777216</memory>
<currentMemory unit='KiB'>16777216</currentMemory>
diff --git a/tests/vmx2xmldata/fusion-in-the-wild-1.xml b/tests/vmx2xmldata/fusion-in-the-wild-1.xml
index a47fab5cd5..a39bcbb2cd 100644
--- a/tests/vmx2xmldata/fusion-in-the-wild-1.xml
+++ b/tests/vmx2xmldata/fusion-in-the-wild-1.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>ATTM_VM</name>
<uuid>564d7088-01a1-9832-e72b-6790c73b64ea</uuid>
+ <hwuuid>564d7088-01a1-9832-e72b-6790c73b64ea</hwuuid>
<memory unit='KiB'>3657728</memory>
<currentMemory unit='KiB'>3657728</currentMemory>
<vcpu placement='static'>2</vcpu>
diff --git a/tests/vmx2xmldata/gsx-in-the-wild-1.xml b/tests/vmx2xmldata/gsx-in-the-wild-1.xml
index 62ec191c82..ab0368f3a7 100644
--- a/tests/vmx2xmldata/gsx-in-the-wild-1.xml
+++ b/tests/vmx2xmldata/gsx-in-the-wild-1.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>Server1</name>
<uuid>564d1223-f835-c4b1-bbf6-e32390d62bd3</uuid>
+ <hwuuid>564d1223-f835-c4b1-bbf6-e32390d62bd3</hwuuid>
<memory unit='KiB'>32768</memory>
<currentMemory unit='KiB'>32768</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/gsx-in-the-wild-2.xml b/tests/vmx2xmldata/gsx-in-the-wild-2.xml
index 906e4657ca..a9499af0e0 100644
--- a/tests/vmx2xmldata/gsx-in-the-wild-2.xml
+++ b/tests/vmx2xmldata/gsx-in-the-wild-2.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>Server2</name>
<uuid>564d3301-267f-a0ef-8b7d-d45e98d6cba4</uuid>
+ <hwuuid>564d3301-267f-a0ef-8b7d-d45e98d6cba4</hwuuid>
<memory unit='KiB'>32768</memory>
<currentMemory unit='KiB'>32768</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/gsx-in-the-wild-3.xml b/tests/vmx2xmldata/gsx-in-the-wild-3.xml
index 61812851e1..81b630c55a 100644
--- a/tests/vmx2xmldata/gsx-in-the-wild-3.xml
+++ b/tests/vmx2xmldata/gsx-in-the-wild-3.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>Router</name>
<uuid>564ddebe-e86f-d586-0854-a0879cc4be5a</uuid>
+ <hwuuid>564ddebe-e86f-d586-0854-a0879cc4be5a</hwuuid>
<memory unit='KiB'>32768</memory>
<currentMemory unit='KiB'>32768</currentMemory>
<vcpu placement='static'>1</vcpu>
diff --git a/tests/vmx2xmldata/gsx-in-the-wild-4.xml b/tests/vmx2xmldata/gsx-in-the-wild-4.xml
index a65a7d137f..70a60da01a 100644
--- a/tests/vmx2xmldata/gsx-in-the-wild-4.xml
+++ b/tests/vmx2xmldata/gsx-in-the-wild-4.xml
@@ -1,6 +1,7 @@
<domain type='vmware'>
<name>Client</name>
<uuid>564dad58-0629-d3e6-ecfe-8ff839c5e35d</uuid>
+ <hwuuid>564dad58-0629-d3e6-ecfe-8ff839c5e35d</hwuuid>
<memory unit='KiB'>270336</memory>
<currentMemory unit='KiB'>270336</currentMemory>
<vcpu placement='static'>1</vcpu>
--
2.54.0

View File

@ -1,5 +1,5 @@
From abe5489da9a426f9d50dca1c9a99e6a8ed0ec5a2 Mon Sep 17 00:00:00 2001
Message-ID: <abe5489da9a426f9d50dca1c9a99e6a8ed0ec5a2.1768319110.git.jdenemar@redhat.com>
From 1ff41e00c1d0a280b22ba4f8bf4e86472570486a Mon Sep 17 00:00:00 2001
Message-ID: <1ff41e00c1d0a280b22ba4f8bf4e86472570486a.1769699749.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 6 Jan 2026 17:18:03 +0100
Subject: [PATCH] esx: URI encode inventory objects twice
@ -22,18 +22,18 @@ Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 6c9d2591c668732eb05cf17d27c9102ef3d40b39)
Resolves: https://issues.redhat.com/browse/RHEL-140465
Resolves: https://issues.redhat.com/browse/RHEL-140196
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/esx/esx_driver.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 875cd076df..8614ba3f32 100644
index 40b7f793cd..010c62b8e8 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2574,9 +2574,9 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
domain->conn->uri->server, domain->conn->uri->port);
@@ -2599,9 +2599,9 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
"/folder/");
virBufferURIEncodeString(&buffer, directoryAndFileName);
virBufferAddLit(&buffer, "?dcPath=");
- virBufferURIEncodeString(&buffer, priv->primary->datacenterPath);
@ -44,7 +44,7 @@ index 875cd076df..8614ba3f32 100644
url = virBufferContentAndReset(&buffer);
@@ -3009,9 +3009,9 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
@@ -3035,9 +3035,9 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
virBufferURIEncodeString(&buffer, escapedName);
virBufferAddLit(&buffer, ".vmx?dcPath=");

View File

@ -1,5 +1,5 @@
From b6acf18d7eb7391a59a57930a6d96d693de9ae7f Mon Sep 17 00:00:00 2001
Message-ID: <b6acf18d7eb7391a59a57930a6d96d693de9ae7f.1768319110.git.jdenemar@redhat.com>
From 0776d3a966522785927456bf85037503a9d85bd7 Mon Sep 17 00:00:00 2001
Message-ID: <0776d3a966522785927456bf85037503a9d85bd7.1769699749.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 7 Jan 2026 10:34:25 +0100
Subject: [PATCH] esx_util: Introduce esxUtil_EscapeInventoryObject()
@ -21,7 +21,7 @@ Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit ffe74c7c551bd641cbcaa2512ed0ad4a25d3980b)
Resolves: https://issues.redhat.com/browse/RHEL-140465
Resolves: https://issues.redhat.com/browse/RHEL-140196
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/esx/esx_util.c | 18 ++++++++++++++++++
@ -29,7 +29,7 @@ Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2 files changed, 21 insertions(+)
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index 7ee0e5f7c0..9b714d90ba 100644
index 12a34a2275..963bcd0a75 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -448,3 +448,21 @@ esxUtil_EscapeForXml(const char *string)

View File

@ -0,0 +1,45 @@
From c8f630723faa1f5a4ac42a123e0bc21ef47a5682 Mon Sep 17 00:00:00 2001
Message-ID: <c8f630723faa1f5a4ac42a123e0bc21ef47a5682.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Thu, 26 Mar 2026 14:32:36 +0100
Subject: [PATCH] hypervisor: Call virWaitForDevices() after detaching host
devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On systems with selinux enabled starting a VM with managed host device
using IOMMUFD backend can run into race-condition where both libvirt and
udev are setting selinux label on /dev/vfio/devices/vfioX device. If
udev is the last one to set selinux label starting VM fails with:
error: internal error: QEMU unexpectedly closed the monitor (vm='test'): 2026-03-26T15:47:36.620422Z qemu-kvm: -device {"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"20","bus":"pci.7","addr":"0x0"}: vfio hostdev0: Failed to add fd 20 to KVM VFIO device: Invalid argument
We need to wait for udev to finish processing all events.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit b96ea4db3aabac4790d6e1d53e2f309f5e73efae)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/hypervisor/virhostdev.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
index 43155ceb6c..981ca4cd20 100644
--- a/src/hypervisor/virhostdev.c
+++ b/src/hypervisor/virhostdev.c
@@ -782,6 +782,9 @@ virHostdevPreparePCIDevicesImpl(virHostdevManager *mgr,
}
}
+ /* Step 2.5: Wait for udev to handle all events for devices. */
+ virWaitForDevices();
+
/* At this point, all devices are attached to the stub driver and have
* been marked as inactive */
--
2.53.0

View File

@ -0,0 +1,98 @@
From de60967b754a58d40e1e410cbf4c85e18f3411c2 Mon Sep 17 00:00:00 2001
Message-ID: <de60967b754a58d40e1e410cbf4c85e18f3411c2.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 11:57:43 +0100
Subject: [PATCH] hypervisor: Fix virHostdevNeedsVFIO detection
Function virHostdevNeedsVFIO is used only in QEMU to figure out if the
host device needs access to /dev/vfio/vfio, for PCI host devices that is
true only if libvirt is not using IOMMUFD.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit ffa8020d3665f7ff27c6b82e88d3a93674155c8d)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/domain_conf.c | 13 +++++++++++++
src/conf/domain_conf.h | 3 +++
src/hypervisor/virhostdev.c | 9 ++++++++-
src/libvirt_private.syms | 1 +
4 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cddb7181f9..12727c9eef 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32878,6 +32878,19 @@ virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev)
}
+/**
+ * virHostdevIsPCIDeviceWithIOMMUFD:
+ * @hostdev: host device to check
+ *
+ * Returns true if @hostdev is a PCI device with IOMMUFD disabled, false otherwise.
+ */
+bool
+virHostdevIsPCIDeviceWithoutIOMMUFD(const virDomainHostdevDef *hostdev)
+{
+ return virHostdevIsPCIDeviceImpl(hostdev, VIR_TRISTATE_BOOL_NO);
+}
+
+
static void
virDomainObjGetMessagesIOErrorsSrc(virStorageSource *src,
const char *diskdst,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ead3b07475..7f8c02a87b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4728,6 +4728,9 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
bool
virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev)
ATTRIBUTE_NONNULL(1);
+bool
+virHostdevIsPCIDeviceWithoutIOMMUFD(const virDomainHostdevDef *hostdev)
+ ATTRIBUTE_NONNULL(1);
void
virDomainObjGetMessagesIOErrorsChain(virStorageSource *src,
diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
index 7d7df4418d..43155ceb6c 100644
--- a/src/hypervisor/virhostdev.c
+++ b/src/hypervisor/virhostdev.c
@@ -2510,10 +2510,17 @@ virHostdevUpdateActiveNVMeDevices(virHostdevManager *hostdev_mgr,
goto cleanup;
}
+/**
+ * virHostdevNeedsVFIO:
+ * @hostdev: host device to check
+ *
+ * Returns true if using the @hostdev requires access to /dev/vfio/vfio,
+ * otherwise false.
+ */
bool
virHostdevNeedsVFIO(const virDomainHostdevDef *hostdev)
{
- return virHostdevIsPCIDevice(hostdev) ||
+ return virHostdevIsPCIDeviceWithoutIOMMUFD(hostdev) ||
virHostdevIsMdevDevice(hostdev);
}
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9b46e1ea1a..f1fef9d415 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -816,6 +816,7 @@ virDomainQemuMonitorEventStateRegisterID;
virHostdevIsMdevDevice;
virHostdevIsPCIDevice;
virHostdevIsPCIDeviceWithIOMMUFD;
+virHostdevIsPCIDeviceWithoutIOMMUFD;
virHostdevIsSCSIDevice;
--
2.53.0

View File

@ -1,325 +0,0 @@
From bbb7dceccc95c5329fed28d71b35264a0cdf2b3c Mon Sep 17 00:00:00 2001
Message-ID: <bbb7dceccc95c5329fed28d71b35264a0cdf2b3c.1752837271.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 1 Jul 2025 16:11:12 +0200
Subject: [PATCH] hypervisor: Split out individual steps out of
virDomainDriverAutoShutdown
'virDomainDriverAutoShutdown' grew into an unwieldy function. Extract
the code for each of the save/shutdown/poweroff steps into helpers and
call them.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit e13e9b46f62d4d9f0aad33983fda39c5f3f7e645)
https://issues.redhat.com/browse/RHEL-95196
---
src/hypervisor/domain_driver.c | 285 +++++++++++++++++++--------------
1 file changed, 161 insertions(+), 124 deletions(-)
diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 353b8875ec..cce6c64d1b 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -738,6 +738,164 @@ virDomainDriverAutoShutdownActive(virDomainDriverAutoShutdownConfig *cfg)
}
+static void
+virDomainDriverAutoShutdownDoSave(virDomainPtr *domains,
+ bool *transient,
+ size_t numDomains,
+ virDomainDriverAutoShutdownConfig *cfg)
+{
+ g_autofree unsigned int *flags = g_new0(unsigned int, numDomains);
+ size_t i;
+
+ if (cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE)
+ return;
+
+ for (i = 0; i < numDomains; i++) {
+ int state;
+
+ if ((transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ||
+ (!transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT))
+ continue;
+
+ virSystemdNotifyStatus("Suspending '%s' (%zu of %zu)",
+ virDomainGetName(domains[i]), i + 1, numDomains);
+ VIR_INFO("Suspending '%s'", virDomainGetName(domains[i]));
+
+ /*
+ * Pause all VMs to make them stop dirtying pages,
+ * so save is quicker. We remember if any VMs were
+ * paused so we can restore that on resume.
+ */
+ flags[i] = VIR_DOMAIN_SAVE_RUNNING;
+ if (virDomainGetState(domains[i], &state, NULL, 0) == 0) {
+ if (state == VIR_DOMAIN_PAUSED)
+ flags[i] = VIR_DOMAIN_SAVE_PAUSED;
+ }
+ if (cfg->saveBypassCache)
+ flags[i] |= VIR_DOMAIN_SAVE_BYPASS_CACHE;
+
+ if (flags[i] & VIR_DOMAIN_SAVE_RUNNING)
+ virDomainSuspend(domains[i]);
+ }
+
+ for (i = 0; i < numDomains; i++) {
+ virSystemdNotifyStatus("Saving '%s' (%zu of %zu)",
+ virDomainGetName(domains[i]), i + 1, numDomains);
+ VIR_INFO("Saving '%s'", virDomainGetName(domains[i]));
+
+ if (virDomainManagedSave(domains[i], flags[i]) < 0) {
+ VIR_WARN("auto-shutdown: unable to perform managed save of '%s': %s",
+ domains[i]->name,
+ virGetLastErrorMessage());
+ if (flags[i] & VIR_DOMAIN_SAVE_RUNNING)
+ virDomainResume(domains[i]);
+ continue;
+ }
+ virObjectUnref(domains[i]);
+ domains[i] = NULL;
+ }
+}
+
+
+static void
+virDomainDriverAutoShutdownDoShutdown(virDomainPtr *domains,
+ bool *transient,
+ size_t numDomains,
+ virDomainDriverAutoShutdownConfig *cfg)
+{
+ GTimer *timer = NULL;
+ size_t i;
+
+ if (cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE)
+ return;
+
+ for (i = 0; i < numDomains; i++) {
+ if (domains[i] == NULL)
+ continue;
+
+ if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ||
+ (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT))
+ continue;
+
+ virSystemdNotifyStatus("Shutting down '%s' (%zu of %zu)",
+ virDomainGetName(domains[i]), i + 1, numDomains);
+ VIR_INFO("Shutting down '%s'", virDomainGetName(domains[i]));
+
+ if (virDomainShutdown(domains[i]) < 0) {
+ VIR_WARN("auto-shutdown: unable to request graceful shutdown of '%s': %s",
+ domains[i]->name,
+ virGetLastErrorMessage());
+ break;
+ }
+ }
+
+ timer = g_timer_new();
+ virSystemdNotifyStatus("Waiting %u secs for VM shutdown completion",
+ cfg->waitShutdownSecs);
+ VIR_INFO("Waiting %u secs for VM shutdown completion", cfg->waitShutdownSecs);
+ while (1) {
+ bool anyRunning = false;
+ for (i = 0; i < numDomains; i++) {
+ if (!domains[i])
+ continue;
+
+ if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ||
+ (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT))
+ continue;
+
+ if (virDomainIsActive(domains[i]) == 1) {
+ anyRunning = true;
+ } else {
+ virObjectUnref(domains[i]);
+ domains[i] = NULL;
+ }
+ }
+
+ if (!anyRunning)
+ break;
+ if (g_timer_elapsed(timer, NULL) > cfg->waitShutdownSecs)
+ break;
+ g_usleep(1000*500);
+ }
+ g_timer_destroy(timer);
+}
+
+
+static void
+virDomainDriverAutoShutdownDoPoweroff(virDomainPtr *domains,
+ bool *transient,
+ size_t numDomains,
+ virDomainDriverAutoShutdownConfig *cfg)
+{
+ size_t i;
+
+ if (cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE)
+ return;
+
+ for (i = 0; i < numDomains; i++) {
+ if (domains[i] == NULL)
+ continue;
+
+ if ((transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ||
+ (!transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT))
+ continue;
+
+ virSystemdNotifyStatus("Destroying '%s' (%zu of %zu)",
+ virDomainGetName(domains[i]), i + 1, numDomains);
+ VIR_INFO("Destroying '%s'", virDomainGetName(domains[i]));
+ /*
+ * NB might fail if we gave up on waiting for
+ * virDomainShutdown, but it then completed anyway,
+ * hence we're not checking for failure
+ */
+ virDomainDestroy(domains[i]);
+
+ virObjectUnref(domains[i]);
+ domains[i] = NULL;
+ }
+}
+
+
void
virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg)
{
@@ -816,130 +974,9 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg)
}
}
- if (cfg->trySave != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) {
- g_autofree unsigned int *flags = g_new0(unsigned int, numDomains);
- for (i = 0; i < numDomains; i++) {
- int state;
-
- if ((transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ||
- (!transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT))
- continue;
-
- virSystemdNotifyStatus("Suspending '%s' (%zu of %d)",
- virDomainGetName(domains[i]), i + 1, numDomains);
- VIR_INFO("Suspending '%s'", virDomainGetName(domains[i]));
-
- /*
- * Pause all VMs to make them stop dirtying pages,
- * so save is quicker. We remember if any VMs were
- * paused so we can restore that on resume.
- */
- flags[i] = VIR_DOMAIN_SAVE_RUNNING;
- if (virDomainGetState(domains[i], &state, NULL, 0) == 0) {
- if (state == VIR_DOMAIN_PAUSED)
- flags[i] = VIR_DOMAIN_SAVE_PAUSED;
- }
- if (cfg->saveBypassCache)
- flags[i] |= VIR_DOMAIN_SAVE_BYPASS_CACHE;
-
- if (flags[i] & VIR_DOMAIN_SAVE_RUNNING)
- virDomainSuspend(domains[i]);
- }
-
- for (i = 0; i < numDomains; i++) {
- virSystemdNotifyStatus("Saving '%s' (%zu of %d)",
- virDomainGetName(domains[i]), i + 1, numDomains);
- VIR_INFO("Saving '%s'", virDomainGetName(domains[i]));
-
- if (virDomainManagedSave(domains[i], flags[i]) < 0) {
- VIR_WARN("auto-shutdown: unable to perform managed save of '%s': %s",
- domains[i]->name,
- virGetLastErrorMessage());
- if (flags[i] & VIR_DOMAIN_SAVE_RUNNING)
- virDomainResume(domains[i]);
- continue;
- }
- virObjectUnref(domains[i]);
- domains[i] = NULL;
- }
- }
-
- if (cfg->tryShutdown != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) {
- GTimer *timer = NULL;
- for (i = 0; i < numDomains; i++) {
- if (domains[i] == NULL)
- continue;
-
- if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ||
- (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT))
- continue;
-
- virSystemdNotifyStatus("Shutting down '%s' (%zu of %d)",
- virDomainGetName(domains[i]), i + 1, numDomains);
- VIR_INFO("Shutting down '%s'", virDomainGetName(domains[i]));
-
- if (virDomainShutdown(domains[i]) < 0) {
- VIR_WARN("auto-shutdown: unable to request graceful shutdown of '%s': %s",
- domains[i]->name,
- virGetLastErrorMessage());
- break;
- }
- }
-
- timer = g_timer_new();
- virSystemdNotifyStatus("Waiting %u secs for VM shutdown completion",
- cfg->waitShutdownSecs);
- VIR_INFO("Waiting %u secs for VM shutdown completion", cfg->waitShutdownSecs);
- while (1) {
- bool anyRunning = false;
- for (i = 0; i < numDomains; i++) {
- if (!domains[i])
- continue;
-
- if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ||
- (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT))
- continue;
-
- if (virDomainIsActive(domains[i]) == 1) {
- anyRunning = true;
- } else {
- virObjectUnref(domains[i]);
- domains[i] = NULL;
- }
- }
-
- if (!anyRunning)
- break;
- if (g_timer_elapsed(timer, NULL) > cfg->waitShutdownSecs)
- break;
- g_usleep(1000*500);
- }
- g_timer_destroy(timer);
- }
-
- if (cfg->poweroff != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) {
- for (i = 0; i < numDomains; i++) {
- if (domains[i] == NULL)
- continue;
-
- if ((transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ||
- (!transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT))
- continue;
-
- virSystemdNotifyStatus("Destroying '%s' (%zu of %d)",
- virDomainGetName(domains[i]), i + 1, numDomains);
- VIR_INFO("Destroying '%s'", virDomainGetName(domains[i]));
- /*
- * NB might fail if we gave up on waiting for
- * virDomainShutdown, but it then completed anyway,
- * hence we're not checking for failure
- */
- virDomainDestroy(domains[i]);
-
- virObjectUnref(domains[i]);
- domains[i] = NULL;
- }
- }
+ virDomainDriverAutoShutdownDoSave(domains, transient, numDomains, cfg);
+ virDomainDriverAutoShutdownDoShutdown(domains, transient, numDomains, cfg);
+ virDomainDriverAutoShutdownDoPoweroff(domains, transient, numDomains, cfg);
virSystemdNotifyStatus("Processed %d domains", numDomains);
VIR_INFO("Processed %d domains", numDomains);
--
2.50.1

View File

@ -1,77 +0,0 @@
From 8ebd4e7c38291929f8a6c481b768a4d8355ea19c Mon Sep 17 00:00:00 2001
Message-ID: <8ebd4e7c38291929f8a6c481b768a4d8355ea19c.1752837271.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 27 Jun 2025 15:22:22 +0200
Subject: [PATCH] hypervisor: domain: Extract logic for auto shutdown to
virDomainDriverAutoShutdownActive
Extract the checker that determines whether the daemon auto shutdown
functionality is active to a separate helper
'virDomainDriverAutoShutdownActive'.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit bb51963bb173b28dacb6a1374712b1344e9a61c2)
https://issues.redhat.com/browse/RHEL-95361
---
src/hypervisor/domain_driver.c | 13 ++++++++++---
src/hypervisor/domain_driver.h | 1 +
src/libvirt_private.syms | 1 +
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index 62bbe176ae..353b8875ec 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -729,6 +729,15 @@ virDomainDriverAutoStart(virDomainObjList *domains,
}
+bool
+virDomainDriverAutoShutdownActive(virDomainDriverAutoShutdownConfig *cfg)
+{
+ return cfg->trySave != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE ||
+ cfg->tryShutdown != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE ||
+ cfg->poweroff != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE;
+}
+
+
void
virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg)
{
@@ -773,9 +782,7 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg)
}
/* Short-circuit if all actions are disabled */
- if (cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE &&
- cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE &&
- cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE)
+ if (!virDomainDriverAutoShutdownActive(cfg))
return;
if (!(conn = virConnectOpen(cfg->uri)))
diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h
index d90466b942..af1c4eaed6 100644
--- a/src/hypervisor/domain_driver.h
+++ b/src/hypervisor/domain_driver.h
@@ -116,4 +116,5 @@ typedef struct _virDomainDriverAutoShutdownConfig {
bool autoRestore;
} virDomainDriverAutoShutdownConfig;
+bool virDomainDriverAutoShutdownActive(virDomainDriverAutoShutdownConfig *cfg);
void virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8f1489ecc8..1b9be478e4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1658,6 +1658,7 @@ virDomainCgroupSetupVcpuBW;
# hypervisor/domain_driver.h
virDomainDriverAddIOThreadCheck;
virDomainDriverAutoShutdown;
+virDomainDriverAutoShutdownActive;
virDomainDriverAutoShutdownScopeTypeFromString;
virDomainDriverAutoShutdownScopeTypeToString;
virDomainDriverAutoStart;
--
2.50.1

View File

@ -0,0 +1,69 @@
From af33f07936bd97081a626499700a872c9cfdbecb Mon Sep 17 00:00:00 2001
Message-ID: <af33f07936bd97081a626499700a872c9cfdbecb.1772815314.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 30 Jan 2026 18:34:40 +0100
Subject: [PATCH] include: Mention varstore where applicable
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We are not introducing additional API flags for varstore
handling since that would require unnecessary churn in all
libvirt-based apps, and the intent is the same: recreate
the UEFI variable storage, be it NVRAM or varstore, from its
template.
In order to clarify that the existing flags affect varstore
too, update their documentation.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 31e40b6229cd3bc1affaecdc577f1ec1dd85d54c)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
include/libvirt/libvirt-domain-snapshot.h | 2 +-
include/libvirt/libvirt-domain.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/libvirt/libvirt-domain-snapshot.h b/include/libvirt/libvirt-domain-snapshot.h
index a11cd3f823..e14b661e37 100644
--- a/include/libvirt/libvirt-domain-snapshot.h
+++ b/include/libvirt/libvirt-domain-snapshot.h
@@ -217,7 +217,7 @@ typedef enum {
VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING = 1 << 0, /* Run after revert (Since: 0.9.5) */
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED = 1 << 1, /* Pause after revert (Since: 0.9.5) */
VIR_DOMAIN_SNAPSHOT_REVERT_FORCE = 1 << 2, /* Allow risky reverts (Since: 0.9.7) */
- VIR_DOMAIN_SNAPSHOT_REVERT_RESET_NVRAM = 1 << 3, /* Re-initialize NVRAM from template (Since: 8.1.0) */
+ VIR_DOMAIN_SNAPSHOT_REVERT_RESET_NVRAM = 1 << 3, /* Re-initialize NVRAM/varstore from template (Since: 8.1.0) */
} virDomainSnapshotRevertFlags;
/* Revert the domain to a point-in-time snapshot. The
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 8e62bd23d4..221e22443e 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -371,7 +371,7 @@ typedef enum {
VIR_DOMAIN_START_BYPASS_CACHE = 1 << 2, /* Avoid file system cache pollution (Since: 0.9.4) */
VIR_DOMAIN_START_FORCE_BOOT = 1 << 3, /* Boot, discarding any managed save (Since: 0.9.5) */
VIR_DOMAIN_START_VALIDATE = 1 << 4, /* Validate the XML document against schema (Since: 1.2.12) */
- VIR_DOMAIN_START_RESET_NVRAM = 1 << 5, /* Re-initialize NVRAM from template (Since: 8.1.0) */
+ VIR_DOMAIN_START_RESET_NVRAM = 1 << 5, /* Re-initialize NVRAM/varstore from template (Since: 8.1.0) */
} virDomainCreateFlags;
@@ -1652,7 +1652,7 @@ typedef enum {
VIR_DOMAIN_SAVE_BYPASS_CACHE = 1 << 0, /* Avoid file system cache pollution (Since: 0.9.4) */
VIR_DOMAIN_SAVE_RUNNING = 1 << 1, /* Favor running over paused (Since: 0.9.5) */
VIR_DOMAIN_SAVE_PAUSED = 1 << 2, /* Favor paused over running (Since: 0.9.5) */
- VIR_DOMAIN_SAVE_RESET_NVRAM = 1 << 3, /* Re-initialize NVRAM from template (Since: 8.1.0) */
+ VIR_DOMAIN_SAVE_RESET_NVRAM = 1 << 3, /* Re-initialize NVRAM/varstore from template (Since: 8.1.0) */
} virDomainSaveRestoreFlags;
int virDomainSave (virDomainPtr domain,
--
2.53.0

View File

@ -0,0 +1,38 @@
From a07ea47ade888579a3ceb1699a2e029c699fda4f Mon Sep 17 00:00:00 2001
Message-ID: <a07ea47ade888579a3ceb1699a2e029c699fda4f.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Tue, 17 Feb 2026 08:38:07 +0100
Subject: [PATCH] iommufd: fix FD leak in case of error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reported-by: coverity
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit f37e14119c257281eab4fd1fed1b1018fe4f63b1)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/util/viriommufd.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c
index 1f3353eab4..b62d59241d 100644
--- a/src/util/viriommufd.c
+++ b/src/util/viriommufd.c
@@ -87,8 +87,10 @@ virIOMMUFDOpenDevice(void)
if ((fd = open(VIR_IOMMU_DEV_PATH, O_RDWR | O_CLOEXEC)) < 0)
virReportSystemError(errno, "%s", _("cannot open IOMMUFD device"));
- if (virIOMMUFDSetRLimitMode(fd, true) < 0)
+ if (virIOMMUFDSetRLimitMode(fd, true) < 0) {
+ VIR_FORCE_CLOSE(fd);
return -1;
+ }
return fd;
}
--
2.53.0

View File

@ -1,44 +0,0 @@
From c50a7108b0090fdce43c7f9d0cef9c905c989cc5 Mon Sep 17 00:00:00 2001
Message-ID: <c50a7108b0090fdce43c7f9d0cef9c905c989cc5.1752837271.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 1 Jul 2025 13:46:59 +0200
Subject: [PATCH] kbase: tlscerts: Drop 'encryption_key' feature request
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As TLS 1.3 performs key exchange separately from the algorithm used to
verify authenticity, the certificates for libvirt's use of TLS don't
need to require the 'encryption_key' feature any more.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 3da460236968be1c67a38a01711d46cb257a7125)
https://issues.redhat.com/browse/RHEL-100711
---
docs/kbase/tlscerts.rst | 2 --
1 file changed, 2 deletions(-)
diff --git a/docs/kbase/tlscerts.rst b/docs/kbase/tlscerts.rst
index e4aa5bb3c9..215d454998 100644
--- a/docs/kbase/tlscerts.rst
+++ b/docs/kbase/tlscerts.rst
@@ -204,7 +204,6 @@ define the server as follows:
ip_address = 2001:cafe::74
ip_address = fe20::24
tls_www_server
- encryption_key
signing_key
The 'cn' field should refer to the fully qualified public hostname of the
@@ -298,7 +297,6 @@ briefly cover the steps.
organization = Libvirt Project
cn = client1
tls_www_client
- encryption_key
signing_key
and sign by doing:
--
2.50.1

View File

@ -1,137 +0,0 @@
From 2840e187716ce3dbcf79a147e3bee58ed3c96502 Mon Sep 17 00:00:00 2001
Message-ID: <2840e187716ce3dbcf79a147e3bee58ed3c96502.1759908360.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-111863
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 529c65b9b0..7c8f785f32 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(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(vm, 0, false);
+ goto cleanup;
+ }
+
+ if (qemuProcessStart(NULL, driver, vm, NULL, VIR_ASYNC_JOB_START,
+ NULL, -1, NULL, NULL, NULL,
+ VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
+ 0) < 0) {
+ virDomainAuditStart(vm, "booted", false);
+ qemuDomainRemoveInactive(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

@ -1,70 +0,0 @@
From 390dbe0e7dc35d902e038739f011155a26671961 Mon Sep 17 00:00:00 2001
Message-ID: <390dbe0e7dc35d902e038739f011155a26671961.1759908360.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:07 -0400
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-111863
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 732c89fe29..3def894a22 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -741,6 +741,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"amd-iommu", /* QEMU_CAPS_AMD_IOMMU */
"amd-iommu.pci-id", /* QEMU_CAPS_AMD_IOMMU_PCI_ID */
"usb-bot", /* QEMU_CAPS_DEVICE_USB_BOT */
+ "tdx-guest", /* QEMU_CAPS_TDX_GUEST */
);
@@ -1429,6 +1430,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "nvme-ns", QEMU_CAPS_DEVICE_NVME_NS },
{ "amd-iommu", QEMU_CAPS_AMD_IOMMU },
{ "usb-bot", QEMU_CAPS_DEVICE_USB_BOT },
+ { "tdx-guest", QEMU_CAPS_TDX_GUEST},
};
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 966e30fa11..2c78ea14f3 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -722,6 +722,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_AMD_IOMMU, /* -device amd-iommu */
QEMU_CAPS_AMD_IOMMU_PCI_ID, /* amd-iommu.pci-id */
QEMU_CAPS_DEVICE_USB_BOT, /* -device usb-bot */
+ 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 5744a7a305..4be89b68d9 100644
--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
+++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
@@ -191,6 +191,7 @@
<flag name='amd-iommu'/>
<flag name='amd-iommu.pci-id'/>
<flag name='usb-bot'/>
+ <flag name='tdx-guest'/>
<version>10000050</version>
<microcodeVersion>43100286</microcodeVersion>
<package>v10.0.0-1724-gf9a3def17b</package>
--
2.51.0

View File

@ -1,114 +0,0 @@
From f2e592b5b406d59c9de56c3e7870777f56251281 Mon Sep 17 00:00:00 2001
Message-ID: <f2e592b5b406d59c9de56c3e7870777f56251281.1759908360.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-111863
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
src/conf/domain_conf.h | 5 +++++
src/qemu/qemu_command.c | 27 +++++++++++++++++++++++++++
src/qemu/qemu_validate.c | 12 ++++++++++++
3 files changed, 44 insertions(+)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e216c63018..51c05a3f18 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3008,6 +3008,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 5a52014c23..9b72cfbfd3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9952,6 +9952,32 @@ qemuBuildPVCommandLine(virCommand *cmd)
}
+static int
+qemuBuildTDXCommandLine(virCommand *cmd, virDomainTDXDef *tdx)
+{
+ g_autoptr(virJSONValue) props = NULL;
+
+ 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) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static int
qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
virDomainSecDef *sec)
@@ -9970,6 +9996,7 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
return qemuBuildPVCommandLine(cmd);
case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ return qemuBuildTDXCommandLine(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 93e191dd13..ef9f326a9b 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1414,6 +1414,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

@ -1,81 +0,0 @@
From c11fc06e0fa1d174eb46794f9a73125ff2a28e7a Mon Sep 17 00:00:00 2001
Message-ID: <c11fc06e0fa1d174eb46794f9a73125ff2a28e7a.1759908360.git.jdenemar@redhat.com>
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Thu, 10 Jul 2025 03:21:17 -0400
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-111863
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 cf5437f642..b89162df42 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2999,6 +2999,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 9b72cfbfd3..17b2c98211 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9955,15 +9955,29 @@ qemuBuildPVCommandLine(virCommand *cmd)
static int
qemuBuildTDXCommandLine(virCommand *cmd, virDomainTDXDef *tdx)
{
+ g_autoptr(virJSONValue) addr = NULL;
g_autoptr(virJSONValue) props = NULL;
+ 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

@ -1,48 +0,0 @@
From bfd9b7a87e4a8add0536d6252b60c8d90a16ad1b Mon Sep 17 00:00:00 2001
Message-ID: <bfd9b7a87e4a8add0536d6252b60c8d90a16ad1b.1759908360.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-111863
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 6d984df412..d726175d42 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1073,6 +1073,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

@ -1,68 +0,0 @@
From 475fe7ef2cd5110a9b05437d0a4aaaf2b83fb48e Mon Sep 17 00:00:00 2001
Message-ID: <475fe7ef2cd5110a9b05437d0a4aaaf2b83fb48e.1759908359.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-111863
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 b02f8e7a01..732c89fe29 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -5322,6 +5322,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.
@@ -5335,7 +5353,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,125 @@
From 48ae2b31930d1b5203c88acd6498893948aa2674 Mon Sep 17 00:00:00 2001
Message-ID: <48ae2b31930d1b5203c88acd6498893948aa2674.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 19:42:39 +0100
Subject: [PATCH] qemu: Convert IOMMUFD to qemuFDPassDirect
This cleans up creating QEMU command line and makes it easier when
adding hotplug support.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit df59beed37db5451a44955c1c440eebc474bffb2)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_command.c | 7 ++-----
src/qemu/qemu_domain.c | 4 ++--
src/qemu/qemu_domain.h | 2 +-
src/qemu/qemu_process.c | 6 ++++--
tests/qemuxmlconftest.c | 6 ++++--
5 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3119191413..443780eff5 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5350,19 +5350,16 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd,
virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
- g_autofree char *fdstr = g_strdup_printf("%d", priv->iommufd);
g_autoptr(virJSONValue) props = NULL;
if (!virDomainDefHasPCIHostdevWithIOMMUFD(def))
return 0;
- virCommandPassFD(cmd, priv->iommufd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
-
- priv->iommufd = -1;
+ qemuFDPassDirectTransferCommand(priv->iommufd, cmd);
if (qemuMonitorCreateObjectProps(&props, "iommufd",
"iommufd0",
- "S:fd", fdstr,
+ "S:fd", qemuFDPassDirectGetPath(priv->iommufd),
NULL) < 0)
return -1;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 64b01e524f..d9cd9324e0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1975,7 +1975,7 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivate *priv)
priv->migrationRecoverSetup = false;
- VIR_FORCE_CLOSE(priv->iommufd);
+ g_clear_pointer(&priv->iommufd, qemuFDPassDirectFree);
g_clear_pointer(&priv->memoryBackingDir, g_free);
}
@@ -2044,7 +2044,7 @@ qemuDomainObjPrivateAlloc(void *opaque)
priv->blockjobs = virHashNew(virObjectUnref);
priv->fds = virHashNew(g_object_unref);
- priv->iommufd = -1;
+ priv->iommufd = NULL;
priv->pidMonitored = -1;
/* agent commands block by default, user can choose different behavior */
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 30ca67bf76..a5403ecc93 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -264,7 +264,7 @@ struct _qemuDomainObjPrivate {
/* named file descriptor groups associated with the VM */
GHashTable *fds;
- int iommufd;
+ qemuFDPassDirect *iommufd;
char *memoryBackingDir;
};
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 3729edcd7e..91167d73bc 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7685,13 +7685,15 @@ static int
qemuProcessOpenIommuFd(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
+ int iommufd;
VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name);
- if ((priv->iommufd = virIOMMUFDOpenDevice()) < 0)
+ if ((iommufd = virIOMMUFDOpenDevice()) < 0)
return -1;
- VIR_DEBUG("Opened IOMMU FD %d for domain %s", priv->iommufd, vm->def->name);
+ priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
+
return 0;
}
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 6f16b6cee8..b58bdc1f80 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -406,8 +406,10 @@ testQemuPrepareHostdev(virDomainObj *vm)
}
}
- if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def))
- priv->iommufd = 0;
+ if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
+ int iommufd = 0;
+ priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
+ }
}
--
2.53.0

View File

@ -0,0 +1,129 @@
From f0bc052ed97cd00f6d3da0493bb33b95db93a776 Mon Sep 17 00:00:00 2001
Message-ID: <f0bc052ed97cd00f6d3da0493bb33b95db93a776.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 19:28:16 +0100
Subject: [PATCH] qemu: Convert vfioDeviceFd to qemuFDPassDirect
This cleans up creating QEMU command line and makes it easier when
adding hotplug support.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 4611f227c7882c8b9237da5e2fab21932ef6bd51)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_command.c | 15 +++++----------
src/qemu/qemu_domain.c | 4 ++--
src/qemu/qemu_domain.h | 2 +-
src/qemu/qemu_process.c | 6 +++++-
tests/qemuxmlconftest.c | 4 +++-
5 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 443780eff5..33127fbc0a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4811,12 +4811,10 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_YES) {
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev);
- if (hostdevPriv->vfioDeviceFd != -1) {
- g_autofree char *fdstr = g_strdup_printf("%d", hostdevPriv->vfioDeviceFd);
- if (virJSONValueObjectAdd(&props, "S:fd", fdstr, NULL) < 0)
- return NULL;
- hostdevPriv->vfioDeviceFd = -1;
- }
+ if (virJSONValueObjectAdd(&props,
+ "S:fd", qemuFDPassDirectGetPath(hostdevPriv->vfioDeviceFd),
+ NULL) < 0)
+ return NULL;
}
if (qemuBuildDeviceAddressProps(props, def, dev->info) < 0)
@@ -5266,10 +5264,7 @@ qemuBuildHostdevCommandLine(virCommand *cmd,
if (subsys->u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) {
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
- if (hostdevPriv->vfioDeviceFd != -1) {
- virCommandPassFD(cmd, hostdevPriv->vfioDeviceFd,
- VIR_COMMAND_PASS_FD_CLOSE_PARENT);
- }
+ qemuFDPassDirectTransferCommand(hostdevPriv->vfioDeviceFd, cmd);
}
if (!(devprops = qemuBuildPCIHostdevDevProps(def, hostdev)))
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d9cd9324e0..ada9d3431c 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1245,7 +1245,7 @@ qemuDomainHostdevPrivateDispose(void *obj)
{
qemuDomainHostdevPrivate *priv = obj;
- VIR_FORCE_CLOSE(priv->vfioDeviceFd);
+ g_clear_pointer(&priv->vfioDeviceFd, qemuFDPassDirectFree);
}
@@ -1271,7 +1271,7 @@ qemuDomainHostdevPrivateNew(void)
if (!(priv = virObjectNew(qemuDomainHostdevPrivateClass)))
return NULL;
- priv->vfioDeviceFd = -1;
+ priv->vfioDeviceFd = NULL;
return (virObject *) priv;
}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index a5403ecc93..8aa94fc25b 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -471,7 +471,7 @@ struct _qemuDomainHostdevPrivate {
virObject parent;
/* VFIO device file descriptor for iommufd passthrough */
- int vfioDeviceFd;
+ qemuFDPassDirect *vfioDeviceFd;
};
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 91167d73bc..59fff1aa19 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7710,10 +7710,14 @@ qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
{
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
virDomainHostdevSubsysPCI *pci = &hostdev->source.subsys.u.pci;
+ g_autofree char *name = g_strdup_printf("hostdev-%s-fd", hostdev->info->alias);
+ int vfioDeviceFd;
- if ((hostdevPriv->vfioDeviceFd = virPCIDeviceOpenVfioFd(&pci->addr)) < 0)
+ if ((vfioDeviceFd = virPCIDeviceOpenVfioFd(&pci->addr)) < 0)
return -1;
+ hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFd);
+
return 0;
}
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index b58bdc1f80..bddd659fd4 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -357,8 +357,10 @@ testQemuPrepareHostdevPCI(virDomainHostdevDef *hostdev)
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
+ g_autofree char *name = g_strdup_printf("hostdev-%s-fd", hostdev->info->alias);
/* Use a placeholder FD value for tests */
- hostdevPriv->vfioDeviceFd = 0;
+ int vfioDeviceFD = 0;
+ hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFD);
}
}
--
2.53.0

View File

@ -0,0 +1,118 @@
From ab8dbe11d56790f6fd140919559ad7610cc1f535 Mon Sep 17 00:00:00 2001
Message-ID: <ab8dbe11d56790f6fd140919559ad7610cc1f535.1772815314.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 23 Jan 2026 19:47:13 +0100
Subject: [PATCH] qemu: Create and delete varstore file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Simply mimicking what is currently done for NVRAM files does
the trick. A few user-visible messages are updated to reflect
the fact that they apply both to NVRAM and varstore.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 5dc97de2c4fb4c2097c29cbe0eb38e3cdb4e92b0)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/qemu/qemu_driver.c | 14 +++++++++-----
src/qemu/qemu_process.c | 28 ++++++++++++++++++++++++++--
2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d314aa94ce..ad894c7584 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6639,22 +6639,26 @@ qemuDomainUndefineFlags(virDomainPtr dom,
}
}
- if (vm->def->os.loader && vm->def->os.loader->nvram &&
- virStorageSourceIsLocalStorage(vm->def->os.loader->nvram)) {
- nvram_path = g_strdup(vm->def->os.loader->nvram->path);
+ if (vm->def->os.loader) {
+ if (vm->def->os.loader->nvram &&
+ virStorageSourceIsLocalStorage(vm->def->os.loader->nvram)) {
+ nvram_path = g_strdup(vm->def->os.loader->nvram->path);
+ } else if (vm->def->os.varstore && vm->def->os.varstore->path) {
+ nvram_path = g_strdup(vm->def->os.varstore->path);
+ }
}
if (nvram_path && virFileExists(nvram_path)) {
if ((flags & VIR_DOMAIN_UNDEFINE_NVRAM)) {
if (unlink(nvram_path) < 0) {
virReportSystemError(errno,
- _("failed to remove nvram: %1$s"),
+ _("Failed to remove NVRAM/varstore: %1$s"),
nvram_path);
goto endjob;
}
} else if (!(flags & VIR_DOMAIN_UNDEFINE_KEEP_NVRAM)) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("cannot undefine domain with nvram"));
+ _("Cannot undefine domain with NVRAM/varstore"));
goto endjob;
}
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 47deb9abb9..3ca87df284 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5031,6 +5031,27 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
}
+static int
+qemuPrepareVarstore(virQEMUDriver *driver,
+ virDomainDef *def,
+ bool reset_nvram)
+{
+ virDomainLoaderDef *loader = def->os.loader;
+ virDomainVarstoreDef *varstore = def->os.varstore;
+
+ if (!loader || !varstore)
+ return 0;
+
+ VIR_DEBUG("varstore='%s'", NULLSTR(varstore->path));
+
+ if (qemuPrepareNVRAMFileCommon(driver, varstore->path,
+ varstore->template, reset_nvram) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static void
qemuLogOperation(virDomainObj *vm,
const char *msg,
@@ -7795,6 +7816,7 @@ qemuProcessPrepareHost(virQEMUDriver *driver,
unsigned int hostdev_flags = 0;
qemuDomainObjPrivate *priv = vm->privateData;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+ bool reset_nvram = !!(flags & VIR_QEMU_PROCESS_START_RESET_NVRAM);
/*
* Create all per-domain directories in order to make sure domain
@@ -7804,8 +7826,10 @@ qemuProcessPrepareHost(virQEMUDriver *driver,
qemuProcessMakeDir(driver, vm, priv->channelTargetDir) < 0)
return -1;
- if (qemuPrepareNVRAM(driver, vm->def,
- !!(flags & VIR_QEMU_PROCESS_START_RESET_NVRAM)) < 0)
+ if (qemuPrepareNVRAM(driver, vm->def, reset_nvram) < 0)
+ return -1;
+
+ if (qemuPrepareVarstore(driver, vm->def, reset_nvram) < 0)
return -1;
if (vm->def->vsock) {
--
2.53.0

View File

@ -0,0 +1,51 @@
From be3005e77a42998ca56ccf410c24d25561d1ae69 Mon Sep 17 00:00:00 2001
Message-ID: <be3005e77a42998ca56ccf410c24d25561d1ae69.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 12:52:05 +0100
Subject: [PATCH] qemu: Expand call to qemuDomainNeedsVFIO
The function qemuDomainNeedsVFIO() was originally used by other parts
of qemu code to figure out if the VM needs /dev/vfio/vfio.
Later it was also used by code calculating locked memory limit for all
architectures, and after that change again and used only for PPC64.
Now it needs to be changed again due to IOMMUFD support, the
/dev/vfio/vfio device is used by QEMU only if IOMMUFD is not used
but for accounting we still need consider all PCI host devices
because if IOMMUFD is used it still requires increasing locked
memory limit.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit c89b2bf1a80e3261bd18cdb352be1ffce9f4639e)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_domain.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 5c9f4831fd..57f18a02b6 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8259,8 +8259,14 @@ getPPC64MemLockLimitBytes(virDomainDef *def)
passthroughLimit = maxMemory +
128 * (1ULL<<30) / 512 * nPCIHostBridges +
8192;
- } else if (qemuDomainNeedsVFIO(def) || virDomainDefHasVDPANet(def)) {
- /* For regular (non-NVLink2 present) VFIO passthrough, the value
+ } else if (virDomainDefHasPCIHostdev(def) ||
+ virDomainDefHasMdevHostdev(def) ||
+ virDomainDefHasNVMeDisk(def) ||
+ virDomainDefHasVDPANet(def)) {
+ /* Not using qemuDomainNeedsVFIO() as that doesn't take PCI host
+ * devices with IOMMFD into account.
+ *
+ * For regular (non-NVLink2 present) VFIO passthrough, the value
* of passthroughLimit is:
*
* passthroughLimit := max( 2 GiB * #PHBs, (c)
--
2.53.0

View File

@ -0,0 +1,144 @@
From 92a7fef67b736e20c8e94f3407df7a984ee59102 Mon Sep 17 00:00:00 2001
Message-ID: <92a7fef67b736e20c8e94f3407df7a984ee59102.1771336681.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 29 Jan 2026 11:15:04 +0100
Subject: [PATCH] qemu: Extract disk setup done via QMP into a separate helper
Introduce 'qemuProcessSetupDiskPropsRuntime' helper function which will
collect all code used for runtime setup of a disk.
This is currently old-style throttling.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 1789a0f8a3623e8f0f6e50730feb58e3d8c48376)
https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2]
Conflicts:
- Commit b9b9092c9c1f8b42e311c524d9fc4a8e73ae28a6 which dropped disk
property refresh was not backported, thus the context around the call
to qemuProcessSetupDiskPropsRuntime was different
---
src/qemu/qemu_hotplug.c | 23 +++++------------------
src/qemu/qemu_process.c | 37 +++++++++++++++++++++++++++----------
src/qemu/qemu_process.h | 3 +++
3 files changed, 35 insertions(+), 28 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index fb426deb1a..f2dc4469a3 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -569,13 +569,8 @@ qemuDomainChangeMediaBlockdev(virDomainObj *vm,
}
/* set throttling for the new image */
- if (rc == 0 &&
- !virStorageSourceIsEmpty(newsrc) &&
- qemuDiskConfigBlkdeviotuneEnabled(disk)) {
- rc = qemuMonitorSetBlockIoThrottle(priv->mon,
- diskPriv->qomName,
- &disk->blkdeviotune);
- }
+ if (rc == 0)
+ rc = qemuProcessSetupDiskPropsRuntime(priv->mon, disk);
if (rc == 0)
rc = qemuMonitorBlockdevTrayClose(priv->mon, diskPriv->qomName);
@@ -795,21 +790,13 @@ qemuDomainAttachDiskGeneric(virDomainObj *vm,
if (rc == 0)
rc = qemuMonitorAddDeviceProps(priv->mon, &devprops);
- /* Setup throttling of disk via block_set_io_throttle QMP command. This
- * is a hack until the 'throttle' blockdev driver will support modification
- * of the trhottle group. See also qemuProcessSetupDiskThrottlingBlockdev.
- * As there isn't anything sane to do if this fails, let's just return
- * success.
- */
if (rc == 0) {
qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
g_autoptr(GHashTable) blockinfo = NULL;
- if (qemuDiskConfigBlkdeviotuneEnabled(disk)) {
- if (qemuMonitorSetBlockIoThrottle(priv->mon, diskPriv->qomName,
- &disk->blkdeviotune) < 0)
- VIR_WARN("failed to set blkdeviotune for '%s' of '%s'", disk->dst, vm->def->name);
- }
+ /* There isn't anything sane to do if this fails (rollback would
+ * require hot-unplug), let's just return success. */
+ ignore_value(qemuProcessSetupDiskPropsRuntime(priv->mon, disk));
if ((blockinfo = qemuMonitorGetBlockInfo(priv->mon))) {
struct qemuDomainDiskInfo *diskinfo;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d8f0c78fd1..c99bb36c93 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7937,6 +7937,32 @@ qemuProcessGenID(virDomainObj *vm,
}
+/**
+ * qemuProcessSetupDiskPropsRuntime:
+ * @mon: qemu monitor object
+ * @disk: disk definition
+ *
+ * This function expects that caller already entered 'monitor' context.
+ *
+ * Sets up disk properties which are only possible to be set in runtime.
+ */
+int
+qemuProcessSetupDiskPropsRuntime(qemuMonitor *mon,
+ virDomainDiskDef *disk)
+{
+ if (virStorageSourceIsEmpty(disk->src))
+ return 0;
+
+ if (qemuDiskConfigBlkdeviotuneEnabled(disk) &&
+ qemuMonitorSetBlockIoThrottle(mon,
+ QEMU_DOMAIN_DISK_PRIVATE(disk)->qomName,
+ &disk->blkdeviotune) < 0)
+ return -1;
+
+ return 0;
+}
+
+
/**
* qemuProcessSetupDiskThrottling:
*
@@ -7960,16 +7986,7 @@ qemuProcessSetupDiskThrottling(virDomainObj *vm,
for (i = 0; i < vm->def->ndisks; i++) {
virDomainDiskDef *disk = vm->def->disks[i];
- /* Setting throttling for empty drives fails */
- if (virStorageSourceIsEmpty(disk->src))
- continue;
-
- if (!qemuDiskConfigBlkdeviotuneEnabled(disk))
- continue;
-
- if (qemuMonitorSetBlockIoThrottle(qemuDomainGetMonitor(vm),
- QEMU_DOMAIN_DISK_PRIVATE(disk)->qomName,
- &disk->blkdeviotune) < 0)
+ if (qemuProcessSetupDiskPropsRuntime(qemuDomainGetMonitor(vm), disk) < 0)
goto cleanup;
}
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 426e11d79e..df78b00abb 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -146,6 +146,9 @@ int qemuProcessPrepareHostStorageSourceChain(virDomainObj *vm,
int qemuProcessPrepareHostStorageDisk(virDomainObj *vm,
virDomainDiskDef *disk);
+int qemuProcessSetupDiskPropsRuntime(qemuMonitor *mon,
+ virDomainDiskDef *disk);
+
int qemuProcessDeleteThreadContext(virDomainObj *vm);
int qemuProcessLaunch(virConnectPtr conn,
--
2.53.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,245 @@
From 098bba491e62352f049e84e8155f1db85eacb215 Mon Sep 17 00:00:00 2001
Message-ID: <098bba491e62352f049e84e8155f1db85eacb215.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 27 Feb 2026 17:55:34 +0100
Subject: [PATCH] qemu: Fix IOMMUFD and VFIO security labels
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When IOMMUFD support was introduced it incorrectly tried to label
`/dev/iommu` and `/dev/vfio/devices/vfioX` but they are not added to
QEMU namespace because libvirt opens FDs and passes these FDs to QEMU.
We need to label these FDs instead.
Fixes: 7d2f91f9cb572ab95d0916bdd1a46dd198874529
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 03f2672ab4eff8ee01410c9acba6288bfb4fa231)
Resolves: https://redhat.atlassian.net/browse/RHEL-159912
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_hotplug.c | 2 +-
src/qemu/qemu_process.c | 16 ++++++++++++----
src/qemu/qemu_process.h | 3 ++-
src/security/security_apparmor.c | 12 ------------
src/security/security_dac.c | 27 ---------------------------
src/security/security_selinux.c | 23 -----------------------
6 files changed, 15 insertions(+), 68 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 845f42bf20..994cc749f6 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1621,7 +1621,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
}
if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
- if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
+ if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0)
goto error;
if (!priv->iommufdState) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1559d6e0f8..dab417c9af 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7730,13 +7730,16 @@ int
qemuProcessOpenIommuFd(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
- int iommufd;
+ VIR_AUTOCLOSE iommufd = -1;
VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name);
if ((iommufd = virIOMMUFDOpenDevice()) < 0)
return -1;
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
+ return -1;
+
priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
return 0;
@@ -7751,16 +7754,21 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
* Returns: 0 on success, -1 on failure
*/
int
-qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
+qemuProcessOpenVfioDeviceFd(virDomainObj *vm,
+ virDomainHostdevDef *hostdev)
{
+ qemuDomainObjPrivate *priv = vm->privateData;
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
virDomainHostdevSubsysPCI *pci = &hostdev->source.subsys.u.pci;
g_autofree char *name = g_strdup_printf("hostdev-%s-fd", hostdev->info->alias);
- int vfioDeviceFd;
+ VIR_AUTOCLOSE vfioDeviceFd = -1;
if ((vfioDeviceFd = virPCIDeviceOpenVfioFd(&pci->addr)) < 0)
return -1;
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, vfioDeviceFd) < 0)
+ return -1;
+
hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFd);
return 0;
@@ -7778,7 +7786,7 @@ qemuProcessPrepareHostHostdev(virDomainObj *vm)
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
/* Open VFIO device FD */
- if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
+ if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0)
return -1;
}
break;
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 1023b7cb25..dc16622ed9 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -136,7 +136,8 @@ int qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm,
int qemuProcessOpenIommuFd(virDomainObj *vm);
-int qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev);
+int qemuProcessOpenVfioDeviceFd(virDomainObj *vm,
+ virDomainHostdevDef *hostdev);
int qemuProcessPrepareHost(virQEMUDriver *driver,
virDomainObj *vm,
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 1c3496893c..40f13ec1a5 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -45,7 +45,6 @@
#include "virstring.h"
#include "virscsi.h"
#include "virmdev.h"
-#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -856,17 +855,6 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
if (AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr) < 0)
return -1;
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr) < 0)
- return -1;
-
- if (AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr) < 0)
- return -1;
}
} else {
if (virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr) < 0)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index dc6dac0fb1..5aa13741e6 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -41,7 +41,6 @@
#include "virscsivhost.h"
#include "virstring.h"
#include "virutil.h"
-#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -1295,17 +1294,6 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
&cbdata) < 0) {
return -1;
}
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata) < 0)
- return -1;
-
- if (virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata) < 0)
- return -1;
}
} else {
if (virPCIDeviceFileIterate(pci,
@@ -1476,21 +1464,6 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
vfioGroupDev, false) < 0) {
return -1;
}
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- vfiofdDev, false) < 0) {
- return -1;
- }
-
- if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- VIR_IOMMU_DEV_PATH, false) < 0) {
- return -1;
- }
}
} else {
if (virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr) < 0)
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 94a796ec49..89546e3316 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -41,7 +41,6 @@
#include "virconf.h"
#include "virtpm.h"
#include "virstring.h"
-#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -2267,17 +2266,6 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
&data) < 0) {
return -1;
}
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data) < 0)
- return -1;
-
- if (virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data) < 0)
- return -1;
}
} else {
if (virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data) < 0)
@@ -2519,17 +2507,6 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false) < 0)
return -1;
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false) < 0)
- return -1;
-
- if (virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false) < 0)
- return -1;
}
} else {
if (virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr) < 0)
--
2.53.0

View File

@ -1,93 +0,0 @@
From 79f9281a8d3dcd15b2332e2e4f599617d47b5fd0 Mon Sep 17 00:00:00 2001
Message-ID: <79f9281a8d3dcd15b2332e2e4f599617d47b5fd0.1752837271.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 27 Jun 2025 16:10:03 +0200
Subject: [PATCH] qemu: Fix auto-shutdown of qemu VMs by the qemu driver
When auto-shutdown via the qemu driver is requested (rather than via
libvirt guests) we need to start the VMs in a way that they will be kept
around for libvirt to terminate them. This involves inverting the
dependancy relationship for the machined unit file.
Since the setup is done at startup of the VM, add a disclaimer to
qemu.conf that switching between the two modes with VMs running will not
work properly.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 82963fdcb67742fad3066d31f2bd9b14c8153574)
https://issues.redhat.com/browse/RHEL-95361
---
src/qemu/qemu.conf.in | 15 ++++++++++++++-
src/qemu/qemu_cgroup.c | 8 +++++++-
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in
index 221bfa8095..6358a45ae2 100644
--- a/src/qemu/qemu.conf.in
+++ b/src/qemu/qemu.conf.in
@@ -663,7 +663,10 @@
# implemented for transient VMs.
#
# If 'libvirt-guests.service' is enabled, then this must be
-# set to 'none' for system daemons to avoid dueling actions
+# set to 'none' for system daemons to avoid dueling actions.
+# Warning: Switching between 'libvirt-guests.service' and this option
+# causes VMs running at that point to misbehave on host shutdown unless
+# they are restarted, or saved and restored.
#auto_shutdown_try_save = "persistent"
# As above, but with a graceful shutdown action instead of
@@ -675,6 +678,9 @@
#
# If 'libvirt-guests.service' is enabled, then this must be
# set to 'none' for system daemons to avoid dueling actions
+# Warning: Switching between 'libvirt-guests.service' and this option
+# causes VMs running at that point to misbehave on host shutdown unless
+# they are restarted, or saved and restored.
#auto_shutdown_try_shutdown = "all"
# As above, but with a forced poweroff instead of managed
@@ -687,6 +693,13 @@
#
# If 'libvirt-guests.service' is enabled, then this must be
# set to 'none' for system daemons to avoid dueling actions
+#
+# Warning: Switching between 'libvirt-guests.service' and this option
+# causes VMs running at that point to misbehave on host shutdown unless
+# they are restarted, or saved and restored.
+#
+# When using any 'auto_shutdown_try_save', 'auto_shutdown_try_shutdown' this
+# feature should to be enabled as well to ensure proper cleanup of the VMs.
#auto_shutdown_poweroff = "all"
# How may seconds to wait for running VMs to gracefully shutdown
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 04d6370011..25e42ebfc6 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -910,6 +910,12 @@ qemuSetupCgroup(virDomainObj *vm,
{
qemuDomainObjPrivate *priv = vm->privateData;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
+ /* When users wants to auto-shutdown the VMs via the qemu daemon itself
+ * we need to instruct machined to create dependencies for the units
+ * in such way that the VMs will not be killed before the auto shutdown
+ * code is reached.
+ */
+ bool daemonAutoShutdown = virDomainDriverAutoShutdownActive(&cfg->autoShutdown);
if (virDomainCgroupSetupCgroup("qemu",
vm,
@@ -919,7 +925,7 @@ qemuSetupCgroup(virDomainObj *vm,
cfg->cgroupControllers,
cfg->maxThreadsPerProc,
priv->driver->privileged,
- false,
+ daemonAutoShutdown,
priv->machineName) < 0)
return -1;
--
2.50.1

View File

@ -1,73 +0,0 @@
From 82f694fc23fc1ec20e46cc0ce85f1a9605c89f31 Mon Sep 17 00:00:00 2001
Message-ID: <82f694fc23fc1ec20e46cc0ce85f1a9605c89f31.1759908360.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-111863
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 ef9f326a9b..adba3e4a89 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1425,6 +1425,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

@ -1,5 +1,5 @@
From c9e94ac936d4f9de638b1c06856dbb14a5998988 Mon Sep 17 00:00:00 2001
Message-ID: <c9e94ac936d4f9de638b1c06856dbb14a5998988.1770825171.git.jdenemar@redhat.com>
From 636b8f50486f3007be1b92ddb84f326f58d168d8 Mon Sep 17 00:00:00 2001
Message-ID: <636b8f50486f3007be1b92ddb84f326f58d168d8.1770825107.git.jdenemar@redhat.com>
From: Jean-Louis Dupond <jean-louis@dupond.be>
Date: Thu, 5 Feb 2026 14:18:42 +0100
Subject: [PATCH] qemu: Ignore cmp_legacy CPU flag
@ -19,79 +19,78 @@ Signed-off-by: Jean-Louis Dupond <jean-louis@dupond.be>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit fc5840b4980045a05b8973900cdbe36162e48331)
https://issues.redhat.com/browse/RHEL-148502
https://issues.redhat.com/browse/RHEL-148494
Conflicts:
tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args
tests/qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args
tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-latest.args
- the -cpu option was different downstream as several
unrelated upstream commits were not backported
tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-latest.args
tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-latest.args
tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-latest.args
- no change required, downstream -cpu option does not
contain cmp_legacy feaature
- upstream commit v11.10.0-78-g380764992d
(qemucapabilitiesdata: Re-generate 'caps_10.2.0_x86_64')
that added rdseed=off to test files is not backported
tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args
tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.0.0.args
tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.1.0.args
tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.2.0.args
tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.0.0.args
tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.1.0.args
tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.2.0.args
tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-10.1.0.args
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.args
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.args
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.args
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.args
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.args
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.args
tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.0.0.args
tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.1.0.args
tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.2.0.args
tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.0.0.args
tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.1.0.args
tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.2.0.args
tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-10.1.0.args
tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.args
- missing downstream, added upstream after the last rebase
- missing downstream, it was added upstream after the last
rebase
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 1 +
.../cpu-host-model-fallback-kvm.x86_64-10.0.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-10.1.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-6.2.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-7.0.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-7.1.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-7.2.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-8.0.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-8.1.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-8.2.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-9.0.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-9.1.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-9.2.0.args | 2 +-
.../cpu-host-model-fallback-kvm.x86_64-latest.args | 2 +-
.../cpu-host-model-fallback-tcg.x86_64-10.1.0.args | 2 +-
.../cpu-host-model-fallback-tcg.x86_64-latest.args | 2 +-
.../qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.2.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.0.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.1.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.2.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.0.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.1.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-10.0.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-10.1.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-6.2.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-7.0.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-7.1.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-7.2.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-8.0.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-8.1.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-8.2.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-9.0.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-9.1.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-9.2.0.args | 2 +-
.../cpu-host-model-nofallback-kvm.x86_64-latest.args | 2 +-
.../cpu-host-model-nofallback-tcg.x86_64-10.1.0.args | 2 +-
.../cpu-host-model-nofallback-tcg.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-translation.x86_64-latest.args | 2 +-
24 files changed, 24 insertions(+), 23 deletions(-)
48 files changed, 48 insertions(+), 47 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 9365891ddf..f15b5867a3 100644
index 92b863a826..d738805ee8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3739,6 +3739,7 @@ const char *ignoredFeatures[] = {
@@ -3772,6 +3772,7 @@ const char *ignoredFeatures[] = {
"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 */
@ -99,6 +98,32 @@ index 9365891ddf..f15b5867a3 100644
};
bool
diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.0.0.args
index edd334dd8b..08f37274b2 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.0.0.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-i440fx-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=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-host-model-fallback-kvm.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.1.0.args
index 57982574eb..e4044a0c64 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.1.0.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-i440fx-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=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-host-model-fallback-kvm.x86_64-6.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-6.2.0.args
index 4aa9011fe8..e8a9aceb4a 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-6.2.0.args
@ -177,29 +202,133 @@ index 3b733a3c5d..58ad565dba 100644
-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-fallback-kvm.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args
index a0247e4310..0481de137e 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args
diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.2.0.args
index 73296c7df0..fa1b674fa5 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.2.0.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 \
-machine pc-i440fx-8.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=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-host-model-fallback-kvm.x86_64-9.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.0.0.args
index 8f8b74fa56..fc9985f901 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.0.0.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-i440fx-9.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=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-host-model-fallback-kvm.x86_64-9.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.1.0.args
index c2f394bf09..1db86cb31e 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.1.0.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-i440fx-9.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=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-host-model-fallback-kvm.x86_64-9.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.2.0.args
index 35c8d397c4..4dcd9332cb 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.2.0.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-i440fx-9.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=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-host-model-fallback-kvm.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args
index 6afa8a4c2d..e5b0acb87b 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.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 EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off \
+-cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=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-host-model-fallback-tcg.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-10.1.0.args
index 3b93ed510d..0b67c7f158 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-10.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-10.1.0.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-i440fx-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel tcg \
--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \
+-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=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-host-model-fallback-tcg.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-latest.args
index 01cf90bb67..443de62f69 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.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 EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \
+-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=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-host-model-features.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args
index a60ce4dee0..7b51f6643a 100644
index ce60a39acc..52f636fa77 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-features.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 EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off,abm=on,ds=on,invtsc=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off,abm=on,ds=on,invtsc=off \
--cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off,abm=on,ds=on,invtsc=off \
+-cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off,abm=on,ds=on,invtsc=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-host-model-kvm.x86_64-10.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.args
index a1c034ec51..7dd5723b98 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.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-q35-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=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-host-model-kvm.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.args
index ddf940f75c..987baa9b30 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.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-q35-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
@ -281,19 +410,97 @@ index 901f279a02..8360dc02ef 100644
-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-kvm.x86_64-8.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.args
index d141aca9f0..b00138933c 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.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-q35-8.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=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-host-model-kvm.x86_64-9.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.args
index 49575ff4d9..3b42130bd2 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.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-q35-9.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=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-host-model-kvm.x86_64-9.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.args
index fd25e4cd23..c451426cdd 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.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-q35-9.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=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-host-model-kvm.x86_64-9.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.args
index 4b69f59064..1da6e508ff 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.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-q35-9.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=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-host-model-kvm.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args
index e2e6d08246..f5984cbf22 100644
index 2bf920b9c7..30010edb3b 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.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 q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off \
+-cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=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-host-model-nofallback-kvm.x86_64-10.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.0.0.args
index edd334dd8b..08f37274b2 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.0.0.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-i440fx-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=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-host-model-nofallback-kvm.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.1.0.args
index 57982574eb..e4044a0c64 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.1.0.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-i440fx-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=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-host-model-nofallback-kvm.x86_64-6.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-6.2.0.args
index 4aa9011fe8..e8a9aceb4a 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-6.2.0.args
@ -372,16 +579,120 @@ index 3b733a3c5d..58ad565dba 100644
-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-nofallback-kvm.x86_64-8.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.2.0.args
index 73296c7df0..fa1b674fa5 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.2.0.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-i440fx-8.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=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-host-model-nofallback-kvm.x86_64-9.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.0.0.args
index 8f8b74fa56..fc9985f901 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.0.0.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-i440fx-9.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=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-host-model-nofallback-kvm.x86_64-9.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.1.0.args
index c2f394bf09..1db86cb31e 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.1.0.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-i440fx-9.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=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-host-model-nofallback-kvm.x86_64-9.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.2.0.args
index 35c8d397c4..4dcd9332cb 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.2.0.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-i440fx-9.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=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-host-model-nofallback-kvm.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-latest.args
index a0247e4310..0481de137e 100644
index 6afa8a4c2d..e5b0acb87b 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.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 EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \
--cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off \
+-cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=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-host-model-nofallback-tcg.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-10.1.0.args
index 3b93ed510d..0b67c7f158 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-10.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-10.1.0.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-i440fx-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel tcg \
--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \
+-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=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-host-model-nofallback-tcg.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-latest.args
index 01cf90bb67..443de62f69 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.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 EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \
+-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=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-host-model-tcg.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.args
index 4defeceac3..d12cb96786 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.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-q35-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel tcg \
--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \
+-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=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-host-model-tcg.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-latest.args
index 479266659a..688a217c3c 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-tcg.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 q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel tcg \
--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \
+-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \

View File

@ -1,290 +0,0 @@
From be89e50ce38423980564b93321a9fe075b8c69b5 Mon Sep 17 00:00:00 2001
Message-ID: <be89e50ce38423980564b93321a9fe075b8c69b5.1763729878.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-126094
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 a394bae754..1b9dcb51b8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3688,6 +3688,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,47 @@
From dd52dfae42e6180f4fb2804614dcd84bffb89c4e Mon Sep 17 00:00:00 2001
Message-ID: <dd52dfae42e6180f4fb2804614dcd84bffb89c4e.1774618368.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 11 Mar 2026 12:12:40 +0100
Subject: [PATCH] qemu: Implement
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 3215fee34967c49f37a965154879fc5860293cac)
https://issues.redhat.com/browse/RHEL-154553
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_driver.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ad894c7584..92b94bb830 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16736,7 +16736,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
virDomainVirtType virttype;
g_autoptr(virDomainCaps) domCaps = NULL;
- virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES,
+ virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES |
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
NULL);
if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0)
@@ -16762,6 +16763,12 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
VIR_CPU_FEATURE_DISABLE);
}
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) {
+ virCPUDef *cpu = domCaps->cpu.hostModel;
+ if (cpu && virCPUExpandFeatures(arch, cpu) < 0)
+ return NULL;
+ }
+
return virDomainCapsFormat(domCaps);
}
--
2.53.0

View File

@ -0,0 +1,127 @@
From d57da0146a8754477d975067dafb8f8c7cc4ba1d Mon Sep 17 00:00:00 2001
Message-ID: <d57da0146a8754477d975067dafb8f8c7cc4ba1d.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 16 Mar 2026 15:29:32 +0100
Subject: [PATCH] qemu: Implement iommufd fdgroup
When fdgroup is used for iommufd we will start QEMU with -object iommufd
even if the VM has no host device. When virDomainFDAssociate() is used
the FD libvirt is holding is closed with connection.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 0a83b28795f0c18592f9d842927528f0676cc56d)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_command.c | 4 +++-
src/qemu/qemu_hotplug.c | 4 ++--
src/qemu/qemu_process.c | 47 ++++++++++++++++++++++++++++++++++++++---
3 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 88d2d1c1aa..776b46764a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5360,8 +5360,10 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd,
qemuDomainObjPrivate *priv = vm->privateData;
g_autoptr(virJSONValue) props = NULL;
- if (!virDomainDefHasPCIHostdevWithIOMMUFD(def))
+ if (!virDomainDefHasPCIHostdevWithIOMMUFD(def) &&
+ !def->iommufd_fdgroup) {
return 0;
+ }
qemuFDPassDirectTransferCommand(priv->iommufd, cmd);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 25fe699bb3..8944062aa4 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1624,7 +1624,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0)
goto error;
- if (!priv->iommufdState) {
+ if (!priv->iommufdState && !vm->def->iommufd_fdgroup) {
if (qemuProcessOpenIommuFd(vm) < 0)
goto error;
@@ -5031,7 +5031,7 @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver,
}
}
- if (priv->iommufdState &&
+ if (priv->iommufdState && !vm->def->iommufd_fdgroup &&
!virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
qemuDomainObjEnterMonitor(vm);
ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false));
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9c5fa69846..8b4b48873a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7745,6 +7745,44 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
return 0;
}
+/**
+ * qemuProcessGetPassedIommuFd:
+ * @vm: domain object
+ *
+ * Find passed FD via virDomainFDAssociate() API for the VM.
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int
+qemuProcessGetPassedIommuFd(virDomainObj *vm)
+{
+ qemuDomainObjPrivate *priv = vm->privateData;
+ virDomainFDTuple *fdt = virHashLookup(priv->fds, vm->def->iommufd_fdgroup);
+ VIR_AUTOCLOSE iommufd = -1;
+
+ if (!fdt) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("file descriptor group '%1$s' was not associated with the domain"),
+ vm->def->iommufd_fdgroup);
+ return -1;
+ }
+
+ if (fdt->nfds != 1) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("Only one file descriptor needs to be associated with iommufd"));
+ return -1;
+ }
+
+ iommufd = dup(fdt->fds[0]);
+
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
+ return -1;
+
+ priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
+
+ return 0;
+}
+
/**
* qemuProcessOpenVfioDeviceFd:
* @hostdev: host device definition
@@ -7800,9 +7838,12 @@ qemuProcessPrepareHostHostdev(virDomainObj *vm)
}
/* Open IOMMU FD */
- if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def) &&
- qemuProcessOpenIommuFd(vm) < 0) {
- return -1;
+ if (vm->def->iommufd_fdgroup) {
+ if (qemuProcessGetPassedIommuFd(vm) < 0)
+ return -1;
+ } else if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
+ if (qemuProcessOpenIommuFd(vm) < 0)
+ return -1;
}
return 0;
--
2.53.0

View File

@ -0,0 +1,119 @@
From 36e121071fd7df4276de3ff107e9c10d1ec97972 Mon Sep 17 00:00:00 2001
Message-ID: <36e121071fd7df4276de3ff107e9c10d1ec97972.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 17:59:01 +0100
Subject: [PATCH] qemu: Implement iommufd
Ideally this should be done in qemuDomainHostdevDefPostParse but that
would require a lot of refactoring mainly due to how interface backed by
hostdev works.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit fc516031ed865f78d590068424ada19a941046ba)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_domain.c | 12 +++++++++---
src/qemu/qemu_domain.h | 3 ++-
src/qemu/qemu_hotplug.c | 2 +-
src/qemu/qemu_process.c | 4 ++--
4 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index a61939aa15..495cbd4f7d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -10120,10 +10120,12 @@ qemuDomainPrepareHostdevSCSI(virDomainHostdevDef *hostdev,
static int
-qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev,
+qemuDomainPrepareHostdevPCI(const virDomainDef *def,
+ virDomainHostdevDef *hostdev,
virQEMUCaps *qemuCaps)
{
virDeviceHostdevPCIDriverName *driverName = &hostdev->source.subsys.u.pci.driver.name;
+ virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci;
/* assign defaults for hostdev passthrough */
switch (*driverName) {
@@ -10160,12 +10162,16 @@ qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev,
return -1;
}
+ if (pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_ABSENT)
+ pcisrc->driver.iommufd = def->iommufd;
+
return 0;
}
int
-qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
+qemuDomainPrepareHostdev(const virDomainDef *def,
+ virDomainHostdevDef *hostdev,
qemuDomainObjPrivate *priv)
{
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
@@ -10175,7 +10181,7 @@ qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
return qemuDomainPrepareHostdevSCSI(hostdev, priv);
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
- return qemuDomainPrepareHostdevPCI(hostdev, priv->qemuCaps);
+ return qemuDomainPrepareHostdevPCI(def, hostdev, priv->qemuCaps);
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 62c5252b9f..8cd221062c 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1048,7 +1048,8 @@ qemuDomainDiskCachemodeFlags(virDomainDiskCache cachemode,
bool *noflush);
int
-qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
+qemuDomainPrepareHostdev(const virDomainDef *def,
+ virDomainHostdevDef *hostdev,
qemuDomainObjPrivate *priv);
char * qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivate *priv);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 994cc749f6..25fe699bb3 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2900,7 +2900,7 @@ qemuDomainAttachHostDevice(virQEMUDriver *driver,
return -1;
}
- if (qemuDomainPrepareHostdev(hostdev, vm->privateData) < 0)
+ if (qemuDomainPrepareHostdev(vm->def, hostdev, vm->privateData) < 0)
return -1;
switch (hostdev->source.subsys.type) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7295b2ba79..9c5fa69846 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6089,7 +6089,7 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm)
/* For hostdev present in qemuProcessPrepareDomain() phase this was
* done already, but this code runs after that, so we have to call
* it ourselves. */
- if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
+ if (qemuDomainPrepareHostdev(def, hostdev, priv) < 0)
return -1;
virDomainHostdevInsert(def, hostdev);
@@ -6877,7 +6877,7 @@ qemuProcessPrepareDomainHostdevs(virDomainObj *vm,
for (i = 0; i < vm->def->nhostdevs; i++) {
virDomainHostdevDef *hostdev = vm->def->hostdevs[i];
- if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
+ if (qemuDomainPrepareHostdev(vm->def, hostdev, priv) < 0)
return -1;
}
--
2.53.0

View File

@ -0,0 +1,191 @@
From bb8ef43213cb1f8c123cdcc693d99a30b09dfa16 Mon Sep 17 00:00:00 2001
Message-ID: <bb8ef43213cb1f8c123cdcc693d99a30b09dfa16.1770383182.git.jdenemar@redhat.com>
From: Nathan Chen <nathanc@nvidia.com>
Date: Fri, 30 Jan 2026 10:59:12 -0800
Subject: [PATCH] qemu: Implement support for associating iommufd to hostdev
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implement a new iommufd attribute under hostdevs' PCI
subsystem driver that can be used to specify associated
iommufd object when launching a qemu VM.
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit fd113055bb174c7284081731d16959f73796e3d7)
Resolves: https://issues.redhat.com/browse/RHEL-74202
Resolves: https://issues.redhat.com/browse/RHEL-126346
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
docs/formatdomain.rst | 6 +++++
src/conf/device_conf.c | 11 ++++++++
src/conf/device_conf.h | 1 +
src/conf/schemas/basictypes.rng | 5 ++++
src/qemu/qemu_command.c | 46 +++++++++++++++++++++++++++++++++
5 files changed, 69 insertions(+)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 1467fc7e10..167912348e 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -4907,6 +4907,12 @@ or:
found is "problematic" in some way, the generic vfio-pci driver
similarly be forced.
+ :since:`Since 12.1.0 (QEMU and KVM only)`, the ``iommufd`` element
+ can be used to enable IOMMUFD backend for VFIO device. This
+ provides an interface to propagate DMA mappings to kernel for
+ assigned devices. Libvirt will open the /dev/iommu and VFIO device
+ cdev and pass associated file descriptors to QEMU.
+
(Note: :since:`Since 1.0.5`, the ``name`` attribute has been
described to be used to select the type of PCI device assignment
("vfio", "kvm", or "xen"), but those values have been mostly
diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
index c278b81652..d68232a4f4 100644
--- a/src/conf/device_conf.c
+++ b/src/conf/device_conf.c
@@ -67,6 +67,11 @@ virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr node,
return -1;
}
+ if (virXMLPropTristateBool(node, "iommufd",
+ VIR_XML_PROP_NONE,
+ &driver->iommufd) < 0)
+ return -1;
+
driver->model = virXMLPropString(node, "model");
return 0;
}
@@ -93,6 +98,12 @@ virDeviceHostdevPCIDriverInfoFormat(virBuffer *buf,
virBufferEscapeString(&driverAttrBuf, " model='%s'", driver->model);
+ if (driver->iommufd == VIR_TRISTATE_BOOL_YES) {
+ virBufferAddLit(&driverAttrBuf, " iommufd='yes'");
+ } else if (driver->iommufd == VIR_TRISTATE_BOOL_NO) {
+ virBufferAddLit(&driverAttrBuf, " iommufd='no'");
+ }
+
virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL);
return 0;
}
diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
index e570f51824..116b959143 100644
--- a/src/conf/device_conf.h
+++ b/src/conf/device_conf.h
@@ -47,6 +47,7 @@ VIR_ENUM_DECL(virDeviceHostdevPCIDriverName);
struct _virDeviceHostdevPCIDriverInfo {
virDeviceHostdevPCIDriverName name;
char *model;
+ virTristateBool iommufd;
};
typedef enum {
diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng
index 5689170fad..381e0ac24f 100644
--- a/src/conf/schemas/basictypes.rng
+++ b/src/conf/schemas/basictypes.rng
@@ -673,6 +673,11 @@
<ref name="genericName"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="iommufd">
+ <ref name="virYesNo"/>
+ </attribute>
+ </optional>
<empty/>
</element>
</define>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index fb89dbec27..1fb31d1721 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4754,6 +4754,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
g_autofree char *host = virPCIDeviceAddressAsString(&pcisrc->addr);
const char *failover_pair_id = NULL;
const char *driver = NULL;
+ const char *iommufdId = NULL;
/* 'ramfb' property must be omitted unless it's to be enabled */
bool ramfb = pcisrc->ramfb == VIR_TRISTATE_SWITCH_ON;
@@ -4787,6 +4788,9 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
teaming->persistent)
failover_pair_id = teaming->persistent;
+ if (pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_YES)
+ iommufdId = "iommufd0";
+
if (virJSONValueObjectAdd(&props,
"s:driver", driver,
"s:host", host,
@@ -4795,6 +4799,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
"S:failover_pair_id", failover_pair_id,
"S:display", qemuOnOffAuto(pcisrc->display),
"B:ramfb", ramfb,
+ "S:iommufd", iommufdId,
NULL) < 0)
return NULL;
@@ -5314,6 +5319,44 @@ qemuBuildHostdevCommandLine(virCommand *cmd,
}
+static int
+qemuBuildIOMMUFDCommandLine(virCommand *cmd,
+ const virDomainDef *def)
+{
+ size_t i;
+
+ for (i = 0; i < def->nhostdevs; i++) {
+ virDomainHostdevDef *hostdev = def->hostdevs[i];
+ virDomainHostdevSubsys *subsys = &hostdev->source.subsys;
+ g_autoptr(virJSONValue) props = NULL;
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+
+ if (subsys->type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ continue;
+
+ if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED)
+ continue;
+
+ if (subsys->u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES)
+ continue;
+
+ if (qemuMonitorCreateObjectProps(&props, "iommufd",
+ "iommufd0",
+ NULL) < 0)
+ return -1;
+
+ if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
+ return -1;
+
+ break;
+ }
+
+ return 0;
+}
+
+
static int
qemuBuildMonitorCommandLine(virCommand *cmd,
qemuDomainObjPrivate *priv)
@@ -10926,6 +10969,9 @@ qemuBuildCommandLine(virDomainObj *vm,
if (qemuBuildRedirdevCommandLine(cmd, def, qemuCaps) < 0)
return NULL;
+ if (qemuBuildIOMMUFDCommandLine(cmd, def) < 0)
+ return NULL;
+
if (qemuBuildHostdevCommandLine(cmd, def, qemuCaps) < 0)
return NULL;
--
2.52.0

View File

@ -0,0 +1,220 @@
From 3f03b1cbc20d0af7900cc43cc576a356a95a292b Mon Sep 17 00:00:00 2001
Message-ID: <3f03b1cbc20d0af7900cc43cc576a356a95a292b.1771336681.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 11 Dec 2025 19:47:16 +0100
Subject: [PATCH] qemu: Implement support for persistent reservation migration
control
The 'migration' attribute for the '<reservations>' element allows to
control the persistent reservation migration feature independently of
the machine type default.
Add the XML plumbing and qemu support.
We consider it ABI for now since it influences qemu migration protocol.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 0d3ef7cb71979172de2c531d865e4525a314f902)
https://issues.redhat.com/browse/RHEL-140614 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-135115 [rhel-10.2]
---
docs/formatdomain.rst | 3 +++
src/conf/domain_conf.c | 21 +++++++++++++++++++
src/conf/schemas/storagecommon.rng | 5 +++++
src/conf/storage_source_conf.c | 10 +++++++++
src/conf/storage_source_conf.h | 2 ++
src/qemu/qemu_command.c | 4 ++++
src/qemu/qemu_validate.c | 16 ++++++++++++++
...irtio-scsi-reservations.x86_64-latest.args | 2 +-
.../disk-virtio-scsi-reservations.xml | 2 +-
9 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 167912348e..9836837441 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -3169,6 +3169,9 @@ paravirtualized driver is specified via the ``disk`` element.
the socket, and finally ``mode`` which accepts one value ``client``
specifying the role of hypervisor. It's recommended to allow libvirt
manage the persistent reservations.
+ :since:`Since 12.1.0` the ``migration`` (values ``yes``, ``no``) controls
+ whether the hypervisor should attempt to migrate persistent reservations
+ during migration.
``initiator``
:since:`Since 4.7.0`, the ``initiator`` element is supported for
a disk ``type`` "network" that is using a ``source`` element with the
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 902c1188ef..f5c4d135a9 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20951,6 +20951,27 @@ virDomainDiskDefCheckABIStability(virDomainDiskDef *src,
return false;
}
+ /* While not guest visible it influences the qemu migration stream so
+ * we need to keep it identical */
+ if (src->src->pr || dst->src->pr) {
+ virTristateBool srcmig = VIR_TRISTATE_BOOL_ABSENT;
+ virTristateBool dstmig = VIR_TRISTATE_BOOL_ABSENT;
+
+ if (src->src->pr)
+ srcmig = src->src->pr->migration;
+
+ if (dst->src->pr)
+ dstmig = dst->src->pr->migration;
+
+ if (srcmig != dstmig) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target disk reservations 'migration' property %1$s does not match source %2$s"),
+ virTristateBoolTypeToString(dstmig),
+ virTristateBoolTypeToString(srcmig));
+ return false;
+ }
+ }
+
if (!virDomainVirtioOptionsCheckABIStability(src->virtio, dst->virtio))
return false;
diff --git a/src/conf/schemas/storagecommon.rng b/src/conf/schemas/storagecommon.rng
index 14704c737e..450d53131f 100644
--- a/src/conf/schemas/storagecommon.rng
+++ b/src/conf/schemas/storagecommon.rng
@@ -104,6 +104,11 @@
<ref name="virYesNo"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="migration">
+ <ref name="virYesNo"/>
+ </attribute>
+ </optional>
<optional>
<ref name="unixSocketSource"/>
</optional>
diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c
index 087de1eaf2..24d4b0de6a 100644
--- a/src/conf/storage_source_conf.c
+++ b/src/conf/storage_source_conf.c
@@ -330,6 +330,11 @@ virStoragePRDefParseXML(xmlXPathContextPtr ctxt)
&prd->managed) < 0)
goto cleanup;
+ if (virXMLPropTristateBool(ctxt->node, "migration",
+ VIR_XML_PROP_NONZERO,
+ &prd->migration) < 0)
+ goto cleanup;
+
type = virXPathString("string(./source[1]/@type)", ctxt);
path = virXPathString("string(./source[1]/@path)", ctxt);
mode = virXPathString("string(./source[1]/@mode)", ctxt);
@@ -384,6 +389,11 @@ virStoragePRDefFormat(virBuffer *buf,
{
virBufferAsprintf(buf, "<reservations managed='%s'",
virTristateBoolTypeToString(prd->managed));
+
+ if (prd->migration != VIR_TRISTATE_BOOL_ABSENT)
+ virBufferAsprintf(buf, " migration='%s'",
+ virTristateBoolTypeToString(prd->migration));
+
if (prd->path &&
(prd->managed == VIR_TRISTATE_BOOL_NO || !migratable)) {
virBufferAddLit(buf, ">\n");
diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h
index fc868b31af..5a4b088eeb 100644
--- a/src/conf/storage_source_conf.h
+++ b/src/conf/storage_source_conf.h
@@ -235,6 +235,8 @@ struct _virStoragePRDef {
virTristateBool managed;
char *path;
+ virTristateBool migration;
+
/* manager object alias */
char *mgralias;
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f355352018..c8626e6d49 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1691,6 +1691,7 @@ qemuBuildDiskDeviceProps(const virDomainDef *def,
g_autofree char *usbdiskalias = NULL;
const virDomainDeviceInfo *deviceinfo = &disk->info;
g_autoptr(virJSONValue) statistics = NULL;
+ virTristateBool migrate_pr = VIR_TRISTATE_BOOL_ABSENT;
virDomainDeviceInfo usbSCSIinfo = {
.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE,
.addr.drive = { .diskbus = VIR_DOMAIN_DISK_BUS_USB },
@@ -1716,6 +1717,8 @@ qemuBuildDiskDeviceProps(const virDomainDef *def,
case VIR_DOMAIN_DISK_BUS_SCSI:
if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
driver = "scsi-block";
+ if (disk->src->pr)
+ migrate_pr = disk->src->pr->migration;
} else {
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
driver = "scsi-cd";
@@ -1937,6 +1940,7 @@ qemuBuildDiskDeviceProps(const virDomainDef *def,
"S:rerror", rpolicy,
"A:stats-intervals", &statistics,
"T:dpofua", disk->dpofua, /* SCSI-only, ensured by validation */
+ "T:migrate-pr", migrate_pr, /* 'scsi-block' only, ensured by validation */
NULL) < 0)
return NULL;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index da08fd17cd..a3dbd9a33b 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -3227,6 +3227,22 @@ qemuValidateDomainDeviceDefDiskFrontend(const virDomainDiskDef *disk,
}
}
+ if (disk->src->pr &&
+ disk->src->pr->migration != VIR_TRISTATE_BOOL_ABSENT) {
+ if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN ||
+ disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("persistent reservation migration supported only with 'lun' disks on 'scsi' bus"));
+ return -1;
+ }
+
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("persistent reservation migration not supported by this qemu"));
+ return -1;
+ }
+ }
+
if (disk->rotation_rate) {
if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI &&
disk->bus != VIR_DOMAIN_DISK_BUS_IDE &&
diff --git a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args
index cbc2a0f398..f1d7a450ee 100644
--- a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args
@@ -33,7 +33,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-device '{"driver":"scsi-block","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":0,"drive":"libvirt-2-storage","id":"scsi0-0-0-0","bootindex":1}' \
-object '{"qom-type":"pr-manager-helper","id":"pr-helper-libvirt-1-storage","path":"/path/to/qemu-pr-helper.sock"}' \
-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest2","pr-manager":"pr-helper-libvirt-1-storage","node-name":"libvirt-1-storage","read-only":false}' \
--device '{"driver":"scsi-block","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":1,"drive":"libvirt-1-storage","id":"scsi0-0-0-1"}' \
+-device '{"driver":"scsi-block","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":1,"drive":"libvirt-1-storage","id":"scsi0-0-0-1","migrate-pr":true}' \
-audiodev '{"id":"audio1","driver":"none"}' \
-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x4"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
diff --git a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml
index 9c55d6ec3e..7f9160ff3a 100644
--- a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml
+++ b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml
@@ -28,7 +28,7 @@
<disk type='block' device='lun'>
<driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest2'>
- <reservations managed='no'>
+ <reservations managed='no' migration='yes'>
<source type='unix' path='/path/to/qemu-pr-helper.sock' mode='client'/>
</reservations>
</source>
--
2.53.0

View File

@ -0,0 +1,266 @@
From 13871e41d1697608a55fa40d3855193a636109bb Mon Sep 17 00:00:00 2001
Message-ID: <13871e41d1697608a55fa40d3855193a636109bb.1771423658.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 16 Feb 2026 08:59:39 +0100
Subject: [PATCH] qemu: Introduce QEMU_CAPS_OBJECT_IOMMUFD
Detect if QEMU was compiled with IOMMUFD.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 4a0ea9bcf13ea05c90f294ba70c767bc79e2ebbe)
Conflicts:
These files don't exist in downstream:
tests/qemucapabilitiesdata/caps_10.1.0_s390x.xml
tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml
tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml
tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_capabilities.c | 4 ++++
src/qemu/qemu_capabilities.h | 3 +++
src/qemu/qemu_validate.c | 8 ++++++++
tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml | 1 +
tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml | 1 +
tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml | 1 +
tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml | 1 +
.../qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml | 1 +
tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml | 1 +
tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml | 1 +
tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml | 1 +
tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml | 1 +
tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml | 1 +
tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml | 1 +
tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml | 1 +
tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml | 1 +
tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml | 1 +
17 files changed, 29 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2c8bd62c99..c23ff5539a 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -756,6 +756,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
"query-accelerators", /* QEMU_CAPS_QUERY_ACCELERATORS */
"mshv", /* QEMU_CAPS_MSHV */
"scsi-block.migrate-pr", /* QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR */
+
+ /* 490 */
+ "iommufd", /* QEMU_CAPS_OBJECT_IOMMUFD */
);
@@ -1463,6 +1466,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "tpm-emulator", QEMU_CAPS_DEVICE_TPM_EMULATOR },
{ "tpm-passthrough", QEMU_CAPS_DEVICE_TPM_PASSTHROUGH },
{ "acpi-generic-initiator", QEMU_CAPS_ACPI_GENERIC_INITIATOR },
+ { "iommufd", QEMU_CAPS_OBJECT_IOMMUFD },
};
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 0c76f2edda..f7c8680f94 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -732,6 +732,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_MSHV, /* -accel mshv */
QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, /* persistent reservation migration support */
+ /* 490 */
+ QEMU_CAPS_OBJECT_IOMMUFD, /* -object iommufd */
+
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index a3dbd9a33b..18f148f48c 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -2723,6 +2723,14 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev,
_("VFIO PCI device assignment is not supported by this version of qemu"));
return -1;
}
+
+ if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOMMUFD)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("IOMMUFD is not supported by this version of qemu"));
+ return -1;
+ }
+ }
}
if (hostdev->writeFiltering != VIR_TRISTATE_BOOL_ABSENT) {
diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml
index 90e8d868cc..bbb8b33cde 100644
--- a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml
@@ -163,6 +163,7 @@
<flag name='nvme-ns'/>
<flag name='usb-bot'/>
<flag name='acpi-generic-initiator'/>
+ <flag name='iommufd'/>
<version>10000000</version>
<microcodeVersion>61700285</microcodeVersion>
<package>v10.0.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml
index 82a66a6524..cf00ac4ea0 100644
--- a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml
@@ -136,6 +136,7 @@
<flag name='nvme'/>
<flag name='nvme-ns'/>
<flag name='usb-bot'/>
+ <flag name='iommufd'/>
<version>10000000</version>
<microcodeVersion>39100285</microcodeVersion>
<package>v10.0.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml
index cfce1c963d..5acd1a33fd 100644
--- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml
+++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml
@@ -209,6 +209,7 @@
<flag name='amd-iommu'/>
<flag name='usb-bot'/>
<flag name='acpi-generic-initiator'/>
+ <flag name='iommufd'/>
<version>10000000</version>
<microcodeVersion>43100285</microcodeVersion>
<package>v10.0.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
index f94c8388d6..50f58791e6 100644
--- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
@@ -209,6 +209,7 @@
<flag name='amd-iommu.pci-id'/>
<flag name='usb-bot'/>
<flag name='acpi-generic-initiator'/>
+ <flag name='iommufd'/>
<version>10000000</version>
<microcodeVersion>43100285</microcodeVersion>
<package>v10.0.0</package>
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 8e989a139f..e321c352a3 100644
--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
+++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
@@ -191,6 +191,7 @@
<flag name='usb-bot'/>
<flag name='tdx-guest'/>
<flag name='acpi-generic-initiator'/>
+ <flag name='iommufd'/>
<version>10000050</version>
<microcodeVersion>43100286</microcodeVersion>
<package>v10.0.0-1724-gf9a3def17b</package>
diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml
index 520a3d8ee8..2d52659520 100644
--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml
@@ -214,6 +214,7 @@
<flag name='tdx-guest'/>
<flag name='qom-list-get'/>
<flag name='acpi-generic-initiator'/>
+ <flag name='iommufd'/>
<version>10001000</version>
<microcodeVersion>43100286</microcodeVersion>
<package>v10.1.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml
index 874fd7bddb..eb2ab001a6 100644
--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml
+++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml
@@ -201,6 +201,7 @@
<flag name='acpi-generic-initiator'/>
<flag name='query-accelerators'/>
<flag name='mshv'/>
+ <flag name='iommufd'/>
<version>10001050</version>
<microcodeVersion>43100287</microcodeVersion>
<package>v10.1.0-1778-ge090e0312d</package>
diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml
index 7d5a75ce88..c4ea924c1f 100644
--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml
@@ -216,6 +216,7 @@
<flag name='disk-timed-stats'/>
<flag name='query-accelerators'/>
<flag name='scsi-block.migrate-pr'/>
+ <flag name='iommufd'/>
<version>10001091</version>
<microcodeVersion>43100287</microcodeVersion>
<package>v10.2.0-rc1-38-gfb241d0a1f</package>
diff --git a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml
index 1f2e27a218..88bd502fee 100644
--- a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml
@@ -204,6 +204,7 @@
<flag name='amd-iommu'/>
<flag name='usb-bot'/>
<flag name='acpi-generic-initiator'/>
+ <flag name='iommufd'/>
<version>9000000</version>
<microcodeVersion>43100245</microcodeVersion>
<package>v9.0.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml
index b961f79808..3d2692b02c 100644
--- a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml
@@ -126,6 +126,7 @@
<flag name='nvme'/>
<flag name='nvme-ns'/>
<flag name='usb-bot'/>
+ <flag name='iommufd'/>
<version>9001000</version>
<microcodeVersion>39100246</microcodeVersion>
<package>v9.1.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml
index 35ddf30736..66578099a7 100644
--- a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml
@@ -203,6 +203,7 @@
<flag name='amd-iommu'/>
<flag name='usb-bot'/>
<flag name='acpi-generic-initiator'/>
+ <flag name='iommufd'/>
<version>9001000</version>
<microcodeVersion>43100246</microcodeVersion>
<package>v9.1.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml
index e9f79261f7..9f95ed891e 100644
--- a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml
@@ -129,6 +129,7 @@
<flag name='nvme'/>
<flag name='nvme-ns'/>
<flag name='usb-bot'/>
+ <flag name='iommufd'/>
<version>9002000</version>
<microcodeVersion>39100247</microcodeVersion>
<package>v9.2.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml
index 0e52c3e23d..6636346bc5 100644
--- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml
+++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml
@@ -207,6 +207,7 @@
<flag name='amd-iommu'/>
<flag name='usb-bot'/>
<flag name='acpi-generic-initiator'/>
+ <flag name='iommufd'/>
<version>9002000</version>
<microcodeVersion>43100247</microcodeVersion>
<package>v9.2.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml
index 95f8a4d878..dee30415aa 100644
--- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml
@@ -205,6 +205,7 @@
<flag name='amd-iommu'/>
<flag name='usb-bot'/>
<flag name='acpi-generic-initiator'/>
+ <flag name='iommufd'/>
<version>9002000</version>
<microcodeVersion>43100247</microcodeVersion>
<package>v9.2.0</package>
--
2.53.0

View File

@ -0,0 +1,277 @@
From 94e2bf223d9fb7b9b65deaf8f2fbafb01dff5578 Mon Sep 17 00:00:00 2001
Message-ID: <94e2bf223d9fb7b9b65deaf8f2fbafb01dff5578.1770383182.git.jdenemar@redhat.com>
From: Nathan Chen <nathanc@nvidia.com>
Date: Fri, 30 Jan 2026 10:59:13 -0800
Subject: [PATCH] qemu: Introduce privateData for hostdevs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce private data for hostdevs and allocate hostdev
private data by default.
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 1043e04e17ed4be59b46e925089204333c08f05e)
Resolves: https://issues.redhat.com/browse/RHEL-74202
Resolves: https://issues.redhat.com/browse/RHEL-126346
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/bhyve/bhyve_parse_command.c | 2 +-
src/conf/domain_conf.c | 13 +++++++++--
src/conf/domain_conf.h | 5 ++++-
src/libxl/xen_common.c | 2 +-
src/libxl/xen_xl.c | 2 +-
src/lxc/lxc_native.c | 2 +-
src/qemu/qemu_domain.c | 40 +++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 15 +++++++++++++
src/vbox/vbox_common.c | 2 +-
tests/virhostdevtest.c | 2 +-
10 files changed, 76 insertions(+), 9 deletions(-)
diff --git a/src/bhyve/bhyve_parse_command.c b/src/bhyve/bhyve_parse_command.c
index d62ea64beb..8b405206bd 100644
--- a/src/bhyve/bhyve_parse_command.c
+++ b/src/bhyve/bhyve_parse_command.c
@@ -687,7 +687,7 @@ bhyveParsePassthru(virDomainDef *def G_GNUC_UNUSED,
return -1;
}
- hostdev = virDomainHostdevDefNew();
+ hostdev = virDomainHostdevDefNew(NULL);
hostdev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 541dad5bdc..f950f7c75d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2733,6 +2733,8 @@ virDomainHostdevDefClear(virDomainHostdevDef *def)
case VIR_DOMAIN_HOSTDEV_MODE_LAST:
break;
}
+
+ g_clear_pointer(&def->privateData, virObjectUnref);
}
@@ -3483,7 +3485,7 @@ void virDomainVideoDefFree(virDomainVideoDef *def)
virDomainHostdevDef *
-virDomainHostdevDefNew(void)
+virDomainHostdevDefNew(virDomainXMLOption *xmlopt)
{
virDomainHostdevDef *def;
@@ -3491,6 +3493,13 @@ virDomainHostdevDefNew(void)
def->info = g_new0(virDomainDeviceInfo, 1);
+ if (xmlopt && xmlopt->privateData.hostdevNew &&
+ !(def->privateData = xmlopt->privateData.hostdevNew())) {
+ VIR_FREE(def->info);
+ VIR_FREE(def);
+ return NULL;
+ }
+
return def;
}
@@ -13678,7 +13687,7 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt,
ctxt->node = node;
- def = virDomainHostdevDefNew();
+ def = virDomainHostdevDefNew(xmlopt);
if (virXMLPropEnumDefault(node, "mode", virDomainHostdevModeTypeFromString,
VIR_XML_PROP_NONE,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cb35ff06bd..8f53ed96c0 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -364,6 +364,8 @@ struct _virDomainHostdevDef {
*/
virDomainNetDef *parentnet;
+ virObject *privateData;
+
virDomainHostdevMode mode;
virDomainStartupPolicy startupPolicy;
bool managed;
@@ -3588,6 +3590,7 @@ struct _virDomainXMLPrivateDataCallbacks {
virDomainXMLPrivateDataNewFunc vsockNew;
virDomainXMLPrivateDataNewFunc cryptoNew;
virDomainXMLPrivateDataNewFunc graphicsNew;
+ virDomainXMLPrivateDataNewFunc hostdevNew;
virDomainXMLPrivateDataNewFunc networkNew;
virDomainXMLPrivateDataNetParseFunc networkParse;
virDomainXMLPrivateDataNetFormatFunc networkFormat;
@@ -3797,7 +3800,7 @@ virDomainVideoDef *virDomainVideoDefNew(virDomainXMLOption *xmlopt);
void virDomainVideoDefFree(virDomainVideoDef *def);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVideoDef, virDomainVideoDefFree);
void virDomainVideoDefClear(virDomainVideoDef *def);
-virDomainHostdevDef *virDomainHostdevDefNew(void);
+virDomainHostdevDef *virDomainHostdevDefNew(virDomainXMLOption *xmlopt);
void virDomainHostdevDefFree(virDomainHostdevDef *def);
void virDomainHubDefFree(virDomainHubDef *def);
void virDomainRedirdevDefFree(virDomainRedirdevDef *def);
diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c
index 666c6cae20..f19e4f6abb 100644
--- a/src/libxl/xen_common.c
+++ b/src/libxl/xen_common.c
@@ -445,7 +445,7 @@ xenParsePCI(char *entry)
}
}
- hostdev = virDomainHostdevDefNew();
+ hostdev = virDomainHostdevDefNew(NULL);
hostdev->managed = false;
hostdev->writeFiltering = filtered;
hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c
index b2ff0edcf2..e62302736b 100644
--- a/src/libxl/xen_xl.c
+++ b/src/libxl/xen_xl.c
@@ -930,7 +930,7 @@ xenParseXLUSB(virConf *conf, virDomainDef *def)
key = nextkey;
}
- hostdev = virDomainHostdevDefNew();
+ hostdev = virDomainHostdevDefNew(NULL);
hostdev->managed = false;
hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
hostdev->source.subsys.u.usb.bus = busNum;
diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c
index 7700804429..a94427b027 100644
--- a/src/lxc/lxc_native.c
+++ b/src/lxc/lxc_native.c
@@ -376,7 +376,7 @@ lxcCreateNetDef(const char *type,
static virDomainHostdevDef *
lxcCreateHostdevDef(const char *data)
{
- virDomainHostdevDef *hostdev = virDomainHostdevDefNew();
+ virDomainHostdevDef *hostdev = virDomainHostdevDefNew(NULL);
hostdev->mode = VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES;
hostdev->source.caps.type = VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET;
hostdev->source.caps.u.net.ifname = g_strdup(data);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 486a0e7913..3366214677 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1238,6 +1238,45 @@ qemuDomainNetworkPrivateFormat(const virDomainNetDef *net,
}
+static virClass *qemuDomainHostdevPrivateClass;
+
+static void
+qemuDomainHostdevPrivateDispose(void *obj)
+{
+ qemuDomainHostdevPrivate *priv = obj;
+
+ VIR_FORCE_CLOSE(priv->vfioDeviceFd);
+}
+
+
+static int
+qemuDomainHostdevPrivateOnceInit(void)
+{
+ if (!VIR_CLASS_NEW(qemuDomainHostdevPrivate, virClassForObject()))
+ return -1;
+
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(qemuDomainHostdevPrivate);
+
+virObject *
+qemuDomainHostdevPrivateNew(void)
+{
+ qemuDomainHostdevPrivate *priv;
+
+ if (qemuDomainHostdevPrivateInitialize() < 0)
+ return NULL;
+
+ if (!(priv = virObjectNew(qemuDomainHostdevPrivateClass)))
+ return NULL;
+
+ priv->vfioDeviceFd = -1;
+
+ return (virObject *) priv;
+}
+
+
/* qemuDomainSecretInfoSetup:
* @priv: pointer to domain private object
* @alias: alias of the secret
@@ -3563,6 +3602,7 @@ virDomainXMLPrivateDataCallbacks virQEMUDriverPrivateDataCallbacks = {
.chrSourceNew = qemuDomainChrSourcePrivateNew,
.vsockNew = qemuDomainVsockPrivateNew,
.graphicsNew = qemuDomainGraphicsPrivateNew,
+ .hostdevNew = qemuDomainHostdevPrivateNew,
.networkNew = qemuDomainNetworkPrivateNew,
.networkParse = qemuDomainNetworkPrivateParse,
.networkFormat = qemuDomainNetworkPrivateFormat,
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index b9bb338682..88c8416aa4 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -461,6 +461,18 @@ struct _qemuDomainTPMPrivate {
};
+#define QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev) \
+ ((qemuDomainHostdevPrivate *) (hostdev)->privateData)
+
+typedef struct _qemuDomainHostdevPrivate qemuDomainHostdevPrivate;
+struct _qemuDomainHostdevPrivate {
+ virObject parent;
+
+ /* VFIO device file descriptor for iommufd passthrough */
+ int vfioDeviceFd;
+};
+
+
void
qemuDomainNetworkPrivateClearFDs(qemuDomainNetworkPrivate *priv);
@@ -1175,3 +1187,6 @@ qemuDomainCheckCPU(virArch arch,
bool
qemuDomainMachineSupportsFloppy(const char *machine,
virQEMUCaps *qemuCaps);
+
+virObject *
+qemuDomainHostdevPrivateNew(void);
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 26c5fdfef6..d2a8cf8da4 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -3090,7 +3090,7 @@ vboxHostDeviceGetXMLDesc(struct _vboxDriver *data, virDomainDef *def, IMachine *
def->hostdevs = g_new0(virDomainHostdevDef *, def->nhostdevs);
for (i = 0; i < def->nhostdevs; i++)
- def->hostdevs[i] = virDomainHostdevDefNew();
+ def->hostdevs[i] = virDomainHostdevDefNew(NULL);
for (i = 0; i < deviceFilters.count; i++) {
PRBool active = PR_FALSE;
diff --git a/tests/virhostdevtest.c b/tests/virhostdevtest.c
index aec474a148..a35c1d9402 100644
--- a/tests/virhostdevtest.c
+++ b/tests/virhostdevtest.c
@@ -124,7 +124,7 @@ myInit(void)
for (i = 0; i < nhostdevs; i++) {
virDomainHostdevSubsys *subsys;
- hostdevs[i] = virDomainHostdevDefNew();
+ hostdevs[i] = virDomainHostdevDefNew(NULL);
if (!hostdevs[i])
goto cleanup;
hostdevs[i]->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
--
2.52.0

View File

@ -0,0 +1,123 @@
From 11e31d9728c42cbb9f4a3a564e9ddec5d09849ba Mon Sep 17 00:00:00 2001
Message-ID: <11e31d9728c42cbb9f4a3a564e9ddec5d09849ba.1772815314.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Tue, 3 Feb 2026 20:26:59 +0100
Subject: [PATCH] qemu: Introduce qemuPrepareNVRAMFileCommon()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Most of the code in the qemuPrepareNVRAMFile() function can
be reused to create a varstore file from template. Move the
common parts to a generic helper, leaving only the parts
that are NVRAM-specific in the original function.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 41fe1199bbad4ab9cc4bda078571cd7bc5897d44)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/qemu/qemu_process.c | 56 +++++++++++++++++++++++++++--------------
1 file changed, 37 insertions(+), 19 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1aff3a277b..47deb9abb9 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4921,45 +4921,40 @@ qemuPrepareNVRAMBlock(virDomainLoaderDef *loader,
static int
-qemuPrepareNVRAMFile(virQEMUDriver *driver,
- virDomainLoaderDef *loader,
- bool reset_nvram)
+qemuPrepareNVRAMFileCommon(virQEMUDriver *driver,
+ const char *path,
+ const char *template,
+ bool reset_nvram)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
VIR_AUTOCLOSE srcFD = -1;
struct qemuPrepareNVRAMHelperData data;
- if (virFileExists(loader->nvram->path) && !reset_nvram)
+ if (!path)
return 0;
- if (!loader->nvramTemplate) {
+ if (virFileExists(path) && !reset_nvram)
+ return 0;
+
+ if (!template) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("unable to find any master var store for loader: %1$s"),
- loader->path);
+ path);
return -1;
}
- /* If 'nvramTemplateFormat' is empty it means that it's a user-provided
- * template which we couldn't verify. Assume the user knows what they're doing */
- if (loader->nvramTemplateFormat != VIR_STORAGE_FILE_NONE &&
- loader->nvram->format != loader->nvramTemplateFormat) {
- virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
- _("conversion of the nvram template to another target format is not supported"));
- return -1;
- }
-
- if ((srcFD = virFileOpenAs(loader->nvramTemplate, O_RDONLY,
+ if ((srcFD = virFileOpenAs(template, O_RDONLY,
0, -1, -1, 0)) < 0) {
virReportSystemError(-srcFD,
_("Failed to open file '%1$s'"),
- loader->nvramTemplate);
+ template);
return -1;
}
data.srcFD = srcFD;
- data.srcPath = loader->nvramTemplate;
+ data.srcPath = template;
- if (virFileRewrite(loader->nvram->path,
+ if (virFileRewrite(path,
S_IRUSR | S_IWUSR,
cfg->user, cfg->group,
qemuPrepareNVRAMHelper,
@@ -4971,6 +4966,29 @@ qemuPrepareNVRAMFile(virQEMUDriver *driver,
}
+static int
+qemuPrepareNVRAMFile(virQEMUDriver *driver,
+ virDomainLoaderDef *loader,
+ bool reset_nvram)
+{
+ /* If 'nvramTemplateFormat' is empty it means that it's a user-provided
+ * template which we couldn't verify. Assume the user knows what they're doing */
+ if (loader && loader->nvram &&
+ loader->nvramTemplateFormat != VIR_STORAGE_FILE_NONE &&
+ loader->nvram->format != loader->nvramTemplateFormat) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("conversion of the nvram template to another target format is not supported"));
+ return -1;
+ }
+
+ if (qemuPrepareNVRAMFileCommon(driver, loader->nvram->path,
+ loader->nvramTemplate, reset_nvram) < 0)
+ return -1;
+
+ return 0;
+}
+
+
int
qemuPrepareNVRAM(virQEMUDriver *driver,
virDomainDef *def,
--
2.53.0

View File

@ -0,0 +1,135 @@
From b59cc7646f454eb6626e976f20649d2bce3f21e6 Mon Sep 17 00:00:00 2001
Message-ID: <b59cc7646f454eb6626e976f20649d2bce3f21e6.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Wed, 4 Feb 2026 17:43:36 +0100
Subject: [PATCH] qemu: Introduce varstoreDir
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is the same as the existing nvramDir, except it will be
used to store the files used with the uefi-vars QEMU device.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit df3121d21ef257c601c0f15deb78deadcc6bffad)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
libvirt.spec.in | 1 +
src/qemu/meson.build | 1 +
src/qemu/qemu_conf.c | 4 ++++
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_driver.c | 12 ++++++++++++
tests/testutilsqemu.c | 2 ++
6 files changed, 21 insertions(+)
diff --git a/src/qemu/meson.build b/src/qemu/meson.build
index ff9a904277..b4fb62f14f 100644
--- a/src/qemu/meson.build
+++ b/src/qemu/meson.build
@@ -223,6 +223,7 @@ if conf.has('WITH_QEMU')
localstatedir / 'lib' / 'libvirt' / 'qemu' / 'ram',
localstatedir / 'lib' / 'libvirt' / 'qemu' / 'save',
localstatedir / 'lib' / 'libvirt' / 'qemu' / 'snapshot',
+ localstatedir / 'lib' / 'libvirt' / 'qemu' / 'varstore',
localstatedir / 'lib' / 'libvirt' / 'swtpm',
localstatedir / 'log' / 'libvirt' / 'qemu',
localstatedir / 'log' / 'swtpm' / 'libvirt' / 'qemu',
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 242955200a..0a2eae3d76 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -167,6 +167,7 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged,
cfg->checkpointDir = g_strdup_printf("%s/checkpoint", cfg->libDir);
cfg->autoDumpPath = g_strdup_printf("%s/dump", cfg->libDir);
cfg->nvramDir = g_strdup_printf("%s/nvram", cfg->libDir);
+ cfg->varstoreDir = g_strdup_printf("%s/varstore", cfg->libDir);
cfg->memoryBackingDir = g_strdup_printf("%s/ram", cfg->libDir);
} else if (privileged) {
cfg->logDir = g_strdup_printf("%s/log/libvirt/qemu", LOCALSTATEDIR);
@@ -188,6 +189,7 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged,
cfg->checkpointDir = g_strdup_printf("%s/checkpoint", cfg->libDir);
cfg->autoDumpPath = g_strdup_printf("%s/dump", cfg->libDir);
cfg->nvramDir = g_strdup_printf("%s/nvram", cfg->libDir);
+ cfg->varstoreDir = g_strdup_printf("%s/varstore", cfg->libDir);
cfg->memoryBackingDir = g_strdup_printf("%s/ram", cfg->libDir);
cfg->swtpmStorageDir = g_strdup_printf("%s/lib/libvirt/swtpm",
LOCALSTATEDIR);
@@ -215,6 +217,7 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged,
cfg->configBaseDir);
cfg->autoDumpPath = g_strdup_printf("%s/qemu/dump", cfg->configBaseDir);
cfg->nvramDir = g_strdup_printf("%s/qemu/nvram", cfg->configBaseDir);
+ cfg->varstoreDir = g_strdup_printf("%s/qemu/varstore", cfg->configBaseDir);
cfg->memoryBackingDir = g_strdup_printf("%s/qemu/ram", cfg->configBaseDir);
cfg->swtpmStorageDir = g_strdup_printf("%s/qemu/swtpm",
cfg->configBaseDir);
@@ -367,6 +370,7 @@ static void virQEMUDriverConfigDispose(void *obj)
g_free(cfg->checkpointDir);
g_free(cfg->channelTargetDir);
g_free(cfg->nvramDir);
+ g_free(cfg->varstoreDir);
g_free(cfg->defaultTLSx509certdir);
g_free(cfg->defaultTLSx509secretUUID);
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index edb65c99f4..3b97d24622 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -120,6 +120,7 @@ struct _virQEMUDriverConfig {
char *checkpointDir;
char *channelTargetDir;
char *nvramDir;
+ char *varstoreDir;
char *swtpmStorageDir;
char *defaultTLSx509certdir;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f3e7410f9e..d314aa94ce 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -626,6 +626,11 @@ qemuStateInitialize(bool privileged,
cfg->nvramDir);
goto error;
}
+ if (g_mkdir_with_parents(cfg->varstoreDir, 0777) < 0) {
+ virReportSystemError(errno, _("Failed to create varstore dir %1$s"),
+ cfg->varstoreDir);
+ goto error;
+ }
if (g_mkdir_with_parents(cfg->memoryBackingDir, 0777) < 0) {
virReportSystemError(errno, _("Failed to create memory backing dir %1$s"),
cfg->memoryBackingDir);
@@ -784,6 +789,13 @@ qemuStateInitialize(bool privileged,
(int)cfg->group);
goto error;
}
+ if (chown(cfg->varstoreDir, cfg->user, cfg->group) < 0) {
+ virReportSystemError(errno,
+ _("unable to set ownership of '%1$s' to %2$d:%3$d"),
+ cfg->varstoreDir, (int)cfg->user,
+ (int)cfg->group);
+ goto error;
+ }
if (chown(cfg->memoryBackingDir, cfg->user, cfg->group) < 0) {
virReportSystemError(errno,
_("unable to set ownership of '%1$s' to %2$d:%3$d"),
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index 78ec521266..21dfd3141d 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -336,6 +336,8 @@ int qemuTestDriverInit(virQEMUDriver *driver)
cfg->memoryBackingDir = g_strdup("/var/lib/libvirt/qemu/ram");
VIR_FREE(cfg->nvramDir);
cfg->nvramDir = g_strdup("/var/lib/libvirt/qemu/nvram");
+ VIR_FREE(cfg->varstoreDir);
+ cfg->varstoreDir = g_strdup("/var/lib/libvirt/qemu/varstore");
VIR_FREE(cfg->passtStateDir);
cfg->passtStateDir = g_strdup("/var/run/libvirt/qemu/passt");
VIR_FREE(cfg->dbusStateDir);
--
2.53.0

View File

@ -0,0 +1,111 @@
From cd9099d42dfaa10d7863f1615a35c48db9924191 Mon Sep 17 00:00:00 2001
Message-ID: <cd9099d42dfaa10d7863f1615a35c48db9924191.1771423658.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 16 Feb 2026 09:12:02 +0100
Subject: [PATCH] qemu: Move IOMMUFD validation to qemu_validate
Fail early if kernel doesn't support IOMMUFD.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 0c1af67be554d4daa2facfb647ce6e9914da2f06)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/libvirt_private.syms | 1 +
src/qemu/qemu_process.c | 8 +-------
src/qemu/qemu_validate.c | 7 +++++++
src/util/viriommufd.c | 13 +++++++++++++
src/util/viriommufd.h | 2 ++
5 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e2a7a16347..0904265459 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2654,6 +2654,7 @@ virInitctlSetRunLevel;
# util/viriommufd.h
virIOMMUFDSetRLimitMode;
+virIOMMUFDSupported;
# util/viriscsi.h
virISCSIConnectionLogin;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 37e688018c..479437fb34 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7690,13 +7690,7 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name);
if ((fd = open(VIR_IOMMU_DEV_PATH, O_RDWR | O_CLOEXEC)) < 0) {
- if (errno == ENOENT) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("IOMMU FD support requires /dev/iommu device"));
- } else {
- virReportSystemError(errno, "%s",
- _("cannot open /dev/iommu"));
- }
+ virReportSystemError(errno, "%s", _("cannot open /dev/iommu"));
return -1;
}
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 18f148f48c..aa441188cb 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -27,6 +27,7 @@
#include "qemu_process.h"
#include "domain_conf.h"
#include "virbitmap.h"
+#include "viriommufd.h"
#include "virlog.h"
#include "virutil.h"
@@ -2730,6 +2731,12 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev,
_("IOMMUFD is not supported by this version of qemu"));
return -1;
}
+
+ if (!virIOMMUFDSupported()) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("IOMMUFD is not supported by host kernel"));
+ return -1;
+ }
}
}
diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c
index 5af097683d..44b30029a5 100644
--- a/src/util/viriommufd.c
+++ b/src/util/viriommufd.c
@@ -88,3 +88,16 @@ int virIOMMUFDSetRLimitMode(int fd G_GNUC_UNUSED,
}
#endif
+
+/**
+ * virIOMMUFDSupported:
+ *
+ * Check the presence of IOMMU device.
+ *
+ * Retruns: true if it exists, false otherwise
+ */
+bool
+virIOMMUFDSupported(void)
+{
+ return virFileExists(VIR_IOMMU_DEV_PATH);
+}
diff --git a/src/util/viriommufd.h b/src/util/viriommufd.h
index ebecfe3633..ec6be9fa66 100644
--- a/src/util/viriommufd.h
+++ b/src/util/viriommufd.h
@@ -23,3 +23,5 @@
#define VIR_IOMMU_DEV_PATH "/dev/iommu"
int virIOMMUFDSetRLimitMode(int fd, bool processAccounting);
+
+bool virIOMMUFDSupported(void);
--
2.53.0

View File

@ -0,0 +1,196 @@
From 2e48398265ebe3a372fa699380696a11c27e409b Mon Sep 17 00:00:00 2001
Message-ID: <2e48398265ebe3a372fa699380696a11c27e409b.1781277506.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 12:36:48 +0200
Subject: [PATCH] qemu: Move domain caps flags handling to
virQEMUCapsFillDomainCPUHostModel
We will need to generate the capabilities in a different way based on
the flags.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit b4d3572198848e6a2886352e1a48b46afa37bec1)
https://redhat.atlassian.net/browse/RHEL-180449
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 34 ++++++++++++++++++++++++----------
src/qemu/qemu_capabilities.h | 3 ++-
src/qemu/qemu_conf.c | 6 ++++--
src/qemu/qemu_conf.h | 3 ++-
src/qemu/qemu_driver.c | 15 ++-------------
tests/domaincapstest.c | 2 +-
6 files changed, 35 insertions(+), 28 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 51a98b123d..34c3fd991b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6627,14 +6627,26 @@ virQEMUCapsFillDomainCPUMaximum(virDomainCaps *domCaps)
static void
virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
- virDomainCaps *domCaps)
+ virDomainCaps *domCaps,
+ unsigned int flags)
{
- virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED);
+ virQEMUCapsHostCPUType cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
+ virCPUDef *cpu;
- domCaps->cpu.hostModel = virCPUDefCopy(cpu);
- domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
- domCaps->virttype);
+ cpu = virCPUDefCopy(virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
+ cpuType));
+
+ cpu->addr = virQEMUCapsGetHostPhysAddr(qemuCaps, domCaps->virttype);
+
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES) {
+ virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, domCaps->virttype,
+ cpu, VIR_CPU_FEATURE_DISABLE);
+ }
+
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
+ virCPUExpandFeatures(domCaps->arch, cpu);
+
+ domCaps->cpu.hostModel = cpu;
}
@@ -6659,7 +6671,8 @@ virQEMUCapsFillDomainCPUCustom(virQEMUCaps *qemuCaps,
static void
virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
virArch hostarch,
- virDomainCaps *domCaps)
+ virDomainCaps *domCaps,
+ unsigned int flags)
{
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_PASSTHROUGH,
@@ -6676,7 +6689,7 @@ virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_MODEL,
domCaps->machine)) {
- virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps);
+ virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps, flags);
}
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
@@ -7306,7 +7319,8 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
virQEMUCaps *qemuCaps,
virArch hostarch,
virDomainCaps *domCaps,
- bool privileged)
+ bool privileged,
+ unsigned int flags)
{
virDomainCapsOS *os = &domCaps->os;
virDomainCapsDeviceDisk *disk = &domCaps->disk;
@@ -7349,7 +7363,7 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
firmwares, nfirmwares) < 0)
return -1;
- virQEMUCapsFillDomainCPUCaps(qemuCaps, hostarch, domCaps);
+ virQEMUCapsFillDomainCPUCaps(qemuCaps, hostarch, domCaps, flags);
virQEMUCapsFillDomainMemoryBackingCaps(qemuCaps, memoryBacking);
virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, domCaps->machine, disk);
virQEMUCapsFillDomainDeviceGraphicsCaps(cfg, qemuCaps, graphics);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 4dcf464061..d5a8027523 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -897,7 +897,8 @@ int virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
virQEMUCaps *qemuCaps,
virArch hostarch,
virDomainCaps *domCaps,
- bool privileged);
+ bool privileged,
+ unsigned int flags);
void virQEMUCapsFillDomainMemoryBackingCaps(virQEMUCaps *qemuCaps,
virDomainCapsMemoryBacking *memoryBacking);
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 0a2eae3d76..fa8592a04c 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1712,7 +1712,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
virQEMUCaps *qemuCaps,
const char *machine,
virArch arch,
- virDomainVirtType virttype)
+ virDomainVirtType virttype,
+ unsigned int flags)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autoptr(virDomainCaps) domCaps = NULL;
@@ -1746,7 +1747,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
qemuCaps,
driver->hostarch,
domCaps,
- driver->privileged) < 0)
+ driver->privileged,
+ flags) < 0)
return NULL;
return g_steal_pointer(&domCaps);
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 3b97d24622..9d5e93a45b 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -376,7 +376,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
virQEMUCaps *qemuCaps,
const char *machine,
virArch arch,
- virDomainVirtType virttype);
+ virDomainVirtType virttype,
+ unsigned int flags);
int qemuDriverAllocateID(virQEMUDriver *driver);
virDomainXMLOption *virQEMUDriverCreateXMLConf(virQEMUDriver *driver,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 15bbd0c5b0..f8de2b6736 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16754,21 +16754,10 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
if (!(domCaps = virQEMUDriverGetDomainCapabilities(driver,
qemuCaps, machine,
- arch, virttype)))
+ arch, virttype,
+ flags)))
return NULL;
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES) {
- virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, virttype,
- domCaps->cpu.hostModel,
- VIR_CPU_FEATURE_DISABLE);
- }
-
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) {
- virCPUDef *cpu = domCaps->cpu.hostModel;
- if (cpu && virCPUExpandFeatures(arch, cpu) < 0)
- return NULL;
- }
-
return virDomainCapsFormat(domCaps);
}
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index 5b2fc80f0a..f2248c2435 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -101,7 +101,7 @@ fillQemuCaps(virDomainCaps *domCaps,
if (virQEMUCapsFillDomainCaps(cfg,
qemuCaps, domCaps->arch, domCaps,
- false) < 0)
+ false, 0) < 0)
return -1;
/* As of f05b6a918e28 we are expecting to see OVMF_CODE.fd file which
--
2.54.0

View File

@ -0,0 +1,79 @@
From 66f478cd56f2f8fbd3bca3b229a8fcafe29bbee0 Mon Sep 17 00:00:00 2001
Message-ID: <66f478cd56f2f8fbd3bca3b229a8fcafe29bbee0.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sat, 14 Feb 2026 17:54:57 +0100
Subject: [PATCH] qemu: Save IOMMUFD state into status XML
We need to track if iommufd object was added to the VM when we add
hotplug support.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit b21b6dcc72f1853f103f3cfbe1ebbcfbf128b458)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_command.c | 2 ++
src/qemu/qemu_domain.c | 6 ++++++
src/qemu/qemu_domain.h | 1 +
3 files changed, 9 insertions(+)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d11d16e533..cca5fed285 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5359,6 +5359,8 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd,
if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
return -1;
+ priv->iommufdState = true;
+
return 0;
}
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index ada9d3431c..ccbfc8bac7 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1976,6 +1976,7 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivate *priv)
priv->migrationRecoverSetup = false;
g_clear_pointer(&priv->iommufd, qemuFDPassDirectFree);
+ priv->iommufdState = false;
g_clear_pointer(&priv->memoryBackingDir, g_free);
}
@@ -2844,6 +2845,9 @@ qemuDomainObjPrivateXMLFormat(virBuffer *buf,
priv->preMigrationMemlock);
}
+ if (priv->iommufdState)
+ virBufferAddLit(buf, "<iommufd/>\n");
+
return 0;
}
@@ -3582,6 +3586,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
return -1;
}
+ priv->iommufdState = virXPathBoolean("boolean(./iommufd)", ctxt) == 1;
+
return 0;
}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 8aa94fc25b..62c5252b9f 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -265,6 +265,7 @@ struct _qemuDomainObjPrivate {
GHashTable *fds;
qemuFDPassDirect *iommufd;
+ bool iommufdState; /* true if --object iommufd was added */
char *memoryBackingDir;
};
--
2.53.0

View File

@ -1,138 +0,0 @@
From 285324c27451376aabdcb867521f500c864ac894 Mon Sep 17 00:00:00 2001
Message-ID: <285324c27451376aabdcb867521f500c864ac894.1759908360.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-111863
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 a61dbf4529..bafa929c47 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 3d05ffc5aa..fad58cf409 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5051,6 +5051,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) */
@@ -5115,6 +5116,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 7c8f785f32..7467a378ad 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(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 de33ed9d74..21dbf6e1d2 100644
--- a/tools/virsh-domain-event.c
+++ b/tools/virsh-domain-event.c
@@ -71,7 +71,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,
@@ -104,7 +105,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,132 @@
From f496b6095bf96eb8931b78054a272a5aaf70a2d9 Mon Sep 17 00:00:00 2001
Message-ID: <f496b6095bf96eb8931b78054a272a5aaf70a2d9.1771336682.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 23 Jan 2026 17:18:14 +0100
Subject: [PATCH] qemu: Setup disk latency histograms on startup/hotplug/update
Setup the histograms on startup and hotplug of devices via
'qemuProcessSetupDiskPropsRuntime' and facilitate update/reset/disable
of histogram collection via 'qemuDomainChangeDiskLive'.
The latter allows to use the update device API to either clear the bins
or select new bin configuration or disable the histogram altogether
without the need for a specific API.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 5787326541be4eafaa7ae3b4f866b3da793d44fe)
https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2]
---
src/qemu/qemu_domain.c | 17 +++++++++++++++++
src/qemu/qemu_domain.h | 3 +++
src/qemu/qemu_hotplug.c | 29 +++++++++++++++++++++++++++++
src/qemu/qemu_process.c | 10 ++++++++++
4 files changed, 59 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8e1ebe7799..bdab117e96 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -10463,6 +10463,23 @@ qemuDomainInitializePflashStorageSource(virDomainObj *vm,
}
+/**
+ * qemuDomainDiskHasLatencyHistogram:
+ * @disk: disk definition
+ *
+ * Returns whether @disk has any latency histogram settings configured.
+ */
+bool
+qemuDomainDiskHasLatencyHistogram(virDomainDiskDef *disk)
+{
+ return disk->histogram_boundaries ||
+ disk->histogram_boundaries_read ||
+ disk->histogram_boundaries_write ||
+ disk->histogram_boundaries_zone ||
+ disk->histogram_boundaries_flush;
+}
+
+
/**
* qemuDomainDiskBlockJobIsSupported:
*
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 3361e97315..30ca67bf76 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1078,6 +1078,9 @@ int
qemuDomainInitializePflashStorageSource(virDomainObj *vm,
virQEMUDriverConfig *cfg);
+bool
+qemuDomainDiskHasLatencyHistogram(virDomainDiskDef *disk);
+
bool
qemuDomainDiskBlockJobIsSupported(virDomainDiskDef *disk);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f2dc4469a3..9445599d2c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -7310,6 +7310,35 @@ qemuDomainChangeDiskLive(virDomainObj *vm,
dev->data.disk->src = NULL;
}
+ if (qemuDomainDiskHasLatencyHistogram(disk) ||
+ qemuDomainDiskHasLatencyHistogram(orig_disk)) {
+ int rc;
+
+ qemuDomainObjEnterMonitor(vm);
+ rc = qemuMonitorBlockLatencyHistogramSet(qemuDomainGetMonitor(vm),
+ QEMU_DOMAIN_DISK_PRIVATE(orig_disk)->qomName,
+ disk->histogram_boundaries,
+ disk->histogram_boundaries_read,
+ disk->histogram_boundaries_write,
+ disk->histogram_boundaries_zone,
+ disk->histogram_boundaries_flush);
+ qemuDomainObjExitMonitor(vm);
+
+ if (rc < 0)
+ return -1;
+
+ g_clear_pointer(&orig_disk->histogram_boundaries, g_free);
+ g_clear_pointer(&orig_disk->histogram_boundaries_read, g_free);
+ g_clear_pointer(&orig_disk->histogram_boundaries_write, g_free);
+ g_clear_pointer(&orig_disk->histogram_boundaries_zone, g_free);
+ g_clear_pointer(&orig_disk->histogram_boundaries_flush, g_free);
+ orig_disk->histogram_boundaries = g_steal_pointer(&disk->histogram_boundaries);
+ orig_disk->histogram_boundaries_read = g_steal_pointer(&disk->histogram_boundaries_read);
+ orig_disk->histogram_boundaries_write = g_steal_pointer(&disk->histogram_boundaries_write);
+ orig_disk->histogram_boundaries_zone = g_steal_pointer(&disk->histogram_boundaries_zone);
+ orig_disk->histogram_boundaries_flush = g_steal_pointer(&disk->histogram_boundaries_flush);
+ }
+
/* in case when we aren't updating disk source we update startup policy here */
orig_disk->startupPolicy = dev->data.disk->startupPolicy;
orig_disk->snapshot = dev->data.disk->snapshot;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index aadfaa92b0..37e688018c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7959,6 +7959,16 @@ qemuProcessSetupDiskPropsRuntime(qemuMonitor *mon,
&disk->blkdeviotune) < 0)
return -1;
+ if (qemuDomainDiskHasLatencyHistogram(disk) &&
+ qemuMonitorBlockLatencyHistogramSet(mon,
+ QEMU_DOMAIN_DISK_PRIVATE(disk)->qomName,
+ disk->histogram_boundaries,
+ disk->histogram_boundaries_read,
+ disk->histogram_boundaries_write,
+ disk->histogram_boundaries_zone,
+ disk->histogram_boundaries_flush) < 0)
+ return -1;
+
return 0;
}
--
2.53.0

View File

@ -1,150 +0,0 @@
From d6538b2bb2cc1499a020e9f8171ee187c741f9b2 Mon Sep 17 00:00:00 2001
Message-ID: <d6538b2bb2cc1499a020e9f8171ee187c741f9b2.1759908360.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-111863
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 22cad50f55..16e04829c4 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -130,6 +130,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 514fc372ac..738ae1a1f3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1970,13 +1970,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 d726175d42..c1fef8d5de 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1083,6 +1083,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 7467a378ad..3a6ea44c8b 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 b8c4af4aaf..9f783790ac 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -190,6 +190,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,212 @@
From 9a525305075612f540a1d3b2727ddf8b5320ff01 Mon Sep 17 00:00:00 2001
Message-ID: <9a525305075612f540a1d3b2727ddf8b5320ff01.1770383182.git.jdenemar@redhat.com>
From: Nathan Chen <nathanc@nvidia.com>
Date: Fri, 30 Jan 2026 10:59:14 -0800
Subject: [PATCH] qemu: Support per-process memory accounting for iommufd
Implement the IOMMU_OPTION_RLIMIT_MODE
ioctl to set per-process memory accounting for
iommufd. This prevents ENOMEM errors from the
default per-user memory accounting when multiple
VMs under the libvirt-qemu user have their pinned
memory summed and checked against a per-process
RLIMIT_MEMLOCK limit.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit f91a07d0c8dd583928974e80bb13b54feb5aa908)
Resolves: https://issues.redhat.com/browse/RHEL-74202
Resolves: https://issues.redhat.com/browse/RHEL-126346
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
meson.build | 1 +
po/POTFILES | 1 +
src/libvirt_private.syms | 3 ++
src/util/meson.build | 1 +
src/util/viriommufd.c | 90 ++++++++++++++++++++++++++++++++++++++++
src/util/viriommufd.h | 25 +++++++++++
6 files changed, 121 insertions(+)
create mode 100644 src/util/viriommufd.c
create mode 100644 src/util/viriommufd.h
diff --git a/meson.build b/meson.build
index 6ac9d01952..28745e4e32 100644
--- a/meson.build
+++ b/meson.build
@@ -673,6 +673,7 @@ headers = [
'ifaddrs.h',
'libtasn1.h',
'linux/kvm.h',
+ 'linux/iommufd.h',
'mntent.h',
'net/ethernet.h',
'net/if.h',
diff --git a/po/POTFILES b/po/POTFILES
index f0aad35c8c..c78d2b8000 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -303,6 +303,7 @@ src/util/virhostuptime.c
src/util/viridentity.c
src/util/virinhibitor.c
src/util/virinitctl.c
+src/util/viriommufd.c
src/util/viriscsi.c
src/util/virjson.c
src/util/virlease.c
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4e57e4a8f6..66261ed6cf 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2652,6 +2652,9 @@ virInhibitorRelease;
virInitctlFifos;
virInitctlSetRunLevel;
+# util/viriommufd.h
+virIOMMUFDSetRLimitMode;
+
# util/viriscsi.h
virISCSIConnectionLogin;
virISCSIConnectionLogout;
diff --git a/src/util/meson.build b/src/util/meson.build
index 4950a795cc..9fb0aa0fe7 100644
--- a/src/util/meson.build
+++ b/src/util/meson.build
@@ -46,6 +46,7 @@ util_sources = [
'viridentity.c',
'virinhibitor.c',
'virinitctl.c',
+ 'viriommufd.c',
'viriscsi.c',
'virjson.c',
'virkeycode.c',
diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c
new file mode 100644
index 0000000000..5af097683d
--- /dev/null
+++ b/src/util/viriommufd.c
@@ -0,0 +1,90 @@
+#include <config.h>
+
+#include "viriommufd.h"
+#include "virlog.h"
+#include "virerror.h"
+#include "virfile.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+VIR_LOG_INIT("util.iommufd");
+
+#ifdef __linux__
+
+# include <sys/ioctl.h>
+# include <linux/types.h>
+
+# ifdef HAVE_LINUX_IOMMUFD_H
+# include <linux/iommufd.h>
+# endif
+
+# ifndef IOMMU_OPTION
+
+enum iommufd_option {
+ IOMMU_OPTION_RLIMIT_MODE = 0,
+ IOMMU_OPTION_HUGE_PAGES = 1,
+};
+
+enum iommufd_option_ops {
+ IOMMU_OPTION_OP_SET = 0,
+ IOMMU_OPTION_OP_GET = 1,
+};
+
+struct iommu_option {
+ __u32 size;
+ __u32 option_id;
+ __u16 op;
+ __u16 __reserved;
+ __u32 object_id;
+ __aligned_u64 val64;
+};
+
+# define IOMMUFD_TYPE (';')
+# define IOMMUFD_CMD_OPTION 0x87
+# define IOMMU_OPTION _IO(IOMMUFD_TYPE, IOMMUFD_CMD_OPTION)
+
+# endif
+
+/**
+ * virIOMMUFDSetRLimitMode:
+ * @fd: iommufd file descriptor
+ * @processAccounting: true for per-process, false for per-user
+ *
+ * Set RLIMIT_MEMLOCK accounting mode for the iommufd.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int
+virIOMMUFDSetRLimitMode(int fd, bool processAccounting)
+{
+ struct iommu_option option = {
+ .size = sizeof(struct iommu_option),
+ .option_id = IOMMU_OPTION_RLIMIT_MODE,
+ .op = IOMMU_OPTION_OP_SET,
+ .__reserved = 0,
+ .object_id = 0,
+ .val64 = processAccounting ? 1 : 0,
+ };
+
+ if (ioctl(fd, IOMMU_OPTION, &option) < 0) {
+ virReportSystemError(errno, "%s",
+ _("failed to set memory accounting for iommufd"));
+ return -1;
+ }
+
+ VIR_DEBUG("Set iommufd rlimit mode to %s-based accounting",
+ processAccounting ? "process" : "user");
+ return 0;
+}
+
+#else
+
+int virIOMMUFDSetRLimitMode(int fd G_GNUC_UNUSED,
+ bool processAccounting G_GNUC_UNUSED)
+{
+ virReportError(VIR_ERR_NO_SUPPORT, "%s",
+ _("IOMMUFD is not supported on this platform"));
+ return -1;
+}
+
+#endif
diff --git a/src/util/viriommufd.h b/src/util/viriommufd.h
new file mode 100644
index 0000000000..ebecfe3633
--- /dev/null
+++ b/src/util/viriommufd.h
@@ -0,0 +1,25 @@
+/*
+ * viriommufd.h: iommufd helpers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "internal.h"
+
+#define VIR_IOMMU_DEV_PATH "/dev/iommu"
+
+int virIOMMUFDSetRLimitMode(int fd, bool processAccounting);
--
2.52.0

View File

@ -1,96 +0,0 @@
From 0a5602be0bed2e4dc13aa85ec28b3e012649c64e Mon Sep 17 00:00:00 2001
Message-ID: <0a5602be0bed2e4dc13aa85ec28b3e012649c64e.1759908360.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-111863
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 b06949ab66..6d984df412 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1060,10 +1060,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 98eabbb89f..755f347e17 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 6697b747b0..9f51421478 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,336 @@
From 01ce19df7986fe190ce212fa05f2caed799cc50f Mon Sep 17 00:00:00 2001
Message-ID: <01ce19df7986fe190ce212fa05f2caed799cc50f.1770383182.git.jdenemar@redhat.com>
From: Nathan Chen <nathanc@nvidia.com>
Date: Fri, 30 Jan 2026 10:59:17 -0800
Subject: [PATCH] qemu: Update Cgroup, namespace, and seclabel for iommufd
When launching a qemu VM with the iommufd feature enabled for VFIO
hostdevs:
- Do not allow cgroup, namespace, and seclabel access to VFIO
paths (/dev/vfio/vfio and /dev/vfio/<iommugroup>)
- Allow access to iommufd paths (/dev/iommu and
/dev/vfio/devices/vfio*) for AppArmor, SELinux, and DAC
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 7d2f91f9cb572ab95d0916bdd1a46dd198874529)
Resolves: https://issues.redhat.com/browse/RHEL-74202
Resolves: https://issues.redhat.com/browse/RHEL-126346
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_cgroup.c | 3 ++
src/qemu/qemu_namespace.c | 3 ++
src/security/security_apparmor.c | 28 ++++++++++++------
src/security/security_dac.c | 49 +++++++++++++++++++++++++-------
src/security/security_selinux.c | 47 +++++++++++++++++++++++-------
src/security/virt-aa-helper.c | 32 ++++++++++++++++-----
6 files changed, 127 insertions(+), 35 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 7dadef0739..6148990f19 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -479,6 +479,9 @@ qemuSetupHostdevCgroup(virDomainObj *vm,
g_autofree char *path = NULL;
int perms;
+ if (dev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES)
+ return 0;
+
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
return 0;
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index c689cc3e40..fb0734193d 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -345,6 +345,9 @@ qemuDomainSetupHostdev(virDomainObj *vm,
{
g_autofree char *path = NULL;
+ if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES)
+ return 0;
+
if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0)
return -1;
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 68ac39611f..934acfb461 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -45,6 +45,7 @@
#include "virstring.h"
#include "virscsi.h"
#include "virmdev.h"
+#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -841,25 +842,36 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
- virPCIDevice *pci =
+ g_autoptr(virPCIDevice) pci =
virPCIDeviceNew(&pcisrc->addr);
if (!pci)
goto done;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
+ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
- if (!vfioGroupDev) {
- virPCIDeviceFree(pci);
- goto done;
+ if (!vfioGroupDev) {
+ goto done;
+ }
+ ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr);
+ VIR_FREE(vfioGroupDev);
+ } else {
+ g_autofree char *vfiofdDev = NULL;
+
+ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0)
+ goto done;
+
+ ret = AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr);
+ if (ret < 0)
+ goto done;
+
+ ret = AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr);
}
- ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr);
- VIR_FREE(vfioGroupDev);
} else {
ret = virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr);
}
- virPCIDeviceFree(pci);
break;
}
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 2f788b872a..d0ed22db2d 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -41,6 +41,7 @@
#include "virscsivhost.h"
#include "virstring.h"
#include "virutil.h"
+#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -1282,14 +1283,27 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
+ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
- if (!vfioGroupDev)
- return -1;
+ if (!vfioGroupDev)
+ return -1;
- ret = virSecurityDACSetHostdevLabelHelper(vfioGroupDev,
- false,
- &cbdata);
+ ret = virSecurityDACSetHostdevLabelHelper(vfioGroupDev,
+ false,
+ &cbdata);
+ } else {
+ g_autofree char *vfiofdDev = NULL;
+
+ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0)
+ return -1;
+
+ ret = virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata);
+ if (ret < 0)
+ break;
+
+ ret = virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata);
+ }
} else {
ret = virPCIDeviceFileIterate(pci,
virSecurityDACSetPCILabel,
@@ -1443,13 +1457,28 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
+ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
- if (!vfioGroupDev)
- return -1;
+ if (!vfioGroupDev)
+ return -1;
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
+ ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
vfioGroupDev, false);
+ } else {
+ g_autofree char *vfiofdDev = NULL;
+
+ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0)
+ return -1;
+
+ ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
+ vfiofdDev, false);
+ if (ret < 0)
+ break;
+
+ ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
+ VIR_IOMMU_DEV_PATH, false);
+ }
} else {
ret = virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr);
}
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 2f3cc274a5..834383a7de 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -41,6 +41,7 @@
#include "virconf.h"
#include "virtpm.h"
#include "virstring.h"
+#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -2256,14 +2257,27 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
+ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
- if (!vfioGroupDev)
- return -1;
+ if (!vfioGroupDev)
+ return -1;
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev,
- false,
- &data);
+ ret = virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev,
+ false,
+ &data);
+ } else {
+ g_autofree char *vfiofdDev = NULL;
+
+ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0)
+ return -1;
+
+ ret = virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data);
+ if (ret)
+ break;
+
+ ret = virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data);
+ }
} else {
ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data);
}
@@ -2491,12 +2505,25 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
+ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
- if (!vfioGroupDev)
- return -1;
+ if (!vfioGroupDev)
+ return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false);
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false);
+ } else {
+ g_autofree char *vfiofdDev = NULL;
+
+ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0)
+ return -1;
+
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false);
+ if (ret < 0)
+ break;
+
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false);
+ }
} else {
ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr);
}
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index de0a826063..29e844c7ff 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -50,6 +50,7 @@
#include "virstring.h"
#include "virgettext.h"
#include "virhostdev.h"
+#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -1114,8 +1115,9 @@ get_files(vahControl * ctl)
virDeviceHostdevPCIDriverName driverName = dev->source.subsys.u.pci.driver.name;
- if (driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO ||
- driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT) {
+ if ((driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO ||
+ driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT) &&
+ dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
needsVfio = true;
}
@@ -1385,9 +1387,18 @@ get_files(vahControl * ctl)
}
}
- if (ctl->newfile &&
- vah_add_file(&buf, ctl->newfile, "rwk") != 0) {
- return -1;
+ if (ctl->newfile) {
+ const char *perms = "rwk";
+
+ /* VFIO and iommufd devices need mmap permission */
+ if (STRPREFIX(ctl->newfile, "/dev/vfio/devices/vfio") ||
+ STREQ(ctl->newfile, VIR_IOMMU_DEV_PATH)) {
+ perms = "rwm";
+ }
+
+ if (vah_add_file(&buf, ctl->newfile, perms) != 0) {
+ return -1;
+ }
}
ctl->files = virBufferContentAndReset(&buf);
@@ -1561,8 +1572,15 @@ main(int argc, char **argv)
}
}
if (ctl->append && ctl->newfile) {
- if (vah_add_file(&buf, ctl->newfile, "rwk") != 0)
- goto cleanup;
+ const char *perms = "rwk";
+
+ if (STRPREFIX(ctl->newfile, "/dev/vfio/devices/vfio") ||
+ STREQ(ctl->newfile, VIR_IOMMU_DEV_PATH)) {
+ perms = "rwm";
+ }
+
+ if (vah_add_file(&buf, ctl->newfile, perms) != 0)
+ return -1;
} else {
if (ctl->def->virtType == VIR_DOMAIN_VIRT_QEMU ||
ctl->def->virtType == VIR_DOMAIN_VIRT_KQEMU ||
--
2.52.0

View File

@ -0,0 +1,107 @@
From 4cab992a178b61de2422f632d86070e1f5618791 Mon Sep 17 00:00:00 2001
Message-ID: <4cab992a178b61de2422f632d86070e1f5618791.1774618368.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 13:10:37 +0100
Subject: [PATCH] qemu: Update qemuDomainNeedsVFIO to ignore PCI hostdev with
IOMMUFD
This function is used to figure out if VM needs access to /dev/vfio/vfio.
In case of PCI host devices that is true only if IOMMUFD is not enabled.
This fixes error when hotplugging PCI host device with IOMMUFD disabled
to a VM that already has PCI host device with IOMMIFD enabled:
Could not open '/dev/vfio/vfio': No such file or directory
The function is used in this case to check if /dev/vfio/vfio was already
made available to QEMU or not.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit d1fb5cf127d7681fa6c27e5b163ef410132aea49)
Resolves: https://redhat.atlassian.net/browse/RHEL-159175
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/domain_conf.c | 14 ++++++++++++++
src/conf/domain_conf.h | 3 +++
src/libvirt_private.syms | 1 +
src/qemu/qemu_domain.c | 9 ++++++++-
4 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 12727c9eef..d029fc01ea 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32563,6 +32563,20 @@ virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def)
}
+bool
+virDomainDefHasPCIHostdevWithoutIOMMUFD(const virDomainDef *def)
+{
+ size_t i;
+
+ for (i = 0; i < def->nhostdevs; i++) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(def->hostdevs[i]))
+ return true;
+ }
+
+ return false;
+}
+
+
bool
virDomainDefHasMdevHostdev(const virDomainDef *def)
{
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7f8c02a87b..a1cc2f05ac 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4667,6 +4667,9 @@ virDomainDefHasPCIHostdev(const virDomainDef *def);
bool
virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def);
+bool
+virDomainDefHasPCIHostdevWithoutIOMMUFD(const virDomainDef *def);
+
bool
virDomainDefHasMdevHostdev(const virDomainDef *def);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f1fef9d415..765c55f3b2 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -349,6 +349,7 @@ virDomainDefHasOldStyleROUEFI;
virDomainDefHasOldStyleUEFI;
virDomainDefHasPCIHostdev;
virDomainDefHasPCIHostdevWithIOMMUFD;
+virDomainDefHasPCIHostdevWithoutIOMMUFD;
virDomainDefHasTimer;
virDomainDefHasUSB;
virDomainDefHasVcpusOffline;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 57f18a02b6..a61939aa15 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9284,10 +9284,17 @@ qemuDomainSupportsVideoVga(const virDomainVideoDef *video,
}
+/**
+ * qemuDomainNeedsVFIO:
+ * @def: domain definition to check
+ *
+ * Check the domain definition to figure out if QEMU needs access
+ * to /dev/vfio/vfio. It's not required if IOMMUFD is used.
+ */
bool
qemuDomainNeedsVFIO(const virDomainDef *def)
{
- return virDomainDefHasPCIHostdev(def) ||
+ return virDomainDefHasPCIHostdevWithoutIOMMUFD(def) ||
virDomainDefHasMdevHostdev(def) ||
virDomainDefHasNVMeDisk(def);
}
--
2.53.0

View File

@ -0,0 +1,69 @@
From 933524784d813b24aa0970992b820698f1e03180 Mon Sep 17 00:00:00 2001
Message-ID: <933524784d813b24aa0970992b820698f1e03180.1766070439.git.jdenemar@redhat.com>
From: Nathan Chen via Devel <devel@lists.libvirt.org>
Date: Tue, 2 Dec 2025 11:59:47 -0800
Subject: [PATCH] qemu: Use pci_bus to identify multi-smmuv3 model
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Use presence of non-negative pci_bus to identify multi-smmuv3
IOMMU model, instead of the niommus attribute. This allows for
specifying a single arm-smmuv3 on the qemu command line,
instead of both the virt-machine smmuv3 and arm-smmuv3
being specified at the same time.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Fixes: e70c4d54d365 conf: Support multiple device-pluggable smmuv3 IOMMUs
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit da4305b7bc8d3bd52c60db1905db88e43ebd9868)
https://issues.redhat.com/browse/RHEL-74200
Signed-off-by: Ján Tomko <jtomko@redhat.com>
---
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_postparse.c | 2 +-
.../iommu-smmuv3-pci-bus-single.aarch64-latest.args | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b69fe23236..fb89dbec27 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7192,7 +7192,7 @@ qemuBuildMachineCommandLine(virCommand *cmd,
if (qemuAppendDomainFeaturesMachineParam(&buf, def, qemuCaps) < 0)
return -1;
- if (def->niommus == 1) {
+ if (def->iommus && def->iommus[0]->pci_bus < 0) {
switch (def->iommus[0]->model) {
case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
virBufferAddLit(&buf, ",iommu=smmuv3");
diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c
index dc5ade829a..840d6a1174 100644
--- a/src/qemu/qemu_postparse.c
+++ b/src/qemu/qemu_postparse.c
@@ -1559,7 +1559,7 @@ qemuDomainDefEnableDefaultFeatures(virDomainDef *def,
* domain already has IOMMU without inremap. This will be fixed in
* qemuDomainIOMMUDefPostParse() but there domain definition can't be
* modified so change it now. */
- if (def->iommus && def->niommus == 1 &&
+ if (def->iommus && def->iommus[0]->pci_bus < 0 &&
(def->iommus[0]->intremap == VIR_TRISTATE_SWITCH_ON ||
qemuDomainNeedsIOMMUWithEIM(def)) &&
def->features[VIR_DOMAIN_FEATURE_IOAPIC] == VIR_DOMAIN_IOAPIC_NONE) {
diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args
index 976467e641..34e7bda1c5 100644
--- a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args
+++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args
@@ -10,7 +10,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \
-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 virt,usb=off,gic-version=2,iommu=smmuv3,dump-guest-core=off,memory-backend=mach-virt.ram,acpi=off \
+-machine virt,usb=off,gic-version=2,dump-guest-core=off,memory-backend=mach-virt.ram,acpi=off \
-accel tcg \
-cpu cortex-a15 \
-m size=1048576k \
--
2.52.0

View File

@ -0,0 +1,65 @@
From 8b337691d19e1619f711b437b2618ac269e5e12f Mon Sep 17 00:00:00 2001
Message-ID: <8b337691d19e1619f711b437b2618ac269e5e12f.1772815313.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 21 Nov 2025 19:32:31 +0100
Subject: [PATCH] qemu: Validate presence of uefi-vars device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The use of varstore requires the uefi-vars device to be present
in the QEMU binary.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit bd3504651759afac45e76b73912952bf2af2bcfa)
https://issues.redhat.com/browse/RHEL-82645
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/qemu/qemu_validate.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index aa441188cb..25e1b9cf58 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -754,6 +754,23 @@ qemuValidateDomainDefNvram(const virDomainDef *def,
}
+static int
+qemuValidateDomainDefVarstore(const virDomainDef *def,
+ virQEMUCaps *qemuCaps)
+{
+ if (!def->os.varstore)
+ return 0;
+
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_UEFI_VARS)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("The uefi-vars device is not supported by this QEMU binary"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
qemuValidateDomainDefBoot(const virDomainDef *def,
virQEMUCaps *qemuCaps)
@@ -797,6 +814,9 @@ qemuValidateDomainDefBoot(const virDomainDef *def,
if (qemuValidateDomainDefNvram(def, qemuCaps) < 0)
return -1;
+
+ if (qemuValidateDomainDefVarstore(def, qemuCaps) < 0)
+ return -1;
}
for (i = 0; i < def->os.nacpiTables; i++) {
--
2.53.0

View File

@ -0,0 +1,59 @@
From 6cd1753e46526b5484a7942cdd21bd6d7e7f3240 Mon Sep 17 00:00:00 2001
Message-ID: <6cd1753e46526b5484a7942cdd21bd6d7e7f3240.1773324140.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 11 Feb 2026 10:16:34 +0100
Subject: [PATCH] qemu: Wire up new hyperv host-model mode behavior
Since some hyperv features might be already enabled/disabled when
entering qemuProcessEnableDomainFeatures() only those which are
not set in domain XML (i.e. are VIR_TRISTATE_SWITCH_ABSENT)
should be modified. Furthermore, some features are not a simple
on/off switch, but a number or a string even. Well, that doesn't
matter really as the logic for setting them is the same: only set
their value iff they are not already set.
Resolves: https://issues.redhat.com/browse/RHEL-148219
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 11057abfd13f6aad15f9821235b66c68e6211af6)
Resolves: https://issues.redhat.com/browse/RHEL-153576
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_process.c | 8 +++++++-
.../qemuxmlconfdata/hyperv-host-model.x86_64-latest.args | 2 +-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 3ca87df284..1559d6e0f8 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7003,7 +7003,13 @@ qemuProcessEnableDomainFeatures(virDomainObj *vm)
if (!VIR_DOMAIN_CAPS_ENUM_IS_SET(hv->features, i))
continue;
- vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
+ if (vm->def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ABSENT) {
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
+ } else {
+ /* if the user provided already config for this we skip the
+ * auto-population code */
+ continue;
+ }
if (i == VIR_DOMAIN_HYPERV_SPINLOCKS) {
if (hv->spinlocks != 0) {
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
index 58502ff51e..d1f2326da1 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,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' \
+-cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x2000,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' \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
--
2.53.0

Some files were not shown because too many files have changed in this diff Show More