libvirt-12.5.0-1.el10nv

- Rebased to libvirt-12.5.0 (VOYAGER-1356)
- The rebase also fixes the following bugs: VOYAGER-1351
- conf: Include check for pci_bus in virDomainIOMMUDefEquals() (VOYAGER-1043)
- qemu: introduce QEMU_CAPS_DEVICE_ARM_SMMUV3 (VOYAGER-1043)
- qemu: introduce QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS (VOYAGER-1043)
- qemu: introduce QEMU_CAPS_ARM_SMMUV3_ACCEL (VOYAGER-1043)
- qemu: Add support for HW-accelerated nested SMMUv3 (VOYAGER-1043)
- tests: qemuxmlconfdata: provide HW-accel smmuv3 sample XML and CLI args (VOYAGER-1043)
- qemu: Support NVIDIA Tegra241 CMDQV for SMMUv3 (VOYAGER-1045)
- tests: qemuxmlconfdata: provide cmdqv sample XML and CLI args (VOYAGER-1045)
- conf: Support EGM memory device model (VOYAGER-1109)
- qemu: Add cgroup, namespace, and seclabel setup for EGM memory device model (VOYAGER-1109)
- qemu: Add qemu CLI support for EGM (VOYAGER-1109)
- tests: Add qemuxmlconftest for ACPI EGM memory device (VOYAGER-1109)

Resolves: VOYAGER-1043, VOYAGER-1045, VOYAGER-1109, VOYAGER-1351, VOYAGER-1356
This commit is contained in:
Pavel Hrdina 2026-08-07 12:00:17 +02:00
parent dd91c3be50
commit 2985e48061
118 changed files with 3201 additions and 22838 deletions

View File

@ -1,31 +0,0 @@
[suppress_function]
symbol_version_regexp = LIBVIRT_PRIVATE.*
soname_regexp = libvirt\\.so.*
[suppress_function]
symbol_version_regexp = LIBVIRT_ADMIN_PRIVATE.*
soname_regexp = libvirt-admin\\.so.*
[suppress_variable]
symbol_version_regexp = LIBVIRT_PRIVATE.*
soname_regexp = libvirt\\.so.*
[suppress_variable]
symbol_version_regexp = LIBVIRT_ADMIN_PRIVATE.*
soname_regexp = libvirt-admin\\.so.*
[suppress_function]
symbol_version_regexp = .*
soname_regexp = libvirt_storage_.*\\.so.*
[suppress_variable]
symbol_version_regexp = .*
soname_regexp = libvirt_storage_.*\\.so.*
[suppress_function]
symbol_version_regexp = .*
soname_regexp = libvirt_driver_.*\\.so.*
[suppress_variable]
symbol_version_regexp = .*
soname_regexp = libvirt_driver_.*\\.so.*

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

View File

@ -1,248 +0,0 @@
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

@ -1,422 +0,0 @@
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

@ -1,125 +0,0 @@
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,162 +0,0 @@
From b06fc0bbe490630c77ac8382ff73d5fb8bc86682 Mon Sep 17 00:00:00 2001
Message-ID: <b06fc0bbe490630c77ac8382ff73d5fb8bc86682.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 15:28:17 +0100
Subject: [PATCH] conf: Add iommufd fdgroup support
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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 a211de1237..44f9b6e197 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1368,7 +1368,7 @@ Host Device IOMMUFD
<domain>
...
- <iommufd enabled='yes'/>
+ <iommufd enabled='yes' fdgroup='iommu'/>
...
</domain>
@@ -1382,6 +1382,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 fe8309cb81..06790e0962 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4192,6 +4192,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);
@@ -19806,6 +19808,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;
}
@@ -28081,6 +28085,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 0d41aca3a9..06e03deafe 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3239,6 +3239,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 51f7961e3c..f243b119a4 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1996,6 +1996,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)
@@ -2057,6 +2070,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 40aa3eac27..839a144da8 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1353,6 +1353,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

@ -0,0 +1,35 @@
From 5523cd4c855ca4739af3314e5b1e55eca2f3cf05 Mon Sep 17 00:00:00 2001
Message-ID: <5523cd4c855ca4739af3314e5b1e55eca2f3cf05.1786096788.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 5 Aug 2026 15:12:55 -0700
Subject: [PATCH] conf: Include check for pci_bus in virDomainIOMMUDefEquals()
From: Nathan Chen <nathanc@nvidia.com>
virDomainIOMMUDefEquals() should check for pci_bus being equal
across two virDomainIOMMUDef being compared.
Fixes: 4d6419b286af ("qemu: Implement pluggable-device smmuv3")
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
(cherry picked from commit b2bfc6b4c8b7243840750e1e95514a8646482cd4)
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1043
---
src/conf/domain_conf.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 17c4a57cd8..94cfb27c1d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -16849,6 +16849,7 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a,
a->iotlb != b->iotlb ||
a->aw_bits != b->aw_bits ||
a->dma_translation != b->dma_translation ||
+ a->pci_bus != b->pci_bus ||
a->xtsup != b->xtsup ||
a->pt != b->pt ||
a->granule != b->granule)
--
2.55.0

View File

@ -1,220 +0,0 @@
From 449dfefeb208ed42425a76a1ba69d5dd5401a7d0 Mon Sep 17 00:00:00 2001
Message-ID: <449dfefeb208ed42425a76a1ba69d5dd5401a7d0.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 11:57:57 +0100
Subject: [PATCH] conf: Introduce domain iommufd element
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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 8f1be253de..a211de1237 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1361,6 +1361,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 6e49507e83..fe8309cb81 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19784,6 +19784,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,
@@ -19862,6 +19887,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;
@@ -28041,6 +28069,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)
@@ -29589,6 +29633,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 de803d0dcc..0d41aca3a9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3238,6 +3238,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 5d0e538535..40aa3eac27 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1001,6 +1001,10 @@
<ref name="numatune"/>
</optional>
+ <optional>
+ <ref name="iommufd"/>
+ </optional>
+
<optional>
<ref name="respartition"/>
</optional>
@@ -1344,6 +1348,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

@ -1,69 +0,0 @@
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

@ -1,132 +0,0 @@
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

@ -1,89 +0,0 @@
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

@ -1,332 +0,0 @@
From 29bd170f0fafdb9518f0c795207aab1ea73f2fad Mon Sep 17 00:00:00 2001
Message-ID: <29bd170f0fafdb9518f0c795207aab1ea73f2fad.1774023916.git.phrdina@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
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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 effe44fe57..386e757d81 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1177,7 +1177,6 @@ virStorageSourceChainHasManagedPR;
virStorageSourceChainHasNVMe;
virStorageSourceClear;
virStorageSourceCopy;
-virStorageSourceFDTupleNew;
virStorageSourceGetActualType;
virStorageSourceGetSecurityLabelDef;
virStorageSourceHasBacking;
@@ -1230,6 +1229,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 f3e7410f9e..5e63614b4a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20234,7 +20234,7 @@ qemuDomainFDHashCloseConnect(virDomainObj *vm,
virConnectPtr conn)
{
qemuDomainObjPrivate *priv = QEMU_DOMAIN_PRIVATE(vm);
- virStorageSourceFDTuple *data;
+ virDomainFDTuple *data;
GHashTableIter htitr;
if (!priv->fds)
@@ -20258,7 +20258,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;
@@ -20276,7 +20276,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 78ec521266..fc51e0e3df 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -713,7 +713,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

@ -1,82 +0,0 @@
From 67ed6a3cc79096910ce80aebd4998e856b73de1d Mon Sep 17 00:00:00 2001
Message-ID: <67ed6a3cc79096910ce80aebd4998e856b73de1d.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 11:47:21 +0100
Subject: [PATCH] conf: Refactor virHostdevIsPCIDevice
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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 4e12ebf712..da90fd1446 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32883,6 +32883,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
@@ -32892,8 +32919,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);
}
@@ -32906,9 +32932,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

@ -1,5 +1,5 @@
From 8049e03589d633edba613c6775dcd5656d851460 Mon Sep 17 00:00:00 2001
Message-ID: <8049e03589d633edba613c6775dcd5656d851460.1779098642.git.phrdina@redhat.com>
From 7f6076eef8f66e5252cf1ecaa25446c26288a4aa Mon Sep 17 00:00:00 2001
Message-ID: <7f6076eef8f66e5252cf1ecaa25446c26288a4aa.1786096789.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Tue, 25 Nov 2025 11:17:01 -0800
Subject: [PATCH] conf: Support EGM memory device model
@ -14,7 +14,7 @@ respectively.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Resolves: https://redhat.atlassian.net/browse/VOYAGER-13
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1109
---
docs/formatdomain.rst | 18 +++++++++++++++++-
src/conf/domain_conf.c | 29 +++++++++++++++++++++++++++++
@ -25,10 +25,10 @@ Resolves: https://redhat.atlassian.net/browse/VOYAGER-13
6 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 44f9b6e197..4fde1534d6 100644
index f7b35d31fa..b1500ba718 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9119,6 +9119,16 @@ Example: usage of the memory devices
@@ -9193,6 +9193,16 @@ Example: usage of the memory devices
<size unit='KiB'>16384</size>
</target>
</memory>
@ -45,7 +45,7 @@ index 44f9b6e197..4fde1534d6 100644
</devices>
...
@@ -9130,7 +9140,8 @@ Example: usage of the memory devices
@@ -9204,7 +9214,8 @@ Example: usage of the memory devices
persistent memory device. :since:`Since 7.1.0` Provide ``virtio-mem`` model
to add paravirtualized memory device. :since:`Since 7.9.0` Provide
``sgx-epc`` model to add a SGX enclave page cache (EPC) memory to the guest.
@ -55,7 +55,7 @@ index 44f9b6e197..4fde1534d6 100644
``access``
An optional attribute ``access`` ( :since:`since 3.2.0` ) that provides
@@ -9265,6 +9276,11 @@ Example: usage of the memory devices
@@ -9339,6 +9350,11 @@ Example: usage of the memory devices
The physical address in memory, where device is mapped.
:since:`Since 9.4.0`
@ -68,10 +68,10 @@ index 44f9b6e197..4fde1534d6 100644
IOMMU devices
~~~~~~~~~~~~~
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 06790e0962..038476edd7 100644
index 974746bb5c..74b07ad88e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1522,6 +1522,7 @@ VIR_ENUM_IMPL(virDomainMemoryModel,
@@ -1535,6 +1535,7 @@ VIR_ENUM_IMPL(virDomainMemoryModel,
"virtio-pmem",
"virtio-mem",
"sgx-epc",
@ -79,7 +79,7 @@ index 06790e0962..038476edd7 100644
);
VIR_ENUM_IMPL(virDomainShmemModel,
@@ -3638,6 +3639,9 @@ void virDomainMemoryDefFree(virDomainMemoryDef *def)
@@ -3682,6 +3683,9 @@ void virDomainMemoryDefFree(virDomainMemoryDef *def)
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
virBitmapFree(def->source.sgx_epc.nodes);
break;
@ -89,7 +89,7 @@ index 06790e0962..038476edd7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -14216,6 +14220,10 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node,
@@ -14320,6 +14324,10 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node,
}
break;
@ -100,7 +100,7 @@ index 06790e0962..038476edd7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -14292,6 +14300,10 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
@@ -14396,6 +14404,10 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
addr = &def->target.virtio_pmem.address;
break;
@ -111,7 +111,7 @@ index 06790e0962..038476edd7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@@ -14513,6 +14525,7 @@ virDomainMemoryIsVirtioModel(const virDomainMemoryDef *def)
@@ -14617,6 +14629,7 @@ virDomainMemoryIsVirtioModel(const virDomainMemoryDef *def)
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -119,7 +119,7 @@ index 06790e0962..038476edd7 100644
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
}
@@ -16415,6 +16428,12 @@ virDomainMemoryFindByDefInternal(virDomainDef *def,
@@ -16561,6 +16574,12 @@ virDomainMemoryFindByDefInternal(virDomainDef *def,
continue;
break;
@ -132,7 +132,7 @@ index 06790e0962..038476edd7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -22430,6 +22449,7 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDef *src,
@@ -22705,6 +22724,7 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDef *src,
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -140,7 +140,7 @@ index 06790e0962..038476edd7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -26998,6 +27018,10 @@ virDomainMemorySourceDefFormat(virBuffer *buf,
@@ -27306,6 +27326,10 @@ virDomainMemorySourceDefFormat(virBuffer *buf,
}
break;
@ -151,7 +151,7 @@ index 06790e0962..038476edd7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -27060,6 +27084,11 @@ virDomainMemoryTargetDefFormat(virBuffer *buf,
@@ -27368,6 +27392,11 @@ virDomainMemoryTargetDefFormat(virBuffer *buf,
}
break;
@ -164,10 +164,10 @@ index 06790e0962..038476edd7 100644
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_NONE:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 06e03deafe..4d03521245 100644
index 9a65a12e2c..2e49fa837d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2755,6 +2755,7 @@ typedef enum {
@@ -2787,6 +2787,7 @@ typedef enum {
VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM, /* virtio-pmem memory device */
VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM, /* virtio-mem memory device */
VIR_DOMAIN_MEMORY_MODEL_SGX_EPC, /* SGX enclave page cache */
@ -175,7 +175,7 @@ index 06e03deafe..4d03521245 100644
VIR_DOMAIN_MEMORY_MODEL_LAST
} virDomainMemoryModel;
@@ -2787,6 +2788,9 @@ struct _virDomainMemoryDef {
@@ -2819,6 +2820,9 @@ struct _virDomainMemoryDef {
struct {
virBitmap *nodes; /* source NUMA nodes */
} sgx_epc;
@ -185,7 +185,7 @@ index 06e03deafe..4d03521245 100644
} source;
union {
@@ -2812,6 +2816,9 @@ struct _virDomainMemoryDef {
@@ -2844,6 +2848,9 @@ struct _virDomainMemoryDef {
} virtio_mem;
struct {
} sgx_epc;
@ -196,10 +196,10 @@ index 06e03deafe..4d03521245 100644
virDomainDeviceInfo info;
diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c
index 38e731348d..0181d21f0e 100644
index cbaae75c02..2c21e06910 100644
--- a/src/conf/domain_postparse.c
+++ b/src/conf/domain_postparse.c
@@ -632,6 +632,7 @@ virDomainMemoryDefPostParse(virDomainMemoryDef *mem,
@@ -616,6 +616,7 @@ virDomainMemoryDefPostParse(virDomainMemoryDef *mem,
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
@ -208,10 +208,10 @@ index 38e731348d..0181d21f0e 100644
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index f243b119a4..34906ddc84 100644
index 1cd407bedc..9ddb4e319c 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2525,6 +2525,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
@@ -2564,6 +2564,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
}
break;
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -219,7 +219,7 @@ index f243b119a4..34906ddc84 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -2571,6 +2572,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
@@ -2610,6 +2611,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
switch (other->model) {
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -227,7 +227,7 @@ index f243b119a4..34906ddc84 100644
case VIR_DOMAIN_MEMORY_MODEL_LAST:
continue;
break;
@@ -2751,6 +2753,19 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
@@ -2790,6 +2792,19 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
}
break;
@ -248,10 +248,10 @@ index f243b119a4..34906ddc84 100644
case VIR_DOMAIN_MEMORY_MODEL_LAST:
default:
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 839a144da8..123e4057b7 100644
index ea7c177a68..ec0bca1a84 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -7561,6 +7561,7 @@
@@ -7664,6 +7664,7 @@
<value>virtio-pmem</value>
<value>virtio-mem</value>
<value>sgx-epc</value>
@ -259,7 +259,7 @@ index 839a144da8..123e4057b7 100644
</choice>
</attribute>
<optional>
@@ -7692,6 +7693,11 @@
@@ -7795,6 +7796,11 @@
</attribute>
</element>
</optional>
@ -272,4 +272,4 @@ index 839a144da8..123e4057b7 100644
</element>
</define>
--
2.54.0
2.55.0

View File

@ -1,62 +0,0 @@
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

@ -1,51 +0,0 @@
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

@ -1,96 +0,0 @@
From dad5203ccef4ef9321034a4234ea82af6d945af3 Mon Sep 17 00:00:00 2001
Message-ID: <dad5203ccef4ef9321034a4234ea82af6d945af3.1772544849.git.phrdina@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
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-227
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 b8c180e72d..4e12ebf712 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;
@@ -9653,6 +9666,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
@@ -10346,6 +10362,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

@ -1,119 +0,0 @@
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
Abstract the places where we create URLs into one place. This is just
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-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 9f965811b1..29735e359f 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -582,7 +582,37 @@ esxCapsInit(esxPrivate *priv)
return NULL;
}
+static char *
+esxCreateURL(const char *transport,
+ const char *server,
+ int port,
+ const char *path)
+{
+ char *url;
+ url = g_strdup_printf("%s://%s:%d%s",
+ transport,
+ server,
+ port,
+ path);
+ return url;
+}
+
+/*
+ * Same as above, but add it to a buffer because the calling code will
+ * append query strings etc.
+ */
+static void
+esxCreateURLBuffer(virBuffer *buffer,
+ const char *transport,
+ const char *server,
+ int port,
+ const char *path)
+{
+ g_autofree char *url = esxCreateURL(transport, server, port, path);
+
+ virBufferAdd(buffer, url, -1);
+}
static int
esxConnectToHost(esxPrivate *priv,
@@ -619,8 +649,8 @@ esxConnectToHost(esxPrivate *priv,
conn->uri->server)))
goto cleanup;
- url = g_strdup_printf("%s://%s:%d/sdk", priv->parsedUri->transport,
- conn->uri->server, conn->uri->port);
+ url = esxCreateURL(priv->parsedUri->transport,
+ conn->uri->server, conn->uri->port, "/sdk");
if (esxVI_Context_Alloc(&priv->host) < 0 ||
esxVI_Context_Connect(priv->host, url, ipAddress, username, password,
@@ -706,8 +736,8 @@ esxConnectToVCenter(esxPrivate *priv,
if (!(password = virAuthGetPassword(conn, auth, "esx", username, hostname)))
return -1;
- url = g_strdup_printf("%s://%s:%d/sdk", priv->parsedUri->transport, hostname,
- conn->uri->port);
+ url = esxCreateURL(priv->parsedUri->transport, hostname,
+ conn->uri->port, "/sdk");
if (esxVI_Context_Alloc(&priv->vCenter) < 0 ||
esxVI_Context_Connect(priv->vCenter, url, ipAddress, username,
@@ -2357,8 +2387,9 @@ esxDomainScreenshot(virDomainPtr domain, virStreamPtr stream,
}
/* Build URL */
- virBufferAsprintf(&buffer, "%s://%s:%d/screen?id=", priv->parsedUri->transport,
- domain->conn->uri->server, domain->conn->uri->port);
+ esxCreateURLBuffer(&buffer, priv->parsedUri->transport,
+ domain->conn->uri->server, domain->conn->uri->port,
+ "/screen?id=");
virBufferURIEncodeString(&buffer, virtualMachine->obj->value);
url = virBufferContentAndReset(&buffer);
@@ -2563,8 +2594,9 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
goto cleanup;
}
- virBufferAsprintf(&buffer, "%s://%s:%d/folder/", priv->parsedUri->transport,
- domain->conn->uri->server, domain->conn->uri->port);
+ esxCreateURLBuffer(&buffer, priv->parsedUri->transport,
+ domain->conn->uri->server, domain->conn->uri->port,
+ "/folder/");
virBufferURIEncodeString(&buffer, directoryAndFileName);
virBufferAddLit(&buffer, "?dcPath=");
virBufferURIEncodeString(&buffer, priv->primary->datacenterPath);
@@ -2987,8 +3019,9 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
goto cleanup;
}
- virBufferAsprintf(&buffer, "%s://%s:%d/folder/", priv->parsedUri->transport,
- conn->uri->server, conn->uri->port);
+ esxCreateURLBuffer(&buffer, priv->parsedUri->transport,
+ conn->uri->server, conn->uri->port,
+ "/folder/");
if (directoryName) {
virBufferURIEncodeString(&buffer, directoryName);
--
2.52.0

View File

@ -1,43 +0,0 @@
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
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When connecting to a VMWare server, the hostname from URI is
resolved using esxUtil_ResolveHostname() which in turn calls
getaddrinfo(). But in the hints argument, we restrict the return
address to be IPv4 (AF_INET) which obviously fails if the address
to resolve is an IPv6 address. Set the hint to AF_UNSPEC which
allows both IPv4 and IPv6. While at it, also allow IPv4 addresses
mapped in IPv6 by setting AI_V4MAPPED flag.
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)
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 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)
int errcode;
g_autofree char *address = NULL;
- hints.ai_flags = AI_ADDRCONFIG;
- hints.ai_family = AF_INET;
+ hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
+ hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
--
2.52.0

View File

@ -1,29 +0,0 @@
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-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 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)
long responseCode = 0;
const char *redirectUrl = NULL;
+ VIR_DEBUG("URL: %s", url);
+
errorCode = curl_easy_perform(curl->handle);
if (errorCode != CURLE_OK) {
--
2.52.0

View File

@ -1,57 +0,0 @@
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
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since libvirt has existing support for creating URIs, use that rather
than home-rolling our own code without any escaping.
As a side-effect this ensures that URLs containing IPv6 addresses are
escaped correctly, for example as below (note square brackets):
https://[1234:56:0:789a:bcde:72ff:fe0a:7baa]:443/sdk
Fixes: https://issues.redhat.com/browse/RHEL-138300
Updates: commit 845210011a9ffd9d17e30c51cbc81ba67c5d3166
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-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 29735e359f..40b7f793cd 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -588,14 +588,14 @@ esxCreateURL(const char *transport,
int port,
const char *path)
{
- char *url;
+ virURI uri = {
+ .scheme = (char*)transport,
+ .server = (char*)server,
+ .port = port,
+ .path = (char*)path,
+ };
- url = g_strdup_printf("%s://%s:%d%s",
- transport,
- server,
- port,
- path);
- return url;
+ return virURIFormat(&uri);
}
/*
--
2.52.0

View File

@ -1,60 +0,0 @@
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
While discouraged by a KB article to use special characters in
inventory object names [1], ESX won't stop you. And thus users
can end up with a datastore named "datastore2+", for instance.
The datastore name (and datacenter path) are important when
fetching/uploading a .vmx file (used in APIs like
virDomainGetXMLDesc() or virDomainDefineXML()). And while we do
URI encode both (dcPath and dsName), encoding them once is not
enough. Cole Robinson discovered [2] that they need to be
URI-encoded twice. Use newly introduced
esxUtil_EscapeInventoryObject() helper to encode them twice.
1: https://knowledge.broadcom.com/external/article/386368/vcenter-inventory-object-name-with-speci.html
2: https://issues.redhat.com/browse/RHEL-133729#comment-28604072
Resolves: https://issues.redhat.com/browse/RHEL-134127
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-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 40b7f793cd..010c62b8e8 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2599,9 +2599,9 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
"/folder/");
virBufferURIEncodeString(&buffer, directoryAndFileName);
virBufferAddLit(&buffer, "?dcPath=");
- virBufferURIEncodeString(&buffer, priv->primary->datacenterPath);
+ esxUtil_EscapeInventoryObject(&buffer, priv->primary->datacenterPath);
virBufferAddLit(&buffer, "&dsName=");
- virBufferURIEncodeString(&buffer, datastoreName);
+ esxUtil_EscapeInventoryObject(&buffer, datastoreName);
url = virBufferContentAndReset(&buffer);
@@ -3035,9 +3035,9 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
virBufferURIEncodeString(&buffer, escapedName);
virBufferAddLit(&buffer, ".vmx?dcPath=");
- virBufferURIEncodeString(&buffer, priv->primary->datacenterPath);
+ esxUtil_EscapeInventoryObject(&buffer, priv->primary->datacenterPath);
virBufferAddLit(&buffer, "&dsName=");
- virBufferURIEncodeString(&buffer, datastoreName);
+ esxUtil_EscapeInventoryObject(&buffer, datastoreName);
url = virBufferContentAndReset(&buffer);
--
2.52.0

View File

@ -1,76 +0,0 @@
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()
The aim of this helper function is to URI-encode given string
twice. There's a bug (fixed in next commit) in which we're unable
to fetch .vmx file for a domain if corresponding datastore
contains some special characters (like +). Cole Robinson
discovered that encoding datastore twice enables libvirt to work
around the issue [2]. Well, this function does exactly that.
It was tested with the following inputs and all worked
flawlessly: "datastore", "datastore2", "datastore2+",
"datastore3+-@", "data store2+".
1: https://issues.redhat.com/browse/RHEL-134127
2: https://issues.redhat.com/browse/RHEL-133729#comment-28604072
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-140196
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/esx/esx_util.c | 18 ++++++++++++++++++
src/esx/esx_util.h | 3 +++
2 files changed, 21 insertions(+)
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
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)
return virBufferContentAndReset(&buffer);
}
+
+
+/* esxUtil_EscapeInventoryObject:
+ * @buf: the buffer to append to
+ * @string: the string argument which will be URI-encoded
+ *
+ * URI-encode given @string TWICE and append the result to the @buf. This is
+ * to be used with inventory objects (like 'dcPath' and 'dsName') to work
+ * around a VMware bug in which once round of URI-encoding is not enough.
+ */
+void
+esxUtil_EscapeInventoryObject(virBuffer *buf, const char *string)
+{
+ g_autoptr(GString) escaped = g_string_new(NULL);
+
+ g_string_append_uri_escaped(escaped, string, NULL, false);
+ virBufferURIEncodeString(buf, escaped->str);
+}
diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h
index 58bc44e744..29f01e0c15 100644
--- a/src/esx/esx_util.h
+++ b/src/esx/esx_util.h
@@ -22,6 +22,7 @@
#pragma once
#include "internal.h"
+#include "virbuffer.h"
#include "viruri.h"
#define ESX_VI_CHECK_ARG_LIST(val) \
@@ -67,3 +68,5 @@ void esxUtil_ReplaceSpecialWindowsPathChars(char *string);
char *esxUtil_EscapeDatastoreItem(const char *string);
char *esxUtil_EscapeForXml(const char *string);
+
+void esxUtil_EscapeInventoryObject(virBuffer *buf, const char *string);
--
2.52.0

View File

@ -1,47 +0,0 @@
From f753d55edab43dae78f9ef5dc13ca53f626e09fe Mon Sep 17 00:00:00 2001
Message-ID: <f753d55edab43dae78f9ef5dc13ca53f626e09fe.1774625709.git.phrdina@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
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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

@ -1,100 +0,0 @@
From c57b38c1bf7771489142198c7cf6fdc6ac1b15e1 Mon Sep 17 00:00:00 2001
Message-ID: <c57b38c1bf7771489142198c7cf6fdc6ac1b15e1.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 11:57:43 +0100
Subject: [PATCH] hypervisor: Fix virHostdevNeedsVFIO detection
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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 da90fd1446..e8c4116fa0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32936,6 +32936,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 91b8976ea5..36e69ad6fd 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4726,6 +4726,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 386e757d81..ea1e2d8586 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -814,6 +814,7 @@ virDomainQemuMonitorEventStateRegisterID;
virHostdevIsMdevDevice;
virHostdevIsPCIDevice;
virHostdevIsPCIDeviceWithIOMMUFD;
+virHostdevIsPCIDeviceWithoutIOMMUFD;
virHostdevIsSCSIDevice;
--
2.53.0

View File

@ -1,38 +0,0 @@
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,5 +1,5 @@
From d1f3b404a08e097e6ddac10452b4ed142e35a89b Mon Sep 17 00:00:00 2001
Message-ID: <d1f3b404a08e097e6ddac10452b4ed142e35a89b.1779098642.git.phrdina@redhat.com>
From 966bfc59fb5c3ca6ef01bf70a055b55ff2b8292e Mon Sep 17 00:00:00 2001
Message-ID: <966bfc59fb5c3ca6ef01bf70a055b55ff2b8292e.1786096789.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Tue, 25 Nov 2025 11:17:02 -0800
Subject: [PATCH] qemu: Add cgroup, namespace, and seclabel setup for EGM
@ -17,7 +17,7 @@ Implement proper isolation and access control for EGM memory devices:
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Resolves: https://redhat.atlassian.net/browse/VOYAGER-13
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1109
---
src/qemu/qemu_cgroup.c | 10 ++++++++++
src/qemu/qemu_namespace.c | 3 +++
@ -85,10 +85,10 @@ index 6267e4f737..2a6a4b979c 100644
network inet dgram,
network inet6 stream,
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index e53486ee0c..4d8b1e20d3 100644
index a66382fbac..bae9f9defc 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -631,6 +631,8 @@ AppArmorSetMemoryLabel(virSecurityManager *mgr,
@@ -632,6 +632,8 @@ AppArmorSetMemoryLabel(virSecurityManager *mgr,
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -98,10 +98,10 @@ index e53486ee0c..4d8b1e20d3 100644
break;
}
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index b891f6f121..bff0e03f35 100644
index e7cffa8e59..7cd153ceb6 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1909,6 +1909,9 @@ virSecurityDACRestoreMemoryLabel(virSecurityManager *mgr,
@@ -1908,6 +1908,9 @@ virSecurityDACRestoreMemoryLabel(virSecurityManager *mgr,
* don't need to restore anything. */
break;
@ -111,7 +111,7 @@ index b891f6f121..bff0e03f35 100644
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
@@ -2140,6 +2143,11 @@ virSecurityDACSetMemoryLabel(virSecurityManager *mgr,
@@ -2145,6 +2148,11 @@ virSecurityDACSetMemoryLabel(virSecurityManager *mgr,
return -1;
break;
@ -124,10 +124,10 @@ index b891f6f121..bff0e03f35 100644
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 2b801aecd5..fd7d5ff703 100644
index 423dcd0bd9..b13dfea066 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1666,6 +1666,9 @@ virSecuritySELinuxSetMemoryLabel(virSecurityManager *mgr,
@@ -1663,6 +1663,9 @@ virSecuritySELinuxSetMemoryLabel(virSecurityManager *mgr,
seclabel->imagelabel, true) < 0)
return -1;
break;
@ -137,7 +137,7 @@ index 2b801aecd5..fd7d5ff703 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
@@ -1709,6 +1712,9 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManager *mgr,
@@ -1706,6 +1709,9 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManager *mgr,
if (virSecuritySELinuxRestoreFileLabel(mgr, DEV_SGX_PROVISION, true, false) < 0)
ret = -1;
return ret;
@ -148,10 +148,10 @@ index 2b801aecd5..fd7d5ff703 100644
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index af95a64c42..0a62a30da3 100644
index 2eae4d7f3f..eb08d92d2d 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1196,6 +1196,10 @@ get_files(vahControl * ctl)
@@ -1217,6 +1217,10 @@ get_files(vahControl * ctl)
return -1;
}
break;
@ -163,4 +163,4 @@ index af95a64c42..0a62a30da3 100644
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
--
2.54.0
2.55.0

View File

@ -1,5 +1,5 @@
From 9965f1b7b0fb1810fe32498f7892aa549a754d19 Mon Sep 17 00:00:00 2001
Message-ID: <9965f1b7b0fb1810fe32498f7892aa549a754d19.1779098642.git.phrdina@redhat.com>
From e9835e4f6ed51080ec16c180e9323b7689a45b7c Mon Sep 17 00:00:00 2001
Message-ID: <e9835e4f6ed51080ec16c180e9323b7689a45b7c.1786096789.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Tue, 25 Nov 2025 11:17:03 -0800
Subject: [PATCH] qemu: Add qemu CLI support for EGM
@ -17,7 +17,7 @@ Add qemu CLI support for EGM memory device model:
Signed-off-by: Ian May <ianm@nvidia.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Resolves: https://redhat.atlassian.net/browse/VOYAGER-13
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1109
---
src/qemu/qemu_alias.c | 7 +-
src/qemu/qemu_capabilities.c | 2 +
@ -59,39 +59,39 @@ index 400ce73283..719224e1ba 100644
case VIR_DOMAIN_MEMORY_MODEL_LAST:
default:
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index ed6aa86da2..010933bc4e 100644
index c60ca02d97..13572adbef 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -760,6 +760,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
/* 490 */
"iommufd", /* QEMU_CAPS_OBJECT_IOMMUFD */
@@ -770,6 +770,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"arm-smmuv3", /* QEMU_CAPS_DEVICE_ARM_SMMUV3 */
"arm-smmuv3.smmu_per_bus", /* QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS */
"arm-smmuv3.accel", /* QEMU_CAPS_ARM_SMMUV3_ACCEL */
+ "acpi-egm-memory", /* QEMU_CAPS_DEVICE_ACPI_EGM_MEMORY */
);
@@ -1468,6 +1469,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "tpm-passthrough", QEMU_CAPS_DEVICE_TPM_PASSTHROUGH },
{ "acpi-generic-initiator", QEMU_CAPS_ACPI_GENERIC_INITIATOR },
{ "iommufd", QEMU_CAPS_OBJECT_IOMMUFD },
@@ -1484,6 +1485,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "uefi-vars-x64", QEMU_CAPS_DEVICE_UEFI_VARS },
{ "uefi-vars-sysbus", QEMU_CAPS_DEVICE_UEFI_VARS },
{ "arm-smmuv3", QEMU_CAPS_DEVICE_ARM_SMMUV3 },
+ { "acpi-egm-memory", QEMU_CAPS_DEVICE_ACPI_EGM_MEMORY },
};
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index f7c8680f94..85615b4524 100644
index 28085144a2..59c2583821 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -734,6 +734,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
/* 490 */
QEMU_CAPS_OBJECT_IOMMUFD, /* -object iommufd */
@@ -744,6 +744,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_DEVICE_ARM_SMMUV3, /* -device arm-smmuv3 */
QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS, /* arm-smmuv3.smmu_per_bus */
QEMU_CAPS_ARM_SMMUV3_ACCEL, /* arm-smmuv3.accel */
+ QEMU_CAPS_DEVICE_ACPI_EGM_MEMORY, /* For using extended GPU memory */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a76f504e6f..63fd9885b7 100644
index 9b272c8314..d5bf667aa3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -135,6 +135,21 @@ VIR_ENUM_IMPL(qemuACPITableSIG,
@ -116,7 +116,7 @@ index a76f504e6f..63fd9885b7 100644
const char *
qemuAudioDriverTypeToString(virDomainAudioType type)
@@ -992,6 +1007,7 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device,
@@ -953,6 +968,7 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device,
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -124,7 +124,7 @@ index a76f504e6f..63fd9885b7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -3166,6 +3182,7 @@ qemuBuildMemoryGetPagesize(virQEMUDriverConfig *cfg,
@@ -3125,6 +3141,7 @@ qemuBuildMemoryGetPagesize(virQEMUDriverConfig *cfg,
nvdimmPath = mem->source.virtio_pmem.path;
break;
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -132,7 +132,7 @@ index a76f504e6f..63fd9885b7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -3366,6 +3383,9 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
@@ -3325,6 +3342,9 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
nvdimmPath = mem->source.virtio_pmem.path;
break;
@ -142,7 +142,7 @@ index a76f504e6f..63fd9885b7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -3577,12 +3597,17 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd,
@@ -3542,12 +3562,17 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd,
virDomainMemoryDef *mem,
virDomainDef *def,
virQEMUDriverConfig *cfg,
@ -161,7 +161,7 @@ index a76f504e6f..63fd9885b7 100644
if (!mem->info.alias) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -3592,19 +3617,65 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd,
@@ -3557,19 +3582,65 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd,
alias = g_strdup_printf("mem%s", mem->info.alias);
@ -237,7 +237,7 @@ index a76f504e6f..63fd9885b7 100644
return 0;
}
@@ -3675,6 +3746,7 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg,
@@ -3640,6 +3711,7 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg,
dynamicMemslots = mem->target.virtio_mem.dynamicMemslots;
break;
@ -245,7 +245,7 @@ index a76f504e6f..63fd9885b7 100644
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
@@ -7193,6 +7265,7 @@ qemuAppendDomainMemoryMachineParams(virBuffer *buf,
@@ -7170,6 +7242,7 @@ qemuAppendDomainMemoryMachineParams(virBuffer *buf,
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
@ -253,7 +253,7 @@ index a76f504e6f..63fd9885b7 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -7910,6 +7983,8 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
@@ -7887,6 +7960,8 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
size_t ncells = virDomainNumaGetNodeCount(def->numa);
ssize_t masterInitiator = -1;
int rc;
@ -262,7 +262,7 @@ index a76f504e6f..63fd9885b7 100644
if (!virDomainNumatuneNodesetIsAvailable(def->numa, priv->autoNodeset))
goto cleanup;
@@ -7924,6 +7999,37 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
@@ -7901,6 +7976,37 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
hmat = true;
}
@ -300,7 +300,7 @@ index a76f504e6f..63fd9885b7 100644
nodeBackends = g_new0(virJSONValue *, ncells);
nodemask = g_new0(virBitmap *, ncells);
@@ -7959,8 +8065,18 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
@@ -7936,8 +8042,18 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
for (i = 0; i < ncells; i++) {
ssize_t initiator = virDomainNumaGetNodeInitiator(def->numa, i);
unsigned long long memSize = virDomainNumaGetNodeMemorySize(def->numa, i);
@ -320,7 +320,7 @@ index a76f504e6f..63fd9885b7 100644
g_autoptr(virJSONValue) tcProps = NULL;
if (qemuBuildThreadContextProps(&tcProps, &nodeBackends[i],
@@ -7990,7 +8106,15 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
@@ -7967,7 +8083,15 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
if (memSize > 0) {
if (needBackend) {
@ -337,7 +337,7 @@ index a76f504e6f..63fd9885b7 100644
} else {
virBufferAsprintf(&buf, ",mem=%llu", memSize / 1024);
}
@@ -8054,7 +8178,10 @@ qemuBuildMemoryDeviceCommandLine(virCommand *cmd,
@@ -8031,7 +8155,10 @@ qemuBuildMemoryDeviceCommandLine(virCommand *cmd,
for (i = 0; i < def->nmems; i++) {
g_autoptr(virJSONValue) props = NULL;
@ -349,7 +349,7 @@ index a76f504e6f..63fd9885b7 100644
return -1;
switch (def->mems[i]->model) {
@@ -8074,6 +8201,9 @@ qemuBuildMemoryDeviceCommandLine(virCommand *cmd,
@@ -8051,6 +8178,9 @@ qemuBuildMemoryDeviceCommandLine(virCommand *cmd,
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
break;
@ -360,10 +360,10 @@ index a76f504e6f..63fd9885b7 100644
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 495cbd4f7d..c5e3d09360 100644
index e1b805d906..62aa602fed 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7266,6 +7266,7 @@ qemuDomainUpdateMemoryDeviceInfo(virDomainObj *vm,
@@ -7277,6 +7277,7 @@ qemuDomainUpdateMemoryDeviceInfo(virDomainObj *vm,
break;
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -371,7 +371,7 @@ index 495cbd4f7d..c5e3d09360 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -7500,7 +7501,8 @@ qemuDomainAlignMemorySizes(virDomainDef *def)
@@ -7511,7 +7512,8 @@ qemuDomainAlignMemorySizes(virDomainDef *def)
def->mems[i]->size = VIR_ROUND_UP(def->mems[i]->size, align);
}
@ -381,7 +381,7 @@ index 495cbd4f7d..c5e3d09360 100644
if (def->mems[i]->size > maxmemkb) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -7988,6 +7990,12 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem,
@@ -7999,6 +8001,12 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem,
virDomainMemoryModelTypeToString(mem->model));
return -1;
@ -394,7 +394,7 @@ index 495cbd4f7d..c5e3d09360 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
return -1;
@@ -8046,6 +8054,7 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
@@ -8057,6 +8065,7 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -402,7 +402,7 @@ index 495cbd4f7d..c5e3d09360 100644
case VIR_DOMAIN_MEMORY_MODEL_LAST:
case VIR_DOMAIN_MEMORY_MODEL_NONE:
break;
@@ -8093,6 +8102,8 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
@@ -8104,6 +8113,8 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
/* sgx epc memory does not support hotplug, skip this check */
@ -412,10 +412,10 @@ index 495cbd4f7d..c5e3d09360 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
break;
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 7233df888c..97e533bf9a 100644
index a8292a9782..408be72fac 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -3124,6 +3124,7 @@ qemuDomainAssignMemoryDeviceSlot(virDomainObj *vm,
@@ -3120,6 +3120,7 @@ qemuDomainAssignMemoryDeviceSlot(virDomainObj *vm,
return qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev);
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -423,7 +423,7 @@ index 7233df888c..97e533bf9a 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -3151,6 +3152,7 @@ qemuDomainReleaseMemoryDeviceSlot(virDomainObj *vm,
@@ -3147,6 +3148,7 @@ qemuDomainReleaseMemoryDeviceSlot(virDomainObj *vm,
break;
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -431,7 +431,7 @@ index 7233df888c..97e533bf9a 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
@@ -3185,6 +3187,7 @@ qemuDomainAssignMemorySlots(virDomainDef *def)
@@ -3181,6 +3183,7 @@ qemuDomainAssignMemorySlots(virDomainDef *def)
/* handled in qemuDomainAssignPCIAddresses() */
break;
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -440,10 +440,10 @@ index 7233df888c..97e533bf9a 100644
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5e63614b4a..247c98d84e 100644
index 8ec9e1f9c4..b395279ea6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6712,6 +6712,7 @@ qemuDomainAttachMemoryConfig(virDomainDef *vmdef,
@@ -6869,6 +6869,7 @@ qemuDomainAttachMemoryConfig(virDomainDef *vmdef,
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -452,10 +452,10 @@ index 5e63614b4a..247c98d84e 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_LAST:
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 8944062aa4..de47702bc5 100644
index 5be567b510..0f4a51afad 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -7417,6 +7417,7 @@ qemuDomainChangeMemoryLiveValidateChange(const virDomainMemoryDef *oldDef,
@@ -7503,6 +7503,7 @@ qemuDomainChangeMemoryLiveValidateChange(const virDomainMemoryDef *oldDef,
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -464,10 +464,10 @@ index 8944062aa4..de47702bc5 100644
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("cannot modify memory of model '%1$s'"),
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 45f690d9e2..2bf9bb885e 100644
index 28f7d93834..55736a3607 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -7285,6 +7285,7 @@ qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitor *mon,
@@ -7332,6 +7332,7 @@ qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitor *mon,
switch ((virDomainMemoryModel) model) {
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
@ -476,10 +476,10 @@ index 45f690d9e2..2bf9bb885e 100644
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
/* While 'id' attribute is marked as optional in QEMU's QAPI
diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c
index 840d6a1174..c74824322a 100644
index 9eda2f6b99..3f25b34eb2 100644
--- a/src/qemu/qemu_postparse.c
+++ b/src/qemu/qemu_postparse.c
@@ -1839,6 +1839,7 @@ qemuDomainDefNumaAutoAdd(virDomainDef *def,
@@ -1927,6 +1927,7 @@ qemuDomainDefNumaAutoAdd(virDomainDef *def,
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -488,10 +488,10 @@ index 840d6a1174..c74824322a 100644
break;
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 10a4a70f1c..8132f13791 100644
index 4c94ff3c91..a111812df6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4158,6 +4158,7 @@ qemuProcessDomainMemoryDefNeedHugepagesPath(const virDomainMemoryDef *mem,
@@ -4167,6 +4167,7 @@ qemuProcessDomainMemoryDefNeedHugepagesPath(const virDomainMemoryDef *mem,
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
pagesize = mem->source.virtio_mem.pagesize;
break;
@ -499,7 +499,7 @@ index 10a4a70f1c..8132f13791 100644
case VIR_DOMAIN_MEMORY_MODEL_NONE:
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
@@ -4247,6 +4248,7 @@ qemuProcessNeedMemoryBackingPath(virDomainDef *def,
@@ -4256,6 +4257,7 @@ qemuProcessNeedMemoryBackingPath(virDomainDef *def,
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@ -508,10 +508,10 @@ index 10a4a70f1c..8132f13791 100644
/* Backed by user provided path. Not stored in memory
* backing dir anyway. */
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index c39d8c869f..e03da3e27e 100644
index 1093eb8363..2f64e0b77b 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -5892,6 +5892,12 @@ qemuValidateDomainDeviceDefMemory(const virDomainMemoryDef *mem,
@@ -6039,6 +6039,12 @@ qemuValidateDomainDeviceDefMemory(const virDomainMemoryDef *mem,
break;
@ -525,4 +525,4 @@ index c39d8c869f..e03da3e27e 100644
case VIR_DOMAIN_MEMORY_MODEL_LAST:
break;
--
2.54.0
2.55.0

View File

@ -1,118 +1,104 @@
From 8a7be5ca6f76e60a5a52eaf88e08d276d255ef47 Mon Sep 17 00:00:00 2001
Message-ID: <8a7be5ca6f76e60a5a52eaf88e08d276d255ef47.1771499562.git.phrdina@redhat.com>
From e99dacdae8ffa42463b7dc06eab8043d4ed2d829 Mon Sep 17 00:00:00 2001
Message-ID: <e99dacdae8ffa42463b7dc06eab8043d4ed2d829.1786096788.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 30 Jan 2026 10:37:06 -0800
Date: Wed, 5 Aug 2026 15:13:00 -0700
Subject: [PATCH] qemu: Add support for HW-accelerated nested SMMUv3
From: Nathan Chen <nathanc@nvidia.com>
Add support for enabling HW-accelerated nested SMMUv3
via <accel> attribute and its additional attributes for
ATS, SSID, RIL, and OAS configuration. Support element
for specifying PCI hostdev PASID capability offset.
Add support for enabling HW-accelerated nested SMMUv3 via <accel>
attribute and its additional attributes for ATS, SSID, RIL, and OAS
configuration.
Validate the domain iommu accel attribute in qemu_validate.c when
QEMU lacks this capability. Checking accel is sufficient because ats,
ril, ssidsize, and oas were introduced in the same QEMU release, and
it only makes sense to backport accel, ats, ril, ssidsize, and oas
all together.
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
(cherry picked from commit d4605d8279d73bf8d2b8031d49f453529738ef34)
Resolves: https://issues.redhat.com/browse/VOYAGER-4
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1043
---
docs/formatdomain.rst | 36 +++++++++++
src/conf/domain_conf.c | 101 +++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 6 ++
src/conf/domain_validate.c | 36 ++++++++++-
src/conf/schemas/domaincommon.rng | 32 ++++++++++
src/qemu/qemu_command.c | 23 +++++++
src/util/virpci.h | 4 ++
7 files changed, 233 insertions(+), 5 deletions(-)
docs/formatdomain.rst | 38 +++++++++++++++
src/conf/domain_conf.c | 79 +++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 5 ++
src/conf/domain_validate.c | 27 ++++++++++-
src/conf/schemas/domaincommon.rng | 25 ++++++++++
src/qemu/qemu_command.c | 15 ++++++
src/qemu/qemu_validate.c | 12 +++++
7 files changed, 200 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 31232deb3c..9ce647eba7 100644
index a861f9f177..1e8c81c3a5 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -4917,6 +4917,13 @@ or:
device; if PCI ROM loading is disabled through this attribute, attempts to
tweak the loading process further using the ``bar`` or ``file`` attributes
will be rejected. :since:`Since 4.3.0 (QEMU and KVM only)`.
+``vpasidCapOffset``
+ The ``vpasidCapOffset`` element is used to change the offset at which a
+ PASID PCIe extended capability is placed in a vfio-pci device's PCIe
+ extended configuration space. If not specified or set to 0, the capability
+ is placed at the end of the extended configuration space when PASID is
+ supported. The offset must be 4-byte aligned and within the PCIe extended
+ configuration space.
``address``
The ``address`` element for USB devices has a ``bus`` and ``device``
attribute to specify the USB bus and device number the device appears at on
@@ -9307,6 +9314,35 @@ Example:
@@ -9426,6 +9426,44 @@ Examples:
The ``pciBus`` attribute notes the index of the controller that an
IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only)
+ ``accel``
+ The ``accel`` attribute with possible values ``on`` and ``off`` can be used
+ to enable hardware acceleration support for smmuv3Dev IOMMU devices.
+ (QEMU/KVM and ``smmuv3`` model only)
+ The ``accel`` attribute with possible values ``on`` and ``off`` can
+ be used to enable hardware acceleration support for smmuv3 IOMMU
+ devices.
+ :since:`Since 12.7.0` (QEMU/KVM and ``smmuv3`` model only)
+
+ ``ats``
+ The ``ats`` attribute with possible values ``on`` and ``off`` can be used
+ to enable reporting Address Translation Services capability to the guest
+ for smmuv3Dev IOMMU devices with ``accel`` set to ``on``, if the host
+ SMMUv3 supports ATS and the associated passthrough device supports ATS.
+ (QEMU/KVM and ``smmuv3`` model only)
+ The ``ats`` attribute with possible values ``on`` and ``off`` can be
+ used to enable reporting Address Translation Services capability to
+ the guest for smmuv3 IOMMU devices with ``accel`` set to ``on``, if
+ the host SMMUv3 supports ATS and the associated passthrough device
+ supports ATS. If ``accel`` is enabled and ``ats`` is not configured,
+ the hypervisor default value is used.
+ :since:`Since 12.7.0` (QEMU/KVM and ``smmuv3`` model only)
+
+ ``ril``
+ The ``ril`` attribute with possible values ``on`` and ``off`` can be used
+ to report whether Range Invalidation for smmuv3Dev IOMMU devices with
+ ``accel`` set to ``on`` is compatible with host SMMUv3 support.
+ (QEMU/KVM and ``smmuv3`` model only)
+ The ``ril`` attribute with possible values ``on`` and ``off`` can be
+ used to report whether Range Invalidation for IOMMU devices with
+ ``accel`` set to ``on`` is compatible with host SMMUv3 support. If
+ ``accel`` is enabled and ``ril`` is not configured, the hypervisor
+ default value is used.
+ :since:`Since 12.7.0` (QEMU/KVM and ``smmuv3`` model only)
+
+ ``ssidSize``
+ The ``ssidSize`` attribute sets the number of bits used to represent
+ SubstreamIDs. A value of N allows SSIDs in the range [0 .. 2^N - 1].
+ The valid range is 0-20, and a value greater than 0 is required for
+ enabling PASID support, as doing so advertises PASID capability to
+ the vIOMMU. (QEMU/KVM and ``smmuv3`` model only)
+ ``ssidsize``
+ The ``ssidsize`` attribute sets the number of bits used to
+ represent SubstreamIDs. A value of N allows SSIDs in the range
+ [0 .. 2^N - 1]. The valid range is 0-20, and a value greater than 0
+ is required for enabling PASID support, as doing so advertises PASID
+ capability to the vIOMMU. If ``accel`` is enabled and ``ssidsize`` is
+ not configured, the hypervisor default value is used.
+ :since:`Since 12.7.0` (QEMU/KVM and ``smmuv3`` model only)
+
+ ``oas``
+ The ``oas`` attribute sets the output address size in units of bits.
+ (QEMU/KVM and ``smmuv3`` model only)
+ If ``accel`` is enabled and ``oas`` is not configured, the hypervisor
+ default value is used.
+ :since:`Since 12.7.0` (QEMU/KVM and ``smmuv3`` model only)
+
The ``virtio`` IOMMU devices can further have ``address`` element as described
in `Device addresses`_ (address has to by type of ``pci``).
In case of ``virtio`` IOMMU device, the ``driver`` element can optionally
contain ``granule`` subelement that allows to choose which granule will be
used by default. It is useful when running guests with different page size
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cb047e5a3e..8ea3206485 100644
index 94cfb27c1d..db44ba9a72 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13777,6 +13777,7 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt,
virDomainHostdevDef *def;
VIR_XPATH_NODE_AUTORESTORE(ctxt)
unsigned int type;
+ int rc;
@@ -2863,6 +2863,10 @@ virDomainIOMMUDefNew(void)
ctxt->node = node;
iommu->pci_bus = -1;
@@ -13830,8 +13831,16 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt,
def->shareable = true;
break;
+ iommu->ssid_size = -1;
+
+ iommu->oas = -1;
+
return g_steal_pointer(&iommu);
}
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ rc = virXPathUIntBase("string(./vpasidCapOffset)", ctxt,
+ 0, &def->vpasidCapOffset);
+ if (rc == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Invalid format for vpasidCapOffset"));
+ goto error;
+ }
+ break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
@@ -14613,6 +14622,26 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt,
if (virXMLPropInt(driver, "pciBus", 10, VIR_XML_PROP_NONE,
@@ -14746,6 +14750,26 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt,
&iommu->pci_bus, -1) < 0)
return NULL;
+
+ if (virXMLPropTristateSwitch(driver, "accel", VIR_XML_PROP_NONE,
+ &iommu->accel) < 0)
+ return NULL;
@ -125,47 +111,30 @@ index cb047e5a3e..8ea3206485 100644
+ &iommu->ril) < 0)
+ return NULL;
+
+ if (virXMLPropUInt(driver, "ssidSize", 10, VIR_XML_PROP_NONE,
+ &iommu->ssid_size) < 0)
+ if (virXMLPropInt(driver, "ssidsize", 10, VIR_XML_PROP_NONE,
+ &iommu->ssid_size, -1) < 0)
+ return NULL;
+
+ if (virXMLPropUInt(driver, "oas", 10, VIR_XML_PROP_NONE,
+ &iommu->oas) < 0)
+ if (virXMLPropInt(driver, "oas", 10, VIR_XML_PROP_NONE,
+ &iommu->oas, -1) < 0)
+ return NULL;
}
if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt,
@@ -16676,7 +16705,13 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a,
a->eim != b->eim ||
a->iotlb != b->iotlb ||
+
if ((granule = virXPathNode("./driver/granule", ctxt))) {
g_autofree char *mode = virXMLPropString(granule, "mode");
unsigned long long size;
@@ -16850,6 +16874,11 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a,
a->aw_bits != b->aw_bits ||
- a->dma_translation != b->dma_translation)
+ a->dma_translation != b->dma_translation ||
+ a->pci_bus != b->pci_bus ||
a->dma_translation != b->dma_translation ||
a->pci_bus != b->pci_bus ||
+ a->accel != b->accel ||
+ a->ats != b->ats ||
+ a->ril != b->ril ||
+ a->ssid_size != b->ssid_size ||
+ a->oas != b->oas)
return false;
if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
@@ -21432,6 +21467,14 @@ virDomainHostdevDefCheckABIStability(virDomainHostdevDef *src,
}
}
+ if (src->vpasidCapOffset != dst->vpasidCapOffset) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target host device vPASID capability offset %1$s does not match source %2$s"),
+ virDomainHostdevModeTypeToString(dst->vpasidCapOffset),
+ virDomainHostdevModeTypeToString(src->vpasidCapOffset));
+ return false;
+ }
+
if (!virDomainDeviceInfoCheckABIStability(src->info, dst->info))
return false;
@@ -22394,6 +22437,36 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src,
+ a->oas != b->oas ||
a->xtsup != b->xtsup ||
a->pt != b->pt ||
a->granule != b->granule)
@@ -22734,6 +22763,36 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src,
dst->pci_bus, src->pci_bus);
return false;
}
@ -202,18 +171,7 @@ index cb047e5a3e..8ea3206485 100644
if (src->dma_translation != dst->dma_translation) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target domain IOMMU device dma translation '%1$s' does not match source '%2$s'"),
@@ -27845,6 +27918,10 @@ virDomainHostdevDefFormat(virBuffer *buf,
if (def->shareable)
virBufferAddLit(buf, "<shareable/>\n");
+ if (def->vpasidCapOffset)
+ virBufferAsprintf(buf, "<vpasidCapOffset>0x%x</vpasidCapOffset>\n",
+ def->vpasidCapOffset);
+
virDomainDeviceInfoFormat(buf, def->info, flags | VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT
| VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM);
@@ -28770,6 +28847,26 @@ virDomainIOMMUDefFormat(virBuffer *buf,
@@ -29204,6 +29263,26 @@ virDomainIOMMUDefFormat(virBuffer *buf,
virBufferAsprintf(&driverAttrBuf, " pciBus='%d'",
iommu->pci_bus);
}
@ -229,123 +187,99 @@ index cb047e5a3e..8ea3206485 100644
+ virBufferAsprintf(&driverAttrBuf, " ril='%s'",
+ virTristateSwitchTypeToString(iommu->ril));
+ }
+ if (iommu->ssid_size > 0) {
+ virBufferAsprintf(&driverAttrBuf, " ssidSize='%d'",
+ if (iommu->ssid_size >= 0) {
+ virBufferAsprintf(&driverAttrBuf, " ssidsize='%d'",
+ iommu->ssid_size);
+ }
+ if (iommu->oas > 0) {
+ if (iommu->oas >= 0) {
+ virBufferAsprintf(&driverAttrBuf, " oas='%d'",
+ iommu->oas);
+ }
virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL);
if (iommu->granule != 0) {
if (iommu->granule == -1) {
virBufferAddLit(&driverChildBuf, "<granule mode='host'/>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 69a8e79c6d..a7afbca2a2 100644
index 0c6c79c413..40ea6090f8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -372,6 +372,7 @@ struct _virDomainHostdevDef {
bool missing;
bool readonly;
bool shareable;
+ unsigned int vpasidCapOffset;
virTristateBool writeFiltering;
union {
virDomainHostdevSubsys subsys;
@@ -3071,6 +3072,11 @@ struct _virDomainIOMMUDef {
virTristateSwitch dma_translation;
@@ -3105,6 +3105,11 @@ struct _virDomainIOMMUDef {
virTristateSwitch xtsup;
virTristateSwitch pt;
int granule; /* -1 means 'host', 0 unset, page size in KiB otherwise */
+ virTristateSwitch accel;
+ virTristateSwitch ats;
+ virTristateSwitch ril;
+ unsigned int ssid_size;
+ unsigned int oas;
+ int ssid_size;
+ int oas;
};
typedef enum {
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 4558e7b210..aed5eb0278 100644
index 3946f92182..710a891904 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -29,6 +29,7 @@
#include "virutil.h"
#include "virstring.h"
#include "virhostmem.h"
+#include "virpci.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
@@ -2364,6 +2365,20 @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev)
_("PCI host devices must use 'pci' or 'unassigned' address type"));
return -1;
}
+ if (hostdev->vpasidCapOffset) {
+ if (hostdev->vpasidCapOffset & 0x3) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vpasidCapOffset must be 4-byte aligned"));
+ return -1;
+ }
+ /* PASID ECAP size of 0x8 */
+ if (hostdev->vpasidCapOffset < VIR_DOMAIN_PCI_CONFIG_SPACE_SIZE ||
+ hostdev->vpasidCapOffset > VIR_DOMAIN_PCIE_CONFIG_SPACE_SIZE - 0x8) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vpasidCapOffset must be within PCIe extended configuration space (0x100-0xFFF)"));
+ return -1;
+ }
+ }
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
if (hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
@@ -3140,7 +3155,12 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->aw_bits != 0 ||
iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
- iommu->pci_bus >= 0) {
+ iommu->pci_bus >= 0 ||
+ iommu->accel != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ats != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ssid_size != 0 ||
+ iommu->oas != 0) {
virReportError(VIR_ERR_XML_ERROR,
_("iommu model '%1$s' doesn't support additional attributes"),
@@ -3203,6 +3203,16 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
virDomainIOMMUModelTypeToString(iommu->model));
@@ -3153,7 +3173,12 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
return -1;
}
+ if (iommu->accel != VIR_TRISTATE_SWITCH_ON &&
+ (iommu->ats != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ssid_size >= 0 ||
+ iommu->oas >= 0)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("accel must be enabled for iommu model '%1$s' when setting ats, ril, ssidsize, or oas"),
+ virDomainIOMMUModelTypeToString(iommu->model));
+ return -1;
+ }
break;
case VIR_DOMAIN_IOMMU_MODEL_VIRTIO:
if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT ||
@@ -3210,7 +3220,12 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->eim != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->aw_bits != 0 ||
iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
- iommu->pci_bus >= 0) {
+ iommu->pci_bus >= 0 ||
+ iommu->accel != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ats != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ssid_size != 0 ||
+ iommu->oas != 0) {
+ iommu->ssid_size >= 0 ||
+ iommu->oas >= 0) {
virReportError(VIR_ERR_XML_ERROR,
_("iommu model '%1$s' doesn't support some additional attributes"),
virDomainIOMMUModelTypeToString(iommu->model));
@@ -3164,7 +3189,12 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
case VIR_DOMAIN_IOMMU_MODEL_INTEL:
@@ -3233,6 +3248,11 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->aw_bits != 0 ||
iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->pci_bus >= 0 ||
+ iommu->accel != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ats != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ssid_size >= 0 ||
+ iommu->oas >= 0 ||
iommu->granule != 0) {
virReportError(VIR_ERR_XML_ERROR,
_("iommu model '%1$s' doesn't support some additional attributes"),
@@ -3245,6 +3265,11 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
if (iommu->pt != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT ||
- iommu->pci_bus >= 0) {
+ iommu->pci_bus >= 0 ||
iommu->pci_bus >= 0 ||
+ iommu->accel != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ats != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->ssid_size != 0 ||
+ iommu->oas != 0) {
+ iommu->ssid_size >= 0 ||
+ iommu->oas >= 0 ||
iommu->granule != 0) {
virReportError(VIR_ERR_XML_ERROR,
_("iommu model '%1$s' doesn't support some additional attributes"),
virDomainIOMMUModelTypeToString(iommu->model));
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 441328a08e..6de939c9f5 100644
index 121e4e06a6..c7d7ebc876 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6339,6 +6339,31 @@
<data type="unsignedInt"/>
</attribute>
@@ -6454,6 +6454,31 @@
<empty/>
</element>
</optional>
+ <optional>
+ <attribute name="accel">
@ -363,90 +297,77 @@ index 441328a08e..6de939c9f5 100644
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="ssidSize">
+ <data type="unsignedInt"/>
+ <attribute name="ssidsize">
+ <data type="int"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="oas">
+ <data type="unsignedInt"/>
+ <data type="int"/>
+ </attribute>
+ </optional>
</element>
</optional>
<optional>
@@ -6620,6 +6645,13 @@
<ref name="pciaddress"/>
</element>
</element>
+ <optional>
+ <element name="vpasidCapOffset">
+ <data type="string">
+ <param name="pattern">(0x[0-9a-fA-F]+|[0-9]+)</param>
+ </data>
+ </element>
+ </optional>
<ref name="hostdevsubsysvfiodisplay"/>
</interleave>
</define>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 521aefbc10..e7c6e1d0eb 100644
index e726dc661c..2d5eaa1e80 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4812,6 +4812,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
"B:ramfb", ramfb,
"S:iommufd", iommufdId,
"S:fd", fdstr,
+ "p:x-vpasid-cap-offset", dev->vpasidCapOffset,
NULL) < 0)
return NULL;
@@ -6276,6 +6276,8 @@ qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def,
{
g_autoptr(virJSONValue) props = NULL;
g_autofree char *bus = NULL;
+ g_autofree char *ssidsizeStr = NULL;
+ g_autofree char *oasStr = NULL;
virPCIDeviceAddress addr = { .bus = iommu->pci_bus };
@@ -6323,9 +6324,31 @@ qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def,
bus = qemuBuildDeviceAddressPCIGetBus(def, &addr);
@@ -6286,10 +6288,23 @@ qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def,
return NULL;
}
+ if (iommu->ssid_size >= 0) {
+ ssidsizeStr = g_strdup_printf("%u", iommu->ssid_size);
+ }
+
+ if (iommu->oas >= 0) {
+ oasStr = g_strdup_printf("%u", iommu->oas);
+ }
+
if (virJSONValueObjectAdd(&props,
"s:driver", "arm-smmuv3",
"s:primary-bus", bus,
"s:id", iommu->info.alias,
+ "B:accel", (iommu->accel == VIR_TRISTATE_SWITCH_ON),
+ "B:ats", (iommu->ats == VIR_TRISTATE_SWITCH_ON),
+ "T:accel", iommu->accel,
+ "S:ats", qemuOnOffAuto(iommu->ats),
+ "S:ril", qemuOnOffAuto(iommu->ril),
+ "S:ssidsize", ssidsizeStr,
+ "S:oas", oasStr,
NULL) < 0)
return NULL;
+ /* QEMU SMMUv3 has RIL support by default; only emit when explicitly disabling */
+ if (iommu->ril == VIR_TRISTATE_SWITCH_OFF) {
+ if (virJSONValueObjectAppendBoolean(props, "ril", false) < 0)
+ return NULL;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 2da99329c5..1093eb8363 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -5827,6 +5827,18 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu,
return -1;
}
+ /* While QEMU_CAPS_ARM_SMMUV3_ACCEL tracks the .accel attribute of
+ * arm-smmuv3 it is also a good indicator of .ats, .ril, .ssidsize, and
+ * .oas attributes as all of them were introduced in the same release,
+ * and these features are meant to be backported all together. */
+ if (iommu->model == VIR_DOMAIN_IOMMU_MODEL_SMMUV3 &&
+ iommu->accel != VIR_TRISTATE_SWITCH_ABSENT &&
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_ARM_SMMUV3_ACCEL)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("iommu: accel is not supported with this QEMU binary"));
+ return -1;
+ }
+
+ if (iommu->ssid_size > 0) {
+ if (virJSONValueObjectAdd(&props,
+ "p:ssidsize", iommu->ssid_size,
+ NULL) < 0)
+ return NULL;
+ }
+
+ if (iommu->oas > 0) {
+ if (virJSONValueObjectAdd(&props,
+ "p:oas", iommu->oas,
+ NULL) < 0)
+ return NULL;
+ }
+
return g_steal_pointer(&props);
}
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 933099da6c..04bf586e76 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -35,6 +35,10 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDeviceList, virObjectUnref);
#define VIR_DOMAIN_DEVICE_ZPCI_MAX_UID UINT16_MAX
#define VIR_DOMAIN_DEVICE_ZPCI_MAX_FID UINT32_MAX
+/* Size of the standard PCI config space */
+#define VIR_DOMAIN_PCI_CONFIG_SPACE_SIZE 0x100
+/* Size of the standard PCIe config space: 4KB */
+#define VIR_DOMAIN_PCIE_CONFIG_SPACE_SIZE 0x1000
typedef struct _virZPCIDeviceAddressID virZPCIDeviceAddressID;
typedef struct _virZPCIDeviceAddress virZPCIDeviceAddress;
if (iommu->granule > 0) {
/* QEMU supports only 4KiB, 8KiB, 16KiB and 64KiB granule size */
if (!(iommu->granule == 4 ||
--
2.53.0
2.55.0

View File

@ -1,125 +0,0 @@
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

@ -1,129 +0,0 @@
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

@ -1,53 +0,0 @@
From 0ee217dd22cb6f93191e495e7b6a8127f5e9983f Mon Sep 17 00:00:00 2001
Message-ID: <0ee217dd22cb6f93191e495e7b6a8127f5e9983f.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 12:52:05 +0100
Subject: [PATCH] qemu: Expand call to qemuDomainNeedsVFIO
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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

@ -1,144 +0,0 @@
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

View File

@ -1,247 +0,0 @@
From 0feb51944a7355e5c8502536df4c63e91f474d43 Mon Sep 17 00:00:00 2001
Message-ID: <0feb51944a7355e5c8502536df4c63e91f474d43.1774023916.git.phrdina@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
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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 1aff3a277b..7fb992ce5a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7685,13 +7685,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;
@@ -7706,16 +7709,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;
@@ -7733,7 +7741,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 2a4c7f6a3c..d8cf117fc4 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 96ca59a7a4..0fa50630f7 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,713 +0,0 @@
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
Since commit 99a637a8 in qemu 10.0, the way the cmp_legacy flag is
reported changed. The same way as happend with the 'ht' flag in commit
c6bd2dd634208, which was fixed in libvirt since commit ba16113c.
This causes migrations from a hypervisor running a qemu version before
that commit to a hypervisor running qemu after that commit fails
with the following error:
guest CPU doesn't match specification: extra features: cmp_legacy
We can just ignore this flag, just like we did with the 'ht' flag.
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-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
- 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
- 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 +-
48 files changed, 48 insertions(+), 47 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 92b863a826..d738805ee8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -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 */
+ "cmp_legacy", /* ignored by QEMU, set according to topology */
};
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
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-6.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-6.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-fallback-kvm.x86_64-7.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.0.0.args
index e944e69cfd..0df6ce9e3d 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.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-7.0,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-fallback-kvm.x86_64-7.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.1.0.args
index d9edda2733..b4a91fa921 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.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-7.1,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-fallback-kvm.x86_64-7.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.2.0.args
index 1d1839b7fa..5d69199876 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.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-7.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-fallback-kvm.x86_64-8.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.0.0.args
index 8278629ee7..e7b424819e 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.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-8.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,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-fallback-kvm.x86_64-8.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.1.0.args
index 3b733a3c5d..58ad565dba 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.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-8.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,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,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,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-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-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 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-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 \
diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.2.0.args
index f65444948e..4402bad82d 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.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-6.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-kvm.x86_64-7.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.0.0.args
index 8f8b1645d5..d6dfadc3b2 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.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-7.0,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-kvm.x86_64-7.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.1.0.args
index df03bafab3..09e220487d 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.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-7.1,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-kvm.x86_64-7.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.2.0.args
index 7a796812fa..7e90b309a9 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.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-7.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-kvm.x86_64-8.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.0.0.args
index d63438e81c..fc02c9a7e0 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.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-8.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,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-kvm.x86_64-8.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.1.0.args
index 901f279a02..8360dc02ef 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.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-8.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,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,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,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-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 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
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-6.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-6.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-nofallback-kvm.x86_64-7.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.0.0.args
index e944e69cfd..0df6ce9e3d 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.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-7.0,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-nofallback-kvm.x86_64-7.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.1.0.args
index d9edda2733..b4a91fa921 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.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-7.1,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-nofallback-kvm.x86_64-7.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.2.0.args
index 1d1839b7fa..5d69199876 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.2.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.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-7.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel kvm \
--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-nofallback-kvm.x86_64-8.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.0.0.args
index 8278629ee7..e7b424819e 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.0.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.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-8.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,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
+-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=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,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=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-nofallback-kvm.x86_64-8.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.1.0.args
index 3b733a3c5d..58ad565dba 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.1.0.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.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-8.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,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,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,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-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 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-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 \
diff --git a/tests/qemuxmlconfdata/cpu-translation.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-translation.x86_64-latest.args
index 49e1b590dd..d425866c67 100644
--- a/tests/qemuxmlconfdata/cpu-translation.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-translation.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,pclmulqdq=on,ds-cpl=on,tsc-adjust=on,fxsr-opt=on,lahf-lm=on,cmp-legacy=on,nodeid-msr=on,perfctr-core=on,perfctr-nb=on,kvm-pv-eoi=on,kvm-pv-unhalt=on \
+-cpu Haswell,pclmulqdq=on,ds-cpl=on,tsc-adjust=on,fxsr-opt=on,lahf-lm=on,nodeid-msr=on,perfctr-core=on,perfctr-nb=on,kvm-pv-eoi=on,kvm-pv-unhalt=on \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
--
2.53.0

View File

@ -1,129 +0,0 @@
From 5e9b5534fdf50bcfc19b0fd12d44db5c8f635675 Mon Sep 17 00:00:00 2001
Message-ID: <5e9b5534fdf50bcfc19b0fd12d44db5c8f635675.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 16 Mar 2026 15:29:32 +0100
Subject: [PATCH] qemu: Implement iommufd fdgroup
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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 30bed14b0c..a76f504e6f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5361,8 +5361,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 5fe4a33944..2b1d47ed86 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7700,6 +7700,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
@@ -7755,9 +7793,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

@ -1,121 +0,0 @@
From aa8c64443e0f8dfdd0d304372e68a2b50543f1bc Mon Sep 17 00:00:00 2001
Message-ID: <aa8c64443e0f8dfdd0d304372e68a2b50543f1bc.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 17:59:01 +0100
Subject: [PATCH] qemu: Implement iommufd
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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 6a9625e283..5fe4a33944 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6050,7 +6050,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);
@@ -6838,7 +6838,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

@ -1,191 +0,0 @@
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

@ -1,220 +0,0 @@
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

@ -1,266 +0,0 @@
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

@ -1,277 +0,0 @@
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

@ -1,111 +0,0 @@
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

@ -1,79 +0,0 @@
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,132 +0,0 @@
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

@ -0,0 +1,161 @@
From 79a6beccbab92190c293a9f5a0b53e25a1150a71 Mon Sep 17 00:00:00 2001
Message-ID: <79a6beccbab92190c293a9f5a0b53e25a1150a71.1786096789.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 11 Mar 2026 12:12:09 -0700
Subject: [PATCH] qemu: Support NVIDIA Tegra241 CMDQV for SMMUv3
From: Nathan Chen <nathanc@nvidia.com>
Introduce support for a "cmdqv" IOMMU attribute which enables
NVIDIA Tegra241 CMDQV, an extension for ARM SMMUv3. This
supports passthrough of physical SMMU-CMDQ linked command
queue from host space to a VM.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1045
---
docs/formatdomain.rst | 6 ++++++
src/conf/domain_conf.c | 15 +++++++++++++++
src/conf/domain_conf.h | 1 +
src/conf/domain_validate.c | 5 ++++-
src/conf/schemas/domaincommon.rng | 5 +++++
src/qemu/qemu_command.c | 1 +
6 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 1e8c81c3a5..f7b35d31fa 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9464,6 +9464,12 @@ Examples:
default value is used.
:since:`Since 12.7.0` (QEMU/KVM and ``smmuv3`` model only)
+ ``cmdqv``
+ The ``cmdqv`` attribute with possible values ``on`` and ``off`` can be used
+ to enable NVIDIA Tegra241 CMDQV, an extension for ARM SMMUv3 that supports
+ passthrough of physical SMMU-CMDQ linked command queue from host space to VM.
+ :since:`Since 12.1.0` (QEMU/KVM and ``smmuv3`` model only)
+
In case of ``virtio`` IOMMU device, the ``driver`` element can optionally
contain ``granule`` subelement that allows to choose which granule will be
used by default. It is useful when running guests with different page size
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index db44ba9a72..974746bb5c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14770,6 +14770,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt,
&iommu->oas, -1) < 0)
return NULL;
+ if (virXMLPropTristateSwitch(driver, "cmdqv", VIR_XML_PROP_NONE,
+ &iommu->cmdqv) < 0)
+ return NULL;
+
if ((granule = virXPathNode("./driver/granule", ctxt))) {
g_autofree char *mode = virXMLPropString(granule, "mode");
unsigned long long size;
@@ -16881,6 +16885,7 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a,
a->oas != b->oas ||
a->xtsup != b->xtsup ||
a->pt != b->pt ||
+ a->cmdqv != b->cmdqv ||
a->granule != b->granule)
return false;
@@ -22793,6 +22798,12 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src,
dst->oas, src->oas);
return false;
}
+ if (src->cmdqv != dst->cmdqv) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target domain IOMMU device cmdqv value '%1$d' does not match source '%2$d'"),
+ dst->cmdqv, src->cmdqv);
+ return false;
+ }
if (src->dma_translation != dst->dma_translation) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target domain IOMMU device dma translation '%1$s' does not match source '%2$s'"),
@@ -29283,6 +29294,10 @@ virDomainIOMMUDefFormat(virBuffer *buf,
virBufferAsprintf(&driverAttrBuf, " oas='%d'",
iommu->oas);
}
+ if (iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&driverAttrBuf, " cmdqv='%s'",
+ virTristateSwitchTypeToString(iommu->cmdqv));
+ }
if (iommu->granule != 0) {
if (iommu->granule == -1) {
virBufferAddLit(&driverChildBuf, "<granule mode='host'/>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 40ea6090f8..9a65a12e2c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3110,6 +3110,7 @@ struct _virDomainIOMMUDef {
virTristateSwitch ril;
int ssid_size;
int oas;
+ virTristateSwitch cmdqv;
};
typedef enum {
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 710a891904..1cd407bedc 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -3225,7 +3225,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->ats != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ssid_size >= 0 ||
- iommu->oas >= 0) {
+ iommu->oas >= 0 ||
+ iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT) {
virReportError(VIR_ERR_XML_ERROR,
_("iommu model '%1$s' doesn't support some additional attributes"),
virDomainIOMMUModelTypeToString(iommu->model));
@@ -3253,6 +3254,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ssid_size >= 0 ||
iommu->oas >= 0 ||
+ iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->granule != 0) {
virReportError(VIR_ERR_XML_ERROR,
_("iommu model '%1$s' doesn't support some additional attributes"),
@@ -3270,6 +3272,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ssid_size >= 0 ||
iommu->oas >= 0 ||
+ iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->granule != 0) {
virReportError(VIR_ERR_XML_ERROR,
_("iommu model '%1$s' doesn't support some additional attributes"),
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index c7d7ebc876..ea7c177a68 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6432,6 +6432,11 @@
<data type="unsignedInt"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="cmdqv">
+ <ref name="virOnOff"/>
+ </attribute>
+ </optional>
<optional>
<element name="granule">
<choice>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2d5eaa1e80..9b272c8314 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6305,6 +6305,7 @@ qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def,
"S:ril", qemuOnOffAuto(iommu->ril),
"S:ssidsize", ssidsizeStr,
"S:oas", oasStr,
+ "S:cmdqv", qemuOnOffAuto(iommu->cmdqv),
NULL) < 0)
return NULL;
--
2.55.0

View File

@ -1,212 +0,0 @@
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,336 +0,0 @@
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

@ -1,109 +0,0 @@
From ba63f0bdc6a08aab9ff9217c6ad665b6a27ce738 Mon Sep 17 00:00:00 2001
Message-ID: <ba63f0bdc6a08aab9ff9217c6ad665b6a27ce738.1774023916.git.phrdina@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
From: Pavel Hrdina <phrdina@redhat.com>
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/VOYAGER-309
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 e8c4116fa0..6e49507e83 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32621,6 +32621,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 36e69ad6fd..de803d0dcc 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4665,6 +4665,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 ea1e2d8586..d2563e587a 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

@ -1,69 +0,0 @@
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

@ -1,145 +0,0 @@
From e29d49aeeb384f3e1430c8a1d0e5b85f82305335 Mon Sep 17 00:00:00 2001
Message-ID: <e29d49aeeb384f3e1430c8a1d0e5b85f82305335.1771499562.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Tue, 6 Jan 2026 12:54:24 -0800
Subject: [PATCH] qemu: add IOMMU attribute "cmdqv" for smmuv3
From: Nathan Chen <nathanc@nvidia.com>
Introduce support for "cmdqv" IOMMU attribute, which
enables NVIDIA Tegra241 CMDQV, an extension for ARM
SMMUv3. It supports passthroughs of physical SMMU-CMDQ
linked command queue from host space to a VM.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Resolves: https://issues.redhat.com/browse/VOYAGER-14
---
docs/formatdomain.rst | 5 +++++
src/conf/domain_conf.c | 9 +++++++++
src/conf/domain_conf.h | 1 +
src/conf/domain_validate.c | 3 +++
src/conf/schemas/domaincommon.rng | 5 +++++
src/qemu/qemu_command.c | 1 +
6 files changed, 24 insertions(+)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 9ce647eba7..8f1be253de 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9319,6 +9319,11 @@ Example:
to enable hardware acceleration support for smmuv3Dev IOMMU devices.
(QEMU/KVM and ``smmuv3`` model only)
+ ``cmdqv``
+ The ``cmdqv`` attribute with possibel values ``on`` and ``off`` can be used
+ to enable NVIDIA Tegra241 CMDQV, an extension for ARM SMMUv3 that supports
+ passthrough of physical SMMU-CMDQ linked command queue from host space to VM.
+
``ats``
The ``ats`` attribute with possible values ``on`` and ``off`` can be used
to enable reporting Address Translation Services capability to the guest
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8ea3206485..b8c180e72d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14627,6 +14627,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt,
&iommu->accel) < 0)
return NULL;
+ if (virXMLPropTristateSwitch(driver, "cmdqv", VIR_XML_PROP_NONE,
+ &iommu->cmdqv) < 0)
+ return NULL;
+
if (virXMLPropTristateSwitch(driver, "ats", VIR_XML_PROP_NONE,
&iommu->ats) < 0)
return NULL;
@@ -16708,6 +16712,7 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a,
a->dma_translation != b->dma_translation ||
a->pci_bus != b->pci_bus ||
a->accel != b->accel ||
+ a->cmdqv != b->cmdqv ||
a->ats != b->ats ||
a->ril != b->ril ||
a->ssid_size != b->ssid_size ||
@@ -28851,6 +28856,10 @@ virDomainIOMMUDefFormat(virBuffer *buf,
virBufferAsprintf(&driverAttrBuf, " accel='%s'",
virTristateSwitchTypeToString(iommu->accel));
}
+ if (iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&driverAttrBuf, " cmdqv='%s'",
+ virTristateSwitchTypeToString(iommu->cmdqv));
+ }
if (iommu->ats != VIR_TRISTATE_SWITCH_ABSENT) {
virBufferAsprintf(&driverAttrBuf, " ats='%s'",
virTristateSwitchTypeToString(iommu->ats));
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a7afbca2a2..91b8976ea5 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3073,6 +3073,7 @@ struct _virDomainIOMMUDef {
virTristateSwitch xtsup;
virTristateSwitch pt;
virTristateSwitch accel;
+ virTristateSwitch cmdqv;
virTristateSwitch ats;
virTristateSwitch ril;
unsigned int ssid_size;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index aed5eb0278..51f7961e3c 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -3157,6 +3157,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->pci_bus >= 0 ||
iommu->accel != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ats != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ssid_size != 0 ||
@@ -3175,6 +3176,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->pci_bus >= 0 ||
iommu->accel != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ats != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ssid_size != 0 ||
@@ -3191,6 +3193,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->pci_bus >= 0 ||
iommu->accel != VIR_TRISTATE_SWITCH_ABSENT ||
+ iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ats != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ril != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->ssid_size != 0 ||
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 6de939c9f5..5d0e538535 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6344,6 +6344,11 @@
<ref name="virOnOff"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="cmdqv">
+ <ref name="virOnOff"/>
+ </attribute>
+ </optional>
<optional>
<attribute name="ats">
<ref name="virOnOff"/>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e7c6e1d0eb..fdc79e18be 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6325,6 +6325,7 @@ qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def,
"s:primary-bus", bus,
"s:id", iommu->info.alias,
"B:accel", (iommu->accel == VIR_TRISTATE_SWITCH_ON),
+ "B:tegra241-cmdqv", (iommu->cmdqv == VIR_TRISTATE_SWITCH_ON),
"B:ats", (iommu->ats == VIR_TRISTATE_SWITCH_ON),
NULL) < 0)
return NULL;
--
2.53.0

View File

@ -1,58 +0,0 @@
From 2674cc2e58f98439fe72e4d832e6e2e9b41a614f Mon Sep 17 00:00:00 2001
Message-ID: <2674cc2e58f98439fe72e4d832e6e2e9b41a614f.1771336681.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 11 Dec 2025 19:26:40 +0100
Subject: [PATCH] qemu: capabilities: Introduce
QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR
Introduce capability for persisten migration control support.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit b0edb7eb9b819e0560bb7d65b4e0c89082b3b43b)
https://issues.redhat.com/browse/RHEL-140614 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-135115 [rhel-10.2]
Conflicts:
- Commit befdd44bf836c3ba46e46d57b587127e12736591 adding
QEMU_CAPS_VIRTIO_IOMMU_AW_BITS was not backported
---
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 1efb77d03b..2c8bd62c99 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -755,6 +755,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"disk-timed-stats", /* QEMU_CAPS_DISK_TIMED_STATS */
"query-accelerators", /* QEMU_CAPS_QUERY_ACCELERATORS */
"mshv", /* QEMU_CAPS_MSHV */
+ "scsi-block.migrate-pr", /* QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR */
);
@@ -1536,6 +1537,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIDisk[] = {
};
static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIBlock[] = {
+ { "migrate-pr", QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, NULL },
};
static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIGeneric[] = {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index f180844e66..0c76f2edda 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -730,6 +730,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_DISK_TIMED_STATS, /* timed stats support ('stats-intervals' property of disk frontends) */
QEMU_CAPS_QUERY_ACCELERATORS, /* query-accelerators command */
QEMU_CAPS_MSHV, /* -accel mshv */
+ QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, /* persistent reservation migration support */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
--
2.53.0

View File

@ -0,0 +1,83 @@
From a594bace1865115e40b45e26083b039b1e53aac5 Mon Sep 17 00:00:00 2001
Message-ID: <a594bace1865115e40b45e26083b039b1e53aac5.1786096788.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 5 Aug 2026 15:12:59 -0700
Subject: [PATCH] qemu: introduce QEMU_CAPS_ARM_SMMUV3_ACCEL
From: Nathan Chen <nathanc@nvidia.com>
The arm-smmuv3 accel device property, used for HW-accelerated nested
SMMUv3, was added in QEMU 11.0.0 on top of the pluggable device
introduced in 10.2. Probe it alongside smmu_per_bus via
device-list-properties.
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
(cherry picked from commit 90b01b9d3e3b684837190e92257eba15511515b0)
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1043
---
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml | 1 +
tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml | 1 +
4 files changed, 5 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a7d121f917..c60ca02d97 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -769,6 +769,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"blockdev-mirror.target-is-zero", /* QEMU_CAPS_BLOCKDEV_MIRROR_TARGET_IS_ZERO */
"arm-smmuv3", /* QEMU_CAPS_DEVICE_ARM_SMMUV3 */
"arm-smmuv3.smmu_per_bus", /* QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS */
+ "arm-smmuv3.accel", /* QEMU_CAPS_ARM_SMMUV3_ACCEL */
);
@@ -1648,6 +1649,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsAMDIOMMU[] = {
static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsArmSmmuv3[] = {
{ "smmu_per_bus", QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS, NULL },
+ { "accel", QEMU_CAPS_ARM_SMMUV3_ACCEL, NULL },
};
/* see documentation for virQEMUQAPISchemaPathGet for the query format */
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 0dc9836ca9..28085144a2 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -743,6 +743,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_BLOCKDEV_MIRROR_TARGET_IS_ZERO, /* 'blockdev-mirror' supports 'target-is-zero' */
QEMU_CAPS_DEVICE_ARM_SMMUV3, /* -device arm-smmuv3 */
QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS, /* arm-smmuv3.smmu_per_bus */
+ QEMU_CAPS_ARM_SMMUV3_ACCEL, /* arm-smmuv3.accel */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml
index 2280800fca..ca6def23dc 100644
--- a/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml
@@ -190,6 +190,7 @@
<flag name='blockdev-mirror.target-is-zero'/>
<flag name='arm-smmuv3'/>
<flag name='arm-smmuv3.smmu_per_bus'/>
+ <flag name='arm-smmuv3.accel'/>
<version>11000000</version>
<microcodeVersion>61700286</microcodeVersion>
<package>v11.0.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
index b4200f35bb..306f2981c1 100644
--- a/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
@@ -190,6 +190,7 @@
<flag name='blockdev-mirror.target-is-zero'/>
<flag name='arm-smmuv3'/>
<flag name='arm-smmuv3.smmu_per_bus'/>
+ <flag name='arm-smmuv3.accel'/>
<version>11000050</version>
<microcodeVersion>61700287</microcodeVersion>
<package>v11.0.0-1600-g5611a9268d</package>
--
2.55.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,154 @@
From 2b8afaa4f1e28c5e895301790098f9f7bc3b365b Mon Sep 17 00:00:00 2001
Message-ID: <2b8afaa4f1e28c5e895301790098f9f7bc3b365b.1786096788.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 5 Aug 2026 15:12:57 -0700
Subject: [PATCH] qemu: introduce QEMU_CAPS_DEVICE_ARM_SMMUV3
From: Nathan Chen <nathanc@nvidia.com>
The arm-smmuv3 QOM type is reported by qom-list-types on ARM QEMU.
Register it as QEMU_CAPS_DEVICE_ARM_SMMUV3 so later device-list-properties
probing for arm-smmuv3 properties can be gated on this capability
instead of an architecture check.
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
(cherry picked from commit 93e0d7845585fd42fc770991e5eb9f365c96d6bb)
Conflicts:
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
- missing upstream commit 248981ff51116e06d3b7be7dbd33559a45261e24
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1043
---
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml | 1 +
tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml | 1 +
tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml | 1 +
tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml | 1 +
tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml | 1 +
tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml | 1 +
tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml | 1 +
9 files changed, 10 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index be57dcad8e..33efc6651b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -767,6 +767,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
/* 495 */
"blockdev-mirror.target-is-zero", /* QEMU_CAPS_BLOCKDEV_MIRROR_TARGET_IS_ZERO */
+ "arm-smmuv3", /* QEMU_CAPS_DEVICE_ARM_SMMUV3 */
);
@@ -1480,6 +1481,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "iommufd", QEMU_CAPS_OBJECT_IOMMUFD },
{ "uefi-vars-x64", QEMU_CAPS_DEVICE_UEFI_VARS },
{ "uefi-vars-sysbus", QEMU_CAPS_DEVICE_UEFI_VARS },
+ { "arm-smmuv3", QEMU_CAPS_DEVICE_ARM_SMMUV3 },
};
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 3014f3dc5e..e5d589b0c4 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -741,6 +741,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
/* 495 */
QEMU_CAPS_BLOCKDEV_MIRROR_TARGET_IS_ZERO, /* 'blockdev-mirror' supports 'target-is-zero' */
+ QEMU_CAPS_DEVICE_ARM_SMMUV3, /* -device arm-smmuv3 */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml
index b6434e6019..b2a0872853 100644
--- a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml
@@ -166,6 +166,7 @@
<flag name='virtio-iommu.aw-bits'/>
<flag name='iommufd'/>
<flag name='uefi-vars'/>
+ <flag name='arm-smmuv3'/>
<version>10000000</version>
<microcodeVersion>61700285</microcodeVersion>
<package>v10.0.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml
index df3e2a8275..449f2f65c7 100644
--- a/tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml
@@ -186,6 +186,7 @@
<flag name='iommufd'/>
<flag name='uefi-vars'/>
<flag name='blockdev-mirror.target-is-zero'/>
+ <flag name='arm-smmuv3'/>
<version>10002000</version>
<microcodeVersion>61700287</microcodeVersion>
<package>v10.2.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml
index 3fdc0d6621..b9acf8ac67 100644
--- a/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml
@@ -188,6 +188,7 @@
<flag name='uefi-vars'/>
<flag name='query-block-flat'/>
<flag name='blockdev-mirror.target-is-zero'/>
+ <flag name='arm-smmuv3'/>
<version>11000000</version>
<microcodeVersion>61700286</microcodeVersion>
<package>v11.0.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
index f7dd14a1ad..0595e5f88c 100644
--- a/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
@@ -188,6 +188,7 @@
<flag name='uefi-vars'/>
<flag name='query-block-flat'/>
<flag name='blockdev-mirror.target-is-zero'/>
+ <flag name='arm-smmuv3'/>
<version>11000050</version>
<microcodeVersion>61700287</microcodeVersion>
<package>v11.0.0-1600-g5611a9268d</package>
diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml
index bb70bcaf1f..e026abfd96 100644
--- a/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.xml
@@ -161,6 +161,7 @@
<flag name='nvme'/>
<flag name='nvme-ns'/>
<flag name='usb-bot'/>
+ <flag name='arm-smmuv3'/>
<version>8002000</version>
<microcodeVersion>61700246</microcodeVersion>
<package>v8.2.0</package>
diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml b/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml
index 9590bc464a..d3af74bcb3 100644
--- a/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml
+++ b/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.xml
@@ -168,6 +168,7 @@
<flag name='nvme'/>
<flag name='nvme-ns'/>
<flag name='usb-bot'/>
+ <flag name='arm-smmuv3'/>
<version>8002000</version>
<microcodeVersion>0</microcodeVersion>
<package>qemu-8.2.0-7.fc39</package>
diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml b/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml
index 9c843f9e5c..8c777c121e 100644
--- a/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml
+++ b/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.xml
@@ -136,6 +136,7 @@
<flag name='usb-bot'/>
<flag name='acpi-generic-initiator'/>
<flag name='virtio-iommu.aw-bits'/>
+ <flag name='arm-smmuv3'/>
<version>9002002</version>
<microcodeVersion>61700247</microcodeVersion>
<package></package>
--
2.55.0

View File

@ -1,147 +0,0 @@
From 64ae2c71b95cd25fb1e18fbc68ddbc814f3de8ca Mon Sep 17 00:00:00 2001
Message-ID: <64ae2c71b95cd25fb1e18fbc68ddbc814f3de8ca.1770203422.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 17:00:10 +0100
Subject: [PATCH] qemu: migration: Always offer block dirty bitmaps during
migration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Until now block dirty bitmaps were offered to destination only if
non-shared storage migration was enabled.
Upcoming patches will want to support it also in cases when storage is
shared but the destination has a qcow2 overlay using the 'data_file'
feature where the qcow2 overlay is not actually shared.
To support that we'll now always offer bitmaps for migration. The
destination can then decide (using existing logic) to pick only the
ones that are not present in the image on destination, which is how
it was supposed to work even now.
The patch removes all the flag checks and simply offers bitmaps in any
case. The overhead incurred by this is one 'query-named-block-nodes'
call to qemu.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit a4f610ff3fe190058f18baea18b095d0bc69441b)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
src/qemu/qemu_migration.c | 28 +++++++---------------------
1 file changed, 7 insertions(+), 21 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 723e131c98..755b9a5e1a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2580,16 +2580,13 @@ qemuMigrationAnyConnectionClosed(virDomainObj *vm,
* qemuMigrationSrcBeginPhaseBlockDirtyBitmaps:
* @mig: migration cookie struct
* @vm: domain object
- * @migrate_disks: disks which are being migrated
- * @nmigrage_disks: number of @migrate_disks
*
* Enumerates block dirty bitmaps on disks which will undergo storage migration
* and fills them into @mig to be offered to the destination.
*/
static int
qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(qemuMigrationCookie *mig,
- virDomainObj *vm,
- const char **migrate_disks)
+ virDomainObj *vm)
{
GSList *disks = NULL;
@@ -2611,9 +2608,6 @@ qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(qemuMigrationCookie *mig,
if (!nodedata)
continue;
- if (!qemuMigrationAnyCopyDisk(diskdef, migrate_disks))
- continue;
-
for (j = 0; j < nodedata->nbitmaps; j++) {
qemuMigrationBlockDirtyBitmapsDiskBitmap *bitmap;
@@ -2680,7 +2674,6 @@ qemuMigrationSrcBeginXML(virDomainObj *vm,
char **cookieout,
int *cookieoutlen,
unsigned int cookieFlags,
- const char **migrate_disks,
unsigned int flags)
{
qemuDomainObjPrivate *priv = vm->privateData;
@@ -2696,8 +2689,7 @@ qemuMigrationSrcBeginXML(virDomainObj *vm,
if (!(mig = qemuMigrationCookieNew(vm->def, priv->origname)))
return NULL;
- if (cookieFlags & QEMU_MIGRATION_COOKIE_NBD &&
- qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm, migrate_disks) < 0)
+ if (qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm) < 0)
return NULL;
if (qemuMigrationCookieFormat(mig, driver, vm,
@@ -2879,8 +2871,7 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver,
return NULL;
return qemuMigrationSrcBeginXML(vm, xmlin,
- cookieout, cookieoutlen, cookieFlags,
- migrate_disks, flags);
+ cookieout, cookieoutlen, cookieFlags, flags);
}
@@ -2969,8 +2960,7 @@ qemuMigrationSrcBeginResume(virDomainObj *vm,
return NULL;
}
- return qemuMigrationSrcBeginXML(vm, xmlin,
- cookieout, cookieoutlen, 0, NULL, flags);
+ return qemuMigrationSrcBeginXML(vm, xmlin, cookieout, cookieoutlen, 0, flags);
}
@@ -4752,7 +4742,6 @@ qemuMigrationSrcRunPrepareBlockDirtyBitmaps(virDomainObj *vm,
/* For VIR_MIGRATE_NON_SHARED_INC we can migrate the bitmaps directly,
* otherwise we must create merged bitmaps from the whole chain */
-
if (!(flags & VIR_MIGRATE_NON_SHARED_INC) &&
qemuMigrationSrcRunPrepareBlockDirtyBitmapsMerge(vm, mig) < 0)
return -1;
@@ -4943,7 +4932,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
VIR_AUTOCLOSE fd = -1;
unsigned long restore_max_bandwidth = priv->migMaxBandwidth;
virErrorPtr orig_err = NULL;
- unsigned int cookieFlags = 0;
+ unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS;
bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
bool storageMigration = flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC);
bool cancel = false;
@@ -4967,10 +4956,8 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
storageMigration = qemuMigrationHasAnyStorageMigrationDisks(vm->def,
migrate_disks);
- if (storageMigration) {
+ if (storageMigration)
cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
- cookieFlags |= QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS;
- }
if (virLockManagerPluginUsesState(driver->lockManager) &&
!cookieout) {
@@ -5004,8 +4991,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
cookiein, cookieinlen,
cookieFlags |
QEMU_MIGRATION_COOKIE_GRAPHICS |
- QEMU_MIGRATION_COOKIE_CAPS |
- QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS);
+ QEMU_MIGRATION_COOKIE_CAPS);
if (!mig)
goto error;
--
2.52.0

View File

@ -1,182 +0,0 @@
From 99b1b6fda9b4e098a7bbbbb44e02064c57bff558 Mon Sep 17 00:00:00 2001
Message-ID: <99b1b6fda9b4e098a7bbbbb44e02064c57bff558.1771336681.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 11 Dec 2025 18:38:12 +0100
Subject: [PATCH] qemu: monitor: Add handlers for 'block-latency-histogram-set'
Add QMP monitor code for setting up latency histogram configuration.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit ad4830ce6844b75800685ea85b15a53b8dbc5ac6)
https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2]
---
src/qemu/qemu_monitor.c | 21 +++++++++++++
src/qemu/qemu_monitor.h | 9 ++++++
src/qemu/qemu_monitor_json.c | 60 ++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 9 ++++++
tests/qemumonitorjsontest.c | 9 ++++++
5 files changed, 108 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index cdd08004fb..3d7477c01c 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4612,3 +4612,24 @@ qemuMonitorBlockdevSetActive(qemuMonitor *mon,
return qemuMonitorJSONBlockdevSetActive(mon, nodename, active);
}
+
+
+int
+qemuMonitorBlockLatencyHistogramSet(qemuMonitor *mon,
+ const char *id,
+ unsigned int *boundaries,
+ unsigned int *boundaries_read,
+ unsigned int *boundaries_write,
+ unsigned int *boundaries_zone,
+ unsigned int *boundaries_flush)
+{
+ QEMU_CHECK_MONITOR(mon);
+ VIR_DEBUG("id='%s'", id);
+
+ return qemuMonitorJSONBlockLatencyHistogramSet(mon, id,
+ boundaries,
+ boundaries_read,
+ boundaries_write,
+ boundaries_zone,
+ boundaries_flush);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 238f7be875..bbe400003a 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1988,3 +1988,12 @@ int
qemuMonitorBlockdevSetActive(qemuMonitor *mon,
const char *nodename,
bool active);
+
+int
+qemuMonitorBlockLatencyHistogramSet(qemuMonitor *mon,
+ const char *id,
+ unsigned int *boundaries,
+ unsigned int *boundaries_read,
+ unsigned int *boundaries_write,
+ unsigned int *boundaries_zone,
+ unsigned int *boundaries_flush);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index edeea22ee0..45f690d9e2 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -9130,3 +9130,63 @@ qemuMonitorJSONBlockdevSetActive(qemuMonitor *mon,
return qemuMonitorJSONCheckError(cmd, reply);
}
+
+
+static virJSONValue *
+qemuMonitorJSONBlockLatencyHistogramBoundary(unsigned int *bound)
+{
+ g_autoptr(virJSONValue) ret = virJSONValueNewArray();
+
+ if (!bound)
+ return NULL;
+
+ for (; *bound > 0; bound++) {
+ g_autoptr(virJSONValue) val = virJSONValueNewNumberUint(*bound);
+
+ /* the only error is if the first argument is not an array */
+ ignore_value(virJSONValueArrayAppend(ret, &val));
+ }
+
+ return g_steal_pointer(&ret);
+}
+
+
+int
+qemuMonitorJSONBlockLatencyHistogramSet(qemuMonitor *mon,
+ const char *id,
+ unsigned int *boundaries,
+ unsigned int *boundaries_read,
+ unsigned int *boundaries_write,
+ unsigned int *boundaries_zone,
+ unsigned int *boundaries_flush)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+
+ g_autoptr(virJSONValue) bound = NULL;
+ g_autoptr(virJSONValue) bound_read = NULL;
+ g_autoptr(virJSONValue) bound_write = NULL;
+ g_autoptr(virJSONValue) bound_zone = NULL;
+ g_autoptr(virJSONValue) bound_flush = NULL;
+
+ bound = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries);
+ bound_read = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries_read);
+ bound_write = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries_write);
+ bound_zone = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries_zone);
+ bound_flush = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries_flush);
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("block-latency-histogram-set",
+ "s:id", id,
+ "A:boundaries", &bound,
+ "A:boundaries-read", &bound_read,
+ "A:boundaries-write", &bound_write,
+ "A:boundaries-zap", &bound_zone,
+ "A:boundaries-flush", &bound_flush,
+ NULL)))
+ return -1;
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ return -1;
+
+ return qemuMonitorJSONCheckError(cmd, reply);
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index db9160eb68..b418f70048 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -815,3 +815,12 @@ int
qemuMonitorJSONBlockdevSetActive(qemuMonitor *mon,
const char *nodename,
bool active);
+
+int
+qemuMonitorJSONBlockLatencyHistogramSet(qemuMonitor *mon,
+ const char *id,
+ unsigned int *boundaries,
+ unsigned int *boundaries_read,
+ unsigned int *boundaries_write,
+ unsigned int *boundaries_zone,
+ unsigned int *boundaries_flush);
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index bfe81739a7..1c1aaaa586 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -1130,6 +1130,14 @@ GEN_TEST_FUNC(qemuMonitorJSONSetAction,
GEN_TEST_FUNC(qemuMonitorJSONSetLaunchSecurityState, "sev_secret_header",
"sev_secret", 0, true)
+unsigned int testHistogramBoundaries[] = {10, 30, 50, 0};
+GEN_TEST_FUNC(qemuMonitorJSONBlockLatencyHistogramSet, "devid",
+ testHistogramBoundaries,
+ testHistogramBoundaries,
+ testHistogramBoundaries,
+ testHistogramBoundaries,
+ testHistogramBoundaries)
+
static int
testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque)
{
@@ -2958,6 +2966,7 @@ mymain(void)
DO_TEST_GEN(qemuMonitorJSONBlockJobCancel);
DO_TEST_GEN(qemuMonitorJSONSetAction);
DO_TEST_GEN(qemuMonitorJSONSetLaunchSecurityState);
+ DO_TEST_GEN(qemuMonitorJSONBlockLatencyHistogramSet);
DO_TEST(qemuMonitorJSONGetBalloonInfo);
DO_TEST(qemuMonitorJSONGetBlockInfo);
DO_TEST(qemuMonitorJSONGetAllBlockStatsInfo);
--
2.53.0

View File

@ -1,173 +0,0 @@
From 0722d1d58171ca59ec1852026cf6df0faa0d9312 Mon Sep 17 00:00:00 2001
Message-ID: <0722d1d58171ca59ec1852026cf6df0faa0d9312.1770203422.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 20:07:32 +0100
Subject: [PATCH] qemu: monitor: Detect list of bitmaps from 'qcow2' format
specific data
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We currently probe dirty block tracking bitmaps by looking at the loaded
ones ('dirty-bitmaps'). Unfortunately those may not yet be populated on
incoming migration when the image was not yet activated, but we need to
know which ones are stored in the image so that we don't migrate those
explicitly, which would fail.
Load the list of bitmaps in a qcow2 image from the format specific data,
which is already loaded at that point.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit b2fe3465de1db033e436f38fdd24648c8c884a3d)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
src/qemu/qemu_monitor.h | 4 ++++
src/qemu/qemu_monitor_json.c | 17 +++++++++++++++++
tests/qemublocktest.c | 11 +++++++++++
tests/qemublocktestdata/bitmap/snapshots.out | 5 +++++
tests/qemublocktestdata/bitmap/synthetic.out | 4 ++++
5 files changed, 41 insertions(+)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d096f474c1..041aa7bc12 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -893,8 +893,12 @@ struct _qemuBlockNamedNodeData {
unsigned long long capacity;
unsigned long long physical;
+ /* Information about change block tracking bitmaps which are active and loaded */
qemuBlockNamedNodeDataBitmap **bitmaps;
size_t nbitmaps;
+ /* With qcow2 we have also a separate list of bitmaps present in the image
+ * but not yet activated, which happens when starting qemu during migration */
+ char **qcow2bitmaps;
/* hash table indexed by snapshot name containing data about snapshots
* (qemuBlockNamedNodeDataSnapshot) */
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 494d7ef515..401a28ff9a 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2730,6 +2730,7 @@ qemuMonitorJSONBlockNamedNodeDataFree(qemuBlockNamedNodeData *data)
qemuMonitorJSONBlockNamedNodeDataBitmapFree(data->bitmaps[i]);
g_clear_pointer(&data->snapshots, g_hash_table_unref);
g_free(data->bitmaps);
+ g_strfreev(data->qcow2bitmaps);
g_free(data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuBlockNamedNodeData, qemuMonitorJSONBlockNamedNodeDataFree);
@@ -2854,6 +2855,9 @@ qemuMonitorJSONBlockGetNamedNodeDataWorker(size_t pos G_GNUC_UNUSED,
virJSONValue *qcow2props = virJSONValueObjectGetObject(format_specific, "data");
if (qcow2props) {
+ virJSONValue *bmp;
+ size_t nbmp;
+
if (STREQ_NULLABLE(virJSONValueObjectGetString(qcow2props, "compat"), "0.10"))
ent->qcow2v2 = true;
@@ -2862,6 +2866,19 @@ qemuMonitorJSONBlockGetNamedNodeDataWorker(size_t pos G_GNUC_UNUSED,
ignore_value(virJSONValueObjectGetBoolean(qcow2props, "data-file-raw",
&ent->qcow2dataFileRaw));
+
+ if ((bmp = virJSONValueObjectGetArray(qcow2props, "bitmaps")) &&
+ ((nbmp = virJSONValueArraySize(bmp)) > 0)) {
+ size_t i;
+
+ ent->qcow2bitmaps = g_new0(char *, nbmp + 1);
+
+ for (i = 0; i < nbmp; i++) {
+ virJSONValue *b = virJSONValueArrayGet(bmp, i);
+
+ ent->qcow2bitmaps[i] = g_strdup(virJSONValueObjectGetString(b, "name"));
+ }
+ }
}
}
diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
index 51d9268cdd..18ec90edf5 100644
--- a/tests/qemublocktest.c
+++ b/tests/qemublocktest.c
@@ -600,6 +600,17 @@ testQemuDetectBitmapsWorker(void *payload,
bitmap->granularity, bitmap->dirtybytes);
}
+ if (data->qcow2bitmaps) {
+ char **b;
+
+ virBufferAddLit(buf, "qcow2 bitmaps:");
+
+ for (b = data->qcow2bitmaps; *b; b++)
+ virBufferAsprintf(buf, " %s", *b);
+
+ virBufferAddLit(buf, "\n");
+ }
+
if (data->snapshots) {
g_autofree virHashKeyValuePair *snaps = virHashGetItems(data->snapshots, NULL, true);
virHashKeyValuePair *n;
diff --git a/tests/qemublocktestdata/bitmap/snapshots.out b/tests/qemublocktestdata/bitmap/snapshots.out
index 29c586be7e..dedd77465c 100644
--- a/tests/qemublocktestdata/bitmap/snapshots.out
+++ b/tests/qemublocktestdata/bitmap/snapshots.out
@@ -4,21 +4,26 @@ libvirt-1-format:
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: current c b a d
libvirt-1-storage:
libvirt-2-format:
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: d a b c
libvirt-2-storage:
libvirt-3-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: c b a
libvirt-3-storage:
libvirt-4-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: a
libvirt-4-storage:
libvirt-5-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: a
libvirt-5-storage:
diff --git a/tests/qemublocktestdata/bitmap/synthetic.out b/tests/qemublocktestdata/bitmap/synthetic.out
index 2f4ae2b217..0a47a90107 100644
--- a/tests/qemublocktestdata/bitmap/synthetic.out
+++ b/tests/qemublocktestdata/bitmap/synthetic.out
@@ -6,17 +6,21 @@ libvirt-1-format:
top-inactive: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
top-transient: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
top-transient-inactive: record:0 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: current
libvirt-1-storage:
libvirt-2-format:
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: d
libvirt-2-storage:
libvirt-3-format:
b: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: c b
libvirt-3-storage:
libvirt-4-format:
libvirt-4-storage:
libvirt-5-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: a
libvirt-5-storage:
--
2.52.0

View File

@ -1,168 +0,0 @@
From e02f5e7ca63bdaaec62c2fffa681b9354bee0792 Mon Sep 17 00:00:00 2001
Message-ID: <e02f5e7ca63bdaaec62c2fffa681b9354bee0792.1771336681.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 29 Jan 2026 14:08:18 +0100
Subject: [PATCH] qemu: monitor: Extract block latency histogram stats into
'qemuBlockStats'
Extract the 'rd_latency_histogram', 'wr_latency_histogram',
'zone_append_latency_histogram', and 'flush_latency_histogram' stats
objects into our internal data.
Rather than storing 'boundaries' between bins we store them as start
points.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 1c77d396ea9704eae09d7fea160cfd1a897beaf3)
https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2]
---
src/qemu/qemu_monitor.c | 20 +++++++++++++
src/qemu/qemu_monitor.h | 18 ++++++++++++
src/qemu/qemu_monitor_json.c | 55 ++++++++++++++++++++++++++++++++++++
3 files changed, 93 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 504500c864..cdd08004fb 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1986,6 +1986,26 @@ qemuBlockStatsFinalize(GObject *object)
g_free(stats->limits);
g_free(stats->timed_stats);
+ if (stats->histogram_read) {
+ g_free(stats->histogram_read->bins);
+ g_free(stats->histogram_read);
+ }
+
+ if (stats->histogram_write) {
+ g_free(stats->histogram_write->bins);
+ g_free(stats->histogram_write);
+ }
+
+ if (stats->histogram_zone) {
+ g_free(stats->histogram_zone->bins);
+ g_free(stats->histogram_zone);
+ }
+
+ if (stats->histogram_flush) {
+ g_free(stats->histogram_flush->bins);
+ g_free(stats->histogram_flush);
+ }
+
G_OBJECT_CLASS(qemu_block_stats_parent_class)->finalize(object);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 041aa7bc12..238f7be875 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -806,6 +806,18 @@ struct qemuBlockStatsLimits {
};
+struct qemuBlockStatsLatencyHistogramBin {
+ unsigned long long start;
+ unsigned long long value;
+};
+
+
+struct qemuBlockStatsLatencyHistogram {
+ struct qemuBlockStatsLatencyHistogramBin *bins;
+ size_t nbins;
+};
+
+
struct qemuBlockStatsTimed {
unsigned long long interval_length;
@@ -858,6 +870,12 @@ struct _qemuBlockStats {
/* block accounting/timed stats from qemu - one entry per interval configured */
size_t n_timed_stats;
struct qemuBlockStatsTimed *timed_stats;
+
+ /* latency histograms */
+ struct qemuBlockStatsLatencyHistogram *histogram_read;
+ struct qemuBlockStatsLatencyHistogram *histogram_write;
+ struct qemuBlockStatsLatencyHistogram *histogram_zone;
+ struct qemuBlockStatsLatencyHistogram *histogram_flush;
};
G_DECLARE_FINAL_TYPE(qemuBlockStats, qemu_block_stats, QEMU, BLOCK_STATS, GObject);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 401a28ff9a..edeea22ee0 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2425,6 +2425,52 @@ qemuMonitorJSONBlockStatsCollectDataTimed(virJSONValue *timed_stats,
}
+static void
+qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(virJSONValue *stats,
+ const char *histogram_field,
+ struct qemuBlockStatsLatencyHistogram **histogram_data)
+{
+ virJSONValue *hist;
+ virJSONValue *hist_bins;
+ virJSONValue *hist_bounds;
+ g_autofree struct qemuBlockStatsLatencyHistogramBin *bins = NULL;
+ size_t nbins = 0;
+ size_t i;
+
+ if (!(hist = virJSONValueObjectGetObject(stats, histogram_field)))
+ return;
+
+ if (!(hist_bins = virJSONValueObjectGetArray(hist, "bins")) ||
+ !(hist_bounds = virJSONValueObjectGetArray(hist, "boundaries")) ||
+ virJSONValueArraySize(hist_bins) != (virJSONValueArraySize(hist_bounds) + 1)) {
+ VIR_DEBUG("malformed latency histogram container");
+ return;
+ }
+
+ nbins = virJSONValueArraySize(hist_bins);
+ bins = g_new0(struct qemuBlockStatsLatencyHistogramBin, nbins);
+
+ for (i = 0; i < nbins; i++) {
+ virJSONValue *bin = virJSONValueArrayGet(hist_bins, i);
+ virJSONValue *bound = NULL;
+
+ if (i > 0)
+ bound = virJSONValueArrayGet(hist_bounds, i - 1);
+
+ if (!bin ||
+ virJSONValueGetNumberUlong(bin, &(bins[i].value)) < 0 ||
+ (bound && virJSONValueGetNumberUlong(bound, &(bins[i].start)) < 0)) {
+ VIR_DEBUG("malformed latency histogram container");
+ return;
+ }
+ }
+
+ *histogram_data = g_new0(struct qemuBlockStatsLatencyHistogram, 1);
+ (*histogram_data)->bins = g_steal_pointer(&bins);
+ (*histogram_data)->nbins = nbins;
+}
+
+
static qemuBlockStats *
qemuMonitorJSONBlockStatsCollectData(virJSONValue *dev,
int *nstats)
@@ -2469,6 +2515,15 @@ qemuMonitorJSONBlockStatsCollectData(virJSONValue *dev,
bstats->wr_highest_offset_valid = true;
}
+ qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "rd_latency_histogram",
+ &bstats->histogram_read);
+ qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "wr_latency_histogram",
+ &bstats->histogram_write);
+ qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "zone_append_latency_histogram",
+ &bstats->histogram_zone);
+ qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "flush_latency_histogram",
+ &bstats->histogram_flush);
+
if ((timed_stats = virJSONValueObjectGetArray(stats, "timed_stats")) &&
virJSONValueArraySize(timed_stats) > 0)
qemuMonitorJSONBlockStatsCollectDataTimed(timed_stats, bstats);
--
2.53.0

View File

@ -1,247 +0,0 @@
From 68a23646ba165aa45d3811d626885054ae9d9299 Mon Sep 17 00:00:00 2001
Message-ID: <68a23646ba165aa45d3811d626885054ae9d9299.1770383182.git.jdenemar@redhat.com>
From: Nathan Chen <nathanc@nvidia.com>
Date: Fri, 30 Jan 2026 10:59:15 -0800
Subject: [PATCH] qemu: open VFIO FDs from libvirt backend
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Open VFIO FDs from libvirt backend without exposing
these FDs to XML users, i.e. one per iommufd hostdev
for /dev/vfio/devices/vfioX, and pass the FD to qemu
command line.
Suggested-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 f6230804727df834da27370e835204672218ab23)
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/libvirt_private.syms | 1 +
src/qemu/qemu_command.c | 21 +++++++++++
src/qemu/qemu_process.c | 78 ++++++++++++++++++++++++++++++++++++++++
src/util/virpci.c | 39 ++++++++++++++++++++
src/util/virpci.h | 2 ++
5 files changed, 141 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 66261ed6cf..e2a7a16347 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3162,6 +3162,7 @@ virPCIDeviceGetStubDriverName;
virPCIDeviceGetStubDriverType;
virPCIDeviceGetUnbindFromStub;
virPCIDeviceGetUsedBy;
+virPCIDeviceGetVfioPath;
virPCIDeviceGetVPD;
virPCIDeviceHasPCIExpressLink;
virPCIDeviceIsAssignable;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1fb31d1721..83935e82c3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4803,6 +4803,18 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
NULL) < 0)
return NULL;
+ if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
+ 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 (qemuBuildDeviceAddressProps(props, def, dev->info) < 0)
return NULL;
@@ -5247,6 +5259,15 @@ qemuBuildHostdevCommandLine(virCommand *cmd,
if (qemuCommandAddExtDevice(cmd, hostdev->info, def, qemuCaps) < 0)
return -1;
+ 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);
+ }
+ }
+
if (!(devprops = qemuBuildPCIHostdevDevProps(def, hostdev)))
return -1;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0e50cd1ccc..1ac57a6321 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -103,6 +103,7 @@
#include "storage_source.h"
#include "backup_conf.h"
#include "storage_file_probe.h"
+#include "virpci.h"
#include "logging/log_manager.h"
#include "logging/log_protocol.h"
@@ -7671,6 +7672,81 @@ qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm,
return 0;
}
+/**
+ * qemuProcessOpenVfioDeviceFd:
+ * @hostdev: host device definition
+ * @vfioFd: returned file descriptor
+ *
+ * Opens the VFIO device file descriptor for a hostdev.
+ *
+ * Returns: FD on success, -1 on failure
+ */
+static int
+qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
+{
+ g_autofree char *vfioPath = NULL;
+ int fd = -1;
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
+ hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("VFIO FD only supported for PCI hostdevs"));
+ return -1;
+ }
+
+ if (virPCIDeviceGetVfioPath(&hostdev->source.subsys.u.pci.addr, &vfioPath) < 0)
+ return -1;
+
+ VIR_DEBUG("Opening VFIO device %s", vfioPath);
+
+ if ((fd = open(vfioPath, O_RDWR | O_CLOEXEC)) < 0) {
+ if (errno == ENOENT) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("VFIO device %1$s not found - ensure device is bound to vfio-pci driver"),
+ vfioPath);
+ } else {
+ virReportSystemError(errno,
+ _("cannot open VFIO device %1$s"), vfioPath);
+ }
+ return -1;
+ }
+
+ VIR_DEBUG("Opened VFIO device FD %d for %s", fd, vfioPath);
+ return fd;
+}
+
+/**
+ * qemuProcessOpenVfioFds:
+ * @vm: domain object
+ *
+ * Opens all necessary VFIO file descriptors for the domain.
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int
+qemuProcessOpenVfioFds(virDomainObj *vm)
+{
+ size_t i;
+
+ /* Check if we have any hostdevs that need VFIO FDs */
+ for (i = 0; i < vm->def->nhostdevs; i++) {
+ virDomainHostdevDef *hostdev = vm->def->hostdevs[i];
+ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
+
+ 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) {
+ /* Open VFIO device FD */
+ hostdevPriv->vfioDeviceFd = qemuProcessOpenVfioDeviceFd(hostdev);
+ if (hostdevPriv->vfioDeviceFd == -1)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
/**
* qemuProcessPrepareHost:
* @driver: qemu driver
@@ -7726,6 +7802,8 @@ qemuProcessPrepareHost(virQEMUDriver *driver,
hostdev_flags |= VIR_HOSTDEV_COLD_BOOT;
if (qemuHostdevPrepareDomainDevices(driver, vm->def, hostdev_flags) < 0)
return -1;
+ if (qemuProcessOpenVfioFds(vm) < 0)
+ return -1;
VIR_DEBUG("Preparing chr device backends");
if (qemuProcessPrepareHostBackendChardev(vm) < 0)
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 90617e69c6..2348a98003 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -3320,3 +3320,42 @@ virPCIDeviceAddressFree(virPCIDeviceAddress *address)
{
g_free(address);
}
+
+/**
+ * virPCIDeviceGetVfioPath:
+ * @addr: host device PCI address
+ * @vfioPath: returned VFIO device path
+ *
+ * Constructs the VFIO device path for a PCI hostdev.
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+int
+virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr,
+ char **vfioPath)
+{
+ g_autofree char *addrStr = NULL;
+ g_autofree char *sysfsPath = NULL;
+ g_autoptr(DIR) dir = NULL;
+ struct dirent *entry = NULL;
+
+ *vfioPath = NULL;
+ addrStr = virPCIDeviceAddressAsString(addr);
+
+ /* Look in device's vfio-dev subdirectory */
+ sysfsPath = g_strdup_printf("/sys/bus/pci/devices/%s/vfio-dev/", addrStr);
+
+ if (virDirOpen(&dir, sysfsPath) == 1) {
+ while (virDirRead(dir, &entry, sysfsPath) > 0) {
+ if (STRPREFIX(entry->d_name, "vfio")) {
+ *vfioPath = g_strdup_printf("/dev/vfio/devices/%s", entry->d_name);
+ return 0;
+ }
+ }
+ }
+
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot find VFIO device for PCI device %1$s"),
+ addrStr);
+ return -1;
+}
diff --git a/src/util/virpci.h b/src/util/virpci.h
index fc538566e1..24ede10755 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -296,6 +296,8 @@ void virPCIEDeviceInfoFree(virPCIEDeviceInfo *dev);
void virPCIDeviceAddressFree(virPCIDeviceAddress *address);
+int virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, char **vfioPath);
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDevice, virPCIDeviceFree);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDeviceAddress, virPCIDeviceAddressFree);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIEDeviceInfo, virPCIEDeviceInfoFree);
--
2.52.0

View File

@ -1,175 +0,0 @@
From a444918da5bd01fc11793c82ad33308892777c3a Mon Sep 17 00:00:00 2001
Message-ID: <a444918da5bd01fc11793c82ad33308892777c3a.1770383182.git.jdenemar@redhat.com>
From: Nathan Chen <nathanc@nvidia.com>
Date: Fri, 30 Jan 2026 10:59:16 -0800
Subject: [PATCH] qemu: open iommufd FD from libvirt backend
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Open iommufd FD from libvirt backend without exposing
these FDs to XML users, i.e. one per domain for
/dev/iommu, and pass the FD to qemu command line. Set
per-process memory accounting for iommufd instead of
the default per-user memory accounting.
Suggested-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 2f0999a161910e3992458902ce90d37f8b8f2642)
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_command.c | 13 +++++++++++--
src/qemu/qemu_domain.c | 1 +
src/qemu/qemu_domain.h | 2 ++
src/qemu/qemu_process.c | 43 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 83935e82c3..f355352018 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5342,9 +5342,13 @@ qemuBuildHostdevCommandLine(virCommand *cmd,
static int
qemuBuildIOMMUFDCommandLine(virCommand *cmd,
- const virDomainDef *def)
+ const virDomainDef *def,
+ virDomainObj *vm)
{
size_t i;
+ qemuDomainObjPrivate *priv = vm->privateData;
+ g_autofree char *fdstr = g_strdup_printf("%d", priv->iommufd);
+
for (i = 0; i < def->nhostdevs; i++) {
virDomainHostdevDef *hostdev = def->hostdevs[i];
@@ -5363,8 +5367,13 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd,
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;
@@ -10990,7 +10999,7 @@ qemuBuildCommandLine(virDomainObj *vm,
if (qemuBuildRedirdevCommandLine(cmd, def, qemuCaps) < 0)
return NULL;
- if (qemuBuildIOMMUFDCommandLine(cmd, def) < 0)
+ if (qemuBuildIOMMUFDCommandLine(cmd, def, vm) < 0)
return NULL;
if (qemuBuildHostdevCommandLine(cmd, def, qemuCaps) < 0)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 3366214677..8e1ebe7799 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2042,6 +2042,7 @@ qemuDomainObjPrivateAlloc(void *opaque)
priv->blockjobs = virHashNew(virObjectUnref);
priv->fds = virHashNew(g_object_unref);
+ priv->iommufd = -1;
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 88c8416aa4..3361e97315 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -264,6 +264,8 @@ struct _qemuDomainObjPrivate {
/* named file descriptor groups associated with the VM */
GHashTable *fds;
+ int iommufd;
+
char *memoryBackingDir;
};
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1ac57a6321..d8f0c78fd1 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -104,6 +104,7 @@
#include "backup_conf.h"
#include "storage_file_probe.h"
#include "virpci.h"
+#include "viriommufd.h"
#include "logging/log_manager.h"
#include "logging/log_protocol.h"
@@ -7672,6 +7673,42 @@ qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm,
return 0;
}
+/**
+ * qemuProcessOpenIommuFd:
+ * @vm: domain object
+ * @iommuFd: returned file descriptor
+ *
+ * Opens /dev/iommu file descriptor for the VM.
+ *
+ * Returns: FD on success, -1 on failure
+ */
+static int
+qemuProcessOpenIommuFd(virDomainObj *vm)
+{
+ int fd = -1;
+
+ 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"));
+ }
+ return -1;
+ }
+
+ if (virIOMMUFDSetRLimitMode(fd, true) < 0) {
+ VIR_FORCE_CLOSE(fd);
+ return -1;
+ }
+
+ VIR_DEBUG("Opened IOMMU FD %d for domain %s", fd, vm->def->name);
+ return fd;
+}
+
/**
* qemuProcessOpenVfioDeviceFd:
* @hostdev: host device definition
@@ -7726,6 +7763,7 @@ qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
static int
qemuProcessOpenVfioFds(virDomainObj *vm)
{
+ qemuDomainObjPrivate *priv = vm->privateData;
size_t i;
/* Check if we have any hostdevs that need VFIO FDs */
@@ -7741,6 +7779,11 @@ qemuProcessOpenVfioFds(virDomainObj *vm)
hostdevPriv->vfioDeviceFd = qemuProcessOpenVfioDeviceFd(hostdev);
if (hostdevPriv->vfioDeviceFd == -1)
return -1;
+
+ /* Open IOMMU FD */
+ priv->iommufd = qemuProcessOpenIommuFd(vm);
+ if (priv->iommufd == -1)
+ return -1;
}
}
--
2.52.0

View File

@ -1,62 +0,0 @@
From 0359b5fcf870f955bbdca998e5a02261e27c40b7 Mon Sep 17 00:00:00 2001
Message-ID: <0359b5fcf870f955bbdca998e5a02261e27c40b7.1771336681.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 29 Jan 2026 11:21:38 +0100
Subject: [PATCH] qemu: process: Rename 'qemuProcessSetupDiskThrottling' to
'qemuProcessSetupDisks'
Rename the runtime disk option setup function to be universal.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 42a39d703d98e4e48f0f9c8779884b6ac107de26)
https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8]
https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2]
---
src/qemu/qemu_process.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c99bb36c93..aadfaa92b0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7964,21 +7964,19 @@ qemuProcessSetupDiskPropsRuntime(qemuMonitor *mon,
/**
- * qemuProcessSetupDiskThrottling:
+ * qemuProcessSetupDisks:
*
- * Sets up disk trottling for -blockdev via block_set_io_throttle monitor
- * command. This hack should be replaced by proper use of the 'throttle'
- * blockdev driver in qemu once it will support changing of the throttle group.
- * Same hack is done in qemuDomainAttachDiskGeneric.
+ * Sets up disk settings available only at runtime:
+ * - trottling for -blockdev via block_set_io_throttle QMP command
*/
static int
-qemuProcessSetupDiskThrottling(virDomainObj *vm,
- virDomainAsyncJob asyncJob)
+qemuProcessSetupDisks(virDomainObj *vm,
+ virDomainAsyncJob asyncJob)
{
size_t i;
int ret = -1;
- VIR_DEBUG("Setting up disk throttling for -blockdev via block_set_io_throttle");
+ VIR_DEBUG("Setting up disk config via runtime commands");
if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
return -1;
@@ -8575,7 +8573,7 @@ qemuProcessLaunch(virConnectPtr conn,
if (qemuProcessSetupBalloon(vm, asyncJob) < 0)
goto cleanup;
- if (qemuProcessSetupDiskThrottling(vm, asyncJob) < 0)
+ if (qemuProcessSetupDisks(vm, asyncJob) < 0)
goto cleanup;
/* Since CPUs were not started yet, the balloon could not return the memory
--
2.53.0

View File

@ -1,119 +0,0 @@
From 8e9dc8aed52c98c3683949dfe1127061bd9df47a Mon Sep 17 00:00:00 2001
Message-ID: <8e9dc8aed52c98c3683949dfe1127061bd9df47a.1766070439.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 1 Dec 2025 11:35:32 +0100
Subject: [PATCH] qemu: tpm: Account for possible migration without actually
sharing storage
The current logic in 'qemuTPMEmulatorBuildCommand' skips all setup if
the *location* of the data is on what we'd consider shared storage.
This means that if the location is not actually shared (e.g. it's shared
betweeh some other hosts than the two doing the migration) and the path
wasn't ever used (e.g. by migrating out) from the host where we're
migrating into the complete setup of the location would be skipped even
when it doesn't exist.
Fix the logic by skipping only some of the setup steps so that
'qemuTPMEmulatorCreateStorage' can still create the storage if it
doesn't exist.
The rest of the code then needs to take the 'created' flag returned from
'qemuTPMEmulatorCreateStorage' into account.
Fixes: 68103e9daf633b789428fedef56f816c92f6ee75
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit d56d0560946770d4364a4918cc289e6a7fe5d15c)
https://issues.redhat.com/browse/RHEL-132534
---
src/qemu/qemu_tpm.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c
index 4c9445d72c..660410bcba 100644
--- a/src/qemu/qemu_tpm.c
+++ b/src/qemu/qemu_tpm.c
@@ -158,6 +158,7 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir,
/**
* qemuTPMEmulatorCreateStorage:
* @tpm: TPM definition for an emulator type
+ * @sharedStorageMigration: VM is being migrated with possibly shared storage
* @created: a pointer to a bool that will be set to true if the
* storage was created because it did not exist yet
* @swtpm_user: The uid that needs to be able to access the directory
@@ -169,6 +170,7 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir,
*/
static int
qemuTPMEmulatorCreateStorage(virDomainTPMDef *tpm,
+ bool sharedStorageMigration,
bool *created,
uid_t swtpm_user,
gid_t swtpm_group)
@@ -187,8 +189,17 @@ qemuTPMEmulatorCreateStorage(virDomainTPMDef *tpm,
*created = false;
if (!virFileExists(source_path) ||
- virDirIsEmpty(source_path, true) > 0)
+ virDirIsEmpty(source_path, true) > 0) {
*created = true;
+ } else {
+ /* If the location exists and is shared, we don't need to create it
+ * during migration */
+ if (sharedStorageMigration) {
+ VIR_DEBUG("Skipping TPM storage creation. Path '%s' already exists and is on shared storage.",
+ source_path);
+ return 0;
+ }
+ }
if (virDirCreate(source_path, 0700, swtpm_user, swtpm_group,
VIR_DIR_CREATE_ALLOW_EXIST) < 0) {
@@ -809,16 +820,13 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
run_setup = true;
}
- /* Do not create storage and run swtpm_setup on incoming migration over
- * shared storage
- */
on_shared_storage = virFileIsSharedFS(tpm->data.emulator.source_path,
cfg->sharedFilesystems) == 1;
- if (incomingMigration && on_shared_storage)
- create_storage = false;
if (create_storage) {
- if (qemuTPMEmulatorCreateStorage(tpm, &created,
+ if (qemuTPMEmulatorCreateStorage(tpm,
+ incomingMigration && on_shared_storage,
+ &created,
cfg->swtpm_user, cfg->swtpm_group) < 0)
return NULL;
run_setup = created;
@@ -885,6 +893,9 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
/* If swtpm supports it and the TPM state is stored on shared storage,
* start swtpm with --migration release-lock-outgoing so it can migrate
* across shared storage if needed.
+ *
+ * Note that if 'created' is true, the location didn't exist so the storage
+ * is not actually shared.
*/
QEMU_DOMAIN_TPM_PRIVATE(tpm)->swtpm.can_migrate_shared_storage = false;
if (on_shared_storage &&
@@ -892,13 +903,13 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm,
virCommandAddArg(cmd, "--migration");
virCommandAddArgFormat(cmd, "release-lock-outgoing%s",
- incomingMigration ? ",incoming": "");
+ incomingMigration && !created ? ",incoming": "");
QEMU_DOMAIN_TPM_PRIVATE(tpm)->swtpm.can_migrate_shared_storage = true;
} else {
/* Report an error if there's an incoming migration across shared
* storage and swtpm does not support the --migration option.
*/
- if (incomingMigration && on_shared_storage) {
+ if (incomingMigration && on_shared_storage && !created) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
_("%1$s (on destination side) does not support the --migration option needed for migration with shared storage"),
swtpm);
--
2.52.0

View File

@ -1,68 +0,0 @@
From 2f60aff267af628839c90fe36cacbc9d5057509a Mon Sep 17 00:00:00 2001
Message-ID: <2f60aff267af628839c90fe36cacbc9d5057509a.1769699749.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 16 Jan 2026 16:38:38 +0100
Subject: [PATCH] qemuDomainSetBlockIoTuneField: Move setting of 'group_name'
out of the loop
The refactor will simplify further change which will introduce another
source for the group name.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit fa064375668df0e67b4d68fdfc4a386862026f3f)
https://issues.redhat.com/browse/RHEL-141820 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-144010 [rhel-9.8]
---
src/qemu/qemu_driver.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 194017a29a..ecfb65c535 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15173,6 +15173,7 @@ qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info,
int *eventNparams,
int *eventMaxparams)
{
+ const char *param_group_name = NULL;
size_t i;
#define SET_IOTUNE_FIELD(FIELD, BOOL, CONST) \
@@ -15218,15 +15219,8 @@ qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info,
WRITE_IOPS_SEC_MAX);
SET_IOTUNE_FIELD(size_iops_sec, SIZE_IOPS, SIZE_IOPS_SEC);
- /* NB: Cannot use macro since this is a value.s not a value.ul */
if (STREQ(param->field, VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME)) {
- info->group_name = g_strdup(param->value.s);
- *set_fields |= QEMU_BLOCK_IOTUNE_SET_GROUP_NAME;
- if (virTypedParamsAddString(eventParams, eventNparams,
- eventMaxparams,
- VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME,
- param->value.s) < 0)
- return -1;
+ param_group_name = param->value.s;
continue;
}
@@ -15244,6 +15238,16 @@ qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info,
WRITE_IOPS_SEC_MAX_LENGTH);
}
+ if (param_group_name) {
+ info->group_name = g_strdup(param_group_name);
+ *set_fields |= QEMU_BLOCK_IOTUNE_SET_GROUP_NAME;
+ if (virTypedParamsAddString(eventParams, eventNparams,
+ eventMaxparams,
+ VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME,
+ param_group_name) < 0)
+ return -1;
+ }
+
#undef SET_IOTUNE_FIELD
return 0;
--
2.52.0

View File

@ -1,75 +0,0 @@
From f44d3fa49e7f1507e93c1e9525dd0db4227809cc Mon Sep 17 00:00:00 2001
Message-ID: <f44d3fa49e7f1507e93c1e9525dd0db4227809cc.1769699749.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 16 Jan 2026 16:39:40 +0100
Subject: [PATCH] qemuDomainSetThrottleGroup: Always honour thottle group name
passed as argument
Due to the code share with 'qemuDomainSetBlockIoTune' the throttle group
setting code accepts the throttle group name also via typed parameters.
In 'qemuDomainSetThrottleGroup', this means that there are 2 ways to
pass it the throttle group name and both are handled slightly
differently. Specifically the name of the group used in the list of
groups is the name taken from the typed parameters rather than the one
passed via API. We also don't validate that they match.
Now if the name in the typed parameters is missing we'd add empty string
to the group list which would later crash when looking up the group
name.
To avoid this problem always use the name passed via argument. This is
achieved by passing it into 'qemuDomainSetBlockIoTuneFields' so that it
overrides whatever is in the typed parameters.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 0cd13906dcf15ea5709a7b253466816a1b875640)
https://issues.redhat.com/browse/RHEL-141820 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-144010 [rhel-9.8]
---
src/qemu/qemu_driver.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ecfb65c535..a6d5dd6e05 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15168,6 +15168,7 @@ static int
qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info,
virTypedParameterPtr params,
int nparams,
+ const char *group_name,
qemuBlockIoTuneSetFlags *set_fields,
virTypedParameterPtr *eventParams,
int *eventNparams,
@@ -15238,6 +15239,10 @@ qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info,
WRITE_IOPS_SEC_MAX_LENGTH);
}
+ /* The name of the throttle group passed via API always takes precedence */
+ if (group_name)
+ param_group_name = group_name;
+
if (param_group_name) {
info->group_name = g_strdup(param_group_name);
*set_fields |= QEMU_BLOCK_IOTUNE_SET_GROUP_NAME;
@@ -15385,6 +15390,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
if (qemuDomainSetBlockIoTuneFields(&info,
params,
nparams,
+ NULL,
&set_fields,
&eventParams,
&eventNparams,
@@ -20379,6 +20385,7 @@ qemuDomainSetThrottleGroup(virDomainPtr dom,
if (qemuDomainSetBlockIoTuneFields(&info,
params,
nparams,
+ groupname,
&set_fields,
&eventParams,
&eventNparams,
--
2.52.0

View File

@ -1,43 +0,0 @@
From e48225074a9179e73b8ce9a573a513e619ae0a65 Mon Sep 17 00:00:00 2001
Message-ID: <e48225074a9179e73b8ce9a573a513e619ae0a65.1769699749.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 16 Jan 2026 16:39:49 +0100
Subject: [PATCH] qemuDomainSetThrottleGroup: Don't put group name into the
'tunable' event twice
'qemuDomainSetBlockIoTuneFields' already populates the contents of the
VIR_DOMAIN_EVENT_ID_TUNABLE params with the group name so there's no
need to do it explicitly. We'd report the group name twice:
event 'tunable' for domain 'cd':
blkdeviotune.group_name: asdf
blkdeviotune.total_bytes_sec: 1234
blkdeviotune.group_name: asdf
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit adcc14e1538433ec1b2f4b103cdf641917e63242)
https://issues.redhat.com/browse/RHEL-141820 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-144010 [rhel-9.8]
---
src/qemu/qemu_driver.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a6d5dd6e05..08a547c546 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20378,10 +20378,6 @@ qemuDomainSetThrottleGroup(virDomainPtr dom,
if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0)
goto endjob;
- if (virTypedParamsAddString(&eventParams, &eventNparams, &eventMaxparams,
- VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME, groupname) < 0)
- goto endjob;
-
if (qemuDomainSetBlockIoTuneFields(&info,
params,
nparams,
--
2.52.0

View File

@ -1,38 +0,0 @@
From fee37458a1f93dc30a209ceeda1ec31847884fcf Mon Sep 17 00:00:00 2001
Message-ID: <fee37458a1f93dc30a209ceeda1ec31847884fcf.1769699749.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 16 Jan 2026 16:36:50 +0100
Subject: [PATCH] qemuDomainSetThrottleGroup: Enforce non-zero 'groupname'
string length
Having a name of 0 characters makes no sense. Reject it.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit abcdc9511b1c78df7dcdee9f01c6d55651d3a424)
https://issues.redhat.com/browse/RHEL-141820 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-144010 [rhel-9.8]
---
src/qemu/qemu_driver.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f2e024dae3..194017a29a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20345,6 +20345,12 @@ qemuDomainSetThrottleGroup(virDomainPtr dom,
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG, -1);
+ if (strlen(groupname) == 0) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("'groupname' parameter string must have non-zero length"));
+ return -1;
+ }
+
if (qemuDomainValidateBlockIoTune(params, nparams) < 0)
return -1;
--
2.52.0

View File

@ -1,98 +0,0 @@
From bbd0fde5f840726928cdcd06691da13f1093c02e Mon Sep 17 00:00:00 2001
Message-ID: <bbd0fde5f840726928cdcd06691da13f1093c02e.1770203422.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 17:28:48 +0100
Subject: [PATCH] qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Always consider
offered bitmaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Consider bitmaps for incoming migration regardless of non-shared storage
flag.
When bitmaps are offered from the source, consult the local image if the
bitmap is present and if not accept migration. Migration of bitmaps
which exist in the qcow2 metadata is skipped because qemu rejects such
setup (although handles it correctly in case of shared storage setup;
see below).
This allows bitmap propagation for cases when the qcow2 image is not
actually shared between destinations but the data is (using the
data_file feature).
At the same time this preserves existing bitmap handling semantics for
other cases. Specifically qemu, in case of shared storage properly
propagates the bitmap which was already recorded in the qcow2 metadata
on disk even if libvirt doesn't instruct migration, yet tolerates
migration instruction if the file is not yet recorded in the on-disk
metadata. In both cases the contents are preserved correctly.
When storage is not shared (which includes even cases when we migrate
it via NBD) it's expected that the bitmaps don't exist on the
destination and thus all will be picked for migration. We can also
infer that this wasn't ever a problem by the fact that the code skipping
migration of existing bitmaps was broken until recently, and qemu
would refuse such config.
I've tested all the above scenarios including verifying that the
resulting bitmaps capture dirtied regions before and after migration.
For testing this the following command is useful:
virsh qemu-monitor-command --domain DOMNAME --hmp 'qemu-io -d /machine/peripheral/virtio-disk0/virtio-backend "write -P 0xcc 4M 1M"'
Which simulates a write from the guest side without the need to interact
with the guest OS.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit bf34b90bb4e39b3a2fd22a5531f5ea5a95681015)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
src/qemu/qemu_migration.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 755b9a5e1a..2a4df1191d 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3183,7 +3183,6 @@ qemuMigrationDstPrepare(virQEMUDriver *driver,
* @vm: domain object
* @mig: migration cookie
* @migParams: migration parameters
- * @flags: migration flags
*
* Checks whether block dirty bitmaps offered by the migration source are
* to be migrated (e.g. they don't exist, the destination is compatible etc)
@@ -3194,16 +3193,13 @@ qemuMigrationDstPrepare(virQEMUDriver *driver,
static int
qemuMigrationDstPrepareAnyBlockDirtyBitmaps(virDomainObj *vm,
qemuMigrationCookie *mig,
- qemuMigrationParams *migParams,
- unsigned int flags)
+ qemuMigrationParams *migParams)
{
g_autoptr(virJSONValue) mapping = NULL;
g_autoptr(GHashTable) blockNamedNodeData = NULL;
GSList *nextdisk;
- if (!mig->nbd ||
- !mig->blockDirtyBitmaps ||
- !(flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)))
+ if (!mig->blockDirtyBitmaps)
return 0;
if (qemuMigrationCookieBlockDirtyBitmapsMatchDisks(vm->def, mig->blockDirtyBitmaps) < 0)
@@ -3350,7 +3346,7 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver,
goto error;
}
- if (qemuMigrationDstPrepareAnyBlockDirtyBitmaps(vm, mig, migParams, flags) < 0)
+ if (qemuMigrationDstPrepareAnyBlockDirtyBitmaps(vm, mig, migParams) < 0)
goto error;
if (qemuMigrationParamsCheck(vm, VIR_ASYNC_JOB_MIGRATION_IN, migParams,
--
2.52.0

View File

@ -1,68 +0,0 @@
From b99fb51812da73df754151c59c259d15fa654168 Mon Sep 17 00:00:00 2001
Message-ID: <b99fb51812da73df754151c59c259d15fa654168.1770203422.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 19:22:08 +0100
Subject: [PATCH] qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Fix check for
existing bitmaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On incoming migration qemu doesn't load bitmaps into memory (which makes
them available under the 'dirty-bitmaps' field which we parse as the
'bitmaps' array in 'qemuBlockNamedNodeData') until after actually
resuming CPUs, thus the check for existing bitmaps never actually
worked.
We need to check the 'qcow2bitmaps' field instead which is populated
from the qcow2 headers prior to activating the image.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 0c75fc1747f039bf878ceab69cf12482ebb14095)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
src/qemu/qemu_migration.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 9059f9aa3a..723e131c98 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3227,6 +3227,8 @@ qemuMigrationDstPrepareAnyBlockDirtyBitmaps(virDomainObj *vm,
qemuBlockNamedNodeData *nodedata;
GSList *nextbitmap;
+ VIR_DEBUG("offer migrate bitmaps for '%s'", disk->target);
+
if (!(nodedata = virHashLookup(blockNamedNodeData, disk->nodename))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to find data for block node '%1$s'"),
@@ -3243,18 +3245,14 @@ qemuMigrationDstPrepareAnyBlockDirtyBitmaps(virDomainObj *vm,
for (nextbitmap = disk->bitmaps; nextbitmap; nextbitmap = nextbitmap->next) {
qemuMigrationBlockDirtyBitmapsDiskBitmap *bitmap = nextbitmap->data;
- size_t k;
/* don't migrate into existing bitmaps */
- for (k = 0; k < nodedata->nbitmaps; k++) {
- if (STREQ(bitmap->bitmapname, nodedata->bitmaps[k]->name)) {
- bitmap->skip = true;
- break;
- }
- }
+ if (nodedata->qcow2bitmaps)
+ bitmap->skip = g_strv_contains((const char **) nodedata->qcow2bitmaps, bitmap->bitmapname);
+
+ VIR_DEBUG("offer migrate bitmap '%s' disk '%s' -> skip: '%d'",
+ bitmap->bitmapname, disk->target, bitmap->skip);
- if (bitmap->skip)
- continue;
}
}
--
2.52.0

View File

@ -1,56 +0,0 @@
From 5a7cc07af8355ae117d04d357bd8b694fc2af091 Mon Sep 17 00:00:00 2001
Message-ID: <5a7cc07af8355ae117d04d357bd8b694fc2af091.1769173967.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 12 Jan 2026 10:54:38 +0100
Subject: [PATCH] qemuSecurityMoveImageMetadata: Move seclabels only to
virStorageSource of same type
The concept of moving a seclabel is used e.g. when a new image is
introduced to the backing chain (or one of the existing ones becomes
active during block commit). What it does is that it moves the metedata
remembering the original seclabel to the new image.
That idea works reasonably well if both the original and new image are
of same type e.g. a file, where they have comparable seclabel.
It breaks down though when you e.g. create a snapshot stored in a 'file'
on top of a disk originally backed by a 'block' storage source, since
the seclabels differ quite siginificantly.
This patch restricts the seclabel move in qemuSecurityMoveImageMetadata
to happen only if the storage sources are of same type to avoid the
issue. This means that the seclabels will not be remebered and will be
restored to the default but it's better than to transfer wrong labels.
Resolves: https://issues.redhat.com/browse/RHEL-114412
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 37d51c0d27692a245d7a5eeeef57748e7574de4b)
---
src/qemu/qemu_security.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c
index 6bb0f9170d..84cb981a96 100644
--- a/src/qemu/qemu_security.c
+++ b/src/qemu/qemu_security.c
@@ -201,6 +201,16 @@ qemuSecurityMoveImageMetadata(virQEMUDriver *driver,
if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
pid = vm->pid;
+ /* Moving seclabel metadata makes sense only when 'src' and 'dst' are of
+ * the same type. Otherwise 'dst' could end up with a seclabel that doesn't
+ * make sense for it (e.g. a seclabel originating from a block device /dev
+ * node moved to a file), once the seclabels are restored for it */
+ if (src && dst && src->type != dst->type) {
+ VIR_DEBUG("dropping security label metadata instead of moving it from '%s' to '%s' due to type mismatch",
+ NULLSTR(src->path), NULLSTR(dst->path));
+ dst = NULL;
+ }
+
return virSecurityManagerMoveImageMetadata(driver->securityManager,
cfg->sharedFilesystems,
pid, src, dst);
--
2.52.0

View File

@ -1,48 +0,0 @@
From 744a5361793546bed7976acebed669b1928e8c9d Mon Sep 17 00:00:00 2001
Message-ID: <744a5361793546bed7976acebed669b1928e8c9d.1769699749.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 23 Jan 2026 08:42:50 +0100
Subject: [PATCH] qemuSnapshotDiskHasBackingDisk: Avoid call of
virStorageSourceIsSameLocation with NULL argument
When the 'backingStore' pointer is not populated the function calls
'virStorageSourceGetMetadata' to try to populate it but if the on-disk
metadata doesn't have a backing image (e.g. if it's the 'base' image of
the chain) the 'backingStore' or the metadata fetcher fails the pointer
will still be NULL.
The function then calls 'virStorageSourceIsSameLocation' but the
internal functions for dealing with storage sources don't handle NULL
gracefully.
Since the code calling 'qemu-img' based on the data detected here
doesn't actually raise errors if the operations fail there's no point
in raising errors here either.
Closes: https://gitlab.com/libvirt/libvirt/-/issues/844
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit b43aee9cc904961e0f18156c3c84a3e460bdb7be)
https://issues.redhat.com/browse/RHEL-144089 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-144090 [rhel-9.8]
---
src/qemu/qemu_snapshot.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 302775af92..dfc3f449e3 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3135,7 +3135,8 @@ qemuSnapshotDiskHasBackingDisk(void *payload,
if (!disk->src->backingStore)
ignore_value(virStorageSourceGetMetadata(disk->src, uid, gid, 1, false));
- if (virStorageSourceIsSameLocation(disk->src->backingStore, iterdata->diskSrc)) {
+ if (disk->src->backingStore &&
+ virStorageSourceIsSameLocation(disk->src->backingStore, iterdata->diskSrc)) {
struct _qemuSnapshotDisksWithBackingStoreData *data =
g_new0(struct _qemuSnapshotDisksWithBackingStoreData, 1);
--
2.52.0

View File

@ -1,75 +0,0 @@
From 78e9a796a24c4f60c162ee3643c4a251c97ab1d2 Mon Sep 17 00:00:00 2001
Message-ID: <78e9a796a24c4f60c162ee3643c4a251c97ab1d2.1769699749.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 26 Jan 2026 16:39:24 +0100
Subject: [PATCH] qemuSnapshotDiskHasBackingDisk: Use proper 'max_depth' when
calling 'virStorageSourceGetMetadata'
The 'max_depth' argument of 'virStorageSourceGetMetadata' doesn't just
limit how far the function goes but also fails completely if the chain
is deeper than the passed value.
In 'qemuSnapshotDiskHasBackingDisk' we only care about finding the
backing image, so just one level below, the passed path, but due to the
above setting '1' as max_depth will make the function simply fail every
time.
Extract and reuse QEMU_DOMAIN_STORAGE_SOURCE_CHAIN_MAX_DEPTH as the
detection depth. While '200' layers is overkill for this code, we also
start a full qemu instance just to delete an snapshot so this doens't
matter and still protects from self-referential images.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 6bcdf4ee59595041c76ed2339c45503723400737)
https://issues.redhat.com/browse/RHEL-144089 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-144090 [rhel-9.8]
---
src/qemu/qemu_domain.c | 2 --
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_snapshot.c | 4 +++-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index ac56fc7cb4..486a0e7913 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -6297,8 +6297,6 @@ qemuDomainStorageAlias(const char *device, int depth)
}
-#define QEMU_DOMAIN_STORAGE_SOURCE_CHAIN_MAX_DEPTH 200
-
/**
* qemuDomainStorageSourceValidateDepth:
* @src: storage source chain to validate
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 3396f929fd..b9bb338682 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -706,6 +706,7 @@ int qemuDomainCheckDiskStartupPolicy(virQEMUDriver *driver,
size_t diskIndex,
bool cold_boot);
+#define QEMU_DOMAIN_STORAGE_SOURCE_CHAIN_MAX_DEPTH 200
int qemuDomainStorageSourceValidateDepth(virStorageSource *src,
int add,
const char *diskdst);
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 942ba0d437..c23add5103 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3133,7 +3133,9 @@ qemuSnapshotDiskHasBackingDisk(void *payload,
NULL, &uid, &gid);
if (!disk->src->backingStore)
- ignore_value(virStorageSourceGetMetadata(disk->src, uid, gid, 1, false));
+ ignore_value(virStorageSourceGetMetadata(disk->src, uid, gid,
+ QEMU_DOMAIN_STORAGE_SOURCE_CHAIN_MAX_DEPTH,
+ false));
if (disk->src->backingStore &&
virStorageSourceIsSameLocation(disk->src->backingStore, iterdata->diskSrc)) {
--
2.52.0

View File

@ -1,34 +0,0 @@
From ca8a9f6b124dbfe5809c83d7f2d268bb18b9fa75 Mon Sep 17 00:00:00 2001
Message-ID: <ca8a9f6b124dbfe5809c83d7f2d268bb18b9fa75.1769699749.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 23 Jan 2026 08:54:32 +0100
Subject: [PATCH] qemuSnapshotUpdateBackingStore: Remove stale comment
The code does a 'qemu-img rebase' rather than a 'qemu-img create' what
the commit suggests. Since we enumerate all arguments right below,
there's no need for a comment.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 452c281aee7a043b59a288de043ea4e3b75a6b7c)
https://issues.redhat.com/browse/RHEL-144089 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-144090 [rhel-9.8]
---
src/qemu/qemu_snapshot.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index dfc3f449e3..942ba0d437 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3698,7 +3698,6 @@ qemuSnapshotUpdateBackingStore(qemuSnapshotDeleteExternalData *data)
struct _qemuSnapshotDisksWithBackingStoreData *backingData = cur->data;
g_autoptr(virCommand) cmd = NULL;
- /* creates cmd line args: qemu-img create -f qcow2 -o */
if (!(cmd = virCommandNewArgList("qemu-img",
"rebase",
"-u",
--
2.52.0

View File

@ -1,97 +0,0 @@
From 7d39e57db8479f4c481636c8c41311f3eabc935f Mon Sep 17 00:00:00 2001
Message-ID: <7d39e57db8479f4c481636c8c41311f3eabc935f.1769699749.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 26 Jan 2026 16:49:50 +0100
Subject: [PATCH] qemuSnapshotUpdateBackingStore: Retry as curent user if
qemu-img fails
The code calls 'qemu-img rebase' to fix the backing store references.
The 'qemu-img' process here is run as the 'qemu' user or whatever the
defaults and domain XML resolve to. Since this, in certain cases, works
also on images which are not part of the backing chain and in privileged
deployments thus can be owned by 'root:root' the update may fail
(silently).
To preserver root-squash deployments but fix also the above case, retry
the operation on failure as current user.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 6bb982178b40768f37c5177f317e73562733530f)
https://issues.redhat.com/browse/RHEL-144089 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-144090 [rhel-9.8]
---
src/qemu/qemu_snapshot.c | 53 ++++++++++++++++++++++++++++------------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index c23add5103..e30ade9dc8 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3698,25 +3698,48 @@ qemuSnapshotUpdateBackingStore(qemuSnapshotDeleteExternalData *data)
for (cur = data->disksWithBacking; cur; cur = g_slist_next(cur)) {
struct _qemuSnapshotDisksWithBackingStoreData *backingData = cur->data;
- g_autoptr(virCommand) cmd = NULL;
+ /* Try to run the command first as the appropriate user based on the
+ * domain definition and config. If error is returned retry as current
+ * (possibly privileged) user for cases where seclabels were reset
+ * to the default */
+ g_autoptr(virCommand) cmd_user_qemu = NULL;
+ g_autoptr(virCommand) cmd_user_curr = NULL;
- if (!(cmd = virCommandNewArgList("qemu-img",
- "rebase",
- "-u",
- "-F",
- virStorageFileFormatTypeToString(data->parentDiskSrc->format),
- "-f",
- virStorageFileFormatTypeToString(backingData->diskSrc->format),
- "-b",
- data->parentDiskSrc->path,
- backingData->diskSrc->path,
- NULL)))
+ if (!(cmd_user_qemu = virCommandNewArgList("qemu-img",
+ "rebase",
+ "-u",
+ "-F",
+ virStorageFileFormatTypeToString(data->parentDiskSrc->format),
+ "-f",
+ virStorageFileFormatTypeToString(backingData->diskSrc->format),
+ "-b",
+ data->parentDiskSrc->path,
+ backingData->diskSrc->path,
+ NULL)))
continue;
- virCommandSetUID(cmd, backingData->uid);
- virCommandSetGID(cmd, backingData->gid);
+ virCommandSetUID(cmd_user_qemu, backingData->uid);
+ virCommandSetGID(cmd_user_qemu, backingData->gid);
- ignore_value(virCommandRun(cmd, NULL));
+ /* done on success */
+ if (virCommandRun(cmd_user_qemu, NULL) == 0)
+ continue;
+
+ /* retry as current user */
+ if (!(cmd_user_curr = virCommandNewArgList("qemu-img",
+ "rebase",
+ "-u",
+ "-F",
+ virStorageFileFormatTypeToString(data->parentDiskSrc->format),
+ "-f",
+ virStorageFileFormatTypeToString(backingData->diskSrc->format),
+ "-b",
+ data->parentDiskSrc->path,
+ backingData->diskSrc->path,
+ NULL)))
+ continue;
+
+ ignore_value(virCommandRun(cmd_user_curr, NULL));
}
}
--
2.52.0

View File

@ -1,134 +0,0 @@
From 5cb651d76f287f1ae0212cf0f4d2d7618050e5d1 Mon Sep 17 00:00:00 2001
Message-ID: <5cb651d76f287f1ae0212cf0f4d2d7618050e5d1.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 19:49:16 +0100
Subject: [PATCH] qemu_command: Don't use host property if IOMMUFD is used
They should not be used at the same time.
Fixes: f6230804727df834da27370e835204672218ab23
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit f67e4ac4d071f6f05ae387bc3b09c6cebb10455d)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_command.c | 24 +++++++++----------
.../iommufd-q35.x86_64-latest.args | 2 +-
...fd-virt-pci-bus-single.aarch64-latest.args | 2 +-
.../iommufd-virt.aarch64-latest.args | 4 ++--
.../iommufd.x86_64-latest.args | 2 +-
5 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 33127fbc0a..d11d16e533 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4755,10 +4755,11 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
g_autoptr(virJSONValue) props = NULL;
virDomainHostdevSubsysPCI *pcisrc = &dev->source.subsys.u.pci;
virDomainNetTeamingInfo *teaming;
- g_autofree char *host = virPCIDeviceAddressAsString(&pcisrc->addr);
+ g_autofree char *host = NULL;
const char *failover_pair_id = NULL;
const char *driver = NULL;
const char *iommufdId = NULL;
+ const char *fdstr = NULL;
/* 'ramfb' property must be omitted unless it's to be enabled */
bool ramfb = pcisrc->ramfb == VIR_TRISTATE_SWITCH_ON;
@@ -4792,31 +4793,28 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
teaming->persistent)
failover_pair_id = teaming->persistent;
- if (pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_YES)
+ if (virHostdevIsPCIDeviceWithIOMMUFD(dev)) {
+ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev);
+
+ fdstr = qemuFDPassDirectGetPath(hostdevPriv->vfioDeviceFd);
iommufdId = "iommufd0";
+ } else {
+ host = virPCIDeviceAddressAsString(&pcisrc->addr);
+ }
if (virJSONValueObjectAdd(&props,
"s:driver", driver,
- "s:host", host,
+ "S:host", host,
"s:id", dev->info->alias,
"p:bootindex", dev->info->effectiveBootIndex,
"S:failover_pair_id", failover_pair_id,
"S:display", qemuOnOffAuto(pcisrc->display),
"B:ramfb", ramfb,
"S:iommufd", iommufdId,
+ "S:fd", fdstr,
NULL) < 0)
return NULL;
- if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
- pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_YES) {
- qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev);
-
- if (virJSONValueObjectAdd(&props,
- "S:fd", qemuFDPassDirectGetPath(hostdevPriv->vfioDeviceFd),
- NULL) < 0)
- return NULL;
- }
-
if (qemuBuildDeviceAddressProps(props, def, dev->info) < 0)
return NULL;
diff --git a/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args
index d5fe704021..f886c488e1 100644
--- a/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args
@@ -36,6 +36,6 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.config \
-global ICH9-LPC.noreboot=off \
-watchdog-action reset \
-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \
--device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x3"}' \
+-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x3"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args b/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args
index 99886468fb..d6562f9be3 100644
--- a/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args
+++ b/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args
@@ -28,6 +28,6 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-boot strict=on \
-audiodev '{"id":"audio1","driver":"none"}' \
-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \
--device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x1"}' \
+-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x1"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args b/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args
index e3695c6982..9fd2a6adee 100644
--- a/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args
+++ b/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args
@@ -31,7 +31,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-device '{"driver":"pcie-root-port","port":10,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x2"}' \
-audiodev '{"id":"audio1","driver":"none"}' \
-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \
--device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.1","addr":"0x0"}' \
--device '{"driver":"vfio-pci","host":"0000:07:12.5","id":"hostdev1","iommufd":"iommufd0","fd":"0","bus":"pci.2","addr":"0x0"}' \
+-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.1","addr":"0x0"}' \
+-device '{"driver":"vfio-pci","id":"hostdev1","iommufd":"iommufd0","fd":"0","bus":"pci.2","addr":"0x0"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/iommufd.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd.x86_64-latest.args
index 15dabe197c..b9aefda39d 100644
--- a/tests/qemuxmlconfdata/iommufd.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/iommufd.x86_64-latest.args
@@ -29,7 +29,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
-audiodev '{"id":"audio1","driver":"none"}' \
-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \
--device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.0","addr":"0x3"}' \
+-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.0","addr":"0x3"}' \
-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
--
2.53.0

View File

@ -1,73 +0,0 @@
From e5bdfe01cb976c45a440b88061a40f65ac6f8be8 Mon Sep 17 00:00:00 2001
Message-ID: <e5bdfe01cb976c45a440b88061a40f65ac6f8be8.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 20:10:50 +0100
Subject: [PATCH] qemu_command: Extract building IOMMUFD props to function
This will be reused by hotplug code.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 3f7ad3a8a5f0e453c85f186e811e051ead0f769a)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_command.c | 20 ++++++++++++++++----
src/qemu/qemu_command.h | 3 +++
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index cca5fed285..521aefbc10 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5337,6 +5337,21 @@ qemuBuildHostdevCommandLine(virCommand *cmd,
}
+virJSONValue *
+qemuBuildIOMMUFDProps(qemuFDPassDirect *iommufd)
+{
+ g_autoptr(virJSONValue) props = NULL;
+
+ if (qemuMonitorCreateObjectProps(&props, "iommufd",
+ "iommufd0",
+ "S:fd", qemuFDPassDirectGetPath(iommufd),
+ NULL) < 0)
+ return NULL;
+
+ return g_steal_pointer(&props);
+}
+
+
static int
qemuBuildIOMMUFDCommandLine(virCommand *cmd,
const virDomainDef *def,
@@ -5350,10 +5365,7 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd,
qemuFDPassDirectTransferCommand(priv->iommufd, cmd);
- if (qemuMonitorCreateObjectProps(&props, "iommufd",
- "iommufd0",
- "S:fd", qemuFDPassDirectGetPath(priv->iommufd),
- NULL) < 0)
+ if (!(props = qemuBuildIOMMUFDProps(priv->iommufd)))
return -1;
if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index ad068f1f16..028d002ef9 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -190,6 +190,9 @@ int
qemuBuildRNGBackendProps(virDomainRNGDef *rng,
virJSONValue **props);
+virJSONValue *
+qemuBuildIOMMUFDProps(qemuFDPassDirect *iommufd);
+
/* Current, best practice */
virJSONValue *
qemuBuildUSBHostdevDevProps(const virDomainDef *def,
--
2.53.0

View File

@ -1,51 +0,0 @@
From bbb78985cf3d7891578f6bfef8e5c2d65cb3868f Mon Sep 17 00:00:00 2001
Message-ID: <bbb78985cf3d7891578f6bfef8e5c2d65cb3868f.1773230519.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 6 Mar 2026 09:19:30 +0100
Subject: [PATCH] qemu_command: Update cmdqv to the latest qemu-kvm changes
From: Pavel Hrdina <phrdina@redhat.com>
The property was renamed and the type was changed from boolean to
string in order to accept `auto` as valid value.
With the change to on/off/auto we need to use qemuOnOffAuto().
Resolves: https://issues.redhat.com/browse/VOYAGER-296
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_command.c | 2 +-
.../iommu-smmuv3-pci-bus-accel-cmdqv.aarch64-latest.args | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index fdc79e18be..d419e92cdf 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6325,7 +6325,7 @@ qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def,
"s:primary-bus", bus,
"s:id", iommu->info.alias,
"B:accel", (iommu->accel == VIR_TRISTATE_SWITCH_ON),
- "B:tegra241-cmdqv", (iommu->cmdqv == VIR_TRISTATE_SWITCH_ON),
+ "S:cmdqv", qemuOnOffAuto(iommu->cmdqv),
"B:ats", (iommu->ats == VIR_TRISTATE_SWITCH_ON),
NULL) < 0)
return NULL;
diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel-cmdqv.aarch64-latest.args b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel-cmdqv.aarch64-latest.args
index 7c9d883661..d5a30927fe 100644
--- a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel-cmdqv.aarch64-latest.args
+++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-accel-cmdqv.aarch64-latest.args
@@ -30,8 +30,8 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \
-device '{"driver":"pxb-pcie","bus_nr":248,"id":"pci.2","bus":"pcie.0","addr":"0x2"}' \
-device '{"driver":"pcie-root-port","port":0,"chassis":21,"id":"pci.3","bus":"pci.1","addr":"0x0"}' \
-device '{"driver":"pcie-root-port","port":168,"chassis":22,"id":"pci.4","bus":"pci.2","addr":"0x0"}' \
--device '{"driver":"arm-smmuv3","primary-bus":"pci.1","id":"iommu0","accel":true,"tegra241-cmdqv":true,"ats":true,"ssidsize":20,"oas":44}' \
--device '{"driver":"arm-smmuv3","primary-bus":"pci.2","id":"iommu1","accel":true,"tegra241-cmdqv":true,"ats":true,"ssidsize":20,"oas":44}' \
+-device '{"driver":"arm-smmuv3","primary-bus":"pci.1","id":"iommu0","accel":true,"cmdqv":"on","ats":true,"ssidsize":20,"oas":44}' \
+-device '{"driver":"arm-smmuv3","primary-bus":"pci.2","id":"iommu1","accel":true,"cmdqv":"on","ats":true,"ssidsize":20,"oas":44}' \
-audiodev '{"id":"audio1","driver":"none"}' \
-object '{"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"}' \
-device '{"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.3","addr":"0x0"}' \
--
2.53.0

View File

@ -1,33 +0,0 @@
From 31d95c7ad884094f2afd4a0f2450141cc68594ff Mon Sep 17 00:00:00 2001
Message-ID: <31d95c7ad884094f2afd4a0f2450141cc68594ff.1771423658.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sat, 14 Feb 2026 16:12:11 +0100
Subject: [PATCH] qemu_domain: Add missing IOMMUFD cleanup
If starting VM fails we would leak the FD for IOMMU device.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 7c062bfc4f8c0ba853873e72d21dba77f6ca938f)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_domain.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index bdab117e96..64b01e524f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1975,6 +1975,8 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivate *priv)
priv->migrationRecoverSetup = false;
+ VIR_FORCE_CLOSE(priv->iommufd);
+
g_clear_pointer(&priv->memoryBackingDir, g_free);
}
--
2.53.0

View File

@ -1,134 +0,0 @@
From 598a0e9ee5f59faea21f03ccb02d0830e73f975f Mon Sep 17 00:00:00 2001
Message-ID: <598a0e9ee5f59faea21f03ccb02d0830e73f975f.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 21:21:53 +0100
Subject: [PATCH] qemu_hotplug: Add support to hotplug host device with IOMMUFD
For first host device we need to add iommufd object as well.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 5d16bef1a69500791be454239e3b9ac68ec53ace)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_hotplug.c | 39 +++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_process.c | 4 ++--
src/qemu/qemu_process.h | 3 +++
3 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 10ad13a416..a455c2cd53 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1561,13 +1561,16 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV,
{ .hostdev = hostdev } };
virDomainDeviceInfo *info = hostdev->info;
+ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
int ret;
g_autoptr(virJSONValue) devprops = NULL;
+ g_autoptr(virJSONValue) objprops = NULL;
bool releaseaddr = false;
bool teardowncgroup = false;
bool teardownlabel = false;
bool teardowndevice = false;
bool teardownmemlock = false;
+ bool removeiommufd = false;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
unsigned int flags = 0;
@@ -1617,11 +1620,38 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
goto error;
}
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
+ if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
+ goto error;
+
+ if (!priv->iommufdState) {
+ if (qemuProcessOpenIommuFd(vm) < 0)
+ goto error;
+
+ if (!(objprops = qemuBuildIOMMUFDProps(priv->iommufd)))
+ goto error;
+ }
+ }
+
if (!(devprops = qemuBuildPCIHostdevDevProps(vm->def, hostdev)))
goto error;
qemuDomainObjEnterMonitor(vm);
+ if (objprops) {
+ if ((ret = qemuFDPassDirectTransferMonitor(priv->iommufd, priv->mon)) < 0)
+ goto exit_monitor;
+
+ if ((ret = qemuMonitorAddObject(priv->mon, &objprops, NULL)) < 0)
+ goto exit_monitor;
+
+ priv->iommufdState = true;
+ removeiommufd = true;
+ }
+
+ if ((ret = qemuFDPassDirectTransferMonitor(hostdevPriv->vfioDeviceFd, priv->mon)) < 0)
+ goto exit_monitor;
+
if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0)
goto exit_monitor;
@@ -1652,6 +1682,15 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
if (teardownmemlock && qemuDomainAdjustMaxMemLock(vm) < 0)
VIR_WARN("Unable to reset maximum locked memory on hotplug fail");
+ if (removeiommufd) {
+ qemuDomainObjEnterMonitor(vm);
+ ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false));
+ qemuDomainObjExitMonitor(vm);
+ }
+
+ qemuFDPassDirectTransferMonitorRollback(hostdevPriv->vfioDeviceFd, priv->mon);
+ qemuFDPassDirectTransferMonitorRollback(priv->iommufd, priv->mon);
+
if (releaseaddr)
qemuDomainReleaseDeviceAddress(vm, info);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 59fff1aa19..1aff3a277b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7681,7 +7681,7 @@ qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm,
*
* Returns: 0 on success, -1 on failure
*/
-static int
+int
qemuProcessOpenIommuFd(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
@@ -7705,7 +7705,7 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
*
* Returns: 0 on success, -1 on failure
*/
-static int
+int
qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
{
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index df78b00abb..1023b7cb25 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -134,6 +134,9 @@ int qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm,
virDomainDeviceDef *dev)
ATTRIBUTE_MOCKABLE;
+int qemuProcessOpenIommuFd(virDomainObj *vm);
+
+int qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev);
int qemuProcessPrepareHost(virQEMUDriver *driver,
virDomainObj *vm,
--
2.53.0

View File

@ -1,98 +0,0 @@
From e90816b502675a2737ad1fa1c85b8ae5dfff8680 Mon Sep 17 00:00:00 2001
Message-ID: <e90816b502675a2737ad1fa1c85b8ae5dfff8680.1773230519.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Tue, 10 Mar 2026 09:34:48 +0100
Subject: [PATCH] qemu_hotplug: Fix crash when attaching network inteface with
hostdev network
From: Pavel Hrdina <phrdina@redhat.com>
The following interface XML will crash libvirt when attached to
running VM:
<interface type='network'>
<source network='hostdev_net'/>
</interface>
Instead of trying to figure out every single place where hostdev is used
as struct directly and allocating empty private data check if iommufd
is configured as that will happen only for <hostdev> device where the
private data are correctly allocated.
This patch is best viewed with `git show -w`.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 25662b3700da9c32b5083d46ff3831aa4afc2eab)
Resolves: https://issues.redhat.com/browse/VOYAGER-227
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_hotplug.c | 37 +++++++++++++++++++++----------------
1 file changed, 21 insertions(+), 16 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index bb88815e27..845f42bf20 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1638,20 +1638,23 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
qemuDomainObjEnterMonitor(vm);
- if (objprops) {
- if ((ret = qemuFDPassDirectTransferMonitor(priv->iommufd, priv->mon)) < 0)
- goto exit_monitor;
- if ((ret = qemuMonitorAddObject(priv->mon, &objprops, NULL)) < 0)
- goto exit_monitor;
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
+ if (objprops) {
+ if ((ret = qemuFDPassDirectTransferMonitor(priv->iommufd, priv->mon)) < 0)
+ goto exit_monitor;
+
+ if ((ret = qemuMonitorAddObject(priv->mon, &objprops, NULL)) < 0)
+ goto exit_monitor;
- priv->iommufdState = true;
- removeiommufd = true;
+ priv->iommufdState = true;
+ removeiommufd = true;
+ }
+
+ if ((ret = qemuFDPassDirectTransferMonitor(hostdevPriv->vfioDeviceFd, priv->mon)) < 0)
+ goto exit_monitor;
}
- if ((ret = qemuFDPassDirectTransferMonitor(hostdevPriv->vfioDeviceFd, priv->mon)) < 0)
- goto exit_monitor;
-
if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0)
goto exit_monitor;
@@ -1682,15 +1685,17 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
if (teardownmemlock && qemuDomainAdjustMaxMemLock(vm) < 0)
VIR_WARN("Unable to reset maximum locked memory on hotplug fail");
- qemuDomainObjEnterMonitor(vm);
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
+ qemuDomainObjEnterMonitor(vm);
- if (removeiommufd)
- ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false));
+ if (removeiommufd)
+ ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false));
- qemuFDPassDirectTransferMonitorRollback(hostdevPriv->vfioDeviceFd, priv->mon);
- qemuFDPassDirectTransferMonitorRollback(priv->iommufd, priv->mon);
+ qemuFDPassDirectTransferMonitorRollback(hostdevPriv->vfioDeviceFd, priv->mon);
+ qemuFDPassDirectTransferMonitorRollback(priv->iommufd, priv->mon);
- qemuDomainObjExitMonitor(vm);
+ qemuDomainObjExitMonitor(vm);
+ }
if (releaseaddr)
qemuDomainReleaseDeviceAddress(vm, info);
--
2.53.0

View File

@ -1,40 +0,0 @@
From 2274a02bd1b2cefb48d7d66fe8db10e5c9cd853d Mon Sep 17 00:00:00 2001
Message-ID: <2274a02bd1b2cefb48d7d66fe8db10e5c9cd853d.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 19:57:12 +0100
Subject: [PATCH] qemu_hotplug: Remove iommufd object if no longer needed
When removing last host device using IOMMUFD remove the iommufd object
as well.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 300ebf01b88d154312c1a5a684be2add95dd7f31)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_hotplug.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9445599d2c..10ad13a416 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4986,6 +4986,14 @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver,
}
}
+ if (priv->iommufdState &&
+ !virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
+ qemuDomainObjEnterMonitor(vm);
+ ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false));
+ qemuDomainObjExitMonitor(vm);
+ priv->iommufdState = false;
+ }
+
virDomainAuditHostdev(vm, hostdev, "detach", true);
if (!virHostdevIsPCIDevice(hostdev) &&
--
2.53.0

View File

@ -1,48 +0,0 @@
From af8b75eaad8a84b712338a2975091d8bbe144015 Mon Sep 17 00:00:00 2001
Message-ID: <af8b75eaad8a84b712338a2975091d8bbe144015.1772544849.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Thu, 26 Feb 2026 10:54:18 +0100
Subject: [PATCH] qemu_hotplug: enter monitor in order to rollback passed FD
From: Pavel Hrdina <phrdina@redhat.com>
Reported-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 4374dbbbf0d87f0052dd96be96baad6c20963713)
https://issues.redhat.com/browse/VOYAGER-227
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_hotplug.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a455c2cd53..bb88815e27 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1682,15 +1682,16 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
if (teardownmemlock && qemuDomainAdjustMaxMemLock(vm) < 0)
VIR_WARN("Unable to reset maximum locked memory on hotplug fail");
- if (removeiommufd) {
- qemuDomainObjEnterMonitor(vm);
+ qemuDomainObjEnterMonitor(vm);
+
+ if (removeiommufd)
ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false));
- qemuDomainObjExitMonitor(vm);
- }
qemuFDPassDirectTransferMonitorRollback(hostdevPriv->vfioDeviceFd, priv->mon);
qemuFDPassDirectTransferMonitorRollback(priv->iommufd, priv->mon);
+ qemuDomainObjExitMonitor(vm);
+
if (releaseaddr)
qemuDomainReleaseDeviceAddress(vm, info);
--
2.53.0

View File

@ -1,48 +0,0 @@
From e42d8373633488a6d67b6c895953de183b1dd495 Mon Sep 17 00:00:00 2001
Message-ID: <e42d8373633488a6d67b6c895953de183b1dd495.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 19:13:19 +0100
Subject: [PATCH] qemu_process: Fix FD leak with multiple host devices using
IOMMUFD
We would open IOMMU device for each host device with IOMMUFD backend
leaking FD except for the last one. Since we are adding only single
iommufd object we need to open it only once.
Fixes: 2f0999a161910e3992458902ce90d37f8b8f2642
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit d194f362f342c22731670e365e8a2681759dbc57)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_process.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 3bd81c55b3..da7a9fc11f 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7736,13 +7736,15 @@ qemuProcessOpenVfioFds(virDomainObj *vm)
/* Open VFIO device FD */
if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
return -1;
-
- /* Open IOMMU FD */
- if (qemuProcessOpenIommuFd(vm) < 0)
- return -1;
}
}
+ /* Open IOMMU FD */
+ if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def) &&
+ qemuProcessOpenIommuFd(vm) < 0) {
+ return -1;
+ }
+
return 0;
}
--
2.53.0

View File

@ -1,72 +0,0 @@
From da301bafb4eb4658a0b4aae8d8b633bc9a1ef2f9 Mon Sep 17 00:00:00 2001
Message-ID: <da301bafb4eb4658a0b4aae8d8b633bc9a1ef2f9.1771423658.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 19:01:35 +0100
Subject: [PATCH] qemu_process: Refactor qemuProcessOpenIommuFd
This will allow us reusing same code for hotplug.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit ff2848827f42578115ef54a389a41798a96fd338)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_process.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index dd165512f3..71770d2099 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7676,24 +7676,23 @@ qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm,
/**
* qemuProcessOpenIommuFd:
* @vm: domain object
- * @iommuFd: returned file descriptor
*
* Opens /dev/iommu file descriptor for the VM.
*
- * Returns: FD on success, -1 on failure
+ * Returns: 0 on success, -1 on failure
*/
static int
qemuProcessOpenIommuFd(virDomainObj *vm)
{
- int fd = -1;
+ qemuDomainObjPrivate *priv = vm->privateData;
VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name);
- if ((fd = virIOMMUFDOpenDevice()) < 0)
+ if ((priv->iommufd = virIOMMUFDOpenDevice()) < 0)
return -1;
- VIR_DEBUG("Opened IOMMU FD %d for domain %s", fd, vm->def->name);
- return fd;
+ VIR_DEBUG("Opened IOMMU FD %d for domain %s", priv->iommufd, vm->def->name);
+ return 0;
}
/**
@@ -7750,7 +7749,6 @@ qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
static int
qemuProcessOpenVfioFds(virDomainObj *vm)
{
- qemuDomainObjPrivate *priv = vm->privateData;
size_t i;
/* Check if we have any hostdevs that need VFIO FDs */
@@ -7768,8 +7766,7 @@ qemuProcessOpenVfioFds(virDomainObj *vm)
return -1;
/* Open IOMMU FD */
- priv->iommufd = qemuProcessOpenIommuFd(vm);
- if (priv->iommufd == -1)
+ if (qemuProcessOpenIommuFd(vm) < 0)
return -1;
}
}
--
2.53.0

View File

@ -1,75 +0,0 @@
From 24f32b0d564d4c782b4a39990ef6508d9260774a Mon Sep 17 00:00:00 2001
Message-ID: <24f32b0d564d4c782b4a39990ef6508d9260774a.1771423658.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 19:09:23 +0100
Subject: [PATCH] qemu_process: Refactor qemuProcessOpenVfioDeviceFd
This will allow us reusing same code for hotplug support.
As part of refactor remove redundant checks.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 76b720168bee49497519bbca2147cbd65ae7fcbf)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_process.c | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 55cd930df8..7e32325fa0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7698,23 +7698,21 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
/**
* qemuProcessOpenVfioDeviceFd:
* @hostdev: host device definition
- * @vfioFd: returned file descriptor
*
* Opens the VFIO device file descriptor for a hostdev.
*
- * Returns: FD on success, -1 on failure
+ * Returns: 0 on success, -1 on failure
*/
static int
qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
{
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
- hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("VFIO FD only supported for PCI hostdevs"));
- return -1;
- }
+ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
+ virDomainHostdevSubsysPCI *pci = &hostdev->source.subsys.u.pci;
- return virPCIDeviceOpenVfioFd(&hostdev->source.subsys.u.pci.addr);
+ if ((hostdevPriv->vfioDeviceFd = virPCIDeviceOpenVfioFd(&pci->addr)) < 0)
+ return -1;
+
+ return 0;
}
/**
@@ -7733,16 +7731,14 @@ qemuProcessOpenVfioFds(virDomainObj *vm)
/* Check if we have any hostdevs that need VFIO FDs */
for (i = 0; i < vm->def->nhostdevs; i++) {
virDomainHostdevDef *hostdev = vm->def->hostdevs[i];
- qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
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) {
/* Open VFIO device FD */
- hostdevPriv->vfioDeviceFd = qemuProcessOpenVfioDeviceFd(hostdev);
- if (hostdevPriv->vfioDeviceFd == -1)
- return -1;
+ if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
+ return -1;
/* Open IOMMU FD */
if (qemuProcessOpenIommuFd(vm) < 0)
--
2.53.0

View File

@ -1,77 +0,0 @@
From a3696f1e0ba8ddf997e54fccd945593272635762 Mon Sep 17 00:00:00 2001
Message-ID: <a3696f1e0ba8ddf997e54fccd945593272635762.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sun, 15 Feb 2026 19:15:52 +0100
Subject: [PATCH] qemu_process: Refactor qemuProcessOpenVfioFds
Follow our switch pattern to simplify the code logic
and rename the function to follow our naming pattern.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit c83b4f367f23868793fc6b071771d0e641b7a546)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_process.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index da7a9fc11f..3729edcd7e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7715,27 +7715,28 @@ qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
return 0;
}
-/**
- * qemuProcessOpenVfioFds:
- * @vm: domain object
- *
- * Opens all necessary VFIO file descriptors for the domain.
- *
- * Returns: 0 on success, -1 on failure
- */
static int
-qemuProcessOpenVfioFds(virDomainObj *vm)
+qemuProcessPrepareHostHostdev(virDomainObj *vm)
{
size_t i;
- /* Check if we have any hostdevs that need VFIO FDs */
for (i = 0; i < vm->def->nhostdevs; i++) {
virDomainHostdevDef *hostdev = vm->def->hostdevs[i];
- if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
- /* Open VFIO device FD */
- if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
- return -1;
+ switch (hostdev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
+ /* Open VFIO device FD */
+ if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
+ return -1;
+ }
+ break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
+ break;
}
}
@@ -7803,7 +7804,7 @@ qemuProcessPrepareHost(virQEMUDriver *driver,
hostdev_flags |= VIR_HOSTDEV_COLD_BOOT;
if (qemuHostdevPrepareDomainDevices(driver, vm->def, hostdev_flags) < 0)
return -1;
- if (qemuProcessOpenVfioFds(vm) < 0)
+ if (qemuProcessPrepareHostHostdev(vm) < 0)
return -1;
VIR_DEBUG("Preparing chr device backends");
--
2.53.0

View File

@ -1,175 +0,0 @@
From 65beee7622ce4f110dbd56c631502444197756e6 Mon Sep 17 00:00:00 2001
Message-ID: <65beee7622ce4f110dbd56c631502444197756e6.1770203422.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 22:49:09 +0100
Subject: [PATCH] qemublocktest: Iterate all nodenames in
'testQemuDetectBitmaps'
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Rather than looking for 30 specific nodenames (via a loop) iterate
everything in the hash table (in a sorted order). This simplifies the
code and provides more test outputs on previously-ignored nodenames.
The listing of internal snapshots in the output was also missing a
newline, which would now cause problems with multiple images reproted.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 71643c197e86a3adc792c0b2a378a245ae6c5756)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
tests/qemublocktest.c | 24 +++++++------------
tests/qemublocktestdata/bitmap/basic.out | 1 +
tests/qemublocktestdata/bitmap/empty.out | 1 +
.../bitmap/snapshots-internal.out | 7 ++++++
tests/qemublocktestdata/bitmap/snapshots.out | 5 ++++
tests/qemublocktestdata/bitmap/synthetic.out | 5 ++++
6 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
index 47746207cc..51d9268cdd 100644
--- a/tests/qemublocktest.c
+++ b/tests/qemublocktest.c
@@ -575,17 +575,15 @@ testQemuImageCreate(const void *opaque)
static const char *bitmapDetectPrefix = "qemublocktestdata/bitmap/";
-static void
-testQemuDetectBitmapsWorker(GHashTable *nodedata,
+static int
+testQemuDetectBitmapsWorker(void *payload,
const char *nodename,
- virBuffer *buf)
+ void *opaque)
{
- qemuBlockNamedNodeData *data;
+ qemuBlockNamedNodeData *data = payload;
+ virBuffer *buf = opaque;
size_t i;
- if (!(data = virHashLookup(nodedata, nodename)))
- return;
-
virBufferAsprintf(buf, "%s:\n", nodename);
if (data->qcow2v2)
virBufferAddLit(buf, " qcow2 v2\n");
@@ -617,9 +615,12 @@ testQemuDetectBitmapsWorker(GHashTable *nodedata,
virBufferAsprintf(buf, " '%s'%s", (const char *) n->key, vms);
}
+
+ virBufferAddLit(buf, "\n");
}
virBufferAdjustIndent(buf, -1);
+ return 0;
}
@@ -632,7 +633,6 @@ testQemuDetectBitmaps(const void *opaque)
g_autofree char *actual = NULL;
g_autofree char *expectpath = NULL;
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
- size_t i;
expectpath = g_strdup_printf("%s/%s%s.out", abs_srcdir,
bitmapDetectPrefix, name);
@@ -646,13 +646,7 @@ testQemuDetectBitmaps(const void *opaque)
return -1;
}
- /* we detect for the first 30 nodenames for simplicity */
- for (i = 0; i < 30; i++) {
- g_autofree char *nodename = g_strdup_printf("libvirt-%zu-format", i);
-
- testQemuDetectBitmapsWorker(nodedata, nodename, &buf);
- }
-
+ virHashForEachSorted(nodedata, testQemuDetectBitmapsWorker, &buf);
actual = virBufferContentAndReset(&buf);
return virTestCompareToFile(actual, expectpath);
diff --git a/tests/qemublocktestdata/bitmap/basic.out b/tests/qemublocktestdata/bitmap/basic.out
index 5c4c35b3f0..b96ffe3d39 100644
--- a/tests/qemublocktestdata/bitmap/basic.out
+++ b/tests/qemublocktestdata/bitmap/basic.out
@@ -4,3 +4,4 @@ libvirt-1-format:
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-1-storage:
diff --git a/tests/qemublocktestdata/bitmap/empty.out b/tests/qemublocktestdata/bitmap/empty.out
index 3787cbd354..c9a5be4f07 100644
--- a/tests/qemublocktestdata/bitmap/empty.out
+++ b/tests/qemublocktestdata/bitmap/empty.out
@@ -1 +1,2 @@
libvirt-1-format:
+libvirt-1-storage:
diff --git a/tests/qemublocktestdata/bitmap/snapshots-internal.out b/tests/qemublocktestdata/bitmap/snapshots-internal.out
index dbb3cfded4..cf7bde96a5 100644
--- a/tests/qemublocktestdata/bitmap/snapshots-internal.out
+++ b/tests/qemublocktestdata/bitmap/snapshots-internal.out
@@ -1,2 +1,9 @@
libvirt-1-format:
internal snapshots: '1727868651'(*) '1727872064'(*)
+libvirt-1-storage:
+libvirt-2-storage:
+libvirt-pflash0-format:
+libvirt-pflash0-storage:
+libvirt-pflash1-format:
+ internal snapshots: '1727868651' '1727872064'
+libvirt-pflash1-storage:
diff --git a/tests/qemublocktestdata/bitmap/snapshots.out b/tests/qemublocktestdata/bitmap/snapshots.out
index 24ca27e4d8..29c586be7e 100644
--- a/tests/qemublocktestdata/bitmap/snapshots.out
+++ b/tests/qemublocktestdata/bitmap/snapshots.out
@@ -4,16 +4,21 @@ libvirt-1-format:
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-1-storage:
libvirt-2-format:
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-2-storage:
libvirt-3-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-3-storage:
libvirt-4-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-4-storage:
libvirt-5-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-5-storage:
diff --git a/tests/qemublocktestdata/bitmap/synthetic.out b/tests/qemublocktestdata/bitmap/synthetic.out
index 45423903a0..2f4ae2b217 100644
--- a/tests/qemublocktestdata/bitmap/synthetic.out
+++ b/tests/qemublocktestdata/bitmap/synthetic.out
@@ -6,12 +6,17 @@ libvirt-1-format:
top-inactive: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
top-transient: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
top-transient-inactive: record:0 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
+libvirt-1-storage:
libvirt-2-format:
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-2-storage:
libvirt-3-format:
b: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-3-storage:
libvirt-4-format:
+libvirt-4-storage:
libvirt-5-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-5-storage:
--
2.52.0

View File

@ -1,101 +0,0 @@
From d851b46d3794d4ad2d0f9b74c0e0cf1a10d06682 Mon Sep 17 00:00:00 2001
Message-ID: <d851b46d3794d4ad2d0f9b74c0e0cf1a10d06682.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sat, 14 Feb 2026 11:39:19 +0100
Subject: [PATCH] qemuxmlconftest: Refactor host device preparation
Create a single place for host device preparation code.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit cb23831c020a5fab33be417426b2746a73ecdd10)
Conflicts:
- missing upstream commit b97afe28f54dae1d122baa33d1a371b68775b7b2
tests/qemuxmlconftest.c
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
tests/qemuxmlconftest.c | 59 ++++++++++++++++++++++++++++++-----------
1 file changed, 43 insertions(+), 16 deletions(-)
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 757f0a9fc0..0c146601ed 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -378,6 +378,48 @@ testSetupHostdevPrivateData(virDomainDef *def)
}
+static void
+testQemuPrepareHostdevUSB(virDomainHostdevDef *hostdev)
+{
+ virDomainHostdevSubsysUSB *usb = &hostdev->source.subsys.u.usb;
+
+ if (!usb->device && !usb->bus) {
+ if (usb->vendor == 0x1234 && usb->product == 0x4321) {
+ usb->bus = 42;
+ usb->device = 0x1234;
+ } else {
+ g_assert_not_reached();
+ }
+ }
+}
+
+
+static void
+testQemuPrepareHostdev(virDomainObj *vm)
+{
+ size_t i;
+
+ for (i = 0; i < vm->def->nhostdevs; i++) {
+ virDomainHostdevDef *hostdev = vm->def->hostdevs[i];
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+
+ switch (hostdev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
+ testQemuPrepareHostdevUSB(hostdev);
+ break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
+ break;
+ }
+ }
+}
+
+
static virNetworkDriver fakeNetworkDriver = {
.networkLookupByName = fakeNetworkLookupByName,
.networkGetXMLDesc = fakeNetworkGetXMLDesc,
@@ -524,22 +566,7 @@ testCompareXMLToArgvCreateArgs(virQEMUDriver *drv,
}
}
- 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_USB) {
- virDomainHostdevSubsysUSB *usb = &hostdev->source.subsys.u.usb;
- if (!usb->device && !usb->bus) {
- if (usb->vendor == 0x1234 && usb->product == 0x4321) {
- usb->bus = 42;
- usb->device = 0x1234;
- } else {
- g_assert_not_reached();
- }
- }
- }
- }
+ testQemuPrepareHostdev(vm);
if (flags & FLAG_SLIRP_HELPER) {
for (i = 0; i < vm->def->nnets; i++) {
--
2.53.0

View File

@ -1,78 +0,0 @@
From ef36f155015cd42f1f631d4955b76173ca16b9f3 Mon Sep 17 00:00:00 2001
Message-ID: <ef36f155015cd42f1f631d4955b76173ca16b9f3.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sat, 14 Feb 2026 11:48:53 +0100
Subject: [PATCH] qemuxmlconftest: Rename and refactor
testSetupHostdevPrivateData
There is no need to call qemuDomainHostdevPrivateNew() because
privateData is allocated on creation by virDomainHostdevDefNew().
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 15ad45758bcb674924ddb2ebb86a767cf40b990d)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
tests/qemuxmlconftest.c | 29 +++++++----------------------
1 file changed, 7 insertions(+), 22 deletions(-)
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 0c146601ed..f7e50dc655 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -352,28 +352,13 @@ fakeNetworkPortGetXMLDesc(virNetworkPortPtr port,
static void
-testSetupHostdevPrivateData(virDomainDef *def)
+testQemuPrepareHostdevPCI(virDomainHostdevDef *hostdev)
{
- size_t i;
+ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
- for (i = 0; i < def->nhostdevs; i++) {
- virDomainHostdevDef *hostdev = 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) {
-
- qemuDomainHostdevPrivate *priv;
-
- if (!hostdev->privateData) {
- hostdev->privateData = qemuDomainHostdevPrivateNew();
- }
-
- priv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
- /* Use a placeholder FD value for tests */
- priv->vfioDeviceFd = 0;
- }
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
+ /* Use a placeholder FD value for tests */
+ hostdevPriv->vfioDeviceFd = 0;
}
}
@@ -410,6 +395,8 @@ testQemuPrepareHostdev(virDomainObj *vm)
testQemuPrepareHostdevUSB(hostdev);
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ testQemuPrepareHostdevPCI(hostdev);
+ break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
@@ -473,8 +460,6 @@ testCompareXMLToArgvCreateArgs(virQEMUDriver *drv,
if (testQemuPrepareHostBackendChardevOne(NULL, priv->monConfig, vm) < 0)
return NULL;
- testSetupHostdevPrivateData(vm->def);
-
for (i = 0; i < vm->def->ndisks; i++) {
virDomainDiskDef *disk = vm->def->disks[i];
virStorageSource *src;
--
2.53.0

View File

@ -1,98 +0,0 @@
From fc19eece815873aa653d733494294f4b83a9416e Mon Sep 17 00:00:00 2001
Message-ID: <fc19eece815873aa653d733494294f4b83a9416e.1771423659.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Sat, 14 Feb 2026 17:11:44 +0100
Subject: [PATCH] qemuxmlconftest: Set fake FD for IOMMUFD
Same as for VFIO FD for host device.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 4a80a0468e21866d11f08bd64888f399cff98d94)
Resolves: https://issues.redhat.com/browse/RHEL-150351
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args | 2 +-
.../iommufd-virt-pci-bus-single.aarch64-latest.args | 2 +-
tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args | 2 +-
tests/qemuxmlconfdata/iommufd.x86_64-latest.args | 2 +-
tests/qemuxmlconftest.c | 4 ++++
5 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args
index 7d819e141b..d5fe704021 100644
--- a/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args
@@ -35,7 +35,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.config \
-device '{"driver":"qxl-vga","id":"video0","max_outputs":1,"ram_size":67108864,"vram_size":33554432,"vram64_size_mb":0,"vgamem_mb":8,"bus":"pcie.0","addr":"0x1"}' \
-global ICH9-LPC.noreboot=off \
-watchdog-action reset \
--object '{"qom-type":"iommufd","id":"iommufd0","fd":"-1"}' \
+-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \
-device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x3"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args b/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args
index dbfd395168..99886468fb 100644
--- a/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args
+++ b/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args
@@ -27,7 +27,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-no-shutdown \
-boot strict=on \
-audiodev '{"id":"audio1","driver":"none"}' \
--object '{"qom-type":"iommufd","id":"iommufd0","fd":"-1"}' \
+-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \
-device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x1"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args b/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args
index d5713ff826..e3695c6982 100644
--- a/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args
+++ b/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args
@@ -30,7 +30,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \
-device '{"driver":"pcie-root-port","port":10,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x2"}' \
-audiodev '{"id":"audio1","driver":"none"}' \
--object '{"qom-type":"iommufd","id":"iommufd0","fd":"-1"}' \
+-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \
-device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.1","addr":"0x0"}' \
-device '{"driver":"vfio-pci","host":"0000:07:12.5","id":"hostdev1","iommufd":"iommufd0","fd":"0","bus":"pci.2","addr":"0x0"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
diff --git a/tests/qemuxmlconfdata/iommufd.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd.x86_64-latest.args
index 3130ba2e3a..15dabe197c 100644
--- a/tests/qemuxmlconfdata/iommufd.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/iommufd.x86_64-latest.args
@@ -28,7 +28,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-boot strict=on \
-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
-audiodev '{"id":"audio1","driver":"none"}' \
--object '{"qom-type":"iommufd","id":"iommufd0","fd":"-1"}' \
+-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \
-device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.0","addr":"0x3"}' \
-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index f7e50dc655..6f16b6cee8 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -382,6 +382,7 @@ testQemuPrepareHostdevUSB(virDomainHostdevDef *hostdev)
static void
testQemuPrepareHostdev(virDomainObj *vm)
{
+ qemuDomainObjPrivate *priv = QEMU_DOMAIN_PRIVATE(vm);
size_t i;
for (i = 0; i < vm->def->nhostdevs; i++) {
@@ -404,6 +405,9 @@ testQemuPrepareHostdev(virDomainObj *vm)
break;
}
}
+
+ if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def))
+ priv->iommufd = 0;
}
--
2.53.0

View File

@ -1,613 +0,0 @@
From 0c3734057bd0fa76b475f9ad38d836c8a2b5e454 Mon Sep 17 00:00:00 2001
Message-ID: <0c3734057bd0fa76b475f9ad38d836c8a2b5e454.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 2 Mar 2026 12:46:00 +0100
Subject: [PATCH] security: Cleanup hostdev label error logic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Pavel Hrdina <phrdina@redhat.com>
Current code used mix of return, goto, break and setting ret variable.
Simplify the logic to just return -1 on error.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit b7483e6558acbb0d80e2ff2c3648ca63cb7f41f9)
Resolves: https://redhat.atlassian.net/browse/VOYAGER-309
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/security/security_apparmor.c | 56 +++++++++--------
src/security/security_dac.c | 103 ++++++++++++++++++-------------
src/security/security_selinux.c | 87 ++++++++++++++------------
3 files changed, 139 insertions(+), 107 deletions(-)
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 74c5b10063..1c3496893c 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -800,7 +800,6 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
const char *vroot)
{
g_autofree struct SDPDOP *ptr = NULL;
- int ret = -1;
virSecurityLabelDef *secdef =
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
virDomainHostdevSubsysUSB *usbsrc = &dev->source.subsys.u.usb;
@@ -834,9 +833,10 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
g_autoptr(virUSBDevice) usb =
virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot);
if (!usb)
- goto done;
+ return -1;
- ret = virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr);
+ if (virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr) < 0)
+ return -1;
break;
}
@@ -845,30 +845,32 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
virPCIDeviceNew(&pcisrc->addr);
if (!pci)
- goto done;
+ return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
- if (!vfioGroupDev) {
- goto done;
- }
- ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr);
+ if (!vfioGroupDev)
+ return -1;
+
+ if (AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr) < 0)
+ return -1;
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- goto done;
+ return -1;
- ret = AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr);
- if (ret < 0)
- goto done;
+ if (AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr) < 0)
+ return -1;
- ret = AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr);
+ if (AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr) < 0)
+ return -1;
}
} else {
- ret = virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr);
+ if (virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr) < 0)
+ return -1;
}
break;
}
@@ -881,10 +883,11 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
scsihostsrc->target, scsihostsrc->unit,
dev->readonly, dev->shareable);
- if (!scsi)
- goto done;
+ if (!scsi)
+ return -1;
- ret = virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr);
+ if (virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr) < 0)
+ return -1;
break;
}
@@ -892,11 +895,13 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
g_autoptr(virSCSIVHostDevice) host = virSCSIVHostDeviceNew(hostsrc->wwpn);
if (!host)
- goto done;
+ return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- AppArmorSetSecurityHostLabel,
- ptr);
+ if (virSCSIVHostDeviceFileIterate(host,
+ AppArmorSetSecurityHostLabel,
+ ptr) < 0) {
+ return -1;
+ }
break;
}
@@ -904,19 +909,18 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
g_autofree char *vfiodev = NULL;
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
- goto done;
+ return -1;
- ret = AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr);
+ if (AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- done:
- return ret;
+ return 0;
}
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 704c8dbfec..2a4c7f6a3c 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1234,7 +1234,6 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi;
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev;
- int ret = -1;
if (!priv->dynamicOwnership)
return 0;
@@ -1265,9 +1264,11 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!(usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot)))
return -1;
- ret = virUSBDeviceFileIterate(usb,
- virSecurityDACSetUSBLabel,
- &cbdata);
+ if (virUSBDeviceFileIterate(usb,
+ virSecurityDACSetUSBLabel,
+ &cbdata) < 0) {
+ return -1;
+ }
break;
}
@@ -1275,7 +1276,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
g_autoptr(virPCIDevice) pci = NULL;
if (!virPCIDeviceExists(&pcisrc->addr))
- break;
+ return -1;
pci = virPCIDeviceNew(&pcisrc->addr);
@@ -1289,25 +1290,29 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!vfioGroupDev)
return -1;
- ret = virSecurityDACSetHostdevLabelHelper(vfioGroupDev,
- false,
- &cbdata);
+ if (virSecurityDACSetHostdevLabelHelper(vfioGroupDev,
+ false,
+ &cbdata) < 0) {
+ return -1;
+ }
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
return -1;
- ret = virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata);
- if (ret < 0)
- break;
+ if (virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata) < 0)
+ return -1;
- ret = virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata);
+ if (virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata) < 0)
+ return -1;
}
} else {
- ret = virPCIDeviceFileIterate(pci,
- virSecurityDACSetPCILabel,
- &cbdata);
+ if (virPCIDeviceFileIterate(pci,
+ virSecurityDACSetPCILabel,
+ &cbdata) < 0) {
+ return -1;
+ }
}
break;
}
@@ -1323,9 +1328,11 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!scsi)
return -1;
- ret = virSCSIDeviceFileIterate(scsi,
- virSecurityDACSetSCSILabel,
- &cbdata);
+ if (virSCSIDeviceFileIterate(scsi,
+ virSecurityDACSetSCSILabel,
+ &cbdata) < 0) {
+ return -1;
+ }
break;
}
@@ -1335,9 +1342,11 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!host)
return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- virSecurityDACSetHostLabel,
- &cbdata);
+ if (virSCSIVHostDeviceFileIterate(host,
+ virSecurityDACSetHostLabel,
+ &cbdata) < 0) {
+ return -1;
+ }
break;
}
@@ -1347,16 +1356,16 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
return -1;
- ret = virSecurityDACSetHostdevLabelHelper(vfiodev, false, &cbdata);
+ if (virSecurityDACSetHostdevLabelHelper(vfiodev, false, &cbdata) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- return ret;
+ return 0;
}
@@ -1414,7 +1423,6 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi;
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev;
- int ret = -1;
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
@@ -1441,7 +1449,8 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!(usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot)))
return -1;
- ret = virUSBDeviceFileIterate(usb, virSecurityDACRestoreUSBLabel, mgr);
+ if (virUSBDeviceFileIterate(usb, virSecurityDACRestoreUSBLabel, mgr) < 0)
+ return -1;
break;
}
@@ -1449,7 +1458,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
g_autoptr(virPCIDevice) pci = NULL;
if (!virPCIDeviceExists(&pcisrc->addr))
- break;
+ return -1;
pci = virPCIDeviceNew(&pcisrc->addr);
@@ -1463,24 +1472,29 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!vfioGroupDev)
return -1;
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- vfioGroupDev, false);
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
+ vfioGroupDev, false) < 0) {
+ return -1;
+ }
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
return -1;
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- vfiofdDev, false);
- if (ret < 0)
- break;
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
+ vfiofdDev, false) < 0) {
+ return -1;
+ }
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- VIR_IOMMU_DEV_PATH, false);
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
+ VIR_IOMMU_DEV_PATH, false) < 0) {
+ return -1;
+ }
}
} else {
- ret = virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr);
+ if (virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr) < 0)
+ return -1;
}
break;
}
@@ -1496,7 +1510,8 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!scsi)
return -1;
- ret = virSCSIDeviceFileIterate(scsi, virSecurityDACRestoreSCSILabel, mgr);
+ if (virSCSIDeviceFileIterate(scsi, virSecurityDACRestoreSCSILabel, mgr) < 0)
+ return -1;
break;
}
@@ -1506,9 +1521,11 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!host)
return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- virSecurityDACRestoreHostLabel,
- mgr);
+ if (virSCSIVHostDeviceFileIterate(host,
+ virSecurityDACRestoreHostLabel,
+ mgr) < 0) {
+ return -1;
+ }
break;
}
@@ -1518,16 +1535,16 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
return -1;
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfiodev, false);
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfiodev, false) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- return ret;
+ return 0;
}
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 4a5f61d16b..96ca59a7a4 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2219,8 +2219,6 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev;
virSecuritySELinuxCallbackData data = {.mgr = mgr, .def = def};
- int ret = -1;
-
/* Like virSecuritySELinuxSetImageLabelInternal() for a networked
* disk, do nothing for an iSCSI hostdev
*/
@@ -2241,7 +2239,8 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
if (!usb)
return -1;
- ret = virUSBDeviceFileIterate(usb, virSecuritySELinuxSetUSBLabel, &data);
+ if (virUSBDeviceFileIterate(usb, virSecuritySELinuxSetUSBLabel, &data) < 0)
+ return -1;
break;
}
@@ -2249,7 +2248,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
g_autoptr(virPCIDevice) pci = NULL;
if (!virPCIDeviceExists(&pcisrc->addr))
- break;
+ return -1;
pci = virPCIDeviceNew(&pcisrc->addr);
@@ -2263,23 +2262,26 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
if (!vfioGroupDev)
return -1;
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev,
- false,
- &data);
+ if (virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev,
+ false,
+ &data) < 0) {
+ return -1;
+ }
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
return -1;
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data);
- if (ret)
- break;
+ if (virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data) < 0)
+ return -1;
- ret = virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data);
+ if (virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data) < 0)
+ return -1;
}
} else {
- ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data);
+ if (virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data) < 0)
+ return -1;
}
break;
}
@@ -2296,9 +2298,11 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
if (!scsi)
return -1;
- ret = virSCSIDeviceFileIterate(scsi,
- virSecuritySELinuxSetSCSILabel,
- &data);
+ if (virSCSIDeviceFileIterate(scsi,
+ virSecuritySELinuxSetSCSILabel,
+ &data) < 0) {
+ return -1;
+ }
break;
}
@@ -2308,9 +2312,11 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
if (!host)
return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- virSecuritySELinuxSetHostLabel,
- &data);
+ if (virSCSIVHostDeviceFileIterate(host,
+ virSecuritySELinuxSetHostLabel,
+ &data) < 0) {
+ return -1;
+ }
break;
}
@@ -2318,18 +2324,18 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
g_autofree char *vfiodev = NULL;
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
- return ret;
+ return -1;
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfiodev, false, &data);
+ if (virSecuritySELinuxSetHostdevLabelHelper(vfiodev, false, &data) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- return ret;
+ return 0;
}
@@ -2467,7 +2473,6 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi;
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev;
- int ret = -1;
/* Like virSecuritySELinuxRestoreImageLabelInt() for a networked
* disk, do nothing for an iSCSI hostdev
@@ -2489,7 +2494,8 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!usb)
return -1;
- ret = virUSBDeviceFileIterate(usb, virSecuritySELinuxRestoreUSBLabel, mgr);
+ if (virUSBDeviceFileIterate(usb, virSecuritySELinuxRestoreUSBLabel, mgr) < 0)
+ return -1;
break;
}
@@ -2497,7 +2503,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
g_autoptr(virPCIDevice) pci = NULL;
if (!virPCIDeviceExists(&pcisrc->addr))
- break;
+ return -1;
pci = virPCIDeviceNew(&pcisrc->addr);
@@ -2511,21 +2517,23 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!vfioGroupDev)
return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false);
+ if (virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false) < 0)
+ return -1;
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false);
- if (ret < 0)
- break;
+ if (virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false) < 0)
+ return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false);
+ if (virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false) < 0)
+ return -1;
}
} else {
- ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr);
+ if (virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr) < 0)
+ return -1;
}
break;
}
@@ -2541,7 +2549,8 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!scsi)
return -1;
- ret = virSCSIDeviceFileIterate(scsi, virSecuritySELinuxRestoreSCSILabel, mgr);
+ if (virSCSIDeviceFileIterate(scsi, virSecuritySELinuxRestoreSCSILabel, mgr) < 0)
+ return -1;
break;
}
@@ -2551,9 +2560,11 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!host)
return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- virSecuritySELinuxRestoreHostLabel,
- mgr);
+ if (virSCSIVHostDeviceFileIterate(host,
+ virSecuritySELinuxRestoreHostLabel,
+ mgr) < 0) {
+ return -1;
+ }
break;
}
@@ -2563,16 +2574,16 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false, false);
+ if (virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false, false) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- return ret;
+ return 0;
}
--
2.53.0

View File

@ -1,120 +0,0 @@
From d3c83b7a546f63aec8d8a9b55f99a726b2988a4f Mon Sep 17 00:00:00 2001
Message-ID: <d3c83b7a546f63aec8d8a9b55f99a726b2988a4f.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 2 Mar 2026 12:47:43 +0100
Subject: [PATCH] security_apparmor: Use g_auto* in
AppArmorSetSecurityHostdevLabel
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 75f698c77f0705ae9793331eadb08fbbf89572f6)
Resolves: https://redhat.atlassian.net/browse/VOYAGER-309
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/security/security_apparmor.c | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 6c5da2a650..74c5b10063 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -799,7 +799,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
virDomainHostdevDef *dev,
const char *vroot)
{
- struct SDPDOP *ptr;
+ g_autofree struct SDPDOP *ptr = NULL;
int ret = -1;
virSecurityLabelDef *secdef =
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
@@ -831,13 +831,12 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
switch (dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
- virUSBDevice *usb =
+ g_autoptr(virUSBDevice) usb =
virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot);
if (!usb)
goto done;
ret = virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr);
- virUSBDeviceFree(usb);
break;
}
@@ -850,13 +849,12 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
- char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
+ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev) {
goto done;
}
ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr);
- VIR_FREE(vfioGroupDev);
} else {
g_autofree char *vfiofdDev = NULL;
@@ -877,7 +875,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
virDomainHostdevSubsysSCSIHost *scsihostsrc = &scsisrc->u.host;
- virSCSIDevice *scsi =
+ g_autoptr(virSCSIDevice) scsi =
virSCSIDeviceNew(NULL,
scsihostsrc->adapter, scsihostsrc->bus,
scsihostsrc->target, scsihostsrc->unit,
@@ -887,13 +885,11 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
goto done;
ret = virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr);
- virSCSIDeviceFree(scsi);
-
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: {
- virSCSIVHostDevice *host = virSCSIVHostDeviceNew(hostsrc->wwpn);
+ g_autoptr(virSCSIVHostDevice) host = virSCSIVHostDeviceNew(hostsrc->wwpn);
if (!host)
goto done;
@@ -901,19 +897,16 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
ret = virSCSIVHostDeviceFileIterate(host,
AppArmorSetSecurityHostLabel,
ptr);
- virSCSIVHostDeviceFree(host);
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: {
- char *vfiodev = NULL;
+ g_autofree char *vfiodev = NULL;
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
goto done;
ret = AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr);
-
- VIR_FREE(vfiodev);
break;
}
@@ -923,7 +916,6 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
}
done:
- VIR_FREE(ptr);
return ret;
}
--
2.53.0

View File

@ -1,98 +0,0 @@
From 1aa7206312b153f5209a5c161b4345e65a762c26 Mon Sep 17 00:00:00 2001
Message-ID: <1aa7206312b153f5209a5c161b4345e65a762c26.1770714339.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 20 Jan 2026 16:19:00 +0100
Subject: [PATCH] src: Use device alias when ifname is unset in
virDomainInterfaceAddresses()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The virDomainInterfaceAddresses() API returns an array of
_virDomainInterface structs which then describe IP addresses
associated with given domain. The struct contains 'name' member
which is documented deliberately vaguely: "interface name". This
is because depending on the source of truth used (controlled by
'source' argument) the name can be wildly different from the one
in domain XML. Now, in case of source =
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP, the host's ARP table is
parsed and matching interfaces are found by comparing MAC
addresses. If it's a match then the 'name' is set to net->ifname
(corresponds to /interface/target/@dev). But that is not always
set and sometimes may be NULL (e.g. for hostdevs, usernet). We
can't change the API (like we did for hwaddr in v1.2.14-rc1~105)
because this is already released. So the next best thing to do is
to put the interface alias in there.
To be on a safe side, do the same change to the
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE case.
Resolves: https://issues.redhat.com/browse/RHEL-141496
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 4009126f17a19ea2f512f1952f4ea32d231ade85)
Resolves: https://issues.redhat.com/browse/RHEL-143933
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 16 ++++++++++++++--
src/libvirt-domain.c | 2 ++
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f950f7c75d..902c1188ef 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -15604,6 +15604,12 @@ virDomainNetDHCPInterfaces(virDomainDef *def,
goto error;
if (n_leases) {
+ const char *ifname = def->nets[i]->ifname;
+
+ if (!ifname) {
+ ifname = def->nets[i]->info.alias;
+ }
+
ifaces_ret = g_renew(virDomainInterfacePtr, ifaces_ret, ifaces_count + 1);
ifaces_ret[ifaces_count] = g_new0(virDomainInterface, 1);
iface = ifaces_ret[ifaces_count];
@@ -15612,7 +15618,7 @@ virDomainNetDHCPInterfaces(virDomainDef *def,
/* Assuming each lease corresponds to a separate IP */
iface->naddrs = n_leases;
iface->addrs = g_new0(virDomainIPAddress, iface->naddrs);
- iface->name = g_strdup(def->nets[i]->ifname);
+ iface->name = g_strdup(ifname);
iface->hwaddr = g_strdup(macaddr);
}
@@ -15666,9 +15672,15 @@ virDomainNetARPInterfaces(virDomainDef *def,
virArpTableEntry entry = table->t[j];
if (STREQ(entry.mac, macaddr)) {
+ const char *ifname = def->nets[i]->ifname;
+
+ if (!ifname) {
+ ifname = def->nets[i]->info.alias;
+ }
+
iface = g_new0(virDomainInterface, 1);
- iface->name = g_strdup(def->nets[i]->ifname);
+ iface->name = g_strdup(ifname);
iface->hwaddr = g_strdup(macaddr);
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 74c70a0a43..c7451fee05 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12880,6 +12880,8 @@ virDomainFSInfoFree(virDomainFSInfoPtr info)
* Note that for some @source values some pieces of returned @ifaces
* might be unset (e.g. VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP does not
* set IP address prefix as ARP table does not have any notion of that).
+ * Moreover, it may happen that the interface doesn't have a name. In
+ * that case, @ifaces->name is set to the interface's device alias.
*
* @ifaces->name and @ifaces->hwaddr are never NULL.
*
--
2.53.0

View File

@ -1,154 +0,0 @@
From e8cc2fdb6f842c7e5b6f23ea4ccf54d553624e67 Mon Sep 17 00:00:00 2001
Message-ID: <e8cc2fdb6f842c7e5b6f23ea4ccf54d553624e67.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 12:25:13 +0100
Subject: [PATCH] src: Use virHostdevIsPCIDeviceWith* to check for IOMMUFD
From: Pavel Hrdina <phrdina@redhat.com>
Use virHostdevIsPCIDeviceWithIOMMUFD where we need to check if hostdev
is PCI device using IOMMUFD and virHostdevIsPCIDeviceWithoutIOMMUFD
where we need to check if hostdev is PCI device not using IOMMUFD.
Fixes: 7d2f91f9cb572ab95d0916bdd1a46dd198874529
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit c1d38e9428783730f063b59ad32f08d2e80aff9f)
Resolves: https://redhat.atlassian.net/browse/VOYAGER-309
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_cgroup.c | 2 +-
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_namespace.c | 2 +-
src/qemu/qemu_validate.c | 2 +-
src/security/security_apparmor.c | 2 +-
src/security/security_dac.c | 4 ++--
src/security/security_selinux.c | 4 ++--
src/security/virt-aa-helper.c | 2 +-
8 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 6148990f19..0e1815f571 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -479,7 +479,7 @@ qemuSetupHostdevCgroup(virDomainObj *vm,
g_autofree char *path = NULL;
int perms;
- if (dev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES)
+ if (virHostdevIsPCIDeviceWithIOMMUFD(dev))
return 0;
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d419e92cdf..30bed14b0c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5260,7 +5260,7 @@ qemuBuildHostdevCommandLine(virCommand *cmd,
if (qemuCommandAddExtDevice(cmd, hostdev->info, def, qemuCaps) < 0)
return -1;
- if (subsys->u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
qemuFDPassDirectTransferCommand(hostdevPriv->vfioDeviceFd, cmd);
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index fb0734193d..4a063064f1 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -345,7 +345,7 @@ qemuDomainSetupHostdev(virDomainObj *vm,
{
g_autofree char *path = NULL;
- if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES)
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev))
return 0;
if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index aa441188cb..c39d8c869f 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -2725,7 +2725,7 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev,
return -1;
}
- if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOMMUFD)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("IOMMUFD is not supported by this version of qemu"));
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 40f13ec1a5..e53486ee0c 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -847,7 +847,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index d8cf117fc4..b891f6f121 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1283,7 +1283,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
@@ -1454,7 +1454,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 0fa50630f7..2b801aecd5 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2255,7 +2255,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
@@ -2499,7 +2499,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 29e844c7ff..af95a64c42 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1117,7 +1117,7 @@ get_files(vahControl * ctl)
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) {
+ virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
needsVfio = true;
}
--
2.53.0

View File

@ -1,53 +0,0 @@
From d4bacfba4087228a4a509f41a02aefaaeac187a0 Mon Sep 17 00:00:00 2001
Message-ID: <d4bacfba4087228a4a509f41a02aefaaeac187a0.1770825107.git.jdenemar@redhat.com>
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Feb 2026 10:55:12 +0000
Subject: [PATCH] src/esx/esx_vi.c: Debug path element comparisons
Libvirt vpx:// and esx:// URIs are quite obscure. In particular it is
very difficult to construct a correct path to a VMware resource.
Basically you are iterating over VMware structures blindly with no way
to know what your choices are at each level in the path.
This commit doesn't directly address this. It's still difficult. But
at least let's add the true path choices to the debug output so
someone could in theory use 'LIBVIRT_DEBUG=1' to find out what
possible choices exist at a path level.
For example this command fails because the label (which looks like an
IPv6 address, but is really a label) should use "::" instead of ":0:":
LIBVIRT_DEBUG=1 virsh -c 'vpx://root@.../data/aaaa:52:0:49e0:2eea:7fff:fee6:eca0/?no_verify=1'
In the debugging output we now print:
2026-02-05 10:58:25.421+0000: 1528876: debug : esxVI_LookupManagedObjectHelper:4956 : comparing path element 'aaaa:52:0:49e0:2eea:7fff:fee6:eca0' with candidate name 'aaaa:52::49e0:2eea:7fff:fee6:eca0'
2026-02-05 10:58:25.421+0000: 1528876: error : esxVI_Context_LookupManagedObjectsByPath:1098 : internal error: Could not find compute resource specified in '/data/aaaa:52:0:49e0:2eea:7fff:fee6:eca0/'
In an ideal world we should improve the error message to show the
possible choices, but the way the code is structured makes that
prohibitive.
Related: https://issues.redhat.com/browse/RHEL-145080
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 090223d01a8b8128543fd717920982ba9517bd34)
---
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 8d2ffb3f8f..cfd783622d 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -4953,6 +4953,8 @@ esxVI_LookupManagedObjectHelper(esxVI_Context *ctx,
goto cleanup;
}
+ VIR_DEBUG("comparing path element '%s' with candidate name '%s'",
+ name, name_candidate);
if (STREQ(name_candidate, name)) {
/* Found item with matching name */
break;
--
2.53.0

View File

@ -1,268 +0,0 @@
From 12ee11bc8ea918b8c7c15e52b4bbbd09e2e95fb0 Mon Sep 17 00:00:00 2001
Message-ID: <12ee11bc8ea918b8c7c15e52b4bbbd09e2e95fb0.1774023916.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 16 Mar 2026 15:30:18 +0100
Subject: [PATCH] tests: Add iommufd fdgroup test
From: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 406b7fb0bd82251d94ce1fcb5fd7e35d51e1a1b7)
Conflicts:
- tests/qemuxmlconftest.c
missing upstream commit 6d6da1cbac4f0194ca257c8ff8f5038a96791a62
Resolves: https://redhat.atlassian.net/browse/VOYAGER-309
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_process.c | 14 +++--
src/qemu/qemu_processpriv.h | 2 +
.../iommufd-q35-fd.x86_64-latest.args | 41 +++++++++++++
.../iommufd-q35-fd.x86_64-latest.xml | 60 +++++++++++++++++++
tests/qemuxmlconfdata/iommufd-q35-fd.xml | 38 ++++++++++++
tests/qemuxmlconftest.c | 9 ++-
6 files changed, 159 insertions(+), 5 deletions(-)
create mode 100644 tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/iommufd-q35-fd.xml
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2b1d47ed86..10a4a70f1c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7706,9 +7706,11 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
*
* Find passed FD via virDomainFDAssociate() API for the VM.
*
+ * Exported only to be used in tests.
+ *
* Returns: 0 on success, -1 on failure
*/
-static int
+int
qemuProcessGetPassedIommuFd(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
@@ -7728,10 +7730,14 @@ qemuProcessGetPassedIommuFd(virDomainObj *vm)
return -1;
}
- iommufd = dup(fdt->fds[0]);
+ if (fdt->testfds) {
+ iommufd = dup2(fdt->fds[0], fdt->testfds[0]);
+ } else {
+ iommufd = dup(fdt->fds[0]);
- if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
- return -1;
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
+ return -1;
+ }
priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
diff --git a/src/qemu/qemu_processpriv.h b/src/qemu/qemu_processpriv.h
index 0ba5897f40..4bef5025b9 100644
--- a/src/qemu/qemu_processpriv.h
+++ b/src/qemu/qemu_processpriv.h
@@ -37,3 +37,5 @@ void qemuProcessHandleDeviceDeleted(qemuMonitor *mon,
const char *devAlias);
int qemuProcessQMPInitMonitor(qemuMonitor *mon);
+
+int qemuProcessGetPassedIommuFd(virDomainObj *vm);
diff --git a/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args
new file mode 100644
index 0000000000..7df3d173f3
--- /dev/null
+++ b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args
@@ -0,0 +1,41 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-q35-test \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=q35-test,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-q35-test/master-key.aes"}' \
+-machine q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=2097152k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":2147483648}' \
+-overcommit mem-lock=off \
+-smp 2,sockets=2,cores=1,threads=1 \
+-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"}' \
+-device '{"driver":"pcie-root-port","port":17,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x2.0x1"}' \
+-device '{"driver":"qemu-xhci","id":"usb","bus":"pci.1","addr":"0x0"}' \
+-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","read-only":false}' \
+-device '{"driver":"ide-hd","bus":"ide.0","drive":"libvirt-1-storage","id":"sata0-0-0","bootindex":1}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"qxl-vga","id":"video0","max_outputs":1,"ram_size":67108864,"vram_size":33554432,"vram64_size_mb":0,"vgamem_mb":8,"bus":"pcie.0","addr":"0x1"}' \
+-global ICH9-LPC.noreboot=off \
+-watchdog-action reset \
+-object '{"qom-type":"iommufd","id":"iommufd0","fd":"20"}' \
+-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x3"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml
new file mode 100644
index 0000000000..a6be49cbb3
--- /dev/null
+++ b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml
@@ -0,0 +1,60 @@
+<domain type='qemu'>
+ <name>q35-test</name>
+ <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
+ <memory unit='KiB'>2097152</memory>
+ <currentMemory unit='KiB'>2097152</currentMemory>
+ <vcpu placement='static' cpuset='0-1'>2</vcpu>
+ <iommufd enabled='yes' fdgroup='iommu'/>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='sda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='1' port='0x10'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='2' port='0x11'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
+ </controller>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <controller type='usb' index='0' model='qemu-xhci'>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1' primary='yes'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+ </video>
+ <hostdev mode='subsystem' type='pci' managed='yes'>
+ <source>
+ <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </hostdev>
+ <watchdog model='itco' action='reset'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/iommufd-q35-fd.xml b/tests/qemuxmlconfdata/iommufd-q35-fd.xml
new file mode 100644
index 0000000000..1cef31fffa
--- /dev/null
+++ b/tests/qemuxmlconfdata/iommufd-q35-fd.xml
@@ -0,0 +1,38 @@
+<domain type='qemu'>
+ <name>q35-test</name>
+ <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
+ <memory unit='KiB'>2097152</memory>
+ <currentMemory unit='KiB'>2097152</currentMemory>
+ <vcpu placement='static' cpuset='0-1'>2</vcpu>
+ <iommufd enabled='yes' fdgroup='iommu'/>
+ <os>
+ <type arch='x86_64' machine='q35'>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>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='sda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <hostdev mode='subsystem' type='pci' managed='yes'>
+ <source>
+ <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </hostdev>
+ <controller type='sata' index='0'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <video>
+ <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
+ </video>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index b15bd115c2..26287e1f8d 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -27,6 +27,9 @@
# include "configmake.h"
# include "testutilsqemuschema.h"
+# define LIBVIRT_QEMU_PROCESSPRIV_H_ALLOW
+# include "qemu/qemu_processpriv.h"
+
# define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW
# include "qemu/qemu_capspriv.h"
@@ -408,7 +411,9 @@ testQemuPrepareHostdev(virDomainObj *vm)
}
}
- if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
+ if (vm->def->iommufd_fdgroup) {
+ ignore_value(qemuProcessGetPassedIommuFd(vm));
+ } else if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
int iommufd = 0;
priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
}
@@ -3102,6 +3107,8 @@ mymain(void)
DO_TEST_CAPS_LATEST("iommufd");
DO_TEST_CAPS_LATEST("iommufd-q35");
+ DO_TEST_CAPS_ARCH_LATEST_FULL("iommufd-q35-fd", "x86_64",
+ ARG_FD_GROUP, "iommu", false, 1, 20);
DO_TEST_CAPS_ARCH_LATEST("iommufd-virt", "aarch64");
DO_TEST_CAPS_ARCH_LATEST("iommufd-virt-pci-bus-single", "aarch64");
--
2.53.0

View File

@ -1,5 +1,5 @@
From 980f098c11773796a35b8e2cb6ae9a1c2296c8b4 Mon Sep 17 00:00:00 2001
Message-ID: <980f098c11773796a35b8e2cb6ae9a1c2296c8b4.1779098642.git.phrdina@redhat.com>
From e9fd118c9efe3738217b932e7d2fe03f15c5ff83 Mon Sep 17 00:00:00 2001
Message-ID: <e9fd118c9efe3738217b932e7d2fe03f15c5ff83.1786096789.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Tue, 25 Nov 2025 11:17:04 -0800
Subject: [PATCH] tests: Add qemuxmlconftest for ACPI EGM memory device
@ -20,7 +20,7 @@ QEMU command line generation for the EGM device.
Signed-off-by: Ian May <ianm@nvidia.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Resolves: https://redhat.atlassian.net/browse/VOYAGER-13
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1109
---
src/conf/domain_conf.c | 5 +-
src/conf/domain_postparse.c | 5 +-
@ -31,18 +31,18 @@ Resolves: https://redhat.atlassian.net/browse/VOYAGER-13
.../acpi-egm-memory.aarch64-latest.args | 47 +++++++
.../acpi-egm-memory.aarch64-latest.xml | 124 ++++++++++++++++++
tests/qemuxmlconfdata/acpi-egm-memory.xml | 124 ++++++++++++++++++
tests/qemuxmlconftest.c | 8 +-
10 files changed, 381 insertions(+), 4 deletions(-)
tests/qemuxmlconftest.c | 7 +-
10 files changed, 380 insertions(+), 4 deletions(-)
create mode 100644 tests/qemuegmmock.c
create mode 100644 tests/qemuxmlconfdata/acpi-egm-memory.aarch64-latest.args
create mode 100644 tests/qemuxmlconfdata/acpi-egm-memory.aarch64-latest.xml
create mode 100644 tests/qemuxmlconfdata/acpi-egm-memory.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 038476edd7..d3236b7425 100644
index 74b07ad88e..43515ed98f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8930,8 +8930,11 @@ virDomainDefGetMemoryInitial(const virDomainDef *def)
@@ -9031,8 +9031,11 @@ virDomainDefGetMemoryInitial(const virDomainDef *def)
size_t i;
unsigned long long ret = def->mem.total_memory;
@ -56,7 +56,7 @@ index 038476edd7..d3236b7425 100644
return ret;
}
diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c
index 0181d21f0e..bb4a61b7d8 100644
index 2c21e06910..0654a8d395 100644
--- a/src/conf/domain_postparse.c
+++ b/src/conf/domain_postparse.c
@@ -44,8 +44,11 @@ virDomainDefPostParseMemory(virDomainDef *def,
@ -73,10 +73,10 @@ index 0181d21f0e..bb4a61b7d8 100644
if (numaMemory) {
/* update the sizes in XML if nothing was set in the XML or ABI update
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c5e3d09360..d1bc9aa621 100644
index 62aa602fed..24e4b086b0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8085,6 +8085,8 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
@@ -8096,6 +8096,8 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
}
for (i = 0; i < def->nmems; i++) {
@ -86,7 +86,7 @@ index c5e3d09360..d1bc9aa621 100644
switch (def->mems[i]->model) {
diff --git a/src/util/virfile.h b/src/util/virfile.h
index ce2ffb8ed4..5203ef4425 100644
index 8c9ad59898..67acc2efc5 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -167,7 +167,7 @@ int virFileReadHeaderQuiet(const char *path, int maxlen, char **buf)
@ -99,16 +99,16 @@ index ce2ffb8ed4..5203ef4425 100644
G_GNUC_WARN_UNUSED_RESULT ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
int virFileReadBufQuiet(const char *file, char *buf, int len)
diff --git a/tests/meson.build b/tests/meson.build
index bb6ee6b4ee..28ee8591a3 100644
index d1d26fcea2..e7d3a6aabf 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -174,6 +174,7 @@ if conf.has('WITH_QEMU')
@@ -176,6 +176,7 @@ if conf.has('WITH_QEMU')
{ 'name': 'qemucaps2xmlmock' },
{ 'name': 'qemucapsprobemock', 'link_with': [ test_qemu_driver_lib ] },
{ 'name': 'qemucpumock' },
+ { 'name': 'qemuegmmock' },
{ 'name': 'qemuhotplugmock', 'link_with': [ test_qemu_driver_lib, test_utils_qemu_lib, test_utils_lib ] },
{ 'name': 'qemuxml2argvmock' },
{ 'name': 'qemuxml2argvmock', 'link_with': [ test_utils_lib ] },
{ 'name': 'virhostidmock' },
diff --git a/tests/qemuegmmock.c b/tests/qemuegmmock.c
new file mode 100644
@ -185,7 +185,7 @@ index 0000000000..c915212f45
+}
diff --git a/tests/qemuxmlconfdata/acpi-egm-memory.aarch64-latest.args b/tests/qemuxmlconfdata/acpi-egm-memory.aarch64-latest.args
new file mode 100644
index 0000000000..41d1fcc026
index 0000000000..358ddccb54
--- /dev/null
+++ b/tests/qemuxmlconfdata/acpi-egm-memory.aarch64-latest.args
@@ -0,0 +1,47 @@
@ -219,7 +219,7 @@ index 0000000000..41d1fcc026
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-chardev socket,id=charmonitor,fd=@mon-fd@,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
@ -497,10 +497,10 @@ index 0000000000..bd73d613e5
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 26287e1f8d..4c13dca6d0 100644
index 5c280fc141..0473addbe0 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -3275,6 +3275,10 @@ mymain(void)
@@ -3174,6 +3174,10 @@ mymain(void)
DO_TEST_CAPS_LATEST("devices-acpi-index");
@ -511,16 +511,12 @@ index 26287e1f8d..4c13dca6d0 100644
DO_TEST_CAPS_ARCH_LATEST_FULL("hvf-x86_64-q35-headless", "x86_64", ARG_CAPS_VARIANT, "+hvf", ARG_END);
DO_TEST_CAPS_ARCH_LATEST_FULL("hvf-aarch64-virt-headless", "aarch64", ARG_CAPS_VARIANT, "+hvf", ARG_END);
/* HVF guests should not work on Linux with KVM */
@@ -3381,7 +3385,9 @@ VIR_TEST_MAIN_PRELOAD(mymain,
@@ -3283,4 +3287,5 @@ VIR_TEST_MAIN_PRELOAD(mymain,
VIR_TEST_MOCK("domaincaps"),
VIR_TEST_MOCK("virrandom"),
VIR_TEST_MOCK("qemucpu"),
- VIR_TEST_MOCK("virnuma"))
+ VIR_TEST_MOCK("virnuma"),
+ VIR_TEST_MOCK("virpci"),
+ VIR_TEST_MOCK("qemuegm"))
#else
--
2.54.0
2.55.0

View File

@ -1,111 +0,0 @@
From 0bb3bb84670dbd45c6eca2d108b2d4d5a7754ef4 Mon Sep 17 00:00:00 2001
Message-ID: <0bb3bb84670dbd45c6eca2d108b2d4d5a7754ef4.1766070439.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 5 Dec 2025 15:09:15 +0100
Subject: [PATCH] tests: Test virFileIsSharedFSOverride
Technically virFileIsSharedFSOverride is available on any OS, but we
need a mocked realpath() to test it. Because the virfilemock library
also mocks statfs() which is only available on Linux, we don't even try
to load the library anywhere else. Thus we need to skip testing
virFileIsSharedFSOverride on non-Linux too.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 121d179e068b584f62ea2c029d89a44e67c909c0)
https://issues.redhat.com/browse/RHEL-102925
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
tests/virfiletest.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/tests/virfiletest.c b/tests/virfiletest.c
index e05925a321..ccd76a3fac 100644
--- a/tests/virfiletest.c
+++ b/tests/virfiletest.c
@@ -329,6 +329,55 @@ testFileIsSharedFSType(const void *opaque G_GNUC_UNUSED)
}
+static const char *shared_filesystems[] = {
+ "/run/user/501/gvfs",
+ "/nfs",
+ "/gluster",
+ "/ceph/multi",
+ "/gpfs/data/blaf",
+ "/quobyte",
+ NULL,
+};
+
+static int
+testFileIsSharedFSOverride(const void *opaque G_GNUC_UNUSED)
+{
+#ifndef __linux__
+ return EXIT_AM_SKIP;
+#else
+ const struct testFileIsSharedFSType *data = opaque;
+ g_autofree char *mtabFile = NULL;
+ bool actual;
+ int ret = -1;
+
+ /* mtab is used by mocked realpath to decide whether a given path exists */
+ mtabFile = g_strdup_printf(abs_srcdir "/virfiledata/%s", data->mtabFile);
+
+ if (!g_setenv("LIBVIRT_MTAB", mtabFile, true)) {
+ fprintf(stderr, "Unable to set env variable\n");
+ goto cleanup;
+ }
+
+ actual = virFileIsSharedFSOverride(data->filename,
+ (char * const *) shared_filesystems);
+
+ if (actual != data->expected) {
+ fprintf(stderr, "FS of '%s' is %s. Expected: %s\n",
+ data->filename,
+ actual ? "shared" : "not shared",
+ data->expected ? "shared" : "not shared");
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ g_unsetenv("LIBVIRT_MTAB");
+ return ret;
+#endif
+}
+
+
static int
mymain(void)
{
@@ -439,6 +488,26 @@ mymain(void)
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gpfs/data", true);
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/quobyte", true);
+#define DO_TEST_FILE_IS_SHARED_FS_OVERRIDE(mtab, file, exp) \
+ do { \
+ struct testFileIsSharedFSType data = { \
+ .mtabFile = mtab, .filename = file, .expected = exp \
+ }; \
+ if (virTestRun(virTestCounterNext(), testFileIsSharedFSOverride, &data) < 0) \
+ ret = -1; \
+ } while (0)
+
+ virTestCounterReset("testFileIsSharedFSOverride ");
+ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts2.txt", "/boot/vmlinuz", false);
+ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts2.txt", "/run/user/501/gvfs/some/file", true);
+ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/nfs/file", true);
+ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/gluster/file", true);
+ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/some/symlink/file", true);
+ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/ceph/file", false);
+ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/ceph/multi/file", true);
+ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/gpfs/data", false);
+ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/quobyte", true);
+
return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
--
2.52.0

View File

@ -1,201 +0,0 @@
From d30c21439f3847ecc229db9355eb802f0256a3f0 Mon Sep 17 00:00:00 2001
Message-ID: <d30c21439f3847ecc229db9355eb802f0256a3f0.1766070438.git.jdenemar@redhat.com>
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
Date: Fri, 5 Dec 2025 08:50:51 +0100
Subject: [PATCH] tests: add test for a single per-device smmuv3
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 45ff1c002629dadd9d94b91742ffb985b0fe027f)
https://issues.redhat.com/browse/RHEL-74200
Signed-off-by: Ján Tomko <jtomko@redhat.com>
---
...-smmuv3-pci-bus-single.aarch64-latest.args | 40 +++++++++++++
...u-smmuv3-pci-bus-single.aarch64-latest.xml | 59 +++++++++++++++++++
.../iommu-smmuv3-pci-bus-single.xml | 46 +++++++++++++++
tests/qemuxmlconftest.c | 1 +
4 files changed, 146 insertions(+)
create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args
create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.xml
create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.xml
diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args
new file mode 100644
index 0000000000..976467e641
--- /dev/null
+++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args
@@ -0,0 +1,40 @@
+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-aarch64 \
+-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 \
+-accel tcg \
+-cpu cortex-a15 \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"mach-virt.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"pxb-pcie","bus_nr":252,"id":"pci.1","bus":"pcie.0","addr":"0x1"}' \
+-device '{"driver":"pxb-pcie","bus_nr":248,"id":"pci.2","bus":"pcie.0","addr":"0x2"}' \
+-device '{"driver":"pcie-root-port","port":0,"chassis":21,"id":"pci.3","bus":"pci.1","addr":"0x0"}' \
+-device '{"driver":"pcie-root-port","port":168,"chassis":22,"id":"pci.4","bus":"pci.2","addr":"0x0"}' \
+-device '{"driver":"arm-smmuv3","primary-bus":"pci.1","id":"iommu0"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-object '{"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"}' \
+-device '{"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.3","addr":"0x0"}' \
+-object '{"qom-type":"rng-random","id":"objrng1","filename":"/dev/urandom"}' \
+-device '{"driver":"virtio-rng-pci","rng":"objrng1","id":"rng1","bus":"pci.4","addr":"0x0"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.xml b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.xml
new file mode 100644
index 0000000000..e6071fd71b
--- /dev/null
+++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.xml
@@ -0,0 +1,59 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='aarch64' machine='virt'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <gic version='2'/>
+ </features>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>cortex-a15</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-aarch64</emulator>
+ <controller type='usb' index='0' model='none'/>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-expander-bus'>
+ <model name='pxb-pcie'/>
+ <target busNr='252'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-expander-bus'>
+ <model name='pxb-pcie'/>
+ <target busNr='248'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </controller>
+ <controller type='pci' index='3' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='21' port='0x0'/>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='pci' index='4' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='22' port='0xa8'/>
+ <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
+ </controller>
+ <audio id='1' type='none'/>
+ <memballoon model='none'/>
+ <rng model='virtio'>
+ <backend model='random'>/dev/urandom</backend>
+ <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
+ </rng>
+ <rng model='virtio'>
+ <backend model='random'>/dev/urandom</backend>
+ <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
+ </rng>
+ <iommu model='smmuv3'>
+ <driver pciBus='1'/>
+ </iommu>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.xml b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.xml
new file mode 100644
index 0000000000..6f40a19740
--- /dev/null
+++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.xml
@@ -0,0 +1,46 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='aarch64' machine='virt'>hvm</type>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu-system-aarch64</emulator>
+ <controller type='usb' model='none'/>
+ <memballoon model='none'/>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-expander-bus'>
+ <model name='pxb-pcie'/>
+ <target busNr='252'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-expander-bus'>
+ <model name='pxb-pcie'/>
+ <target busNr='248'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </controller>
+ <controller type='pci' index='3' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='21' port='0x0'/>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='pci' index='4' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='22' port='0xa8'/>
+ <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
+ </controller>
+ <rng model='virtio'>
+ <backend model='random'>/dev/urandom</backend>
+ <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
+ </rng>
+ <rng model='virtio'>
+ <backend model='random'>/dev/urandom</backend>
+ <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
+ </rng>
+ <iommu model='smmuv3'>
+ <driver pciBus='1'/>
+ </iommu>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index de03c58c8a..9a3257ea55 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -3039,6 +3039,7 @@ mymain(void)
DO_TEST_CAPS_LATEST_ABI_UPDATE("intel-iommu-eim-autoadd-v2");
DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64");
DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3-pci-bus", "aarch64");
+ DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3-pci-bus-single", "aarch64");
DO_TEST_CAPS_LATEST("virtio-iommu-x86_64");
DO_TEST_CAPS_ARCH_LATEST("virtio-iommu-aarch64", "aarch64");
DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-wrong-machine");
--
2.52.0

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