libvirt-11.10.0-13.el9

- conf: Parse hyperv features even for host-model (RHEL-151688)
- qemu: Wire up new hyperv host-model mode behavior (RHEL-151688)
- Introduce EXPAND_CPU_FEATURES flag for domain capabilities (RHEL-153653)
- qemu: Implement VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES (RHEL-153653)
- virsh: Add --expand-cpu-features option for domcapabilities (RHEL-153653)
- docs: Clarify host-model description in domain capabilities (RHEL-153653)
- qemu: Fix job handling when domain dies in post-copy migration (RHEL-145179)
- security_apparmor: Use g_auto* in AppArmorSetSecurityHostdevLabel (RHEL-159902)
- security: Cleanup hostdev label error logic (RHEL-159902)
- qemu: Fix IOMMUFD and VFIO security labels (RHEL-159902)
- viriommufd: Set IOMMU_OPTION_RLIMIT_MODE only when running privileged (RHEL-156803)
- conf: Move and rename virStorageSourceFDTuple object (RHEL-156803)
- conf: Refactor virHostdevIsPCIDevice (RHEL-156803)
- hypervisor: Fix virHostdevNeedsVFIO detection (RHEL-156803)
- qemu: Expand call to qemuDomainNeedsVFIO (RHEL-156803)
- qemu: Update qemuDomainNeedsVFIO to ignore PCI hostdev with IOMMUFD (RHEL-156803)
- src: Use virHostdevIsPCIDeviceWith* to check for IOMMUFD (RHEL-156803)
- conf: Introduce domain iommufd element (RHEL-156803)
- qemu: Implement iommufd (RHEL-156803)
- conf: Add iommufd fdgroup support (RHEL-156803)
- qemu: Implement iommufd fdgroup (RHEL-156803)
- tests: Add iommufd fdgroup test (RHEL-156803)
- hypervisor: Call virWaitForDevices() after detaching host devices (RHEL-156803)
- qemuMigrationSrcBeginXML: Don't call 'qemuMigrationSrcBeginPhaseBlockDirtyBitmaps' with offline VM (RHEL-173433)
- qemuMigrationSrcBeginPhase: Don't call 'qemuBlockNodesEnsureActive' with offline VM (RHEL-173433)
- util: virGetSubIDs: do not limit file size (RHEL-174491)
- cpu_conf: Introduce virCPUDefSortFeatures (RHEL-177364)
- qemu_capabilities: Split virQEMUCapsFillDomainCPUCaps (RHEL-177364)
- qemu: Move domain caps flags handling to virQEMUCapsFillDomainCPUHostModel (RHEL-177364)
- qemu_capabilities: Always sort features in host-model CPU (RHEL-177364)
- qemu_capabilities: Use g_autoptr in virQEMUCapsInitHostCPUModel (RHEL-177364)
- qemu_capabilities: Split conditions in virQEMUCapsInitHostCPUModel (RHEL-177364)
- qemu_capabilities: Cache expanded CPU (RHEL-177364)
- domaincapstest: Test EXPAND_CPU_FEATURES flag (RHEL-177364)
- util: Publish and mock virHostCPUGetMSRFromKVM (RHEL-177364)
- cpu_x86: Introduce virCPUx86DataAddMSR (RHEL-177364)
- cpu: Introduce virCPUUpdateFeatures (RHEL-177364)
- Fix documentation of VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES (RHEL-177364)
- Introduce VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag (RHEL-177364)
- virsh: Add --supported-cpu-features option for domcapabilities (RHEL-177364)
- domaincapstest: Test SUPPORTED_CPU_FEATURES flag (RHEL-177364)
- qemu_capabilities: Fix domain capabilities on AMD CPUs (RHEL-177364)
- distro: Replace old gating with tmt

Resolves: RHEL-145179, RHEL-151688, RHEL-153653, RHEL-156803, RHEL-159902
Resolves: RHEL-173433, RHEL-174491, RHEL-177364
This commit is contained in:
Jiri Denemark 2026-06-04 13:06:07 +02:00
parent 24db687d3a
commit 884d801843
46 changed files with 55710 additions and 11 deletions

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

View File

@ -1,10 +0,0 @@
# recipients: libvirt-qe
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
subject_type: brew-build
rules:
- !PassingTestCaseRule {test_case_name: libvirt-ci.libvirt.brew-build.gating.x86_64.tier1.functional}
- !PassingTestCaseRule {test_case_name: libvirt-ci.libvirt-python.brew-build.gating.x86_64.tier1.functional}
- !PassingTestCaseRule {test_case_name: libvirt-ci.libvirt.brew-build.gating.s390x.tier1.functional}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,160 @@
From 99ca73f9c43c7a266cf65f0012a5350197d0f229 Mon Sep 17 00:00:00 2001
Message-ID: <99ca73f9c43c7a266cf65f0012a5350197d0f229.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 15:28:17 +0100
Subject: [PATCH] conf: Add iommufd fdgroup support
This will allow management applications running libvirt without
necessary permissions to pass FD for /dev/iommu with per-process
locked memory accounting enabled.
Kernel uses per-user locked memory accounting by default which may
cause error while starting multiple VMs with host devices using IOMMUFD.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 58875a6df679c5272f61028d33bf1380c51b0d5b)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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 86b3bad903..225152e0f2 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 1e91561fea..cec0f88f0f 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);
@@ -19765,6 +19767,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;
}
@@ -27998,6 +28002,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 e12064a3ab..8c8c11c0cf 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3232,6 +3232,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 4558e7b210..3e6ba5e609 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1995,6 +1995,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)
@@ -2056,6 +2069,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 81b57a937a..9fde565d94 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.54.0

View File

@ -0,0 +1,218 @@
From 28b77cb65fd0eedbd017d97d803256265ce3cbf4 Mon Sep 17 00:00:00 2001
Message-ID: <28b77cb65fd0eedbd017d97d803256265ce3cbf4.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 11:57:57 +0100
Subject: [PATCH] conf: Introduce domain iommufd element
In addition to configuring IOMMUFD for each host device add
configuration for the whole VM. This will be extended to add support for
passing FD to libvirt from management applications.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit c03b8f0804f648a2bbc2eb7e957f2f8821b8e167)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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 5ec9a41aac..86b3bad903 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 576a1bd79b..1e91561fea 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19743,6 +19743,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,
@@ -19821,6 +19846,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;
@@ -27958,6 +27986,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)
@@ -29482,6 +29526,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 f1c8478208..e12064a3ab 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3231,6 +3231,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 afdf7bfc1a..81b57a937a 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.54.0

View File

@ -0,0 +1,330 @@
From 15b1edcb2dca52b4d2276359c1eeaa97d66ac400 Mon Sep 17 00:00:00 2001
Message-ID: <15b1edcb2dca52b4d2276359c1eeaa97d66ac400.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 16:59:01 +0100
Subject: [PATCH] conf: Move and rename virStorageSourceFDTuple object
Associating FD can be used by other parts of VM so rename it to generic
virDomainFDTuple.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit f89e3dbce809f64246a8fe5ef0d05a63a28a05c0)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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 ecd19663ce..8db9cbb6a2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20241,7 +20241,7 @@ qemuDomainFDHashCloseConnect(virDomainObj *vm,
virConnectPtr conn)
{
qemuDomainObjPrivate *priv = QEMU_DOMAIN_PRIVATE(vm);
- virStorageSourceFDTuple *data;
+ virDomainFDTuple *data;
GHashTableIter htitr;
if (!priv->fds)
@@ -20265,7 +20265,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;
@@ -20283,7 +20283,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.54.0

View File

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

View File

@ -0,0 +1,80 @@
From 7af5a1f92b63d250922e04b56cae67bfb65fa4f4 Mon Sep 17 00:00:00 2001
Message-ID: <7af5a1f92b63d250922e04b56cae67bfb65fa4f4.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 11:47:21 +0100
Subject: [PATCH] conf: Refactor virHostdevIsPCIDevice
Future patches will need to check if the host device uses IOMMUFD or not
but we also need to keep a function that will check only if it is PCI device.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit d0afa0a842ce8a6dcb3f881d7dccdf5198f78fa7)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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 35de8bab6b..59df028192 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32782,6 +32782,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
@@ -32791,8 +32818,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);
}
@@ -32805,9 +32831,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.54.0

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
From b338719eb9908c7dfd493d5ab4a1b0bcc2258d9b Mon Sep 17 00:00:00 2001
Message-ID: <b338719eb9908c7dfd493d5ab4a1b0bcc2258d9b.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Thu, 26 Mar 2026 14:32:36 +0100
Subject: [PATCH] hypervisor: Call virWaitForDevices() after detaching host
devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On systems with selinux enabled starting a VM with managed host device
using IOMMUFD backend can run into race-condition where both libvirt and
udev are setting selinux label on /dev/vfio/devices/vfioX device. If
udev is the last one to set selinux label starting VM fails with:
error: internal error: QEMU unexpectedly closed the monitor (vm='test'): 2026-03-26T15:47:36.620422Z qemu-kvm: -device {"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"20","bus":"pci.7","addr":"0x0"}: vfio hostdev0: Failed to add fd 20 to KVM VFIO device: Invalid argument
We need to wait for udev to finish processing all events.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit b96ea4db3aabac4790d6e1d53e2f309f5e73efae)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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.54.0

View File

@ -0,0 +1,98 @@
From 2f8eef47f391248abf5253c6836520100d5d49c1 Mon Sep 17 00:00:00 2001
Message-ID: <2f8eef47f391248abf5253c6836520100d5d49c1.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 11:57:43 +0100
Subject: [PATCH] hypervisor: Fix virHostdevNeedsVFIO detection
Function virHostdevNeedsVFIO is used only in QEMU to figure out if the
host device needs access to /dev/vfio/vfio, for PCI host devices that is
true only if libvirt is not using IOMMUFD.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit ffa8020d3665f7ff27c6b82e88d3a93674155c8d)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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 59df028192..99d2a0aa53 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32835,6 +32835,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 69a8e79c6d..8f5780ee4c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4719,6 +4719,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.54.0

View File

@ -0,0 +1,51 @@
From 5512f4ffa8f4ea8a4afd354e4592b69dc5c39c61 Mon Sep 17 00:00:00 2001
Message-ID: <5512f4ffa8f4ea8a4afd354e4592b69dc5c39c61.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 12:52:05 +0100
Subject: [PATCH] qemu: Expand call to qemuDomainNeedsVFIO
The function qemuDomainNeedsVFIO() was originally used by other parts
of qemu code to figure out if the VM needs /dev/vfio/vfio.
Later it was also used by code calculating locked memory limit for all
architectures, and after that change again and used only for PPC64.
Now it needs to be changed again due to IOMMUFD support, the
/dev/vfio/vfio device is used by QEMU only if IOMMUFD is not used
but for accounting we still need consider all PCI host devices
because if IOMMUFD is used it still requires increasing locked
memory limit.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit c89b2bf1a80e3261bd18cdb352be1ffce9f4639e)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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.54.0

View File

@ -0,0 +1,245 @@
From 39dd90e66f661ce816592c1ee7cfd5bba54ea6f5 Mon Sep 17 00:00:00 2001
Message-ID: <39dd90e66f661ce816592c1ee7cfd5bba54ea6f5.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 27 Feb 2026 17:55:34 +0100
Subject: [PATCH] qemu: Fix IOMMUFD and VFIO security labels
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When IOMMUFD support was introduced it incorrectly tried to label
`/dev/iommu` and `/dev/vfio/devices/vfioX` but they are not added to
QEMU namespace because libvirt opens FDs and passes these FDs to QEMU.
We need to label these FDs instead.
Fixes: 7d2f91f9cb572ab95d0916bdd1a46dd198874529
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 03f2672ab4eff8ee01410c9acba6288bfb4fa231)
Resolves: https://redhat.atlassian.net/browse/RHEL-159902
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 29601683a0..0a69063a4b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7691,13 +7691,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;
@@ -7712,16 +7715,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;
@@ -7739,7 +7747,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.54.0

View File

@ -0,0 +1,60 @@
From 0c8a23f5f3e063b35b890d5538e5497f51d1095c Mon Sep 17 00:00:00 2001
Message-ID: <0c8a23f5f3e063b35b890d5538e5497f51d1095c.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 23 Feb 2026 16:23:10 +0100
Subject: [PATCH] qemu: Fix job handling when domain dies in post-copy
migration
When a domain is in post-copy migration phase, we need to keep the job
active if something fails to protect the domain from changes.
Unfortunately, there is a race between migration code and
qemuProcessStop that can cause the job to stay active even when the
domain is gone and thus preventing the domain from being started again
(until virtqemud is restarted). The race is caused by unlocking the vm
object when calling virConnectUnregisterCloseCallback. While the domain
is unlocked qemuProcessStop can finish its work and the domain may no
longer be active when we get the lock back. The post-copy path does not
properly check if a domain is still active.
Instead of adding the virDomainObjIsActive check in all places where
this could happen, we can add it in virDomainObjIsPostcopy and
virDomainObjIsFailedPostcopy and let the code take the pre-copy cleanup
path. Clearly an inactive domain can never be in (failed) post-copy
migration.
https://issues.redhat.com/browse/RHEL-145179
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 3d1e6d92de784e5c9d2a5e4bc18829c92278343a)
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/conf/domain_conf.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1f7b1ca340..35de8bab6b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30493,6 +30493,9 @@ bool
virDomainObjIsFailedPostcopy(virDomainObj *dom,
virDomainJobObj *job)
{
+ if (!virDomainObjIsActive(dom))
+ return false;
+
if (job && job->asyncPaused &&
(job->asyncJob == VIR_ASYNC_JOB_MIGRATION_IN ||
job->asyncJob == VIR_ASYNC_JOB_MIGRATION_OUT))
@@ -30509,6 +30512,9 @@ bool
virDomainObjIsPostcopy(virDomainObj *dom,
virDomainJobObj *job)
{
+ if (!virDomainObjIsActive(dom))
+ return false;
+
if (virDomainObjIsFailedPostcopy(dom, job))
return true;
--
2.54.0

View File

@ -0,0 +1,47 @@
From eccea5104691012040f130ee0d400c2cc0b174f7 Mon Sep 17 00:00:00 2001
Message-ID: <eccea5104691012040f130ee0d400c2cc0b174f7.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 11 Mar 2026 12:12:40 +0100
Subject: [PATCH] qemu: Implement
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 3215fee34967c49f37a965154879fc5860293cac)
https://issues.redhat.com/browse/RHEL-153653
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_driver.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f3e7410f9e..ecd19663ce 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16720,7 +16720,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
virDomainVirtType virttype;
g_autoptr(virDomainCaps) domCaps = NULL;
- virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES,
+ virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES |
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
NULL);
if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0)
@@ -16746,6 +16747,12 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
VIR_CPU_FEATURE_DISABLE);
}
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) {
+ virCPUDef *cpu = domCaps->cpu.hostModel;
+ if (cpu && virCPUExpandFeatures(arch, cpu) < 0)
+ return NULL;
+ }
+
return virDomainCapsFormat(domCaps);
}
--
2.54.0

View File

@ -0,0 +1,127 @@
From 8cdc3bb132898c37fe17762aba7dabb59819ce0a Mon Sep 17 00:00:00 2001
Message-ID: <8cdc3bb132898c37fe17762aba7dabb59819ce0a.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 16 Mar 2026 15:29:32 +0100
Subject: [PATCH] qemu: Implement iommufd fdgroup
When fdgroup is used for iommufd we will start QEMU with -object iommufd
even if the VM has no host device. When virDomainFDAssociate() is used
the FD libvirt is holding is closed with connection.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 0a83b28795f0c18592f9d842927528f0676cc56d)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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 23e799de3c..db72407ecc 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5360,8 +5360,10 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd,
qemuDomainObjPrivate *priv = vm->privateData;
g_autoptr(virJSONValue) props = NULL;
- if (!virDomainDefHasPCIHostdevWithIOMMUFD(def))
+ if (!virDomainDefHasPCIHostdevWithIOMMUFD(def) &&
+ !def->iommufd_fdgroup) {
return 0;
+ }
qemuFDPassDirectTransferCommand(priv->iommufd, cmd);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 25fe699bb3..8944062aa4 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1624,7 +1624,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0)
goto error;
- if (!priv->iommufdState) {
+ if (!priv->iommufdState && !vm->def->iommufd_fdgroup) {
if (qemuProcessOpenIommuFd(vm) < 0)
goto error;
@@ -5031,7 +5031,7 @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver,
}
}
- if (priv->iommufdState &&
+ if (priv->iommufdState && !vm->def->iommufd_fdgroup &&
!virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
qemuDomainObjEnterMonitor(vm);
ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false));
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d13bce8fcf..e4746374f6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7706,6 +7706,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
@@ -7761,9 +7799,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.54.0

View File

@ -0,0 +1,119 @@
From e52edf2ed7f3e1e379fb85ae0c0870113912c9d6 Mon Sep 17 00:00:00 2001
Message-ID: <e52edf2ed7f3e1e379fb85ae0c0870113912c9d6.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 17:59:01 +0100
Subject: [PATCH] qemu: Implement iommufd
Ideally this should be done in qemuDomainHostdevDefPostParse but that
would require a lot of refactoring mainly due to how interface backed by
hostdev works.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit fc516031ed865f78d590068424ada19a941046ba)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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 9b8b378b1f..d13bce8fcf 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.54.0

View File

@ -0,0 +1,196 @@
From 9ec1c8fc52cd3150712f5ada134e070fbdabb7bb Mon Sep 17 00:00:00 2001
Message-ID: <9ec1c8fc52cd3150712f5ada134e070fbdabb7bb.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 12:36:48 +0200
Subject: [PATCH] qemu: Move domain caps flags handling to
virQEMUCapsFillDomainCPUHostModel
We will need to generate the capabilities in a different way based on
the flags.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit b4d3572198848e6a2886352e1a48b46afa37bec1)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 34 ++++++++++++++++++++++++----------
src/qemu/qemu_capabilities.h | 3 ++-
src/qemu/qemu_conf.c | 6 ++++--
src/qemu/qemu_conf.h | 3 ++-
src/qemu/qemu_driver.c | 15 ++-------------
tests/domaincapstest.c | 2 +-
6 files changed, 35 insertions(+), 28 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0b32296cc8..c17b55420d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6584,14 +6584,26 @@ virQEMUCapsFillDomainCPUMaximum(virDomainCaps *domCaps)
static void
virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
- virDomainCaps *domCaps)
+ virDomainCaps *domCaps,
+ unsigned int flags)
{
- virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED);
+ virQEMUCapsHostCPUType cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
+ virCPUDef *cpu;
- domCaps->cpu.hostModel = virCPUDefCopy(cpu);
- domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
- domCaps->virttype);
+ cpu = virCPUDefCopy(virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
+ cpuType));
+
+ cpu->addr = virQEMUCapsGetHostPhysAddr(qemuCaps, domCaps->virttype);
+
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES) {
+ virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, domCaps->virttype,
+ cpu, VIR_CPU_FEATURE_DISABLE);
+ }
+
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
+ virCPUExpandFeatures(domCaps->arch, cpu);
+
+ domCaps->cpu.hostModel = cpu;
}
@@ -6616,7 +6628,8 @@ virQEMUCapsFillDomainCPUCustom(virQEMUCaps *qemuCaps,
static void
virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
virArch hostarch,
- virDomainCaps *domCaps)
+ virDomainCaps *domCaps,
+ unsigned int flags)
{
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_PASSTHROUGH,
@@ -6633,7 +6646,7 @@ virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_MODEL,
domCaps->machine)) {
- virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps);
+ virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps, flags);
}
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
@@ -7263,7 +7276,8 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
virQEMUCaps *qemuCaps,
virArch hostarch,
virDomainCaps *domCaps,
- bool privileged)
+ bool privileged,
+ unsigned int flags)
{
virDomainCapsOS *os = &domCaps->os;
virDomainCapsDeviceDisk *disk = &domCaps->disk;
@@ -7305,7 +7319,7 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
firmwares, nfirmwares) < 0)
return -1;
- virQEMUCapsFillDomainCPUCaps(qemuCaps, hostarch, domCaps);
+ virQEMUCapsFillDomainCPUCaps(qemuCaps, hostarch, domCaps, flags);
virQEMUCapsFillDomainMemoryBackingCaps(qemuCaps, memoryBacking);
virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, domCaps->machine, disk);
virQEMUCapsFillDomainDeviceGraphicsCaps(cfg, qemuCaps, graphics);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index f7c8680f94..bc3ecbb89f 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -896,7 +896,8 @@ int virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
virQEMUCaps *qemuCaps,
virArch hostarch,
virDomainCaps *domCaps,
- bool privileged);
+ bool privileged,
+ unsigned int flags);
void virQEMUCapsFillDomainMemoryBackingCaps(virQEMUCaps *qemuCaps,
virDomainCapsMemoryBacking *memoryBacking);
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 242955200a..5e40635871 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1708,7 +1708,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
virQEMUCaps *qemuCaps,
const char *machine,
virArch arch,
- virDomainVirtType virttype)
+ virDomainVirtType virttype,
+ unsigned int flags)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autoptr(virDomainCaps) domCaps = NULL;
@@ -1742,7 +1743,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
qemuCaps,
driver->hostarch,
domCaps,
- driver->privileged) < 0)
+ driver->privileged,
+ flags) < 0)
return NULL;
return g_steal_pointer(&domCaps);
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index edb65c99f4..36d7808e10 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -375,7 +375,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
virQEMUCaps *qemuCaps,
const char *machine,
virArch arch,
- virDomainVirtType virttype);
+ virDomainVirtType virttype,
+ unsigned int flags);
int qemuDriverAllocateID(virQEMUDriver *driver);
virDomainXMLOption *virQEMUDriverCreateXMLConf(virQEMUDriver *driver,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8db9cbb6a2..0a61f97666 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16738,21 +16738,10 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
if (!(domCaps = virQEMUDriverGetDomainCapabilities(driver,
qemuCaps, machine,
- arch, virttype)))
+ arch, virttype,
+ flags)))
return NULL;
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES) {
- virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, virttype,
- domCaps->cpu.hostModel,
- VIR_CPU_FEATURE_DISABLE);
- }
-
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) {
- virCPUDef *cpu = domCaps->cpu.hostModel;
- if (cpu && virCPUExpandFeatures(arch, cpu) < 0)
- return NULL;
- }
-
return virDomainCapsFormat(domCaps);
}
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index 5b2fc80f0a..f2248c2435 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -101,7 +101,7 @@ fillQemuCaps(virDomainCaps *domCaps,
if (virQEMUCapsFillDomainCaps(cfg,
qemuCaps, domCaps->arch, domCaps,
- false) < 0)
+ false, 0) < 0)
return -1;
/* As of f05b6a918e28 we are expecting to see OVMF_CODE.fd file which
--
2.54.0

View File

@ -0,0 +1,107 @@
From 84c12b67bed448ae5129e3b7c18b52fa397cf217 Mon Sep 17 00:00:00 2001
Message-ID: <84c12b67bed448ae5129e3b7c18b52fa397cf217.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 13:10:37 +0100
Subject: [PATCH] qemu: Update qemuDomainNeedsVFIO to ignore PCI hostdev with
IOMMUFD
This function is used to figure out if VM needs access to /dev/vfio/vfio.
In case of PCI host devices that is true only if IOMMUFD is not enabled.
This fixes error when hotplugging PCI host device with IOMMUFD disabled
to a VM that already has PCI host device with IOMMIFD enabled:
Could not open '/dev/vfio/vfio': No such file or directory
The function is used in this case to check if /dev/vfio/vfio was already
made available to QEMU or not.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit d1fb5cf127d7681fa6c27e5b163ef410132aea49)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
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 99d2a0aa53..576a1bd79b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32520,6 +32520,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 8f5780ee4c..f1c8478208 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4658,6 +4658,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.54.0

View File

@ -0,0 +1,59 @@
From dbaf42b6deae0149f88a3be8fbf52a5e94eb799d Mon Sep 17 00:00:00 2001
Message-ID: <dbaf42b6deae0149f88a3be8fbf52a5e94eb799d.1780571166.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 11 Feb 2026 10:16:34 +0100
Subject: [PATCH] qemu: Wire up new hyperv host-model mode behavior
Since some hyperv features might be already enabled/disabled when
entering qemuProcessEnableDomainFeatures() only those which are
not set in domain XML (i.e. are VIR_TRISTATE_SWITCH_ABSENT)
should be modified. Furthermore, some features are not a simple
on/off switch, but a number or a string even. Well, that doesn't
matter really as the logic for setting them is the same: only set
their value iff they are not already set.
Resolves: https://issues.redhat.com/browse/RHEL-148219
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 11057abfd13f6aad15f9821235b66c68e6211af6)
Resolves: https://issues.redhat.com/browse/RHEL-151688
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_process.c | 8 +++++++-
.../qemuxmlconfdata/hyperv-host-model.x86_64-latest.args | 2 +-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1aff3a277b..29601683a0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6964,7 +6964,13 @@ qemuProcessEnableDomainFeatures(virDomainObj *vm)
if (!VIR_DOMAIN_CAPS_ENUM_IS_SET(hv->features, i))
continue;
- vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
+ if (vm->def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ABSENT) {
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
+ } else {
+ /* if the user provided already config for this we skip the
+ * auto-population code */
+ continue;
+ }
if (i == VIR_DOMAIN_HYPERV_SPINLOCKS) {
if (hv->spinlocks != 0) {
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
index 58502ff51e..d1f2326da1 100644
--- a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
-accel tcg \
--cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0xfff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on,hv-reset=on,hv-vendor-id=Linux KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-avic=on,hv-emsr-bitmap=on,hv-xmm-input=on' \
+-cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x2000,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on,hv-reset=on,hv-vendor-id=Linux KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-avic=on,hv-emsr-bitmap=on' \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
--
2.54.0

View File

@ -0,0 +1,46 @@
From 3e6b8f45de2cef2a8f08f84d62915b3cbaa050de Mon Sep 17 00:00:00 2001
Message-ID: <3e6b8f45de2cef2a8f08f84d62915b3cbaa050de.1780571166.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 18 Mar 2026 08:54:16 +0100
Subject: [PATCH] qemuMigrationSrcBeginPhase: Don't call
'qemuBlockNodesEnsureActive' with offline VM
Commits 7b5566ce67b18a and f879d5f40385358 ( v11.8.0-92-gf879d5f403 )
moved around code for re-activating block backends after migration.
While previously it was done when migration failed now we do it when we
need qemu to do some block operations.
'qemuBlockNodesEnsureActive' is thus called also when 'VIR_MIGRATE_OFFLINE'
is used. This doesn't cause failure similar to previous patch only due
to a conincidence as 'qemuCaps' wasn't initialized yet and thus we
assume that QEMU doesn't support 'blockdev-set-active' and skip all
monitor code.
Make the code more robust and explicit by calling
'qemuBlockNodesEnsureActive' only on active VMs during migration.
Fixes: 7b5566ce67b18a2bebe68fdb07e046f25185f8d3
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 4537c0b8708851136b8246b1869c6008a56240ae)
https://redhat.atlassian.net/browse/RHEL-173433
---
src/qemu/qemu_migration.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 1fd9b1dd55..2b3f464fa6 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2868,7 +2868,8 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver,
vm->newDef && !qemuDomainVcpuHotplugIsInOrder(vm->newDef)))
cookieFlags |= QEMU_MIGRATION_COOKIE_CPU_HOTPLUG;
- if (qemuBlockNodesEnsureActive(vm, vm->job->asyncJob) < 0)
+ if (virDomainObjIsActive(vm) &&
+ qemuBlockNodesEnsureActive(vm, vm->job->asyncJob) < 0)
return NULL;
return qemuMigrationSrcBeginXML(vm, xmlin,
--
2.54.0

View File

@ -0,0 +1,45 @@
From f875d6f1e560dd9d73e373d576f2c784f6f8cb4c Mon Sep 17 00:00:00 2001
Message-ID: <f875d6f1e560dd9d73e373d576f2c784f6f8cb4c.1780571166.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 23 Mar 2026 22:39:58 +0100
Subject: [PATCH] qemuMigrationSrcBeginXML: Don't call
'qemuMigrationSrcBeginPhaseBlockDirtyBitmaps' with offline VM
Commit a4f610ff3fe190058f1 made the call to
'qemuMigrationSrcBeginPhaseBlockDirtyBitmaps' inside
'qemuMigrationSrcBeginXML' unconditional. This unfortunately means that
it was called also with 'VIR_MIGRATE_OFFLINE'.
Attempting to enter the monitor in such case results in an error:
error: operation failed: domain is no longer running
Restrict the call only to non-offline migration.
Fixes: a4f610ff3fe190058f18baea18b095d0bc69441b
Resolves: https://redhat.atlassian.net/browse/RHEL-156800
Closes: https://gitlab.com/libvirt/libvirt/-/work_items/865
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 59fde80f39567101010e7ba4dece4fd68b50090d)
https://redhat.atlassian.net/browse/RHEL-173433
---
src/qemu/qemu_migration.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 2a4df1191d..1fd9b1dd55 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2689,7 +2689,8 @@ qemuMigrationSrcBeginXML(virDomainObj *vm,
if (!(mig = qemuMigrationCookieNew(vm->def, priv->origname)))
return NULL;
- if (qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm) < 0)
+ if (!(flags & VIR_MIGRATE_OFFLINE) &&
+ qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm) < 0)
return NULL;
if (qemuMigrationCookieFormat(mig, driver, vm,
--
2.54.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
From fba9c200834d8d31ed34e632470563a0074fe528 Mon Sep 17 00:00:00 2001
Message-ID: <fba9c200834d8d31ed34e632470563a0074fe528.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 17:55:28 +0200
Subject: [PATCH] qemu_capabilities: Cache expanded CPU
When probing host model CPU we already expand it to get a list of all
CPU features. Let's store the expanded CPU definition in virQEMUCaps and
copy it to domain capabilities when requested by the
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flag instead of
expanding the CPU over and over on each request.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 312000a739aebaa9de655bb1f6a539326ea8783d)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 39 ++++++++++++++++++++++++++----------
src/qemu/qemu_capabilities.h | 3 +++
2 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2e8f220abc..555723cafb 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -788,6 +788,9 @@ struct _virQEMUCapsHostCPUData {
unsigned int physAddrSize;
/* Host CPU definition reported in domain capabilities. */
virCPUDef *reported;
+ /* Expanded host CPU definition with features that are implicitly enabled
+ * by the selected CPU model. */
+ virCPUDef *expanded;
/* Migratable host CPU definition used for updating guest CPU. */
virCPUDef *migratable;
/* CPU definition with features detected by libvirt using virCPUGetHost
@@ -1962,6 +1965,9 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUData *dst,
if (src->reported)
dst->reported = virCPUDefCopy(src->reported);
+ if (src->expanded)
+ dst->expanded = virCPUDefCopy(src->expanded);
+
if (src->migratable)
dst->migratable = virCPUDefCopy(src->migratable);
@@ -1975,6 +1981,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUData *cpuData)
{
qemuMonitorCPUModelInfoFree(cpuData->info);
virCPUDefFree(cpuData->reported);
+ virCPUDefFree(cpuData->expanded);
virCPUDefFree(cpuData->migratable);
virCPUDefFree(cpuData->full);
@@ -2301,6 +2308,9 @@ virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps,
/* 'full' is non-NULL only if we have data from both QEMU and
* virCPUGetHost */
return cpuData->full ? cpuData->full : cpuData->reported;
+
+ case VIR_QEMU_CAPS_HOST_CPU_EXPANDED:
+ return cpuData->expanded;
}
return NULL;
@@ -2312,6 +2322,7 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps,
virDomainVirtType type,
unsigned int physAddrSize,
virCPUDef *reported,
+ virCPUDef *expanded,
virCPUDef *migratable,
virCPUDef *full)
{
@@ -2320,6 +2331,7 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps,
cpuData = &virQEMUCapsGetAccel(qemuCaps, type)->hostCPU;
cpuData->physAddrSize = physAddrSize;
cpuData->reported = reported;
+ cpuData->expanded = expanded;
cpuData->migratable = migratable;
cpuData->full = full;
}
@@ -4123,16 +4135,18 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
virCPUDefCopyModelFilter(cpu, hostCPU, true, virQEMUCapsCPUFilterFeatures,
&qemuCaps->arch);
- } else if (virQEMUCapsTypeIsAccelerated(type) &&
- virCPUGetHostIsSupported(qemuCaps->arch)) {
+ }
+
+ cpuExpanded = virCPUDefCopy(cpu);
+ if (virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0)
+ goto error;
+
+ if (rc == 0 &&
+ virQEMUCapsTypeIsAccelerated(type) &&
+ virCPUGetHostIsSupported(qemuCaps->arch)) {
if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL)))
goto error;
- cpuExpanded = virCPUDefCopy(cpu);
-
- if (virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0)
- goto error;
-
for (i = 0; i < cpuExpanded->nfeatures; i++) {
if (cpuExpanded->features[i].policy == VIR_CPU_FEATURE_REQUIRE)
virCPUDefUpdateFeature(fullCPU, cpuExpanded->features[i].name,
@@ -4171,6 +4185,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize,
g_steal_pointer(&cpu),
+ g_steal_pointer(&cpuExpanded),
g_steal_pointer(&migCPU),
g_steal_pointer(&fullCPU));
@@ -6587,9 +6602,14 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
virDomainCaps *domCaps,
unsigned int flags)
{
- virQEMUCapsHostCPUType cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
+ virQEMUCapsHostCPUType cpuType;
virCPUDef *cpu;
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
+ cpuType = VIR_QEMU_CAPS_HOST_CPU_EXPANDED;
+ else
+ cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
+
cpu = virCPUDefCopy(virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
cpuType));
@@ -6600,9 +6620,6 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
cpu, VIR_CPU_FEATURE_DISABLE);
}
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
- virCPUExpandFeatures(domCaps->arch, cpu);
-
virCPUDefSortFeatures(cpu);
domCaps->cpu.hostModel = cpu;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index bc3ecbb89f..8822bf120b 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -788,6 +788,9 @@ typedef enum {
* combined with features reported by QEMU. This is used for backward
* compatible comparison between a guest CPU and a host CPU. */
VIR_QEMU_CAPS_HOST_CPU_FULL,
+ /* Expanded host CPU definition with features that are implicitly enabled
+ * by the selected CPU model. */
+ VIR_QEMU_CAPS_HOST_CPU_EXPANDED,
} virQEMUCapsHostCPUType;
virCPUDef *virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps,
--
2.54.0

View File

@ -0,0 +1,156 @@
From ce373eb396f931d5ebdd03105a3f1950eb842cfd Mon Sep 17 00:00:00 2001
Message-ID: <ce373eb396f931d5ebdd03105a3f1950eb842cfd.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 25 May 2026 14:31:07 +0200
Subject: [PATCH] qemu_capabilities: Fix domain capabilities on AMD CPUs
The arch-capabilities MSR is not defined on AMD CPUs, but KVM has always
been emulating them. Unfortunately, this may cause Windows to crash so
QEMU (since 10.1, commit d3a24134e37d57abd3e7445842cda2717f49e96d)
decided to mask the MSR by default with some additional compatibility
code for older machine types.
This is all mostly transparent except for probing when we run QEMU
without a machine type and expand the "host" CPU model. With QEMU 10.1
and newer none of the arch-capabilities features will be shown as
enabled, which may cause unexpected issues for users (such as KubeVirt)
that get the list of all supported features from the host-model CPU
definition in domain capabilities to select possible target nodes for
migration. As a result of the change, no AMD host with new QEMU will be
shown as available for incoming migration from older hosts.
Since the features are supported on the host (it's possible to
explicitly enable them), but they should not be enabled by default in
host-model CPU, we only add the to domain capabilities when
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag is set.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 54ff2058d6f7bb2547afebbd9c65c7b4b501e372)
https://redhat.atlassian.net/browse/RHEL-177364
Conflicts:
tests/domaincapsdata/qemu_11.0.0-q35.x86_64+sgx-supported.xml
tests/domaincapsdata/qemu_11.0.0-q35.x86_64-supported.xml
- QEMU 11.0 data do not exist downstream
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 24 +++++++++++++++++++
src/qemu/qemu_driver.c | 3 ++-
.../qemu_10.1.0-q35.x86_64-supported.xml | 7 ++++++
.../qemu_10.2.0-q35.x86_64-supported.xml | 7 ++++++
4 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 555723cafb..f06f376dd7 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6604,6 +6604,7 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
{
virQEMUCapsHostCPUType cpuType;
virCPUDef *cpu;
+ virArch arch = domCaps->arch;
if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
cpuType = VIR_QEMU_CAPS_HOST_CPU_EXPANDED;
@@ -6620,6 +6621,29 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
cpu, VIR_CPU_FEATURE_DISABLE);
}
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES) {
+ uint32_t index = 0x10a; /* arch-capabilities MSR */
+ uint64_t msr = 0;
+
+ /* While the arch-capabilities MSR is not defined on AMD CPUs, KVM has
+ * always been emulating them. Unfortunately, this may cause some
+ * Windows version to crash so QEMU decided to mask the MSR by default.
+ * When asked for all CPU features supported on a host we need to add
+ * the affected features to the host-model.
+ */
+ if (ARCH_IS_X86(arch) &&
+ STREQ_NULLABLE(cpu->vendor, "AMD") &&
+ virCPUCheckFeature(arch, cpu, "arch-capabilities") == 0 &&
+ virHostCPUGetMSRFromKVM(index, &msr) == 0) {
+ g_autoptr(virCPUData) data = virCPUDataNew(arch);
+ virCPUFeaturePolicy policy = VIR_CPU_FEATURE_REQUIRE;
+
+ virCPUx86DataAddMSR(data, index, msr);
+ virCPUUpdateFeatures(arch, cpu, data, policy);
+ virCPUDefUpdateFeature(cpu, "arch-capabilities", policy);
+ }
+ }
+
virCPUDefSortFeatures(cpu);
domCaps->cpu.hostModel = cpu;
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0a61f97666..dcb49a9d42 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16721,7 +16721,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
g_autoptr(virDomainCaps) domCaps = NULL;
virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES |
- VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES |
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES,
NULL);
if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0)
diff --git a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml
index 244fce575b..4ea61a6cbe 100644
--- a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml
+++ b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml
@@ -45,17 +45,24 @@
<vendor>AMD</vendor>
<maxphysaddr mode='passthrough' limit='64'/>
<feature policy='require' name='amd-ssbd'/>
+ <feature policy='require' name='arch-capabilities'/>
<feature policy='require' name='cmp_legacy'/>
<feature policy='require' name='flushbyasid'/>
+ <feature policy='require' name='gds-no'/>
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ibpb-brtype'/>
<feature policy='require' name='invtsc'/>
<feature policy='require' name='lbrv'/>
<feature policy='require' name='lfence-always-serializing'/>
+ <feature policy='require' name='mds-no'/>
<feature policy='require' name='null-sel-clr-base'/>
<feature policy='require' name='overflow-recov'/>
<feature policy='require' name='pause-filter'/>
<feature policy='require' name='pfthreshold'/>
+ <feature policy='require' name='pschange-mc-no'/>
+ <feature policy='require' name='rdctl-no'/>
+ <feature policy='require' name='rfds-no'/>
+ <feature policy='require' name='skip-l1dfl-vmentry'/>
<feature policy='require' name='ssbd'/>
<feature policy='require' name='stibp'/>
<feature policy='require' name='succor'/>
diff --git a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml
index 9389141012..d9c0ea6f1d 100644
--- a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml
+++ b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml
@@ -44,12 +44,19 @@
<model fallback='forbid'>EPYC-Turin</model>
<vendor>AMD</vendor>
<maxphysaddr mode='passthrough' limit='64'/>
+ <feature policy='require' name='arch-capabilities'/>
<feature policy='require' name='cmp_legacy'/>
<feature policy='require' name='flush-l1d'/>
+ <feature policy='require' name='gds-no'/>
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='invtsc'/>
<feature policy='disable' name='la57'/>
+ <feature policy='require' name='mds-no'/>
<feature policy='disable' name='pcid'/>
+ <feature policy='require' name='pschange-mc-no'/>
+ <feature policy='require' name='rdctl-no'/>
+ <feature policy='require' name='rfds-no'/>
+ <feature policy='require' name='skip-l1dfl-vmentry'/>
<feature policy='require' name='spec-ctrl'/>
<feature policy='require' name='ssbd'/>
<feature policy='require' name='stibp'/>
--
2.54.0

View File

@ -0,0 +1,71 @@
From 1b72f3955f62a442b8482eed46e6456ba2e1c14b Mon Sep 17 00:00:00 2001
Message-ID: <1b72f3955f62a442b8482eed46e6456ba2e1c14b.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 17:30:21 +0200
Subject: [PATCH] qemu_capabilities: Split conditions in
virQEMUCapsInitHostCPUModel
Having 'else' after goto is useless.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 8b4f56447f32171671e18b82fbdfd478f2ec4293)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2265dae7ba..2e8f220abc 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4102,9 +4102,17 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
if (!(cpu = virQEMUCapsNewHostCPUModel()))
goto error;
- if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0)
goto error;
- } else if (rc == 1) {
+
+ if (rc == 2) {
+ VIR_DEBUG("QEMU does not provide CPU model for arch=%s virttype=%s",
+ virArchToString(qemuCaps->arch),
+ virDomainVirtTypeToString(type));
+ goto error;
+ }
+
+ if (rc == 1) {
g_autoptr(virDomainCapsCPUModels) cpuModels = NULL;
VIR_DEBUG("No host CPU model info from QEMU; probing host CPU directly");
@@ -4115,11 +4123,6 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
virCPUDefCopyModelFilter(cpu, hostCPU, true, virQEMUCapsCPUFilterFeatures,
&qemuCaps->arch);
- } else if (rc == 2) {
- VIR_DEBUG("QEMU does not provide CPU model for arch=%s virttype=%s",
- virArchToString(qemuCaps->arch),
- virDomainVirtTypeToString(type));
- goto error;
} else if (virQEMUCapsTypeIsAccelerated(type) &&
virCPUGetHostIsSupported(qemuCaps->arch)) {
if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL)))
@@ -4140,9 +4143,10 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
if (!(migCPU = virQEMUCapsNewHostCPUModel()))
goto error;
- if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0)
goto error;
- } else if (rc == 1) {
+
+ if (rc == 1) {
VIR_DEBUG("CPU migratability not provided by QEMU");
virCPUDefFree(migCPU);
--
2.54.0

View File

@ -0,0 +1,150 @@
From b41da9180160e455bf36d9db7870b64457a6ca8c Mon Sep 17 00:00:00 2001
Message-ID: <b41da9180160e455bf36d9db7870b64457a6ca8c.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 12:24:25 +0200
Subject: [PATCH] qemu_capabilities: Split virQEMUCapsFillDomainCPUCaps
Each CPU mode is filled in its own dedicated function.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 354ac21caba1da52d3d48e57c7395f899efc9ca4)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 96 ++++++++++++++++++++++++------------
1 file changed, 64 insertions(+), 32 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index ed6aa86da2..0b32296cc8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6553,6 +6553,66 @@ virQEMUCapsFillDomainOSCaps(virDomainCapsOS *os,
}
+static void
+virQEMUCapsFillDomainCPUHostPassthrough(virQEMUCaps *qemuCaps,
+ virDomainCaps *domCaps)
+{
+ domCaps->cpu.hostPassthrough = true;
+
+ domCaps->cpu.hostPassthroughMigratable.report = true;
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MIGRATABLE)) {
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
+ VIR_TRISTATE_SWITCH_ON);
+ }
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
+ VIR_TRISTATE_SWITCH_OFF);
+}
+
+
+static void
+virQEMUCapsFillDomainCPUMaximum(virDomainCaps *domCaps)
+{
+ domCaps->cpu.maximum = true;
+
+ domCaps->cpu.maximumMigratable.report = true;
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
+ VIR_TRISTATE_SWITCH_ON);
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
+ VIR_TRISTATE_SWITCH_OFF);
+}
+
+
+static void
+virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
+ virDomainCaps *domCaps)
+{
+ virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
+
+ domCaps->cpu.hostModel = virCPUDefCopy(cpu);
+ domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
+ domCaps->virttype);
+}
+
+
+static void
+virQEMUCapsFillDomainCPUCustom(virQEMUCaps *qemuCaps,
+ virDomainCaps *domCaps)
+{
+ const char *forbidden[] = { "host", NULL };
+ g_auto(GStrv) models = NULL;
+
+ if (virCPUGetModels(domCaps->arch, &models) >= 0) {
+ domCaps->cpu.custom = virQEMUCapsGetCPUModels(qemuCaps,
+ domCaps->virttype,
+ (const char **)models,
+ forbidden);
+ } else {
+ domCaps->cpu.custom = NULL;
+ }
+}
+
+
static void
virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
virArch hostarch,
@@ -6561,53 +6621,25 @@ virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_PASSTHROUGH,
domCaps->machine)) {
- domCaps->cpu.hostPassthrough = true;
-
- domCaps->cpu.hostPassthroughMigratable.report = true;
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MIGRATABLE)) {
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
- VIR_TRISTATE_SWITCH_ON);
- }
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
- VIR_TRISTATE_SWITCH_OFF);
+ virQEMUCapsFillDomainCPUHostPassthrough(qemuCaps, domCaps);
}
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_MAXIMUM,
domCaps->machine)) {
- domCaps->cpu.maximum = true;
-
- domCaps->cpu.maximumMigratable.report = true;
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
- VIR_TRISTATE_SWITCH_ON);
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
- VIR_TRISTATE_SWITCH_OFF);
+ virQEMUCapsFillDomainCPUMaximum(domCaps);
}
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_MODEL,
domCaps->machine)) {
- virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED);
- domCaps->cpu.hostModel = virCPUDefCopy(cpu);
- domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
- domCaps->virttype);
+ virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps);
}
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_CUSTOM,
domCaps->machine)) {
- const char *forbidden[] = { "host", NULL };
- g_auto(GStrv) models = NULL;
-
- if (virCPUGetModels(domCaps->arch, &models) >= 0) {
- domCaps->cpu.custom = virQEMUCapsGetCPUModels(qemuCaps,
- domCaps->virttype,
- (const char **)models,
- forbidden);
- } else {
- domCaps->cpu.custom = NULL;
- }
+ virQEMUCapsFillDomainCPUCustom(qemuCaps, domCaps);
}
}
--
2.54.0

View File

@ -0,0 +1,65 @@
From 2141acf3d9891c1451d741abc1d043e35b1ed074 Mon Sep 17 00:00:00 2001
Message-ID: <2141acf3d9891c1451d741abc1d043e35b1ed074.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 14:15:01 +0200
Subject: [PATCH] qemu_capabilities: Use g_autoptr in
virQEMUCapsInitHostCPUModel
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit eca4c6672d3f373bb9cff271adfc2cd8b13cb4bc)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6951e50c03..2265dae7ba 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4087,11 +4087,11 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
virArch hostArch,
virDomainVirtType type)
{
- virCPUDef *cpu = NULL;
- virCPUDef *cpuExpanded = NULL;
- virCPUDef *migCPU = NULL;
- virCPUDef *hostCPU = NULL;
- virCPUDef *fullCPU = NULL;
+ g_autoptr(virCPUDef) cpu = NULL;
+ g_autoptr(virCPUDef) cpuExpanded = NULL;
+ g_autoptr(virCPUDef) migCPU = NULL;
+ g_autoptr(virCPUDef) hostCPU = NULL;
+ g_autoptr(virCPUDef) fullCPU = NULL;
unsigned int physAddrSize = 0;
size_t i;
int rc;
@@ -4165,19 +4165,15 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
if (virQEMUCapsTypeIsAccelerated(type))
virHostCPUGetPhysAddrSize(hostArch, &physAddrSize);
- virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize, cpu, migCPU, fullCPU);
+ virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize,
+ g_steal_pointer(&cpu),
+ g_steal_pointer(&migCPU),
+ g_steal_pointer(&fullCPU));
- cleanup:
- virCPUDefFree(cpuExpanded);
- virCPUDefFree(hostCPU);
return;
error:
- virCPUDefFree(cpu);
- virCPUDefFree(migCPU);
- virCPUDefFree(fullCPU);
virResetLastError();
- goto cleanup;
}
--
2.54.0

View File

@ -0,0 +1,611 @@
From ab58ab56b88b4a5fc4a2d5dc85b249220951ce36 Mon Sep 17 00:00:00 2001
Message-ID: <ab58ab56b88b4a5fc4a2d5dc85b249220951ce36.1780571166.git.jdenemar@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
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/RHEL-159902
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.54.0

View File

@ -0,0 +1,118 @@
From b2037dd33febe910a6dad3521549b747322d37cb Mon Sep 17 00:00:00 2001
Message-ID: <b2037dd33febe910a6dad3521549b747322d37cb.1780571166.git.jdenemar@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
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/RHEL-159902
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.54.0

View File

@ -0,0 +1,152 @@
From 8442235a61de81d3572cc955a0b40969347fa6a1 Mon Sep 17 00:00:00 2001
Message-ID: <8442235a61de81d3572cc955a0b40969347fa6a1.1780571166.git.jdenemar@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
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/RHEL-156803
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 db512f6757..23e799de3c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5259,7 +5259,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 5c8c21335d..63c5f8e037 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -2722,7 +2722,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.54.0

View File

@ -0,0 +1,266 @@
From c0d508913546c66014f4cad54779ff4ad1549d7a Mon Sep 17 00:00:00 2001
Message-ID: <c0d508913546c66014f4cad54779ff4ad1549d7a.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 16 Mar 2026 15:30:18 +0100
Subject: [PATCH] tests: Add iommufd fdgroup test
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/RHEL-156803
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 e4746374f6..b56e79ed1c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7712,9 +7712,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;
@@ -7734,10 +7736,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 aa877bf16a..29b7e1883c 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -30,6 +30,9 @@
# define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW
# include "qemu/qemu_capspriv.h"
+# define LIBVIRT_QEMU_PROCESSPRIV_H_ALLOW
+# include "qemu/qemu_processpriv.h"
+
# include "testutilsqemu.h"
# define VIR_FROM_THIS VIR_FROM_QEMU
@@ -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);
}
@@ -3099,6 +3104,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.54.0

View File

@ -0,0 +1,127 @@
From d1421d7387a3a747d3476471d7c94b294cfb2748 Mon Sep 17 00:00:00 2001
Message-ID: <d1421d7387a3a747d3476471d7c94b294cfb2748.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 25 May 2026 12:27:41 +0200
Subject: [PATCH] util: Publish and mock virHostCPUGetMSRFromKVM
The function will later be called when probing QEMU capabilities.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 3184289356bd97daa75f77bec189e5ce152ba5e6)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virhostcpu.c | 22 +++++++++++++++++++++-
src/util/virhostcpu.h | 3 +++
tests/qemucpumock.c | 22 ++++++++++++++++++++++
4 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1733286bad..3eca15f066 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2586,6 +2586,7 @@ virHostCPUGetKVMMaxVCPUs;
virHostCPUGetMap;
virHostCPUGetMicrocodeVersion;
virHostCPUGetMSR;
+virHostCPUGetMSRFromKVM;
virHostCPUGetOnline;
virHostCPUGetOnlineBitmap;
virHostCPUGetPhysAddrSize;
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 09395ddb04..a23a3f95e7 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -1329,7 +1329,18 @@ virHostCPUGetMicrocodeVersion(virArch hostArch G_GNUC_UNUSED)
#if WITH_LINUX_KVM_H && defined(KVM_GET_MSRS) && \
(defined(__i386__) || defined(__x86_64__))
-static int
+/**
+ * virHostCPUGetMSRFromKVM:
+ * @index: MSR to read
+ * @result: where to store the content of the @index register
+ *
+ * Reads the 64b content of the specified register via KVM_GET_MSRS ioctl.
+ *
+ * Returns 0 on success,
+ * 1 when the MSR is not supported by the host CPU,
+ * -1 on error.
+ */
+int
virHostCPUGetMSRFromKVM(unsigned long index,
uint64_t *result)
{
@@ -1566,6 +1577,15 @@ virHostCPUGetCPUID(void)
return NULL;
}
+int
+virHostCPUGetMSRFromKVM(unsigned long index G_GNUC_UNUSED,
+ uint64_t *result G_GNUC_UNUSED)
+{
+ virReportSystemError(ENOSYS, "%s",
+ _("Reading MSRs is not supported on this platform"));
+ return -1;
+}
+
int
virHostCPUGetMSR(unsigned long index G_GNUC_UNUSED,
uint64_t *msr G_GNUC_UNUSED)
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
index 289ae41439..24c7fdaf7c 100644
--- a/src/util/virhostcpu.h
+++ b/src/util/virhostcpu.h
@@ -80,6 +80,9 @@ int virHostCPUGetOnline(unsigned int cpu, bool *online);
unsigned int
virHostCPUGetMicrocodeVersion(virArch hostArch) ATTRIBUTE_MOCKABLE;
+int virHostCPUGetMSRFromKVM(unsigned long index,
+ uint64_t *result) ATTRIBUTE_MOCKABLE;
+
int virHostCPUGetMSR(unsigned long index,
uint64_t *msr);
diff --git a/tests/qemucpumock.c b/tests/qemucpumock.c
index 5a63308347..de1e79bfc1 100644
--- a/tests/qemucpumock.c
+++ b/tests/qemucpumock.c
@@ -23,6 +23,7 @@
#include "qemu/qemu_capspriv.h"
#include "testutilshostcpus.h"
#include "virarch.h"
+#include "util/virhostcpu.h"
virCPUDef *
@@ -33,3 +34,24 @@ virQEMUCapsProbeHostCPU(virArch hostArch G_GNUC_UNUSED,
return testUtilsHostCpusGetDefForModel(model);
}
+
+
+int
+virHostCPUGetMSRFromKVM(unsigned long index,
+ uint64_t *result)
+{
+ if (index == 0x10a) {
+ /* Return some arbitrary bits in arch-capabilities MSR */
+ *result =
+ 0x00000001 | /* rdctl-no */
+ 0x00000008 | /* skip-l1dfl-vmentry */
+ 0x00000020 | /* mds-no */
+ 0x00000040 | /* pschange-mc-no */
+ 0x04000000 | /* gds-no */
+ 0x08000000; /* rfds-no */
+ return 0;
+ }
+
+ errno = ENOTSUP;
+ return -1;
+}
--
2.54.0

View File

@ -0,0 +1,43 @@
From 89d55e7dc4be2177645e6090a21ce0f293feec6a Mon Sep 17 00:00:00 2001
Message-ID: <89d55e7dc4be2177645e6090a21ce0f293feec6a.1780571166.git.jdenemar@redhat.com>
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
Date: Tue, 12 May 2026 13:10:43 +0200
Subject: [PATCH] util: virGetSubIDs: do not limit file size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On systems with many users, this file can be larger than BUFSIZ.
Since the file should only be editable by root and virFileReadAll
reallocates the buffer in increments as needed as opposed to
allocating for 'maxlen' upfront, set the maximum to INT_MAX.
https://gitlab.com/libvirt/libvirt/-/work_items/874
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit b0c104e7aaf9cde62702dd66e2c7e4343495de59)
https://redhat.atlassian.net/browse/RHEL-174491
Signed-off-by: Ján Tomko <jtomko@redhat.com>
---
src/util/virutil.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/util/virutil.c b/src/util/virutil.c
index fb64237692..94a6958582 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -1202,7 +1202,9 @@ virGetSubIDs(virSubID **retval, const char *file)
*retval = NULL;
- if (virFileReadAll(file, BUFSIZ, &buf) < 0)
+ /* We trust the source of the file so we set the limit absurdly high.
+ * For smaller files, the helper function will not allocate as much space */
+ if (virFileReadAll(file, INT_MAX, &buf) < 0)
return -1;
lines = g_strsplit(buf, "\n", 0);
--
2.54.0

View File

@ -0,0 +1,79 @@
From 32ff11b8bbc74b61f5ff531f9fb5c83f1a4da343 Mon Sep 17 00:00:00 2001
Message-ID: <32ff11b8bbc74b61f5ff531f9fb5c83f1a4da343.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 10:50:36 +0100
Subject: [PATCH] viriommufd: Set IOMMU_OPTION_RLIMIT_MODE only when running
privileged
If libvirt daemon is running unprivileged it will fail so we should not
even try to set it.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 293bb59e75f4b4c975bbeccb1bb8b39b6f439a35)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_process.c | 2 +-
src/util/viriommufd.c | 6 +++---
src/util/viriommufd.h | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0a69063a4b..9b8b378b1f 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7695,7 +7695,7 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name);
- if ((iommufd = virIOMMUFDOpenDevice()) < 0)
+ if ((iommufd = virIOMMUFDOpenDevice(priv->driver->privileged)) < 0)
return -1;
if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c
index b62d59241d..82920923a2 100644
--- a/src/util/viriommufd.c
+++ b/src/util/viriommufd.c
@@ -80,14 +80,14 @@ virIOMMUFDSetRLimitMode(int fd, bool processAccounting)
}
int
-virIOMMUFDOpenDevice(void)
+virIOMMUFDOpenDevice(bool privileged)
{
int fd = -1;
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 (privileged && virIOMMUFDSetRLimitMode(fd, true) < 0) {
VIR_FORCE_CLOSE(fd);
return -1;
}
@@ -98,7 +98,7 @@ virIOMMUFDOpenDevice(void)
#else
int
-virIOMMUFDOpenDevice(void)
+virIOMMUFDOpenDevice(bool privileged G_GNUC_UNUSED)
{
virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("IOMMUFD is not supported on this platform"));
diff --git a/src/util/viriommufd.h b/src/util/viriommufd.h
index 223f44eb5c..7bad5c7472 100644
--- a/src/util/viriommufd.h
+++ b/src/util/viriommufd.h
@@ -22,6 +22,6 @@
#define VIR_IOMMU_DEV_PATH "/dev/iommu"
-int virIOMMUFDOpenDevice(void);
+int virIOMMUFDOpenDevice(bool privileged);
bool virIOMMUFDSupported(void);
--
2.54.0

View File

@ -0,0 +1,68 @@
From 169253f6cc07e089162c1350d434e8d197298f6a Mon Sep 17 00:00:00 2001
Message-ID: <169253f6cc07e089162c1350d434e8d197298f6a.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 11 Mar 2026 12:13:22 +0100
Subject: [PATCH] virsh: Add --expand-cpu-features option for domcapabilities
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 57e5bb55cef5e97eea14fcecef7114e804576d6c)
https://issues.redhat.com/browse/RHEL-153653
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
docs/manpages/virsh.rst | 5 +++++
tools/virsh-host.c | 7 +++++++
2 files changed, 12 insertions(+)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index ff0cf1a715..85fa6ab011 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -592,6 +592,7 @@ domcapabilities
domcapabilities [virttype] [emulatorbin] [arch] [machine]
[--xpath EXPRESSION] [--wrap]
[--disable-deprecated-features]
+ [--expand-cpu-features]
Print an XML document describing the domain capabilities for the
@@ -638,6 +639,10 @@ of host-model CPU XML, updating the features list with any features
flagged as deprecated for the CPU model by the hypervisor. These
features will be paired with the "disable" policy.
+The **--expand-cpu-features** option will cause the host-model CPU definition
+to contain all CPU features supported on the host including those implicitly
+enabled by the selected CPU model.
+
pool-capabilities
-----------------
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index e918cfa4ca..dd98917fa8 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -118,6 +118,10 @@ static const vshCmdOptDef opts_domcapabilities[] = {
.type = VSH_OT_BOOL,
.help = N_("report host CPU model with deprecated features disabled"),
},
+ {.name = "expand-cpu-features",
+ .type = VSH_OT_BOOL,
+ .help = N_("show all features in host CPU model"),
+ },
{.name = NULL}
};
@@ -137,6 +141,9 @@ cmdDomCapabilities(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "disable-deprecated-features"))
flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES;
+ if (vshCommandOptBool(cmd, "expand-cpu-features"))
+ flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES;
+
if (vshCommandOptString(ctl, cmd, "virttype", &virttype) < 0 ||
vshCommandOptString(ctl, cmd, "emulatorbin", &emulatorbin) < 0 ||
vshCommandOptString(ctl, cmd, "arch", &arch) < 0 ||
--
2.54.0

View File

@ -0,0 +1,75 @@
From ec36f1c9c281c98378dd937ba60aeee60e95daaf Mon Sep 17 00:00:00 2001
Message-ID: <ec36f1c9c281c98378dd937ba60aeee60e95daaf.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 29 May 2026 12:52:59 +0200
Subject: [PATCH] virsh: Add --supported-cpu-features option for
domcapabilities
The option corresponds to the
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES API flag.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 26ffa1d4f0b74c7cda5a6906510cf2d6362b5b8b)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
docs/manpages/virsh.rst | 8 +++++++-
tools/virsh-host.c | 7 +++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 7169b6bc05..2936df6a73 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -592,7 +592,7 @@ domcapabilities
domcapabilities [virttype] [emulatorbin] [arch] [machine]
[--xpath EXPRESSION] [--wrap]
[--disable-deprecated-features]
- [--expand-cpu-features]
+ [--expand-cpu-features] [--supported-cpu-features]
Print an XML document describing the domain capabilities for the
@@ -644,6 +644,12 @@ to contain all required CPU features including those implicitly enabled by the
selected CPU model. Without this flag features that are part of the CPU model
itself will not be listed.
+The **--supported-cpu-features** option will update the host-model CPU
+definition with features that are supported on the host, but will not be
+enabled by default when starting a domain with host-model CPU. Using both
+**--supported-cpu-features** and **--expand-cpu-features** will provide a
+complete list of features that can be enabled on the host.
+
pool-capabilities
-----------------
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 5dbeb54ae5..4b95d2748e 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -122,6 +122,10 @@ static const vshCmdOptDef opts_domcapabilities[] = {
.type = VSH_OT_BOOL,
.help = N_("expand 'host-model' CPU to also show features enabled by the CPU model"),
},
+ {.name = "supported-cpu-features",
+ .type = VSH_OT_BOOL,
+ .help = N_("include all supported CPU features in 'host-model' mode, not only those enabled by default"),
+ },
{.name = NULL}
};
@@ -144,6 +148,9 @@ cmdDomCapabilities(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "expand-cpu-features"))
flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES;
+ if (vshCommandOptBool(cmd, "supported-cpu-features"))
+ flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES;
+
if (vshCommandOptString(ctl, cmd, "virttype", &virttype) < 0 ||
vshCommandOptString(ctl, cmd, "emulatorbin", &emulatorbin) < 0 ||
vshCommandOptString(ctl, cmd, "arch", &arch) < 0 ||
--
2.54.0

View File

@ -294,7 +294,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 11.10.0
Release: 12%{?dist}%{?extra_release}
Release: 13%{?dist}%{?extra_release}
License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1
URL: https://libvirt.org/
@ -379,6 +379,48 @@ Patch74: libvirt-iommufd-fix-FD-leak-in-case-of-error.patch
Patch75: libvirt-domain_conf-initialize-network-hostdev-private-data.patch
Patch76: libvirt-qemu_hotplug-enter-monitor-in-order-to-rollback-passed-FD.patch
Patch77: libvirt-qemu_hotplug-Fix-crash-when-attaching-network-inteface-with-hostdev-network.patch
Patch78: libvirt-conf-Parse-hyperv-features-even-for-host-model.patch
Patch79: libvirt-qemu-Wire-up-new-hyperv-host-model-mode-behavior.patch
Patch80: libvirt-Introduce-EXPAND_CPU_FEATURES-flag-for-domain-capabilities.patch
Patch81: libvirt-qemu-Implement-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES.patch
Patch82: libvirt-virsh-Add-expand-cpu-features-option-for-domcapabilities.patch
Patch83: libvirt-docs-Clarify-host-model-description-in-domain-capabilities.patch
Patch84: libvirt-qemu-Fix-job-handling-when-domain-dies-in-post-copy-migration.patch
Patch85: libvirt-security_apparmor-Use-g_auto-in-AppArmorSetSecurityHostdevLabel.patch
Patch86: libvirt-security-Cleanup-hostdev-label-error-logic.patch
Patch87: libvirt-qemu-Fix-IOMMUFD-and-VFIO-security-labels.patch
Patch88: libvirt-viriommufd-Set-IOMMU_OPTION_RLIMIT_MODE-only-when-running-privileged.patch
Patch89: libvirt-conf-Move-and-rename-virStorageSourceFDTuple-object.patch
Patch90: libvirt-conf-Refactor-virHostdevIsPCIDevice.patch
Patch91: libvirt-hypervisor-Fix-virHostdevNeedsVFIO-detection.patch
Patch92: libvirt-qemu-Expand-call-to-qemuDomainNeedsVFIO.patch
Patch93: libvirt-qemu-Update-qemuDomainNeedsVFIO-to-ignore-PCI-hostdev-with-IOMMUFD.patch
Patch94: libvirt-src-Use-virHostdevIsPCIDeviceWith-to-check-for-IOMMUFD.patch
Patch95: libvirt-conf-Introduce-domain-iommufd-element.patch
Patch96: libvirt-qemu-Implement-iommufd.patch
Patch97: libvirt-conf-Add-iommufd-fdgroup-support.patch
Patch98: libvirt-qemu-Implement-iommufd-fdgroup.patch
Patch99: libvirt-tests-Add-iommufd-fdgroup-test.patch
Patch100: libvirt-hypervisor-Call-virWaitForDevices-after-detaching-host-devices.patch
Patch101: libvirt-qemuMigrationSrcBeginXML-Don-t-call-qemuMigrationSrcBeginPhaseBlockDirtyBitmaps-with-offline-VM.patch
Patch102: libvirt-qemuMigrationSrcBeginPhase-Don-t-call-qemuBlockNodesEnsureActive-with-offline-VM.patch
Patch103: libvirt-util-virGetSubIDs-do-not-limit-file-size.patch
Patch104: libvirt-cpu_conf-Introduce-virCPUDefSortFeatures.patch
Patch105: libvirt-qemu_capabilities-Split-virQEMUCapsFillDomainCPUCaps.patch
Patch106: libvirt-qemu-Move-domain-caps-flags-handling-to-virQEMUCapsFillDomainCPUHostModel.patch
Patch107: libvirt-qemu_capabilities-Always-sort-features-in-host-model-CPU.patch
Patch108: libvirt-qemu_capabilities-Use-g_autoptr-in-virQEMUCapsInitHostCPUModel.patch
Patch109: libvirt-qemu_capabilities-Split-conditions-in-virQEMUCapsInitHostCPUModel.patch
Patch110: libvirt-qemu_capabilities-Cache-expanded-CPU.patch
Patch111: libvirt-domaincapstest-Test-EXPAND_CPU_FEATURES-flag.patch
Patch112: libvirt-util-Publish-and-mock-virHostCPUGetMSRFromKVM.patch
Patch113: libvirt-cpu_x86-Introduce-virCPUx86DataAddMSR.patch
Patch114: libvirt-cpu-Introduce-virCPUUpdateFeatures.patch
Patch115: libvirt-Fix-documentation-of-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES.patch
Patch116: libvirt-Introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES-flag.patch
Patch117: libvirt-virsh-Add-supported-cpu-features-option-for-domcapabilities.patch
Patch118: libvirt-domaincapstest-Test-SUPPORTED_CPU_FEATURES-flag.patch
Patch119: libvirt-qemu_capabilities-Fix-domain-capabilities-on-AMD-CPUs.patch
Requires: libvirt-daemon = %{version}-%{release}
@ -2770,6 +2812,51 @@ exit 0
%endif
%changelog
* Thu Jun 4 2026 Jiri Denemark <jdenemar@redhat.com> - 11.10.0-13
- conf: Parse hyperv features even for host-model (RHEL-151688)
- qemu: Wire up new hyperv host-model mode behavior (RHEL-151688)
- Introduce EXPAND_CPU_FEATURES flag for domain capabilities (RHEL-153653)
- qemu: Implement VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES (RHEL-153653)
- virsh: Add --expand-cpu-features option for domcapabilities (RHEL-153653)
- docs: Clarify host-model description in domain capabilities (RHEL-153653)
- qemu: Fix job handling when domain dies in post-copy migration (RHEL-145179)
- security_apparmor: Use g_auto* in AppArmorSetSecurityHostdevLabel (RHEL-159902)
- security: Cleanup hostdev label error logic (RHEL-159902)
- qemu: Fix IOMMUFD and VFIO security labels (RHEL-159902)
- viriommufd: Set IOMMU_OPTION_RLIMIT_MODE only when running privileged (RHEL-156803)
- conf: Move and rename virStorageSourceFDTuple object (RHEL-156803)
- conf: Refactor virHostdevIsPCIDevice (RHEL-156803)
- hypervisor: Fix virHostdevNeedsVFIO detection (RHEL-156803)
- qemu: Expand call to qemuDomainNeedsVFIO (RHEL-156803)
- qemu: Update qemuDomainNeedsVFIO to ignore PCI hostdev with IOMMUFD (RHEL-156803)
- src: Use virHostdevIsPCIDeviceWith* to check for IOMMUFD (RHEL-156803)
- conf: Introduce domain iommufd element (RHEL-156803)
- qemu: Implement iommufd (RHEL-156803)
- conf: Add iommufd fdgroup support (RHEL-156803)
- qemu: Implement iommufd fdgroup (RHEL-156803)
- tests: Add iommufd fdgroup test (RHEL-156803)
- hypervisor: Call virWaitForDevices() after detaching host devices (RHEL-156803)
- qemuMigrationSrcBeginXML: Don't call 'qemuMigrationSrcBeginPhaseBlockDirtyBitmaps' with offline VM (RHEL-173433)
- qemuMigrationSrcBeginPhase: Don't call 'qemuBlockNodesEnsureActive' with offline VM (RHEL-173433)
- util: virGetSubIDs: do not limit file size (RHEL-174491)
- cpu_conf: Introduce virCPUDefSortFeatures (RHEL-177364)
- qemu_capabilities: Split virQEMUCapsFillDomainCPUCaps (RHEL-177364)
- qemu: Move domain caps flags handling to virQEMUCapsFillDomainCPUHostModel (RHEL-177364)
- qemu_capabilities: Always sort features in host-model CPU (RHEL-177364)
- qemu_capabilities: Use g_autoptr in virQEMUCapsInitHostCPUModel (RHEL-177364)
- qemu_capabilities: Split conditions in virQEMUCapsInitHostCPUModel (RHEL-177364)
- qemu_capabilities: Cache expanded CPU (RHEL-177364)
- domaincapstest: Test EXPAND_CPU_FEATURES flag (RHEL-177364)
- util: Publish and mock virHostCPUGetMSRFromKVM (RHEL-177364)
- cpu_x86: Introduce virCPUx86DataAddMSR (RHEL-177364)
- cpu: Introduce virCPUUpdateFeatures (RHEL-177364)
- Fix documentation of VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES (RHEL-177364)
- Introduce VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag (RHEL-177364)
- virsh: Add --supported-cpu-features option for domcapabilities (RHEL-177364)
- domaincapstest: Test SUPPORTED_CPU_FEATURES flag (RHEL-177364)
- qemu_capabilities: Fix domain capabilities on AMD CPUs (RHEL-177364)
- distro: Replace old gating with tmt
* Tue Mar 10 2026 Jiri Denemark <jdenemar@redhat.com> - 11.10.0-12
- qemu_hotplug: Fix crash when attaching network inteface with hostdev network (RHEL-151953)

9
plans.fmf Normal file
View File

@ -0,0 +1,9 @@
/gating:
plan:
import:
url: https://gitlab.cee.redhat.com/phrdina/libvirt-tests
name: /plans/gating
adjust:
enabled: false
when: distro != rhel