Enable building for ppc64le

This commit is contained in:
Eduard Abdullin 2026-08-24 13:19:58 +00:00 committed by root
commit a828d0d749
64 changed files with 61568 additions and 2 deletions

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,211 @@
From ef0dfcf0dea53cc1d8aabc08942a7091c9dbf30c Mon Sep 17 00:00:00 2001
Message-ID: <ef0dfcf0dea53cc1d8aabc08942a7091c9dbf30c.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 8 Jun 2026 16:55:05 +0200
Subject: [PATCH] conf: Add fields for recording actually-selected virtio video
device
QEMU's commandline generator picks for virtio video between various
actual device models not only based on the XML definition but also
capabilities present. Since none of the devices is actually ABI
compatible we need to record the actually selected device in the XML.
Introduce 'device' attribute:
<video>
<model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
which will record the actually selected model so that we can preserve
ABI across restarts on deployment changes but more importantly across
migrations where the deployment differs.
The code specifically avoids an ABI stability check for the new field
because there are already possibly broken configurations that the users
may want to fix by picking the proper model which could be forbidden.
Users are instructed to not set the field in the XML.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit b6f7c2d3db28626d4799d00c299e33dae07c5201)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
docs/formatdomain.rst | 8 +++++++
src/conf/domain_conf.c | 35 +++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 15 +++++++++++++
src/conf/schemas/domaincommon.rng | 18 +++++++++++++++-
src/libvirt_private.syms | 1 +
5 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 225152e0f2..8e7577f3b7 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -7295,6 +7295,14 @@ A video device.
guest. The ``edid`` attribute is only valid for model types ``vga``, ``bochs``,
and ``virtio``.
+ :since:`Since 12.5.0` the ``virtio`` video model has an additional attribute
+ ``device``, which records the specific virtio device model which was picked
+ for the configuration, to preserve guest ABI and migration compatibility.
+ Users do not need to set this attribute as aprropriate value is picked and
+ filled in automatically. Accepted values are ``virtio-vga``, ``virtio-gpu``,
+ ``virtio-vga-gl``, and ``virtio-gpu-gl``, but not all combinations of config
+ and this field make sense.
+
``acceleration``
Configure if video acceleration should be enabled.
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index dc19e258dd..47200d27c5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -909,6 +909,17 @@ VIR_ENUM_IMPL(virDomainVideoVGAConf,
"off",
);
+VIR_ENUM_IMPL(virDomainVideoVirtioDevice,
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_LAST,
+ "",
+ "virtio-vga",
+ "virtio-gpu",
+ "virtio-vga-gl",
+ "virtio-gpu-gl",
+ "vhost-user-vga",
+ "vhost-user-gpu",
+);
+
VIR_ENUM_IMPL(virDomainInput,
VIR_DOMAIN_INPUT_TYPE_LAST,
"mouse",
@@ -13726,6 +13737,14 @@ virDomainVideoModelDefParseXML(virDomainVideoDef *def,
VIR_DOMAIN_VIDEO_TYPE_DEFAULT) < 0)
return -1;
+ if (def->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
+ if (virXMLPropEnumDefault(node, "device",
+ virDomainVideoVirtioDeviceTypeFromString,
+ VIR_XML_PROP_NONZERO, &def->virtiodevice,
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_DEFAULT) < 0)
+ return -1;
+ }
+
if (virXMLPropUInt(node, "ram", 10, VIR_XML_PROP_NONE, &def->ram) < 0)
return -1;
@@ -21437,6 +21456,18 @@ virDomainVideoDefCheckABIStability(virDomainVideoDef *src,
return false;
}
+ /* While 'src->virtiodevice' vs 'dst->virtiodevice' match is considered
+ * guest ABI (both the device looks different to the guest OS and qemu
+ * refuses to migrate into wrong device) we deliberately omit the check
+ * here due to historical reasons.
+ *
+ * The actual values were not recorded in the XML after picking a device
+ * based on capabilities and thus, if the host configuration changes
+ * different defaults can be picked. Users might want to fix their
+ * saveimage or migration by specifying the proper model which will differ
+ * from the one that will be auto-picked via post-parse callback when the
+ * XML is loaded for the first time */
+
if (!virDomainVirtioOptionsCheckABIStability(src->virtio, dst->virtio))
return false;
@@ -27110,6 +27141,10 @@ virDomainVideoDefFormat(virBuffer *buf,
if (def->edid != VIR_TRISTATE_SWITCH_ABSENT)
virBufferAsprintf(&modelAttrBuf, " edid='%s'", virTristateSwitchTypeToString(def->edid));
+ if (def->virtiodevice != VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_DEFAULT)
+ virBufferAsprintf(&modelAttrBuf, " device='%s'",
+ virDomainVideoVirtioDeviceTypeToString(def->virtiodevice));
+
virDomainVideoAccelDefFormat(&modelChildBuf, def->accel);
virDomainVideoResolutionDefFormat(&modelChildBuf, def->res);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8c8c11c0cf..3a1a2fdce1 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1877,6 +1877,20 @@ typedef enum {
VIR_ENUM_DECL(virDomainVideoVGAConf);
+typedef enum {
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_DEFAULT = 0,
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA,
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU,
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA_GL,
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU_GL,
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VHOST_USER_VGA,
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VHOST_USER_GPU,
+
+ VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_LAST
+} virDomainVideoVirtioDevice;
+
+VIR_ENUM_DECL(virDomainVideoVirtioDevice);
+
struct _virDomainVideoAccelDef {
virTristateBool accel2d;
virTristateBool accel3d;
@@ -1907,6 +1921,7 @@ struct _virDomainVideoDef {
virDomainVideoResolutionDef *res;
virTristateSwitch blob;
virDomainVideoDriverDef *driver;
+ virDomainVideoVirtioDevice virtiodevice; /* virtio device frontend */
virDomainDeviceInfo info;
virDomainVirtioOptions *virtio;
virDomainVideoBackendType backend;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 9fde565d94..b8283f129e 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -4812,7 +4812,6 @@
<value>vmvga</value>
<value>xen</value>
<value>vbox</value>
- <value>virtio</value>
<value>gop</value>
<value>none</value>
<value>bochs</value>
@@ -4839,6 +4838,23 @@
</attribute>
</optional>
</group>
+ <group>
+ <attribute name="type">
+ <value>virtio</value>
+ </attribute>
+ <optional>
+ <attribute name="device">
+ <choice>
+ <value>virtio-vga</value>
+ <value>virtio-vga-gl</value>
+ <value>virtio-gpu</value>
+ <value>virtio-gpu-gl</value>
+ <value>vhost-user-vga</value>
+ <value>vhost-user-gpu</value>
+ </choice>
+ </attribute>
+ </optional>
+ </group>
</choice>
<optional>
<attribute name="vram">
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4a0f9065fa..b9f5056693 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -728,6 +728,7 @@ virDomainVideoTypeFromString;
virDomainVideoTypeToString;
virDomainVideoVGAConfTypeFromString;
virDomainVideoVGAConfTypeToString;
+virDomainVideoVirtioDeviceTypeToString;
virDomainVirtTypeFromString;
virDomainVirtTypeToString;
virDomainVsockDefEquals;
--
2.55.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,194 @@
From 8ceddabb12d1b32fbcffe9697885462af133d309 Mon Sep 17 00:00:00 2001
Message-ID: <8ceddabb12d1b32fbcffe9697885462af133d309.1784297531.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 11 Jun 2026 12:00:45 +0200
Subject: [PATCH] qemu: Allow reuse of 'qemuProcessStartUpdateCustomCaps'
Move and rename the function to 'qemuDomainUpdateCustomCapabilities' and
modify the arguments so that it will be possible to reuse it also in the
post-parse and validation code which ought to base decisions on the same
logic as VM startup would.
Since copying of the qemu capabilities object is very expensive (I've
observed an almost 4x slowdown of qemuxmlconftest)
'qemuDomainUpdateCustomCapabilities' copies the capabilities only when
necessary.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 9ec26e2c4f7c60a1ba62a90948a51a7ac0f582d8)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_domain.c | 79 +++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 6 ++++
src/qemu/qemu_process.c | 42 +---------------------
3 files changed, 86 insertions(+), 41 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 495cbd4f7d..7699d1000f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11769,3 +11769,82 @@ qemuDomainMachineSupportsFloppy(const char *machine,
return true;
}
+
+
+/**
+ * qemuDomainUpdateCustomCapabilities:
+ * @def: domain definition
+ * @qemuCaps: qemu capabilities
+ * @qemuCapsCopy: if non-NULL filled filled with a valid virQEMUCaps pointer (see below)
+ *
+ * Updates @qemuCaps based on the qemu namespace XML config for modifying
+ * capabilities:
+ *
+ * <domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
+ * <qemu:capabilities>
+ * <qemu:add capability='blockdev'/>
+ * <qemu:del capability='drive'/>
+ * </qemu:capabilities>
+ * </domain>
+ *
+ * If @qemuCapsCopy is NULL, @qemuCaps is directly modified.
+ *
+ * If @qemuCapsCopy is non-NULL, it's always filled with a virQEMUCaps instance
+ * that the caller needs to unref. The following applies:
+ * - no caps modification needed: @qemuCaps is ref'd and filled into @qemuCapsCopy
+ * - caps modifications are needed: @qemuCaps is copied into @qemuCapsCopy and
+ * modifications happen on the copy
+ *
+ * Returns 0 on success (including when no modification was needed), -1 on
+ * error and reports libvirt errors.
+ */
+int
+qemuDomainUpdateCustomCapabilities(const virDomainDef *def,
+ virQEMUCaps *qemuCaps,
+ virQEMUCaps **qemuCapsCopy)
+{
+ qemuDomainXmlNsDef *nsdef = def->namespaceData;
+ char **next;
+ int tmp;
+
+ if (!nsdef ||
+ (!nsdef->capsadd && !nsdef->capsdel)) {
+
+ if (qemuCapsCopy)
+ *qemuCapsCopy = virObjectRef(qemuCaps);
+
+ return 0;
+ }
+
+ if (qemuCapsCopy) {
+ *qemuCapsCopy = virQEMUCapsNewCopy(qemuCaps);
+
+ qemuCaps = *qemuCapsCopy;
+ }
+
+ for (next = nsdef->capsadd; next && *next; next++) {
+ if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid qemu namespace capability '%1$s'"),
+ *next);
+ return -1;
+ }
+
+ virQEMUCapsSet(qemuCaps, tmp);
+ }
+
+ for (next = nsdef->capsdel; next && *next; next++) {
+ if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid qemu namespace capability '%1$s'"),
+ *next);
+ return -1;
+ }
+
+ virQEMUCapsClear(qemuCaps, tmp);
+ }
+
+ virQEMUCapsInitProcessCapsInterlock(qemuCaps);
+
+ return 0;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 8cd221062c..ff26885ffe 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1197,3 +1197,9 @@ qemuDomainMachineSupportsFloppy(const char *machine,
virObject *
qemuDomainHostdevPrivateNew(void);
+
+int
+qemuDomainUpdateCustomCapabilities(const virDomainDef *def,
+ virQEMUCaps *qemuCaps,
+ virQEMUCaps **qemuCapsCopy)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7d9f754fc2..1540c74087 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5823,43 +5823,6 @@ qemuProcessStartValidate(virQEMUDriver *driver,
}
-static int
-qemuProcessStartUpdateCustomCaps(virDomainObj *vm)
-{
- qemuDomainObjPrivate *priv = vm->privateData;
- qemuDomainXmlNsDef *nsdef = vm->def->namespaceData;
-
- if (nsdef) {
- char **next;
- int tmp;
-
- for (next = nsdef->capsadd; next && *next; next++) {
- if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("invalid qemu namespace capability '%1$s'"),
- *next);
- return -1;
- }
-
- virQEMUCapsSet(priv->qemuCaps, tmp);
- }
-
- for (next = nsdef->capsdel; next && *next; next++) {
- if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("invalid qemu namespace capability '%1$s'"),
- *next);
- return -1;
- }
-
- virQEMUCapsClear(priv->qemuCaps, tmp);
- }
- }
-
- return 0;
-}
-
-
/**
* qemuProcessPrepareQEMUCaps:
* @vm: domain object
@@ -5883,12 +5846,9 @@ qemuProcessPrepareQEMUCaps(virDomainObj *vm,
return -1;
/* Update qemu capabilities according to lists passed in via namespace */
- if (qemuProcessStartUpdateCustomCaps(vm) < 0)
+ if (qemuDomainUpdateCustomCapabilities(vm->def, priv->qemuCaps, NULL) < 0)
return -1;
- /* re-process capability lockouts since we might have removed capabilities */
- virQEMUCapsInitProcessCapsInterlock(priv->qemuCaps);
-
return 0;
}
--
2.55.0

View File

@ -0,0 +1,119 @@
From 36c833cacb0d001ab43ba9662fe432922491c3b5 Mon Sep 17 00:00:00 2001
Message-ID: <36c833cacb0d001ab43ba9662fe432922491c3b5.1782911963.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 15 Jun 2026 13:01:01 +0200
Subject: [PATCH] qemu: Ensure proper shutdown ordering of virtlockd/virtlogd
daemons
For socket activation to work our systemd unit files use the following
pattern:
[virtlogd.socket] <----(After)--- [virtlogd.service]
[virtqemud.socket] <----(After)--- [virtqemud.service]
Now the qemu daemon also wants to use the services provided by those
daemons so we have dependency between the two too:
[virtlogd.socket] <----(After)--- [virtlogd.service]
^
+-------------(After+Requires)-------+
|
[virtqemud.socket] <----(After)--- [virtqemud.service]
Now on startup everything is fine, because with socket activation, when
'virtqemud.service' wants to use 'virtlogd' services the socket is
already up due to the dependency+ordering and opening a connection will
cause 'virtlogd.service' to be socket-activated.
On shutdown though there's no transitive 'After' ordering between
'virtqemud.service' and 'virtlogd.service' and thus nothing explicitly
telling systemd that if virtlogd was started. In fact systemd is free to
translate it that 'virtlogd' and 'virtqemud' need to be stopped before
stopping 'virtlogd.socket'.
To illustrate what happens consider the following scenario:
A host is running a VM under virtqemud. 'virtqemud' is configured to
attempt shutdown on the VMs before killing them (daemon-based guest
shutdown, but the same reproduces also with libvirt-guests). The host
is being rebooted.
(virtqemud attempts to shut down guests, but guest takes more than the
configured shutdown inhibition timeout, journald output follows):
06:44:02 fedora systemd-logind[664]: Delay lock is active (UID 0/root, PID 991/virtqemud) but inhibitor timeout is reached.
06:44:02 fedora systemd-logind[664]: System is rebooting.
[...]
06:44:02 fedora virtlogd[802]: 802: debug : virSystemdNotify:667 : Notify 'STOPPING=1'
06:44:02 fedora systemd[1]: Stopping virtlogd.service - libvirt logging daemon...
06:44:02 fedora systemd[1]: Stopping virtqemud.service - libvirt QEMU daemon...
06:44:02 fedora virtqemud[991]: 991: debug : virSystemdNotify:667 : Notify 'STOPPING=1'
06:44:02 fedora systemd[1]: virtlogd.service: Deactivated successfully.
06:44:02 fedora systemd[1]: Stopped virtlogd.service - libvirt logging daemon.
(the shutdown times out, virtqemud kills the unresponsive vm)
06:44:27 fedora virtqemud[991]: 1053: debug : qemuProcessStop:8916 : Shutting down vm=0x7f71ac032670 name=virt-vm1 id=1 pid=805, reason=destroyed, asyncJob=none, flags=0x0
06:44:27 fedora virtqemud[991]: 1053: debug : qemuDomainLogAppendMessage:5757 : Append log message (vm='virt-vm1' message='2026-06-15 10:44:27.427+0000: shutting down, reason=destroyed
) stdioLogD=1
06:44:27 fedora virtqemud[991]: 1053: error : virNetSocketReadWire:1767 : Cannot recv data: Connection reset by peer
06:44:27 fedora virtqemud[991]: 1053: debug : qemuProcessKill:8811 : vm=0x7f71ac032670 name=virt-vm1 pid=805 flags=0x5
Now the log shows that we want to add VM log file message in
'qemuDomainLogAppendMessage' but it fails because virtlogd is dead
already.
Now the same happens also with 'virtlockd' but with much worse outcome,
especially if the configured action is to save the VMs because shutdown
of 'virtlockd' when locks are held ends up 'fencing' the VMs by killing
them.
The same also happens when libvirt-guests is used to shutdown the guests
instead.
This patch adds an explicit 'After=virtlo[ck|g]d.service' to the daemons
containing the qemu driver to ensure that the shutdown ordering makes
sense. This doesn't break socket activation (e.g. the log/lock daemons
are not started unless first invoked).
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit aa1bf13b9caa4ef893cd4fdbaa111d5da73aa120)
https://redhat.atlassian.net/browse/RHEL-180876
---
src/qemu/virtqemud.service.extra.in | 4 ++++
src/remote/libvirtd.service.in | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/src/qemu/virtqemud.service.extra.in b/src/qemu/virtqemud.service.extra.in
index cc16b6a9bb..3cc2edcfd0 100644
--- a/src/qemu/virtqemud.service.extra.in
+++ b/src/qemu/virtqemud.service.extra.in
@@ -6,6 +6,10 @@ Requires=virtlogd.socket
Wants=virtlockd.socket
After=virtlogd.socket
After=virtlockd.socket
+# To ensure that our helper daemons are not shut down before the main daemon
+# shuts down we need also explicit ordering with the .service unit
+After=virtlogd.service
+After=virtlock.service
Wants=systemd-machined.service
After=systemd-machined.service
After=remote-fs.target
diff --git a/src/remote/libvirtd.service.in b/src/remote/libvirtd.service.in
index b0a062e885..f26494d646 100644
--- a/src/remote/libvirtd.service.in
+++ b/src/remote/libvirtd.service.in
@@ -15,6 +15,10 @@ Requires=virtlogd.socket
Wants=virtlockd.socket
After=virtlogd.socket
After=virtlockd.socket
+# To ensure that our helper daemons are not shut down before the main daemon
+# shuts down we need also explicit ordering with the .service unit
+After=virtlogd.service
+After=virtlock.service
Wants=systemd-machined.service
After=network.target
After=dbus.service
--
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,64 @@
From 5b39266bbc99576fec79c1dc9e24823a9aaa3602 Mon Sep 17 00:00:00 2001
Message-ID: <5b39266bbc99576fec79c1dc9e24823a9aaa3602.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 9 Jun 2026 22:58:54 +0200
Subject: [PATCH] qemu: Remove 'qemuDomainSupportsVideoVga'
The function is unused remove it.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit a95619316406b43457c0fb1436031042d5e25bec)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_domain.c | 17 -----------------
src/qemu/qemu_domain.h | 3 ---
2 files changed, 20 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 7699d1000f..78587e2574 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9267,23 +9267,6 @@ qemuDomainVcpuPersistOrder(virDomainDef *def)
}
-bool
-qemuDomainSupportsVideoVga(const virDomainVideoDef *video,
- virQEMUCaps *qemuCaps)
-{
- if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
- if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VHOST_USER_VGA))
- return false;
- } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_VGA)) {
- return false;
- }
- }
-
- return true;
-}
-
-
/**
* qemuDomainNeedsVFIO:
* @def: domain definition to check
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index ff26885ffe..a8bf301d51 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -985,9 +985,6 @@ bool qemuDomainVcpuHotplugIsInOrder(virDomainDef *def)
void qemuDomainVcpuPersistOrder(virDomainDef *def)
ATTRIBUTE_NONNULL(1);
-bool qemuDomainSupportsVideoVga(const virDomainVideoDef *video,
- virQEMUCaps *qemuCaps);
-
bool qemuDomainNeedsVFIO(const virDomainDef *def);
int qemuDomainGetHostdevPath(virDomainHostdevDef *dev,
--
2.55.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,247 @@
From 2564c0a45ab725c84deb64abc4fb57ad263fad15 Mon Sep 17 00:00:00 2001
Message-ID: <2564c0a45ab725c84deb64abc4fb57ad263fad15.1784297531.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 11 Jun 2026 11:33:36 +0200
Subject: [PATCH] qemu: capabilities: Apply 'capability_filters' configration
option on all capabilities
The 'capability_filters' allows admins to globally disable some qemu
capabilities via the config file.
Until now it was applied only directly when starting the VM, but that is
too late as the capability is still present when e.g. the post-parse
code is picking defaults.
Rework the code so that 'capability_filters' is applied directly after
probing qemu so all existing capabilities will lack the filtered out
ones.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit b8dfb9551e4cafebea94fc09b2ab51f63dfa8512)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_capabilities.c | 21 ++++++++++++++++++---
src/qemu/qemu_capabilities.h | 3 ++-
src/qemu/qemu_capspriv.h | 3 ++-
src/qemu/qemu_driver.c | 23 ++++++++++++++++++++++-
src/qemu/qemu_process.c | 19 +++----------------
tests/qemucapsprobe.c | 3 ++-
tests/testutilsqemu.c | 3 ++-
7 files changed, 51 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f06f376dd7..83ec1e2769 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4538,6 +4538,11 @@ struct _virQEMUCapsCachePriv {
/* cache whether /dev/kvm is usable as runUid:runGuid */
virTristateBool kvmUsable;
time_t kvmCtime;
+
+ /* qemu.conf allows masking out supported capabilities via
+ * 'capabilities_filter' configuration. 'maskedCaps' if non-NULL
+ * maps out which bits are to be removed */
+ virBitmap *maskedCaps;
};
typedef struct _virQEMUCapsCachePriv virQEMUCapsCachePriv;
@@ -4551,6 +4556,7 @@ virQEMUCapsCachePrivFree(void *privData)
g_free(priv->kernelVersion);
virCPUDataFree(priv->cpuData);
g_free(priv->hostCPUSignature);
+ virBitmapFree(priv->maskedCaps);
g_free(priv);
}
@@ -6110,7 +6116,8 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
const char *hostCPUSignature,
unsigned int microcodeVersion,
const char *kernelVersion,
- virCPUData* cpuData)
+ virCPUData* cpuData,
+ virBitmap *maskedCaps)
{
g_autoptr(virQEMUCaps) qemuCaps = virQEMUCapsNewBinary(binary);
struct stat sb;
@@ -6149,6 +6156,10 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
qemuCaps->libvirtCtime = virGetSelfLastChanged();
qemuCaps->libvirtVersion = LIBVIR_VERSION_NUMBER;
+ /* If we have capabilities masked out via qemu.conf apply them here */
+ if (maskedCaps)
+ virBitmapSubtract(qemuCaps->flags, maskedCaps);
+
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
@@ -6189,7 +6200,8 @@ virQEMUCapsNewData(const char *binary,
priv->hostCPUSignature,
virHostCPUGetMicrocodeVersion(priv->hostArch),
priv->kernelVersion,
- priv->cpuData);
+ priv->cpuData,
+ priv->maskedCaps);
}
@@ -6228,7 +6240,8 @@ virFileCache *
virQEMUCapsCacheNew(const char *libDir,
const char *cacheDir,
uid_t runUid,
- gid_t runGid)
+ gid_t runGid,
+ virBitmap *maskedCaps)
{
g_autofree char *capsCacheDir = NULL;
virFileCache *cache = NULL;
@@ -6258,9 +6271,11 @@ virQEMUCapsCacheNew(const char *libDir,
priv->kernelVersion = g_strdup_printf("%s %s", uts.release, uts.version);
priv->cpuData = virCPUDataGetHost();
+ priv->maskedCaps = maskedCaps;
return cache;
error:
+ virBitmapFree(maskedCaps);
virObjectUnref(cache);
return NULL;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 8822bf120b..8701c76b6d 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -861,7 +861,8 @@ char * virQEMUCapsGetDefaultEmulator(virArch hostarch,
virFileCache *virQEMUCapsCacheNew(const char *libDir,
const char *cacheDir,
uid_t uid,
- gid_t gid);
+ gid_t gid,
+ virBitmap *maskedCaps);
virQEMUCaps *virQEMUCapsCacheLookup(virFileCache *cache,
const char *binary);
virQEMUCaps *virQEMUCapsCacheLookupCopy(virFileCache *cache,
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index 55286d7d29..9dca15d09b 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -36,7 +36,8 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
const char *hostCPUSignature,
unsigned int microcodeVersion,
const char *kernelVersion,
- virCPUData* cpuData);
+ virCPUData* cpuData,
+ virBitmap *maskedCaps);
int virQEMUCapsLoadCache(virArch hostArch,
virQEMUCaps *qemuCaps,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index dcb49a9d42..3c7de45301 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -538,6 +538,7 @@ qemuStateInitialize(bool privileged,
const char *defsecmodel = NULL;
g_autoptr(virIdentity) identity = virIdentityGetCurrent();
virDomainDriverAutoStartConfig autostartCfg;
+ g_autoptr(virBitmap) maskedCaps = NULL;
qemu_driver = g_new0(virQEMUDriver, 1);
@@ -817,10 +818,30 @@ qemuStateInitialize(bool privileged,
run_gid = cfg->group;
}
+ if (cfg->capabilityfilters) {
+ int tmp;
+ char **next;
+
+ maskedCaps = virBitmapNew(0);
+
+ for (next = cfg->capabilityfilters; *next; next++) {
+ if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
+ virReportError(VIR_ERR_CONF_SYNTAX,
+ _("invalid capability_filters capability '%1$s'"),
+ *next);
+ return -1;
+ }
+
+ virBitmapSetBitExpand(maskedCaps, tmp);
+ }
+ }
+
+
qemu_driver->qemuCapsCache = virQEMUCapsCacheNew(cfg->libDir,
cfg->cacheDir,
run_uid,
- run_gid);
+ run_gid,
+ g_steal_pointer(&maskedCaps));
if (!qemu_driver->qemuCapsCache)
goto error;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b56e79ed1c..7d9f754fc2 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5827,25 +5827,12 @@ static int
qemuProcessStartUpdateCustomCaps(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
- g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
qemuDomainXmlNsDef *nsdef = vm->def->namespaceData;
- char **next;
- int tmp;
-
- if (cfg->capabilityfilters) {
- for (next = cfg->capabilityfilters; *next; next++) {
- if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("invalid capability_filters capability '%1$s'"),
- *next);
- return -1;
- }
-
- virQEMUCapsClear(priv->qemuCaps, tmp);
- }
- }
if (nsdef) {
+ char **next;
+ int tmp;
+
for (next = nsdef->capsadd; next && *next; next++) {
if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
diff --git a/tests/qemucapsprobe.c b/tests/qemucapsprobe.c
index cd117170ab..8ce5c10dec 100644
--- a/tests/qemucapsprobe.c
+++ b/tests/qemucapsprobe.c
@@ -79,7 +79,8 @@ main(int argc, char **argv)
return EXIT_FAILURE;
if (!(caps = virQEMUCapsNewForBinaryInternal(VIR_ARCH_NONE, argv[1], "/tmp",
- -1, -1, NULL, 0, NULL, NULL)))
+ -1, -1, NULL, 0, NULL, NULL,
+ NULL)))
return EXIT_FAILURE;
host = virArchFromHost();
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index fc51e0e3df..bd797525f0 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -363,7 +363,8 @@ int qemuTestDriverInit(virQEMUDriver *driver)
/* Using /dev/null for libDir and cacheDir automatically produces errors
* upon attempt to use any of them */
- driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0);
+ driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null",
+ 0, 0, NULL);
if (!driver->qemuCapsCache)
goto error;
--
2.55.0

View File

@ -0,0 +1,66 @@
From 173a0b7768999f9be2eb0e16bad6a3eaf12fbb74 Mon Sep 17 00:00:00 2001
Message-ID: <173a0b7768999f9be2eb0e16bad6a3eaf12fbb74.1784297531.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 11 Jun 2026 12:12:42 +0200
Subject: [PATCH] qemu: capabilities: Export 'virQEMUCapsNewCopy' outside of
'qemu_capspriv'
Upcoming patch will add a function which will need to optionally copy
passed capabilities for modification. Export 'virQEMUCapsNewCopy'
outside of tests.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 1bbefb6409d43969505db7a71999943e40aa9c9d)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_capabilities.c | 3 ++-
src/qemu/qemu_capabilities.h | 2 ++
src/qemu/qemu_capspriv.h | 2 --
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 83ec1e2769..6dd7284505 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2082,7 +2082,8 @@ virQEMUCapsAccelCopy(virQEMUCapsAccel *dst,
}
-virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps)
+virQEMUCaps *
+virQEMUCapsNewCopy(virQEMUCaps *qemuCaps)
{
g_autoptr(virQEMUCaps) ret = virQEMUCapsNewBinary(qemuCaps->binary);
size_t i;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 8701c76b6d..334e98aac4 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -876,6 +876,8 @@ virQEMUCaps *virQEMUCapsCacheLookupDefault(virFileCache *cache,
virDomainVirtType *retVirttype,
const char **retMachine);
+virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps);
+
virCaps *virQEMUCapsInit(virFileCache *cache);
int virQEMUCapsGetDefaultVersion(virCaps *caps,
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index 9dca15d09b..3dfff2e3d8 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -25,8 +25,6 @@
#pragma once
-virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps);
-
virQEMUCaps *
virQEMUCapsNewForBinaryInternal(virArch hostArch,
const char *binary,
--
2.55.0

View File

@ -0,0 +1,931 @@
From 53bcd009b21687baecb0568bc4b4768b03c3ad89 Mon Sep 17 00:00:00 2001
Message-ID: <53bcd009b21687baecb0568bc4b4768b03c3ad89.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 8 Jun 2026 16:54:50 +0200
Subject: [PATCH] qemu: postparse: Fill in selected virtio video frondend
device in the XML
Historically 'virtio-vga' was always picked as the first '<video>'
(virtio) device and any sub-sequent ones were 'virtio-gpu'. When support
for aarch64 VMs was being added an exception to use 'virtio-gpu' for the
primary device was added as aarch64 doesn't have anything resembling the
"legacy" 'VGA' interface. At this point this exception was only for
aarch64. The distinction between 'virtio-vga' and 'virtio-gpu' was *not*
recorded in the VM XML as it was a new feature (for aarch64) and it
didn't make sense to pick 'virtio-vga'.
Some time later the following commit:
commit 4c029e8cfa3338ef1a2d6851908a9fcf494a32e5
Author: Pavel Hrdina <phrdina@redhat.com>
Date: Fri Sep 30 14:41:37 2016 +0200
qemu_command: properly detect which model to use for video device
This improves commit 706b5b6277 in a way that we check qemu capabilities
instead of what architecture we are running on to detect whether we can
use *virtio-vga* model or not. This is not a case only for arm/aarch64.
modified the code to do this picking by checking presence of
'virtio-vga' device instead. That approach didn't consider the fact that
the modular deployment of qemu allows for the 'virtio-vga' device to be
missing in certain cases, thus introducing a latent bug as we'll pick
'virtio-gpu' in such case but don't record it anywhere.
Now this creates a problem, if the deployments differ, because you can
have two *incompatible* (at migration stream level) setups which are
based on the same identical XML without the possibility for the
destination libvirt instance during migration to pick which is the
correct one.
To prevent this and actually fix any existing such deployment (which
allows upgrade of libvirt daemons on the source) we will record the
picked device frontend at post-parse time into the XML. This luckily
properly handles running VMs even if 'virtio-vga' were already
installed since we record the actual qemuCaps we've started the VM with.
Now 'virtio-vga' vs 'virtio-gpu' is not the only broken piece of logic.
In fact 'virtio-vga-gl' could have been downgraded to 'virtio-vga' based
on some very weird logic (see comments in code for explanation).
The logic in 'qemuDomainDeviceVideoDefPostParse' re-creates the logic
used to setup virtio-vga vs. virtio-gpu, and 'vhost-user-vga' vs.
'vhost-user-gpu' as those still make sense. For the 'gl' variants two
versions exist, one meant to recover running VMs and one for new VMs
where the broken logic makes no sense.
Now this patch just records what was selected into the XML, but doesn't
yet modify the commandline to actually use that value verbatim (e.g. if
the user specified an actual non-default value already).
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 38c970f64187b42605f611000a6b4c0e2dedd0d8)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_postparse.c | 97 ++++++++++++++++++-
.../virtio-vga-upgrade-missing-out.xml | 2 +-
.../virtio-vga-upgrade-out.xml | 2 +-
.../aarch64-video-default.aarch64-latest.xml | 2 +-
...64-video-virtio-gpu-pci.aarch64-latest.xml | 2 +-
...fault-models.aarch64-latest.abi-update.xml | 2 +-
...h64-virt-default-models.aarch64-latest.xml | 2 +-
.../aarch64-virt-graphics.aarch64-latest.xml | 2 +-
...ault-video-type-aarch64.aarch64-latest.xml | 2 +-
...eo-type-loongarch64.loongarch64-latest.xml | 2 +-
...ault-video-type-riscv64.riscv64-latest.xml | 2 +-
.../default-video-type-s390x.s390x-latest.xml | 2 +-
...t-models.loongarch64-latest.abi-update.xml | 2 +-
...virt-default-models.loongarch64-latest.xml | 2 +-
...rch64-virt-graphics.loongarch64-latest.xml | 2 +-
.../q35-pcie-autoadd.x86_64-latest.xml | 2 +-
.../q35-pcie.x86_64-latest.xml | 2 +-
...fault-models.riscv64-latest.abi-update.xml | 2 +-
...v64-virt-default-models.riscv64-latest.xml | 2 +-
.../riscv64-virt-graphics.riscv64-latest.xml | 2 +-
...default-models.s390x-latest.abi-update.xml | 2 +-
.../s390x-ccw-default-models.s390x-latest.xml | 2 +-
.../s390x-ccw-graphics.s390x-latest.xml | 2 +-
...vhost-user-gpu-secondary.x86_64-latest.xml | 4 +-
.../vhost-user-vga.x86_64-latest.xml | 2 +-
.../video-virtio-blob-off.x86_64-latest.xml | 4 +-
.../video-virtio-blob-on.x86_64-latest.xml | 4 +-
.../video-virtio-edid-none.x86_64-latest.xml | 2 +-
.../video-virtio-edid-off.x86_64-latest.xml | 2 +-
.../video-virtio-edid-on.x86_64-latest.xml | 2 +-
...video-virtio-gpu-ccw-auto.s390x-latest.xml | 2 +-
.../video-virtio-gpu-ccw.s390x-latest.xml | 4 +-
.../video-virtio-gpu-device.x86_64-latest.xml | 2 +-
.../video-virtio-gpu-sdl-gl.x86_64-latest.xml | 2 +-
...deo-virtio-gpu-secondary.x86_64-latest.xml | 4 +-
...ideo-virtio-gpu-spice-gl.x86_64-latest.xml | 2 +-
.../video-virtio-gpu-virgl.x86_64-latest.xml | 2 +-
..._VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml | 2 +-
...t.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml | 4 +-
...CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml | 4 +-
...atest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml | 4 +-
.../video-virtio-vga-gpu-gl.x86_64-latest.xml | 4 +-
...t.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml | 2 +-
.../video-virtio-vga.x86_64-latest.xml | 2 +-
...virtio-options-video-ats.x86_64-latest.xml | 4 +-
...rtio-options-video-iommu.x86_64-latest.xml | 4 +-
...tio-options-video-packed.x86_64-latest.xml | 4 +-
tests/qemuxmlconfdata/virtio-options.xml | 2 +-
48 files changed, 154 insertions(+), 61 deletions(-)
diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c
index cd88cd1806..0d803a8abb 100644
--- a/src/qemu/qemu_postparse.c
+++ b/src/qemu/qemu_postparse.c
@@ -308,7 +308,8 @@ qemuDomainDefaultVideoDevice(const virDomainDef *def,
static int
qemuDomainDeviceVideoDefPostParse(virDomainVideoDef *video,
const virDomainDef *def,
- virQEMUCaps *qemuCaps)
+ virQEMUCaps *qemuCaps,
+ unsigned int parseFlags)
{
if (video->type == VIR_DOMAIN_VIDEO_TYPE_DEFAULT)
video->type = qemuDomainDefaultVideoDevice(def, qemuCaps);
@@ -318,6 +319,98 @@ qemuDomainDeviceVideoDefPostParse(virDomainVideoDef *video,
video->vgamem = QEMU_QXL_VGAMEM_DEFAULT;
}
+ /* Fill in 'virtiodevice' (device='%s' attribute in XML.
+ *
+ * Historically for <video><model type='virtio' ... the selection of the
+ * actual device type (virtio-vga, virtio-vga-gl, virtio-gpu, virtio-gpu-gl)
+ * was done when formatting commandline based on capabilities.
+ *
+ * Unfortunately neither of the aforementioned models are ABI/migration
+ * compatible. We must thus record the selcted model in the XML and that
+ * possibly retroactively based on the capabilities.
+ *
+ * For non accelerated video devices the logic is as follows:
+ * - for any secondary video device 'virtio-gpu' is always picked
+ * - for 'primary' video device 'virtio-vga' is used if available. If not
+ * 'virtio-gpu' is picked instead.
+ *
+ * We want to use the above logic both for existing VMs and new VMs since
+ * this is currently the proper configuration.
+ *
+ * For accelerated video devices the logic is slightly more broken as the
+ * fallbacks depended both on which of 'virtio-vga', 'virtio-vga-gl',
+ * 'virtio-gpu-gl', modules was actually found (see code below).
+ *
+ * For new VMs we do not want to fall back to non-gl versions since that
+ * disables acceleration.
+ */
+ if (qemuCaps &&
+ video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO &&
+ video->virtiodevice == VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_DEFAULT) {
+ /* in certain cases video->primary was not yet assigned */
+ bool primary = video->primary || (video == def->videos[0]);
+
+ if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
+ /* primary device is 'vhost-user-vga' if available */
+ if (primary &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VHOST_USER_VGA)) {
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VHOST_USER_VGA;
+ } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VHOST_USER_GPU)) {
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VHOST_USER_GPU;
+ } else {
+ /* Don't fill in default; let validation reject the config */
+ }
+ } else {
+ if (video->accel &&
+ video->accel->accel3d == VIR_TRISTATE_BOOL_YES) {
+ /* if starting a new config don't downgrade to the non '-gl' vriants,
+ * allow downgrade only to preserve migration/ABI compatibility */
+ if (parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE) {
+ if (primary &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_VGA_GL)) {
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA_GL;
+ } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_GL_PCI)) {
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU_GL;
+ } else {
+ /* Don't fill in default; let validation reject the config */
+ }
+ } else {
+ /* This logic is wrong, but faithfully represents the device
+ * the qemu driver would pick for an accelerated video device */
+ if (primary &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_VGA)) {
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_VGA_GL)) {
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA_GL;
+ } else {
+ /* based on the above check we know this one exists */
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA;
+ }
+ } else {
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_GL_PCI)) {
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU_GL;
+ } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU)) {
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU;
+ } else {
+ /* this branch isn't a faithful representation of
+ * the old logic, but the VM wouldn't start anyway
+ * so we might as well make validation reject it */
+ }
+ }
+ }
+ } else {
+ /* primary device is 'virtio-vga' if available */
+ if (primary &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_VGA)) {
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA;
+ } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU)) {
+ video->virtiodevice = VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU;
+ } else {
+ /* Don't fill in default; let validation reject the config */
+ }
+ }
+ }
+ }
+
return 0;
}
@@ -855,7 +948,7 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev,
break;
case VIR_DOMAIN_DEVICE_VIDEO:
- ret = qemuDomainDeviceVideoDefPostParse(dev->data.video, def, qemuCaps);
+ ret = qemuDomainDeviceVideoDefPostParse(dev->data.video, def, qemuCaps, parseFlags);
break;
case VIR_DOMAIN_DEVICE_PANIC:
diff --git a/tests/qemustatusxml2xmldata/virtio-vga-upgrade-missing-out.xml b/tests/qemustatusxml2xmldata/virtio-vga-upgrade-missing-out.xml
index e7b3dd17ed..a58c4cc75f 100644
--- a/tests/qemustatusxml2xmldata/virtio-vga-upgrade-missing-out.xml
+++ b/tests/qemustatusxml2xmldata/virtio-vga-upgrade-missing-out.xml
@@ -423,7 +423,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<alias name='video0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</video>
diff --git a/tests/qemustatusxml2xmldata/virtio-vga-upgrade-out.xml b/tests/qemustatusxml2xmldata/virtio-vga-upgrade-out.xml
index 948d4c8135..db6099a2bb 100644
--- a/tests/qemustatusxml2xmldata/virtio-vga-upgrade-out.xml
+++ b/tests/qemustatusxml2xmldata/virtio-vga-upgrade-out.xml
@@ -425,7 +425,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<alias name='video0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</video>
diff --git a/tests/qemuxmlconfdata/aarch64-video-default.aarch64-latest.xml b/tests/qemuxmlconfdata/aarch64-video-default.aarch64-latest.xml
index 558b8fab3e..c559134106 100644
--- a/tests/qemuxmlconfdata/aarch64-video-default.aarch64-latest.xml
+++ b/tests/qemuxmlconfdata/aarch64-video-default.aarch64-latest.xml
@@ -36,7 +36,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</video>
</devices>
diff --git a/tests/qemuxmlconfdata/aarch64-video-virtio-gpu-pci.aarch64-latest.xml b/tests/qemuxmlconfdata/aarch64-video-virtio-gpu-pci.aarch64-latest.xml
index a212a28350..167b40887c 100644
--- a/tests/qemuxmlconfdata/aarch64-video-virtio-gpu-pci.aarch64-latest.xml
+++ b/tests/qemuxmlconfdata/aarch64-video-virtio-gpu-pci.aarch64-latest.xml
@@ -38,7 +38,7 @@
</interface>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
</video>
</devices>
diff --git a/tests/qemuxmlconfdata/aarch64-virt-default-models.aarch64-latest.abi-update.xml b/tests/qemuxmlconfdata/aarch64-virt-default-models.aarch64-latest.abi-update.xml
index 5abf55cf36..0f1e1a5892 100644
--- a/tests/qemuxmlconfdata/aarch64-virt-default-models.aarch64-latest.abi-update.xml
+++ b/tests/qemuxmlconfdata/aarch64-virt-default-models.aarch64-latest.abi-update.xml
@@ -70,7 +70,7 @@
</tpm>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/aarch64-virt-default-models.aarch64-latest.xml b/tests/qemuxmlconfdata/aarch64-virt-default-models.aarch64-latest.xml
index 5abf55cf36..0f1e1a5892 100644
--- a/tests/qemuxmlconfdata/aarch64-virt-default-models.aarch64-latest.xml
+++ b/tests/qemuxmlconfdata/aarch64-virt-default-models.aarch64-latest.xml
@@ -70,7 +70,7 @@
</tpm>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/aarch64-virt-graphics.aarch64-latest.xml b/tests/qemuxmlconfdata/aarch64-virt-graphics.aarch64-latest.xml
index 98ecc9ac70..e4a899384d 100644
--- a/tests/qemuxmlconfdata/aarch64-virt-graphics.aarch64-latest.xml
+++ b/tests/qemuxmlconfdata/aarch64-virt-graphics.aarch64-latest.xml
@@ -109,7 +109,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/default-video-type-aarch64.aarch64-latest.xml b/tests/qemuxmlconfdata/default-video-type-aarch64.aarch64-latest.xml
index e8fb758a71..c8e8f220be 100644
--- a/tests/qemuxmlconfdata/default-video-type-aarch64.aarch64-latest.xml
+++ b/tests/qemuxmlconfdata/default-video-type-aarch64.aarch64-latest.xml
@@ -34,7 +34,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/default-video-type-loongarch64.loongarch64-latest.xml b/tests/qemuxmlconfdata/default-video-type-loongarch64.loongarch64-latest.xml
index 244f57ff8e..41b8bf8133 100644
--- a/tests/qemuxmlconfdata/default-video-type-loongarch64.loongarch64-latest.xml
+++ b/tests/qemuxmlconfdata/default-video-type-loongarch64.loongarch64-latest.xml
@@ -37,7 +37,7 @@
</graphics>
<audio id='1' type='spice'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/default-video-type-riscv64.riscv64-latest.xml b/tests/qemuxmlconfdata/default-video-type-riscv64.riscv64-latest.xml
index 4e138ea717..b9a8152924 100644
--- a/tests/qemuxmlconfdata/default-video-type-riscv64.riscv64-latest.xml
+++ b/tests/qemuxmlconfdata/default-video-type-riscv64.riscv64-latest.xml
@@ -34,7 +34,7 @@
</graphics>
<audio id='1' type='spice'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/default-video-type-s390x.s390x-latest.xml b/tests/qemuxmlconfdata/default-video-type-s390x.s390x-latest.xml
index c8aac8f1bf..d6223b84a0 100644
--- a/tests/qemuxmlconfdata/default-video-type-s390x.s390x-latest.xml
+++ b/tests/qemuxmlconfdata/default-video-type-s390x.s390x-latest.xml
@@ -22,7 +22,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0000'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/loongarch64-virt-default-models.loongarch64-latest.abi-update.xml b/tests/qemuxmlconfdata/loongarch64-virt-default-models.loongarch64-latest.abi-update.xml
index f25d6c2cf0..0d27ffda54 100644
--- a/tests/qemuxmlconfdata/loongarch64-virt-default-models.loongarch64-latest.abi-update.xml
+++ b/tests/qemuxmlconfdata/loongarch64-virt-default-models.loongarch64-latest.abi-update.xml
@@ -64,7 +64,7 @@
</console>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/loongarch64-virt-default-models.loongarch64-latest.xml b/tests/qemuxmlconfdata/loongarch64-virt-default-models.loongarch64-latest.xml
index f25d6c2cf0..0d27ffda54 100644
--- a/tests/qemuxmlconfdata/loongarch64-virt-default-models.loongarch64-latest.xml
+++ b/tests/qemuxmlconfdata/loongarch64-virt-default-models.loongarch64-latest.xml
@@ -64,7 +64,7 @@
</console>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/loongarch64-virt-graphics.loongarch64-latest.xml b/tests/qemuxmlconfdata/loongarch64-virt-graphics.loongarch64-latest.xml
index 0be35dcba8..7bb6b123ea 100644
--- a/tests/qemuxmlconfdata/loongarch64-virt-graphics.loongarch64-latest.xml
+++ b/tests/qemuxmlconfdata/loongarch64-virt-graphics.loongarch64-latest.xml
@@ -102,7 +102,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/q35-pcie-autoadd.x86_64-latest.xml b/tests/qemuxmlconfdata/q35-pcie-autoadd.x86_64-latest.xml
index c92408d95c..92e3943a20 100644
--- a/tests/qemuxmlconfdata/q35-pcie-autoadd.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/q35-pcie-autoadd.x86_64-latest.xml
@@ -138,7 +138,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</video>
<watchdog model='itco' action='reset'/>
diff --git a/tests/qemuxmlconfdata/q35-pcie.x86_64-latest.xml b/tests/qemuxmlconfdata/q35-pcie.x86_64-latest.xml
index 0a36e78e02..b68284320c 100644
--- a/tests/qemuxmlconfdata/q35-pcie.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/q35-pcie.x86_64-latest.xml
@@ -142,7 +142,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</video>
<watchdog model='itco' action='reset'/>
diff --git a/tests/qemuxmlconfdata/riscv64-virt-default-models.riscv64-latest.abi-update.xml b/tests/qemuxmlconfdata/riscv64-virt-default-models.riscv64-latest.abi-update.xml
index 620da73422..2e0d5f6634 100644
--- a/tests/qemuxmlconfdata/riscv64-virt-default-models.riscv64-latest.abi-update.xml
+++ b/tests/qemuxmlconfdata/riscv64-virt-default-models.riscv64-latest.abi-update.xml
@@ -67,7 +67,7 @@
</tpm>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/riscv64-virt-default-models.riscv64-latest.xml b/tests/qemuxmlconfdata/riscv64-virt-default-models.riscv64-latest.xml
index 620da73422..2e0d5f6634 100644
--- a/tests/qemuxmlconfdata/riscv64-virt-default-models.riscv64-latest.xml
+++ b/tests/qemuxmlconfdata/riscv64-virt-default-models.riscv64-latest.xml
@@ -67,7 +67,7 @@
</tpm>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/riscv64-virt-graphics.riscv64-latest.xml b/tests/qemuxmlconfdata/riscv64-virt-graphics.riscv64-latest.xml
index 9f35b5ed18..0857a00710 100644
--- a/tests/qemuxmlconfdata/riscv64-virt-graphics.riscv64-latest.xml
+++ b/tests/qemuxmlconfdata/riscv64-virt-graphics.riscv64-latest.xml
@@ -99,7 +99,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/s390x-ccw-default-models.s390x-latest.abi-update.xml b/tests/qemuxmlconfdata/s390x-ccw-default-models.s390x-latest.abi-update.xml
index 9e0af389a9..cd3a00d01a 100644
--- a/tests/qemuxmlconfdata/s390x-ccw-default-models.s390x-latest.abi-update.xml
+++ b/tests/qemuxmlconfdata/s390x-ccw-default-models.s390x-latest.abi-update.xml
@@ -37,7 +37,7 @@
</console>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0001'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/s390x-ccw-default-models.s390x-latest.xml b/tests/qemuxmlconfdata/s390x-ccw-default-models.s390x-latest.xml
index 9e0af389a9..cd3a00d01a 100644
--- a/tests/qemuxmlconfdata/s390x-ccw-default-models.s390x-latest.xml
+++ b/tests/qemuxmlconfdata/s390x-ccw-default-models.s390x-latest.xml
@@ -37,7 +37,7 @@
</console>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0001'/>
</video>
<memballoon model='none'/>
diff --git a/tests/qemuxmlconfdata/s390x-ccw-graphics.s390x-latest.xml b/tests/qemuxmlconfdata/s390x-ccw-graphics.s390x-latest.xml
index c4c4c4cfdb..3865e00da7 100644
--- a/tests/qemuxmlconfdata/s390x-ccw-graphics.s390x-latest.xml
+++ b/tests/qemuxmlconfdata/s390x-ccw-graphics.s390x-latest.xml
@@ -55,7 +55,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0002'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/vhost-user-gpu-secondary.x86_64-latest.xml b/tests/qemuxmlconfdata/vhost-user-gpu-secondary.x86_64-latest.xml
index 1362326590..9acf8eff2e 100644
--- a/tests/qemuxmlconfdata/vhost-user-gpu-secondary.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/vhost-user-gpu-secondary.x86_64-latest.xml
@@ -42,12 +42,12 @@
<audio id='1' type='none'/>
<video>
<driver name='vhostuser'/>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='vhost-user-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
<driver name='vhostuser'/>
- <model type='virtio' heads='1'/>
+ <model type='virtio' heads='1' device='vhost-user-gpu'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/vhost-user-vga.x86_64-latest.xml b/tests/qemuxmlconfdata/vhost-user-vga.x86_64-latest.xml
index 9a8bb9f92a..51bf78f8f4 100644
--- a/tests/qemuxmlconfdata/vhost-user-vga.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/vhost-user-vga.x86_64-latest.xml
@@ -42,7 +42,7 @@
<audio id='1' type='none'/>
<video>
<driver name='vhostuser'/>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='vhost-user-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-blob-off.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-blob-off.x86_64-latest.xml
index d8de97a642..4a93f53cca 100644
--- a/tests/qemuxmlconfdata/video-virtio-blob-off.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-blob-off.x86_64-latest.xml
@@ -34,11 +34,11 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes' blob='off'/>
+ <model type='virtio' heads='1' primary='yes' blob='off' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
- <model type='virtio' heads='1' blob='off'/>
+ <model type='virtio' heads='1' blob='off' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-blob-on.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-blob-on.x86_64-latest.xml
index 40f40b4132..916a6bd37f 100644
--- a/tests/qemuxmlconfdata/video-virtio-blob-on.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-blob-on.x86_64-latest.xml
@@ -37,11 +37,11 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes' blob='on'/>
+ <model type='virtio' heads='1' primary='yes' blob='on' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
- <model type='virtio' heads='1' blob='on'/>
+ <model type='virtio' heads='1' blob='on' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-edid-none.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-edid-none.x86_64-latest.xml
index 175828f44a..4fd2d71ad2 100644
--- a/tests/qemuxmlconfdata/video-virtio-edid-none.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-edid-none.x86_64-latest.xml
@@ -31,7 +31,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-edid-off.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-edid-off.x86_64-latest.xml
index 35c01128b7..1e90b74ea2 100644
--- a/tests/qemuxmlconfdata/video-virtio-edid-off.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-edid-off.x86_64-latest.xml
@@ -31,7 +31,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes' edid='off'/>
+ <model type='virtio' heads='1' primary='yes' edid='off' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-edid-on.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-edid-on.x86_64-latest.xml
index b6feb171c2..9981cf0584 100644
--- a/tests/qemuxmlconfdata/video-virtio-edid-on.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-edid-on.x86_64-latest.xml
@@ -31,7 +31,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes' edid='on'/>
+ <model type='virtio' heads='1' primary='yes' edid='on' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-gpu-ccw-auto.s390x-latest.xml b/tests/qemuxmlconfdata/video-virtio-gpu-ccw-auto.s390x-latest.xml
index 87ee9eee54..5bf5369ee2 100644
--- a/tests/qemuxmlconfdata/video-virtio-gpu-ccw-auto.s390x-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-gpu-ccw-auto.s390x-latest.xml
@@ -29,7 +29,7 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0001'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-gpu-ccw.s390x-latest.xml b/tests/qemuxmlconfdata/video-virtio-gpu-ccw.s390x-latest.xml
index 9b6bf6c980..cb1dbf10af 100644
--- a/tests/qemuxmlconfdata/video-virtio-gpu-ccw.s390x-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-gpu-ccw.s390x-latest.xml
@@ -29,11 +29,11 @@
</graphics>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0002'/>
</video>
<video>
- <model type='virtio' heads='1'/>
+ <model type='virtio' heads='1' device='virtio-gpu'/>
<address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0003'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-gpu-device.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-gpu-device.x86_64-latest.xml
index 0c31cfb927..601932351b 100644
--- a/tests/qemuxmlconfdata/video-virtio-gpu-device.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-gpu-device.x86_64-latest.xml
@@ -34,7 +34,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-gpu-sdl-gl.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-gpu-sdl-gl.x86_64-latest.xml
index 401fdaf697..12687e63d6 100644
--- a/tests/qemuxmlconfdata/video-virtio-gpu-sdl-gl.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-gpu-sdl-gl.x86_64-latest.xml
@@ -36,7 +36,7 @@
<gl enable='yes'/>
</graphics>
<video>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/video-virtio-gpu-secondary.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-gpu-secondary.x86_64-latest.xml
index 7eae993cc0..776217c498 100644
--- a/tests/qemuxmlconfdata/video-virtio-gpu-secondary.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-gpu-secondary.x86_64-latest.xml
@@ -25,11 +25,11 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
- <model type='virtio' heads='1'/>
+ <model type='virtio' heads='1' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-gpu-spice-gl.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-gpu-spice-gl.x86_64-latest.xml
index 89da83de01..cc0426e2db 100644
--- a/tests/qemuxmlconfdata/video-virtio-gpu-spice-gl.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-gpu-spice-gl.x86_64-latest.xml
@@ -38,7 +38,7 @@
</graphics>
<audio id='1' type='spice'/>
<video>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/video-virtio-gpu-virgl.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-gpu-virgl.x86_64-latest.xml
index 48b1d833ff..fcbff0885e 100644
--- a/tests/qemuxmlconfdata/video-virtio-gpu-virgl.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-gpu-virgl.x86_64-latest.xml
@@ -34,7 +34,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml
index 991141c643..587a1c1d0e 100644
--- a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml
@@ -28,7 +28,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml
index 991141c643..2b53a42bc6 100644
--- a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml
@@ -28,13 +28,13 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
- <model type='virtio' heads='1'>
+ <model type='virtio' heads='1' device='virtio-gpu'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml
index 991141c643..19388b100c 100644
--- a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml
@@ -28,13 +28,13 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
- <model type='virtio' heads='1'>
+ <model type='virtio' heads='1' device='virtio-gpu-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml
index 991141c643..b84241fdac 100644
--- a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml
@@ -28,13 +28,13 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
- <model type='virtio' heads='1'>
+ <model type='virtio' heads='1' device='virtio-gpu-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml
index 991141c643..023db901dd 100644
--- a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml
@@ -28,13 +28,13 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
- <model type='virtio' heads='1'>
+ <model type='virtio' heads='1' device='virtio-gpu-gl'>
<acceleration accel3d='yes'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml b/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml
index 0c31cfb927..c04687983d 100644
--- a/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml
+++ b/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml
@@ -34,7 +34,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.xml
index 0c31cfb927..601932351b 100644
--- a/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.xml
@@ -34,7 +34,7 @@
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<video>
- <model type='virtio' heads='1' primary='yes'/>
+ <model type='virtio' heads='1' primary='yes' device='virtio-vga'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
diff --git a/tests/qemuxmlconfdata/virtio-options-video-ats.x86_64-latest.xml b/tests/qemuxmlconfdata/virtio-options-video-ats.x86_64-latest.xml
index 228ace3fa5..49e488c6b4 100644
--- a/tests/qemuxmlconfdata/virtio-options-video-ats.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/virtio-options-video-ats.x86_64-latest.xml
@@ -26,14 +26,14 @@
<audio id='1' type='none'/>
<video>
<driver ats='on' name='vhostuser'/>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='vhost-user-vga'>
<acceleration accel3d='yes' rendernode='/dev/dri/test'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
<driver ats='off' name='vhostuser'/>
- <model type='virtio' heads='1'>
+ <model type='virtio' heads='1' device='vhost-user-gpu'>
<acceleration accel3d='yes' rendernode='/dev/dri/test'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/virtio-options-video-iommu.x86_64-latest.xml b/tests/qemuxmlconfdata/virtio-options-video-iommu.x86_64-latest.xml
index 971cab51e7..a3fe36980f 100644
--- a/tests/qemuxmlconfdata/virtio-options-video-iommu.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/virtio-options-video-iommu.x86_64-latest.xml
@@ -26,14 +26,14 @@
<audio id='1' type='none'/>
<video>
<driver iommu='on' name='vhostuser'/>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='vhost-user-vga'>
<acceleration accel3d='yes' rendernode='/dev/dri/test'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
<driver iommu='off' name='vhostuser'/>
- <model type='virtio' heads='1'>
+ <model type='virtio' heads='1' device='vhost-user-gpu'>
<acceleration accel3d='yes' rendernode='/dev/dri/test'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/virtio-options-video-packed.x86_64-latest.xml b/tests/qemuxmlconfdata/virtio-options-video-packed.x86_64-latest.xml
index 26856e5e45..efdd865561 100644
--- a/tests/qemuxmlconfdata/virtio-options-video-packed.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/virtio-options-video-packed.x86_64-latest.xml
@@ -26,14 +26,14 @@
<audio id='1' type='none'/>
<video>
<driver packed='on' name='vhostuser'/>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='vhost-user-vga'>
<acceleration accel3d='yes' rendernode='/dev/dri/test'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<video>
<driver packed='off' name='vhostuser'/>
- <model type='virtio' heads='1'>
+ <model type='virtio' heads='1' device='vhost-user-gpu'>
<acceleration accel3d='yes' rendernode='/dev/dri/test'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
diff --git a/tests/qemuxmlconfdata/virtio-options.xml b/tests/qemuxmlconfdata/virtio-options.xml
index 05eaae35a9..89a424febf 100644
--- a/tests/qemuxmlconfdata/virtio-options.xml
+++ b/tests/qemuxmlconfdata/virtio-options.xml
@@ -82,7 +82,7 @@
<audio id='1' type='none'/>
<video>
<driver iommu='on' ats='on' packed='on' page_per_vq='on' name='vhostuser'/>
- <model type='virtio' heads='1' primary='yes'>
+ <model type='virtio' heads='1' primary='yes' device='vhost-user-vga'>
<acceleration accel3d='yes' rendernode='/dev/dri/test'/>
</model>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
--
2.55.0

View File

@ -0,0 +1,50 @@
From f77f7a3d566b6fd6bbc5d4b3d78fc290a2f84e54 Mon Sep 17 00:00:00 2001
Message-ID: <f77f7a3d566b6fd6bbc5d4b3d78fc290a2f84e54.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 11 Jun 2026 12:56:17 +0200
Subject: [PATCH] qemu: postparse: Process VM config with qemuCaps influenced
by <qemu:capabilities>
The user configuration of added/removed qemu capabilities via the qemu
namespace element was applied only right before generating a
commandline, but the post parse code code didn't see these.
Apply the capability modification prior to running post parse code so
that defaults are properly picked based on the configuration.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 011ae74640b230222ca521c6d253e2df59c8ab63)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_postparse.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c
index dc5ade829a..cd88cd1806 100644
--- a/src/qemu/qemu_postparse.c
+++ b/src/qemu/qemu_postparse.c
@@ -1924,9 +1924,16 @@ qemuDomainPostParseDataAlloc(const virDomainDef *def,
void **parseOpaque)
{
virQEMUDriver *driver = opaque;
+ g_autoptr(virQEMUCaps) qemuCapsLocal = NULL;
- if (!(*parseOpaque = virQEMUCapsCacheLookup(driver->qemuCapsCache,
- def->emulator)))
+ *parseOpaque = NULL;
+
+ if (!(qemuCapsLocal = virQEMUCapsCacheLookup(driver->qemuCapsCache,
+ def->emulator)))
+ return 1;
+
+ if (qemuDomainUpdateCustomCapabilities(def, qemuCapsLocal,
+ (virQEMUCaps **) parseOpaque) < 0)
return 1;
return 0;
--
2.55.0

View File

@ -0,0 +1,81 @@
From 2b3ed2f5fbb0255561db89a841eb2673af0095a5 Mon Sep 17 00:00:00 2001
Message-ID: <2b3ed2f5fbb0255561db89a841eb2673af0095a5.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 11 Jun 2026 12:52:16 +0200
Subject: [PATCH] qemu: validate: Validate VM config with qemuCaps influenced
by <qemu:capabilities>
The user configuration of added/removed qemu capabilities via the qemu
namespace element was applied only right before generating a
commandline, but the validation code didn't see these.
Modify the validation entry points so that they apply this optionally.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 5319dd6f0d4ae93ef14ccb25b43346b30490db3a)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_validate.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 63c5f8e037..8f3e6dd134 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1272,18 +1272,21 @@ qemuValidateDomainDef(const virDomainDef *def,
void *parseOpaque)
{
virQEMUDriver *driver = opaque;
+ virQEMUCaps *qemuCapsIn = parseOpaque;
g_autoptr(virQEMUCaps) qemuCapsLocal = NULL;
- virQEMUCaps *qemuCaps = parseOpaque;
+ g_autoptr(virQEMUCaps) qemuCaps = NULL;
size_t i;
- if (!qemuCaps) {
+ if (!qemuCapsIn) {
if (!(qemuCapsLocal = virQEMUCapsCacheLookup(driver->qemuCapsCache,
def->emulator)))
return -1;
-
- qemuCaps = qemuCapsLocal;
+ qemuCapsIn = qemuCapsLocal;
}
+ if (qemuDomainUpdateCustomCapabilities(def, qemuCapsIn, &qemuCaps) < 0)
+ return -1;
+
if (def->os.type != VIR_DOMAIN_OSTYPE_HVM) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Emulator '%1$s' does not support os type '%2$s'"),
@@ -5958,17 +5961,20 @@ qemuValidateDomainDeviceDef(const virDomainDeviceDef *dev,
void *parseOpaque)
{
virQEMUDriver *driver = opaque;
+ virQEMUCaps *qemuCapsIn = parseOpaque;
g_autoptr(virQEMUCaps) qemuCapsLocal = NULL;
- virQEMUCaps *qemuCaps = parseOpaque;
+ g_autoptr(virQEMUCaps) qemuCaps = NULL;
- if (!qemuCaps) {
+ if (!qemuCapsIn) {
if (!(qemuCapsLocal = virQEMUCapsCacheLookup(driver->qemuCapsCache,
def->emulator)))
return -1;
-
- qemuCaps = qemuCapsLocal;
+ qemuCapsIn = qemuCapsLocal;
}
+ if (qemuDomainUpdateCustomCapabilities(def, qemuCapsIn, &qemuCaps) < 0)
+ return -1;
+
if (qemuValidateDomainDeviceInfo(dev, def, qemuCaps) < 0)
return -1;
--
2.55.0

View File

@ -0,0 +1,212 @@
From a3f72e88927f270bc17a7cb47f7abec988b208c9 Mon Sep 17 00:00:00 2001
Message-ID: <a3f72e88927f270bc17a7cb47f7abec988b208c9.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 8 Jun 2026 15:11:45 +0200
Subject: [PATCH] qemuDeviceVideoGetModel: Directly return picked model
There's no point in falling through to the check reporting invalid
type since if the code picks a model that one will be valid.
Reorganize the code so that we can return final decision right away.
This means that the two flags 'virtio' and 'virtioBusSuffix' need to be
set prior to the return.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit d3bd2142095e8203d9cc49448e7761553b0b2600)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_command.c | 156 +++++++++++++++++++---------------------
1 file changed, 75 insertions(+), 81 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index db72407ecc..619ad7a835 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -719,7 +719,6 @@ qemuDeviceVideoGetModel(virQEMUCaps *qemuCaps,
bool *virtio,
bool *virtioBusSuffix)
{
- const char *model = NULL;
bool primaryVga = false;
virTristateBool accel3d = VIR_TRISTATE_BOOL_ABSENT;
@@ -732,98 +731,93 @@ qemuDeviceVideoGetModel(virQEMUCaps *qemuCaps,
if (video->primary && qemuDomainSupportsVideoVga(video, qemuCaps))
primaryVga = true;
+ if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
+ if (primaryVga)
+ return "vhost-user-vga";
+
+ *virtio = true;
+ *virtioBusSuffix = true;
+ return "vhost-user-gpu";
+ }
+
/* We try to chose the best model for primary video device by preferring
* model with VGA compatibility mode. For some video devices on some
* architectures there might not be such model so fallback to one
* without VGA compatibility mode. */
- if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
- if (primaryVga) {
- model = "vhost-user-vga";
- } else {
- model = "vhost-user-gpu";
+ if (primaryVga) {
+ switch ((virDomainVideoType) video->type) {
+ case VIR_DOMAIN_VIDEO_TYPE_VGA:
+ return "VGA";
+
+ case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
+ return "cirrus-vga";
+
+ case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
+ return "vmware-svga";
+
+ case VIR_DOMAIN_VIDEO_TYPE_QXL:
+ return "qxl-vga";
+
+ case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
*virtio = true;
- *virtioBusSuffix = true;
+ *virtioBusSuffix = false;
+
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_VGA_GL) &&
+ accel3d == VIR_TRISTATE_BOOL_YES)
+ return "virtio-vga-gl";
+
+ return "virtio-vga";
+
+ case VIR_DOMAIN_VIDEO_TYPE_BOCHS:
+ return "bochs-display";
+
+ case VIR_DOMAIN_VIDEO_TYPE_RAMFB:
+ return "ramfb";
+
+ case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
+ case VIR_DOMAIN_VIDEO_TYPE_XEN:
+ case VIR_DOMAIN_VIDEO_TYPE_VBOX:
+ case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
+ case VIR_DOMAIN_VIDEO_TYPE_GOP:
+ case VIR_DOMAIN_VIDEO_TYPE_NONE:
+ case VIR_DOMAIN_VIDEO_TYPE_LAST:
+ break;
}
} else {
- if (primaryVga) {
- switch ((virDomainVideoType) video->type) {
- case VIR_DOMAIN_VIDEO_TYPE_VGA:
- model = "VGA";
- break;
- case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
- model = "cirrus-vga";
- break;
- case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
- model = "vmware-svga";
- break;
- case VIR_DOMAIN_VIDEO_TYPE_QXL:
- model = "qxl-vga";
- break;
- case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_VGA_GL) &&
- accel3d == VIR_TRISTATE_BOOL_YES)
- model = "virtio-vga-gl";
- else
- model = "virtio-vga";
+ switch ((virDomainVideoType) video->type) {
+ case VIR_DOMAIN_VIDEO_TYPE_QXL:
+ return "qxl";
- *virtio = true;
- *virtioBusSuffix = false;
- break;
- case VIR_DOMAIN_VIDEO_TYPE_BOCHS:
- model = "bochs-display";
- break;
- case VIR_DOMAIN_VIDEO_TYPE_RAMFB:
- model = "ramfb";
- break;
- case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
- case VIR_DOMAIN_VIDEO_TYPE_XEN:
- case VIR_DOMAIN_VIDEO_TYPE_VBOX:
- case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
- case VIR_DOMAIN_VIDEO_TYPE_GOP:
- case VIR_DOMAIN_VIDEO_TYPE_NONE:
- case VIR_DOMAIN_VIDEO_TYPE_LAST:
- break;
- }
- } else {
- switch ((virDomainVideoType) video->type) {
- case VIR_DOMAIN_VIDEO_TYPE_QXL:
- model = "qxl";
- break;
- case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_GL_PCI) &&
- accel3d == VIR_TRISTATE_BOOL_YES)
- model = "virtio-gpu-gl";
- else
- model = "virtio-gpu";
+ case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
+ *virtio = true;
+ *virtioBusSuffix = true;
- *virtio = true;
- *virtioBusSuffix = true;
- break;
- case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
- case VIR_DOMAIN_VIDEO_TYPE_VGA:
- case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
- case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
- case VIR_DOMAIN_VIDEO_TYPE_XEN:
- case VIR_DOMAIN_VIDEO_TYPE_VBOX:
- case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
- case VIR_DOMAIN_VIDEO_TYPE_GOP:
- case VIR_DOMAIN_VIDEO_TYPE_NONE:
- case VIR_DOMAIN_VIDEO_TYPE_BOCHS:
- case VIR_DOMAIN_VIDEO_TYPE_RAMFB:
- case VIR_DOMAIN_VIDEO_TYPE_LAST:
- break;
- }
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_GL_PCI) &&
+ accel3d == VIR_TRISTATE_BOOL_YES)
+ return "virtio-gpu-gl";
+
+ return "virtio-gpu";
+
+ case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
+ case VIR_DOMAIN_VIDEO_TYPE_VGA:
+ case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
+ case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
+ case VIR_DOMAIN_VIDEO_TYPE_XEN:
+ case VIR_DOMAIN_VIDEO_TYPE_VBOX:
+ case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
+ case VIR_DOMAIN_VIDEO_TYPE_GOP:
+ case VIR_DOMAIN_VIDEO_TYPE_NONE:
+ case VIR_DOMAIN_VIDEO_TYPE_BOCHS:
+ case VIR_DOMAIN_VIDEO_TYPE_RAMFB:
+ case VIR_DOMAIN_VIDEO_TYPE_LAST:
+ break;
}
}
- if (!model || STREQ(model, "")) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("invalid model for video type '%1$s'"),
- virDomainVideoTypeToString(video->type));
- return NULL;
- }
-
- return model;
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("invalid model for video type '%1$s'"),
+ virDomainVideoTypeToString(video->type));
+ return NULL;
}
--
2.55.0

View File

@ -0,0 +1,210 @@
From b59a04973707e5499a56729ecf1887d4a048031f Mon Sep 17 00:00:00 2001
Message-ID: <b59a04973707e5499a56729ecf1887d4a048031f.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 9 Jun 2026 22:02:21 +0200
Subject: [PATCH] qemuDeviceVideoGetModel: Remove logic for selecting 'virtio'
devices
The virtio video device frontend type is either selected by the
post-parse code based on capabilities or provided by the user/existing
XML explicitly. No need to try to come up with a model when generating
commandline based on broken logic.
The difference in test output shows:
- honours user's config in case of the new 'device' attribute
- shows how incorrect fallback would be used for 'virtio-vga-gl'
(picked virtio-vga (non-gl) instead of 'virtio-gpu-gl')
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 659e104affa113b9a546ca1f6948bc9e95ada8d2)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_command.c | 75 +++++++------------
...io-vga-device-downgrade.x86_64-latest.args | 2 +-
...APS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args | 2 +-
3 files changed, 30 insertions(+), 49 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 619ad7a835..2f19a6c1ff 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -703,9 +703,25 @@ qemuBuildDeviceAddressProps(virJSONValue *props,
}
+struct qemuDeviceVideoModelVirtioOpts {
+ bool virtio;
+ bool virtioBusSuffix;
+};
+
+struct qemuDeviceVideoModelVirtioOpts qemuDeviceVideoGetModelVirtioOptsTable[] = {
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_DEFAULT] = { .virtio = false, .virtioBusSuffix = false },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA] = { .virtio = true, .virtioBusSuffix = false },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU] = { .virtio = true, .virtioBusSuffix = true },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA_GL] = { .virtio = true, .virtioBusSuffix = false },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU_GL] = { .virtio = true, .virtioBusSuffix = true },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VHOST_USER_VGA] = { .virtio = false, .virtioBusSuffix = false },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VHOST_USER_GPU] = { .virtio = true, .virtioBusSuffix = true },
+};
+G_STATIC_ASSERT(G_N_ELEMENTS(qemuDeviceVideoGetModelVirtioOptsTable) == VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_LAST);
+
+
/**
* qemuDeviceVideoGetModel:
- * @qemuCaps: qemu capabilities
* @video: video device definition
* @virtio: the returned video device is a 'virtio' device
* @virtioBusSuffix: the returned device needs to get the bus-suffix
@@ -714,37 +730,23 @@ qemuBuildDeviceAddressProps(virJSONValue *props,
* @virtioBusSuffix are filled with the corresponding flags.
*/
static const char *
-qemuDeviceVideoGetModel(virQEMUCaps *qemuCaps,
- const virDomainVideoDef *video,
+qemuDeviceVideoGetModel(const virDomainVideoDef *video,
bool *virtio,
bool *virtioBusSuffix)
{
- bool primaryVga = false;
- virTristateBool accel3d = VIR_TRISTATE_BOOL_ABSENT;
-
*virtio = false;
*virtioBusSuffix = false;
- if (video->accel)
- accel3d = video->accel->accel3d;
+ if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
+ struct qemuDeviceVideoModelVirtioOpts *opts = &qemuDeviceVideoGetModelVirtioOptsTable[video->virtiodevice];
- if (video->primary && qemuDomainSupportsVideoVga(video, qemuCaps))
- primaryVga = true;
+ *virtio = opts->virtio;
+ *virtioBusSuffix = opts->virtioBusSuffix;
- if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
- if (primaryVga)
- return "vhost-user-vga";
-
- *virtio = true;
- *virtioBusSuffix = true;
- return "vhost-user-gpu";
+ return virDomainVideoVirtioDeviceTypeToString(video->virtiodevice);
}
- /* We try to chose the best model for primary video device by preferring
- * model with VGA compatibility mode. For some video devices on some
- * architectures there might not be such model so fallback to one
- * without VGA compatibility mode. */
- if (primaryVga) {
+ if (video->primary) {
switch ((virDomainVideoType) video->type) {
case VIR_DOMAIN_VIDEO_TYPE_VGA:
return "VGA";
@@ -758,22 +760,12 @@ qemuDeviceVideoGetModel(virQEMUCaps *qemuCaps,
case VIR_DOMAIN_VIDEO_TYPE_QXL:
return "qxl-vga";
- case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
- *virtio = true;
- *virtioBusSuffix = false;
-
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_VGA_GL) &&
- accel3d == VIR_TRISTATE_BOOL_YES)
- return "virtio-vga-gl";
-
- return "virtio-vga";
-
case VIR_DOMAIN_VIDEO_TYPE_BOCHS:
return "bochs-display";
case VIR_DOMAIN_VIDEO_TYPE_RAMFB:
return "ramfb";
-
+ case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
case VIR_DOMAIN_VIDEO_TYPE_XEN:
case VIR_DOMAIN_VIDEO_TYPE_VBOX:
@@ -789,15 +781,6 @@ qemuDeviceVideoGetModel(virQEMUCaps *qemuCaps,
return "qxl";
case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
- *virtio = true;
- *virtioBusSuffix = true;
-
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_GL_PCI) &&
- accel3d == VIR_TRISTATE_BOOL_YES)
- return "virtio-gpu-gl";
-
- return "virtio-gpu";
-
case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
case VIR_DOMAIN_VIDEO_TYPE_VGA:
case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
@@ -823,7 +806,6 @@ qemuDeviceVideoGetModel(virQEMUCaps *qemuCaps,
static void
qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device,
- virQEMUCaps *qemuCaps,
const char **baseName,
virDomainVirtioOptions **virtioOptions,
bool *has_tmodel,
@@ -948,8 +930,7 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device,
bool virtio;
bool virtioBusSuffix;
- if (!(*baseName = qemuDeviceVideoGetModel(qemuCaps,
- device->data.video,
+ if (!(*baseName = qemuDeviceVideoGetModel(device->data.video,
&virtio,
&virtioBusSuffix)))
return;
@@ -1028,7 +1009,7 @@ qemuBuildVirtioDevGetConfig(const virDomainDeviceDef *device,
bool has_ntmodel = false;
bool useBusSuffix = true;
- qemuBuildVirtioDevGetConfigDev(device, qemuCaps, &baseName,
+ qemuBuildVirtioDevGetConfigDev(device, &baseName,
virtioOptions, &has_tmodel,
&has_ntmodel, &useBusSuffix);
@@ -4606,7 +4587,7 @@ qemuBuildDeviceVideoCmd(virCommand *cmd,
g_autoptr(virJSONValue) props = NULL;
unsigned int max_outputs = 0;
- if (!(model = qemuDeviceVideoGetModel(qemuCaps, video, &virtio, &virtioBusSuffix)))
+ if (!(model = qemuDeviceVideoGetModel(video, &virtio, &virtioBusSuffix)))
return -1;
if (virtio) {
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.args b/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.args
index fec2b04ca9..5782505b61 100644
--- a/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.args
@@ -31,7 +31,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-blockdev '{"node-name":"libvirt-1-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":"libvirt-1-storage"}' \
-device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-format","id":"ide0-0-0","bootindex":1,"write-cache":"on"}' \
-audiodev '{"id":"audio1","driver":"none"}' \
--device '{"driver":"virtio-vga","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
+-device '{"driver":"virtio-gpu-pci","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args
index d649dc06f8..315c49f953 100644
--- a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args
@@ -28,7 +28,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-boot strict=on \
-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
-audiodev '{"id":"audio1","driver":"none"}' \
--device '{"driver":"virtio-vga","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
+-device '{"driver":"virtio-gpu-gl-pci","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
-device '{"driver":"virtio-gpu-gl-pci","id":"video1","max_outputs":1,"bus":"pci.0","addr":"0x4"}' \
-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
--
2.55.0

View File

@ -0,0 +1,140 @@
From 4c33439fbcd0eb9ea09ab9a8a6aa5b8780ac9175 Mon Sep 17 00:00:00 2001
Message-ID: <4c33439fbcd0eb9ea09ab9a8a6aa5b8780ac9175.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 10 Jun 2026 12:38:00 +0200
Subject: [PATCH] qemuDeviceVideoGetModel: Simplify by relying on checks from
'qemuValidateDomainDeviceDefVideo'
'qemuValidateDomainDeviceDefVideo' ensures that only the correct video
device models are selected as well as that only QXL and VIRTIO video
devices can be selected as secondary.
Remove unnecessary checks and simplify the code.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 736c0f455a0edf1ed6961558f6ece877f5f7dbc6)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_command.c | 94 ++++++++++++++++++-----------------------
1 file changed, 40 insertions(+), 54 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2f19a6c1ff..963dc2afa3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -737,7 +737,32 @@ qemuDeviceVideoGetModel(const virDomainVideoDef *video,
*virtio = false;
*virtioBusSuffix = false;
- if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
+ /* 'qemuValidateDomainDeviceDefVideo' ensures that only supported models
+ * are used as well as that only 'QXL' and 'virtio' graphics can be
+ * secondary */
+ switch ((virDomainVideoType) video->type) {
+ case VIR_DOMAIN_VIDEO_TYPE_VGA:
+ return "VGA";
+
+ case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
+ return "cirrus-vga";
+
+ case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
+ return "vmware-svga";
+
+ case VIR_DOMAIN_VIDEO_TYPE_QXL:
+ if (video->primary)
+ return "qxl-vga";
+
+ return "qxl";
+
+ case VIR_DOMAIN_VIDEO_TYPE_BOCHS:
+ return "bochs-display";
+
+ case VIR_DOMAIN_VIDEO_TYPE_RAMFB:
+ return "ramfb";
+
+ case VIR_DOMAIN_VIDEO_TYPE_VIRTIO: {
struct qemuDeviceVideoModelVirtioOpts *opts = &qemuDeviceVideoGetModelVirtioOptsTable[video->virtiodevice];
*virtio = opts->virtio;
@@ -746,61 +771,22 @@ qemuDeviceVideoGetModel(const virDomainVideoDef *video,
return virDomainVideoVirtioDeviceTypeToString(video->virtiodevice);
}
- if (video->primary) {
- switch ((virDomainVideoType) video->type) {
- case VIR_DOMAIN_VIDEO_TYPE_VGA:
- return "VGA";
+ case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
+ case VIR_DOMAIN_VIDEO_TYPE_XEN:
+ case VIR_DOMAIN_VIDEO_TYPE_VBOX:
+ case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
+ case VIR_DOMAIN_VIDEO_TYPE_GOP:
+ case VIR_DOMAIN_VIDEO_TYPE_NONE:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("invalid model for video type '%1$s'"),
+ virDomainVideoTypeToString(video->type));
+ return NULL;
- case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
- return "cirrus-vga";
-
- case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
- return "vmware-svga";
-
- case VIR_DOMAIN_VIDEO_TYPE_QXL:
- return "qxl-vga";
-
- case VIR_DOMAIN_VIDEO_TYPE_BOCHS:
- return "bochs-display";
-
- case VIR_DOMAIN_VIDEO_TYPE_RAMFB:
- return "ramfb";
- case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
- case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
- case VIR_DOMAIN_VIDEO_TYPE_XEN:
- case VIR_DOMAIN_VIDEO_TYPE_VBOX:
- case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
- case VIR_DOMAIN_VIDEO_TYPE_GOP:
- case VIR_DOMAIN_VIDEO_TYPE_NONE:
- case VIR_DOMAIN_VIDEO_TYPE_LAST:
- break;
- }
- } else {
- switch ((virDomainVideoType) video->type) {
- case VIR_DOMAIN_VIDEO_TYPE_QXL:
- return "qxl";
-
- case VIR_DOMAIN_VIDEO_TYPE_VIRTIO:
- case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
- case VIR_DOMAIN_VIDEO_TYPE_VGA:
- case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
- case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
- case VIR_DOMAIN_VIDEO_TYPE_XEN:
- case VIR_DOMAIN_VIDEO_TYPE_VBOX:
- case VIR_DOMAIN_VIDEO_TYPE_PARALLELS:
- case VIR_DOMAIN_VIDEO_TYPE_GOP:
- case VIR_DOMAIN_VIDEO_TYPE_NONE:
- case VIR_DOMAIN_VIDEO_TYPE_BOCHS:
- case VIR_DOMAIN_VIDEO_TYPE_RAMFB:
- case VIR_DOMAIN_VIDEO_TYPE_LAST:
- break;
- }
+ case VIR_DOMAIN_VIDEO_TYPE_LAST:
+ default:
+ virReportEnumRangeError(virDomainVideoType, video->type);
+ return NULL;
}
-
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("invalid model for video type '%1$s'"),
- virDomainVideoTypeToString(video->type));
- return NULL;
}
--
2.55.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

View File

@ -0,0 +1,272 @@
From d02940fb7bdfbabfc8f34349ff01b64960965d66 Mon Sep 17 00:00:00 2001
Message-ID: <d02940fb7bdfbabfc8f34349ff01b64960965d66.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 10 Jun 2026 14:45:24 +0200
Subject: [PATCH] qemuValidateDomainDeviceDefVideo: Fix checks of virtio video
devices
The currently existing checks are broken:
- only QEMU_CAPS_DEVICE_VHOST_USER_GPU is checked for vhostuser
backends (vhost-user-vga is actually separately packaged)
- the check for the 3d accelerated (-gl) versions checks only if one
of them exists (the commandline formatter picks a non-gl afterwards)
- 'virtio-vga'/'virtio-gpu' is not checked at all
The code also doesn't yet check if, when the user passes the new
'device' property manually the config actually makes sense.
To fix all of the above introduce a table of supported frontend devices
as well as properties that need to be checked for them.
This requires fixing a recently-introduced test case which shows a
nonsensical situation.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 177ff813479872d4d7e3c270acf1e045f25b1e21)
https://redhat.atlassian.net/browse/RHEL-186019
Conflicts:
tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args
Context; conflict with previous conflict resolution
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_validate.c | 88 +++++++++++++------
...VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args | 35 --------
..._VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.err | 1 +
..._VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml | 46 ----------
tests/qemuxmlconftest.c | 1 +
5 files changed, 65 insertions(+), 106 deletions(-)
delete mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.err
delete mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 8f3e6dd134..3e84ef7139 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -2784,6 +2784,26 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev,
}
+struct qemuValidateDeviceVideoVirtioData {
+ virQEMUCapsFlags cap; /* capability for the device */
+ bool primary; /* this device can be only the primary device */
+ bool vhostuser; /* uses the vhostuser protocol */
+ bool gl; /* supports 3d accel */
+};
+
+
+struct qemuValidateDeviceVideoVirtioData qemuValidateDeviceVideoVirtioTable[] = {
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_DEFAULT] = { .cap = QEMU_CAPS_LAST },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA] = { .cap = QEMU_CAPS_DEVICE_VIRTIO_VGA, .primary = true },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU] = { .cap = QEMU_CAPS_DEVICE_VIRTIO_GPU },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VGA_GL] = { .cap = QEMU_CAPS_VIRTIO_VGA_GL, .gl = true, .primary = true },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_GPU_GL] = { .cap = QEMU_CAPS_VIRTIO_GPU_GL_PCI, .gl = true },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VHOST_USER_VGA] = { .cap = QEMU_CAPS_DEVICE_VHOST_USER_VGA, .vhostuser = true, .primary = true },
+ [VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_VHOST_USER_GPU] = { .cap = QEMU_CAPS_DEVICE_VHOST_USER_GPU, .vhostuser = true },
+};
+G_STATIC_ASSERT(G_N_ELEMENTS(qemuValidateDeviceVideoVirtioTable) == VIR_DOMAIN_VIDEO_VIRTIO_DEVICE_LAST);
+
+
static int
qemuValidateDomainDeviceDefVideo(const virDomainVideoDef *video,
const virDomainDef *def,
@@ -2804,6 +2824,49 @@ qemuValidateDomainDeviceDefVideo(const virDomainVideoDef *video,
return -1;
}
+ if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
+ struct qemuValidateDeviceVideoVirtioData *data = &qemuValidateDeviceVideoVirtioTable[video->virtiodevice];
+
+ if (data->cap == QEMU_CAPS_LAST) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("this QEMU binary lacks any suitable 'virtio' video device frontend"));
+ return -1;
+ }
+
+ if (!virQEMUCapsGet(qemuCaps, data->cap)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("this QEMU doesn't support the '%1$s' virtio video device frontend"),
+ virDomainVideoVirtioDeviceTypeToString(video->virtiodevice));
+ return -1;
+ }
+
+ if (data->primary && !video->primary) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("the '%1$s' virtio video device frontend can be only used as primary video device"),
+ virDomainVideoVirtioDeviceTypeToString(video->virtiodevice));
+ return -1;
+ }
+
+ /* this check deliberately allows downgrade to the non-gl frontend as
+ * that was possible due to a bug in capability checking and the
+ * commandline formatter. More details are explained in
+ * 'qemuDomainDeviceVideoDefPostParse' which selects the frontend */
+ if (data->gl &&
+ !(video->accel && video->accel->accel3d == VIR_TRISTATE_BOOL_YES)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("the '%1$s' virtio video device frontend can be only with enabled 3d acceleration"),
+ virDomainVideoVirtioDeviceTypeToString(video->virtiodevice));
+ return -1;
+ }
+
+ if (data->vhostuser != (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("the '%1$s' virtio video device doesn't match the selected vhostuser backend"),
+ virDomainVideoVirtioDeviceTypeToString(video->virtiodevice));
+ return -1;
+ }
+ }
+
if (video->type != VIR_DOMAIN_VIDEO_TYPE_QXL &&
video->type != VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
if (!video->primary) {
@@ -2875,31 +2938,6 @@ qemuValidateDomainDeviceDefVideo(const virDomainVideoDef *video,
}
}
- if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
- if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO &&
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VHOST_USER_GPU)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("this QEMU does not support 'vhost-user' video device"));
- return -1;
- }
- } else if (video->accel) {
- if (video->accel->accel3d == VIR_TRISTATE_BOOL_YES) {
- if (video->type != VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("3d acceleration is supported only with 'virtio' video device"));
- return -1;
- }
-
- if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_VIRGL) ||
- virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_GL_PCI) ||
- virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_VGA_GL))) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("3d acceleration is not supported by this QEMU binary"));
- return -1;
- }
- }
- }
-
if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
if (video->blob != VIR_TRISTATE_SWITCH_ABSENT) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_BLOB)) {
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args
deleted file mode 100644
index 297b919b5b..0000000000
--- a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args
+++ /dev/null
@@ -1,35 +0,0 @@
-LC_ALL=C \
-PATH=/bin \
-HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
-USER=test \
-LOGNAME=test \
-XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
-XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
-XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-/usr/bin/qemu-system-x86_64 \
--name guest=QEMUGuest1,debug-threads=on \
--S \
--object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
--machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
--accel tcg \
--cpu qemu64 \
--m size=1048576k \
--object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
--overcommit mem-lock=off \
--smp 1,sockets=1,cores=1,threads=1 \
--uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
--display none \
--no-user-config \
--nodefaults \
--chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
--mon chardev=charmonitor,id=monitor,mode=control \
--rtc base=utc \
--no-shutdown \
--boot strict=on \
--device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
--audiodev '{"id":"audio1","driver":"none"}' \
--device '{"driver":"virtio-vga-gl","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
--device '{"driver":"virtio-gpu-pci","id":"video1","max_outputs":1,"bus":"pci.0","addr":"0x4"}' \
--device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \
--sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
--msg timestamp=on
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.err b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.err
new file mode 100644
index 0000000000..b94bf12d69
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.err
@@ -0,0 +1 @@
+unsupported configuration: this QEMU binary lacks any suitable 'virtio' video device frontend
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml
deleted file mode 100644
index 587a1c1d0e..0000000000
--- a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<domain type='qemu'>
- <name>QEMUGuest1</name>
- <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
- <memory unit='KiB'>1048576</memory>
- <currentMemory unit='KiB'>1048576</currentMemory>
- <vcpu placement='static'>1</vcpu>
- <os>
- <type arch='x86_64' machine='pc'>hvm</type>
- <boot dev='hd'/>
- </os>
- <cpu mode='custom' match='exact' check='none'>
- <model fallback='forbid'>qemu64</model>
- </cpu>
- <clock offset='utc'/>
- <on_poweroff>destroy</on_poweroff>
- <on_reboot>restart</on_reboot>
- <on_crash>destroy</on_crash>
- <devices>
- <emulator>/usr/bin/qemu-system-x86_64</emulator>
- <controller type='ide' index='0'>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
- </controller>
- <controller type='usb' index='0' model='piix3-uhci'>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
- </controller>
- <controller type='pci' index='0' model='pci-root'/>
- <input type='mouse' bus='ps2'/>
- <input type='keyboard' bus='ps2'/>
- <audio id='1' type='none'/>
- <video>
- <model type='virtio' heads='1' primary='yes' device='virtio-vga-gl'>
- <acceleration accel3d='yes'/>
- </model>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
- </video>
- <video>
- <model type='virtio' heads='1'>
- <acceleration accel3d='yes'/>
- </model>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
- </video>
- <memballoon model='virtio'>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
- </memballoon>
- </devices>
-</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 85cf9960aa..45e9a37794 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2800,6 +2800,7 @@ mymain(void)
ARG_CAPS_VER, "latest",
ARG_QEMU_CAPS_DEL, QEMU_CAPS_VIRTIO_GPU_GL_PCI, QEMU_CAPS_LAST,
ARG_PARSEFLAGS, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
+ ARG_FLAGS, FLAG_EXPECT_PARSE_ERROR,
ARG_END);
DO_TEST_CAPS_LATEST("video-virtio-edid-none");
DO_TEST_CAPS_LATEST("video-virtio-edid-off");
--
2.55.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,84 @@
From c33268a59a91cb38dd22e94bd3a735fc7d3859d9 Mon Sep 17 00:00:00 2001
Message-ID: <c33268a59a91cb38dd22e94bd3a735fc7d3859d9.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 10 Jun 2026 16:57:06 +0200
Subject: [PATCH] qemuxmlconfdata: un-symlink 'video-virtio-vga-gpu-gl' output
Upcoming patches will add additional testing for various virtio-*-gl
devices, including filling of the default model. The output file needs
to not influnece the input for this test to work properly.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit c490360c2590983707d3cf3d2bb011830b014ff7)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
.../video-virtio-vga-gpu-gl.x86_64-latest.xml | 47 ++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
mode change 120000 => 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml
deleted file mode 120000
index 34e32ab8ba..0000000000
--- a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml
+++ /dev/null
@@ -1 +0,0 @@
-video-virtio-vga-gpu-gl.xml
\ No newline at end of file
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml
new file mode 100644
index 0000000000..991141c643
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.xml
@@ -0,0 +1,46 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='virtio' heads='1' primary='yes'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </video>
+ <video>
+ <model type='virtio' heads='1'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </video>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
--
2.55.0

View File

@ -0,0 +1,255 @@
From 3480a65aecf0c5e4f1988a02b007c2d86fc1409c Mon Sep 17 00:00:00 2001
Message-ID: <3480a65aecf0c5e4f1988a02b007c2d86fc1409c.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 10 Jun 2026 16:31:44 +0200
Subject: [PATCH] qemuxmlconftest: Add invocation of 'video-virtio-vga-gpu-gl'
with missing caps and VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
Similarly to previous patch add testing of 'virtio-gpu-gl' or
'virtio-vga-gl' with missing the respective capabilities, but this time
allowing VIR_DOMAIN_DEF_PARSE_ABI_UPDATE.
This will later on show that in case when the fallback can't be honoured
the code will not pick a device that doesn't support acceleration (the
non-gl variant).
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit c10a7f2bafe15e3eb8f14407b23d8683a4a11446)
https://redhat.atlassian.net/browse/RHEL-186019
Conflicts:
- tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args
- tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args
Context; patch tweaking monitor FD passing in tests not backported
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
...VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args | 35 ++++++++++++++
..._VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml | 46 +++++++++++++++++++
...APS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args | 35 ++++++++++++++
...CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml | 46 +++++++++++++++++++
tests/qemuxmlconftest.c | 12 +++++
5 files changed, 174 insertions(+)
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args
new file mode 100644
index 0000000000..297b919b5b
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.args
@@ -0,0 +1,35 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"virtio-vga-gl","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
+-device '{"driver":"virtio-gpu-pci","id":"video1","max_outputs":1,"bus":"pci.0","addr":"0x4"}' \
+-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml
new file mode 100644
index 0000000000..991141c643
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE.xml
@@ -0,0 +1,46 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='virtio' heads='1' primary='yes'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </video>
+ <video>
+ <model type='virtio' heads='1'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </video>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args
new file mode 100644
index 0000000000..d649dc06f8
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.args
@@ -0,0 +1,35 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"virtio-vga","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
+-device '{"driver":"virtio-gpu-gl-pci","id":"video1","max_outputs":1,"bus":"pci.0","addr":"0x4"}' \
+-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml
new file mode 100644
index 0000000000..991141c643
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE.xml
@@ -0,0 +1,46 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='virtio' heads='1' primary='yes'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </video>
+ <video>
+ <model type='virtio' heads='1'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </video>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 8424bdf709..44df46f35c 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2783,11 +2783,23 @@ mymain(void)
ARG_CAPS_VER, "latest",
ARG_QEMU_CAPS_DEL, QEMU_CAPS_VIRTIO_VGA_GL, QEMU_CAPS_LAST,
ARG_END);
+ DO_TEST_FULL("video-virtio-vga-gpu-gl", ".x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled-ABI_UPDATE",
+ ARG_CAPS_ARCH, "x86_64",
+ ARG_CAPS_VER, "latest",
+ ARG_QEMU_CAPS_DEL, QEMU_CAPS_VIRTIO_VGA_GL, QEMU_CAPS_LAST,
+ ARG_PARSEFLAGS, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
+ ARG_END);
DO_TEST_FULL("video-virtio-vga-gpu-gl", ".x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled",
ARG_CAPS_ARCH, "x86_64",
ARG_CAPS_VER, "latest",
ARG_QEMU_CAPS_DEL, QEMU_CAPS_VIRTIO_GPU_GL_PCI, QEMU_CAPS_LAST,
ARG_END);
+ DO_TEST_FULL("video-virtio-vga-gpu-gl", ".x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled-ABI_UPDATE",
+ ARG_CAPS_ARCH, "x86_64",
+ ARG_CAPS_VER, "latest",
+ ARG_QEMU_CAPS_DEL, QEMU_CAPS_VIRTIO_GPU_GL_PCI, QEMU_CAPS_LAST,
+ ARG_PARSEFLAGS, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
+ ARG_END);
DO_TEST_CAPS_LATEST("video-virtio-edid-none");
DO_TEST_CAPS_LATEST("video-virtio-edid-off");
DO_TEST_CAPS_LATEST("video-virtio-edid-on");
--
2.55.0

View File

@ -0,0 +1,177 @@
From cedf4dbcdd3a0c64d4e74a98dd8caacaefced9b6 Mon Sep 17 00:00:00 2001
Message-ID: <cedf4dbcdd3a0c64d4e74a98dd8caacaefced9b6.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 10 Jun 2026 12:26:50 +0200
Subject: [PATCH] qemuxmlconftest: Add test case for specifying 'virtio-gpu'
where 'virtio-vga' would be picked
Add a test case demonstrating the switch to 'virtio-gpu' on a host which
would normally pick 'virtio-vga'.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit ca4bcd775cc2d17d35e752f03842f3442290cf0d)
https://redhat.atlassian.net/browse/RHEL-186019
Conflicts:
- tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.args
Context; patch tweaking monitor FD passing in tests not backported
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
...io-vga-device-downgrade.x86_64-latest.args | 37 ++++++++++++++++
...tio-vga-device-downgrade.x86_64-latest.xml | 44 +++++++++++++++++++
.../video-virtio-vga-device-downgrade.xml | 33 ++++++++++++++
tests/qemuxmlconftest.c | 1 +
4 files changed, 115 insertions(+)
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.xml
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.args b/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.args
new file mode 100644
index 0000000000..fec2b04ca9
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.args
@@ -0,0 +1,37 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/QEMUGuest1","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap","cache":{"direct":true,"no-flush":false}}' \
+-blockdev '{"node-name":"libvirt-1-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":"libvirt-1-storage"}' \
+-device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-format","id":"ide0-0-0","bootindex":1,"write-cache":"on"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"virtio-vga","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
+-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.xml b/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.xml
new file mode 100644
index 0000000000..c04687983d
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.x86_64-latest.xml
@@ -0,0 +1,44 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>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='file' device='disk'>
+ <driver name='qemu' type='qcow2' cache='none'/>
+ <source file='/var/lib/libvirt/images/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='virtio' heads='1' primary='yes' device='virtio-gpu'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </video>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.xml b/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.xml
new file mode 100644
index 0000000000..aef4b64ad4
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-device-downgrade.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' 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>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2' cache='none'/>
+ <source file='/var/lib/libvirt/images/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <video>
+ <model type='virtio' heads='1' device='virtio-gpu'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 44df46f35c..85cf9960aa 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2775,6 +2775,7 @@ mymain(void)
ARG_CAPS_VER, "latest",
ARG_QEMU_CAPS_DEL, QEMU_CAPS_DEVICE_VIRTIO_VGA, QEMU_CAPS_LAST,
ARG_END);
+ DO_TEST_CAPS_LATEST("video-virtio-vga-device-downgrade");
DO_TEST_CAPS_LATEST("video-virtio-blob-on");
DO_TEST_CAPS_LATEST("video-virtio-blob-off");
DO_TEST_CAPS_LATEST("video-virtio-vga-gpu-gl");
--
2.55.0

View File

@ -0,0 +1,256 @@
From f27113ac4b180f85d92ba96c6e2b0065983945da Mon Sep 17 00:00:00 2001
Message-ID: <f27113ac4b180f85d92ba96c6e2b0065983945da.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 9 Jun 2026 14:33:04 +0200
Subject: [PATCH] qemuxmlconftest: Add test cases for configs asking for
'virtio-gpu-gl' or 'virtio-vga-gl' without the capability
The capability check in 'qemuValidateDomainDeviceDefVideo' which
validates whether a <video> definition with acceleration enabled is
possible is only aggregate, thus validates that any '-gl' video backend
is available.
Since qemu compiles each backend into a separate module it's possible to
have an installation where 'virtio-gpu-pci-gl' exist but 'virtio-vga-gl'
doesn't and it will not be rejected at validation. The commandline
though will generate a device *without* the '-gl' which is ABI
incompatible with the counterpart which does have '-gl', but the VM
starts. If such a VM is then migrated to a deployment which does have
the '-gl' variant available, migration will fail because qemu will
generate the '-gl' device as we don't record this fact in the XML.
This test case captures this situation which will be fixed later.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit a30a5a89e7702c7ae31344893735442385ce5777)
https://redhat.atlassian.net/browse/RHEL-186019
Conflicts:
- tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.args
- tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.args
Context; patch tweaking monitor FD passing in tests not backported
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
....QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.args | 35 ++++++++++++++
...t.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml | 46 +++++++++++++++++++
...test.QEMU_CAPS_VIRTIO_VGA_GL-disabled.args | 35 ++++++++++++++
...atest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml | 46 +++++++++++++++++++
tests/qemuxmlconftest.c | 10 ++++
5 files changed, 172 insertions(+)
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.args
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.args
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.args b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.args
new file mode 100644
index 0000000000..297b919b5b
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.args
@@ -0,0 +1,35 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"virtio-vga-gl","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
+-device '{"driver":"virtio-gpu-pci","id":"video1","max_outputs":1,"bus":"pci.0","addr":"0x4"}' \
+-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml
new file mode 100644
index 0000000000..991141c643
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled.xml
@@ -0,0 +1,46 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='virtio' heads='1' primary='yes'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </video>
+ <video>
+ <model type='virtio' heads='1'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </video>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.args b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.args
new file mode 100644
index 0000000000..d649dc06f8
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.args
@@ -0,0 +1,35 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"virtio-vga","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
+-device '{"driver":"virtio-gpu-gl-pci","id":"video1","max_outputs":1,"bus":"pci.0","addr":"0x4"}' \
+-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml
new file mode 100644
index 0000000000..991141c643
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga-gpu-gl.x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled.xml
@@ -0,0 +1,46 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='virtio' heads='1' primary='yes'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </video>
+ <video>
+ <model type='virtio' heads='1'>
+ <acceleration accel3d='yes'/>
+ </model>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </video>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index b00b71e10e..8424bdf709 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2778,6 +2778,16 @@ mymain(void)
DO_TEST_CAPS_LATEST("video-virtio-blob-on");
DO_TEST_CAPS_LATEST("video-virtio-blob-off");
DO_TEST_CAPS_LATEST("video-virtio-vga-gpu-gl");
+ DO_TEST_FULL("video-virtio-vga-gpu-gl", ".x86_64-latest.QEMU_CAPS_VIRTIO_VGA_GL-disabled",
+ ARG_CAPS_ARCH, "x86_64",
+ ARG_CAPS_VER, "latest",
+ ARG_QEMU_CAPS_DEL, QEMU_CAPS_VIRTIO_VGA_GL, QEMU_CAPS_LAST,
+ ARG_END);
+ DO_TEST_FULL("video-virtio-vga-gpu-gl", ".x86_64-latest.QEMU_CAPS_VIRTIO_GPU_GL_PCI-disabled",
+ ARG_CAPS_ARCH, "x86_64",
+ ARG_CAPS_VER, "latest",
+ ARG_QEMU_CAPS_DEL, QEMU_CAPS_VIRTIO_GPU_GL_PCI, QEMU_CAPS_LAST,
+ ARG_END);
DO_TEST_CAPS_LATEST("video-virtio-edid-none");
DO_TEST_CAPS_LATEST("video-virtio-edid-off");
DO_TEST_CAPS_LATEST("video-virtio-edid-on");
--
2.55.0

View File

@ -0,0 +1,149 @@
From d92b3e70c6ae7277aafaf75e31a0b92278480143 Mon Sep 17 00:00:00 2001
Message-ID: <d92b3e70c6ae7277aafaf75e31a0b92278480143.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 26 May 2026 14:14:31 +0200
Subject: [PATCH] qemuxmlconftest: Add 'video-virtio-vga' invocation with
QEMU_CAPS_DEVICE_VIRTIO_VGA disabled
The test case shows that if the 'QEMU_CAPS_DEVICE_VIRTIO_VGA' capability
is not present (e.g. if the corresponding qemu module isn't installed)
libvirt will pick:
-device '{"driver":"virtio-gpu-pci", ...
instead of:
-device '{"driver":"virtio-vga", ...
but without any discernable difference in the XML.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 84b05fe4e3a0c6b4fe4965df3471e891ceb1d4e6)
https://redhat.atlassian.net/browse/RHEL-186019
Conflicts:
- tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.args
Context; patch tweaking monitor FD passing in tests not backported
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
....QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.args | 37 ++++++++++++++++
...t.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml | 44 +++++++++++++++++++
tests/qemuxmlconftest.c | 5 +++
3 files changed, 86 insertions(+)
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.args
create mode 100644 tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml
diff --git a/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.args b/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.args
new file mode 100644
index 0000000000..5782505b61
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.args
@@ -0,0 +1,37 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/QEMUGuest1","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap","cache":{"direct":true,"no-flush":false}}' \
+-blockdev '{"node-name":"libvirt-1-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":"libvirt-1-storage"}' \
+-device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-format","id":"ide0-0-0","bootindex":1,"write-cache":"on"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"virtio-gpu-pci","id":"video0","max_outputs":1,"bus":"pci.0","addr":"0x2"}' \
+-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml b/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml
new file mode 100644
index 0000000000..0c31cfb927
--- /dev/null
+++ b/tests/qemuxmlconfdata/video-virtio-vga.x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.xml
@@ -0,0 +1,44 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>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='file' device='disk'>
+ <driver name='qemu' type='qcow2' cache='none'/>
+ <source file='/var/lib/libvirt/images/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='virtio' heads='1' primary='yes'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </video>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 29b7e1883c..b00b71e10e 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2770,6 +2770,11 @@ mymain(void)
DO_TEST_CAPS_LATEST("video-virtio-gpu-sdl-gl");
DO_TEST_CAPS_LATEST("video-virtio-gpu-secondary");
DO_TEST_CAPS_LATEST("video-virtio-vga");
+ DO_TEST_FULL("video-virtio-vga", ".x86_64-latest.QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled",
+ ARG_CAPS_ARCH, "x86_64",
+ ARG_CAPS_VER, "latest",
+ ARG_QEMU_CAPS_DEL, QEMU_CAPS_DEVICE_VIRTIO_VGA, QEMU_CAPS_LAST,
+ ARG_END);
DO_TEST_CAPS_LATEST("video-virtio-blob-on");
DO_TEST_CAPS_LATEST("video-virtio-blob-off");
DO_TEST_CAPS_LATEST("video-virtio-vga-gpu-gl");
--
2.55.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,145 @@
From 26a62b18ad904305964a92173aea7c98fd35abf7 Mon Sep 17 00:00:00 2001
Message-ID: <26a62b18ad904305964a92173aea7c98fd35abf7.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 8 Jun 2026 11:00:31 +0200
Subject: [PATCH] virDomainVideoDefFormat: Use 'virXMLFormatElement' instead of
custom formatter
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit b64f4bab656a019da307054fb354a3fe36b36b4f)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/conf/domain_conf.c | 79 ++++++++++++++++++++----------------------
1 file changed, 37 insertions(+), 42 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cec0f88f0f..dc19e258dd 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -27034,6 +27034,9 @@ static void
virDomainVideoAccelDefFormat(virBuffer *buf,
virDomainVideoAccelDef *def)
{
+ if (!def)
+ return;
+
virBufferAddLit(buf, "<acceleration");
if (def->accel3d) {
virBufferAsprintf(buf, " accel3d='%s'",
@@ -27051,6 +27054,9 @@ static void
virDomainVideoResolutionDefFormat(virBuffer *buf,
virDomainVideoResolutionDef *def)
{
+ if (!def)
+ return;
+
virBufferAddLit(buf, "<resolution");
if (def->x && def->y) {
virBufferAsprintf(buf, " x='%u' y='%u'",
@@ -27065,7 +27071,10 @@ virDomainVideoDefFormat(virBuffer *buf,
unsigned int flags)
{
const char *model = virDomainVideoTypeToString(def->type);
- g_auto(virBuffer) driverBuf = VIR_BUFFER_INITIALIZER;
+ g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
+ g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER;
+ g_auto(virBuffer) modelAttrBuf = VIR_BUFFER_INITIALIZER;
+ g_auto(virBuffer) modelChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf);
if (!model) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -27073,61 +27082,47 @@ virDomainVideoDefFormat(virBuffer *buf,
return -1;
}
- virBufferAddLit(buf, "<video>\n");
- virBufferAdjustIndent(buf, 2);
- virDomainVirtioOptionsFormat(&driverBuf, def->virtio);
- if (virBufferUse(&driverBuf) || (def->driver && def->driver->vgaconf) ||
- def->backend != VIR_DOMAIN_VIDEO_BACKEND_TYPE_DEFAULT) {
- virBufferAddLit(buf, "<driver");
- if (virBufferUse(&driverBuf))
- virBufferAddBuffer(buf, &driverBuf);
- if (def->driver && def->driver->vgaconf)
- virBufferAsprintf(buf, " vgaconf='%s'",
- virDomainVideoVGAConfTypeToString(def->driver->vgaconf));
- if (def->backend != VIR_DOMAIN_VIDEO_BACKEND_TYPE_DEFAULT)
- virBufferAsprintf(buf, " name='%s'",
- virDomainVideoBackendTypeToString(def->backend));
- virBufferAddLit(buf, "/>\n");
- }
- virBufferAsprintf(buf, "<model type='%s'",
- model);
+ virDomainVirtioOptionsFormat(&driverAttrBuf, def->virtio);
+ if (def->driver && def->driver->vgaconf)
+ virBufferAsprintf(&driverAttrBuf, " vgaconf='%s'",
+ virDomainVideoVGAConfTypeToString(def->driver->vgaconf));
+ if (def->backend != VIR_DOMAIN_VIDEO_BACKEND_TYPE_DEFAULT)
+ virBufferAsprintf(&driverAttrBuf, " name='%s'",
+ virDomainVideoBackendTypeToString(def->backend));
+
+ virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL);
+
+ virBufferAsprintf(&modelAttrBuf, " type='%s'", model);
if (def->ram)
- virBufferAsprintf(buf, " ram='%u'", def->ram);
+ virBufferAsprintf(&modelAttrBuf, " ram='%u'", def->ram);
if (def->vram)
- virBufferAsprintf(buf, " vram='%u'", def->vram);
+ virBufferAsprintf(&modelAttrBuf, " vram='%u'", def->vram);
if (def->vram64)
- virBufferAsprintf(buf, " vram64='%u'", def->vram64);
+ virBufferAsprintf(&modelAttrBuf, " vram64='%u'", def->vram64);
if (def->vgamem)
- virBufferAsprintf(buf, " vgamem='%u'", def->vgamem);
+ virBufferAsprintf(&modelAttrBuf, " vgamem='%u'", def->vgamem);
if (def->heads)
- virBufferAsprintf(buf, " heads='%u'", def->heads);
+ virBufferAsprintf(&modelAttrBuf, " heads='%u'", def->heads);
if (def->primary)
- virBufferAddLit(buf, " primary='yes'");
+ virBufferAddLit(&modelAttrBuf, " primary='yes'");
if (def->blob != VIR_TRISTATE_SWITCH_ABSENT)
- virBufferAsprintf(buf, " blob='%s'", virTristateSwitchTypeToString(def->blob));
+ virBufferAsprintf(&modelAttrBuf, " blob='%s'", virTristateSwitchTypeToString(def->blob));
if (def->edid != VIR_TRISTATE_SWITCH_ABSENT)
- virBufferAsprintf(buf, " edid='%s'", virTristateSwitchTypeToString(def->edid));
- if (def->accel || def->res) {
- virBufferAddLit(buf, ">\n");
- virBufferAdjustIndent(buf, 2);
- if (def->accel)
- virDomainVideoAccelDefFormat(buf, def->accel);
- if (def->res)
- virDomainVideoResolutionDefFormat(buf, def->res);
- virBufferAdjustIndent(buf, -2);
- virBufferAddLit(buf, "</model>\n");
- } else {
- virBufferAddLit(buf, "/>\n");
- }
+ virBufferAsprintf(&modelAttrBuf, " edid='%s'", virTristateSwitchTypeToString(def->edid));
- virDomainDeviceInfoFormat(buf, &def->info, flags);
+ virDomainVideoAccelDefFormat(&modelChildBuf, def->accel);
+ virDomainVideoResolutionDefFormat(&modelChildBuf, def->res);
- virBufferAdjustIndent(buf, -2);
- virBufferAddLit(buf, "</video>\n");
+ virXMLFormatElement(&childBuf, "model", &modelAttrBuf, &modelChildBuf);
+
+ virDomainDeviceInfoFormat(&childBuf, &def->info, flags);
+
+ virXMLFormatElement(buf, "video", NULL, &childBuf);
return 0;
}
+
static int
virDomainInputDefFormat(virBuffer *buf,
virDomainInputDef *def,
--
2.55.0

View File

@ -0,0 +1,46 @@
From 1e63c510b4f687c3b52bf9b606a54793155aea21 Mon Sep 17 00:00:00 2001
Message-ID: <1e63c510b4f687c3b52bf9b606a54793155aea21.1784297532.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 26 May 2026 11:39:28 +0200
Subject: [PATCH] virQEMUCapsCacheLookupDefault: Fix error message when no
emulators are installed
When querying capabilities for the default emulator with no other
arguments (e.g. 'virsh domcapabilities) fix error whithout emulator
installed an error is reported but the error would mention '(null)'
architecture:
# virsh domcapabilities
error: failed to get emulator capabilities
error: unsupported configuration: unable to find any emulator to serve '(null)' architecture
This happens as the error formatting takes 'archStr' which is NULL for
the default architecture instead of using 'arch' which is populated by
the host's architecture and converting it back.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 9e43cf3e5866eb2186e903a000c724461466516a)
https://redhat.atlassian.net/browse/RHEL-186019
https://redhat.atlassian.net/browse/RHEL-177646 (rhel-9.9)
---
src/qemu/qemu_capabilities.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6dd7284505..fc5a428620 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6372,7 +6372,7 @@ virQEMUCapsCacheLookupDefault(virFileCache *cache,
if (!binary) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unable to find any emulator to serve '%1$s' architecture"),
- archStr);
+ virArchToString(arch));
return NULL;
}
--
2.55.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

@ -298,7 +298,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 11.10.0
Release: 12%{?dist}%{?extra_release}.alma.1
Release: 16%{?dist}%{?extra_release}.alma.1
License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1
URL: https://libvirt.org/
@ -383,6 +383,69 @@ 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
Patch120: libvirt-qemu-Ensure-proper-shutdown-ordering-of-virtlockd-virtlogd-daemons.patch
Patch121: libvirt-qemu-capabilities-Apply-capability_filters-configration-option-on-all-capabilities.patch
Patch122: libvirt-qemu-capabilities-Export-virQEMUCapsNewCopy-outside-of-qemu_capspriv.patch
Patch123: libvirt-qemu-Allow-reuse-of-qemuProcessStartUpdateCustomCaps.patch
Patch124: libvirt-qemu-validate-Validate-VM-config-with-qemuCaps-influenced-by-qemu-capabilities.patch
Patch125: libvirt-qemu-postparse-Process-VM-config-with-qemuCaps-influenced-by-qemu-capabilities.patch
Patch126: libvirt-virQEMUCapsCacheLookupDefault-Fix-error-message-when-no-emulators-are-installed.patch
Patch127: libvirt-qemuxmlconfdata-un-symlink-video-virtio-vga-gpu-gl-output.patch
Patch128: libvirt-qemuxmlconftest-Add-video-virtio-vga-invocation-with-QEMU_CAPS_DEVICE_VIRTIO_VGA-disabled.patch
Patch129: libvirt-qemuxmlconftest-Add-test-cases-for-configs-asking-for-virtio-gpu-gl-or-virtio-vga-gl-without-the-capability.patch
Patch130: libvirt-qemuxmlconftest-Add-invocation-of-video-virtio-vga-gpu-gl-with-missing-caps-and-VIR_DOMAIN_DEF_PARSE_ABI_UPDATE.patch
Patch131: libvirt-qemustatusxml2xml-Add-test-case-capturing-virtio-video-device.patch
Patch132: libvirt-virDomainVideoDefFormat-Use-virXMLFormatElement-instead-of-custom-formatter.patch
Patch133: libvirt-conf-Add-fields-for-recording-actually-selected-virtio-video-device.patch
Patch134: libvirt-qemuxmlconftest-Add-test-case-for-specifying-virtio-gpu-where-virtio-vga-would-be-picked.patch
Patch135: libvirt-qemuDeviceVideoGetModel-Directly-return-picked-model.patch
Patch136: libvirt-qemu-postparse-Fill-in-selected-virtio-video-frondend-device-in-the-XML.patch
Patch137: libvirt-qemuValidateDomainDeviceDefVideo-Fix-checks-of-virtio-video-devices.patch
Patch138: libvirt-qemuDeviceVideoGetModel-Remove-logic-for-selecting-virtio-devices.patch
Patch139: libvirt-qemuDeviceVideoGetModel-Simplify-by-relying-on-checks-from-qemuValidateDomainDeviceDefVideo.patch
Patch140: libvirt-qemu-Remove-qemuDomainSupportsVideoVga.patch
Requires: libvirt-daemon = %{version}-%{release}
@ -2774,9 +2837,83 @@ exit 0
%endif
%changelog
* Mon Mar 30 2026 Eduard Abdullin <eabdullin@almalinux.org> - 11.10.0-12.alma.1
* Mon Aug 24 2026 Eduard Abdullin <eabdullin@almalinux.org> - 11.10.0-16.alma.1
- Enable building for ppc64le
* Fri Jul 24 2026 Jiri Denemark <jdenemar@redhat.com> - 11.10.0-16
- Live migration fails when virtio-vga becomes available, video device switches from virtio-gpu-pci to virtio-vga on target (RHEL-177646)
* Fri Jul 17 2026 Jiri Denemark <jdenemar@redhat.com> - 11.10.0-15
- qemu: capabilities: Apply 'capability_filters' configration option on all capabilities (RHEL-177646)
- qemu: capabilities: Export 'virQEMUCapsNewCopy' outside of 'qemu_capspriv' (RHEL-177646)
- qemu: Allow reuse of 'qemuProcessStartUpdateCustomCaps' (RHEL-177646)
- qemu: validate: Validate VM config with qemuCaps influenced by <qemu:capabilities> (RHEL-177646)
- qemu: postparse: Process VM config with qemuCaps influenced by <qemu:capabilities> (RHEL-177646)
- virQEMUCapsCacheLookupDefault: Fix error message when no emulators are installed (RHEL-177646)
- qemuxmlconfdata: un-symlink 'video-virtio-vga-gpu-gl' output (RHEL-177646)
- qemuxmlconftest: Add 'video-virtio-vga' invocation with QEMU_CAPS_DEVICE_VIRTIO_VGA disabled (RHEL-177646)
- qemuxmlconftest: Add test cases for configs asking for 'virtio-gpu-gl' or 'virtio-vga-gl' without the capability (RHEL-177646)
- qemuxmlconftest: Add invocation of 'video-virtio-vga-gpu-gl' with missing caps and VIR_DOMAIN_DEF_PARSE_ABI_UPDATE (RHEL-177646)
- qemustatusxml2xml: Add test case capturing virtio video device (RHEL-177646)
- virDomainVideoDefFormat: Use 'virXMLFormatElement' instead of custom formatter (RHEL-177646)
- conf: Add fields for recording actually-selected virtio video device (RHEL-177646)
- qemuxmlconftest: Add test case for specifying 'virtio-gpu' where 'virtio-vga' would be picked (RHEL-177646)
- qemuDeviceVideoGetModel: Directly return picked model (RHEL-177646)
- qemu: postparse: Fill in selected virtio video frondend device in the XML (RHEL-177646)
- qemuValidateDomainDeviceDefVideo: Fix checks of virtio video devices (RHEL-177646)
- qemuDeviceVideoGetModel: Remove logic for selecting 'virtio' devices (RHEL-177646)
- qemuDeviceVideoGetModel: Simplify by relying on checks from 'qemuValidateDomainDeviceDefVideo' (RHEL-177646)
- qemu: Remove 'qemuDomainSupportsVideoVga' (RHEL-177646)
* Wed Jul 1 2026 Jiri Denemark <jdenemar@redhat.com> - 11.10.0-14
- distro: Update URL in plans.fmf
- qemu: Ensure proper shutdown ordering of virtlockd/virtlogd daemons (RHEL-180876)
* 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)