From 481c875102589f8a057a5390fdb54162ea2d8174 Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Wed, 18 Feb 2026 15:07:39 +0100 Subject: [PATCH] libvirt-11.10.0-10.el10 - qemu: Introduce QEMU_CAPS_OBJECT_IOMMUFD (RHEL-150351) - qemu: Move IOMMUFD validation to qemu_validate (RHEL-150351) - util: Move openning IOMMU device to viriommufd (RHEL-150351) - qemu_process: Refactor qemuProcessOpenIommuFd (RHEL-150351) - util: Move openning VFIO device to virpci (RHEL-150351) - qemu_process: Refactor qemuProcessOpenVfioDeviceFd (RHEL-150351) - util: Use virPCIDevice as argument in virPCIDeviceGetVfioPath (RHEL-150351) - conf: Introduce virHostdevIsPCIDeviceWithIOMMUFD (RHEL-150351) - conf: Introduce virDomainDefHasPCIHostdevWithIOMMUFD (RHEL-150351) - qemu_domain: Add missing IOMMUFD cleanup (RHEL-150351) - qemu_process: Fix FD leak with multiple host devices using IOMMUFD (RHEL-150351) - qemu_process: Refactor qemuProcessOpenVfioFds (RHEL-150351) - qemuxmlconftest: Refactor host device preparation (RHEL-150351) - qemuxmlconftest: Rename and refactor testSetupHostdevPrivateData (RHEL-150351) - qemuxmlconftest: Set fake FD for IOMMUFD (RHEL-150351) - qemu: Convert IOMMUFD to qemuFDPassDirect (RHEL-150351) - qemu: Convert vfioDeviceFd to qemuFDPassDirect (RHEL-150351) - qemu_command: Don't use host property if IOMMUFD is used (RHEL-150351) - qemu: Save IOMMUFD state into status XML (RHEL-150351) - qemu_hotplug: Remove iommufd object if no longer needed (RHEL-150351) - qemu_command: Extract building IOMMUFD props to function (RHEL-150351) - qemu_hotplug: Add support to hotplug host device with IOMMUFD (RHEL-150351) - conf: Introduce iommufd enum for domaincaps (RHEL-148135) - qemu: Fill iommufd domain capability (RHEL-148135) - tests: properly mock VFIO and IOMMU checks (RHEL-148135) - iommufd: fix FD leak in case of error (RHEL-150351) Resolves: RHEL-148135, RHEL-150351 --- ...ntroduce-iommufd-enum-for-domaincaps.patch | 69 + ...virDomainDefHasPCIHostdevWithIOMMUFD.patch | 132 ++ ...uce-virHostdevIsPCIDeviceWithIOMMUFD.patch | 89 ++ ...iommufd-fix-FD-leak-in-case-of-error.patch | 38 + ...-Convert-IOMMUFD-to-qemuFDPassDirect.patch | 125 ++ ...ert-vfioDeviceFd-to-qemuFDPassDirect.patch | 129 ++ ...-qemu-Fill-iommufd-domain-capability.patch | 1257 +++++++++++++++++ ...u-Introduce-QEMU_CAPS_OBJECT_IOMMUFD.patch | 266 ++++ ...-IOMMUFD-validation-to-qemu_validate.patch | 111 ++ ...u-Save-IOMMUFD-state-into-status-XML.patch | 79 ++ ...use-host-property-if-IOMMUFD-is-used.patch | 134 ++ ...t-building-IOMMUFD-props-to-function.patch | 73 + ...u_domain-Add-missing-IOMMUFD-cleanup.patch | 33 + ...-to-hotplug-host-device-with-IOMMUFD.patch | 134 ++ ...e-iommufd-object-if-no-longer-needed.patch | 40 + ...-multiple-host-devices-using-IOMMUFD.patch | 48 + ...cess-Refactor-qemuProcessOpenIommuFd.patch | 72 + ...Refactor-qemuProcessOpenVfioDeviceFd.patch | 75 + ...cess-Refactor-qemuProcessOpenVfioFds.patch | 77 + ...est-Refactor-host-device-preparation.patch | 101 ++ ...refactor-testSetupHostdevPrivateData.patch | 78 + ...uxmlconftest-Set-fake-FD-for-IOMMUFD.patch | 98 ++ ...-properly-mock-VFIO-and-IOMMU-checks.patch | 113 ++ ...-openning-IOMMU-device-to-viriommufd.patch | 115 ++ ...-Move-openning-VFIO-device-to-virpci.patch | 123 ++ ...-argument-in-virPCIDeviceGetVfioPath.patch | 143 ++ libvirt.spec | 56 +- 27 files changed, 3807 insertions(+), 1 deletion(-) create mode 100644 libvirt-conf-Introduce-iommufd-enum-for-domaincaps.patch create mode 100644 libvirt-conf-Introduce-virDomainDefHasPCIHostdevWithIOMMUFD.patch create mode 100644 libvirt-conf-Introduce-virHostdevIsPCIDeviceWithIOMMUFD.patch create mode 100644 libvirt-iommufd-fix-FD-leak-in-case-of-error.patch create mode 100644 libvirt-qemu-Convert-IOMMUFD-to-qemuFDPassDirect.patch create mode 100644 libvirt-qemu-Convert-vfioDeviceFd-to-qemuFDPassDirect.patch create mode 100644 libvirt-qemu-Fill-iommufd-domain-capability.patch create mode 100644 libvirt-qemu-Introduce-QEMU_CAPS_OBJECT_IOMMUFD.patch create mode 100644 libvirt-qemu-Move-IOMMUFD-validation-to-qemu_validate.patch create mode 100644 libvirt-qemu-Save-IOMMUFD-state-into-status-XML.patch create mode 100644 libvirt-qemu_command-Don-t-use-host-property-if-IOMMUFD-is-used.patch create mode 100644 libvirt-qemu_command-Extract-building-IOMMUFD-props-to-function.patch create mode 100644 libvirt-qemu_domain-Add-missing-IOMMUFD-cleanup.patch create mode 100644 libvirt-qemu_hotplug-Add-support-to-hotplug-host-device-with-IOMMUFD.patch create mode 100644 libvirt-qemu_hotplug-Remove-iommufd-object-if-no-longer-needed.patch create mode 100644 libvirt-qemu_process-Fix-FD-leak-with-multiple-host-devices-using-IOMMUFD.patch create mode 100644 libvirt-qemu_process-Refactor-qemuProcessOpenIommuFd.patch create mode 100644 libvirt-qemu_process-Refactor-qemuProcessOpenVfioDeviceFd.patch create mode 100644 libvirt-qemu_process-Refactor-qemuProcessOpenVfioFds.patch create mode 100644 libvirt-qemuxmlconftest-Refactor-host-device-preparation.patch create mode 100644 libvirt-qemuxmlconftest-Rename-and-refactor-testSetupHostdevPrivateData.patch create mode 100644 libvirt-qemuxmlconftest-Set-fake-FD-for-IOMMUFD.patch create mode 100644 libvirt-tests-properly-mock-VFIO-and-IOMMU-checks.patch create mode 100644 libvirt-util-Move-openning-IOMMU-device-to-viriommufd.patch create mode 100644 libvirt-util-Move-openning-VFIO-device-to-virpci.patch create mode 100644 libvirt-util-Use-virPCIDevice-as-argument-in-virPCIDeviceGetVfioPath.patch diff --git a/libvirt-conf-Introduce-iommufd-enum-for-domaincaps.patch b/libvirt-conf-Introduce-iommufd-enum-for-domaincaps.patch new file mode 100644 index 0000000..3570634 --- /dev/null +++ b/libvirt-conf-Introduce-iommufd-enum-for-domaincaps.patch @@ -0,0 +1,69 @@ +From c0fbd0d516a2c4457789d158bfdea839255d0854 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sat, 14 Feb 2026 06:14:20 +0100 +Subject: [PATCH] conf: Introduce iommufd enum for domaincaps + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 855f8fe9e2454555ba84696750e0e1501dd5ba80) + +Resolves: https://issues.redhat.com/browse/RHEL-148135 +Signed-off-by: Pavel Hrdina +--- + docs/formatdomaincaps.rst | 7 +++++++ + src/conf/domain_capabilities.c | 1 + + src/conf/domain_capabilities.h | 1 + + 3 files changed, 9 insertions(+) + +diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst +index 8b4f0ecff3..6ba7f84f96 100644 +--- a/docs/formatdomaincaps.rst ++++ b/docs/formatdomaincaps.rst +@@ -461,6 +461,10 @@ Well, only if the following is enabled: + vfio + xen + ++ ++ yes ++ no ++ + + + +@@ -477,6 +481,9 @@ Well, only if the following is enabled: + ``mode="capabilities"``. + ``pciBackend`` + Options for the ``name`` attribute of the element. ++``iommufd`` ++ Options for the ``iommufd`` attribute of the element. ++ :since:`Since 12.1.0` + + RNG device + ^^^^^^^^^^ +diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c +index f843124695..49179b97ab 100644 +--- a/src/conf/domain_capabilities.c ++++ b/src/conf/domain_capabilities.c +@@ -620,6 +620,7 @@ virDomainCapsDeviceHostdevFormat(virBuffer *buf, + ENUM_PROCESS(hostdev, subsysType, virDomainHostdevSubsysTypeToString); + ENUM_PROCESS(hostdev, capsType, virDomainHostdevCapsTypeToString); + ENUM_PROCESS(hostdev, pciBackend, virDeviceHostdevPCIDriverNameTypeToString); ++ ENUM_PROCESS(hostdev, iommufd, virTristateBoolTypeToString); + + FORMAT_EPILOGUE(hostdev); + } +diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h +index 437981c711..b10370db8f 100644 +--- a/src/conf/domain_capabilities.h ++++ b/src/conf/domain_capabilities.h +@@ -108,6 +108,7 @@ struct _virDomainCapsDeviceHostdev { + virDomainCapsEnum subsysType; /* Info about virDomainHostdevSubsysType */ + virDomainCapsEnum capsType; /* Info about virDomainHostdevCapsType */ + virDomainCapsEnum pciBackend; /* Info about virDomainHostdevSubsysPCIBackendType */ ++ virDomainCapsEnum iommufd; /* Info about iommufd:virTristateBool */ + /* add new fields here */ + }; + +-- +2.53.0 diff --git a/libvirt-conf-Introduce-virDomainDefHasPCIHostdevWithIOMMUFD.patch b/libvirt-conf-Introduce-virDomainDefHasPCIHostdevWithIOMMUFD.patch new file mode 100644 index 0000000..945db18 --- /dev/null +++ b/libvirt-conf-Introduce-virDomainDefHasPCIHostdevWithIOMMUFD.patch @@ -0,0 +1,132 @@ +From 4e8fe2eb42b47a55e491a63e2600a24e0501fd1f Mon Sep 17 00:00:00 2001 +Message-ID: <4e8fe2eb42b47a55e491a63e2600a24e0501fd1f.1771423658.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 18:19:56 +0100 +Subject: [PATCH] conf: Introduce virDomainDefHasPCIHostdevWithIOMMUFD + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 4b176cfc3877cca882d63ab4ed446794d7a05722) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/conf/domain_conf.c | 14 ++++++++++++++ + src/conf/domain_conf.h | 3 +++ + src/libvirt_private.syms | 1 + + src/qemu/qemu_command.c | 42 ++++++++++++---------------------------- + 4 files changed, 30 insertions(+), 30 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 9ae48e9abc..cb047e5a3e 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -32482,6 +32482,20 @@ virDomainDefHasPCIHostdev(const virDomainDef *def) + } + + ++bool ++virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def) ++{ ++ size_t i; ++ ++ for (i = 0; i < def->nhostdevs; i++) { ++ if (virHostdevIsPCIDeviceWithIOMMUFD(def->hostdevs[i])) ++ return true; ++ } ++ ++ return false; ++} ++ ++ + bool + virDomainDefHasMdevHostdev(const virDomainDef *def) + { +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index d958ed04f9..69a8e79c6d 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -4655,6 +4655,9 @@ virDomainDefHasNVMeDisk(const virDomainDef *def); + bool + virDomainDefHasPCIHostdev(const virDomainDef *def); + ++bool ++virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def); ++ + bool + virDomainDefHasMdevHostdev(const virDomainDef *def); + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 863e50ec4f..effe44fe57 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -348,6 +348,7 @@ virDomainDefHasNVMeDisk; + virDomainDefHasOldStyleROUEFI; + virDomainDefHasOldStyleUEFI; + virDomainDefHasPCIHostdev; ++virDomainDefHasPCIHostdevWithIOMMUFD; + virDomainDefHasTimer; + virDomainDefHasUSB; + virDomainDefHasVcpusOffline; +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index c8626e6d49..3119191413 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -5349,43 +5349,25 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd, + const virDomainDef *def, + virDomainObj *vm) + { +- size_t i; + qemuDomainObjPrivate *priv = vm->privateData; + g_autofree char *fdstr = g_strdup_printf("%d", priv->iommufd); ++ g_autoptr(virJSONValue) props = NULL; + ++ if (!virDomainDefHasPCIHostdevWithIOMMUFD(def)) ++ return 0; + +- for (i = 0; i < def->nhostdevs; i++) { +- virDomainHostdevDef *hostdev = def->hostdevs[i]; +- virDomainHostdevSubsys *subsys = &hostdev->source.subsys; +- g_autoptr(virJSONValue) props = NULL; ++ virCommandPassFD(cmd, priv->iommufd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); + +- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) +- continue; ++ priv->iommufd = -1; + +- if (subsys->type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) +- continue; ++ if (qemuMonitorCreateObjectProps(&props, "iommufd", ++ "iommufd0", ++ "S:fd", fdstr, ++ NULL) < 0) ++ return -1; + +- if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED) +- continue; +- +- if (subsys->u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) +- continue; +- +- virCommandPassFD(cmd, priv->iommufd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); +- +- priv->iommufd = -1; +- +- if (qemuMonitorCreateObjectProps(&props, "iommufd", +- "iommufd0", +- "S:fd", fdstr, +- NULL) < 0) +- return -1; +- +- if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0) +- return -1; +- +- break; +- } ++ if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0) ++ return -1; + + return 0; + } +-- +2.53.0 diff --git a/libvirt-conf-Introduce-virHostdevIsPCIDeviceWithIOMMUFD.patch b/libvirt-conf-Introduce-virHostdevIsPCIDeviceWithIOMMUFD.patch new file mode 100644 index 0000000..7f8e036 --- /dev/null +++ b/libvirt-conf-Introduce-virHostdevIsPCIDeviceWithIOMMUFD.patch @@ -0,0 +1,89 @@ +From 615f11792c8988cfd6a30717dcc8d5d9174ea508 Mon Sep 17 00:00:00 2001 +Message-ID: <615f11792c8988cfd6a30717dcc8d5d9174ea508.1771423658.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 18:19:23 +0100 +Subject: [PATCH] conf: Introduce virHostdevIsPCIDeviceWithIOMMUFD + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 97eed30948e980be8b7552fff637e828768854e4) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/conf/domain_conf.c | 15 +++++++++++++++ + src/conf/domain_conf.h | 3 +++ + src/libvirt_private.syms | 1 + + src/qemu/qemu_process.c | 5 +---- + 4 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 83c58ab5ff..9ae48e9abc 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -32758,6 +32758,21 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev) + } + + ++/** ++ * virHostdevIsPCIDeviceWithIOMMUFD: ++ * @hostdev: host device to check ++ * ++ * Returns true if @hostdev is a PCI device with IOMMUFD enabled, false otherwise. ++ */ ++bool ++virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev) ++{ ++ return virHostdevIsPCIDevice(hostdev) && ++ hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO && ++ hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES; ++} ++ ++ + static void + virDomainObjGetMessagesIOErrorsSrc(virStorageSource *src, + const char *diskdst, +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index b120d4a68e..d958ed04f9 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -4713,6 +4713,9 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev) + bool + virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev) + ATTRIBUTE_NONNULL(1); ++bool ++virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev) ++ ATTRIBUTE_NONNULL(1); + + void + virDomainObjGetMessagesIOErrorsChain(virStorageSource *src, +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 9ae44e31b8..863e50ec4f 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -812,6 +812,7 @@ virDomainQemuMonitorEventNew; + virDomainQemuMonitorEventStateRegisterID; + virHostdevIsMdevDevice; + virHostdevIsPCIDevice; ++virHostdevIsPCIDeviceWithIOMMUFD; + virHostdevIsSCSIDevice; + + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 7e32325fa0..3bd81c55b3 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7732,10 +7732,7 @@ qemuProcessOpenVfioFds(virDomainObj *vm) + for (i = 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; + +- if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && +- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && +- hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO && +- hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) { ++ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { + /* Open VFIO device FD */ + if (qemuProcessOpenVfioDeviceFd(hostdev) < 0) + return -1; +-- +2.53.0 diff --git a/libvirt-iommufd-fix-FD-leak-in-case-of-error.patch b/libvirt-iommufd-fix-FD-leak-in-case-of-error.patch new file mode 100644 index 0000000..ef48424 --- /dev/null +++ b/libvirt-iommufd-fix-FD-leak-in-case-of-error.patch @@ -0,0 +1,38 @@ +From a07ea47ade888579a3ceb1699a2e029c699fda4f Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Tue, 17 Feb 2026 08:38:07 +0100 +Subject: [PATCH] iommufd: fix FD leak in case of error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reported-by: coverity +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit f37e14119c257281eab4fd1fed1b1018fe4f63b1) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/util/viriommufd.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c +index 1f3353eab4..b62d59241d 100644 +--- a/src/util/viriommufd.c ++++ b/src/util/viriommufd.c +@@ -87,8 +87,10 @@ virIOMMUFDOpenDevice(void) + if ((fd = open(VIR_IOMMU_DEV_PATH, O_RDWR | O_CLOEXEC)) < 0) + virReportSystemError(errno, "%s", _("cannot open IOMMUFD device")); + +- if (virIOMMUFDSetRLimitMode(fd, true) < 0) ++ if (virIOMMUFDSetRLimitMode(fd, true) < 0) { ++ VIR_FORCE_CLOSE(fd); + return -1; ++ } + + return fd; + } +-- +2.53.0 diff --git a/libvirt-qemu-Convert-IOMMUFD-to-qemuFDPassDirect.patch b/libvirt-qemu-Convert-IOMMUFD-to-qemuFDPassDirect.patch new file mode 100644 index 0000000..e101139 --- /dev/null +++ b/libvirt-qemu-Convert-IOMMUFD-to-qemuFDPassDirect.patch @@ -0,0 +1,125 @@ +From 48ae2b31930d1b5203c88acd6498893948aa2674 Mon Sep 17 00:00:00 2001 +Message-ID: <48ae2b31930d1b5203c88acd6498893948aa2674.1771423659.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 19:42:39 +0100 +Subject: [PATCH] qemu: Convert IOMMUFD to qemuFDPassDirect + +This cleans up creating QEMU command line and makes it easier when +adding hotplug support. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit df59beed37db5451a44955c1c440eebc474bffb2) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_command.c | 7 ++----- + src/qemu/qemu_domain.c | 4 ++-- + src/qemu/qemu_domain.h | 2 +- + src/qemu/qemu_process.c | 6 ++++-- + tests/qemuxmlconftest.c | 6 ++++-- + 5 files changed, 13 insertions(+), 12 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 3119191413..443780eff5 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -5350,19 +5350,16 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd, + virDomainObj *vm) + { + qemuDomainObjPrivate *priv = vm->privateData; +- g_autofree char *fdstr = g_strdup_printf("%d", priv->iommufd); + g_autoptr(virJSONValue) props = NULL; + + if (!virDomainDefHasPCIHostdevWithIOMMUFD(def)) + return 0; + +- virCommandPassFD(cmd, priv->iommufd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); +- +- priv->iommufd = -1; ++ qemuFDPassDirectTransferCommand(priv->iommufd, cmd); + + if (qemuMonitorCreateObjectProps(&props, "iommufd", + "iommufd0", +- "S:fd", fdstr, ++ "S:fd", qemuFDPassDirectGetPath(priv->iommufd), + NULL) < 0) + return -1; + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 64b01e524f..d9cd9324e0 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -1975,7 +1975,7 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivate *priv) + + priv->migrationRecoverSetup = false; + +- VIR_FORCE_CLOSE(priv->iommufd); ++ g_clear_pointer(&priv->iommufd, qemuFDPassDirectFree); + + g_clear_pointer(&priv->memoryBackingDir, g_free); + } +@@ -2044,7 +2044,7 @@ qemuDomainObjPrivateAlloc(void *opaque) + priv->blockjobs = virHashNew(virObjectUnref); + priv->fds = virHashNew(g_object_unref); + +- priv->iommufd = -1; ++ priv->iommufd = NULL; + priv->pidMonitored = -1; + + /* agent commands block by default, user can choose different behavior */ +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 30ca67bf76..a5403ecc93 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -264,7 +264,7 @@ struct _qemuDomainObjPrivate { + /* named file descriptor groups associated with the VM */ + GHashTable *fds; + +- int iommufd; ++ qemuFDPassDirect *iommufd; + + char *memoryBackingDir; + }; +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 3729edcd7e..91167d73bc 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7685,13 +7685,15 @@ static int + qemuProcessOpenIommuFd(virDomainObj *vm) + { + qemuDomainObjPrivate *priv = vm->privateData; ++ int iommufd; + + VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name); + +- if ((priv->iommufd = virIOMMUFDOpenDevice()) < 0) ++ if ((iommufd = virIOMMUFDOpenDevice()) < 0) + return -1; + +- VIR_DEBUG("Opened IOMMU FD %d for domain %s", priv->iommufd, vm->def->name); ++ priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd); ++ + return 0; + } + +diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c +index 6f16b6cee8..b58bdc1f80 100644 +--- a/tests/qemuxmlconftest.c ++++ b/tests/qemuxmlconftest.c +@@ -406,8 +406,10 @@ testQemuPrepareHostdev(virDomainObj *vm) + } + } + +- if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) +- priv->iommufd = 0; ++ if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) { ++ int iommufd = 0; ++ priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd); ++ } + } + + +-- +2.53.0 diff --git a/libvirt-qemu-Convert-vfioDeviceFd-to-qemuFDPassDirect.patch b/libvirt-qemu-Convert-vfioDeviceFd-to-qemuFDPassDirect.patch new file mode 100644 index 0000000..b667693 --- /dev/null +++ b/libvirt-qemu-Convert-vfioDeviceFd-to-qemuFDPassDirect.patch @@ -0,0 +1,129 @@ +From f0bc052ed97cd00f6d3da0493bb33b95db93a776 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 19:28:16 +0100 +Subject: [PATCH] qemu: Convert vfioDeviceFd to qemuFDPassDirect + +This cleans up creating QEMU command line and makes it easier when +adding hotplug support. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 4611f227c7882c8b9237da5e2fab21932ef6bd51) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_command.c | 15 +++++---------- + src/qemu/qemu_domain.c | 4 ++-- + src/qemu/qemu_domain.h | 2 +- + src/qemu/qemu_process.c | 6 +++++- + tests/qemuxmlconftest.c | 4 +++- + 5 files changed, 16 insertions(+), 15 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 443780eff5..33127fbc0a 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -4811,12 +4811,10 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, + pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_YES) { + qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev); + +- if (hostdevPriv->vfioDeviceFd != -1) { +- g_autofree char *fdstr = g_strdup_printf("%d", hostdevPriv->vfioDeviceFd); +- if (virJSONValueObjectAdd(&props, "S:fd", fdstr, NULL) < 0) +- return NULL; +- hostdevPriv->vfioDeviceFd = -1; +- } ++ if (virJSONValueObjectAdd(&props, ++ "S:fd", qemuFDPassDirectGetPath(hostdevPriv->vfioDeviceFd), ++ NULL) < 0) ++ return NULL; + } + + if (qemuBuildDeviceAddressProps(props, def, dev->info) < 0) +@@ -5266,10 +5264,7 @@ qemuBuildHostdevCommandLine(virCommand *cmd, + if (subsys->u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) { + qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); + +- if (hostdevPriv->vfioDeviceFd != -1) { +- virCommandPassFD(cmd, hostdevPriv->vfioDeviceFd, +- VIR_COMMAND_PASS_FD_CLOSE_PARENT); +- } ++ qemuFDPassDirectTransferCommand(hostdevPriv->vfioDeviceFd, cmd); + } + + if (!(devprops = qemuBuildPCIHostdevDevProps(def, hostdev))) +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index d9cd9324e0..ada9d3431c 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -1245,7 +1245,7 @@ qemuDomainHostdevPrivateDispose(void *obj) + { + qemuDomainHostdevPrivate *priv = obj; + +- VIR_FORCE_CLOSE(priv->vfioDeviceFd); ++ g_clear_pointer(&priv->vfioDeviceFd, qemuFDPassDirectFree); + } + + +@@ -1271,7 +1271,7 @@ qemuDomainHostdevPrivateNew(void) + if (!(priv = virObjectNew(qemuDomainHostdevPrivateClass))) + return NULL; + +- priv->vfioDeviceFd = -1; ++ priv->vfioDeviceFd = NULL; + + return (virObject *) priv; + } +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index a5403ecc93..8aa94fc25b 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -471,7 +471,7 @@ struct _qemuDomainHostdevPrivate { + virObject parent; + + /* VFIO device file descriptor for iommufd passthrough */ +- int vfioDeviceFd; ++ qemuFDPassDirect *vfioDeviceFd; + }; + + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 91167d73bc..59fff1aa19 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7710,10 +7710,14 @@ qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) + { + qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); + virDomainHostdevSubsysPCI *pci = &hostdev->source.subsys.u.pci; ++ g_autofree char *name = g_strdup_printf("hostdev-%s-fd", hostdev->info->alias); ++ int vfioDeviceFd; + +- if ((hostdevPriv->vfioDeviceFd = virPCIDeviceOpenVfioFd(&pci->addr)) < 0) ++ if ((vfioDeviceFd = virPCIDeviceOpenVfioFd(&pci->addr)) < 0) + return -1; + ++ hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFd); ++ + return 0; + } + +diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c +index b58bdc1f80..bddd659fd4 100644 +--- a/tests/qemuxmlconftest.c ++++ b/tests/qemuxmlconftest.c +@@ -357,8 +357,10 @@ testQemuPrepareHostdevPCI(virDomainHostdevDef *hostdev) + qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); + + if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { ++ g_autofree char *name = g_strdup_printf("hostdev-%s-fd", hostdev->info->alias); + /* Use a placeholder FD value for tests */ +- hostdevPriv->vfioDeviceFd = 0; ++ int vfioDeviceFD = 0; ++ hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFD); + } + } + +-- +2.53.0 diff --git a/libvirt-qemu-Fill-iommufd-domain-capability.patch b/libvirt-qemu-Fill-iommufd-domain-capability.patch new file mode 100644 index 0000000..de355e6 --- /dev/null +++ b/libvirt-qemu-Fill-iommufd-domain-capability.patch @@ -0,0 +1,1257 @@ +From 39012db60da1f09027c4aa016ddf1c7da9b3d73d Mon Sep 17 00:00:00 2001 +Message-ID: <39012db60da1f09027c4aa016ddf1c7da9b3d73d.1771423659.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Mon, 16 Feb 2026 10:44:57 +0100 +Subject: [PATCH] qemu: Fill iommufd domain capability + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 63434db800b921e96fec424a667b7161af1f02de) + +Conflicts: + These files don't exist in downstream: + tests/domaincapsdata/qemu_10.1.0.s390x.xml + tests/domaincapsdata/qemu_10.2.0-virt.aarch64.xml + tests/domaincapsdata/qemu_10.2.0.aarch64.xml + tests/domaincapsdata/qemu_11.0.0-q35.x86_64.xml + tests/domaincapsdata/qemu_11.0.0-tcg.x86_64.xml + tests/domaincapsdata/qemu_11.0.0-virt.aarch64.xml + tests/domaincapsdata/qemu_11.0.0.aarch64.xml + tests/domaincapsdata/qemu_11.0.0.x86_64.xml + +Resolves: https://issues.redhat.com/browse/RHEL-148135 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_capabilities.c | 21 ++++++++++++++----- + .../qemu_10.0.0-q35.x86_64+amdsev.xml | 4 ++++ + .../domaincapsdata/qemu_10.0.0-q35.x86_64.xml | 4 ++++ + .../qemu_10.0.0-tcg.x86_64+amdsev.xml | 4 ++++ + .../domaincapsdata/qemu_10.0.0-tcg.x86_64.xml | 4 ++++ + .../qemu_10.0.0-virt.aarch64.xml | 4 ++++ + tests/domaincapsdata/qemu_10.0.0.aarch64.xml | 4 ++++ + tests/domaincapsdata/qemu_10.0.0.ppc64.xml | 3 +++ + tests/domaincapsdata/qemu_10.0.0.s390x.xml | 4 ++++ + .../qemu_10.0.0.x86_64+amdsev.xml | 4 ++++ + tests/domaincapsdata/qemu_10.0.0.x86_64.xml | 4 ++++ + .../qemu_10.1.0-q35.x86_64+inteltdx.xml | 4 ++++ + .../domaincapsdata/qemu_10.1.0-q35.x86_64.xml | 4 ++++ + .../qemu_10.1.0-tcg.x86_64+inteltdx.xml | 4 ++++ + .../domaincapsdata/qemu_10.1.0-tcg.x86_64.xml | 4 ++++ + .../qemu_10.1.0.x86_64+inteltdx.xml | 4 ++++ + tests/domaincapsdata/qemu_10.1.0.x86_64.xml | 4 ++++ + .../qemu_10.2.0-q35.x86_64+mshv.xml | 4 ++++ + .../domaincapsdata/qemu_10.2.0-q35.x86_64.xml | 4 ++++ + .../qemu_10.2.0-tcg.x86_64+mshv.xml | 4 ++++ + .../domaincapsdata/qemu_10.2.0-tcg.x86_64.xml | 4 ++++ + .../qemu_10.2.0.x86_64+mshv.xml | 4 ++++ + tests/domaincapsdata/qemu_10.2.0.x86_64.xml | 4 ++++ + .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 3 +++ + tests/domaincapsdata/qemu_6.2.0.ppc64.xml | 3 +++ + tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml | 3 +++ + tests/domaincapsdata/qemu_7.0.0.ppc64.xml | 3 +++ + tests/domaincapsdata/qemu_7.0.0.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml | 3 +++ + tests/domaincapsdata/qemu_7.1.0.ppc64.xml | 3 +++ + tests/domaincapsdata/qemu_7.1.0.x86_64.xml | 3 +++ + .../qemu_7.2.0-hvf.x86_64+hvf.xml | 3 +++ + .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml | 3 +++ + .../qemu_7.2.0-tcg.x86_64+hvf.xml | 3 +++ + .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml | 3 +++ + tests/domaincapsdata/qemu_7.2.0.ppc.xml | 3 +++ + tests/domaincapsdata/qemu_7.2.0.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml | 3 +++ + tests/domaincapsdata/qemu_8.0.0.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml | 3 +++ + tests/domaincapsdata/qemu_8.1.0.s390x.xml | 3 +++ + tests/domaincapsdata/qemu_8.1.0.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml | 3 +++ + .../qemu_8.2.0-tcg-virt.loongarch64.xml | 3 +++ + .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml | 3 +++ + .../qemu_8.2.0-virt.aarch64.xml | 3 +++ + .../qemu_8.2.0-virt.loongarch64.xml | 3 +++ + tests/domaincapsdata/qemu_8.2.0.aarch64.xml | 3 +++ + tests/domaincapsdata/qemu_8.2.0.armv7l.xml | 3 +++ + tests/domaincapsdata/qemu_8.2.0.s390x.xml | 3 +++ + tests/domaincapsdata/qemu_8.2.0.x86_64.xml | 3 +++ + .../domaincapsdata/qemu_9.0.0-q35.x86_64.xml | 4 ++++ + .../domaincapsdata/qemu_9.0.0-tcg.x86_64.xml | 4 ++++ + tests/domaincapsdata/qemu_9.0.0.sparc.xml | 3 +++ + tests/domaincapsdata/qemu_9.0.0.x86_64.xml | 4 ++++ + .../domaincapsdata/qemu_9.1.0-q35.x86_64.xml | 4 ++++ + .../qemu_9.1.0-tcg-virt.riscv64.xml | 3 +++ + .../domaincapsdata/qemu_9.1.0-tcg.x86_64.xml | 4 ++++ + .../qemu_9.1.0-virt.riscv64.xml | 3 +++ + tests/domaincapsdata/qemu_9.1.0.s390x.xml | 4 ++++ + tests/domaincapsdata/qemu_9.1.0.x86_64.xml | 4 ++++ + .../qemu_9.2.0-hvf.aarch64+hvf.xml | 3 +++ + .../qemu_9.2.0-q35.x86_64+amdsev.xml | 4 ++++ + .../domaincapsdata/qemu_9.2.0-q35.x86_64.xml | 4 ++++ + .../qemu_9.2.0-tcg.x86_64+amdsev.xml | 4 ++++ + .../domaincapsdata/qemu_9.2.0-tcg.x86_64.xml | 4 ++++ + tests/domaincapsdata/qemu_9.2.0.s390x.xml | 4 ++++ + .../qemu_9.2.0.x86_64+amdsev.xml | 4 ++++ + tests/domaincapsdata/qemu_9.2.0.x86_64.xml | 4 ++++ + tests/domaincapsmock.c | 17 ++++++++++++++- + 76 files changed, 289 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index c23ff5539a..ed6aa86da2 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -45,6 +45,7 @@ + #include "qemu_firmware.h" + #include "virutil.h" + #include "virtpm.h" ++#include "viriommufd.h" + + #include + #include +@@ -6777,6 +6778,7 @@ virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCaps *qemuCaps, + hostdev->subsysType.report = true; + hostdev->capsType.report = true; + hostdev->pciBackend.report = true; ++ hostdev->iommufd.report = true; + + /* VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES is for containers only */ + VIR_DOMAIN_CAPS_ENUM_SET(hostdev->mode, +@@ -6808,11 +6810,20 @@ virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCaps *qemuCaps, + virDomainCapsEnumClear(&hostdev->capsType); + + virDomainCapsEnumClear(&hostdev->pciBackend); +- if (supportsPassthroughVFIO && +- virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { +- VIR_DOMAIN_CAPS_ENUM_SET(hostdev->pciBackend, +- VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT, +- VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO); ++ ++ VIR_DOMAIN_CAPS_ENUM_SET(hostdev->iommufd, VIR_TRISTATE_BOOL_NO); ++ ++ if (supportsPassthroughVFIO) { ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { ++ VIR_DOMAIN_CAPS_ENUM_SET(hostdev->pciBackend, ++ VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT, ++ VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO); ++ } ++ ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOMMUFD) && ++ virIOMMUFDSupported()) { ++ VIR_DOMAIN_CAPS_ENUM_SET(hostdev->iommufd, VIR_TRISTATE_BOOL_YES); ++ } + } + } + +diff --git a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml +index 8cb51d795c..aeccdf612d 100644 +--- a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml ++++ b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml +@@ -856,6 +856,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml +index 56192354ac..86a740099b 100644 +--- a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml +@@ -1755,6 +1755,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64+amdsev.xml +index 4242f2fe9c..5d9ce948f8 100644 +--- a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64+amdsev.xml ++++ b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64+amdsev.xml +@@ -1840,6 +1840,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml +index 76d5fdd0d9..3915ec38cf 100644 +--- a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml +@@ -1840,6 +1840,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.0.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_10.0.0-virt.aarch64.xml +index 30863d3d6b..058bd84a33 100644 +--- a/tests/domaincapsdata/qemu_10.0.0-virt.aarch64.xml ++++ b/tests/domaincapsdata/qemu_10.0.0-virt.aarch64.xml +@@ -154,6 +154,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.0.0.aarch64.xml b/tests/domaincapsdata/qemu_10.0.0.aarch64.xml +index 30863d3d6b..058bd84a33 100644 +--- a/tests/domaincapsdata/qemu_10.0.0.aarch64.xml ++++ b/tests/domaincapsdata/qemu_10.0.0.aarch64.xml +@@ -154,6 +154,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.0.0.ppc64.xml b/tests/domaincapsdata/qemu_10.0.0.ppc64.xml +index 5136e7a20d..f3ff165aa1 100644 +--- a/tests/domaincapsdata/qemu_10.0.0.ppc64.xml ++++ b/tests/domaincapsdata/qemu_10.0.0.ppc64.xml +@@ -107,6 +107,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.0.0.s390x.xml b/tests/domaincapsdata/qemu_10.0.0.s390x.xml +index 3bbdbd68d0..220afb9d7d 100644 +--- a/tests/domaincapsdata/qemu_10.0.0.s390x.xml ++++ b/tests/domaincapsdata/qemu_10.0.0.s390x.xml +@@ -283,6 +283,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml +index 8b02db8802..9dcc7f2e44 100644 +--- a/tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml ++++ b/tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml +@@ -856,6 +856,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.0.0.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0.x86_64.xml +index 6dac17808c..c0c3a2e6db 100644 +--- a/tests/domaincapsdata/qemu_10.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_10.0.0.x86_64.xml +@@ -1755,6 +1755,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml +index e3170bf2b3..346a94c1ec 100644 +--- a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml ++++ b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml +@@ -860,6 +860,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64.xml +index 6213908152..fc82987630 100644 +--- a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64.xml +@@ -2100,6 +2100,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml +index 949b85bd25..07fe65d429 100644 +--- a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml ++++ b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml +@@ -2088,6 +2088,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64.xml +index 804848b8a7..34e5812613 100644 +--- a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64.xml +@@ -2226,6 +2226,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml +index 93ce017e97..1d476275a2 100644 +--- a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml ++++ b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml +@@ -860,6 +860,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.1.0.x86_64.xml b/tests/domaincapsdata/qemu_10.1.0.x86_64.xml +index 35c9b8c6d3..3be5e34fe6 100644 +--- a/tests/domaincapsdata/qemu_10.1.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_10.1.0.x86_64.xml +@@ -2100,6 +2100,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64+mshv.xml b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64+mshv.xml +index ebba8fd49f..6914726a8b 100644 +--- a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64+mshv.xml ++++ b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64+mshv.xml +@@ -110,6 +110,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64.xml +index 78e8b774e6..baf8f458db 100644 +--- a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64.xml +@@ -1072,6 +1072,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.2.0-tcg.x86_64+mshv.xml b/tests/domaincapsdata/qemu_10.2.0-tcg.x86_64+mshv.xml +index 6c6f1e84c3..35331dc4d4 100644 +--- a/tests/domaincapsdata/qemu_10.2.0-tcg.x86_64+mshv.xml ++++ b/tests/domaincapsdata/qemu_10.2.0-tcg.x86_64+mshv.xml +@@ -2223,6 +2223,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_10.2.0-tcg.x86_64.xml +index 14e8e30f1c..7fba7f45f3 100644 +--- a/tests/domaincapsdata/qemu_10.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_10.2.0-tcg.x86_64.xml +@@ -2226,6 +2226,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.2.0.x86_64+mshv.xml b/tests/domaincapsdata/qemu_10.2.0.x86_64+mshv.xml +index c8f2585d7d..faf9b15e0d 100644 +--- a/tests/domaincapsdata/qemu_10.2.0.x86_64+mshv.xml ++++ b/tests/domaincapsdata/qemu_10.2.0.x86_64+mshv.xml +@@ -110,6 +110,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_10.2.0.x86_64.xml b/tests/domaincapsdata/qemu_10.2.0.x86_64.xml +index 59370259e7..354653d49a 100644 +--- a/tests/domaincapsdata/qemu_10.2.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_10.2.0.x86_64.xml +@@ -1072,6 +1072,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml +index b14cbddc59..0b66b77e73 100644 +--- a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml +@@ -1060,6 +1060,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml +index 51547bf505..ce4b14f28c 100644 +--- a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml +@@ -1862,6 +1862,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_6.2.0.ppc64.xml b/tests/domaincapsdata/qemu_6.2.0.ppc64.xml +index 411925ad66..fb8361ae97 100644 +--- a/tests/domaincapsdata/qemu_6.2.0.ppc64.xml ++++ b/tests/domaincapsdata/qemu_6.2.0.ppc64.xml +@@ -108,6 +108,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml +index ab387c862e..33b2e4905e 100644 +--- a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml +@@ -1060,6 +1060,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml +index 4bbcb516ec..2d7519ae94 100644 +--- a/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml +@@ -1089,6 +1089,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml +index 839f0600c2..01975a5e34 100644 +--- a/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml +@@ -1888,6 +1888,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.0.0.ppc64.xml b/tests/domaincapsdata/qemu_7.0.0.ppc64.xml +index 147d1bf7fb..03bbe16497 100644 +--- a/tests/domaincapsdata/qemu_7.0.0.ppc64.xml ++++ b/tests/domaincapsdata/qemu_7.0.0.ppc64.xml +@@ -110,6 +110,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.0.0.x86_64.xml b/tests/domaincapsdata/qemu_7.0.0.x86_64.xml +index 612b5a44cc..8fa3d3e0f4 100644 +--- a/tests/domaincapsdata/qemu_7.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_7.0.0.x86_64.xml +@@ -1089,6 +1089,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml +index a031b673dd..1991133a62 100644 +--- a/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml +@@ -1056,6 +1056,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml +index 9360f8fadf..41bfdbecb6 100644 +--- a/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml +@@ -1836,6 +1836,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.1.0.ppc64.xml b/tests/domaincapsdata/qemu_7.1.0.ppc64.xml +index f3a2dfe6ff..03d6b23a45 100644 +--- a/tests/domaincapsdata/qemu_7.1.0.ppc64.xml ++++ b/tests/domaincapsdata/qemu_7.1.0.ppc64.xml +@@ -103,6 +103,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.1.0.x86_64.xml b/tests/domaincapsdata/qemu_7.1.0.x86_64.xml +index 6738d8f852..54e8e9d87a 100644 +--- a/tests/domaincapsdata/qemu_7.1.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_7.1.0.x86_64.xml +@@ -1056,6 +1056,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.2.0-hvf.x86_64+hvf.xml b/tests/domaincapsdata/qemu_7.2.0-hvf.x86_64+hvf.xml +index b338bcc470..58ef1bde99 100644 +--- a/tests/domaincapsdata/qemu_7.2.0-hvf.x86_64+hvf.xml ++++ b/tests/domaincapsdata/qemu_7.2.0-hvf.x86_64+hvf.xml +@@ -1061,6 +1061,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml +index 39eb10dc7a..7c325b52aa 100644 +--- a/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml +@@ -1061,6 +1061,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64+hvf.xml b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64+hvf.xml +index 77fce0eb95..27ecea6fe0 100644 +--- a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64+hvf.xml ++++ b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64+hvf.xml +@@ -1541,6 +1541,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml +index 77fce0eb95..27ecea6fe0 100644 +--- a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml +@@ -1541,6 +1541,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.2.0.ppc.xml b/tests/domaincapsdata/qemu_7.2.0.ppc.xml +index 8bda6af431..7cbde763ef 100644 +--- a/tests/domaincapsdata/qemu_7.2.0.ppc.xml ++++ b/tests/domaincapsdata/qemu_7.2.0.ppc.xml +@@ -102,6 +102,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_7.2.0.x86_64.xml b/tests/domaincapsdata/qemu_7.2.0.x86_64.xml +index 16708c3d85..b9a174368a 100644 +--- a/tests/domaincapsdata/qemu_7.2.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_7.2.0.x86_64.xml +@@ -1061,6 +1061,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml +index 4acd9b76b2..60893adebf 100644 +--- a/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml +@@ -1143,6 +1143,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml +index c8efc8f183..23e41eb13c 100644 +--- a/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml +@@ -1636,6 +1636,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.0.0.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0.x86_64.xml +index cfa00f3150..daa91d428f 100644 +--- a/tests/domaincapsdata/qemu_8.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_8.0.0.x86_64.xml +@@ -1143,6 +1143,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml +index 83a703da52..df003825ea 100644 +--- a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml +@@ -1402,6 +1402,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml +index 725002966d..10330281bd 100644 +--- a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml +@@ -1658,6 +1658,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.1.0.s390x.xml b/tests/domaincapsdata/qemu_8.1.0.s390x.xml +index 0872931dd7..c86f0113f3 100644 +--- a/tests/domaincapsdata/qemu_8.1.0.s390x.xml ++++ b/tests/domaincapsdata/qemu_8.1.0.s390x.xml +@@ -371,6 +371,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml +index 6a3cb84342..205334e84b 100644 +--- a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml +@@ -1402,6 +1402,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml +index a25cf01799..bd9dbf8cba 100644 +--- a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml +@@ -1403,6 +1403,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.2.0-tcg-virt.loongarch64.xml b/tests/domaincapsdata/qemu_8.2.0-tcg-virt.loongarch64.xml +index eead5ff076..10e514dd45 100644 +--- a/tests/domaincapsdata/qemu_8.2.0-tcg-virt.loongarch64.xml ++++ b/tests/domaincapsdata/qemu_8.2.0-tcg-virt.loongarch64.xml +@@ -106,6 +106,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml +index 3b986eb386..60e5cb8632 100644 +--- a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml +@@ -1624,6 +1624,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.2.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_8.2.0-virt.aarch64.xml +index bb563d6e6c..f67204a14c 100644 +--- a/tests/domaincapsdata/qemu_8.2.0-virt.aarch64.xml ++++ b/tests/domaincapsdata/qemu_8.2.0-virt.aarch64.xml +@@ -154,6 +154,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.2.0-virt.loongarch64.xml b/tests/domaincapsdata/qemu_8.2.0-virt.loongarch64.xml +index 4d441289a4..6e05a09abb 100644 +--- a/tests/domaincapsdata/qemu_8.2.0-virt.loongarch64.xml ++++ b/tests/domaincapsdata/qemu_8.2.0-virt.loongarch64.xml +@@ -110,6 +110,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.2.0.aarch64.xml b/tests/domaincapsdata/qemu_8.2.0.aarch64.xml +index bb563d6e6c..f67204a14c 100644 +--- a/tests/domaincapsdata/qemu_8.2.0.aarch64.xml ++++ b/tests/domaincapsdata/qemu_8.2.0.aarch64.xml +@@ -154,6 +154,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.2.0.armv7l.xml b/tests/domaincapsdata/qemu_8.2.0.armv7l.xml +index 5c467d4a14..7a537a1abc 100644 +--- a/tests/domaincapsdata/qemu_8.2.0.armv7l.xml ++++ b/tests/domaincapsdata/qemu_8.2.0.armv7l.xml +@@ -104,6 +104,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.2.0.s390x.xml b/tests/domaincapsdata/qemu_8.2.0.s390x.xml +index 5126dd4d00..ad80492e30 100644 +--- a/tests/domaincapsdata/qemu_8.2.0.s390x.xml ++++ b/tests/domaincapsdata/qemu_8.2.0.s390x.xml +@@ -372,6 +372,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml +index 57cd4d63de..c6558915c1 100644 +--- a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml +@@ -1403,6 +1403,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml +index c7932014ad..930014727d 100644 +--- a/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml +@@ -1403,6 +1403,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml +index 3593d70166..19adcfe249 100644 +--- a/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml +@@ -1553,6 +1553,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.0.0.sparc.xml b/tests/domaincapsdata/qemu_9.0.0.sparc.xml +index 6b4dd3c3b5..062e55718b 100644 +--- a/tests/domaincapsdata/qemu_9.0.0.sparc.xml ++++ b/tests/domaincapsdata/qemu_9.0.0.sparc.xml +@@ -90,6 +90,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.0.0.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0.x86_64.xml +index 96303a31cd..bc4e7fa1ee 100644 +--- a/tests/domaincapsdata/qemu_9.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_9.0.0.x86_64.xml +@@ -1403,6 +1403,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml +index 518a6811fe..927c1b4fab 100644 +--- a/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml +@@ -1539,6 +1539,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.1.0-tcg-virt.riscv64.xml b/tests/domaincapsdata/qemu_9.1.0-tcg-virt.riscv64.xml +index ce7fe71141..cb519f348c 100644 +--- a/tests/domaincapsdata/qemu_9.1.0-tcg-virt.riscv64.xml ++++ b/tests/domaincapsdata/qemu_9.1.0-tcg-virt.riscv64.xml +@@ -117,6 +117,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml +index 70928471b3..a8b1bfed73 100644 +--- a/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml +@@ -1658,6 +1658,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.1.0-virt.riscv64.xml b/tests/domaincapsdata/qemu_9.1.0-virt.riscv64.xml +index fabb09bf72..8e9bd3a15b 100644 +--- a/tests/domaincapsdata/qemu_9.1.0-virt.riscv64.xml ++++ b/tests/domaincapsdata/qemu_9.1.0-virt.riscv64.xml +@@ -106,6 +106,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.1.0.s390x.xml b/tests/domaincapsdata/qemu_9.1.0.s390x.xml +index d4649de513..2854713ca3 100644 +--- a/tests/domaincapsdata/qemu_9.1.0.s390x.xml ++++ b/tests/domaincapsdata/qemu_9.1.0.s390x.xml +@@ -235,6 +235,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.1.0.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0.x86_64.xml +index ee101364cc..e4d36b95ac 100644 +--- a/tests/domaincapsdata/qemu_9.1.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_9.1.0.x86_64.xml +@@ -1539,6 +1539,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml b/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml +index ae657c7f72..db51e7b120 100644 +--- a/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml ++++ b/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml +@@ -151,6 +151,9 @@ + default + vfio + ++ ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml +index 35dc5785bc..39bdb2615b 100644 +--- a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml ++++ b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml +@@ -736,6 +736,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml +index baaaf4f91c..cc31c01dee 100644 +--- a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml +@@ -1597,6 +1597,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml +index 033004a1f4..d01e029394 100644 +--- a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml ++++ b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml +@@ -1705,6 +1705,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml +index f20fe882c6..6088c4b905 100644 +--- a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml +@@ -1705,6 +1705,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.2.0.s390x.xml b/tests/domaincapsdata/qemu_9.2.0.s390x.xml +index 21a1b4f5a9..ef379afe69 100644 +--- a/tests/domaincapsdata/qemu_9.2.0.s390x.xml ++++ b/tests/domaincapsdata/qemu_9.2.0.s390x.xml +@@ -235,6 +235,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml b/tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml +index 39390d2ab6..c0485f8ffa 100644 +--- a/tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml ++++ b/tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml +@@ -736,6 +736,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsdata/qemu_9.2.0.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0.x86_64.xml +index c477a1d2c4..dcb78a93c6 100644 +--- a/tests/domaincapsdata/qemu_9.2.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_9.2.0.x86_64.xml +@@ -1597,6 +1597,10 @@ + default + vfio + ++ ++ yes ++ no ++ + + + +diff --git a/tests/domaincapsmock.c b/tests/domaincapsmock.c +index 7bece6c8c1..370ce35709 100644 +--- a/tests/domaincapsmock.c ++++ b/tests/domaincapsmock.c +@@ -16,11 +16,13 @@ + + #include + ++#include "virfile.h" + #include "virhostcpu.h" + #include "virhostmem.h" ++#include "viriommufd.h" ++#include "virmock.h" + + #if WITH_QEMU +-# include "virmock.h" + # include "qemu/qemu_capabilities.h" + #endif + +@@ -78,3 +80,16 @@ virHostMemGetTHPSize(unsigned long long *size) + *size = 2048; + return 0; + } ++ ++static bool (*real_virFileExists)(const char *path); ++ ++bool ++virFileExists(const char *path) ++{ ++ VIR_MOCK_REAL_INIT(virFileExists); ++ ++ if (STREQ(path, VIR_IOMMU_DEV_PATH)) ++ return true; ++ ++ return real_virFileExists(path); ++} +-- +2.53.0 diff --git a/libvirt-qemu-Introduce-QEMU_CAPS_OBJECT_IOMMUFD.patch b/libvirt-qemu-Introduce-QEMU_CAPS_OBJECT_IOMMUFD.patch new file mode 100644 index 0000000..8fdc8af --- /dev/null +++ b/libvirt-qemu-Introduce-QEMU_CAPS_OBJECT_IOMMUFD.patch @@ -0,0 +1,266 @@ +From 13871e41d1697608a55fa40d3855193a636109bb Mon Sep 17 00:00:00 2001 +Message-ID: <13871e41d1697608a55fa40d3855193a636109bb.1771423658.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Mon, 16 Feb 2026 08:59:39 +0100 +Subject: [PATCH] qemu: Introduce QEMU_CAPS_OBJECT_IOMMUFD + +Detect if QEMU was compiled with IOMMUFD. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 4a0ea9bcf13ea05c90f294ba70c767bc79e2ebbe) + +Conflicts: + These files don't exist in downstream: + tests/qemucapabilitiesdata/caps_10.1.0_s390x.xml + tests/qemucapabilitiesdata/caps_10.2.0_aarch64.xml + tests/qemucapabilitiesdata/caps_11.0.0_aarch64.xml + tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_capabilities.c | 4 ++++ + src/qemu/qemu_capabilities.h | 3 +++ + src/qemu/qemu_validate.c | 8 ++++++++ + tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml | 1 + + tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml | 1 + + tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml | 1 + + tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml | 1 + + .../qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml | 1 + + tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml | 1 + + tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml | 1 + + tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml | 1 + + tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml | 1 + + tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml | 1 + + tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml | 1 + + tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml | 1 + + tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml | 1 + + tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml | 1 + + 17 files changed, 29 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 2c8bd62c99..c23ff5539a 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -756,6 +756,9 @@ VIR_ENUM_IMPL(virQEMUCaps, + "query-accelerators", /* QEMU_CAPS_QUERY_ACCELERATORS */ + "mshv", /* QEMU_CAPS_MSHV */ + "scsi-block.migrate-pr", /* QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR */ ++ ++ /* 490 */ ++ "iommufd", /* QEMU_CAPS_OBJECT_IOMMUFD */ + ); + + +@@ -1463,6 +1466,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { + { "tpm-emulator", QEMU_CAPS_DEVICE_TPM_EMULATOR }, + { "tpm-passthrough", QEMU_CAPS_DEVICE_TPM_PASSTHROUGH }, + { "acpi-generic-initiator", QEMU_CAPS_ACPI_GENERIC_INITIATOR }, ++ { "iommufd", QEMU_CAPS_OBJECT_IOMMUFD }, + }; + + +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 0c76f2edda..f7c8680f94 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -732,6 +732,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + QEMU_CAPS_MSHV, /* -accel mshv */ + QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, /* persistent reservation migration support */ + ++ /* 490 */ ++ QEMU_CAPS_OBJECT_IOMMUFD, /* -object iommufd */ ++ + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; + +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index a3dbd9a33b..18f148f48c 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -2723,6 +2723,14 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, + _("VFIO PCI device assignment is not supported by this version of qemu")); + return -1; + } ++ ++ if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) { ++ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOMMUFD)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("IOMMUFD is not supported by this version of qemu")); ++ return -1; ++ } ++ } + } + + if (hostdev->writeFiltering != VIR_TRISTATE_BOOL_ABSENT) { +diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml +index 90e8d868cc..bbb8b33cde 100644 +--- a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml ++++ b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.xml +@@ -163,6 +163,7 @@ + + + ++ + 10000000 + 61700285 + v10.0.0 +diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml +index 82a66a6524..cf00ac4ea0 100644 +--- a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.xml +@@ -136,6 +136,7 @@ + + + ++ + 10000000 + 39100285 + v10.0.0 +diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml +index cfce1c963d..5acd1a33fd 100644 +--- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml ++++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.xml +@@ -209,6 +209,7 @@ + + + ++ + 10000000 + 43100285 + v10.0.0 +diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml +index f94c8388d6..50f58791e6 100644 +--- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml +@@ -209,6 +209,7 @@ + + + ++ + 10000000 + 43100285 + v10.0.0 +diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml +index 8e989a139f..e321c352a3 100644 +--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml ++++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml +@@ -191,6 +191,7 @@ + + + ++ + 10000050 + 43100286 + v10.0.0-1724-gf9a3def17b +diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml +index 520a3d8ee8..2d52659520 100644 +--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml +@@ -214,6 +214,7 @@ + + + ++ + 10001000 + 43100286 + v10.1.0 +diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml +index 874fd7bddb..eb2ab001a6 100644 +--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml ++++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.xml +@@ -201,6 +201,7 @@ + + + ++ + 10001050 + 43100287 + v10.1.0-1778-ge090e0312d +diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml +index 7d5a75ce88..c4ea924c1f 100644 +--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml +@@ -216,6 +216,7 @@ + + + ++ + 10001091 + 43100287 + v10.2.0-rc1-38-gfb241d0a1f +diff --git a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml +index 1f2e27a218..88bd502fee 100644 +--- a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml +@@ -204,6 +204,7 @@ + + + ++ + 9000000 + 43100245 + v9.0.0 +diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml +index b961f79808..3d2692b02c 100644 +--- a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml +@@ -126,6 +126,7 @@ + + + ++ + 9001000 + 39100246 + v9.1.0 +diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml +index 35ddf30736..66578099a7 100644 +--- a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml +@@ -203,6 +203,7 @@ + + + ++ + 9001000 + 43100246 + v9.1.0 +diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml +index e9f79261f7..9f95ed891e 100644 +--- a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml +@@ -129,6 +129,7 @@ + + + ++ + 9002000 + 39100247 + v9.2.0 +diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml +index 0e52c3e23d..6636346bc5 100644 +--- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml ++++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.xml +@@ -207,6 +207,7 @@ + + + ++ + 9002000 + 43100247 + v9.2.0 +diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml +index 95f8a4d878..dee30415aa 100644 +--- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml +@@ -205,6 +205,7 @@ + + + ++ + 9002000 + 43100247 + v9.2.0 +-- +2.53.0 diff --git a/libvirt-qemu-Move-IOMMUFD-validation-to-qemu_validate.patch b/libvirt-qemu-Move-IOMMUFD-validation-to-qemu_validate.patch new file mode 100644 index 0000000..e6c66bb --- /dev/null +++ b/libvirt-qemu-Move-IOMMUFD-validation-to-qemu_validate.patch @@ -0,0 +1,111 @@ +From cd9099d42dfaa10d7863f1615a35c48db9924191 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Mon, 16 Feb 2026 09:12:02 +0100 +Subject: [PATCH] qemu: Move IOMMUFD validation to qemu_validate + +Fail early if kernel doesn't support IOMMUFD. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 0c1af67be554d4daa2facfb647ce6e9914da2f06) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/libvirt_private.syms | 1 + + src/qemu/qemu_process.c | 8 +------- + src/qemu/qemu_validate.c | 7 +++++++ + src/util/viriommufd.c | 13 +++++++++++++ + src/util/viriommufd.h | 2 ++ + 5 files changed, 24 insertions(+), 7 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index e2a7a16347..0904265459 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2654,6 +2654,7 @@ virInitctlSetRunLevel; + + # util/viriommufd.h + virIOMMUFDSetRLimitMode; ++virIOMMUFDSupported; + + # util/viriscsi.h + virISCSIConnectionLogin; +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 37e688018c..479437fb34 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7690,13 +7690,7 @@ qemuProcessOpenIommuFd(virDomainObj *vm) + VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name); + + if ((fd = open(VIR_IOMMU_DEV_PATH, O_RDWR | O_CLOEXEC)) < 0) { +- if (errno == ENOENT) { +- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +- _("IOMMU FD support requires /dev/iommu device")); +- } else { +- virReportSystemError(errno, "%s", +- _("cannot open /dev/iommu")); +- } ++ virReportSystemError(errno, "%s", _("cannot open /dev/iommu")); + return -1; + } + +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index 18f148f48c..aa441188cb 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -27,6 +27,7 @@ + #include "qemu_process.h" + #include "domain_conf.h" + #include "virbitmap.h" ++#include "viriommufd.h" + #include "virlog.h" + #include "virutil.h" + +@@ -2730,6 +2731,12 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, + _("IOMMUFD is not supported by this version of qemu")); + return -1; + } ++ ++ if (!virIOMMUFDSupported()) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("IOMMUFD is not supported by host kernel")); ++ return -1; ++ } + } + } + +diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c +index 5af097683d..44b30029a5 100644 +--- a/src/util/viriommufd.c ++++ b/src/util/viriommufd.c +@@ -88,3 +88,16 @@ int virIOMMUFDSetRLimitMode(int fd G_GNUC_UNUSED, + } + + #endif ++ ++/** ++ * virIOMMUFDSupported: ++ * ++ * Check the presence of IOMMU device. ++ * ++ * Retruns: true if it exists, false otherwise ++ */ ++bool ++virIOMMUFDSupported(void) ++{ ++ return virFileExists(VIR_IOMMU_DEV_PATH); ++} +diff --git a/src/util/viriommufd.h b/src/util/viriommufd.h +index ebecfe3633..ec6be9fa66 100644 +--- a/src/util/viriommufd.h ++++ b/src/util/viriommufd.h +@@ -23,3 +23,5 @@ + #define VIR_IOMMU_DEV_PATH "/dev/iommu" + + int virIOMMUFDSetRLimitMode(int fd, bool processAccounting); ++ ++bool virIOMMUFDSupported(void); +-- +2.53.0 diff --git a/libvirt-qemu-Save-IOMMUFD-state-into-status-XML.patch b/libvirt-qemu-Save-IOMMUFD-state-into-status-XML.patch new file mode 100644 index 0000000..0a4de10 --- /dev/null +++ b/libvirt-qemu-Save-IOMMUFD-state-into-status-XML.patch @@ -0,0 +1,79 @@ +From 66f478cd56f2f8fbd3bca3b229a8fcafe29bbee0 Mon Sep 17 00:00:00 2001 +Message-ID: <66f478cd56f2f8fbd3bca3b229a8fcafe29bbee0.1771423659.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sat, 14 Feb 2026 17:54:57 +0100 +Subject: [PATCH] qemu: Save IOMMUFD state into status XML + +We need to track if iommufd object was added to the VM when we add +hotplug support. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit b21b6dcc72f1853f103f3cfbe1ebbcfbf128b458) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_command.c | 2 ++ + src/qemu/qemu_domain.c | 6 ++++++ + src/qemu/qemu_domain.h | 1 + + 3 files changed, 9 insertions(+) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index d11d16e533..cca5fed285 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -5359,6 +5359,8 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd, + if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0) + return -1; + ++ priv->iommufdState = true; ++ + return 0; + } + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index ada9d3431c..ccbfc8bac7 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -1976,6 +1976,7 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivate *priv) + priv->migrationRecoverSetup = false; + + g_clear_pointer(&priv->iommufd, qemuFDPassDirectFree); ++ priv->iommufdState = false; + + g_clear_pointer(&priv->memoryBackingDir, g_free); + } +@@ -2844,6 +2845,9 @@ qemuDomainObjPrivateXMLFormat(virBuffer *buf, + priv->preMigrationMemlock); + } + ++ if (priv->iommufdState) ++ virBufferAddLit(buf, "\n"); ++ + return 0; + } + +@@ -3582,6 +3586,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, + return -1; + } + ++ priv->iommufdState = virXPathBoolean("boolean(./iommufd)", ctxt) == 1; ++ + return 0; + } + +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 8aa94fc25b..62c5252b9f 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -265,6 +265,7 @@ struct _qemuDomainObjPrivate { + GHashTable *fds; + + qemuFDPassDirect *iommufd; ++ bool iommufdState; /* true if --object iommufd was added */ + + char *memoryBackingDir; + }; +-- +2.53.0 diff --git a/libvirt-qemu_command-Don-t-use-host-property-if-IOMMUFD-is-used.patch b/libvirt-qemu_command-Don-t-use-host-property-if-IOMMUFD-is-used.patch new file mode 100644 index 0000000..9692a73 --- /dev/null +++ b/libvirt-qemu_command-Don-t-use-host-property-if-IOMMUFD-is-used.patch @@ -0,0 +1,134 @@ +From 5cb651d76f287f1ae0212cf0f4d2d7618050e5d1 Mon Sep 17 00:00:00 2001 +Message-ID: <5cb651d76f287f1ae0212cf0f4d2d7618050e5d1.1771423659.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 19:49:16 +0100 +Subject: [PATCH] qemu_command: Don't use host property if IOMMUFD is used + +They should not be used at the same time. + +Fixes: f6230804727df834da27370e835204672218ab23 +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit f67e4ac4d071f6f05ae387bc3b09c6cebb10455d) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_command.c | 24 +++++++++---------- + .../iommufd-q35.x86_64-latest.args | 2 +- + ...fd-virt-pci-bus-single.aarch64-latest.args | 2 +- + .../iommufd-virt.aarch64-latest.args | 4 ++-- + .../iommufd.x86_64-latest.args | 2 +- + 5 files changed, 16 insertions(+), 18 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 33127fbc0a..d11d16e533 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -4755,10 +4755,11 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, + g_autoptr(virJSONValue) props = NULL; + virDomainHostdevSubsysPCI *pcisrc = &dev->source.subsys.u.pci; + virDomainNetTeamingInfo *teaming; +- g_autofree char *host = virPCIDeviceAddressAsString(&pcisrc->addr); ++ g_autofree char *host = NULL; + const char *failover_pair_id = NULL; + const char *driver = NULL; + const char *iommufdId = NULL; ++ const char *fdstr = NULL; + /* 'ramfb' property must be omitted unless it's to be enabled */ + bool ramfb = pcisrc->ramfb == VIR_TRISTATE_SWITCH_ON; + +@@ -4792,31 +4793,28 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, + teaming->persistent) + failover_pair_id = teaming->persistent; + +- if (pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_YES) ++ if (virHostdevIsPCIDeviceWithIOMMUFD(dev)) { ++ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev); ++ ++ fdstr = qemuFDPassDirectGetPath(hostdevPriv->vfioDeviceFd); + iommufdId = "iommufd0"; ++ } else { ++ host = virPCIDeviceAddressAsString(&pcisrc->addr); ++ } + + if (virJSONValueObjectAdd(&props, + "s:driver", driver, +- "s:host", host, ++ "S:host", host, + "s:id", dev->info->alias, + "p:bootindex", dev->info->effectiveBootIndex, + "S:failover_pair_id", failover_pair_id, + "S:display", qemuOnOffAuto(pcisrc->display), + "B:ramfb", ramfb, + "S:iommufd", iommufdId, ++ "S:fd", fdstr, + NULL) < 0) + return NULL; + +- if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO && +- pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_YES) { +- qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev); +- +- if (virJSONValueObjectAdd(&props, +- "S:fd", qemuFDPassDirectGetPath(hostdevPriv->vfioDeviceFd), +- NULL) < 0) +- return NULL; +- } +- + if (qemuBuildDeviceAddressProps(props, def, dev->info) < 0) + return NULL; + +diff --git a/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args +index d5fe704021..f886c488e1 100644 +--- a/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args +@@ -36,6 +36,6 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.config \ + -global ICH9-LPC.noreboot=off \ + -watchdog-action reset \ + -object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \ +--device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x3"}' \ ++-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x3"}' \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ + -msg timestamp=on +diff --git a/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args b/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args +index 99886468fb..d6562f9be3 100644 +--- a/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args ++++ b/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args +@@ -28,6 +28,6 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \ + -boot strict=on \ + -audiodev '{"id":"audio1","driver":"none"}' \ + -object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \ +--device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x1"}' \ ++-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x1"}' \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ + -msg timestamp=on +diff --git a/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args b/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args +index e3695c6982..9fd2a6adee 100644 +--- a/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args ++++ b/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args +@@ -31,7 +31,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \ + -device '{"driver":"pcie-root-port","port":10,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x2"}' \ + -audiodev '{"id":"audio1","driver":"none"}' \ + -object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \ +--device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.1","addr":"0x0"}' \ +--device '{"driver":"vfio-pci","host":"0000:07:12.5","id":"hostdev1","iommufd":"iommufd0","fd":"0","bus":"pci.2","addr":"0x0"}' \ ++-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.1","addr":"0x0"}' \ ++-device '{"driver":"vfio-pci","id":"hostdev1","iommufd":"iommufd0","fd":"0","bus":"pci.2","addr":"0x0"}' \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ + -msg timestamp=on +diff --git a/tests/qemuxmlconfdata/iommufd.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd.x86_64-latest.args +index 15dabe197c..b9aefda39d 100644 +--- a/tests/qemuxmlconfdata/iommufd.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/iommufd.x86_64-latest.args +@@ -29,7 +29,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \ + -device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ + -audiodev '{"id":"audio1","driver":"none"}' \ + -object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \ +--device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.0","addr":"0x3"}' \ ++-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.0","addr":"0x3"}' \ + -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ + -msg timestamp=on +-- +2.53.0 diff --git a/libvirt-qemu_command-Extract-building-IOMMUFD-props-to-function.patch b/libvirt-qemu_command-Extract-building-IOMMUFD-props-to-function.patch new file mode 100644 index 0000000..e6ba5e6 --- /dev/null +++ b/libvirt-qemu_command-Extract-building-IOMMUFD-props-to-function.patch @@ -0,0 +1,73 @@ +From e5bdfe01cb976c45a440b88061a40f65ac6f8be8 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 20:10:50 +0100 +Subject: [PATCH] qemu_command: Extract building IOMMUFD props to function + +This will be reused by hotplug code. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 3f7ad3a8a5f0e453c85f186e811e051ead0f769a) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_command.c | 20 ++++++++++++++++---- + src/qemu/qemu_command.h | 3 +++ + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index cca5fed285..521aefbc10 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -5337,6 +5337,21 @@ qemuBuildHostdevCommandLine(virCommand *cmd, + } + + ++virJSONValue * ++qemuBuildIOMMUFDProps(qemuFDPassDirect *iommufd) ++{ ++ g_autoptr(virJSONValue) props = NULL; ++ ++ if (qemuMonitorCreateObjectProps(&props, "iommufd", ++ "iommufd0", ++ "S:fd", qemuFDPassDirectGetPath(iommufd), ++ NULL) < 0) ++ return NULL; ++ ++ return g_steal_pointer(&props); ++} ++ ++ + static int + qemuBuildIOMMUFDCommandLine(virCommand *cmd, + const virDomainDef *def, +@@ -5350,10 +5365,7 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd, + + qemuFDPassDirectTransferCommand(priv->iommufd, cmd); + +- if (qemuMonitorCreateObjectProps(&props, "iommufd", +- "iommufd0", +- "S:fd", qemuFDPassDirectGetPath(priv->iommufd), +- NULL) < 0) ++ if (!(props = qemuBuildIOMMUFDProps(priv->iommufd))) + return -1; + + if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0) +diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h +index ad068f1f16..028d002ef9 100644 +--- a/src/qemu/qemu_command.h ++++ b/src/qemu/qemu_command.h +@@ -190,6 +190,9 @@ int + qemuBuildRNGBackendProps(virDomainRNGDef *rng, + virJSONValue **props); + ++virJSONValue * ++qemuBuildIOMMUFDProps(qemuFDPassDirect *iommufd); ++ + /* Current, best practice */ + virJSONValue * + qemuBuildUSBHostdevDevProps(const virDomainDef *def, +-- +2.53.0 diff --git a/libvirt-qemu_domain-Add-missing-IOMMUFD-cleanup.patch b/libvirt-qemu_domain-Add-missing-IOMMUFD-cleanup.patch new file mode 100644 index 0000000..e49bab6 --- /dev/null +++ b/libvirt-qemu_domain-Add-missing-IOMMUFD-cleanup.patch @@ -0,0 +1,33 @@ +From 31d95c7ad884094f2afd4a0f2450141cc68594ff Mon Sep 17 00:00:00 2001 +Message-ID: <31d95c7ad884094f2afd4a0f2450141cc68594ff.1771423658.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sat, 14 Feb 2026 16:12:11 +0100 +Subject: [PATCH] qemu_domain: Add missing IOMMUFD cleanup + +If starting VM fails we would leak the FD for IOMMU device. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 7c062bfc4f8c0ba853873e72d21dba77f6ca938f) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_domain.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index bdab117e96..64b01e524f 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -1975,6 +1975,8 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivate *priv) + + priv->migrationRecoverSetup = false; + ++ VIR_FORCE_CLOSE(priv->iommufd); ++ + g_clear_pointer(&priv->memoryBackingDir, g_free); + } + +-- +2.53.0 diff --git a/libvirt-qemu_hotplug-Add-support-to-hotplug-host-device-with-IOMMUFD.patch b/libvirt-qemu_hotplug-Add-support-to-hotplug-host-device-with-IOMMUFD.patch new file mode 100644 index 0000000..9fd58b7 --- /dev/null +++ b/libvirt-qemu_hotplug-Add-support-to-hotplug-host-device-with-IOMMUFD.patch @@ -0,0 +1,134 @@ +From 598a0e9ee5f59faea21f03ccb02d0830e73f975f Mon Sep 17 00:00:00 2001 +Message-ID: <598a0e9ee5f59faea21f03ccb02d0830e73f975f.1771423659.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 21:21:53 +0100 +Subject: [PATCH] qemu_hotplug: Add support to hotplug host device with IOMMUFD + +For first host device we need to add iommufd object as well. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 5d16bef1a69500791be454239e3b9ac68ec53ace) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_hotplug.c | 39 +++++++++++++++++++++++++++++++++++++++ + src/qemu/qemu_process.c | 4 ++-- + src/qemu/qemu_process.h | 3 +++ + 3 files changed, 44 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index 10ad13a416..a455c2cd53 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -1561,13 +1561,16 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver, + virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV, + { .hostdev = hostdev } }; + virDomainDeviceInfo *info = hostdev->info; ++ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); + int ret; + g_autoptr(virJSONValue) devprops = NULL; ++ g_autoptr(virJSONValue) objprops = NULL; + bool releaseaddr = false; + bool teardowncgroup = false; + bool teardownlabel = false; + bool teardowndevice = false; + bool teardownmemlock = false; ++ bool removeiommufd = false; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + unsigned int flags = 0; + +@@ -1617,11 +1620,38 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver, + goto error; + } + ++ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { ++ if (qemuProcessOpenVfioDeviceFd(hostdev) < 0) ++ goto error; ++ ++ if (!priv->iommufdState) { ++ if (qemuProcessOpenIommuFd(vm) < 0) ++ goto error; ++ ++ if (!(objprops = qemuBuildIOMMUFDProps(priv->iommufd))) ++ goto error; ++ } ++ } ++ + if (!(devprops = qemuBuildPCIHostdevDevProps(vm->def, hostdev))) + goto error; + + qemuDomainObjEnterMonitor(vm); + ++ if (objprops) { ++ if ((ret = qemuFDPassDirectTransferMonitor(priv->iommufd, priv->mon)) < 0) ++ goto exit_monitor; ++ ++ if ((ret = qemuMonitorAddObject(priv->mon, &objprops, NULL)) < 0) ++ goto exit_monitor; ++ ++ priv->iommufdState = true; ++ removeiommufd = true; ++ } ++ ++ if ((ret = qemuFDPassDirectTransferMonitor(hostdevPriv->vfioDeviceFd, priv->mon)) < 0) ++ goto exit_monitor; ++ + if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0) + goto exit_monitor; + +@@ -1652,6 +1682,15 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver, + if (teardownmemlock && qemuDomainAdjustMaxMemLock(vm) < 0) + VIR_WARN("Unable to reset maximum locked memory on hotplug fail"); + ++ if (removeiommufd) { ++ qemuDomainObjEnterMonitor(vm); ++ ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false)); ++ qemuDomainObjExitMonitor(vm); ++ } ++ ++ qemuFDPassDirectTransferMonitorRollback(hostdevPriv->vfioDeviceFd, priv->mon); ++ qemuFDPassDirectTransferMonitorRollback(priv->iommufd, priv->mon); ++ + if (releaseaddr) + qemuDomainReleaseDeviceAddress(vm, info); + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 59fff1aa19..1aff3a277b 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7681,7 +7681,7 @@ qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm, + * + * Returns: 0 on success, -1 on failure + */ +-static int ++int + qemuProcessOpenIommuFd(virDomainObj *vm) + { + qemuDomainObjPrivate *priv = vm->privateData; +@@ -7705,7 +7705,7 @@ qemuProcessOpenIommuFd(virDomainObj *vm) + * + * Returns: 0 on success, -1 on failure + */ +-static int ++int + qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) + { + qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); +diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h +index df78b00abb..1023b7cb25 100644 +--- a/src/qemu/qemu_process.h ++++ b/src/qemu/qemu_process.h +@@ -134,6 +134,9 @@ int qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm, + virDomainDeviceDef *dev) + ATTRIBUTE_MOCKABLE; + ++int qemuProcessOpenIommuFd(virDomainObj *vm); ++ ++int qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev); + + int qemuProcessPrepareHost(virQEMUDriver *driver, + virDomainObj *vm, +-- +2.53.0 diff --git a/libvirt-qemu_hotplug-Remove-iommufd-object-if-no-longer-needed.patch b/libvirt-qemu_hotplug-Remove-iommufd-object-if-no-longer-needed.patch new file mode 100644 index 0000000..752c17c --- /dev/null +++ b/libvirt-qemu_hotplug-Remove-iommufd-object-if-no-longer-needed.patch @@ -0,0 +1,40 @@ +From 2274a02bd1b2cefb48d7d66fe8db10e5c9cd853d Mon Sep 17 00:00:00 2001 +Message-ID: <2274a02bd1b2cefb48d7d66fe8db10e5c9cd853d.1771423659.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 19:57:12 +0100 +Subject: [PATCH] qemu_hotplug: Remove iommufd object if no longer needed + +When removing last host device using IOMMUFD remove the iommufd object +as well. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 300ebf01b88d154312c1a5a684be2add95dd7f31) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_hotplug.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index 9445599d2c..10ad13a416 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -4986,6 +4986,14 @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver, + } + } + ++ if (priv->iommufdState && ++ !virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) { ++ qemuDomainObjEnterMonitor(vm); ++ ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false)); ++ qemuDomainObjExitMonitor(vm); ++ priv->iommufdState = false; ++ } ++ + virDomainAuditHostdev(vm, hostdev, "detach", true); + + if (!virHostdevIsPCIDevice(hostdev) && +-- +2.53.0 diff --git a/libvirt-qemu_process-Fix-FD-leak-with-multiple-host-devices-using-IOMMUFD.patch b/libvirt-qemu_process-Fix-FD-leak-with-multiple-host-devices-using-IOMMUFD.patch new file mode 100644 index 0000000..9c0d321 --- /dev/null +++ b/libvirt-qemu_process-Fix-FD-leak-with-multiple-host-devices-using-IOMMUFD.patch @@ -0,0 +1,48 @@ +From e42d8373633488a6d67b6c895953de183b1dd495 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 19:13:19 +0100 +Subject: [PATCH] qemu_process: Fix FD leak with multiple host devices using + IOMMUFD + +We would open IOMMU device for each host device with IOMMUFD backend +leaking FD except for the last one. Since we are adding only single +iommufd object we need to open it only once. + +Fixes: 2f0999a161910e3992458902ce90d37f8b8f2642 +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit d194f362f342c22731670e365e8a2681759dbc57) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_process.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 3bd81c55b3..da7a9fc11f 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7736,13 +7736,15 @@ qemuProcessOpenVfioFds(virDomainObj *vm) + /* Open VFIO device FD */ + if (qemuProcessOpenVfioDeviceFd(hostdev) < 0) + return -1; +- +- /* Open IOMMU FD */ +- if (qemuProcessOpenIommuFd(vm) < 0) +- return -1; + } + } + ++ /* Open IOMMU FD */ ++ if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def) && ++ qemuProcessOpenIommuFd(vm) < 0) { ++ return -1; ++ } ++ + return 0; + } + +-- +2.53.0 diff --git a/libvirt-qemu_process-Refactor-qemuProcessOpenIommuFd.patch b/libvirt-qemu_process-Refactor-qemuProcessOpenIommuFd.patch new file mode 100644 index 0000000..e49302b --- /dev/null +++ b/libvirt-qemu_process-Refactor-qemuProcessOpenIommuFd.patch @@ -0,0 +1,72 @@ +From da301bafb4eb4658a0b4aae8d8b633bc9a1ef2f9 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 19:01:35 +0100 +Subject: [PATCH] qemu_process: Refactor qemuProcessOpenIommuFd + +This will allow us reusing same code for hotplug. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit ff2848827f42578115ef54a389a41798a96fd338) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_process.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index dd165512f3..71770d2099 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7676,24 +7676,23 @@ qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm, + /** + * qemuProcessOpenIommuFd: + * @vm: domain object +- * @iommuFd: returned file descriptor + * + * Opens /dev/iommu file descriptor for the VM. + * +- * Returns: FD on success, -1 on failure ++ * Returns: 0 on success, -1 on failure + */ + static int + qemuProcessOpenIommuFd(virDomainObj *vm) + { +- int fd = -1; ++ qemuDomainObjPrivate *priv = vm->privateData; + + VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name); + +- if ((fd = virIOMMUFDOpenDevice()) < 0) ++ if ((priv->iommufd = virIOMMUFDOpenDevice()) < 0) + return -1; + +- VIR_DEBUG("Opened IOMMU FD %d for domain %s", fd, vm->def->name); +- return fd; ++ VIR_DEBUG("Opened IOMMU FD %d for domain %s", priv->iommufd, vm->def->name); ++ return 0; + } + + /** +@@ -7750,7 +7749,6 @@ qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) + static int + qemuProcessOpenVfioFds(virDomainObj *vm) + { +- qemuDomainObjPrivate *priv = vm->privateData; + size_t i; + + /* Check if we have any hostdevs that need VFIO FDs */ +@@ -7768,8 +7766,7 @@ qemuProcessOpenVfioFds(virDomainObj *vm) + return -1; + + /* Open IOMMU FD */ +- priv->iommufd = qemuProcessOpenIommuFd(vm); +- if (priv->iommufd == -1) ++ if (qemuProcessOpenIommuFd(vm) < 0) + return -1; + } + } +-- +2.53.0 diff --git a/libvirt-qemu_process-Refactor-qemuProcessOpenVfioDeviceFd.patch b/libvirt-qemu_process-Refactor-qemuProcessOpenVfioDeviceFd.patch new file mode 100644 index 0000000..2454281 --- /dev/null +++ b/libvirt-qemu_process-Refactor-qemuProcessOpenVfioDeviceFd.patch @@ -0,0 +1,75 @@ +From 24f32b0d564d4c782b4a39990ef6508d9260774a Mon Sep 17 00:00:00 2001 +Message-ID: <24f32b0d564d4c782b4a39990ef6508d9260774a.1771423658.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 19:09:23 +0100 +Subject: [PATCH] qemu_process: Refactor qemuProcessOpenVfioDeviceFd + +This will allow us reusing same code for hotplug support. +As part of refactor remove redundant checks. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 76b720168bee49497519bbca2147cbd65ae7fcbf) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_process.c | 22 +++++++++------------- + 1 file changed, 9 insertions(+), 13 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 55cd930df8..7e32325fa0 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7698,23 +7698,21 @@ qemuProcessOpenIommuFd(virDomainObj *vm) + /** + * qemuProcessOpenVfioDeviceFd: + * @hostdev: host device definition +- * @vfioFd: returned file descriptor + * + * Opens the VFIO device file descriptor for a hostdev. + * +- * Returns: FD on success, -1 on failure ++ * Returns: 0 on success, -1 on failure + */ + static int + qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) + { +- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || +- hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("VFIO FD only supported for PCI hostdevs")); +- return -1; +- } ++ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); ++ virDomainHostdevSubsysPCI *pci = &hostdev->source.subsys.u.pci; + +- return virPCIDeviceOpenVfioFd(&hostdev->source.subsys.u.pci.addr); ++ if ((hostdevPriv->vfioDeviceFd = virPCIDeviceOpenVfioFd(&pci->addr)) < 0) ++ return -1; ++ ++ return 0; + } + + /** +@@ -7733,16 +7731,14 @@ qemuProcessOpenVfioFds(virDomainObj *vm) + /* Check if we have any hostdevs that need VFIO FDs */ + for (i = 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; +- qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); + + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && + hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO && + hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) { + /* Open VFIO device FD */ +- hostdevPriv->vfioDeviceFd = qemuProcessOpenVfioDeviceFd(hostdev); +- if (hostdevPriv->vfioDeviceFd == -1) +- return -1; ++ if (qemuProcessOpenVfioDeviceFd(hostdev) < 0) ++ return -1; + + /* Open IOMMU FD */ + if (qemuProcessOpenIommuFd(vm) < 0) +-- +2.53.0 diff --git a/libvirt-qemu_process-Refactor-qemuProcessOpenVfioFds.patch b/libvirt-qemu_process-Refactor-qemuProcessOpenVfioFds.patch new file mode 100644 index 0000000..9144e59 --- /dev/null +++ b/libvirt-qemu_process-Refactor-qemuProcessOpenVfioFds.patch @@ -0,0 +1,77 @@ +From a3696f1e0ba8ddf997e54fccd945593272635762 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 19:15:52 +0100 +Subject: [PATCH] qemu_process: Refactor qemuProcessOpenVfioFds + +Follow our switch pattern to simplify the code logic +and rename the function to follow our naming pattern. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit c83b4f367f23868793fc6b071771d0e641b7a546) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_process.c | 31 ++++++++++++++++--------------- + 1 file changed, 16 insertions(+), 15 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index da7a9fc11f..3729edcd7e 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7715,27 +7715,28 @@ qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) + return 0; + } + +-/** +- * qemuProcessOpenVfioFds: +- * @vm: domain object +- * +- * Opens all necessary VFIO file descriptors for the domain. +- * +- * Returns: 0 on success, -1 on failure +- */ + static int +-qemuProcessOpenVfioFds(virDomainObj *vm) ++qemuProcessPrepareHostHostdev(virDomainObj *vm) + { + size_t i; + +- /* Check if we have any hostdevs that need VFIO FDs */ + for (i = 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; + +- if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { +- /* Open VFIO device FD */ +- if (qemuProcessOpenVfioDeviceFd(hostdev) < 0) +- return -1; ++ switch (hostdev->source.subsys.type) { ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: ++ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { ++ /* Open VFIO device FD */ ++ if (qemuProcessOpenVfioDeviceFd(hostdev) < 0) ++ return -1; ++ } ++ break; ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ++ break; + } + } + +@@ -7803,7 +7804,7 @@ qemuProcessPrepareHost(virQEMUDriver *driver, + hostdev_flags |= VIR_HOSTDEV_COLD_BOOT; + if (qemuHostdevPrepareDomainDevices(driver, vm->def, hostdev_flags) < 0) + return -1; +- if (qemuProcessOpenVfioFds(vm) < 0) ++ if (qemuProcessPrepareHostHostdev(vm) < 0) + return -1; + + VIR_DEBUG("Preparing chr device backends"); +-- +2.53.0 diff --git a/libvirt-qemuxmlconftest-Refactor-host-device-preparation.patch b/libvirt-qemuxmlconftest-Refactor-host-device-preparation.patch new file mode 100644 index 0000000..cb2fbd8 --- /dev/null +++ b/libvirt-qemuxmlconftest-Refactor-host-device-preparation.patch @@ -0,0 +1,101 @@ +From d851b46d3794d4ad2d0f9b74c0e0cf1a10d06682 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sat, 14 Feb 2026 11:39:19 +0100 +Subject: [PATCH] qemuxmlconftest: Refactor host device preparation + +Create a single place for host device preparation code. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit cb23831c020a5fab33be417426b2746a73ecdd10) + +Conflicts: + - missing upstream commit b97afe28f54dae1d122baa33d1a371b68775b7b2 + tests/qemuxmlconftest.c + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + tests/qemuxmlconftest.c | 59 ++++++++++++++++++++++++++++++----------- + 1 file changed, 43 insertions(+), 16 deletions(-) + +diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c +index 757f0a9fc0..0c146601ed 100644 +--- a/tests/qemuxmlconftest.c ++++ b/tests/qemuxmlconftest.c +@@ -378,6 +378,48 @@ testSetupHostdevPrivateData(virDomainDef *def) + } + + ++static void ++testQemuPrepareHostdevUSB(virDomainHostdevDef *hostdev) ++{ ++ virDomainHostdevSubsysUSB *usb = &hostdev->source.subsys.u.usb; ++ ++ if (!usb->device && !usb->bus) { ++ if (usb->vendor == 0x1234 && usb->product == 0x4321) { ++ usb->bus = 42; ++ usb->device = 0x1234; ++ } else { ++ g_assert_not_reached(); ++ } ++ } ++} ++ ++ ++static void ++testQemuPrepareHostdev(virDomainObj *vm) ++{ ++ size_t i; ++ ++ for (i = 0; i < vm->def->nhostdevs; i++) { ++ virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; ++ ++ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) ++ continue; ++ ++ switch (hostdev->source.subsys.type) { ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: ++ testQemuPrepareHostdevUSB(hostdev); ++ break; ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ++ break; ++ } ++ } ++} ++ ++ + static virNetworkDriver fakeNetworkDriver = { + .networkLookupByName = fakeNetworkLookupByName, + .networkGetXMLDesc = fakeNetworkGetXMLDesc, +@@ -524,22 +566,7 @@ testCompareXMLToArgvCreateArgs(virQEMUDriver *drv, + } + } + +- for (i = 0; i < vm->def->nhostdevs; i++) { +- virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; +- +- if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && +- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { +- virDomainHostdevSubsysUSB *usb = &hostdev->source.subsys.u.usb; +- if (!usb->device && !usb->bus) { +- if (usb->vendor == 0x1234 && usb->product == 0x4321) { +- usb->bus = 42; +- usb->device = 0x1234; +- } else { +- g_assert_not_reached(); +- } +- } +- } +- } ++ testQemuPrepareHostdev(vm); + + if (flags & FLAG_SLIRP_HELPER) { + for (i = 0; i < vm->def->nnets; i++) { +-- +2.53.0 diff --git a/libvirt-qemuxmlconftest-Rename-and-refactor-testSetupHostdevPrivateData.patch b/libvirt-qemuxmlconftest-Rename-and-refactor-testSetupHostdevPrivateData.patch new file mode 100644 index 0000000..76ec161 --- /dev/null +++ b/libvirt-qemuxmlconftest-Rename-and-refactor-testSetupHostdevPrivateData.patch @@ -0,0 +1,78 @@ +From ef36f155015cd42f1f631d4955b76173ca16b9f3 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sat, 14 Feb 2026 11:48:53 +0100 +Subject: [PATCH] qemuxmlconftest: Rename and refactor + testSetupHostdevPrivateData + +There is no need to call qemuDomainHostdevPrivateNew() because +privateData is allocated on creation by virDomainHostdevDefNew(). + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 15ad45758bcb674924ddb2ebb86a767cf40b990d) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + tests/qemuxmlconftest.c | 29 +++++++---------------------- + 1 file changed, 7 insertions(+), 22 deletions(-) + +diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c +index 0c146601ed..f7e50dc655 100644 +--- a/tests/qemuxmlconftest.c ++++ b/tests/qemuxmlconftest.c +@@ -352,28 +352,13 @@ fakeNetworkPortGetXMLDesc(virNetworkPortPtr port, + + + static void +-testSetupHostdevPrivateData(virDomainDef *def) ++testQemuPrepareHostdevPCI(virDomainHostdevDef *hostdev) + { +- size_t i; ++ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); + +- for (i = 0; i < def->nhostdevs; i++) { +- virDomainHostdevDef *hostdev = def->hostdevs[i]; +- +- if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && +- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && +- hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO && +- hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) { +- +- qemuDomainHostdevPrivate *priv; +- +- if (!hostdev->privateData) { +- hostdev->privateData = qemuDomainHostdevPrivateNew(); +- } +- +- priv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); +- /* Use a placeholder FD value for tests */ +- priv->vfioDeviceFd = 0; +- } ++ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { ++ /* Use a placeholder FD value for tests */ ++ hostdevPriv->vfioDeviceFd = 0; + } + } + +@@ -410,6 +395,8 @@ testQemuPrepareHostdev(virDomainObj *vm) + testQemuPrepareHostdevUSB(hostdev); + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: ++ testQemuPrepareHostdevPCI(hostdev); ++ break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: +@@ -473,8 +460,6 @@ testCompareXMLToArgvCreateArgs(virQEMUDriver *drv, + if (testQemuPrepareHostBackendChardevOne(NULL, priv->monConfig, vm) < 0) + return NULL; + +- testSetupHostdevPrivateData(vm->def); +- + for (i = 0; i < vm->def->ndisks; i++) { + virDomainDiskDef *disk = vm->def->disks[i]; + virStorageSource *src; +-- +2.53.0 diff --git a/libvirt-qemuxmlconftest-Set-fake-FD-for-IOMMUFD.patch b/libvirt-qemuxmlconftest-Set-fake-FD-for-IOMMUFD.patch new file mode 100644 index 0000000..26a14b7 --- /dev/null +++ b/libvirt-qemuxmlconftest-Set-fake-FD-for-IOMMUFD.patch @@ -0,0 +1,98 @@ +From fc19eece815873aa653d733494294f4b83a9416e Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sat, 14 Feb 2026 17:11:44 +0100 +Subject: [PATCH] qemuxmlconftest: Set fake FD for IOMMUFD + +Same as for VFIO FD for host device. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 4a80a0468e21866d11f08bd64888f399cff98d94) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args | 2 +- + .../iommufd-virt-pci-bus-single.aarch64-latest.args | 2 +- + tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args | 2 +- + tests/qemuxmlconfdata/iommufd.x86_64-latest.args | 2 +- + tests/qemuxmlconftest.c | 4 ++++ + 5 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args +index 7d819e141b..d5fe704021 100644 +--- a/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/iommufd-q35.x86_64-latest.args +@@ -35,7 +35,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.config \ + -device '{"driver":"qxl-vga","id":"video0","max_outputs":1,"ram_size":67108864,"vram_size":33554432,"vram64_size_mb":0,"vgamem_mb":8,"bus":"pcie.0","addr":"0x1"}' \ + -global ICH9-LPC.noreboot=off \ + -watchdog-action reset \ +--object '{"qom-type":"iommufd","id":"iommufd0","fd":"-1"}' \ ++-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \ + -device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x3"}' \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ + -msg timestamp=on +diff --git a/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args b/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args +index dbfd395168..99886468fb 100644 +--- a/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args ++++ b/tests/qemuxmlconfdata/iommufd-virt-pci-bus-single.aarch64-latest.args +@@ -27,7 +27,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \ + -no-shutdown \ + -boot strict=on \ + -audiodev '{"id":"audio1","driver":"none"}' \ +--object '{"qom-type":"iommufd","id":"iommufd0","fd":"-1"}' \ ++-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \ + -device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x1"}' \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ + -msg timestamp=on +diff --git a/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args b/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args +index d5713ff826..e3695c6982 100644 +--- a/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args ++++ b/tests/qemuxmlconfdata/iommufd-virt.aarch64-latest.args +@@ -30,7 +30,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \ + -device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \ + -device '{"driver":"pcie-root-port","port":10,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x2"}' \ + -audiodev '{"id":"audio1","driver":"none"}' \ +--object '{"qom-type":"iommufd","id":"iommufd0","fd":"-1"}' \ ++-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \ + -device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.1","addr":"0x0"}' \ + -device '{"driver":"vfio-pci","host":"0000:07:12.5","id":"hostdev1","iommufd":"iommufd0","fd":"0","bus":"pci.2","addr":"0x0"}' \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +diff --git a/tests/qemuxmlconfdata/iommufd.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd.x86_64-latest.args +index 3130ba2e3a..15dabe197c 100644 +--- a/tests/qemuxmlconfdata/iommufd.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/iommufd.x86_64-latest.args +@@ -28,7 +28,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \ + -boot strict=on \ + -device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ + -audiodev '{"id":"audio1","driver":"none"}' \ +--object '{"qom-type":"iommufd","id":"iommufd0","fd":"-1"}' \ ++-object '{"qom-type":"iommufd","id":"iommufd0","fd":"0"}' \ + -device '{"driver":"vfio-pci","host":"0000:06:12.5","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pci.0","addr":"0x3"}' \ + -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c +index f7e50dc655..6f16b6cee8 100644 +--- a/tests/qemuxmlconftest.c ++++ b/tests/qemuxmlconftest.c +@@ -382,6 +382,7 @@ testQemuPrepareHostdevUSB(virDomainHostdevDef *hostdev) + static void + testQemuPrepareHostdev(virDomainObj *vm) + { ++ qemuDomainObjPrivate *priv = QEMU_DOMAIN_PRIVATE(vm); + size_t i; + + for (i = 0; i < vm->def->nhostdevs; i++) { +@@ -404,6 +405,9 @@ testQemuPrepareHostdev(virDomainObj *vm) + break; + } + } ++ ++ if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) ++ priv->iommufd = 0; + } + + +-- +2.53.0 diff --git a/libvirt-tests-properly-mock-VFIO-and-IOMMU-checks.patch b/libvirt-tests-properly-mock-VFIO-and-IOMMU-checks.patch new file mode 100644 index 0000000..c784923 --- /dev/null +++ b/libvirt-tests-properly-mock-VFIO-and-IOMMU-checks.patch @@ -0,0 +1,113 @@ +From 89d43d156f8a5c2fbb48947885e98c27b0617f0f Mon Sep 17 00:00:00 2001 +Message-ID: <89d43d156f8a5c2fbb48947885e98c27b0617f0f.1771423659.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Mon, 16 Feb 2026 16:53:57 +0100 +Subject: [PATCH] tests: properly mock VFIO and IOMMU checks + +Fixes: 63434db800b921e96fec424a667b7161af1f02de +Signed-off-by: Pavel Hrdina +(cherry picked from commit 75db232f90af2b2acd95266dd21290c967e3c625) + +Resolves: https://issues.redhat.com/browse/RHEL-148135 +Signed-off-by: Pavel Hrdina +--- + src/util/virutil.h | 2 +- + tests/domaincapsdata/qemu_9.0.0.sparc.xml | 5 +---- + tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml | 5 +---- + tests/domaincapsmock.c | 10 ++++++++++ + tests/domaincapstest.c | 8 -------- + 5 files changed, 13 insertions(+), 17 deletions(-) + +diff --git a/src/util/virutil.h b/src/util/virutil.h +index ca6fd95363..7e1705e7ce 100644 +--- a/src/util/virutil.h ++++ b/src/util/virutil.h +@@ -141,7 +141,7 @@ unsigned long long virMemoryLimitTruncate(unsigned long long value); + bool virMemoryLimitIsSet(unsigned long long value); + unsigned long long virMemoryMaxValue(bool ulong) ATTRIBUTE_MOCKABLE; + +-bool virHostHasIOMMU(void); ++bool virHostHasIOMMU(void) ATTRIBUTE_MOCKABLE; + + char *virHostGetDRMRenderNode(void) ATTRIBUTE_MOCKABLE; + +diff --git a/tests/domaincapsdata/qemu_9.0.0.sparc.xml b/tests/domaincapsdata/qemu_9.0.0.sparc.xml +index 062e55718b..93d8d40c2c 100644 +--- a/tests/domaincapsdata/qemu_9.0.0.sparc.xml ++++ b/tests/domaincapsdata/qemu_9.0.0.sparc.xml +@@ -86,10 +86,7 @@ + scsi + + +- +- default +- vfio +- ++ + + no + +diff --git a/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml b/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml +index db51e7b120..a65d9d36fd 100644 +--- a/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml ++++ b/tests/domaincapsdata/qemu_9.2.0-hvf.aarch64+hvf.xml +@@ -147,10 +147,7 @@ + scsi + + +- +- default +- vfio +- ++ + + no + +diff --git a/tests/domaincapsmock.c b/tests/domaincapsmock.c +index 370ce35709..aa13deb324 100644 +--- a/tests/domaincapsmock.c ++++ b/tests/domaincapsmock.c +@@ -21,6 +21,7 @@ + #include "virhostmem.h" + #include "viriommufd.h" + #include "virmock.h" ++#include "virutil.h" + + #if WITH_QEMU + # include "qemu/qemu_capabilities.h" +@@ -91,5 +92,14 @@ virFileExists(const char *path) + if (STREQ(path, VIR_IOMMU_DEV_PATH)) + return true; + ++ if (STREQ(path, "/dev/vfio/vfio")) ++ return true; ++ + return real_virFileExists(path); + } ++ ++bool ++virHostHasIOMMU(void) ++{ ++ return true; ++} +diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c +index 71e181d179..5b2fc80f0a 100644 +--- a/tests/domaincapstest.c ++++ b/tests/domaincapstest.c +@@ -104,14 +104,6 @@ fillQemuCaps(virDomainCaps *domCaps, + false) < 0) + return -1; + +- /* The function above tries to query host's VFIO capabilities by calling +- * virHostdevHostSupportsPassthroughVFIO() which, however, can't be +- * successfully mocked as they are not exposed as internal APIs. Therefore, +- * instead of mocking set the expected values here by hand. */ +- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->hostdev.pciBackend, +- VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT, +- VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO); +- + /* As of f05b6a918e28 we are expecting to see OVMF_CODE.fd file which + * may not exists everywhere. */ + while (loader->values.nvalues) +-- +2.53.0 diff --git a/libvirt-util-Move-openning-IOMMU-device-to-viriommufd.patch b/libvirt-util-Move-openning-IOMMU-device-to-viriommufd.patch new file mode 100644 index 0000000..dbfc068 --- /dev/null +++ b/libvirt-util-Move-openning-IOMMU-device-to-viriommufd.patch @@ -0,0 +1,115 @@ +From e0e49da1ab66c90b0379ca246b8bdfeadb9ebdbe Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 15:32:24 +0100 +Subject: [PATCH] util: Move openning IOMMU device to viriommufd + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit c684b83a68158cd15e262523db11259c9edabe4a) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/libvirt_private.syms | 2 +- + src/qemu/qemu_process.c | 9 +-------- + src/util/viriommufd.c | 22 +++++++++++++++++++--- + src/util/viriommufd.h | 2 +- + 4 files changed, 22 insertions(+), 13 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 0904265459..6c4918da9e 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2653,7 +2653,7 @@ virInitctlFifos; + virInitctlSetRunLevel; + + # util/viriommufd.h +-virIOMMUFDSetRLimitMode; ++virIOMMUFDOpenDevice; + virIOMMUFDSupported; + + # util/viriscsi.h +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 479437fb34..dd165512f3 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7689,15 +7689,8 @@ qemuProcessOpenIommuFd(virDomainObj *vm) + + VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name); + +- if ((fd = open(VIR_IOMMU_DEV_PATH, O_RDWR | O_CLOEXEC)) < 0) { +- virReportSystemError(errno, "%s", _("cannot open /dev/iommu")); ++ if ((fd = virIOMMUFDOpenDevice()) < 0) + return -1; +- } +- +- if (virIOMMUFDSetRLimitMode(fd, true) < 0) { +- VIR_FORCE_CLOSE(fd); +- return -1; +- } + + VIR_DEBUG("Opened IOMMU FD %d for domain %s", fd, vm->def->name); + return fd; +diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c +index 44b30029a5..1f3353eab4 100644 +--- a/src/util/viriommufd.c ++++ b/src/util/viriommufd.c +@@ -1,5 +1,7 @@ + #include + ++#include ++ + #include "viriommufd.h" + #include "virlog.h" + #include "virerror.h" +@@ -54,7 +56,7 @@ struct iommu_option { + * + * Returns: 0 on success, -1 on error + */ +-int ++static int + virIOMMUFDSetRLimitMode(int fd, bool processAccounting) + { + struct iommu_option option = { +@@ -77,10 +79,24 @@ virIOMMUFDSetRLimitMode(int fd, bool processAccounting) + return 0; + } + ++int ++virIOMMUFDOpenDevice(void) ++{ ++ 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) ++ return -1; ++ ++ return fd; ++} ++ + #else + +-int virIOMMUFDSetRLimitMode(int fd G_GNUC_UNUSED, +- bool processAccounting G_GNUC_UNUSED) ++int ++virIOMMUFDOpenDevice(void) + { + 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 ec6be9fa66..223f44eb5c 100644 +--- a/src/util/viriommufd.h ++++ b/src/util/viriommufd.h +@@ -22,6 +22,6 @@ + + #define VIR_IOMMU_DEV_PATH "/dev/iommu" + +-int virIOMMUFDSetRLimitMode(int fd, bool processAccounting); ++int virIOMMUFDOpenDevice(void); + + bool virIOMMUFDSupported(void); +-- +2.53.0 diff --git a/libvirt-util-Move-openning-VFIO-device-to-virpci.patch b/libvirt-util-Move-openning-VFIO-device-to-virpci.patch new file mode 100644 index 0000000..65c5525 --- /dev/null +++ b/libvirt-util-Move-openning-VFIO-device-to-virpci.patch @@ -0,0 +1,123 @@ +From d116851dc65d69b95d9de2f0f209ba5d69987cb8 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 17:39:05 +0100 +Subject: [PATCH] util: Move openning VFIO device to virpci + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 22c666097cc56919355e653010bff8ade5d5f12c) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/libvirt_private.syms | 1 + + src/qemu/qemu_process.c | 23 +---------------------- + src/util/virpci.c | 28 ++++++++++++++++++++++++++++ + src/util/virpci.h | 2 ++ + 4 files changed, 32 insertions(+), 22 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 6c4918da9e..9ae44e31b8 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -3180,6 +3180,7 @@ virPCIDeviceListNew; + virPCIDeviceListSteal; + virPCIDeviceListStealIndex; + virPCIDeviceNew; ++virPCIDeviceOpenVfioFd; + virPCIDeviceReattach; + virPCIDeviceRebind; + virPCIDeviceReset; +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 71770d2099..55cd930df8 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7707,9 +7707,6 @@ qemuProcessOpenIommuFd(virDomainObj *vm) + static int + qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) + { +- g_autofree char *vfioPath = NULL; +- int fd = -1; +- + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +@@ -7717,25 +7714,7 @@ qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) + return -1; + } + +- if (virPCIDeviceGetVfioPath(&hostdev->source.subsys.u.pci.addr, &vfioPath) < 0) +- return -1; +- +- VIR_DEBUG("Opening VFIO device %s", vfioPath); +- +- if ((fd = open(vfioPath, O_RDWR | O_CLOEXEC)) < 0) { +- if (errno == ENOENT) { +- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +- _("VFIO device %1$s not found - ensure device is bound to vfio-pci driver"), +- vfioPath); +- } else { +- virReportSystemError(errno, +- _("cannot open VFIO device %1$s"), vfioPath); +- } +- return -1; +- } +- +- VIR_DEBUG("Opened VFIO device FD %d for %s", fd, vfioPath); +- return fd; ++ return virPCIDeviceOpenVfioFd(&hostdev->source.subsys.u.pci.addr); + } + + /** +diff --git a/src/util/virpci.c b/src/util/virpci.c +index 2348a98003..30feec6dae 100644 +--- a/src/util/virpci.c ++++ b/src/util/virpci.c +@@ -3359,3 +3359,31 @@ virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, + addrStr); + return -1; + } ++ ++/** ++ * virPCIDeviceOpenVfioFd: ++ * @addr: ++ * ++ * Opens VFIO device and returns its FD. ++ * ++ * Returns: FD on success, -1 on failure ++ */ ++int ++virPCIDeviceOpenVfioFd(virPCIDeviceAddress *addr) ++{ ++ g_autofree char *vfioPath = NULL; ++ int fd = -1; ++ ++ if (virPCIDeviceGetVfioPath(addr, &vfioPath) < 0) ++ return -1; ++ ++ VIR_DEBUG("Opening VFIO device %s", vfioPath); ++ ++ if ((fd = open(vfioPath, O_RDWR | O_CLOEXEC)) < 0) { ++ virReportSystemError(errno, _("cannot open VFIO device %1$s"), vfioPath); ++ return -1; ++ } ++ ++ VIR_DEBUG("Opened VFIO device FD %d for %s", fd, vfioPath); ++ return fd; ++} +diff --git a/src/util/virpci.h b/src/util/virpci.h +index 24ede10755..7848567285 100644 +--- a/src/util/virpci.h ++++ b/src/util/virpci.h +@@ -298,6 +298,8 @@ void virPCIDeviceAddressFree(virPCIDeviceAddress *address); + + int virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, char **vfioPath); + ++int virPCIDeviceOpenVfioFd(virPCIDeviceAddress *addr); ++ + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDevice, virPCIDeviceFree); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDeviceAddress, virPCIDeviceAddressFree); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIEDeviceInfo, virPCIEDeviceInfoFree); +-- +2.53.0 diff --git a/libvirt-util-Use-virPCIDevice-as-argument-in-virPCIDeviceGetVfioPath.patch b/libvirt-util-Use-virPCIDevice-as-argument-in-virPCIDeviceGetVfioPath.patch new file mode 100644 index 0000000..4654fc5 --- /dev/null +++ b/libvirt-util-Use-virPCIDevice-as-argument-in-virPCIDeviceGetVfioPath.patch @@ -0,0 +1,143 @@ +From 25fa4eb529f1d54995b66ebe3b38bafb3ab755c6 Mon Sep 17 00:00:00 2001 +Message-ID: <25fa4eb529f1d54995b66ebe3b38bafb3ab755c6.1771423658.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 17:51:46 +0100 +Subject: [PATCH] util: Use virPCIDevice as argument in virPCIDeviceGetVfioPath + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 3365bff598a0d0a5b21afc7060e10a0a2f7d21a7) + +Resolves: https://issues.redhat.com/browse/RHEL-150351 +Signed-off-by: Pavel Hrdina +--- + src/security/security_apparmor.c | 2 +- + src/security/security_dac.c | 4 ++-- + src/security/security_selinux.c | 4 ++-- + src/util/virpci.c | 14 ++++++++------ + src/util/virpci.h | 2 +- + 5 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c +index 934acfb461..6c5da2a650 100644 +--- a/src/security/security_apparmor.c ++++ b/src/security/security_apparmor.c +@@ -860,7 +860,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr, + } else { + g_autofree char *vfiofdDev = NULL; + +- if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) + goto done; + + ret = AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr); +diff --git a/src/security/security_dac.c b/src/security/security_dac.c +index d0ed22db2d..704c8dbfec 100644 +--- a/src/security/security_dac.c ++++ b/src/security/security_dac.c +@@ -1295,7 +1295,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr, + } else { + g_autofree char *vfiofdDev = NULL; + +- if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) + return -1; + + ret = virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata); +@@ -1468,7 +1468,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr, + } else { + g_autofree char *vfiofdDev = NULL; + +- if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) + return -1; + + ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL, +diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c +index 834383a7de..4a5f61d16b 100644 +--- a/src/security/security_selinux.c ++++ b/src/security/security_selinux.c +@@ -2269,7 +2269,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr, + } else { + g_autofree char *vfiofdDev = NULL; + +- if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) + return -1; + + ret = virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data); +@@ -2515,7 +2515,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr, + } else { + g_autofree char *vfiofdDev = NULL; + +- if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) + return -1; + + ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false); +diff --git a/src/util/virpci.c b/src/util/virpci.c +index 30feec6dae..78c47869ef 100644 +--- a/src/util/virpci.c ++++ b/src/util/virpci.c +@@ -3331,19 +3331,17 @@ virPCIDeviceAddressFree(virPCIDeviceAddress *address) + * Returns: 0 on success, -1 on failure + */ + int +-virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, ++virPCIDeviceGetVfioPath(virPCIDevice *pci, + char **vfioPath) + { +- g_autofree char *addrStr = NULL; + g_autofree char *sysfsPath = NULL; + g_autoptr(DIR) dir = NULL; + struct dirent *entry = NULL; + + *vfioPath = NULL; +- addrStr = virPCIDeviceAddressAsString(addr); + + /* Look in device's vfio-dev subdirectory */ +- sysfsPath = g_strdup_printf("/sys/bus/pci/devices/%s/vfio-dev/", addrStr); ++ sysfsPath = virPCIFile(pci->name, "vfio-dev"); + + if (virDirOpen(&dir, sysfsPath) == 1) { + while (virDirRead(dir, &entry, sysfsPath) > 0) { +@@ -3356,7 +3354,7 @@ virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, + + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find VFIO device for PCI device %1$s"), +- addrStr); ++ pci->name); + return -1; + } + +@@ -3371,10 +3369,14 @@ virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, + int + virPCIDeviceOpenVfioFd(virPCIDeviceAddress *addr) + { ++ g_autoptr(virPCIDevice) pci = NULL; + g_autofree char *vfioPath = NULL; + int fd = -1; + +- if (virPCIDeviceGetVfioPath(addr, &vfioPath) < 0) ++ if (!(pci = virPCIDeviceNew(addr))) ++ return -1; ++ ++ if (virPCIDeviceGetVfioPath(pci, &vfioPath) < 0) + return -1; + + VIR_DEBUG("Opening VFIO device %s", vfioPath); +diff --git a/src/util/virpci.h b/src/util/virpci.h +index 7848567285..933099da6c 100644 +--- a/src/util/virpci.h ++++ b/src/util/virpci.h +@@ -296,7 +296,7 @@ void virPCIEDeviceInfoFree(virPCIEDeviceInfo *dev); + + void virPCIDeviceAddressFree(virPCIDeviceAddress *address); + +-int virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, char **vfioPath); ++int virPCIDeviceGetVfioPath(virPCIDevice *pci, char **vfioPath); + + int virPCIDeviceOpenVfioFd(virPCIDeviceAddress *addr); + +-- +2.53.0 diff --git a/libvirt.spec b/libvirt.spec index e947f29..2c23d86 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -294,7 +294,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 11.10.0 -Release: 9%{?dist}%{?extra_release} +Release: 10%{?dist}%{?extra_release} License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1 URL: https://libvirt.org/ @@ -355,6 +355,32 @@ Patch50: libvirt-docs-formatdomain-Fix-indentation-of-docs-for-disk-driver-stati Patch51: libvirt-docs-formatdomain-Reword-section-about-the-statistics-element-under-disk-driver.patch Patch52: libvirt-Introduce-support-for-disk-operation-latency-histogram-collection.patch Patch53: libvirt-qemu-Setup-disk-latency-histograms-on-startup-hotplug-update.patch +Patch54: libvirt-qemu-Introduce-QEMU_CAPS_OBJECT_IOMMUFD.patch +Patch55: libvirt-qemu-Move-IOMMUFD-validation-to-qemu_validate.patch +Patch56: libvirt-util-Move-openning-IOMMU-device-to-viriommufd.patch +Patch57: libvirt-qemu_process-Refactor-qemuProcessOpenIommuFd.patch +Patch58: libvirt-util-Move-openning-VFIO-device-to-virpci.patch +Patch59: libvirt-qemu_process-Refactor-qemuProcessOpenVfioDeviceFd.patch +Patch60: libvirt-util-Use-virPCIDevice-as-argument-in-virPCIDeviceGetVfioPath.patch +Patch61: libvirt-conf-Introduce-virHostdevIsPCIDeviceWithIOMMUFD.patch +Patch62: libvirt-conf-Introduce-virDomainDefHasPCIHostdevWithIOMMUFD.patch +Patch63: libvirt-qemu_domain-Add-missing-IOMMUFD-cleanup.patch +Patch64: libvirt-qemu_process-Fix-FD-leak-with-multiple-host-devices-using-IOMMUFD.patch +Patch65: libvirt-qemu_process-Refactor-qemuProcessOpenVfioFds.patch +Patch66: libvirt-qemuxmlconftest-Refactor-host-device-preparation.patch +Patch67: libvirt-qemuxmlconftest-Rename-and-refactor-testSetupHostdevPrivateData.patch +Patch68: libvirt-qemuxmlconftest-Set-fake-FD-for-IOMMUFD.patch +Patch69: libvirt-qemu-Convert-IOMMUFD-to-qemuFDPassDirect.patch +Patch70: libvirt-qemu-Convert-vfioDeviceFd-to-qemuFDPassDirect.patch +Patch71: libvirt-qemu_command-Don-t-use-host-property-if-IOMMUFD-is-used.patch +Patch72: libvirt-qemu-Save-IOMMUFD-state-into-status-XML.patch +Patch73: libvirt-qemu_hotplug-Remove-iommufd-object-if-no-longer-needed.patch +Patch74: libvirt-qemu_command-Extract-building-IOMMUFD-props-to-function.patch +Patch75: libvirt-qemu_hotplug-Add-support-to-hotplug-host-device-with-IOMMUFD.patch +Patch76: libvirt-conf-Introduce-iommufd-enum-for-domaincaps.patch +Patch77: libvirt-qemu-Fill-iommufd-domain-capability.patch +Patch78: libvirt-tests-properly-mock-VFIO-and-IOMMU-checks.patch +Patch79: libvirt-iommufd-fix-FD-leak-in-case-of-error.patch Requires: libvirt-daemon = %{version}-%{release} @@ -2746,6 +2772,34 @@ exit 0 %endif %changelog +* Wed Feb 18 2026 Jiri Denemark - 11.10.0-10 +- qemu: Introduce QEMU_CAPS_OBJECT_IOMMUFD (RHEL-150351) +- qemu: Move IOMMUFD validation to qemu_validate (RHEL-150351) +- util: Move openning IOMMU device to viriommufd (RHEL-150351) +- qemu_process: Refactor qemuProcessOpenIommuFd (RHEL-150351) +- util: Move openning VFIO device to virpci (RHEL-150351) +- qemu_process: Refactor qemuProcessOpenVfioDeviceFd (RHEL-150351) +- util: Use virPCIDevice as argument in virPCIDeviceGetVfioPath (RHEL-150351) +- conf: Introduce virHostdevIsPCIDeviceWithIOMMUFD (RHEL-150351) +- conf: Introduce virDomainDefHasPCIHostdevWithIOMMUFD (RHEL-150351) +- qemu_domain: Add missing IOMMUFD cleanup (RHEL-150351) +- qemu_process: Fix FD leak with multiple host devices using IOMMUFD (RHEL-150351) +- qemu_process: Refactor qemuProcessOpenVfioFds (RHEL-150351) +- qemuxmlconftest: Refactor host device preparation (RHEL-150351) +- qemuxmlconftest: Rename and refactor testSetupHostdevPrivateData (RHEL-150351) +- qemuxmlconftest: Set fake FD for IOMMUFD (RHEL-150351) +- qemu: Convert IOMMUFD to qemuFDPassDirect (RHEL-150351) +- qemu: Convert vfioDeviceFd to qemuFDPassDirect (RHEL-150351) +- qemu_command: Don't use host property if IOMMUFD is used (RHEL-150351) +- qemu: Save IOMMUFD state into status XML (RHEL-150351) +- qemu_hotplug: Remove iommufd object if no longer needed (RHEL-150351) +- qemu_command: Extract building IOMMUFD props to function (RHEL-150351) +- qemu_hotplug: Add support to hotplug host device with IOMMUFD (RHEL-150351) +- conf: Introduce iommufd enum for domaincaps (RHEL-148135) +- qemu: Fill iommufd domain capability (RHEL-148135) +- tests: properly mock VFIO and IOMMU checks (RHEL-148135) +- iommufd: fix FD leak in case of error (RHEL-150351) + * Tue Feb 17 2026 Jiri Denemark - 11.10.0-9 - qemu: capabilities: Probe properties of 'scsi-block' and 'scsi-generic' devices (RHEL-135115) - qemu: capabilities: Introduce QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR (RHEL-135115)