From d39b9dfb91e48d1312cd857b1a480c2c5cf47617 Mon Sep 17 00:00:00 2001 From: Pavel Hrdina Date: Thu, 19 Feb 2026 12:12:47 +0100 Subject: [PATCH] libvirt-11.10.0-10.1.el10nv - qemu: Add support for HW-accelerated nested SMMUv3 (VOYAGER-4) - tests: qemuxmlconfdata: provide HW-accel smmuv3 sample XML and CLI args (VOYAGER-4) - qemu: add IOMMU attribute "cmdqv" for smmuv3 (VOYAGER-14) - tests: qemuxmlconfdata: provide cmdqv sample XML and CLI args (VOYAGER-14) Resolves: VOYAGER-4, VOYAGER-14 --- .abignore | 31 + .gitignore | 5 + gating.yaml | 10 + ...rams-via-virConnectGetAllDomainStats.patch | 248 + ...eration-latency-histogram-collection.patch | 422 + ...-migrate-pr-capability-of-scsi-block.patch | 125 + ...ntroduce-iommufd-enum-for-domaincaps.patch | 69 + ...virDomainDefHasPCIHostdevWithIOMMUFD.patch | 132 + ...uce-virHostdevIsPCIDeviceWithIOMMUFD.patch | 89 + ...s-for-disk-driver-statistics-element.patch | 62 + ...statistics-element-under-disk-driver.patch | 51 + ...-URL-creation-code-into-one-function.patch | 119 + ...-esx-Allow-connecting-to-IPv6-server.patch | 43 + ...ug-URL-just-before-opening-with-curl.patch | 29 + ...-to-creating-URLs-using-virURIFormat.patch | 57 + ...x-URI-encode-inventory-objects-twice.patch | 60 + ...roduce-esxUtil_EscapeInventoryObject.patch | 76 + ...iommufd-fix-FD-leak-in-case-of-error.patch | 38 + ...ort-for-HW-accelerated-nested-SMMUv3.patch | 452 + ...-Convert-IOMMUFD-to-qemuFDPassDirect.patch | 125 + ...ert-vfioDeviceFd-to-qemuFDPassDirect.patch | 129 + ...-done-via-QMP-into-a-separate-helper.patch | 144 + ...-qemu-Fill-iommufd-domain-capability.patch | 1257 +++ libvirt-qemu-Ignore-cmp_legacy-CPU-flag.patch | 713 ++ ...t-for-associating-iommufd-to-hostdev.patch | 191 + ...istent-reservation-migration-control.patch | 220 + ...u-Introduce-QEMU_CAPS_OBJECT_IOMMUFD.patch | 266 + ...u-Introduce-privateData-for-hostdevs.patch | 277 + ...-IOMMUFD-validation-to-qemu_validate.patch | 111 + ...u-Save-IOMMUFD-state-into-status-XML.patch | 79 + ...histograms-on-startup-hotplug-update.patch | 132 + ...rocess-memory-accounting-for-iommufd.patch | 212 + ...p-namespace-and-seclabel-for-iommufd.patch | 336 + ...i_bus-to-identify-multi-smmuv3-model.patch | 69 + ...add-IOMMU-attribute-cmdqv-for-smmuv3.patch | 145 + ...MU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR.patch | 58 + ...-scsi-block-and-scsi-generic-devices.patch | 7714 +++++++++++++++++ ...block-dirty-bitmaps-during-migration.patch | 147 + ...lers-for-block-latency-histogram-set.patch | 182 + ...maps-from-qcow2-format-specific-data.patch | 173 + ...-histogram-stats-into-qemuBlockStats.patch | 168 + ...u-open-VFIO-FDs-from-libvirt-backend.patch | 247 + ...open-iommufd-FD-from-libvirt-backend.patch | 175 + ...kThrottling-to-qemuProcessSetupDisks.patch | 62 + ...ion-without-actually-sharing-storage.patch | 119 + ...etting-of-group_name-out-of-the-loop.patch | 68 + ...hottle-group-name-passed-as-argument.patch | 75 + ...up-name-into-the-tunable-event-twice.patch | 43 + ...rce-non-zero-groupname-string-length.patch | 38 + ...maps-Always-consider-offered-bitmaps.patch | 98 + ...tmaps-Fix-check-for-existing-bitmaps.patch | 68 + ...nly-to-virStorageSource-of-same-type.patch | 56 + ...rceIsSameLocation-with-NULL-argument.patch | 48 + ...-calling-virStorageSourceGetMetadata.patch | 75 + ...ateBackingStore-Remove-stale-comment.patch | 34 + ...try-as-curent-user-if-qemu-img-fails.patch | 97 + ...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 + ...l-nodenames-in-testQemuDetectBitmaps.patch | 175 + ...est-Refactor-host-device-preparation.patch | 101 + ...refactor-testSetupHostdevPrivateData.patch | 78 + ...uxmlconftest-Set-fake-FD-for-IOMMUFD.patch | 98 + ...unset-in-virDomainInterfaceAddresses.patch | 98 + ..._vi.c-Debug-path-element-comparisons.patch | 53 + ...tests-Test-virFileIsSharedFSOverride.patch | 111 + ...-test-for-a-single-per-device-smmuv3.patch | 201 + ...-properly-mock-VFIO-and-IOMMU-checks.patch | 113 + ...accel-smmuv3-sample-XML-and-CLI-args.patch | 217 + ...rovide-cmdqv-sample-XML-and-CLI-args.patch | 207 + ...vide-iommufd-sample-XML-and-CLI-args.patch | 635 ++ ...ndition-in-virFileIsSharedFSOverride.patch | 114 + ...e-condition-in-virFileIsSharedFSType.patch | 144 + ...-openning-IOMMU-device-to-viriommufd.patch | 115 + ...-Move-openning-VFIO-device-to-virpci.patch | 123 + ...FSOverride-using-virFileCheckParents.patch | 84 + ...-argument-in-virPCIDeviceGetVfioPath.patch | 143 + ...ON-nesting-limit-when-parsing-to-300.patch | 50 + ...nExternalNames-Improve-error-message.patch | 37 + ...rjsontest-Add-test-for-nesting-depth.patch | 45 + libvirt.spec | 3318 +++++++ rpminspect.yaml | 8 + sources | 1 + 89 files changed, 23224 insertions(+) create mode 100644 .abignore create mode 100644 gating.yaml create mode 100644 libvirt-Expose-latency-histograms-via-virConnectGetAllDomainStats.patch create mode 100644 libvirt-Introduce-support-for-disk-operation-latency-histogram-collection.patch create mode 100644 libvirt-RHEL-ONLY-backport-test-data-for-migrate-pr-capability-of-scsi-block.patch 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-docs-formatdomain-Fix-indentation-of-docs-for-disk-driver-statistics-element.patch create mode 100644 libvirt-docs-formatdomain-Reword-section-about-the-statistics-element-under-disk-driver.patch create mode 100644 libvirt-esx-Abstract-all-URL-creation-code-into-one-function.patch create mode 100644 libvirt-esx-Allow-connecting-to-IPv6-server.patch create mode 100644 libvirt-esx-Debug-URL-just-before-opening-with-curl.patch create mode 100644 libvirt-esx-Switch-to-creating-URLs-using-virURIFormat.patch create mode 100644 libvirt-esx-URI-encode-inventory-objects-twice.patch create mode 100644 libvirt-esx_util-Introduce-esxUtil_EscapeInventoryObject.patch create mode 100644 libvirt-iommufd-fix-FD-leak-in-case-of-error.patch create mode 100644 libvirt-qemu-Add-support-for-HW-accelerated-nested-SMMUv3.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-Extract-disk-setup-done-via-QMP-into-a-separate-helper.patch create mode 100644 libvirt-qemu-Fill-iommufd-domain-capability.patch create mode 100644 libvirt-qemu-Ignore-cmp_legacy-CPU-flag.patch create mode 100644 libvirt-qemu-Implement-support-for-associating-iommufd-to-hostdev.patch create mode 100644 libvirt-qemu-Implement-support-for-persistent-reservation-migration-control.patch create mode 100644 libvirt-qemu-Introduce-QEMU_CAPS_OBJECT_IOMMUFD.patch create mode 100644 libvirt-qemu-Introduce-privateData-for-hostdevs.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-Setup-disk-latency-histograms-on-startup-hotplug-update.patch create mode 100644 libvirt-qemu-Support-per-process-memory-accounting-for-iommufd.patch create mode 100644 libvirt-qemu-Update-Cgroup-namespace-and-seclabel-for-iommufd.patch create mode 100644 libvirt-qemu-Use-pci_bus-to-identify-multi-smmuv3-model.patch create mode 100644 libvirt-qemu-add-IOMMU-attribute-cmdqv-for-smmuv3.patch create mode 100644 libvirt-qemu-capabilities-Introduce-QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR.patch create mode 100644 libvirt-qemu-capabilities-Probe-properties-of-scsi-block-and-scsi-generic-devices.patch create mode 100644 libvirt-qemu-migration-Always-offer-block-dirty-bitmaps-during-migration.patch create mode 100644 libvirt-qemu-monitor-Add-handlers-for-block-latency-histogram-set.patch create mode 100644 libvirt-qemu-monitor-Detect-list-of-bitmaps-from-qcow2-format-specific-data.patch create mode 100644 libvirt-qemu-monitor-Extract-block-latency-histogram-stats-into-qemuBlockStats.patch create mode 100644 libvirt-qemu-open-VFIO-FDs-from-libvirt-backend.patch create mode 100644 libvirt-qemu-open-iommufd-FD-from-libvirt-backend.patch create mode 100644 libvirt-qemu-process-Rename-qemuProcessSetupDiskThrottling-to-qemuProcessSetupDisks.patch create mode 100644 libvirt-qemu-tpm-Account-for-possible-migration-without-actually-sharing-storage.patch create mode 100644 libvirt-qemuDomainSetBlockIoTuneField-Move-setting-of-group_name-out-of-the-loop.patch create mode 100644 libvirt-qemuDomainSetThrottleGroup-Always-honour-thottle-group-name-passed-as-argument.patch create mode 100644 libvirt-qemuDomainSetThrottleGroup-Don-t-put-group-name-into-the-tunable-event-twice.patch create mode 100644 libvirt-qemuDomainSetThrottleGroup-Enforce-non-zero-groupname-string-length.patch create mode 100644 libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Always-consider-offered-bitmaps.patch create mode 100644 libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Fix-check-for-existing-bitmaps.patch create mode 100644 libvirt-qemuSecurityMoveImageMetadata-Move-seclabels-only-to-virStorageSource-of-same-type.patch create mode 100644 libvirt-qemuSnapshotDiskHasBackingDisk-Avoid-call-of-virStorageSourceIsSameLocation-with-NULL-argument.patch create mode 100644 libvirt-qemuSnapshotDiskHasBackingDisk-Use-proper-max_depth-when-calling-virStorageSourceGetMetadata.patch create mode 100644 libvirt-qemuSnapshotUpdateBackingStore-Remove-stale-comment.patch create mode 100644 libvirt-qemuSnapshotUpdateBackingStore-Retry-as-curent-user-if-qemu-img-fails.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-qemublocktest-Iterate-all-nodenames-in-testQemuDetectBitmaps.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-src-Use-device-alias-when-ifname-is-unset-in-virDomainInterfaceAddresses.patch create mode 100644 libvirt-src-esx-esx_vi.c-Debug-path-element-comparisons.patch create mode 100644 libvirt-tests-Test-virFileIsSharedFSOverride.patch create mode 100644 libvirt-tests-add-test-for-a-single-per-device-smmuv3.patch create mode 100644 libvirt-tests-properly-mock-VFIO-and-IOMMU-checks.patch create mode 100644 libvirt-tests-qemuxmlconfdata-provide-HW-accel-smmuv3-sample-XML-and-CLI-args.patch create mode 100644 libvirt-tests-qemuxmlconfdata-provide-cmdqv-sample-XML-and-CLI-args.patch create mode 100644 libvirt-tests-qemuxmlconfdata-provide-iommufd-sample-XML-and-CLI-args.patch create mode 100644 libvirt-util-Fix-race-condition-in-virFileIsSharedFSOverride.patch create mode 100644 libvirt-util-Fix-race-condition-in-virFileIsSharedFSType.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-Rework-virFileIsSharedFSOverride-using-virFileCheckParents.patch create mode 100644 libvirt-util-Use-virPCIDevice-as-argument-in-virPCIDeviceGetVfioPath.patch create mode 100644 libvirt-util-json-Increase-JSON-nesting-limit-when-parsing-to-300.patch create mode 100644 libvirt-virDomainSnapshotDefAssignExternalNames-Improve-error-message.patch create mode 100644 libvirt-virjsontest-Add-test-for-nesting-depth.patch create mode 100644 libvirt.spec create mode 100644 rpminspect.yaml create mode 100644 sources diff --git a/.abignore b/.abignore new file mode 100644 index 0000000..7cd584b --- /dev/null +++ b/.abignore @@ -0,0 +1,31 @@ +[suppress_function] +symbol_version_regexp = LIBVIRT_PRIVATE.* +soname_regexp = libvirt\\.so.* + +[suppress_function] +symbol_version_regexp = LIBVIRT_ADMIN_PRIVATE.* +soname_regexp = libvirt-admin\\.so.* + +[suppress_variable] +symbol_version_regexp = LIBVIRT_PRIVATE.* +soname_regexp = libvirt\\.so.* + +[suppress_variable] +symbol_version_regexp = LIBVIRT_ADMIN_PRIVATE.* +soname_regexp = libvirt-admin\\.so.* + +[suppress_function] +symbol_version_regexp = .* +soname_regexp = libvirt_storage_.*\\.so.* + +[suppress_variable] +symbol_version_regexp = .* +soname_regexp = libvirt_storage_.*\\.so.* + +[suppress_function] +symbol_version_regexp = .* +soname_regexp = libvirt_driver_.*\\.so.* + +[suppress_variable] +symbol_version_regexp = .* +soname_regexp = libvirt_driver_.*\\.so.* diff --git a/.gitignore b/.gitignore index e69de29..89f9ab7 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,5 @@ +.build*.log +*.rpm +i686 +x86_64 +libvirt-*.tar.xz diff --git a/gating.yaml b/gating.yaml new file mode 100644 index 0000000..fa93037 --- /dev/null +++ b/gating.yaml @@ -0,0 +1,10 @@ +# recipients: libvirt-qe +--- !Policy +product_versions: + - rhel-10 +decision_context: osci_compose_gate +subject_type: brew-build +rules: + - !PassingTestCaseRule {test_case_name: libvirt-ci.libvirt.brew-build.gating.x86_64.tier1.functional} + - !PassingTestCaseRule {test_case_name: libvirt-ci.libvirt-python.brew-build.gating.x86_64.tier1.functional} + - !PassingTestCaseRule {test_case_name: libvirt-ci.libvirt.brew-build.gating.s390x.tier1.functional} diff --git a/libvirt-Expose-latency-histograms-via-virConnectGetAllDomainStats.patch b/libvirt-Expose-latency-histograms-via-virConnectGetAllDomainStats.patch new file mode 100644 index 0000000..fd28497 --- /dev/null +++ b/libvirt-Expose-latency-histograms-via-virConnectGetAllDomainStats.patch @@ -0,0 +1,248 @@ +From 48f5933f6cd6f53997823cfe2a277b822b00264f Mon Sep 17 00:00:00 2001 +Message-ID: <48f5933f6cd6f53997823cfe2a277b822b00264f.1771336681.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Thu, 29 Jan 2026 18:10:26 +0100 +Subject: [PATCH] Expose latency histograms via 'virConnectGetAllDomainStats' + +Add documentation and constants for constructing the stats field names +for latency histograms and expose them in the qemu driver: + +Example: + + block.1.latency_histogram.read.bin.count=9 + block.1.latency_histogram.read.bin.0.start=0 + block.1.latency_histogram.read.bin.0.value=0 + block.1.latency_histogram.read.bin.1.start=10 + block.1.latency_histogram.read.bin.1.value=0 + block.1.latency_histogram.read.bin.2.start=100 + block.1.latency_histogram.read.bin.2.value=0 + block.1.latency_histogram.read.bin.3.start=1000 + block.1.latency_histogram.read.bin.3.value=1047 + block.1.latency_histogram.read.bin.4.start=10000 + block.1.latency_histogram.read.bin.4.value=2131 + block.1.latency_histogram.read.bin.5.start=100000 + block.1.latency_histogram.read.bin.5.value=0 + block.1.latency_histogram.read.bin.6.start=1000000 + block.1.latency_histogram.read.bin.6.value=0 + block.1.latency_histogram.read.bin.7.start=10000000 + block.1.latency_histogram.read.bin.7.value=0 + block.1.latency_histogram.read.bin.8.start=100000000 + block.1.latency_histogram.read.bin.8.value=0 + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 237e49127a9390f054e33e689ba9db1587cdc9f1) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + docs/manpages/virsh.rst | 7 ++ + include/libvirt/libvirt-domain.h | 113 +++++++++++++++++++++++++++++++ + src/qemu/qemu_driver.c | 43 ++++++++++++ + 3 files changed, 163 insertions(+) + +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index a9d691824e..ff0cf1a715 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -2811,6 +2811,13 @@ Information listed includes: + pending write operations in the defined interval + * ``block..timed_group..zone_append_queue_depth_avg`` - average number + of pending zone append operations in the defined interval ++* ``block..latency_histogram..bin.count`` - number of bins in ++ latency histogram. is one of ``read``, ``write``, ``zone_append``, or ++ ``flush`` ++* ``block..latency_histogram..bin..start`` start boundary of ++ a latency histogram bin in nanoseconds of given operation duration ++* ``block..latency_histogram..bin..value`` current number of ++ events corresponding to the given bin and type + + + *--iothread* returns information about IOThreads on the running guest +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index 16fac6b085..8e62bd23d4 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -3815,6 +3815,119 @@ struct _virDomainStatsRecord { + */ + # define VIR_DOMAIN_STATS_BLOCK_SUFFIX_TIMED_GROUP_SUFFIX_ZONE_APPEND_QUEUE_DEPTH_AVG ".zone_append_queue_depth_avg" + ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX: ++ * ++ * The parameter name prefix to access 'read' latency histograms. Concatenate ++ * the prefix with either: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT ++ * to get the number of bins in given histogram ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and ++ * entry number formatted as an unsigned integer and one of the latency ++ * histogram suffix parameters to compelte a full bin parameter name ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX ".latency_histogram.read." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX: ++ * ++ * The parameter name prefix to access 'write' latency histograms. Concatenate ++ * the prefix with either: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT ++ * to get the number of bins in given histogram ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and ++ * entry number formatted as an unsigned integer and one of the latency ++ * histogram suffix parameters to compelte a full bin parameter name ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX ".latency_histogram.write." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX: ++ * ++ * The parameter name prefix to access 'zone_append' latency histograms. Concatenate ++ * the prefix with either: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT ++ * to get the number of bins in given histogram ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and ++ * entry number formatted as an unsigned integer and one of the latency ++ * histogram suffix parameters to compelte a full bin parameter name ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX ".latency_histogram.zone_append." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX: ++ * ++ * The parameter name prefix to access 'flush' latency histograms. Concatenate ++ * the prefix with either: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT ++ * to get the number of bins in given histogram ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and ++ * entry number formatted as an unsigned integer and one of the latency ++ * histogram suffix parameters to compelte a full bin parameter name ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX ".latency_histogram.flush." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT: ++ * ++ * The parameter name suffix to access number of bins in one of the following ++ * latency histogram types: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX ++ * ++ * Number of bins in latency histogram as unsigned long long. ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT "bin.count" ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX: ++ * ++ * The parameter name suffix to access a latency histogram bin in one of the ++ * following latency histogram types: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX ++ * ++ * Concatenate with a bin number as unsigned int and one of the other field ++ * suffixes to access bin parameters. ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX "bin." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_START: ++ * ++ * Start of the current latency histogram bin in nanoseconds as unsigned long long. ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_START ".start" ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_VALUE: ++ * ++ * Current value of the number of occurences of the latency within this bin ++ * as unsigned long long. ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_VALUE ".value" ++ ++ + /** + * VIR_DOMAIN_STATS_PERF_CMT: + * +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 08a547c546..f3e7410f9e 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -17597,6 +17597,36 @@ qemuDomainGetStatsBlockExportBackendStorage(const char *entryname, + } + + ++static void ++qemuDomainGetStatsBlockExportFrontendLatencyHistogram(struct qemuBlockStatsLatencyHistogram *h, ++ size_t disk_idx, ++ const char *prefix_hist, ++ virTypedParamList *par) ++{ ++ size_t i; ++ ++ if (!h) ++ return; ++ ++ virTypedParamListAddULLong(par, h->nbins, ++ VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu%s" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT, ++ disk_idx, prefix_hist); ++ ++ for (i = 0; i < h->nbins; i++) { ++ virTypedParamListAddULLong(par, h->bins[i].start, ++ VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu%s" ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX "%zu" ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_START, ++ disk_idx, prefix_hist, i); ++ virTypedParamListAddULLong(par, h->bins[i].value, ++ VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu%s" ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX "%zu" ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_VALUE, ++ disk_idx, prefix_hist, i); ++ } ++} ++ ++ + static void + qemuDomainGetStatsBlockExportFrontend(const char *frontendname, + GHashTable *stats, +@@ -17721,6 +17751,19 @@ qemuDomainGetStatsBlockExportFrontend(const char *frontendname, + idx, i); + } + } ++ ++ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_read, idx, ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX, ++ par); ++ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_write, idx, ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX, ++ par); ++ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_zone, idx, ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX, ++ par); ++ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_flush, idx, ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX, ++ par); + } + + +-- +2.53.0 diff --git a/libvirt-Introduce-support-for-disk-operation-latency-histogram-collection.patch b/libvirt-Introduce-support-for-disk-operation-latency-histogram-collection.patch new file mode 100644 index 0000000..c417f58 --- /dev/null +++ b/libvirt-Introduce-support-for-disk-operation-latency-histogram-collection.patch @@ -0,0 +1,422 @@ +From 8fbea435edb1635ec98c9419e9249223e5c3b2b6 Mon Sep 17 00:00:00 2001 +Message-ID: <8fbea435edb1635ec98c9419e9249223e5c3b2b6.1771336682.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Fri, 23 Jan 2026 17:09:27 +0100 +Subject: [PATCH] Introduce support for disk operation latency histogram + collection + +Add config and docs allowing enabling latency histogram collection for +block device operations. + +This patch sets up the docs, schema and XML infrastructure. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit b874c944bd8c4ffa6c51394557587c8c203f1656) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + docs/formatdomain.rst | 41 ++++++ + src/conf/domain_conf.c | 133 +++++++++++++++++- + src/conf/domain_conf.h | 7 + + src/conf/schemas/domaincommon.rng | 37 ++++- + ...isk-statistics-intervals.x86_64-latest.xml | 29 ++++ + .../disk-statistics-intervals.xml | 25 ++++ + 6 files changed, 262 insertions(+), 10 deletions(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 70882c6820..31232deb3c 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -3628,6 +3628,47 @@ paravirtualized driver is specified via the ``disk`` element. + + :since:`Since 11.9.0 (QEMU 10.2, virtio, ide, scsi disks only)`. + ++ Block operation latency histogram collection can be configured using ++ ```` sub-element. The histogram is collected for ++ the whole runtime of the VM, but can be re-started or reconfigured using ++ the `virDomainUpdateDeviceFlags `__ ++ API. Using the same config re-starts histogram collection. ++ ++ The optional ``type`` attribute configures specific operation to collect ++ the histogram for. Supported types are ``read``, ``write``, ``zone``, and ++ ``flush``. If the ``type`` attribute is omitted the histogram collection ++ bins bins apply to all of the aforementioned types, which can be overriden ++ with specific config. ++ ++ The ```` has multiple mandatory ```` sub-elements ++ with mandatory ``start`` attribute configuring the starting boundary of ++ the histogram bin configured in nanosecods of the operation duration and ++ the intervals must be properly ordered and non-duplicate. ++ ++ Example:: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ [or for specific operation types] ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ :since:`Since 12.1.0`. ++ + - The optional ``queues`` attribute specifies the number of virt queues for + virtio-blk ( :since:`Since 3.9.0` ) or vhost-user-blk + ( :since:`Since 7.1.0` ) +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index f5c4d135a9..83c58ab5ff 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -2445,6 +2445,11 @@ virDomainDiskDefFree(virDomainDiskDef *def) + virObjectUnref(def->privateData); + g_slist_free_full(def->iothreads, (GDestroyNotify) virDomainIothreadMappingDefFree); + g_free(def->statistics); ++ g_free(def->histogram_boundaries); ++ g_free(def->histogram_boundaries_read); ++ g_free(def->histogram_boundaries_write); ++ g_free(def->histogram_boundaries_zone); ++ g_free(def->histogram_boundaries_flush); + + if (def->throttlefilters) { + size_t i; +@@ -8307,6 +8312,91 @@ virDomainIothreadMappingDefParse(xmlNodePtr driverNode, + } + + ++static int ++virDomainDiskDefDriverParseXMLHistogramOne(virDomainDiskDef *def, ++ xmlNodePtr cur) ++{ ++ g_autofree char *histogram_type = NULL; ++ unsigned int **histogram_config = NULL; ++ g_autoptr(GPtrArray) binNodes = virXMLNodeGetSubelementList(cur, "bin"); ++ size_t nbins = 0; ++ size_t i; ++ ++ if ((histogram_type = virXMLPropString(cur, "type"))) { ++ if (STREQ(histogram_type, "read")) { ++ histogram_config = &def->histogram_boundaries_read; ++ } else if (STREQ(histogram_type, "write")) { ++ histogram_config = &def->histogram_boundaries_write; ++ } else if (STREQ(histogram_type, "zone")) { ++ histogram_config = &def->histogram_boundaries_zone; ++ } else if (STREQ(histogram_type, "flush")) { ++ histogram_config = &def->histogram_boundaries_flush; ++ } else { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unknown latency_histogram type '%1$s'"), ++ histogram_type); ++ return -1; ++ } ++ } else { ++ histogram_config = &def->histogram_boundaries; ++ } ++ ++ if (*histogram_config) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("only one latency-histogram of a given type is supported")); ++ return -1; ++ } ++ ++ if (binNodes->len == 0) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("missing 'bin' elements for 'latency-histogram'")); ++ return -1; ++ } ++ ++ *histogram_config = g_new0(unsigned int, binNodes->len + 1); ++ ++ for (i = 0; i < binNodes->len; i++) { ++ unsigned int val; ++ ++ if (virXMLPropUInt(g_ptr_array_index(binNodes, i), ++ "start", 10, ++ VIR_XML_PROP_REQUIRED, ++ &val) < 0) ++ return -1; ++ ++ if (nbins > 0 && ++ (val == 0 || ++ val <= (*histogram_config)[nbins-1])) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("the values of 'start' attribute of a 'latency-histogram' 'bin' configuration must be sorted and non-overlapping")); ++ return -1; ++ } ++ ++ if (val > 0) ++ (*histogram_config)[nbins++] = val; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virDomainDiskDefDriverParseXMLHistograms(virDomainDiskDef *def, ++ xmlNodePtr cur) ++{ ++ g_autoptr(GPtrArray) histogramNodes = virXMLNodeGetSubelementList(cur, "latency-histogram"); ++ size_t i; ++ ++ for (i = 0; i < histogramNodes->len; i++) { ++ if (virDomainDiskDefDriverParseXMLHistogramOne(def, ++ g_ptr_array_index(histogramNodes, i)) < 0) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + static int + virDomainDiskDefDriverParseXML(virDomainDiskDef *def, + xmlNodePtr cur) +@@ -8380,6 +8470,9 @@ virDomainDiskDefDriverParseXML(virDomainDiskDef *def, + return -1; + } + } ++ ++ if (virDomainDiskDefDriverParseXMLHistograms(def, statisticsNode) < 0) ++ return -1; + } + + if (virXMLPropEnum(cur, "detect_zeroes", +@@ -23961,12 +24054,37 @@ virDomainDiskDefFormatThrottleFilters(virBuffer *buf, + } + + ++static void ++virDomainDiskDefFormatDriverHistogram(virBuffer *buf, ++ const char *type, ++ unsigned int *bins) ++{ ++ g_auto(virBuffer) histogramAttrBuf = VIR_BUFFER_INITIALIZER; ++ g_auto(virBuffer) histogramChildBuf = VIR_BUFFER_INIT_CHILD(buf); ++ ++ if (!bins || bins[0] == 0) ++ return; ++ ++ if (type) ++ virBufferAsprintf(&histogramAttrBuf, " type='%s'", type); ++ ++ /* we dont store the start boundary of the first bin but it's always there */ ++ virBufferAddLit(&histogramChildBuf, "\n"); ++ ++ for (; *bins > 0; bins++) ++ virBufferAsprintf(&histogramChildBuf, "\n", *bins); ++ ++ virXMLFormatElement(buf, "latency-histogram", &histogramAttrBuf, &histogramChildBuf); ++} ++ ++ + static void + virDomainDiskDefFormatDriver(virBuffer *buf, + virDomainDiskDef *disk) + { + g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf); ++ g_auto(virBuffer) statisticsChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf); + + virBufferEscapeString(&attrBuf, " name='%s'", virDomainDiskGetDriver(disk)); + +@@ -24038,16 +24156,25 @@ virDomainDiskDefFormatDriver(virBuffer *buf, + virDomainIothreadMappingDefFormat(&childBuf, disk->iothreads); + + if (disk->statistics) { +- g_auto(virBuffer) statisticsChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf); + size_t i; + + for (i = 0; disk->statistics[i] > 0; i++) + virBufferAsprintf(&statisticsChildBuf, "\n", + disk->statistics[i]); +- +- virXMLFormatElement(&childBuf, "statistics", NULL, &statisticsChildBuf); + } + ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, NULL, ++ disk->histogram_boundaries); ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "read", ++ disk->histogram_boundaries_read); ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "write", ++ disk->histogram_boundaries_write); ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "zone", ++ disk->histogram_boundaries_zone); ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "flush", ++ disk->histogram_boundaries_flush); ++ ++ virXMLFormatElement(&childBuf, "statistics", NULL, &statisticsChildBuf); + + virXMLFormatElement(buf, "driver", &attrBuf, &childBuf); + } +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 8f53ed96c0..b120d4a68e 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -596,6 +596,13 @@ struct _virDomainDiskDef { + GSList *iothreads; /* List of virDomainIothreadMappingDef */ + unsigned int *statistics; /* Optional, zero terminated list of intervals to + collect statistics for */ ++ /* optional zero terminated lists of bin boundaries for latency histograms */ ++ unsigned int *histogram_boundaries; ++ unsigned int *histogram_boundaries_read; ++ unsigned int *histogram_boundaries_write; ++ unsigned int *histogram_boundaries_zone; ++ unsigned int *histogram_boundaries_flush; ++ + virDomainDiskDetectZeroes detect_zeroes; + virTristateSwitch discard_no_unref; + char *domain_name; /* backend domain name */ +diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng +index 1f9ac102a0..441328a08e 100644 +--- a/src/conf/schemas/domaincommon.rng ++++ b/src/conf/schemas/domaincommon.rng +@@ -2728,13 +2728,36 @@ + + + +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ read ++ write ++ zone ++ flush ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml b/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml +index 4c55c50ef5..d02f954073 100644 +--- a/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml ++++ b/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml +@@ -22,6 +22,11 @@ + + + ++ ++ ++ ++ ++ + + + +@@ -33,6 +38,30 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/qemuxmlconfdata/disk-statistics-intervals.xml b/tests/qemuxmlconfdata/disk-statistics-intervals.xml +index f5e801f5a8..5f9e9470d7 100644 +--- a/tests/qemuxmlconfdata/disk-statistics-intervals.xml ++++ b/tests/qemuxmlconfdata/disk-statistics-intervals.xml +@@ -19,6 +19,11 @@ + + + ++ ++ ++ ++ ++ + + + +@@ -29,6 +34,26 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +-- +2.53.0 diff --git a/libvirt-RHEL-ONLY-backport-test-data-for-migrate-pr-capability-of-scsi-block.patch b/libvirt-RHEL-ONLY-backport-test-data-for-migrate-pr-capability-of-scsi-block.patch new file mode 100644 index 0000000..de4bb90 --- /dev/null +++ b/libvirt-RHEL-ONLY-backport-test-data-for-migrate-pr-capability-of-scsi-block.patch @@ -0,0 +1,125 @@ +From c2eb6d70891d9be5ce13f07946841239a81c3ed9 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Mon, 16 Feb 2026 15:08:54 +0100 +Subject: [PATCH] RHEL-ONLY: backport test data for 'migrate-pr' capability of + 'scsi-block' + +In upstream qemu the capability is present starting with qemu-11.0. We +don't have the test data downstream and backporting them would be too +invasive. Backport the relevant capability detection as a +downstream-only fix. + +https://issues.redhat.com/browse/RHEL-140614 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-135115 [rhel-10.2] + +Signed-off-by: Peter Krempa +--- + .../caps_10.2.0_x86_64.replies | 79 ++++++++++++++++++- + .../caps_10.2.0_x86_64.xml | 1 + + 2 files changed, 76 insertions(+), 4 deletions(-) + +diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies +index cb4abb4533..10db9baca1 100644 +--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies +@@ -33081,10 +33081,81 @@ + } + + { +- "error": { +- "class": "DeviceNotFound", +- "desc": "The libvirt device dump was not collected for this version+device tuple" +- }, ++ "return": [ ++ { ++ "default-value": 4294967295, ++ "name": "scsi-id", ++ "type": "uint32" ++ }, ++ { ++ "default-value": 4294967295, ++ "name": "lun", ++ "type": "uint32" ++ }, ++ { ++ "default-value": 0, ++ "name": "channel", ++ "type": "uint32" ++ }, ++ { ++ "default-value": "auto", ++ "name": "rerror", ++ "description": "Error handling policy (report/ignore/enospc/stop/auto)", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "default-value": 2147483647, ++ "name": "max_io_size", ++ "type": "uint64" ++ }, ++ { ++ "default-value": false, ++ "name": "share-rw", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "default-value": true, ++ "name": "migrate-pr", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "default-value": "auto", ++ "name": "werror", ++ "description": "Error handling policy (report/ignore/enospc/stop/auto)", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "default-value": 1073741824, ++ "name": "max_unmap_size", ++ "type": "uint64" ++ }, ++ { ++ "default-value": -1, ++ "name": "scsi_version", ++ "type": "int32" ++ }, ++ { ++ "default-value": 0, ++ "name": "rotation_rate", ++ "type": "uint16" ++ }, ++ { ++ "name": "drive", ++ "description": "Node name or ID of a block device to use as a backend", ++ "type": "str" ++ }, ++ { ++ "default-value": 30, ++ "name": "io_timeout", ++ "type": "uint32" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ } ++ ], + "id": "libvirt-37" + } + +diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml +index 7cff2c2291..7d5a75ce88 100644 +--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml +@@ -215,6 +215,7 @@ + + + ++ + 10001091 + 43100287 + v10.2.0-rc1-38-gfb241d0a1f +-- +2.53.0 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-docs-formatdomain-Fix-indentation-of-docs-for-disk-driver-statistics-element.patch b/libvirt-docs-formatdomain-Fix-indentation-of-docs-for-disk-driver-statistics-element.patch new file mode 100644 index 0000000..b178d43 --- /dev/null +++ b/libvirt-docs-formatdomain-Fix-indentation-of-docs-for-disk-driver-statistics-element.patch @@ -0,0 +1,62 @@ +From f6268acd96651ce72014e2ea7ed649caff0b9133 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Fri, 30 Jan 2026 17:47:46 +0100 +Subject: [PATCH] docs: formatdomain: Fix indentation of docs for + element + +All other paragraphs in this section use 2 spaces after hyphen, fix the +recently added section. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 7da1a83914ca10cc811583d7310bf60e04b70488) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + docs/formatdomain.rst | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 9836837441..45f262113b 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -3605,22 +3605,22 @@ paravirtualized driver is specified via the ``disk`` element. + + + +- - The optional ``statistics`` sub-element allows configuring statistics +- collection in configurable intervals for the given disk. Intervals are +- configured by ```` sub-elements with ``interval`` attribute +- configuring the collection window duration in seconds. The statistics +- are available via the bulk statistics API. ++ - The optional ``statistics`` sub-element allows configuring statistics ++ collection in configurable intervals for the given disk. Intervals are ++ configured by ```` sub-elements with ``interval`` attribute ++ configuring the collection window duration in seconds. The statistics ++ are available via the bulk statistics API. + +- Example:: ++ Example:: + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + +- :since:`Since 11.9.0 (QEMU 10.2, virtio, ide, scsi disks only)`. ++ :since:`Since 11.9.0 (QEMU 10.2, virtio, ide, scsi disks only)`. + + - The optional ``queues`` attribute specifies the number of virt queues for + virtio-blk ( :since:`Since 3.9.0` ) or vhost-user-blk +-- +2.53.0 diff --git a/libvirt-docs-formatdomain-Reword-section-about-the-statistics-element-under-disk-driver.patch b/libvirt-docs-formatdomain-Reword-section-about-the-statistics-element-under-disk-driver.patch new file mode 100644 index 0000000..a727efe --- /dev/null +++ b/libvirt-docs-formatdomain-Reword-section-about-the-statistics-element-under-disk-driver.patch @@ -0,0 +1,51 @@ +From ea6f8a96929577416a5cc4f4452f920312aef081 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Fri, 30 Jan 2026 17:37:48 +0100 +Subject: [PATCH] docs: formatdomain: Reword section about the '' + element under disk driver + +Separate the timed statistics group and link to the fields which are +returned by it. + +Prepare the wording for more statistics configs in the future. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit ad65b00c1393f7f13e15744e2e1be4fb531e2a17) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + docs/formatdomain.rst | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 45f262113b..70882c6820 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -3605,11 +3605,17 @@ paravirtualized driver is specified via the ``disk`` element. + + + +- - The optional ``statistics`` sub-element allows configuring statistics +- collection in configurable intervals for the given disk. Intervals are +- configured by ```` sub-elements with ``interval`` attribute +- configuring the collection window duration in seconds. The statistics +- are available via the bulk statistics API. ++ - The optional ``statistics`` sub-element allows configuring various optional ++ statistics collection. ++ ++ Statistic values returned under ++ `VIR_DOMAIN_STATS_BLOCK_SUFFIX_TIMED_GROUP_PREFIX `__ ++ typed parameter prefix returned by the ++ `virConnectGetAllDomainStats `__ ++ API are collected based on one or more configurable intervals. An interval ++ of collection is configured by ```` sub-elements with ++ ``interval`` attribute configuring the collection window duration in ++ seconds. + + Example:: + +-- +2.53.0 diff --git a/libvirt-esx-Abstract-all-URL-creation-code-into-one-function.patch b/libvirt-esx-Abstract-all-URL-creation-code-into-one-function.patch new file mode 100644 index 0000000..a6aebca --- /dev/null +++ b/libvirt-esx-Abstract-all-URL-creation-code-into-one-function.patch @@ -0,0 +1,119 @@ +From 95ff5dcad20269f8e26eda628c85168dd4702285 Mon Sep 17 00:00:00 2001 +Message-ID: <95ff5dcad20269f8e26eda628c85168dd4702285.1769699749.git.jdenemar@redhat.com> +From: "Richard W.M. Jones" +Date: Mon, 26 Jan 2026 10:47:01 +0000 +Subject: [PATCH] esx: Abstract all URL-creation code into one function + +Abstract the places where we create URLs into one place. This is just +refactoring and should not change the behaviour. + +Signed-off-by: Richard W.M. Jones +(cherry picked from commit e013d5b5cae732ddeae479098165b9331b8ea441) +Resolves: https://issues.redhat.com/browse/RHEL-138300 +Signed-off-by: Michal Privoznik +--- + src/esx/esx_driver.c | 53 +++++++++++++++++++++++++++++++++++--------- + 1 file changed, 43 insertions(+), 10 deletions(-) + +diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c +index 9f965811b1..29735e359f 100644 +--- a/src/esx/esx_driver.c ++++ b/src/esx/esx_driver.c +@@ -582,7 +582,37 @@ esxCapsInit(esxPrivate *priv) + return NULL; + } + ++static char * ++esxCreateURL(const char *transport, ++ const char *server, ++ int port, ++ const char *path) ++{ ++ char *url; + ++ url = g_strdup_printf("%s://%s:%d%s", ++ transport, ++ server, ++ port, ++ path); ++ return url; ++} ++ ++/* ++ * Same as above, but add it to a buffer because the calling code will ++ * append query strings etc. ++ */ ++static void ++esxCreateURLBuffer(virBuffer *buffer, ++ const char *transport, ++ const char *server, ++ int port, ++ const char *path) ++{ ++ g_autofree char *url = esxCreateURL(transport, server, port, path); ++ ++ virBufferAdd(buffer, url, -1); ++} + + static int + esxConnectToHost(esxPrivate *priv, +@@ -619,8 +649,8 @@ esxConnectToHost(esxPrivate *priv, + conn->uri->server))) + goto cleanup; + +- url = g_strdup_printf("%s://%s:%d/sdk", priv->parsedUri->transport, +- conn->uri->server, conn->uri->port); ++ url = esxCreateURL(priv->parsedUri->transport, ++ conn->uri->server, conn->uri->port, "/sdk"); + + if (esxVI_Context_Alloc(&priv->host) < 0 || + esxVI_Context_Connect(priv->host, url, ipAddress, username, password, +@@ -706,8 +736,8 @@ esxConnectToVCenter(esxPrivate *priv, + if (!(password = virAuthGetPassword(conn, auth, "esx", username, hostname))) + return -1; + +- url = g_strdup_printf("%s://%s:%d/sdk", priv->parsedUri->transport, hostname, +- conn->uri->port); ++ url = esxCreateURL(priv->parsedUri->transport, hostname, ++ conn->uri->port, "/sdk"); + + if (esxVI_Context_Alloc(&priv->vCenter) < 0 || + esxVI_Context_Connect(priv->vCenter, url, ipAddress, username, +@@ -2357,8 +2387,9 @@ esxDomainScreenshot(virDomainPtr domain, virStreamPtr stream, + } + + /* Build URL */ +- virBufferAsprintf(&buffer, "%s://%s:%d/screen?id=", priv->parsedUri->transport, +- domain->conn->uri->server, domain->conn->uri->port); ++ esxCreateURLBuffer(&buffer, priv->parsedUri->transport, ++ domain->conn->uri->server, domain->conn->uri->port, ++ "/screen?id="); + virBufferURIEncodeString(&buffer, virtualMachine->obj->value); + + url = virBufferContentAndReset(&buffer); +@@ -2563,8 +2594,9 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) + goto cleanup; + } + +- virBufferAsprintf(&buffer, "%s://%s:%d/folder/", priv->parsedUri->transport, +- domain->conn->uri->server, domain->conn->uri->port); ++ esxCreateURLBuffer(&buffer, priv->parsedUri->transport, ++ domain->conn->uri->server, domain->conn->uri->port, ++ "/folder/"); + virBufferURIEncodeString(&buffer, directoryAndFileName); + virBufferAddLit(&buffer, "?dcPath="); + virBufferURIEncodeString(&buffer, priv->primary->datacenterPath); +@@ -2987,8 +3019,9 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags) + goto cleanup; + } + +- virBufferAsprintf(&buffer, "%s://%s:%d/folder/", priv->parsedUri->transport, +- conn->uri->server, conn->uri->port); ++ esxCreateURLBuffer(&buffer, priv->parsedUri->transport, ++ conn->uri->server, conn->uri->port, ++ "/folder/"); + + if (directoryName) { + virBufferURIEncodeString(&buffer, directoryName); +-- +2.52.0 diff --git a/libvirt-esx-Allow-connecting-to-IPv6-server.patch b/libvirt-esx-Allow-connecting-to-IPv6-server.patch new file mode 100644 index 0000000..232a8cc --- /dev/null +++ b/libvirt-esx-Allow-connecting-to-IPv6-server.patch @@ -0,0 +1,43 @@ +From 16276aad5c682651e2a5aabe7d5a7258dda251c1 Mon Sep 17 00:00:00 2001 +Message-ID: <16276aad5c682651e2a5aabe7d5a7258dda251c1.1769173967.git.jdenemar@redhat.com> +From: Michal Privoznik +Date: Tue, 20 Jan 2026 10:08:29 +0100 +Subject: [PATCH] esx: Allow connecting to IPv6 server +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When connecting to a VMWare server, the hostname from URI is +resolved using esxUtil_ResolveHostname() which in turn calls +getaddrinfo(). But in the hints argument, we restrict the return +address to be IPv4 (AF_INET) which obviously fails if the address +to resolve is an IPv6 address. Set the hint to AF_UNSPEC which +allows both IPv4 and IPv6. While at it, also allow IPv4 addresses +mapped in IPv6 by setting AI_V4MAPPED flag. + +Resolves: https://issues.redhat.com/browse/RHEL-138300 +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 845210011a9ffd9d17e30c51cbc81ba67c5d3166) +Signed-off-by: Michal Privoznik +--- + src/esx/esx_util.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c +index 7ee0e5f7c0..12a34a2275 100644 +--- a/src/esx/esx_util.c ++++ b/src/esx/esx_util.c +@@ -280,8 +280,8 @@ esxUtil_ResolveHostname(const char *hostname, char **ipAddress) + int errcode; + g_autofree char *address = NULL; + +- hints.ai_flags = AI_ADDRCONFIG; +- hints.ai_family = AF_INET; ++ hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED; ++ hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + +-- +2.52.0 diff --git a/libvirt-esx-Debug-URL-just-before-opening-with-curl.patch b/libvirt-esx-Debug-URL-just-before-opening-with-curl.patch new file mode 100644 index 0000000..a8233ef --- /dev/null +++ b/libvirt-esx-Debug-URL-just-before-opening-with-curl.patch @@ -0,0 +1,29 @@ +From 0e5f062ba33929bc592fff175a2cd9d043a32b23 Mon Sep 17 00:00:00 2001 +Message-ID: <0e5f062ba33929bc592fff175a2cd9d043a32b23.1769699749.git.jdenemar@redhat.com> +From: "Richard W.M. Jones" +Date: Mon, 26 Jan 2026 10:38:02 +0000 +Subject: [PATCH] esx: Debug URL just before opening with curl + +Signed-off-by: Richard W.M. Jones +(cherry picked from commit 38c952d89317f5b4bd23223f9a9d8be086ef7a40) +Resolves: https://issues.redhat.com/browse/RHEL-138300 +Signed-off-by: Michal Privoznik +--- + src/esx/esx_vi.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c +index 3264afc13a..8d2ffb3f8f 100644 +--- a/src/esx/esx_vi.c ++++ b/src/esx/esx_vi.c +@@ -231,6 +231,8 @@ esxVI_CURL_Perform(esxVI_CURL *curl, const char *url) + long responseCode = 0; + const char *redirectUrl = NULL; + ++ VIR_DEBUG("URL: %s", url); ++ + errorCode = curl_easy_perform(curl->handle); + + if (errorCode != CURLE_OK) { +-- +2.52.0 diff --git a/libvirt-esx-Switch-to-creating-URLs-using-virURIFormat.patch b/libvirt-esx-Switch-to-creating-URLs-using-virURIFormat.patch new file mode 100644 index 0000000..a990628 --- /dev/null +++ b/libvirt-esx-Switch-to-creating-URLs-using-virURIFormat.patch @@ -0,0 +1,57 @@ +From 1ac21634942d30288dd11005d1d832b8dda86ceb Mon Sep 17 00:00:00 2001 +Message-ID: <1ac21634942d30288dd11005d1d832b8dda86ceb.1769699749.git.jdenemar@redhat.com> +From: "Richard W.M. Jones" +Date: Mon, 26 Jan 2026 17:54:57 +0000 +Subject: [PATCH] esx: Switch to creating URLs using virURIFormat +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since libvirt has existing support for creating URIs, use that rather +than home-rolling our own code without any escaping. + +As a side-effect this ensures that URLs containing IPv6 addresses are +escaped correctly, for example as below (note square brackets): + + https://[1234:56:0:789a:bcde:72ff:fe0a:7baa]:443/sdk + +Fixes: https://issues.redhat.com/browse/RHEL-138300 +Updates: commit 845210011a9ffd9d17e30c51cbc81ba67c5d3166 +Reported-by: Ming Xie +Signed-off-by: Richard W.M. Jones +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 13889feb14a24fdf7717960aa5331a0b63ce97ed) +Resolves: https://issues.redhat.com/browse/RHEL-138300 +Signed-off-by: Michal Privoznik +--- + src/esx/esx_driver.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c +index 29735e359f..40b7f793cd 100644 +--- a/src/esx/esx_driver.c ++++ b/src/esx/esx_driver.c +@@ -588,14 +588,14 @@ esxCreateURL(const char *transport, + int port, + const char *path) + { +- char *url; ++ virURI uri = { ++ .scheme = (char*)transport, ++ .server = (char*)server, ++ .port = port, ++ .path = (char*)path, ++ }; + +- url = g_strdup_printf("%s://%s:%d%s", +- transport, +- server, +- port, +- path); +- return url; ++ return virURIFormat(&uri); + } + + /* +-- +2.52.0 diff --git a/libvirt-esx-URI-encode-inventory-objects-twice.patch b/libvirt-esx-URI-encode-inventory-objects-twice.patch new file mode 100644 index 0000000..c775ab9 --- /dev/null +++ b/libvirt-esx-URI-encode-inventory-objects-twice.patch @@ -0,0 +1,60 @@ +From 1ff41e00c1d0a280b22ba4f8bf4e86472570486a Mon Sep 17 00:00:00 2001 +Message-ID: <1ff41e00c1d0a280b22ba4f8bf4e86472570486a.1769699749.git.jdenemar@redhat.com> +From: Michal Privoznik +Date: Tue, 6 Jan 2026 17:18:03 +0100 +Subject: [PATCH] esx: URI encode inventory objects twice + +While discouraged by a KB article to use special characters in +inventory object names [1], ESX won't stop you. And thus users +can end up with a datastore named "datastore2+", for instance. +The datastore name (and datacenter path) are important when +fetching/uploading a .vmx file (used in APIs like +virDomainGetXMLDesc() or virDomainDefineXML()). And while we do +URI encode both (dcPath and dsName), encoding them once is not +enough. Cole Robinson discovered [2] that they need to be +URI-encoded twice. Use newly introduced +esxUtil_EscapeInventoryObject() helper to encode them twice. + +1: https://knowledge.broadcom.com/external/article/386368/vcenter-inventory-object-name-with-speci.html +2: https://issues.redhat.com/browse/RHEL-133729#comment-28604072 +Resolves: https://issues.redhat.com/browse/RHEL-134127 +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +Reviewed-by: Richard W.M. Jones +(cherry picked from commit 6c9d2591c668732eb05cf17d27c9102ef3d40b39) +Resolves: https://issues.redhat.com/browse/RHEL-140196 +Signed-off-by: Michal Privoznik +--- + src/esx/esx_driver.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c +index 40b7f793cd..010c62b8e8 100644 +--- a/src/esx/esx_driver.c ++++ b/src/esx/esx_driver.c +@@ -2599,9 +2599,9 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) + "/folder/"); + virBufferURIEncodeString(&buffer, directoryAndFileName); + virBufferAddLit(&buffer, "?dcPath="); +- virBufferURIEncodeString(&buffer, priv->primary->datacenterPath); ++ esxUtil_EscapeInventoryObject(&buffer, priv->primary->datacenterPath); + virBufferAddLit(&buffer, "&dsName="); +- virBufferURIEncodeString(&buffer, datastoreName); ++ esxUtil_EscapeInventoryObject(&buffer, datastoreName); + + url = virBufferContentAndReset(&buffer); + +@@ -3035,9 +3035,9 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags) + + virBufferURIEncodeString(&buffer, escapedName); + virBufferAddLit(&buffer, ".vmx?dcPath="); +- virBufferURIEncodeString(&buffer, priv->primary->datacenterPath); ++ esxUtil_EscapeInventoryObject(&buffer, priv->primary->datacenterPath); + virBufferAddLit(&buffer, "&dsName="); +- virBufferURIEncodeString(&buffer, datastoreName); ++ esxUtil_EscapeInventoryObject(&buffer, datastoreName); + + url = virBufferContentAndReset(&buffer); + +-- +2.52.0 diff --git a/libvirt-esx_util-Introduce-esxUtil_EscapeInventoryObject.patch b/libvirt-esx_util-Introduce-esxUtil_EscapeInventoryObject.patch new file mode 100644 index 0000000..34b11ba --- /dev/null +++ b/libvirt-esx_util-Introduce-esxUtil_EscapeInventoryObject.patch @@ -0,0 +1,76 @@ +From 0776d3a966522785927456bf85037503a9d85bd7 Mon Sep 17 00:00:00 2001 +Message-ID: <0776d3a966522785927456bf85037503a9d85bd7.1769699749.git.jdenemar@redhat.com> +From: Michal Privoznik +Date: Wed, 7 Jan 2026 10:34:25 +0100 +Subject: [PATCH] esx_util: Introduce esxUtil_EscapeInventoryObject() + +The aim of this helper function is to URI-encode given string +twice. There's a bug (fixed in next commit) in which we're unable +to fetch .vmx file for a domain if corresponding datastore +contains some special characters (like +). Cole Robinson +discovered that encoding datastore twice enables libvirt to work +around the issue [2]. Well, this function does exactly that. +It was tested with the following inputs and all worked +flawlessly: "datastore", "datastore2", "datastore2+", +"datastore3+-@", "data store2+". + +1: https://issues.redhat.com/browse/RHEL-134127 +2: https://issues.redhat.com/browse/RHEL-133729#comment-28604072 + +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +Reviewed-by: Richard W.M. Jones +(cherry picked from commit ffe74c7c551bd641cbcaa2512ed0ad4a25d3980b) +Resolves: https://issues.redhat.com/browse/RHEL-140196 +Signed-off-by: Michal Privoznik +--- + src/esx/esx_util.c | 18 ++++++++++++++++++ + src/esx/esx_util.h | 3 +++ + 2 files changed, 21 insertions(+) + +diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c +index 12a34a2275..963bcd0a75 100644 +--- a/src/esx/esx_util.c ++++ b/src/esx/esx_util.c +@@ -448,3 +448,21 @@ esxUtil_EscapeForXml(const char *string) + + return virBufferContentAndReset(&buffer); + } ++ ++ ++/* esxUtil_EscapeInventoryObject: ++ * @buf: the buffer to append to ++ * @string: the string argument which will be URI-encoded ++ * ++ * URI-encode given @string TWICE and append the result to the @buf. This is ++ * to be used with inventory objects (like 'dcPath' and 'dsName') to work ++ * around a VMware bug in which once round of URI-encoding is not enough. ++ */ ++void ++esxUtil_EscapeInventoryObject(virBuffer *buf, const char *string) ++{ ++ g_autoptr(GString) escaped = g_string_new(NULL); ++ ++ g_string_append_uri_escaped(escaped, string, NULL, false); ++ virBufferURIEncodeString(buf, escaped->str); ++} +diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h +index 58bc44e744..29f01e0c15 100644 +--- a/src/esx/esx_util.h ++++ b/src/esx/esx_util.h +@@ -22,6 +22,7 @@ + #pragma once + + #include "internal.h" ++#include "virbuffer.h" + #include "viruri.h" + + #define ESX_VI_CHECK_ARG_LIST(val) \ +@@ -67,3 +68,5 @@ void esxUtil_ReplaceSpecialWindowsPathChars(char *string); + char *esxUtil_EscapeDatastoreItem(const char *string); + + char *esxUtil_EscapeForXml(const char *string); ++ ++void esxUtil_EscapeInventoryObject(virBuffer *buf, const char *string); +-- +2.52.0 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-Add-support-for-HW-accelerated-nested-SMMUv3.patch b/libvirt-qemu-Add-support-for-HW-accelerated-nested-SMMUv3.patch new file mode 100644 index 0000000..9dfecdc --- /dev/null +++ b/libvirt-qemu-Add-support-for-HW-accelerated-nested-SMMUv3.patch @@ -0,0 +1,452 @@ +From 8a7be5ca6f76e60a5a52eaf88e08d276d255ef47 Mon Sep 17 00:00:00 2001 +Message-ID: <8a7be5ca6f76e60a5a52eaf88e08d276d255ef47.1771499562.git.phrdina@redhat.com> +From: Pavel Hrdina +Date: Fri, 30 Jan 2026 10:37:06 -0800 +Subject: [PATCH] qemu: Add support for HW-accelerated nested SMMUv3 + +From: Nathan Chen + +Add support for enabling HW-accelerated nested SMMUv3 +via attribute and its additional attributes for +ATS, SSID, RIL, and OAS configuration. Support element +for specifying PCI hostdev PASID capability offset. + +Signed-off-by: Nathan Chen + +Resolves: https://issues.redhat.com/browse/VOYAGER-4 +--- + docs/formatdomain.rst | 36 +++++++++++ + src/conf/domain_conf.c | 101 +++++++++++++++++++++++++++++- + src/conf/domain_conf.h | 6 ++ + src/conf/domain_validate.c | 36 ++++++++++- + src/conf/schemas/domaincommon.rng | 32 ++++++++++ + src/qemu/qemu_command.c | 23 +++++++ + src/util/virpci.h | 4 ++ + 7 files changed, 233 insertions(+), 5 deletions(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 31232deb3c..9ce647eba7 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -4917,6 +4917,13 @@ or: + device; if PCI ROM loading is disabled through this attribute, attempts to + tweak the loading process further using the ``bar`` or ``file`` attributes + will be rejected. :since:`Since 4.3.0 (QEMU and KVM only)`. ++``vpasidCapOffset`` ++ The ``vpasidCapOffset`` element is used to change the offset at which a ++ PASID PCIe extended capability is placed in a vfio-pci device's PCIe ++ extended configuration space. If not specified or set to 0, the capability ++ is placed at the end of the extended configuration space when PASID is ++ supported. The offset must be 4-byte aligned and within the PCIe extended ++ configuration space. + ``address`` + The ``address`` element for USB devices has a ``bus`` and ``device`` + attribute to specify the USB bus and device number the device appears at on +@@ -9307,6 +9314,35 @@ Example: + The ``pciBus`` attribute notes the index of the controller that an + IOMMU device is attached to. (QEMU/KVM and ``smmuv3`` model only) + ++ ``accel`` ++ The ``accel`` attribute with possible values ``on`` and ``off`` can be used ++ to enable hardware acceleration support for smmuv3Dev IOMMU devices. ++ (QEMU/KVM and ``smmuv3`` model only) ++ ++ ``ats`` ++ The ``ats`` attribute with possible values ``on`` and ``off`` can be used ++ to enable reporting Address Translation Services capability to the guest ++ for smmuv3Dev IOMMU devices with ``accel`` set to ``on``, if the host ++ SMMUv3 supports ATS and the associated passthrough device supports ATS. ++ (QEMU/KVM and ``smmuv3`` model only) ++ ++ ``ril`` ++ The ``ril`` attribute with possible values ``on`` and ``off`` can be used ++ to report whether Range Invalidation for smmuv3Dev IOMMU devices with ++ ``accel`` set to ``on`` is compatible with host SMMUv3 support. ++ (QEMU/KVM and ``smmuv3`` model only) ++ ++ ``ssidSize`` ++ The ``ssidSize`` attribute sets the number of bits used to represent ++ SubstreamIDs. A value of N allows SSIDs in the range [0 .. 2^N - 1]. ++ The valid range is 0-20, and a value greater than 0 is required for ++ enabling PASID support, as doing so advertises PASID capability to ++ the vIOMMU. (QEMU/KVM and ``smmuv3`` model only) ++ ++ ``oas`` ++ The ``oas`` attribute sets the output address size in units of bits. ++ (QEMU/KVM and ``smmuv3`` model only) ++ + The ``virtio`` IOMMU devices can further have ``address`` element as described + in `Device addresses`_ (address has to by type of ``pci``). + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index cb047e5a3e..8ea3206485 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -13777,6 +13777,7 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt, + virDomainHostdevDef *def; + VIR_XPATH_NODE_AUTORESTORE(ctxt) + unsigned int type; ++ int rc; + + ctxt->node = node; + +@@ -13830,8 +13831,16 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt, + def->shareable = true; + break; + +- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: ++ rc = virXPathUIntBase("string(./vpasidCapOffset)", ctxt, ++ 0, &def->vpasidCapOffset); ++ if (rc == -2) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Invalid format for vpasidCapOffset")); ++ goto error; ++ } ++ break; ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: +@@ -14613,6 +14622,26 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, + if (virXMLPropInt(driver, "pciBus", 10, VIR_XML_PROP_NONE, + &iommu->pci_bus, -1) < 0) + return NULL; ++ ++ if (virXMLPropTristateSwitch(driver, "accel", VIR_XML_PROP_NONE, ++ &iommu->accel) < 0) ++ return NULL; ++ ++ if (virXMLPropTristateSwitch(driver, "ats", VIR_XML_PROP_NONE, ++ &iommu->ats) < 0) ++ return NULL; ++ ++ if (virXMLPropTristateSwitch(driver, "ril", VIR_XML_PROP_NONE, ++ &iommu->ril) < 0) ++ return NULL; ++ ++ if (virXMLPropUInt(driver, "ssidSize", 10, VIR_XML_PROP_NONE, ++ &iommu->ssid_size) < 0) ++ return NULL; ++ ++ if (virXMLPropUInt(driver, "oas", 10, VIR_XML_PROP_NONE, ++ &iommu->oas) < 0) ++ return NULL; + } + + if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, +@@ -16676,7 +16705,13 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a, + a->eim != b->eim || + a->iotlb != b->iotlb || + a->aw_bits != b->aw_bits || +- a->dma_translation != b->dma_translation) ++ a->dma_translation != b->dma_translation || ++ a->pci_bus != b->pci_bus || ++ a->accel != b->accel || ++ a->ats != b->ats || ++ a->ril != b->ril || ++ a->ssid_size != b->ssid_size || ++ a->oas != b->oas) + return false; + + if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && +@@ -21432,6 +21467,14 @@ virDomainHostdevDefCheckABIStability(virDomainHostdevDef *src, + } + } + ++ if (src->vpasidCapOffset != dst->vpasidCapOffset) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Target host device vPASID capability offset %1$s does not match source %2$s"), ++ virDomainHostdevModeTypeToString(dst->vpasidCapOffset), ++ virDomainHostdevModeTypeToString(src->vpasidCapOffset)); ++ return false; ++ } ++ + if (!virDomainDeviceInfoCheckABIStability(src->info, dst->info)) + return false; + +@@ -22394,6 +22437,36 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, + dst->pci_bus, src->pci_bus); + return false; + } ++ if (src->accel != dst->accel) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Target domain IOMMU device accel value '%1$d' does not match source '%2$d'"), ++ dst->accel, src->accel); ++ return false; ++ } ++ if (src->ats != dst->ats) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Target domain IOMMU device ATS value '%1$d' does not match source '%2$d'"), ++ dst->ats, src->ats); ++ return false; ++ } ++ if (src->ril != dst->ril) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Target domain IOMMU device ril value '%1$d' does not match source '%2$d'"), ++ dst->ril, src->ril); ++ return false; ++ } ++ if (src->ssid_size != dst->ssid_size) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Target domain IOMMU device ssid_size value '%1$d' does not match source '%2$d'"), ++ dst->ssid_size, src->ssid_size); ++ return false; ++ } ++ if (src->oas != dst->oas) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Target domain IOMMU device oas value '%1$d' does not match source '%2$d'"), ++ dst->oas, src->oas); ++ return false; ++ } + if (src->dma_translation != dst->dma_translation) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device dma translation '%1$s' does not match source '%2$s'"), +@@ -27845,6 +27918,10 @@ virDomainHostdevDefFormat(virBuffer *buf, + if (def->shareable) + virBufferAddLit(buf, "\n"); + ++ if (def->vpasidCapOffset) ++ virBufferAsprintf(buf, "0x%x\n", ++ def->vpasidCapOffset); ++ + virDomainDeviceInfoFormat(buf, def->info, flags | VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT + | VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM); + +@@ -28770,6 +28847,26 @@ virDomainIOMMUDefFormat(virBuffer *buf, + virBufferAsprintf(&driverAttrBuf, " pciBus='%d'", + iommu->pci_bus); + } ++ if (iommu->accel != VIR_TRISTATE_SWITCH_ABSENT) { ++ virBufferAsprintf(&driverAttrBuf, " accel='%s'", ++ virTristateSwitchTypeToString(iommu->accel)); ++ } ++ if (iommu->ats != VIR_TRISTATE_SWITCH_ABSENT) { ++ virBufferAsprintf(&driverAttrBuf, " ats='%s'", ++ virTristateSwitchTypeToString(iommu->ats)); ++ } ++ if (iommu->ril != VIR_TRISTATE_SWITCH_ABSENT) { ++ virBufferAsprintf(&driverAttrBuf, " ril='%s'", ++ virTristateSwitchTypeToString(iommu->ril)); ++ } ++ if (iommu->ssid_size > 0) { ++ virBufferAsprintf(&driverAttrBuf, " ssidSize='%d'", ++ iommu->ssid_size); ++ } ++ if (iommu->oas > 0) { ++ virBufferAsprintf(&driverAttrBuf, " oas='%d'", ++ iommu->oas); ++ } + + virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL); + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 69a8e79c6d..a7afbca2a2 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -372,6 +372,7 @@ struct _virDomainHostdevDef { + bool missing; + bool readonly; + bool shareable; ++ unsigned int vpasidCapOffset; + virTristateBool writeFiltering; + union { + virDomainHostdevSubsys subsys; +@@ -3071,6 +3072,11 @@ struct _virDomainIOMMUDef { + virTristateSwitch dma_translation; + virTristateSwitch xtsup; + virTristateSwitch pt; ++ virTristateSwitch accel; ++ virTristateSwitch ats; ++ virTristateSwitch ril; ++ unsigned int ssid_size; ++ unsigned int oas; + }; + + typedef enum { +diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c +index 4558e7b210..aed5eb0278 100644 +--- a/src/conf/domain_validate.c ++++ b/src/conf/domain_validate.c +@@ -29,6 +29,7 @@ + #include "virutil.h" + #include "virstring.h" + #include "virhostmem.h" ++#include "virpci.h" + + #define VIR_FROM_THIS VIR_FROM_DOMAIN + +@@ -2364,6 +2365,20 @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev) + _("PCI host devices must use 'pci' or 'unassigned' address type")); + return -1; + } ++ if (hostdev->vpasidCapOffset) { ++ if (hostdev->vpasidCapOffset & 0x3) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("vpasidCapOffset must be 4-byte aligned")); ++ return -1; ++ } ++ /* PASID ECAP size of 0x8 */ ++ if (hostdev->vpasidCapOffset < VIR_DOMAIN_PCI_CONFIG_SPACE_SIZE || ++ hostdev->vpasidCapOffset > VIR_DOMAIN_PCIE_CONFIG_SPACE_SIZE - 0x8) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("vpasidCapOffset must be within PCIe extended configuration space (0x100-0xFFF)")); ++ return -1; ++ } ++ } + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: + if (hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && +@@ -3140,7 +3155,12 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) + iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT || + iommu->aw_bits != 0 || + iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || +- iommu->pci_bus >= 0) { ++ iommu->pci_bus >= 0 || ++ iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->ats != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->ril != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->ssid_size != 0 || ++ iommu->oas != 0) { + virReportError(VIR_ERR_XML_ERROR, + _("iommu model '%1$s' doesn't support additional attributes"), + virDomainIOMMUModelTypeToString(iommu->model)); +@@ -3153,7 +3173,12 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) + iommu->eim != VIR_TRISTATE_SWITCH_ABSENT || + iommu->aw_bits != 0 || + iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || +- iommu->pci_bus >= 0) { ++ iommu->pci_bus >= 0 || ++ iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->ats != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->ril != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->ssid_size != 0 || ++ iommu->oas != 0) { + virReportError(VIR_ERR_XML_ERROR, + _("iommu model '%1$s' doesn't support some additional attributes"), + virDomainIOMMUModelTypeToString(iommu->model)); +@@ -3164,7 +3189,12 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) + case VIR_DOMAIN_IOMMU_MODEL_INTEL: + if (iommu->pt != VIR_TRISTATE_SWITCH_ABSENT || + iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT || +- iommu->pci_bus >= 0) { ++ iommu->pci_bus >= 0 || ++ iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->ats != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->ril != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->ssid_size != 0 || ++ iommu->oas != 0) { + virReportError(VIR_ERR_XML_ERROR, + _("iommu model '%1$s' doesn't support some additional attributes"), + virDomainIOMMUModelTypeToString(iommu->model)); +diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng +index 441328a08e..6de939c9f5 100644 +--- a/src/conf/schemas/domaincommon.rng ++++ b/src/conf/schemas/domaincommon.rng +@@ -6339,6 +6339,31 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -6620,6 +6645,13 @@ + + + ++ ++ ++ ++ (0x[0-9a-fA-F]+|[0-9]+) ++ ++ ++ + + + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 521aefbc10..e7c6e1d0eb 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -4812,6 +4812,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, + "B:ramfb", ramfb, + "S:iommufd", iommufdId, + "S:fd", fdstr, ++ "p:x-vpasid-cap-offset", dev->vpasidCapOffset, + NULL) < 0) + return NULL; + +@@ -6323,9 +6324,31 @@ qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def, + "s:driver", "arm-smmuv3", + "s:primary-bus", bus, + "s:id", iommu->info.alias, ++ "B:accel", (iommu->accel == VIR_TRISTATE_SWITCH_ON), ++ "B:ats", (iommu->ats == VIR_TRISTATE_SWITCH_ON), + NULL) < 0) + return NULL; + ++ /* QEMU SMMUv3 has RIL support by default; only emit when explicitly disabling */ ++ if (iommu->ril == VIR_TRISTATE_SWITCH_OFF) { ++ if (virJSONValueObjectAppendBoolean(props, "ril", false) < 0) ++ return NULL; ++ } ++ ++ if (iommu->ssid_size > 0) { ++ if (virJSONValueObjectAdd(&props, ++ "p:ssidsize", iommu->ssid_size, ++ NULL) < 0) ++ return NULL; ++ } ++ ++ if (iommu->oas > 0) { ++ if (virJSONValueObjectAdd(&props, ++ "p:oas", iommu->oas, ++ NULL) < 0) ++ return NULL; ++ } ++ + return g_steal_pointer(&props); + } + +diff --git a/src/util/virpci.h b/src/util/virpci.h +index 933099da6c..04bf586e76 100644 +--- a/src/util/virpci.h ++++ b/src/util/virpci.h +@@ -35,6 +35,10 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDeviceList, virObjectUnref); + + #define VIR_DOMAIN_DEVICE_ZPCI_MAX_UID UINT16_MAX + #define VIR_DOMAIN_DEVICE_ZPCI_MAX_FID UINT32_MAX ++/* Size of the standard PCI config space */ ++#define VIR_DOMAIN_PCI_CONFIG_SPACE_SIZE 0x100 ++/* Size of the standard PCIe config space: 4KB */ ++#define VIR_DOMAIN_PCIE_CONFIG_SPACE_SIZE 0x1000 + + typedef struct _virZPCIDeviceAddressID virZPCIDeviceAddressID; + typedef struct _virZPCIDeviceAddress virZPCIDeviceAddress; +-- +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-Extract-disk-setup-done-via-QMP-into-a-separate-helper.patch b/libvirt-qemu-Extract-disk-setup-done-via-QMP-into-a-separate-helper.patch new file mode 100644 index 0000000..9e8f997 --- /dev/null +++ b/libvirt-qemu-Extract-disk-setup-done-via-QMP-into-a-separate-helper.patch @@ -0,0 +1,144 @@ +From 92a7fef67b736e20c8e94f3407df7a984ee59102 Mon Sep 17 00:00:00 2001 +Message-ID: <92a7fef67b736e20c8e94f3407df7a984ee59102.1771336681.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Thu, 29 Jan 2026 11:15:04 +0100 +Subject: [PATCH] qemu: Extract disk setup done via QMP into a separate helper + +Introduce 'qemuProcessSetupDiskPropsRuntime' helper function which will +collect all code used for runtime setup of a disk. + +This is currently old-style throttling. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 1789a0f8a3623e8f0f6e50730feb58e3d8c48376) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] + +Conflicts: + - Commit b9b9092c9c1f8b42e311c524d9fc4a8e73ae28a6 which dropped disk + property refresh was not backported, thus the context around the call + to qemuProcessSetupDiskPropsRuntime was different +--- + src/qemu/qemu_hotplug.c | 23 +++++------------------ + src/qemu/qemu_process.c | 37 +++++++++++++++++++++++++++---------- + src/qemu/qemu_process.h | 3 +++ + 3 files changed, 35 insertions(+), 28 deletions(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index fb426deb1a..f2dc4469a3 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -569,13 +569,8 @@ qemuDomainChangeMediaBlockdev(virDomainObj *vm, + } + + /* set throttling for the new image */ +- if (rc == 0 && +- !virStorageSourceIsEmpty(newsrc) && +- qemuDiskConfigBlkdeviotuneEnabled(disk)) { +- rc = qemuMonitorSetBlockIoThrottle(priv->mon, +- diskPriv->qomName, +- &disk->blkdeviotune); +- } ++ if (rc == 0) ++ rc = qemuProcessSetupDiskPropsRuntime(priv->mon, disk); + + if (rc == 0) + rc = qemuMonitorBlockdevTrayClose(priv->mon, diskPriv->qomName); +@@ -795,21 +790,13 @@ qemuDomainAttachDiskGeneric(virDomainObj *vm, + if (rc == 0) + rc = qemuMonitorAddDeviceProps(priv->mon, &devprops); + +- /* Setup throttling of disk via block_set_io_throttle QMP command. This +- * is a hack until the 'throttle' blockdev driver will support modification +- * of the trhottle group. See also qemuProcessSetupDiskThrottlingBlockdev. +- * As there isn't anything sane to do if this fails, let's just return +- * success. +- */ + if (rc == 0) { + qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); + g_autoptr(GHashTable) blockinfo = NULL; + +- if (qemuDiskConfigBlkdeviotuneEnabled(disk)) { +- if (qemuMonitorSetBlockIoThrottle(priv->mon, diskPriv->qomName, +- &disk->blkdeviotune) < 0) +- VIR_WARN("failed to set blkdeviotune for '%s' of '%s'", disk->dst, vm->def->name); +- } ++ /* There isn't anything sane to do if this fails (rollback would ++ * require hot-unplug), let's just return success. */ ++ ignore_value(qemuProcessSetupDiskPropsRuntime(priv->mon, disk)); + + if ((blockinfo = qemuMonitorGetBlockInfo(priv->mon))) { + struct qemuDomainDiskInfo *diskinfo; +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index d8f0c78fd1..c99bb36c93 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7937,6 +7937,32 @@ qemuProcessGenID(virDomainObj *vm, + } + + ++/** ++ * qemuProcessSetupDiskPropsRuntime: ++ * @mon: qemu monitor object ++ * @disk: disk definition ++ * ++ * This function expects that caller already entered 'monitor' context. ++ * ++ * Sets up disk properties which are only possible to be set in runtime. ++ */ ++int ++qemuProcessSetupDiskPropsRuntime(qemuMonitor *mon, ++ virDomainDiskDef *disk) ++{ ++ if (virStorageSourceIsEmpty(disk->src)) ++ return 0; ++ ++ if (qemuDiskConfigBlkdeviotuneEnabled(disk) && ++ qemuMonitorSetBlockIoThrottle(mon, ++ QEMU_DOMAIN_DISK_PRIVATE(disk)->qomName, ++ &disk->blkdeviotune) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ + /** + * qemuProcessSetupDiskThrottling: + * +@@ -7960,16 +7986,7 @@ qemuProcessSetupDiskThrottling(virDomainObj *vm, + for (i = 0; i < vm->def->ndisks; i++) { + virDomainDiskDef *disk = vm->def->disks[i]; + +- /* Setting throttling for empty drives fails */ +- if (virStorageSourceIsEmpty(disk->src)) +- continue; +- +- if (!qemuDiskConfigBlkdeviotuneEnabled(disk)) +- continue; +- +- if (qemuMonitorSetBlockIoThrottle(qemuDomainGetMonitor(vm), +- QEMU_DOMAIN_DISK_PRIVATE(disk)->qomName, +- &disk->blkdeviotune) < 0) ++ if (qemuProcessSetupDiskPropsRuntime(qemuDomainGetMonitor(vm), disk) < 0) + goto cleanup; + } + +diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h +index 426e11d79e..df78b00abb 100644 +--- a/src/qemu/qemu_process.h ++++ b/src/qemu/qemu_process.h +@@ -146,6 +146,9 @@ int qemuProcessPrepareHostStorageSourceChain(virDomainObj *vm, + int qemuProcessPrepareHostStorageDisk(virDomainObj *vm, + virDomainDiskDef *disk); + ++int qemuProcessSetupDiskPropsRuntime(qemuMonitor *mon, ++ virDomainDiskDef *disk); ++ + int qemuProcessDeleteThreadContext(virDomainObj *vm); + + int qemuProcessLaunch(virConnectPtr conn, +-- +2.53.0 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-Ignore-cmp_legacy-CPU-flag.patch b/libvirt-qemu-Ignore-cmp_legacy-CPU-flag.patch new file mode 100644 index 0000000..376b23d --- /dev/null +++ b/libvirt-qemu-Ignore-cmp_legacy-CPU-flag.patch @@ -0,0 +1,713 @@ +From 636b8f50486f3007be1b92ddb84f326f58d168d8 Mon Sep 17 00:00:00 2001 +Message-ID: <636b8f50486f3007be1b92ddb84f326f58d168d8.1770825107.git.jdenemar@redhat.com> +From: Jean-Louis Dupond +Date: Thu, 5 Feb 2026 14:18:42 +0100 +Subject: [PATCH] qemu: Ignore cmp_legacy CPU flag + +Since commit 99a637a8 in qemu 10.0, the way the cmp_legacy flag is +reported changed. The same way as happend with the 'ht' flag in commit +c6bd2dd634208, which was fixed in libvirt since commit ba16113c. + +This causes migrations from a hypervisor running a qemu version before +that commit to a hypervisor running qemu after that commit fails +with the following error: +guest CPU doesn't match specification: extra features: cmp_legacy + +We can just ignore this flag, just like we did with the 'ht' flag. + +Signed-off-by: Jean-Louis Dupond +Reviewed-by: Jiri Denemark +(cherry picked from commit fc5840b4980045a05b8973900cdbe36162e48331) + +https://issues.redhat.com/browse/RHEL-148494 + +Conflicts: + tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args + tests/qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args + tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-latest.args + - upstream commit v11.10.0-78-g380764992d + (qemucapabilitiesdata: Re-generate 'caps_10.2.0_x86_64') + that added rdseed=off to test files is not backported + + tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args + - missing downstream, it was added upstream after the last + rebase + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_capabilities.c | 1 + + .../cpu-host-model-fallback-kvm.x86_64-10.0.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-10.1.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-6.2.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-7.0.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-7.1.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-7.2.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-8.0.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-8.1.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-8.2.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-9.0.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-9.1.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-9.2.0.args | 2 +- + .../cpu-host-model-fallback-kvm.x86_64-latest.args | 2 +- + .../cpu-host-model-fallback-tcg.x86_64-10.1.0.args | 2 +- + .../cpu-host-model-fallback-tcg.x86_64-latest.args | 2 +- + .../qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.2.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.0.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.1.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.2.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.0.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.1.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-10.0.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-10.1.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-6.2.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-7.0.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-7.1.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-7.2.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-8.0.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-8.1.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-8.2.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-9.0.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-9.1.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-9.2.0.args | 2 +- + .../cpu-host-model-nofallback-kvm.x86_64-latest.args | 2 +- + .../cpu-host-model-nofallback-tcg.x86_64-10.1.0.args | 2 +- + .../cpu-host-model-nofallback-tcg.x86_64-latest.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.args | 2 +- + tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-latest.args | 2 +- + tests/qemuxmlconfdata/cpu-translation.x86_64-latest.args | 2 +- + 48 files changed, 48 insertions(+), 47 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 92b863a826..d738805ee8 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -3772,6 +3772,7 @@ const char *ignoredFeatures[] = { + "vmx-ept-uc", "vmx-ept-wb", /* never supported by QEMU */ + "vmx-invvpid-single-context", /* never supported by QEMU */ + "ht", /* ignored by QEMU, set according to topology */ ++ "cmp_legacy", /* ignored by QEMU, set according to topology */ + }; + + bool +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.0.0.args +index edd334dd8b..08f37274b2 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.1.0.args +index 57982574eb..e4044a0c64 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-10.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-6.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-6.2.0.args +index 4aa9011fe8..e8a9aceb4a 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-6.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-6.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-6.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.0.0.args +index e944e69cfd..0df6ce9e3d 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-7.0,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.1.0.args +index d9edda2733..b4a91fa921 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-7.1,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.2.0.args +index 1d1839b7fa..5d69199876 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-7.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-7.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.0.0.args +index 8278629ee7..e7b424819e 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-8.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.1.0.args +index 3b733a3c5d..58ad565dba 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-8.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.2.0.args +index 73296c7df0..fa1b674fa5 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-8.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-8.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.0.0.args +index 8f8b74fa56..fc9985f901 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-9.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.1.0.args +index c2f394bf09..1db86cb31e 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-9.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.2.0.args +index 35c8d397c4..4dcd9332cb 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-9.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-9.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args +index 6afa8a4c2d..e5b0acb87b 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-kvm.x86_64-latest.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off \ ++-cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-10.1.0.args +index 3b93ed510d..0b67c7f158 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-10.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-10.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel tcg \ +--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ ++-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-latest.args +index 01cf90bb67..443de62f69 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-fallback-tcg.x86_64-latest.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel tcg \ +--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ ++-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args +index ce60a39acc..52f636fa77 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-features.x86_64-latest.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off,abm=on,ds=on,invtsc=off \ ++-cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off,abm=on,ds=on,invtsc=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.args +index a1c034ec51..7dd5723b98 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.args +index ddf940f75c..987baa9b30 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-10.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.2.0.args +index f65444948e..4402bad82d 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-6.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-6.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.0.0.args +index 8f8b1645d5..d6dfadc3b2 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-7.0,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.1.0.args +index df03bafab3..09e220487d 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-7.1,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.2.0.args +index 7a796812fa..7e90b309a9 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-7.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-7.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.0.0.args +index d63438e81c..fc02c9a7e0 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-8.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.1.0.args +index 901f279a02..8360dc02ef 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-8.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.args +index d141aca9f0..b00138933c 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-8.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-8.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.args +index 49575ff4d9..3b42130bd2 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-9.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.args +index fd25e4cd23..c451426cdd 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-9.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.args +index 4b69f59064..1da6e508ff 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-9.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-9.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args +index 2bf920b9c7..30010edb3b 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-kvm.x86_64-latest.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off \ ++-cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.0.0.args +index edd334dd8b..08f37274b2 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-10.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.1.0.args +index 57982574eb..e4044a0c64 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-10.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-6.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-6.2.0.args +index 4aa9011fe8..e8a9aceb4a 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-6.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-6.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-6.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.0.0.args +index e944e69cfd..0df6ce9e3d 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-7.0,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.1.0.args +index d9edda2733..b4a91fa921 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-7.1,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,tsc-scale=on,vmcb-clean=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.2.0.args +index 1d1839b7fa..5d69199876 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-7.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-7.2,usb=off,dump-guest-core=off,memory-backend=pc.ram \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.0.0.args +index 8278629ee7..e7b424819e 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-8.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.1.0.args +index 3b733a3c5d..58ad565dba 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-8.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.2.0.args +index 73296c7df0..fa1b674fa5 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-8.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-8.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.0.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.0.0.args +index 8f8b74fa56..fc9985f901 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.0.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.0.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-9.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.1.0.args +index c2f394bf09..1db86cb31e 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-9.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.2.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.2.0.args +index 35c8d397c4..4dcd9332cb 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.2.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-9.2.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-9.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ ++-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,overflow-recov=on,succor=on,amd-ssbd=on,virt-ssbd=on,lbrv=on,tsc-scale=on,vmcb-clean=on,flushbyasid=on,pause-filter=on,pfthreshold=on,v-vmsave-vmload=on,vgif=on,svme-addr-chk=on,lfence-always-serializing=on,null-sel-clr-base=on,ibpb-brtype=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,gds-no=on,rfds-no=on,xsaves=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-latest.args +index 6afa8a4c2d..e5b0acb87b 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-kvm.x86_64-latest.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel kvm \ +--cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off \ ++-cpu EPYC-Turin,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,spec-ctrl=on,stibp=on,flush-l1d=on,ssbd=on,virt-ssbd=on,tsa-sq-no=on,tsa-l1-no=on,pcid=off,la57=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-10.1.0.args +index 3b93ed510d..0b67c7f158 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-10.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-10.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-i440fx-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel tcg \ +--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ ++-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-latest.args +index 01cf90bb67..443de62f69 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-nofallback-tcg.x86_64-latest.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel tcg \ +--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ ++-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.args b/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.args +index 4defeceac3..d12cb96786 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-10.1.0.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc-q35-10.1,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel tcg \ +--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ ++-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-latest.args +index 479266659a..688a217c3c 100644 +--- a/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/cpu-host-model-tcg.x86_64-latest.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel tcg \ +--cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ ++-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +diff --git a/tests/qemuxmlconfdata/cpu-translation.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-translation.x86_64-latest.args +index 49e1b590dd..d425866c67 100644 +--- a/tests/qemuxmlconfdata/cpu-translation.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/cpu-translation.x86_64-latest.args +@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ + -machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ + -accel tcg \ +--cpu Haswell,pclmulqdq=on,ds-cpl=on,tsc-adjust=on,fxsr-opt=on,lahf-lm=on,cmp-legacy=on,nodeid-msr=on,perfctr-core=on,perfctr-nb=on,kvm-pv-eoi=on,kvm-pv-unhalt=on \ ++-cpu Haswell,pclmulqdq=on,ds-cpl=on,tsc-adjust=on,fxsr-opt=on,lahf-lm=on,nodeid-msr=on,perfctr-core=on,perfctr-nb=on,kvm-pv-eoi=on,kvm-pv-unhalt=on \ + -m size=219136k \ + -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ + -overcommit mem-lock=off \ +-- +2.53.0 diff --git a/libvirt-qemu-Implement-support-for-associating-iommufd-to-hostdev.patch b/libvirt-qemu-Implement-support-for-associating-iommufd-to-hostdev.patch new file mode 100644 index 0000000..8378479 --- /dev/null +++ b/libvirt-qemu-Implement-support-for-associating-iommufd-to-hostdev.patch @@ -0,0 +1,191 @@ +From bb8ef43213cb1f8c123cdcc693d99a30b09dfa16 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Nathan Chen +Date: Fri, 30 Jan 2026 10:59:12 -0800 +Subject: [PATCH] qemu: Implement support for associating iommufd to hostdev +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement a new iommufd attribute under hostdevs' PCI +subsystem driver that can be used to specify associated +iommufd object when launching a qemu VM. + +Signed-off-by: Ján Tomko +Signed-off-by: Nathan Chen +Reviewed-by: Pavel Hrdina +(cherry picked from commit fd113055bb174c7284081731d16959f73796e3d7) + +Resolves: https://issues.redhat.com/browse/RHEL-74202 +Resolves: https://issues.redhat.com/browse/RHEL-126346 + +Signed-off-by: Pavel Hrdina +--- + docs/formatdomain.rst | 6 +++++ + src/conf/device_conf.c | 11 ++++++++ + src/conf/device_conf.h | 1 + + src/conf/schemas/basictypes.rng | 5 ++++ + src/qemu/qemu_command.c | 46 +++++++++++++++++++++++++++++++++ + 5 files changed, 69 insertions(+) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 1467fc7e10..167912348e 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -4907,6 +4907,12 @@ or: + found is "problematic" in some way, the generic vfio-pci driver + similarly be forced. + ++ :since:`Since 12.1.0 (QEMU and KVM only)`, the ``iommufd`` element ++ can be used to enable IOMMUFD backend for VFIO device. This ++ provides an interface to propagate DMA mappings to kernel for ++ assigned devices. Libvirt will open the /dev/iommu and VFIO device ++ cdev and pass associated file descriptors to QEMU. ++ + (Note: :since:`Since 1.0.5`, the ``name`` attribute has been + described to be used to select the type of PCI device assignment + ("vfio", "kvm", or "xen"), but those values have been mostly +diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c +index c278b81652..d68232a4f4 100644 +--- a/src/conf/device_conf.c ++++ b/src/conf/device_conf.c +@@ -67,6 +67,11 @@ virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr node, + return -1; + } + ++ if (virXMLPropTristateBool(node, "iommufd", ++ VIR_XML_PROP_NONE, ++ &driver->iommufd) < 0) ++ return -1; ++ + driver->model = virXMLPropString(node, "model"); + return 0; + } +@@ -93,6 +98,12 @@ virDeviceHostdevPCIDriverInfoFormat(virBuffer *buf, + + virBufferEscapeString(&driverAttrBuf, " model='%s'", driver->model); + ++ if (driver->iommufd == VIR_TRISTATE_BOOL_YES) { ++ virBufferAddLit(&driverAttrBuf, " iommufd='yes'"); ++ } else if (driver->iommufd == VIR_TRISTATE_BOOL_NO) { ++ virBufferAddLit(&driverAttrBuf, " iommufd='no'"); ++ } ++ + virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL); + return 0; + } +diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h +index e570f51824..116b959143 100644 +--- a/src/conf/device_conf.h ++++ b/src/conf/device_conf.h +@@ -47,6 +47,7 @@ VIR_ENUM_DECL(virDeviceHostdevPCIDriverName); + struct _virDeviceHostdevPCIDriverInfo { + virDeviceHostdevPCIDriverName name; + char *model; ++ virTristateBool iommufd; + }; + + typedef enum { +diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng +index 5689170fad..381e0ac24f 100644 +--- a/src/conf/schemas/basictypes.rng ++++ b/src/conf/schemas/basictypes.rng +@@ -673,6 +673,11 @@ + + + ++ ++ ++ ++ ++ + + + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index fb89dbec27..1fb31d1721 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -4754,6 +4754,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, + g_autofree char *host = virPCIDeviceAddressAsString(&pcisrc->addr); + const char *failover_pair_id = NULL; + const char *driver = NULL; ++ const char *iommufdId = NULL; + /* 'ramfb' property must be omitted unless it's to be enabled */ + bool ramfb = pcisrc->ramfb == VIR_TRISTATE_SWITCH_ON; + +@@ -4787,6 +4788,9 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, + teaming->persistent) + failover_pair_id = teaming->persistent; + ++ if (pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_YES) ++ iommufdId = "iommufd0"; ++ + if (virJSONValueObjectAdd(&props, + "s:driver", driver, + "s:host", host, +@@ -4795,6 +4799,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, + "S:failover_pair_id", failover_pair_id, + "S:display", qemuOnOffAuto(pcisrc->display), + "B:ramfb", ramfb, ++ "S:iommufd", iommufdId, + NULL) < 0) + return NULL; + +@@ -5314,6 +5319,44 @@ qemuBuildHostdevCommandLine(virCommand *cmd, + } + + ++static int ++qemuBuildIOMMUFDCommandLine(virCommand *cmd, ++ const virDomainDef *def) ++{ ++ size_t i; ++ ++ for (i = 0; i < def->nhostdevs; i++) { ++ virDomainHostdevDef *hostdev = def->hostdevs[i]; ++ virDomainHostdevSubsys *subsys = &hostdev->source.subsys; ++ g_autoptr(virJSONValue) props = NULL; ++ ++ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) ++ continue; ++ ++ if (subsys->type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) ++ continue; ++ ++ if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED) ++ continue; ++ ++ if (subsys->u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) ++ continue; ++ ++ if (qemuMonitorCreateObjectProps(&props, "iommufd", ++ "iommufd0", ++ NULL) < 0) ++ return -1; ++ ++ if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0) ++ return -1; ++ ++ break; ++ } ++ ++ return 0; ++} ++ ++ + static int + qemuBuildMonitorCommandLine(virCommand *cmd, + qemuDomainObjPrivate *priv) +@@ -10926,6 +10969,9 @@ qemuBuildCommandLine(virDomainObj *vm, + if (qemuBuildRedirdevCommandLine(cmd, def, qemuCaps) < 0) + return NULL; + ++ if (qemuBuildIOMMUFDCommandLine(cmd, def) < 0) ++ return NULL; ++ + if (qemuBuildHostdevCommandLine(cmd, def, qemuCaps) < 0) + return NULL; + +-- +2.52.0 diff --git a/libvirt-qemu-Implement-support-for-persistent-reservation-migration-control.patch b/libvirt-qemu-Implement-support-for-persistent-reservation-migration-control.patch new file mode 100644 index 0000000..9194604 --- /dev/null +++ b/libvirt-qemu-Implement-support-for-persistent-reservation-migration-control.patch @@ -0,0 +1,220 @@ +From 3f03b1cbc20d0af7900cc43cc576a356a95a292b Mon Sep 17 00:00:00 2001 +Message-ID: <3f03b1cbc20d0af7900cc43cc576a356a95a292b.1771336681.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Thu, 11 Dec 2025 19:47:16 +0100 +Subject: [PATCH] qemu: Implement support for persistent reservation migration + control + +The 'migration' attribute for the '' element allows to +control the persistent reservation migration feature independently of +the machine type default. + +Add the XML plumbing and qemu support. + +We consider it ABI for now since it influences qemu migration protocol. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 0d3ef7cb71979172de2c531d865e4525a314f902) + +https://issues.redhat.com/browse/RHEL-140614 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-135115 [rhel-10.2] +--- + docs/formatdomain.rst | 3 +++ + src/conf/domain_conf.c | 21 +++++++++++++++++++ + src/conf/schemas/storagecommon.rng | 5 +++++ + src/conf/storage_source_conf.c | 10 +++++++++ + src/conf/storage_source_conf.h | 2 ++ + src/qemu/qemu_command.c | 4 ++++ + src/qemu/qemu_validate.c | 16 ++++++++++++++ + ...irtio-scsi-reservations.x86_64-latest.args | 2 +- + .../disk-virtio-scsi-reservations.xml | 2 +- + 9 files changed, 63 insertions(+), 2 deletions(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 167912348e..9836837441 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -3169,6 +3169,9 @@ paravirtualized driver is specified via the ``disk`` element. + the socket, and finally ``mode`` which accepts one value ``client`` + specifying the role of hypervisor. It's recommended to allow libvirt + manage the persistent reservations. ++ :since:`Since 12.1.0` the ``migration`` (values ``yes``, ``no``) controls ++ whether the hypervisor should attempt to migrate persistent reservations ++ during migration. + ``initiator`` + :since:`Since 4.7.0`, the ``initiator`` element is supported for + a disk ``type`` "network" that is using a ``source`` element with the +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 902c1188ef..f5c4d135a9 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -20951,6 +20951,27 @@ virDomainDiskDefCheckABIStability(virDomainDiskDef *src, + return false; + } + ++ /* While not guest visible it influences the qemu migration stream so ++ * we need to keep it identical */ ++ if (src->src->pr || dst->src->pr) { ++ virTristateBool srcmig = VIR_TRISTATE_BOOL_ABSENT; ++ virTristateBool dstmig = VIR_TRISTATE_BOOL_ABSENT; ++ ++ if (src->src->pr) ++ srcmig = src->src->pr->migration; ++ ++ if (dst->src->pr) ++ dstmig = dst->src->pr->migration; ++ ++ if (srcmig != dstmig) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Target disk reservations 'migration' property %1$s does not match source %2$s"), ++ virTristateBoolTypeToString(dstmig), ++ virTristateBoolTypeToString(srcmig)); ++ return false; ++ } ++ } ++ + if (!virDomainVirtioOptionsCheckABIStability(src->virtio, dst->virtio)) + return false; + +diff --git a/src/conf/schemas/storagecommon.rng b/src/conf/schemas/storagecommon.rng +index 14704c737e..450d53131f 100644 +--- a/src/conf/schemas/storagecommon.rng ++++ b/src/conf/schemas/storagecommon.rng +@@ -104,6 +104,11 @@ + + + ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c +index 087de1eaf2..24d4b0de6a 100644 +--- a/src/conf/storage_source_conf.c ++++ b/src/conf/storage_source_conf.c +@@ -330,6 +330,11 @@ virStoragePRDefParseXML(xmlXPathContextPtr ctxt) + &prd->managed) < 0) + goto cleanup; + ++ if (virXMLPropTristateBool(ctxt->node, "migration", ++ VIR_XML_PROP_NONZERO, ++ &prd->migration) < 0) ++ goto cleanup; ++ + type = virXPathString("string(./source[1]/@type)", ctxt); + path = virXPathString("string(./source[1]/@path)", ctxt); + mode = virXPathString("string(./source[1]/@mode)", ctxt); +@@ -384,6 +389,11 @@ virStoragePRDefFormat(virBuffer *buf, + { + virBufferAsprintf(buf, "managed)); ++ ++ if (prd->migration != VIR_TRISTATE_BOOL_ABSENT) ++ virBufferAsprintf(buf, " migration='%s'", ++ virTristateBoolTypeToString(prd->migration)); ++ + if (prd->path && + (prd->managed == VIR_TRISTATE_BOOL_NO || !migratable)) { + virBufferAddLit(buf, ">\n"); +diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h +index fc868b31af..5a4b088eeb 100644 +--- a/src/conf/storage_source_conf.h ++++ b/src/conf/storage_source_conf.h +@@ -235,6 +235,8 @@ struct _virStoragePRDef { + virTristateBool managed; + char *path; + ++ virTristateBool migration; ++ + /* manager object alias */ + char *mgralias; + }; +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index f355352018..c8626e6d49 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -1691,6 +1691,7 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, + g_autofree char *usbdiskalias = NULL; + const virDomainDeviceInfo *deviceinfo = &disk->info; + g_autoptr(virJSONValue) statistics = NULL; ++ virTristateBool migrate_pr = VIR_TRISTATE_BOOL_ABSENT; + virDomainDeviceInfo usbSCSIinfo = { + .type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE, + .addr.drive = { .diskbus = VIR_DOMAIN_DISK_BUS_USB }, +@@ -1716,6 +1717,8 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, + case VIR_DOMAIN_DISK_BUS_SCSI: + if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { + driver = "scsi-block"; ++ if (disk->src->pr) ++ migrate_pr = disk->src->pr->migration; + } else { + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { + driver = "scsi-cd"; +@@ -1937,6 +1940,7 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, + "S:rerror", rpolicy, + "A:stats-intervals", &statistics, + "T:dpofua", disk->dpofua, /* SCSI-only, ensured by validation */ ++ "T:migrate-pr", migrate_pr, /* 'scsi-block' only, ensured by validation */ + NULL) < 0) + return NULL; + +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index da08fd17cd..a3dbd9a33b 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -3227,6 +3227,22 @@ qemuValidateDomainDeviceDefDiskFrontend(const virDomainDiskDef *disk, + } + } + ++ if (disk->src->pr && ++ disk->src->pr->migration != VIR_TRISTATE_BOOL_ABSENT) { ++ if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN || ++ disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("persistent reservation migration supported only with 'lun' disks on 'scsi' bus")); ++ return -1; ++ } ++ ++ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("persistent reservation migration not supported by this qemu")); ++ return -1; ++ } ++ } ++ + if (disk->rotation_rate) { + if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI && + disk->bus != VIR_DOMAIN_DISK_BUS_IDE && +diff --git a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args +index cbc2a0f398..f1d7a450ee 100644 +--- a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args +@@ -33,7 +33,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -device '{"driver":"scsi-block","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":0,"drive":"libvirt-2-storage","id":"scsi0-0-0-0","bootindex":1}' \ + -object '{"qom-type":"pr-manager-helper","id":"pr-helper-libvirt-1-storage","path":"/path/to/qemu-pr-helper.sock"}' \ + -blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest2","pr-manager":"pr-helper-libvirt-1-storage","node-name":"libvirt-1-storage","read-only":false}' \ +--device '{"driver":"scsi-block","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":1,"drive":"libvirt-1-storage","id":"scsi0-0-0-1"}' \ ++-device '{"driver":"scsi-block","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":1,"drive":"libvirt-1-storage","id":"scsi0-0-0-1","migrate-pr":true}' \ + -audiodev '{"id":"audio1","driver":"none"}' \ + -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x4"}' \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +diff --git a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml +index 9c55d6ec3e..7f9160ff3a 100644 +--- a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml ++++ b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml +@@ -28,7 +28,7 @@ + + + +- ++ + + + +-- +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-Introduce-privateData-for-hostdevs.patch b/libvirt-qemu-Introduce-privateData-for-hostdevs.patch new file mode 100644 index 0000000..2d97f4c --- /dev/null +++ b/libvirt-qemu-Introduce-privateData-for-hostdevs.patch @@ -0,0 +1,277 @@ +From 94e2bf223d9fb7b9b65deaf8f2fbafb01dff5578 Mon Sep 17 00:00:00 2001 +Message-ID: <94e2bf223d9fb7b9b65deaf8f2fbafb01dff5578.1770383182.git.jdenemar@redhat.com> +From: Nathan Chen +Date: Fri, 30 Jan 2026 10:59:13 -0800 +Subject: [PATCH] qemu: Introduce privateData for hostdevs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce private data for hostdevs and allocate hostdev +private data by default. + +Signed-off-by: Ján Tomko +Signed-off-by: Nathan Chen +Reviewed-by: Pavel Hrdina +(cherry picked from commit 1043e04e17ed4be59b46e925089204333c08f05e) + +Resolves: https://issues.redhat.com/browse/RHEL-74202 +Resolves: https://issues.redhat.com/browse/RHEL-126346 + +Signed-off-by: Pavel Hrdina +--- + src/bhyve/bhyve_parse_command.c | 2 +- + src/conf/domain_conf.c | 13 +++++++++-- + src/conf/domain_conf.h | 5 ++++- + src/libxl/xen_common.c | 2 +- + src/libxl/xen_xl.c | 2 +- + src/lxc/lxc_native.c | 2 +- + src/qemu/qemu_domain.c | 40 +++++++++++++++++++++++++++++++++ + src/qemu/qemu_domain.h | 15 +++++++++++++ + src/vbox/vbox_common.c | 2 +- + tests/virhostdevtest.c | 2 +- + 10 files changed, 76 insertions(+), 9 deletions(-) + +diff --git a/src/bhyve/bhyve_parse_command.c b/src/bhyve/bhyve_parse_command.c +index d62ea64beb..8b405206bd 100644 +--- a/src/bhyve/bhyve_parse_command.c ++++ b/src/bhyve/bhyve_parse_command.c +@@ -687,7 +687,7 @@ bhyveParsePassthru(virDomainDef *def G_GNUC_UNUSED, + return -1; + } + +- hostdev = virDomainHostdevDefNew(); ++ hostdev = virDomainHostdevDefNew(NULL); + hostdev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; + hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 541dad5bdc..f950f7c75d 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -2733,6 +2733,8 @@ virDomainHostdevDefClear(virDomainHostdevDef *def) + case VIR_DOMAIN_HOSTDEV_MODE_LAST: + break; + } ++ ++ g_clear_pointer(&def->privateData, virObjectUnref); + } + + +@@ -3483,7 +3485,7 @@ void virDomainVideoDefFree(virDomainVideoDef *def) + + + virDomainHostdevDef * +-virDomainHostdevDefNew(void) ++virDomainHostdevDefNew(virDomainXMLOption *xmlopt) + { + virDomainHostdevDef *def; + +@@ -3491,6 +3493,13 @@ virDomainHostdevDefNew(void) + + def->info = g_new0(virDomainDeviceInfo, 1); + ++ if (xmlopt && xmlopt->privateData.hostdevNew && ++ !(def->privateData = xmlopt->privateData.hostdevNew())) { ++ VIR_FREE(def->info); ++ VIR_FREE(def); ++ return NULL; ++ } ++ + return def; + } + +@@ -13678,7 +13687,7 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt, + + ctxt->node = node; + +- def = virDomainHostdevDefNew(); ++ def = virDomainHostdevDefNew(xmlopt); + + if (virXMLPropEnumDefault(node, "mode", virDomainHostdevModeTypeFromString, + VIR_XML_PROP_NONE, +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index cb35ff06bd..8f53ed96c0 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -364,6 +364,8 @@ struct _virDomainHostdevDef { + */ + virDomainNetDef *parentnet; + ++ virObject *privateData; ++ + virDomainHostdevMode mode; + virDomainStartupPolicy startupPolicy; + bool managed; +@@ -3588,6 +3590,7 @@ struct _virDomainXMLPrivateDataCallbacks { + virDomainXMLPrivateDataNewFunc vsockNew; + virDomainXMLPrivateDataNewFunc cryptoNew; + virDomainXMLPrivateDataNewFunc graphicsNew; ++ virDomainXMLPrivateDataNewFunc hostdevNew; + virDomainXMLPrivateDataNewFunc networkNew; + virDomainXMLPrivateDataNetParseFunc networkParse; + virDomainXMLPrivateDataNetFormatFunc networkFormat; +@@ -3797,7 +3800,7 @@ virDomainVideoDef *virDomainVideoDefNew(virDomainXMLOption *xmlopt); + void virDomainVideoDefFree(virDomainVideoDef *def); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVideoDef, virDomainVideoDefFree); + void virDomainVideoDefClear(virDomainVideoDef *def); +-virDomainHostdevDef *virDomainHostdevDefNew(void); ++virDomainHostdevDef *virDomainHostdevDefNew(virDomainXMLOption *xmlopt); + void virDomainHostdevDefFree(virDomainHostdevDef *def); + void virDomainHubDefFree(virDomainHubDef *def); + void virDomainRedirdevDefFree(virDomainRedirdevDef *def); +diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c +index 666c6cae20..f19e4f6abb 100644 +--- a/src/libxl/xen_common.c ++++ b/src/libxl/xen_common.c +@@ -445,7 +445,7 @@ xenParsePCI(char *entry) + } + } + +- hostdev = virDomainHostdevDefNew(); ++ hostdev = virDomainHostdevDefNew(NULL); + hostdev->managed = false; + hostdev->writeFiltering = filtered; + hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; +diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c +index b2ff0edcf2..e62302736b 100644 +--- a/src/libxl/xen_xl.c ++++ b/src/libxl/xen_xl.c +@@ -930,7 +930,7 @@ xenParseXLUSB(virConf *conf, virDomainDef *def) + key = nextkey; + } + +- hostdev = virDomainHostdevDefNew(); ++ hostdev = virDomainHostdevDefNew(NULL); + hostdev->managed = false; + hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB; + hostdev->source.subsys.u.usb.bus = busNum; +diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c +index 7700804429..a94427b027 100644 +--- a/src/lxc/lxc_native.c ++++ b/src/lxc/lxc_native.c +@@ -376,7 +376,7 @@ lxcCreateNetDef(const char *type, + static virDomainHostdevDef * + lxcCreateHostdevDef(const char *data) + { +- virDomainHostdevDef *hostdev = virDomainHostdevDefNew(); ++ virDomainHostdevDef *hostdev = virDomainHostdevDefNew(NULL); + hostdev->mode = VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES; + hostdev->source.caps.type = VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET; + hostdev->source.caps.u.net.ifname = g_strdup(data); +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 486a0e7913..3366214677 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -1238,6 +1238,45 @@ qemuDomainNetworkPrivateFormat(const virDomainNetDef *net, + } + + ++static virClass *qemuDomainHostdevPrivateClass; ++ ++static void ++qemuDomainHostdevPrivateDispose(void *obj) ++{ ++ qemuDomainHostdevPrivate *priv = obj; ++ ++ VIR_FORCE_CLOSE(priv->vfioDeviceFd); ++} ++ ++ ++static int ++qemuDomainHostdevPrivateOnceInit(void) ++{ ++ if (!VIR_CLASS_NEW(qemuDomainHostdevPrivate, virClassForObject())) ++ return -1; ++ ++ return 0; ++} ++ ++VIR_ONCE_GLOBAL_INIT(qemuDomainHostdevPrivate); ++ ++virObject * ++qemuDomainHostdevPrivateNew(void) ++{ ++ qemuDomainHostdevPrivate *priv; ++ ++ if (qemuDomainHostdevPrivateInitialize() < 0) ++ return NULL; ++ ++ if (!(priv = virObjectNew(qemuDomainHostdevPrivateClass))) ++ return NULL; ++ ++ priv->vfioDeviceFd = -1; ++ ++ return (virObject *) priv; ++} ++ ++ + /* qemuDomainSecretInfoSetup: + * @priv: pointer to domain private object + * @alias: alias of the secret +@@ -3563,6 +3602,7 @@ virDomainXMLPrivateDataCallbacks virQEMUDriverPrivateDataCallbacks = { + .chrSourceNew = qemuDomainChrSourcePrivateNew, + .vsockNew = qemuDomainVsockPrivateNew, + .graphicsNew = qemuDomainGraphicsPrivateNew, ++ .hostdevNew = qemuDomainHostdevPrivateNew, + .networkNew = qemuDomainNetworkPrivateNew, + .networkParse = qemuDomainNetworkPrivateParse, + .networkFormat = qemuDomainNetworkPrivateFormat, +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index b9bb338682..88c8416aa4 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -461,6 +461,18 @@ struct _qemuDomainTPMPrivate { + }; + + ++#define QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev) \ ++ ((qemuDomainHostdevPrivate *) (hostdev)->privateData) ++ ++typedef struct _qemuDomainHostdevPrivate qemuDomainHostdevPrivate; ++struct _qemuDomainHostdevPrivate { ++ virObject parent; ++ ++ /* VFIO device file descriptor for iommufd passthrough */ ++ int vfioDeviceFd; ++}; ++ ++ + void + qemuDomainNetworkPrivateClearFDs(qemuDomainNetworkPrivate *priv); + +@@ -1175,3 +1187,6 @@ qemuDomainCheckCPU(virArch arch, + bool + qemuDomainMachineSupportsFloppy(const char *machine, + virQEMUCaps *qemuCaps); ++ ++virObject * ++qemuDomainHostdevPrivateNew(void); +diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c +index 26c5fdfef6..d2a8cf8da4 100644 +--- a/src/vbox/vbox_common.c ++++ b/src/vbox/vbox_common.c +@@ -3090,7 +3090,7 @@ vboxHostDeviceGetXMLDesc(struct _vboxDriver *data, virDomainDef *def, IMachine * + def->hostdevs = g_new0(virDomainHostdevDef *, def->nhostdevs); + + for (i = 0; i < def->nhostdevs; i++) +- def->hostdevs[i] = virDomainHostdevDefNew(); ++ def->hostdevs[i] = virDomainHostdevDefNew(NULL); + + for (i = 0; i < deviceFilters.count; i++) { + PRBool active = PR_FALSE; +diff --git a/tests/virhostdevtest.c b/tests/virhostdevtest.c +index aec474a148..a35c1d9402 100644 +--- a/tests/virhostdevtest.c ++++ b/tests/virhostdevtest.c +@@ -124,7 +124,7 @@ myInit(void) + + for (i = 0; i < nhostdevs; i++) { + virDomainHostdevSubsys *subsys; +- hostdevs[i] = virDomainHostdevDefNew(); ++ hostdevs[i] = virDomainHostdevDefNew(NULL); + if (!hostdevs[i]) + goto cleanup; + hostdevs[i]->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; +-- +2.52.0 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-Setup-disk-latency-histograms-on-startup-hotplug-update.patch b/libvirt-qemu-Setup-disk-latency-histograms-on-startup-hotplug-update.patch new file mode 100644 index 0000000..64a9170 --- /dev/null +++ b/libvirt-qemu-Setup-disk-latency-histograms-on-startup-hotplug-update.patch @@ -0,0 +1,132 @@ +From f496b6095bf96eb8931b78054a272a5aaf70a2d9 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Fri, 23 Jan 2026 17:18:14 +0100 +Subject: [PATCH] qemu: Setup disk latency histograms on startup/hotplug/update + +Setup the histograms on startup and hotplug of devices via +'qemuProcessSetupDiskPropsRuntime' and facilitate update/reset/disable +of histogram collection via 'qemuDomainChangeDiskLive'. + +The latter allows to use the update device API to either clear the bins +or select new bin configuration or disable the histogram altogether +without the need for a specific API. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 5787326541be4eafaa7ae3b4f866b3da793d44fe) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + src/qemu/qemu_domain.c | 17 +++++++++++++++++ + src/qemu/qemu_domain.h | 3 +++ + src/qemu/qemu_hotplug.c | 29 +++++++++++++++++++++++++++++ + src/qemu/qemu_process.c | 10 ++++++++++ + 4 files changed, 59 insertions(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 8e1ebe7799..bdab117e96 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -10463,6 +10463,23 @@ qemuDomainInitializePflashStorageSource(virDomainObj *vm, + } + + ++/** ++ * qemuDomainDiskHasLatencyHistogram: ++ * @disk: disk definition ++ * ++ * Returns whether @disk has any latency histogram settings configured. ++ */ ++bool ++qemuDomainDiskHasLatencyHistogram(virDomainDiskDef *disk) ++{ ++ return disk->histogram_boundaries || ++ disk->histogram_boundaries_read || ++ disk->histogram_boundaries_write || ++ disk->histogram_boundaries_zone || ++ disk->histogram_boundaries_flush; ++} ++ ++ + /** + * qemuDomainDiskBlockJobIsSupported: + * +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 3361e97315..30ca67bf76 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -1078,6 +1078,9 @@ int + qemuDomainInitializePflashStorageSource(virDomainObj *vm, + virQEMUDriverConfig *cfg); + ++bool ++qemuDomainDiskHasLatencyHistogram(virDomainDiskDef *disk); ++ + bool + qemuDomainDiskBlockJobIsSupported(virDomainDiskDef *disk); + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index f2dc4469a3..9445599d2c 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -7310,6 +7310,35 @@ qemuDomainChangeDiskLive(virDomainObj *vm, + dev->data.disk->src = NULL; + } + ++ if (qemuDomainDiskHasLatencyHistogram(disk) || ++ qemuDomainDiskHasLatencyHistogram(orig_disk)) { ++ int rc; ++ ++ qemuDomainObjEnterMonitor(vm); ++ rc = qemuMonitorBlockLatencyHistogramSet(qemuDomainGetMonitor(vm), ++ QEMU_DOMAIN_DISK_PRIVATE(orig_disk)->qomName, ++ disk->histogram_boundaries, ++ disk->histogram_boundaries_read, ++ disk->histogram_boundaries_write, ++ disk->histogram_boundaries_zone, ++ disk->histogram_boundaries_flush); ++ qemuDomainObjExitMonitor(vm); ++ ++ if (rc < 0) ++ return -1; ++ ++ g_clear_pointer(&orig_disk->histogram_boundaries, g_free); ++ g_clear_pointer(&orig_disk->histogram_boundaries_read, g_free); ++ g_clear_pointer(&orig_disk->histogram_boundaries_write, g_free); ++ g_clear_pointer(&orig_disk->histogram_boundaries_zone, g_free); ++ g_clear_pointer(&orig_disk->histogram_boundaries_flush, g_free); ++ orig_disk->histogram_boundaries = g_steal_pointer(&disk->histogram_boundaries); ++ orig_disk->histogram_boundaries_read = g_steal_pointer(&disk->histogram_boundaries_read); ++ orig_disk->histogram_boundaries_write = g_steal_pointer(&disk->histogram_boundaries_write); ++ orig_disk->histogram_boundaries_zone = g_steal_pointer(&disk->histogram_boundaries_zone); ++ orig_disk->histogram_boundaries_flush = g_steal_pointer(&disk->histogram_boundaries_flush); ++ } ++ + /* in case when we aren't updating disk source we update startup policy here */ + orig_disk->startupPolicy = dev->data.disk->startupPolicy; + orig_disk->snapshot = dev->data.disk->snapshot; +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index aadfaa92b0..37e688018c 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7959,6 +7959,16 @@ qemuProcessSetupDiskPropsRuntime(qemuMonitor *mon, + &disk->blkdeviotune) < 0) + return -1; + ++ if (qemuDomainDiskHasLatencyHistogram(disk) && ++ qemuMonitorBlockLatencyHistogramSet(mon, ++ QEMU_DOMAIN_DISK_PRIVATE(disk)->qomName, ++ disk->histogram_boundaries, ++ disk->histogram_boundaries_read, ++ disk->histogram_boundaries_write, ++ disk->histogram_boundaries_zone, ++ disk->histogram_boundaries_flush) < 0) ++ return -1; ++ + return 0; + } + +-- +2.53.0 diff --git a/libvirt-qemu-Support-per-process-memory-accounting-for-iommufd.patch b/libvirt-qemu-Support-per-process-memory-accounting-for-iommufd.patch new file mode 100644 index 0000000..33d73ef --- /dev/null +++ b/libvirt-qemu-Support-per-process-memory-accounting-for-iommufd.patch @@ -0,0 +1,212 @@ +From 9a525305075612f540a1d3b2727ddf8b5320ff01 Mon Sep 17 00:00:00 2001 +Message-ID: <9a525305075612f540a1d3b2727ddf8b5320ff01.1770383182.git.jdenemar@redhat.com> +From: Nathan Chen +Date: Fri, 30 Jan 2026 10:59:14 -0800 +Subject: [PATCH] qemu: Support per-process memory accounting for iommufd + +Implement the IOMMU_OPTION_RLIMIT_MODE +ioctl to set per-process memory accounting for +iommufd. This prevents ENOMEM errors from the +default per-user memory accounting when multiple +VMs under the libvirt-qemu user have their pinned +memory summed and checked against a per-process +RLIMIT_MEMLOCK limit. + +Signed-off-by: Nathan Chen +Reviewed-by: Pavel Hrdina +(cherry picked from commit f91a07d0c8dd583928974e80bb13b54feb5aa908) + +Resolves: https://issues.redhat.com/browse/RHEL-74202 +Resolves: https://issues.redhat.com/browse/RHEL-126346 + +Signed-off-by: Pavel Hrdina +--- + meson.build | 1 + + po/POTFILES | 1 + + src/libvirt_private.syms | 3 ++ + src/util/meson.build | 1 + + src/util/viriommufd.c | 90 ++++++++++++++++++++++++++++++++++++++++ + src/util/viriommufd.h | 25 +++++++++++ + 6 files changed, 121 insertions(+) + create mode 100644 src/util/viriommufd.c + create mode 100644 src/util/viriommufd.h + +diff --git a/meson.build b/meson.build +index 6ac9d01952..28745e4e32 100644 +--- a/meson.build ++++ b/meson.build +@@ -673,6 +673,7 @@ headers = [ + 'ifaddrs.h', + 'libtasn1.h', + 'linux/kvm.h', ++ 'linux/iommufd.h', + 'mntent.h', + 'net/ethernet.h', + 'net/if.h', +diff --git a/po/POTFILES b/po/POTFILES +index f0aad35c8c..c78d2b8000 100644 +--- a/po/POTFILES ++++ b/po/POTFILES +@@ -303,6 +303,7 @@ src/util/virhostuptime.c + src/util/viridentity.c + src/util/virinhibitor.c + src/util/virinitctl.c ++src/util/viriommufd.c + src/util/viriscsi.c + src/util/virjson.c + src/util/virlease.c +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 4e57e4a8f6..66261ed6cf 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2652,6 +2652,9 @@ virInhibitorRelease; + virInitctlFifos; + virInitctlSetRunLevel; + ++# util/viriommufd.h ++virIOMMUFDSetRLimitMode; ++ + # util/viriscsi.h + virISCSIConnectionLogin; + virISCSIConnectionLogout; +diff --git a/src/util/meson.build b/src/util/meson.build +index 4950a795cc..9fb0aa0fe7 100644 +--- a/src/util/meson.build ++++ b/src/util/meson.build +@@ -46,6 +46,7 @@ util_sources = [ + 'viridentity.c', + 'virinhibitor.c', + 'virinitctl.c', ++ 'viriommufd.c', + 'viriscsi.c', + 'virjson.c', + 'virkeycode.c', +diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c +new file mode 100644 +index 0000000000..5af097683d +--- /dev/null ++++ b/src/util/viriommufd.c +@@ -0,0 +1,90 @@ ++#include ++ ++#include "viriommufd.h" ++#include "virlog.h" ++#include "virerror.h" ++#include "virfile.h" ++ ++#define VIR_FROM_THIS VIR_FROM_NONE ++ ++VIR_LOG_INIT("util.iommufd"); ++ ++#ifdef __linux__ ++ ++# include ++# include ++ ++# ifdef HAVE_LINUX_IOMMUFD_H ++# include ++# endif ++ ++# ifndef IOMMU_OPTION ++ ++enum iommufd_option { ++ IOMMU_OPTION_RLIMIT_MODE = 0, ++ IOMMU_OPTION_HUGE_PAGES = 1, ++}; ++ ++enum iommufd_option_ops { ++ IOMMU_OPTION_OP_SET = 0, ++ IOMMU_OPTION_OP_GET = 1, ++}; ++ ++struct iommu_option { ++ __u32 size; ++ __u32 option_id; ++ __u16 op; ++ __u16 __reserved; ++ __u32 object_id; ++ __aligned_u64 val64; ++}; ++ ++# define IOMMUFD_TYPE (';') ++# define IOMMUFD_CMD_OPTION 0x87 ++# define IOMMU_OPTION _IO(IOMMUFD_TYPE, IOMMUFD_CMD_OPTION) ++ ++# endif ++ ++/** ++ * virIOMMUFDSetRLimitMode: ++ * @fd: iommufd file descriptor ++ * @processAccounting: true for per-process, false for per-user ++ * ++ * Set RLIMIT_MEMLOCK accounting mode for the iommufd. ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++int ++virIOMMUFDSetRLimitMode(int fd, bool processAccounting) ++{ ++ struct iommu_option option = { ++ .size = sizeof(struct iommu_option), ++ .option_id = IOMMU_OPTION_RLIMIT_MODE, ++ .op = IOMMU_OPTION_OP_SET, ++ .__reserved = 0, ++ .object_id = 0, ++ .val64 = processAccounting ? 1 : 0, ++ }; ++ ++ if (ioctl(fd, IOMMU_OPTION, &option) < 0) { ++ virReportSystemError(errno, "%s", ++ _("failed to set memory accounting for iommufd")); ++ return -1; ++ } ++ ++ VIR_DEBUG("Set iommufd rlimit mode to %s-based accounting", ++ processAccounting ? "process" : "user"); ++ return 0; ++} ++ ++#else ++ ++int virIOMMUFDSetRLimitMode(int fd G_GNUC_UNUSED, ++ bool processAccounting G_GNUC_UNUSED) ++{ ++ virReportError(VIR_ERR_NO_SUPPORT, "%s", ++ _("IOMMUFD is not supported on this platform")); ++ return -1; ++} ++ ++#endif +diff --git a/src/util/viriommufd.h b/src/util/viriommufd.h +new file mode 100644 +index 0000000000..ebecfe3633 +--- /dev/null ++++ b/src/util/viriommufd.h +@@ -0,0 +1,25 @@ ++/* ++ * viriommufd.h: iommufd helpers ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++ ++#pragma once ++ ++#include "internal.h" ++ ++#define VIR_IOMMU_DEV_PATH "/dev/iommu" ++ ++int virIOMMUFDSetRLimitMode(int fd, bool processAccounting); +-- +2.52.0 diff --git a/libvirt-qemu-Update-Cgroup-namespace-and-seclabel-for-iommufd.patch b/libvirt-qemu-Update-Cgroup-namespace-and-seclabel-for-iommufd.patch new file mode 100644 index 0000000..32b82fb --- /dev/null +++ b/libvirt-qemu-Update-Cgroup-namespace-and-seclabel-for-iommufd.patch @@ -0,0 +1,336 @@ +From 01ce19df7986fe190ce212fa05f2caed799cc50f Mon Sep 17 00:00:00 2001 +Message-ID: <01ce19df7986fe190ce212fa05f2caed799cc50f.1770383182.git.jdenemar@redhat.com> +From: Nathan Chen +Date: Fri, 30 Jan 2026 10:59:17 -0800 +Subject: [PATCH] qemu: Update Cgroup, namespace, and seclabel for iommufd + +When launching a qemu VM with the iommufd feature enabled for VFIO +hostdevs: +- Do not allow cgroup, namespace, and seclabel access to VFIO +paths (/dev/vfio/vfio and /dev/vfio/) +- Allow access to iommufd paths (/dev/iommu and +/dev/vfio/devices/vfio*) for AppArmor, SELinux, and DAC + +Signed-off-by: Nathan Chen +Reviewed-by: Pavel Hrdina +(cherry picked from commit 7d2f91f9cb572ab95d0916bdd1a46dd198874529) + +Resolves: https://issues.redhat.com/browse/RHEL-74202 +Resolves: https://issues.redhat.com/browse/RHEL-126346 + +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_cgroup.c | 3 ++ + src/qemu/qemu_namespace.c | 3 ++ + src/security/security_apparmor.c | 28 ++++++++++++------ + src/security/security_dac.c | 49 +++++++++++++++++++++++++------- + src/security/security_selinux.c | 47 +++++++++++++++++++++++------- + src/security/virt-aa-helper.c | 32 ++++++++++++++++----- + 6 files changed, 127 insertions(+), 35 deletions(-) + +diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c +index 7dadef0739..6148990f19 100644 +--- a/src/qemu/qemu_cgroup.c ++++ b/src/qemu/qemu_cgroup.c +@@ -479,6 +479,9 @@ qemuSetupHostdevCgroup(virDomainObj *vm, + g_autofree char *path = NULL; + int perms; + ++ if (dev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) ++ return 0; ++ + if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) + return 0; + +diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c +index c689cc3e40..fb0734193d 100644 +--- a/src/qemu/qemu_namespace.c ++++ b/src/qemu/qemu_namespace.c +@@ -345,6 +345,9 @@ qemuDomainSetupHostdev(virDomainObj *vm, + { + g_autofree char *path = NULL; + ++ if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) ++ return 0; ++ + if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0) + return -1; + +diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c +index 68ac39611f..934acfb461 100644 +--- a/src/security/security_apparmor.c ++++ b/src/security/security_apparmor.c +@@ -45,6 +45,7 @@ + #include "virstring.h" + #include "virscsi.h" + #include "virmdev.h" ++#include "viriommufd.h" + + #define VIR_FROM_THIS VIR_FROM_SECURITY + +@@ -841,25 +842,36 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr, + } + + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: { +- virPCIDevice *pci = ++ g_autoptr(virPCIDevice) pci = + virPCIDeviceNew(&pcisrc->addr); + + if (!pci) + goto done; + + if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { +- char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); ++ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) { ++ char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); + +- if (!vfioGroupDev) { +- virPCIDeviceFree(pci); +- goto done; ++ if (!vfioGroupDev) { ++ goto done; ++ } ++ ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr); ++ VIR_FREE(vfioGroupDev); ++ } else { ++ g_autofree char *vfiofdDev = NULL; ++ ++ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ goto done; ++ ++ ret = AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr); ++ if (ret < 0) ++ goto done; ++ ++ ret = AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr); + } +- ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr); +- VIR_FREE(vfioGroupDev); + } else { + ret = virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr); + } +- virPCIDeviceFree(pci); + break; + } + +diff --git a/src/security/security_dac.c b/src/security/security_dac.c +index 2f788b872a..d0ed22db2d 100644 +--- a/src/security/security_dac.c ++++ b/src/security/security_dac.c +@@ -41,6 +41,7 @@ + #include "virscsivhost.h" + #include "virstring.h" + #include "virutil.h" ++#include "viriommufd.h" + + #define VIR_FROM_THIS VIR_FROM_SECURITY + +@@ -1282,14 +1283,27 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr, + return -1; + + if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { +- g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); ++ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) { ++ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); + +- if (!vfioGroupDev) +- return -1; ++ if (!vfioGroupDev) ++ return -1; + +- ret = virSecurityDACSetHostdevLabelHelper(vfioGroupDev, +- false, +- &cbdata); ++ ret = virSecurityDACSetHostdevLabelHelper(vfioGroupDev, ++ false, ++ &cbdata); ++ } else { ++ g_autofree char *vfiofdDev = NULL; ++ ++ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ return -1; ++ ++ ret = virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata); ++ if (ret < 0) ++ break; ++ ++ ret = virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata); ++ } + } else { + ret = virPCIDeviceFileIterate(pci, + virSecurityDACSetPCILabel, +@@ -1443,13 +1457,28 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr, + return -1; + + if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { +- g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); ++ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) { ++ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); + +- if (!vfioGroupDev) +- return -1; ++ if (!vfioGroupDev) ++ return -1; + +- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL, ++ ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL, + vfioGroupDev, false); ++ } else { ++ g_autofree char *vfiofdDev = NULL; ++ ++ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ return -1; ++ ++ ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL, ++ vfiofdDev, false); ++ if (ret < 0) ++ break; ++ ++ ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL, ++ VIR_IOMMU_DEV_PATH, false); ++ } + } else { + ret = virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr); + } +diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c +index 2f3cc274a5..834383a7de 100644 +--- a/src/security/security_selinux.c ++++ b/src/security/security_selinux.c +@@ -41,6 +41,7 @@ + #include "virconf.h" + #include "virtpm.h" + #include "virstring.h" ++#include "viriommufd.h" + + #define VIR_FROM_THIS VIR_FROM_SECURITY + +@@ -2256,14 +2257,27 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr, + return -1; + + if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { +- g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); ++ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) { ++ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); + +- if (!vfioGroupDev) +- return -1; ++ if (!vfioGroupDev) ++ return -1; + +- ret = virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev, +- false, +- &data); ++ ret = virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev, ++ false, ++ &data); ++ } else { ++ g_autofree char *vfiofdDev = NULL; ++ ++ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ return -1; ++ ++ ret = virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data); ++ if (ret) ++ break; ++ ++ ret = virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data); ++ } + } else { + ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data); + } +@@ -2491,12 +2505,25 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr, + return -1; + + if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { +- g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); ++ if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) { ++ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); + +- if (!vfioGroupDev) +- return -1; ++ if (!vfioGroupDev) ++ return -1; + +- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false); ++ ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false); ++ } else { ++ g_autofree char *vfiofdDev = NULL; ++ ++ if (virPCIDeviceGetVfioPath(&dev->source.subsys.u.pci.addr, &vfiofdDev) < 0) ++ return -1; ++ ++ ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false); ++ if (ret < 0) ++ break; ++ ++ ret = virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false); ++ } + } else { + ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr); + } +diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c +index de0a826063..29e844c7ff 100644 +--- a/src/security/virt-aa-helper.c ++++ b/src/security/virt-aa-helper.c +@@ -50,6 +50,7 @@ + #include "virstring.h" + #include "virgettext.h" + #include "virhostdev.h" ++#include "viriommufd.h" + + #define VIR_FROM_THIS VIR_FROM_SECURITY + +@@ -1114,8 +1115,9 @@ get_files(vahControl * ctl) + + virDeviceHostdevPCIDriverName driverName = dev->source.subsys.u.pci.driver.name; + +- if (driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO || +- driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT) { ++ if ((driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO || ++ driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT) && ++ dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) { + needsVfio = true; + } + +@@ -1385,9 +1387,18 @@ get_files(vahControl * ctl) + } + } + +- if (ctl->newfile && +- vah_add_file(&buf, ctl->newfile, "rwk") != 0) { +- return -1; ++ if (ctl->newfile) { ++ const char *perms = "rwk"; ++ ++ /* VFIO and iommufd devices need mmap permission */ ++ if (STRPREFIX(ctl->newfile, "/dev/vfio/devices/vfio") || ++ STREQ(ctl->newfile, VIR_IOMMU_DEV_PATH)) { ++ perms = "rwm"; ++ } ++ ++ if (vah_add_file(&buf, ctl->newfile, perms) != 0) { ++ return -1; ++ } + } + + ctl->files = virBufferContentAndReset(&buf); +@@ -1561,8 +1572,15 @@ main(int argc, char **argv) + } + } + if (ctl->append && ctl->newfile) { +- if (vah_add_file(&buf, ctl->newfile, "rwk") != 0) +- goto cleanup; ++ const char *perms = "rwk"; ++ ++ if (STRPREFIX(ctl->newfile, "/dev/vfio/devices/vfio") || ++ STREQ(ctl->newfile, VIR_IOMMU_DEV_PATH)) { ++ perms = "rwm"; ++ } ++ ++ if (vah_add_file(&buf, ctl->newfile, perms) != 0) ++ return -1; + } else { + if (ctl->def->virtType == VIR_DOMAIN_VIRT_QEMU || + ctl->def->virtType == VIR_DOMAIN_VIRT_KQEMU || +-- +2.52.0 diff --git a/libvirt-qemu-Use-pci_bus-to-identify-multi-smmuv3-model.patch b/libvirt-qemu-Use-pci_bus-to-identify-multi-smmuv3-model.patch new file mode 100644 index 0000000..17ab1ad --- /dev/null +++ b/libvirt-qemu-Use-pci_bus-to-identify-multi-smmuv3-model.patch @@ -0,0 +1,69 @@ +From 933524784d813b24aa0970992b820698f1e03180 Mon Sep 17 00:00:00 2001 +Message-ID: <933524784d813b24aa0970992b820698f1e03180.1766070439.git.jdenemar@redhat.com> +From: Nathan Chen via Devel +Date: Tue, 2 Dec 2025 11:59:47 -0800 +Subject: [PATCH] qemu: Use pci_bus to identify multi-smmuv3 model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use presence of non-negative pci_bus to identify multi-smmuv3 +IOMMU model, instead of the niommus attribute. This allows for +specifying a single arm-smmuv3 on the qemu command line, +instead of both the virt-machine smmuv3 and arm-smmuv3 +being specified at the same time. + +Signed-off-by: Nathan Chen +Fixes: e70c4d54d365 conf: Support multiple device-pluggable smmuv3 IOMMUs +Reviewed-by: Ján Tomko +(cherry picked from commit da4305b7bc8d3bd52c60db1905db88e43ebd9868) + +https://issues.redhat.com/browse/RHEL-74200 +Signed-off-by: Ján Tomko +--- + src/qemu/qemu_command.c | 2 +- + src/qemu/qemu_postparse.c | 2 +- + .../iommu-smmuv3-pci-bus-single.aarch64-latest.args | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index b69fe23236..fb89dbec27 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -7192,7 +7192,7 @@ qemuBuildMachineCommandLine(virCommand *cmd, + if (qemuAppendDomainFeaturesMachineParam(&buf, def, qemuCaps) < 0) + return -1; + +- if (def->niommus == 1) { ++ if (def->iommus && def->iommus[0]->pci_bus < 0) { + switch (def->iommus[0]->model) { + case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + virBufferAddLit(&buf, ",iommu=smmuv3"); +diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c +index dc5ade829a..840d6a1174 100644 +--- a/src/qemu/qemu_postparse.c ++++ b/src/qemu/qemu_postparse.c +@@ -1559,7 +1559,7 @@ qemuDomainDefEnableDefaultFeatures(virDomainDef *def, + * domain already has IOMMU without inremap. This will be fixed in + * qemuDomainIOMMUDefPostParse() but there domain definition can't be + * modified so change it now. */ +- if (def->iommus && def->niommus == 1 && ++ if (def->iommus && def->iommus[0]->pci_bus < 0 && + (def->iommus[0]->intremap == VIR_TRISTATE_SWITCH_ON || + qemuDomainNeedsIOMMUWithEIM(def)) && + def->features[VIR_DOMAIN_FEATURE_IOAPIC] == VIR_DOMAIN_IOAPIC_NONE) { +diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args +index 976467e641..34e7bda1c5 100644 +--- a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args ++++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args +@@ -10,7 +10,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ + -name guest=guest,debug-threads=on \ + -S \ + -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ +--machine virt,usb=off,gic-version=2,iommu=smmuv3,dump-guest-core=off,memory-backend=mach-virt.ram,acpi=off \ ++-machine virt,usb=off,gic-version=2,dump-guest-core=off,memory-backend=mach-virt.ram,acpi=off \ + -accel tcg \ + -cpu cortex-a15 \ + -m size=1048576k \ +-- +2.52.0 diff --git a/libvirt-qemu-add-IOMMU-attribute-cmdqv-for-smmuv3.patch b/libvirt-qemu-add-IOMMU-attribute-cmdqv-for-smmuv3.patch new file mode 100644 index 0000000..925e07e --- /dev/null +++ b/libvirt-qemu-add-IOMMU-attribute-cmdqv-for-smmuv3.patch @@ -0,0 +1,145 @@ +From e29d49aeeb384f3e1430c8a1d0e5b85f82305335 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Pavel Hrdina +Date: Tue, 6 Jan 2026 12:54:24 -0800 +Subject: [PATCH] qemu: add IOMMU attribute "cmdqv" for smmuv3 + +From: Nathan Chen + +Introduce support for "cmdqv" IOMMU attribute, which +enables NVIDIA Tegra241 CMDQV, an extension for ARM +SMMUv3. It supports passthroughs of physical SMMU-CMDQ +linked command queue from host space to a VM. + +Signed-off-by: Nathan Chen + +Resolves: https://issues.redhat.com/browse/VOYAGER-14 +--- + docs/formatdomain.rst | 5 +++++ + src/conf/domain_conf.c | 9 +++++++++ + src/conf/domain_conf.h | 1 + + src/conf/domain_validate.c | 3 +++ + src/conf/schemas/domaincommon.rng | 5 +++++ + src/qemu/qemu_command.c | 1 + + 6 files changed, 24 insertions(+) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 9ce647eba7..8f1be253de 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -9319,6 +9319,11 @@ Example: + to enable hardware acceleration support for smmuv3Dev IOMMU devices. + (QEMU/KVM and ``smmuv3`` model only) + ++ ``cmdqv`` ++ The ``cmdqv`` attribute with possibel values ``on`` and ``off`` can be used ++ to enable NVIDIA Tegra241 CMDQV, an extension for ARM SMMUv3 that supports ++ passthrough of physical SMMU-CMDQ linked command queue from host space to VM. ++ + ``ats`` + The ``ats`` attribute with possible values ``on`` and ``off`` can be used + to enable reporting Address Translation Services capability to the guest +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 8ea3206485..b8c180e72d 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -14627,6 +14627,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, + &iommu->accel) < 0) + return NULL; + ++ if (virXMLPropTristateSwitch(driver, "cmdqv", VIR_XML_PROP_NONE, ++ &iommu->cmdqv) < 0) ++ return NULL; ++ + if (virXMLPropTristateSwitch(driver, "ats", VIR_XML_PROP_NONE, + &iommu->ats) < 0) + return NULL; +@@ -16708,6 +16712,7 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a, + a->dma_translation != b->dma_translation || + a->pci_bus != b->pci_bus || + a->accel != b->accel || ++ a->cmdqv != b->cmdqv || + a->ats != b->ats || + a->ril != b->ril || + a->ssid_size != b->ssid_size || +@@ -28851,6 +28856,10 @@ virDomainIOMMUDefFormat(virBuffer *buf, + virBufferAsprintf(&driverAttrBuf, " accel='%s'", + virTristateSwitchTypeToString(iommu->accel)); + } ++ if (iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT) { ++ virBufferAsprintf(&driverAttrBuf, " cmdqv='%s'", ++ virTristateSwitchTypeToString(iommu->cmdqv)); ++ } + if (iommu->ats != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(&driverAttrBuf, " ats='%s'", + virTristateSwitchTypeToString(iommu->ats)); +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index a7afbca2a2..91b8976ea5 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -3073,6 +3073,7 @@ struct _virDomainIOMMUDef { + virTristateSwitch xtsup; + virTristateSwitch pt; + virTristateSwitch accel; ++ virTristateSwitch cmdqv; + virTristateSwitch ats; + virTristateSwitch ril; + unsigned int ssid_size; +diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c +index aed5eb0278..51f7961e3c 100644 +--- a/src/conf/domain_validate.c ++++ b/src/conf/domain_validate.c +@@ -3157,6 +3157,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) + iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || + iommu->pci_bus >= 0 || + iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ats != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ril != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ssid_size != 0 || +@@ -3175,6 +3176,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) + iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || + iommu->pci_bus >= 0 || + iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ats != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ril != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ssid_size != 0 || +@@ -3191,6 +3193,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) + iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT || + iommu->pci_bus >= 0 || + iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ats != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ril != VIR_TRISTATE_SWITCH_ABSENT || + iommu->ssid_size != 0 || +diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng +index 6de939c9f5..5d0e538535 100644 +--- a/src/conf/schemas/domaincommon.rng ++++ b/src/conf/schemas/domaincommon.rng +@@ -6344,6 +6344,11 @@ + + + ++ ++ ++ ++ ++ + + + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index e7c6e1d0eb..fdc79e18be 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -6325,6 +6325,7 @@ qemuBuildPCINestedSmmuv3DevProps(const virDomainDef *def, + "s:primary-bus", bus, + "s:id", iommu->info.alias, + "B:accel", (iommu->accel == VIR_TRISTATE_SWITCH_ON), ++ "B:tegra241-cmdqv", (iommu->cmdqv == VIR_TRISTATE_SWITCH_ON), + "B:ats", (iommu->ats == VIR_TRISTATE_SWITCH_ON), + NULL) < 0) + return NULL; +-- +2.53.0 diff --git a/libvirt-qemu-capabilities-Introduce-QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR.patch b/libvirt-qemu-capabilities-Introduce-QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR.patch new file mode 100644 index 0000000..dda2822 --- /dev/null +++ b/libvirt-qemu-capabilities-Introduce-QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR.patch @@ -0,0 +1,58 @@ +From 2674cc2e58f98439fe72e4d832e6e2e9b41a614f Mon Sep 17 00:00:00 2001 +Message-ID: <2674cc2e58f98439fe72e4d832e6e2e9b41a614f.1771336681.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Thu, 11 Dec 2025 19:26:40 +0100 +Subject: [PATCH] qemu: capabilities: Introduce + QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR + +Introduce capability for persisten migration control support. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit b0edb7eb9b819e0560bb7d65b4e0c89082b3b43b) + +https://issues.redhat.com/browse/RHEL-140614 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-135115 [rhel-10.2] + +Conflicts: + - Commit befdd44bf836c3ba46e46d57b587127e12736591 adding + QEMU_CAPS_VIRTIO_IOMMU_AW_BITS was not backported +--- + src/qemu/qemu_capabilities.c | 2 ++ + src/qemu/qemu_capabilities.h | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 1efb77d03b..2c8bd62c99 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -755,6 +755,7 @@ VIR_ENUM_IMPL(virQEMUCaps, + "disk-timed-stats", /* QEMU_CAPS_DISK_TIMED_STATS */ + "query-accelerators", /* QEMU_CAPS_QUERY_ACCELERATORS */ + "mshv", /* QEMU_CAPS_MSHV */ ++ "scsi-block.migrate-pr", /* QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR */ + ); + + +@@ -1536,6 +1537,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIDisk[] = { + }; + + static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIBlock[] = { ++ { "migrate-pr", QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, NULL }, + }; + + static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIGeneric[] = { +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index f180844e66..0c76f2edda 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -730,6 +730,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + QEMU_CAPS_DISK_TIMED_STATS, /* timed stats support ('stats-intervals' property of disk frontends) */ + QEMU_CAPS_QUERY_ACCELERATORS, /* query-accelerators command */ + QEMU_CAPS_MSHV, /* -accel mshv */ ++ QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, /* persistent reservation migration support */ + + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; +-- +2.53.0 diff --git a/libvirt-qemu-capabilities-Probe-properties-of-scsi-block-and-scsi-generic-devices.patch b/libvirt-qemu-capabilities-Probe-properties-of-scsi-block-and-scsi-generic-devices.patch new file mode 100644 index 0000000..5dcf830 --- /dev/null +++ b/libvirt-qemu-capabilities-Probe-properties-of-scsi-block-and-scsi-generic-devices.patch @@ -0,0 +1,7714 @@ +From 661368feba96d228825535a990d4a57381c6e1ee Mon Sep 17 00:00:00 2001 +Message-ID: <661368feba96d228825535a990d4a57381c6e1ee.1771336681.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Thu, 11 Dec 2025 18:43:39 +0100 +Subject: [PATCH] qemu: capabilities: Probe properties of 'scsi-block' and + 'scsi-generic' devices + +Add code to probe properties of 'scsi-block' and 'scsi-generic' qemu +devices. For now the '.replies' are modified using the +'qemu-replies-tool' script and the data is annotated as fake and is in +fact missing. Further updates will populate them for any real dump. + +The properties for the two devices will be later used e.g. to detect +support for persistent reservations migration support. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit d917bf662b65099472b15c5a1fa1493a5f4cdd14) + +https://issues.redhat.com/browse/RHEL-140614 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-135115 [rhel-10.2] + +Conflicts: + - Some capability output files don't exist upstream. +--- + src/qemu/qemu_capabilities.c | 12 +++ + .../caps_10.0.0_aarch64.replies | 76 +++++++++++----- + .../caps_10.0.0_ppc64.replies | 60 ++++++++++--- + .../caps_10.0.0_s390x.replies | 64 ++++++++++---- + .../caps_10.0.0_x86_64+amdsev.replies | 84 ++++++++++++------ + .../caps_10.0.0_x86_64.replies | 84 ++++++++++++------ + .../caps_10.1.0_x86_64+inteltdx.replies | 88 +++++++++++++------ + .../caps_10.1.0_x86_64.replies | 88 +++++++++++++------ + .../caps_10.2.0_x86_64+mshv.replies | 88 +++++++++++++------ + .../caps_10.2.0_x86_64.replies | 88 +++++++++++++------ + .../caps_6.2.0_ppc64.replies | 60 ++++++++++--- + .../caps_6.2.0_x86_64.replies | 84 ++++++++++++------ + .../caps_7.0.0_ppc64.replies | 60 ++++++++++--- + .../caps_7.0.0_x86_64.replies | 84 ++++++++++++------ + .../caps_7.1.0_ppc64.replies | 60 ++++++++++--- + .../caps_7.1.0_x86_64.replies | 84 ++++++++++++------ + .../caps_7.2.0_ppc.replies | 56 +++++++++--- + .../caps_7.2.0_x86_64+hvf.replies | 84 ++++++++++++------ + .../caps_7.2.0_x86_64.replies | 84 ++++++++++++------ + .../caps_8.0.0_x86_64.replies | 84 ++++++++++++------ + .../caps_8.1.0_s390x.replies | 60 ++++++++++--- + .../caps_8.1.0_x86_64.replies | 84 ++++++++++++------ + .../caps_8.2.0_aarch64.replies | 76 +++++++++++----- + .../caps_8.2.0_armv7l.replies | 76 +++++++++++----- + .../caps_8.2.0_loongarch64.replies | 64 ++++++++++---- + .../caps_8.2.0_s390x.replies | 60 ++++++++++--- + .../caps_8.2.0_x86_64.replies | 84 ++++++++++++------ + .../caps_9.0.0_sparc.replies | 52 ++++++++--- + .../caps_9.0.0_x86_64.replies | 84 ++++++++++++------ + .../caps_9.1.0_riscv64.replies | 64 ++++++++++---- + .../caps_9.1.0_s390x.replies | 64 ++++++++++---- + .../caps_9.1.0_x86_64.replies | 84 ++++++++++++------ + .../caps_9.2.0_aarch64+hvf.replies | 72 ++++++++++----- + .../caps_9.2.0_s390x.replies | 64 ++++++++++---- + .../caps_9.2.0_x86_64+amdsev.replies | 84 ++++++++++++------ + .../caps_9.2.0_x86_64.replies | 84 ++++++++++++------ + 36 files changed, 1880 insertions(+), 748 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index d738805ee8..1efb77d03b 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -1535,6 +1535,12 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIDisk[] = { + { "stats-intervals", QEMU_CAPS_DISK_TIMED_STATS, NULL }, + }; + ++static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIBlock[] = { ++}; ++ ++static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIGeneric[] = { ++}; ++ + static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsIDEDrive[] = { + { "stats-intervals", QEMU_CAPS_DISK_TIMED_STATS, NULL }, + }; +@@ -1779,6 +1785,12 @@ static virQEMUCapsDeviceTypeProps virQEMUCapsDeviceProps[] = { + { "amd-iommu", virQEMUCapsDevicePropsAMDIOMMU, + G_N_ELEMENTS(virQEMUCapsDevicePropsAMDIOMMU), + QEMU_CAPS_AMD_IOMMU }, ++ { "scsi-block", virQEMUCapsDevicePropsSCSIBlock, ++ G_N_ELEMENTS(virQEMUCapsDevicePropsSCSIBlock), ++ -1 }, ++ { "scsi-generic", virQEMUCapsDevicePropsSCSIGeneric, ++ G_N_ELEMENTS(virQEMUCapsDevicePropsSCSIGeneric), ++ -1 }, + }; + + static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMemoryBackendFile[] = { +diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.replies b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.replies +index f3d7ee69c1..0448dcaab9 100644 +--- a/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.replies ++++ b/tests/qemucapabilitiesdata/caps_10.0.0_aarch64.replies +@@ -32064,12 +32064,44 @@ + "id": "libvirt-30" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-32" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -32159,7 +32191,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -32167,7 +32199,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -32246,7 +32278,7 @@ + "type": "int" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -32254,7 +32286,7 @@ + "arguments": { + "typename": "max-arm-cpu" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -32502,12 +32534,12 @@ + "type": "link" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { + "execute": "query-machines", +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -33602,7 +33634,7 @@ + "default-ram-id": "ram" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -33610,7 +33642,7 @@ + "arguments": { + "typename": "virt-10.0-machine" + }, +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -33857,7 +33889,7 @@ + "type": "string" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -33865,7 +33897,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -33984,12 +34016,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -34283,12 +34315,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -35755,12 +35787,12 @@ + "option": "drive" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { + "execute": "query-gic-capabilities", +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -35776,7 +35808,7 @@ + "kernel": false + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -35787,7 +35819,7 @@ + "name": "host" + } + }, +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35820,7 +35852,7 @@ + } + } + }, +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35835,11 +35867,11 @@ + } + } + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +- "id": "libvirt-41", ++ "id": "libvirt-43", + "error": { + "class": "GenericError", + "desc": "Parameter 'model.props.hv-passthrough' is unexpected" +diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.replies b/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.replies +index 76d0b6fb6f..4833e479ad 100644 +--- a/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.replies ++++ b/tests/qemucapabilitiesdata/caps_10.0.0_ppc64.replies +@@ -31668,12 +31668,44 @@ + "id": "libvirt-31" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-33" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -31767,7 +31799,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -31775,7 +31807,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -31854,12 +31886,12 @@ + "type": "int" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { + "execute": "query-machines", +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -32198,7 +32230,7 @@ + "default-ram-id": "ppc_spapr.ram" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -32206,7 +32238,7 @@ + "arguments": { + "typename": "pseries-10.0-machine" + }, +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -32469,7 +32501,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -32477,7 +32509,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -32596,12 +32628,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -35133,12 +35165,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -36500,7 +36532,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.replies b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.replies +index 52068141f9..ecd9af85ce 100644 +--- a/tests/qemucapabilitiesdata/caps_10.0.0_s390x.replies ++++ b/tests/qemucapabilitiesdata/caps_10.0.0_s390x.replies +@@ -30530,12 +30530,44 @@ + "id": "libvirt-32" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-34" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-34" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -30625,7 +30657,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -30633,7 +30665,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -30712,12 +30744,12 @@ + "type": "int" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-machines", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -30992,7 +31024,7 @@ + "default-ram-id": "s390.ram" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -31000,7 +31032,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -31119,12 +31151,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -31834,12 +31866,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -33117,7 +33149,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -33128,7 +33160,7 @@ + "name": "host" + } + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -33200,7 +33232,7 @@ + } + } + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -33211,7 +33243,7 @@ + "name": "host" + } + }, +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -33367,7 +33399,7 @@ + } + } + }, +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.replies b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.replies +index d49f1c3548..b228f9fd25 100644 +--- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.replies ++++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64+amdsev.replies +@@ -32202,12 +32202,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32297,7 +32329,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32305,7 +32337,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32384,7 +32416,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32392,7 +32424,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -34565,12 +34597,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35226,7 +35258,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35234,7 +35266,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -35353,7 +35385,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -35361,7 +35393,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -35568,12 +35600,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -37350,12 +37382,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -38878,12 +38910,12 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +@@ -38894,16 +38926,16 @@ + "pdh": "AQAAAAE3AAADEAAAAwAAAAIAAAAZzB1NV5cz0ISI+tYZQHDF/dw77x1Zz+u2jw0cUf+KR3u958kjxZlN5IFNIo7sUgkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8eYMemS1wynFwgVIgw9ZdHI+6qmsr91sCHKjJHGGBLRF3DHGYtdCLEsYQCVmJQywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhAAAAIAAAC/3y8ro5AhFTmPkAnaWckGQXhPEnSKInCUEpNnGgufIttDMtWgsjaAX7Jve/Hjcg8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADe6oGDni6/LfA/HHDe0vBW4xoma82CBGyydXkq/PJfhO6fra1H9symYAiEd6db4n8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "cpu0-id": "BlAwmcr4Ruya3YvEGe2EBxuWjMAfIYolslNNM92RsIKxLkWDDRqivqSBOD+qQRCYS9joBYSHMD1g+rmjY+MmVw==" + }, +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "Could not open '/dev/sgx_vepc': No such file or directory" +@@ -38918,7 +38950,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39319,7 +39351,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39333,7 +39365,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39734,7 +39766,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39749,7 +39781,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -40261,7 +40293,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.replies +index 73d9a1b313..f67fc5d217 100644 +--- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.replies +@@ -32139,12 +32139,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32238,7 +32270,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32246,7 +32278,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32325,7 +32357,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32333,7 +32365,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -34506,12 +34538,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35167,7 +35199,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35175,7 +35207,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -35294,7 +35326,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -35302,7 +35334,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -35509,12 +35541,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -38147,12 +38179,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -39675,16 +39707,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -39693,11 +39725,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "Could not open '/dev/sgx_vepc': No such file or directory" +@@ -39712,7 +39744,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -40113,7 +40145,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -40127,7 +40159,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -40528,7 +40560,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -40543,7 +40575,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -41055,7 +41087,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.replies b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.replies +index 2c4dcb149e..d6ddd6a3c9 100644 +--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.replies ++++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.replies +@@ -31359,12 +31359,44 @@ + "id": "libvirt-34" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-35" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-35" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-36" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-36" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -31454,7 +31486,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -31462,7 +31494,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -31541,7 +31573,7 @@ + "type": "int" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -31549,7 +31581,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -33738,12 +33770,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { + "execute": "query-machines", +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -34149,7 +34181,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -34157,7 +34189,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -34276,7 +34308,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -34284,7 +34316,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34491,12 +34523,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -36342,12 +36374,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -37681,16 +37713,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +- "id": "libvirt-43", ++ "id": "libvirt-45", + "error": { + "class": "GenericError", + "desc": "SEV is not enabled in KVM" +@@ -37699,7 +37731,7 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -37727,7 +37759,7 @@ + ], + "flc": true + }, +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -37738,7 +37770,7 @@ + "name": "host" + } + }, +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +@@ -38143,7 +38175,7 @@ + } + } + }, +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +@@ -38157,7 +38189,7 @@ + } + } + }, +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +@@ -38562,7 +38594,7 @@ + } + } + }, +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +@@ -38573,7 +38605,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39089,7 +39121,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39104,7 +39136,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39620,7 +39652,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.replies +index 8b8079617f..b4ce4668e1 100644 +--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64.replies +@@ -32805,12 +32805,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32904,7 +32936,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32912,7 +32944,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32991,7 +33023,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32999,7 +33031,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -35206,12 +35238,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35617,7 +35649,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35625,7 +35657,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -35749,7 +35781,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -35757,7 +35789,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -35964,12 +35996,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -39021,12 +39053,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -40557,16 +40589,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -40575,11 +40607,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "Could not open '/dev/sgx_vepc': No such file or directory" +@@ -40594,7 +40626,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -40999,7 +41031,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -41013,7 +41045,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -41418,7 +41450,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -41429,7 +41461,7 @@ + "name": "host" + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -41948,7 +41980,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -41963,7 +41995,7 @@ + } + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-52" + } + + { +@@ -42482,7 +42514,7 @@ + } + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-52" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.replies b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.replies +index b8703698ce..168e3253ee 100644 +--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.replies ++++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64+mshv.replies +@@ -32293,12 +32293,44 @@ + "id": "libvirt-35" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-36" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-36" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -32392,7 +32424,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -32400,7 +32432,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32479,7 +32511,7 @@ + "type": "int" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32487,7 +32519,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -34718,12 +34750,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { + "execute": "query-machines", +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -35129,7 +35161,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -35137,7 +35169,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35261,7 +35293,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35269,7 +35301,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -35476,12 +35508,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -36861,12 +36893,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -38256,16 +38288,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +- "id": "libvirt-44", ++ "id": "libvirt-46", + "error": { + "class": "GenericError", + "desc": "KVM not enabled" +@@ -38274,11 +38306,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "Could not open '/dev/sgx_vepc': No such file or directory" +@@ -38293,7 +38325,7 @@ + "name": "host" + } + }, +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +@@ -38701,7 +38733,7 @@ + } + } + }, +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +@@ -38715,7 +38747,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39123,7 +39155,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39134,7 +39166,7 @@ + "name": "host" + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39658,7 +39690,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39673,7 +39705,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -40197,7 +40229,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies +index 72f27e7a48..cb4abb4533 100644 +--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies +@@ -33072,12 +33072,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -33171,7 +33203,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -33179,7 +33211,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -33258,7 +33290,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -33266,7 +33298,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -35497,12 +35529,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35908,7 +35940,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -35916,7 +35948,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -36040,7 +36072,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -36048,7 +36080,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -36255,12 +36287,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -38316,12 +38348,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -39852,16 +39884,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV is not enabled in KVM" +@@ -39870,11 +39902,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "Could not open '/dev/sgx_vepc': No such file or directory" +@@ -39889,7 +39921,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -40297,7 +40329,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -40311,7 +40343,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -40719,7 +40751,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -40730,7 +40762,7 @@ + "name": "host" + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -41254,7 +41286,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -41269,7 +41301,7 @@ + } + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-52" + } + + { +@@ -41793,7 +41825,7 @@ + } + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-52" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_6.2.0_ppc64.replies b/tests/qemucapabilitiesdata/caps_6.2.0_ppc64.replies +index c248bced28..9ca1e062f8 100644 +--- a/tests/qemucapabilitiesdata/caps_6.2.0_ppc64.replies ++++ b/tests/qemucapabilitiesdata/caps_6.2.0_ppc64.replies +@@ -25425,12 +25425,44 @@ + "id": "libvirt-31" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-33" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -25505,7 +25537,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -25513,7 +25545,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -25587,12 +25619,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { + "execute": "query-machines", +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -25955,7 +25987,7 @@ + "default-ram-id": "mpc8544ds.ram" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -25963,7 +25995,7 @@ + "arguments": { + "typename": "pseries-6.2-machine" + }, +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -26195,7 +26227,7 @@ + "type": "string" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -26203,7 +26235,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -26306,12 +26338,12 @@ + "type": "child" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -28963,12 +28995,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -30091,7 +30123,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_6.2.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_6.2.0_x86_64.replies +index 9b0d762799..60ad0860a1 100644 +--- a/tests/qemucapabilitiesdata/caps_6.2.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_6.2.0_x86_64.replies +@@ -25778,12 +25778,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -25862,7 +25894,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -25870,7 +25902,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -25944,7 +25976,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -25952,7 +25984,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -27692,12 +27724,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -28180,7 +28212,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -28188,7 +28220,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -28291,7 +28323,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -28299,7 +28331,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -28463,12 +28495,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -30492,12 +30524,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -31817,16 +31849,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -31835,11 +31867,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "SGX is not enabled in KVM" +@@ -31854,7 +31886,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -32187,7 +32219,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -32201,7 +32233,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -32534,7 +32566,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -32549,7 +32581,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -32882,7 +32914,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_7.0.0_ppc64.replies b/tests/qemucapabilitiesdata/caps_7.0.0_ppc64.replies +index 58a624b006..9eeaa3633e 100644 +--- a/tests/qemucapabilitiesdata/caps_7.0.0_ppc64.replies ++++ b/tests/qemucapabilitiesdata/caps_7.0.0_ppc64.replies +@@ -26130,12 +26130,44 @@ + "id": "libvirt-32" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-34" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-34" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -26214,7 +26246,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -26222,7 +26254,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -26296,12 +26328,12 @@ + "type": "int" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-machines", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -26673,7 +26705,7 @@ + "default-ram-id": "ppc_spapr.ram" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -26681,7 +26713,7 @@ + "arguments": { + "typename": "pseries-7.0-machine" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -26913,7 +26945,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -26921,7 +26953,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -27024,12 +27056,12 @@ + "type": "child" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -29555,12 +29587,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -30747,7 +30779,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_7.0.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_7.0.0_x86_64.replies +index 6f27d3a349..d6ba5062e9 100644 +--- a/tests/qemucapabilitiesdata/caps_7.0.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_7.0.0_x86_64.replies +@@ -26292,12 +26292,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -26376,7 +26408,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -26384,7 +26416,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -26458,7 +26490,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -26466,7 +26498,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -28222,12 +28254,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -28728,7 +28760,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -28736,7 +28768,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -28839,7 +28871,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -28847,7 +28879,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -29024,12 +29056,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -31089,12 +31121,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -32418,16 +32450,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -32436,7 +32468,7 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +@@ -32457,7 +32489,7 @@ + } + ] + }, +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +@@ -32468,7 +32500,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -32805,7 +32837,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -32819,7 +32851,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -33156,7 +33188,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -33171,7 +33203,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -33508,7 +33540,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_7.1.0_ppc64.replies b/tests/qemucapabilitiesdata/caps_7.1.0_ppc64.replies +index 546214a9ef..582a541a87 100644 +--- a/tests/qemucapabilitiesdata/caps_7.1.0_ppc64.replies ++++ b/tests/qemucapabilitiesdata/caps_7.1.0_ppc64.replies +@@ -26820,12 +26820,44 @@ + "id": "libvirt-32" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-34" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-34" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -26904,7 +26936,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -26912,7 +26944,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -26986,12 +27018,12 @@ + "type": "int" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-machines", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -27372,7 +27404,7 @@ + "default-ram-id": "ppc_spapr.ram" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -27380,7 +27412,7 @@ + "arguments": { + "typename": "pseries-7.1-machine" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -27622,7 +27654,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -27630,7 +27662,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -27743,12 +27775,12 @@ + "type": "child" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -30262,12 +30294,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -31454,7 +31486,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_7.1.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_7.1.0_x86_64.replies +index fcee75b20a..f8a7da376c 100644 +--- a/tests/qemucapabilitiesdata/caps_7.1.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_7.1.0_x86_64.replies +@@ -27037,12 +27037,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -27121,7 +27153,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -27129,7 +27161,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -27203,7 +27235,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -27211,7 +27243,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -29004,12 +29036,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -29528,7 +29560,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -29536,7 +29568,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -29649,7 +29681,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -29657,7 +29689,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -29849,12 +29881,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -31793,12 +31825,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -33122,16 +33154,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -33140,11 +33172,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "SGX is not enabled in KVM" +@@ -33159,7 +33191,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -33497,7 +33529,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -33511,7 +33543,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -33849,7 +33881,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -33864,7 +33896,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -34202,7 +34234,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_7.2.0_ppc.replies b/tests/qemucapabilitiesdata/caps_7.2.0_ppc.replies +index a55685c8f0..42e92e070b 100644 +--- a/tests/qemucapabilitiesdata/caps_7.2.0_ppc.replies ++++ b/tests/qemucapabilitiesdata/caps_7.2.0_ppc.replies +@@ -27426,12 +27426,44 @@ + "id": "libvirt-30" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-32" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -27515,7 +27547,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -27523,7 +27555,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -27602,12 +27634,12 @@ + "type": "int" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { + "execute": "query-machines", +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -27710,7 +27742,7 @@ + "default-ram-id": "mpc8544ds.ram" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -27718,7 +27750,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -27831,12 +27863,12 @@ + "type": "child" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -30146,12 +30178,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -31467,5 +31499,5 @@ + "option": "drive" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } +diff --git a/tests/qemucapabilitiesdata/caps_7.2.0_x86_64+hvf.replies b/tests/qemucapabilitiesdata/caps_7.2.0_x86_64+hvf.replies +index 1095899c6e..d4101c3c89 100644 +--- a/tests/qemucapabilitiesdata/caps_7.2.0_x86_64+hvf.replies ++++ b/tests/qemucapabilitiesdata/caps_7.2.0_x86_64+hvf.replies +@@ -28006,12 +28006,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -28095,7 +28127,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -28103,7 +28135,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -28182,7 +28214,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -28190,7 +28222,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -29983,12 +30015,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -30525,7 +30557,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -30533,7 +30565,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -30646,7 +30678,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -30654,7 +30686,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -30846,12 +30878,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -32790,12 +32822,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -34119,16 +34151,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -34137,11 +34169,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "SGX is not enabled in KVM" +@@ -34156,7 +34188,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -34494,7 +34526,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -34508,7 +34540,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -34846,7 +34878,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -34861,7 +34893,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -35199,7 +35231,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_7.2.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_7.2.0_x86_64.replies +index f87ebf41ee..801fbf5ad6 100644 +--- a/tests/qemucapabilitiesdata/caps_7.2.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_7.2.0_x86_64.replies +@@ -28006,12 +28006,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -28095,7 +28127,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -28103,7 +28135,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -28182,7 +28214,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -28190,7 +28222,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -29983,12 +30015,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -30525,7 +30557,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -30533,7 +30565,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -30646,7 +30678,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -30654,7 +30686,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -30846,12 +30878,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -32790,12 +32822,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -34119,16 +34151,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -34137,11 +34169,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "SGX is not enabled in KVM" +@@ -34156,7 +34188,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -34494,7 +34526,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -34508,7 +34540,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -34846,7 +34878,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -34861,7 +34893,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -35199,7 +35231,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.replies +index 49faceec28..97d1531611 100644 +--- a/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.replies +@@ -29355,12 +29355,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -29444,7 +29476,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -29452,7 +29484,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -29531,7 +29563,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -29539,7 +29571,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -31356,12 +31388,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -31977,7 +32009,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -31985,7 +32017,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -32098,7 +32130,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -32106,7 +32138,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -32298,12 +32330,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -34349,12 +34381,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -35795,16 +35827,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -35813,11 +35845,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "SGX is not enabled in KVM" +@@ -35832,7 +35864,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -36175,7 +36207,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -36189,7 +36221,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -36532,7 +36564,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -36547,7 +36579,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -36996,7 +37028,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_8.1.0_s390x.replies b/tests/qemucapabilitiesdata/caps_8.1.0_s390x.replies +index 8a71843283..6bd4f80dc2 100644 +--- a/tests/qemucapabilitiesdata/caps_8.1.0_s390x.replies ++++ b/tests/qemucapabilitiesdata/caps_8.1.0_s390x.replies +@@ -27805,12 +27805,44 @@ + "id": "libvirt-29" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-30" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-30" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-31" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-30" ++ "id": "libvirt-32" + } + + { +@@ -27895,7 +27927,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-30" ++ "id": "libvirt-32" + } + + { +@@ -27903,7 +27935,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -27982,12 +28014,12 @@ + "type": "int" + } + ], +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { + "execute": "query-machines", +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -28262,7 +28294,7 @@ + "default-ram-id": "s390.ram" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -28270,7 +28302,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -28383,12 +28415,12 @@ + "type": "child" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -29152,12 +29184,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -30380,7 +30412,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -30391,7 +30423,7 @@ + "name": "host" + } + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -30440,7 +30472,7 @@ + } + } + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.replies +index 458d656220..10906cb369 100644 +--- a/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.replies +@@ -30132,12 +30132,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -30226,7 +30258,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -30234,7 +30266,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -30313,7 +30345,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -30321,7 +30353,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -32218,12 +32250,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -32859,7 +32891,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -32867,7 +32899,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -32980,7 +33012,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -32988,7 +33020,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -33176,12 +33208,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -35563,12 +35595,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -37026,16 +37058,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -37044,11 +37076,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "SGX is not enabled in KVM" +@@ -37063,7 +37095,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -37426,7 +37458,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -37440,7 +37472,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -37803,7 +37835,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -37818,7 +37850,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -38287,7 +38319,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.replies b/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.replies +index d1ca8b37f5..002ca31b9f 100644 +--- a/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.replies ++++ b/tests/qemucapabilitiesdata/caps_8.2.0_aarch64.replies +@@ -31154,12 +31154,44 @@ + "id": "libvirt-31" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-33" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -31249,7 +31281,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -31257,7 +31289,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -31336,7 +31368,7 @@ + "type": "int" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -31344,7 +31376,7 @@ + "arguments": { + "typename": "max-arm-cpu" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -31553,12 +31585,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-machines", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -32670,7 +32702,7 @@ + "default-ram-id": "ram" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -32678,7 +32710,7 @@ + "arguments": { + "typename": "virt-8.2-machine" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -32914,7 +32946,7 @@ + "type": "child" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -32922,7 +32954,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -33035,12 +33067,12 @@ + "type": "child" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -33334,12 +33366,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -34704,12 +34736,12 @@ + "option": "drive" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-gic-capabilities", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34725,7 +34757,7 @@ + "kernel": false + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34736,7 +34768,7 @@ + "name": "host" + } + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -34769,7 +34801,7 @@ + } + } + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -34784,11 +34816,11 @@ + } + } + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +- "id": "libvirt-42", ++ "id": "libvirt-44", + "error": { + "class": "GenericError", + "desc": "Parameter 'hv-passthrough' is unexpected" +diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.replies b/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.replies +index d28046578d..b8f7b6f68a 100644 +--- a/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.replies ++++ b/tests/qemucapabilitiesdata/caps_8.2.0_armv7l.replies +@@ -31388,12 +31388,44 @@ + "id": "libvirt-31" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-33" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -31487,7 +31519,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -31495,7 +31527,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -31574,7 +31606,7 @@ + "type": "int" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -31582,7 +31614,7 @@ + "arguments": { + "typename": "max-arm-cpu" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -31724,12 +31756,12 @@ + "type": "link" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-machines", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -32787,7 +32819,7 @@ + "default-ram-id": "ram" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -32795,7 +32827,7 @@ + "arguments": { + "typename": "virt-8.2-machine" + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -33031,7 +33063,7 @@ + "type": "child" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -33039,7 +33071,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -33152,12 +33184,12 @@ + "type": "child" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -33379,12 +33411,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -34866,12 +34898,12 @@ + "option": "drive" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-gic-capabilities", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34887,7 +34919,7 @@ + "kernel": false + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34898,11 +34930,11 @@ + "name": "host" + } + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +- "id": "libvirt-41", ++ "id": "libvirt-43", + "error": { + "class": "GenericError", + "desc": "The CPU type 'host' requires KVM" +@@ -34921,11 +34953,11 @@ + } + } + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +- "id": "libvirt-42", ++ "id": "libvirt-44", + "error": { + "class": "GenericError", + "desc": "The CPU type 'host' requires KVM" +diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_loongarch64.replies b/tests/qemucapabilitiesdata/caps_8.2.0_loongarch64.replies +index 7f2bb97635..a908ebf644 100644 +--- a/tests/qemucapabilitiesdata/caps_8.2.0_loongarch64.replies ++++ b/tests/qemucapabilitiesdata/caps_8.2.0_loongarch64.replies +@@ -28042,12 +28042,44 @@ + "id": "libvirt-30" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-32" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -28137,7 +28169,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -28145,7 +28177,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -28224,12 +28256,12 @@ + "type": "int" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { + "execute": "query-machines", +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -28263,7 +28295,7 @@ + "default-ram-id": "ram" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -28271,7 +28303,7 @@ + "arguments": { + "typename": "virt-machine" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -28403,7 +28435,7 @@ + "type": "str" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -28411,7 +28443,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -28524,12 +28556,12 @@ + "type": "child" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -28553,12 +28585,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -29873,7 +29905,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -29884,11 +29916,11 @@ + "name": "host" + } + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +- "id": "libvirt-38", ++ "id": "libvirt-40", + "error": { + "class": "GenericError", + "desc": "The CPU type 'host' is not a recognized LoongArch CPU type" +diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_s390x.replies b/tests/qemucapabilitiesdata/caps_8.2.0_s390x.replies +index 492cef2065..4ee07edb25 100644 +--- a/tests/qemucapabilitiesdata/caps_8.2.0_s390x.replies ++++ b/tests/qemucapabilitiesdata/caps_8.2.0_s390x.replies +@@ -28498,12 +28498,44 @@ + "id": "libvirt-29" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-30" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-30" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-31" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-30" ++ "id": "libvirt-32" + } + + { +@@ -28593,7 +28625,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-30" ++ "id": "libvirt-32" + } + + { +@@ -28601,7 +28633,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -28680,12 +28712,12 @@ + "type": "int" + } + ], +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { + "execute": "query-machines", +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -28970,7 +29002,7 @@ + "default-ram-id": "s390.ram" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -28978,7 +29010,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -29091,12 +29123,12 @@ + "type": "child" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -29860,12 +29892,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -31096,7 +31128,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -31107,7 +31139,7 @@ + "name": "host" + } + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -31156,7 +31188,7 @@ + } + } + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.replies +index 4b34b01eea..aedd6ec2de 100644 +--- a/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.replies +@@ -30823,12 +30823,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -30922,7 +30954,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -30930,7 +30962,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -31009,7 +31041,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -31017,7 +31049,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -32930,12 +32962,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -33551,7 +33583,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -33559,7 +33591,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -33672,7 +33704,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -33680,7 +33712,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -33868,12 +33900,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -36255,12 +36287,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -37731,16 +37763,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -37749,11 +37781,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "SGX is not enabled in KVM" +@@ -37768,7 +37800,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -38135,7 +38167,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -38149,7 +38181,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -38516,7 +38548,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -38531,7 +38563,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -39004,7 +39036,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_9.0.0_sparc.replies b/tests/qemucapabilitiesdata/caps_9.0.0_sparc.replies +index 2d492d7b06..90086a65cc 100644 +--- a/tests/qemucapabilitiesdata/caps_9.0.0_sparc.replies ++++ b/tests/qemucapabilitiesdata/caps_9.0.0_sparc.replies +@@ -24332,12 +24332,44 @@ + } + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-17" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-17" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-18" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-18" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-17" ++ "id": "libvirt-19" + } + + { +@@ -24431,7 +24463,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-17" ++ "id": "libvirt-19" + } + + { +@@ -24439,7 +24471,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-18" ++ "id": "libvirt-20" + } + + { +@@ -24518,12 +24550,12 @@ + "type": "int" + } + ], +- "id": "libvirt-18" ++ "id": "libvirt-20" + } + + { + "execute": "query-machines", +- "id": "libvirt-19" ++ "id": "libvirt-21" + } + + { +@@ -24639,7 +24671,7 @@ + "default-ram-id": "ram" + } + ], +- "id": "libvirt-19" ++ "id": "libvirt-21" + } + + { +@@ -24647,7 +24679,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-20" ++ "id": "libvirt-22" + } + + { +@@ -24760,12 +24792,12 @@ + "type": "child" + } + ], +- "id": "libvirt-20" ++ "id": "libvirt-22" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-21" ++ "id": "libvirt-23" + } + + { +@@ -26098,5 +26130,5 @@ + "option": "drive" + } + ], +- "id": "libvirt-21" ++ "id": "libvirt-23" + } +diff --git a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.replies +index 6099885857..270ba9f557 100644 +--- a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.replies +@@ -31019,12 +31019,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -31118,7 +31150,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -31126,7 +31158,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -31205,7 +31237,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -31213,7 +31245,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -33130,12 +33162,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -33771,7 +33803,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -33779,7 +33811,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -33892,7 +33924,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -33900,7 +33932,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -34092,12 +34124,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -36479,12 +36511,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -37959,16 +37991,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -37977,11 +38009,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "SGX is not enabled in KVM" +@@ -37996,7 +38028,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -38364,7 +38396,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -38378,7 +38410,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -38746,7 +38778,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -38761,7 +38793,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -39235,7 +39267,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.replies b/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.replies +index 51896936cc..e0a9a3082b 100644 +--- a/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.replies ++++ b/tests/qemucapabilitiesdata/caps_9.1.0_riscv64.replies +@@ -29380,12 +29380,44 @@ + "id": "libvirt-29" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-30" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-30" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-31" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-30" ++ "id": "libvirt-32" + } + + { +@@ -29479,7 +29511,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-30" ++ "id": "libvirt-32" + } + + { +@@ -29487,7 +29519,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -29566,12 +29598,12 @@ + "type": "int" + } + ], +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { + "execute": "query-machines", +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -29646,7 +29678,7 @@ + "default-ram-id": "riscv_virt_board.ram" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -29654,7 +29686,7 @@ + "arguments": { + "typename": "virt-machine" + }, +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -29810,7 +29842,7 @@ + "type": "child" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -29818,7 +29850,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -29931,12 +29963,12 @@ + "type": "child" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -30020,12 +30052,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -31439,7 +31471,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -31450,11 +31482,11 @@ + "name": "host" + } + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +- "id": "libvirt-37", ++ "id": "libvirt-39", + "error": { + "class": "GenericError", + "desc": "The requested expansion type is not supported" +diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.replies b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.replies +index d8f0b032ba..4ea1a6a6f7 100644 +--- a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.replies ++++ b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.replies +@@ -29547,12 +29547,44 @@ + "id": "libvirt-30" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-32" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -29642,7 +29674,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -29650,7 +29682,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -29729,12 +29761,12 @@ + "type": "int" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { + "execute": "query-machines", +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -30039,7 +30071,7 @@ + "default-ram-id": "s390.ram" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -30047,7 +30079,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -30160,12 +30192,12 @@ + "type": "child" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -30803,12 +30835,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -32047,7 +32079,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -32058,7 +32090,7 @@ + "name": "host" + } + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32130,7 +32162,7 @@ + } + } + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32141,7 +32173,7 @@ + "name": "host" + } + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32213,7 +32245,7 @@ + } + } + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.replies +index 7c6c525d12..257e43a145 100644 +--- a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.replies +@@ -31428,12 +31428,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -31527,7 +31559,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -31535,7 +31567,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -31614,7 +31646,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -31622,7 +31654,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -33671,12 +33703,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34292,7 +34324,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34300,7 +34332,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -34413,7 +34445,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -34421,7 +34453,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -34613,12 +34645,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -37169,12 +37201,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -38657,16 +38689,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -38675,11 +38707,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "Could not open '/dev/sgx_vepc': No such file or directory" +@@ -38694,7 +38726,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39072,7 +39104,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39086,7 +39118,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39464,7 +39496,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39479,7 +39511,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -39967,7 +39999,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.replies b/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.replies +index 66dcfe42d0..14b11c5c30 100644 +--- a/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.replies ++++ b/tests/qemucapabilitiesdata/caps_9.2.0_aarch64+hvf.replies +@@ -30529,12 +30529,44 @@ + "id": "libvirt-27" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-28" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-28" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-29" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-29" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-28" ++ "id": "libvirt-30" + } + + { +@@ -30619,7 +30651,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-28" ++ "id": "libvirt-30" + } + + { +@@ -30627,7 +30659,7 @@ + "arguments": { + "typename": "max-arm-cpu" + }, +- "id": "libvirt-29" ++ "id": "libvirt-31" + } + + { +@@ -30784,12 +30816,12 @@ + "type": "link" + } + ], +- "id": "libvirt-29" ++ "id": "libvirt-31" + } + + { + "execute": "query-machines", +- "id": "libvirt-30" ++ "id": "libvirt-32" + } + + { +@@ -31839,7 +31871,7 @@ + "default-ram-id": "ram" + } + ], +- "id": "libvirt-30" ++ "id": "libvirt-32" + } + + { +@@ -31847,7 +31879,7 @@ + "arguments": { + "typename": "virt-9.2-machine" + }, +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -32088,7 +32120,7 @@ + "type": "child" + } + ], +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -32096,7 +32128,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -32214,12 +32246,12 @@ + "type": "child" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -32513,12 +32545,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -33834,12 +33866,12 @@ + "option": "drive" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-gic-capabilities", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -33855,7 +33887,7 @@ + "kernel": false + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -33866,11 +33898,11 @@ + "name": "host" + } + }, +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +- "id": "libvirt-36", ++ "id": "libvirt-38", + "error": { + "class": "GenericError", + "desc": "The CPU type 'host' requires KVM" +@@ -33889,11 +33921,11 @@ + } + } + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +- "id": "libvirt-37", ++ "id": "libvirt-39", + "error": { + "class": "GenericError", + "desc": "The CPU type 'host' requires KVM" +diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.replies b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.replies +index 1a47f2b71b..78a59cf3e5 100644 +--- a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.replies ++++ b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.replies +@@ -29757,12 +29757,44 @@ + "id": "libvirt-30" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-32" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -29852,7 +29884,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-31" ++ "id": "libvirt-33" + } + + { +@@ -29860,7 +29892,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { +@@ -29939,12 +29971,12 @@ + "type": "int" + } + ], +- "id": "libvirt-32" ++ "id": "libvirt-34" + } + + { + "execute": "query-machines", +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -30259,7 +30291,7 @@ + "default-ram-id": "s390.ram" + } + ], +- "id": "libvirt-33" ++ "id": "libvirt-35" + } + + { +@@ -30267,7 +30299,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { +@@ -30385,12 +30417,12 @@ + "type": "child" + } + ], +- "id": "libvirt-34" ++ "id": "libvirt-36" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { +@@ -31028,12 +31060,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-35" ++ "id": "libvirt-37" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -32281,7 +32313,7 @@ + "option": "drive" + } + ], +- "id": "libvirt-36" ++ "id": "libvirt-38" + } + + { +@@ -32292,7 +32324,7 @@ + "name": "host" + } + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32364,7 +32396,7 @@ + } + } + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -32375,7 +32407,7 @@ + "name": "host" + } + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32516,7 +32548,7 @@ + } + } + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.replies b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.replies +index 764b71bcdc..81a4188752 100644 +--- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.replies ++++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64+amdsev.replies +@@ -31872,12 +31872,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -31971,7 +32003,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -31979,7 +32011,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32058,7 +32090,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -32066,7 +32098,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -34208,12 +34240,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34859,7 +34891,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34867,7 +34899,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -34985,7 +35017,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -34993,7 +35025,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -35191,12 +35223,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -36821,12 +36853,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -38339,12 +38371,12 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +@@ -38355,16 +38387,16 @@ + "pdh": "AQAAAAE3AAADEAAAAwAAAAIAAAAZzB1NV5cz0ISI+tYZQHDF/dw77x1Zz+u2jw0cUf+KR3u958kjxZlN5IFNIo7sUgkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8eYMemS1wynFwgVIgw9ZdHI+6qmsr91sCHKjJHGGBLRF3DHGYtdCLEsYQCVmJQywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhAAAAIAAAC/3y8ro5AhFTmPkAnaWckGQXhPEnSKInCUEpNnGgufIttDMtWgsjaAX7Jve/Hjcg8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADe6oGDni6/LfA/HHDe0vBW4xoma82CBGyydXkq/PJfhO6fra1H9symYAiEd6db4n8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "cpu0-id": "BlAwmcr4Ruya3YvEGe2EBxuWjMAfIYolslNNM92RsIKxLkWDDRqivqSBOD+qQRCYS9joBYSHMD1g+rmjY+MmVw==" + }, +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "Could not open '/dev/sgx_vepc': No such file or directory" +@@ -38379,7 +38411,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -38779,7 +38811,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -38793,7 +38825,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39193,7 +39225,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39208,7 +39240,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -39719,7 +39751,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.replies +index 1b68825df6..69182ce4fc 100644 +--- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.replies +@@ -31764,12 +31764,44 @@ + "id": "libvirt-36" + } + ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-block" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "The libvirt device dump was not collected for this version+device tuple" ++ }, ++ "id": "libvirt-38" ++} ++ + { + "execute": "qom-list-properties", + "arguments": { + "typename": "memory-backend-file" + }, +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -31863,7 +31895,7 @@ + "type": "bool" + } + ], +- "id": "libvirt-37" ++ "id": "libvirt-39" + } + + { +@@ -31871,7 +31903,7 @@ + "arguments": { + "typename": "memory-backend-memfd" + }, +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -31950,7 +31982,7 @@ + "type": "int" + } + ], +- "id": "libvirt-38" ++ "id": "libvirt-40" + } + + { +@@ -31958,7 +31990,7 @@ + "arguments": { + "typename": "max-x86_64-cpu" + }, +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { +@@ -34100,12 +34132,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-39" ++ "id": "libvirt-41" + } + + { + "execute": "query-machines", +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34741,7 +34773,7 @@ + "default-ram-id": "pc.ram" + } + ], +- "id": "libvirt-40" ++ "id": "libvirt-42" + } + + { +@@ -34749,7 +34781,7 @@ + "arguments": { + "typename": "none-machine" + }, +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -34867,7 +34899,7 @@ + "type": "child" + } + ], +- "id": "libvirt-41" ++ "id": "libvirt-43" + } + + { +@@ -34875,7 +34907,7 @@ + "arguments": { + "typename": "generic-pc-machine" + }, +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { +@@ -35073,12 +35105,12 @@ + "type": "bool" + } + ], +- "id": "libvirt-42" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { +@@ -37521,12 +37553,12 @@ + "deprecated": false + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-45" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { +@@ -39019,16 +39051,16 @@ + "option": "drive" + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-46" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-45" ++ "id": "libvirt-47" + } + + { +- "id": "libvirt-45", ++ "id": "libvirt-47", + "error": { + "class": "GenericError", + "desc": "SEV: Failed to open /dev/sev: No such file or directory" +@@ -39037,11 +39069,11 @@ + + { + "execute": "query-sgx-capabilities", +- "id": "libvirt-46" ++ "id": "libvirt-48" + } + + { +- "id": "libvirt-46", ++ "id": "libvirt-48", + "error": { + "class": "GenericError", + "desc": "Could not open '/dev/sgx_vepc': No such file or directory" +@@ -39056,7 +39088,7 @@ + "name": "host" + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39456,7 +39488,7 @@ + } + } + }, +- "id": "libvirt-47" ++ "id": "libvirt-49" + } + + { +@@ -39470,7 +39502,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39870,7 +39902,7 @@ + } + } + }, +- "id": "libvirt-48" ++ "id": "libvirt-50" + } + + { +@@ -39885,7 +39917,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +@@ -40396,7 +40428,7 @@ + } + } + }, +- "id": "libvirt-49" ++ "id": "libvirt-51" + } + + { +-- +2.53.0 diff --git a/libvirt-qemu-migration-Always-offer-block-dirty-bitmaps-during-migration.patch b/libvirt-qemu-migration-Always-offer-block-dirty-bitmaps-during-migration.patch new file mode 100644 index 0000000..ac29a72 --- /dev/null +++ b/libvirt-qemu-migration-Always-offer-block-dirty-bitmaps-during-migration.patch @@ -0,0 +1,147 @@ +From 64ae2c71b95cd25fb1e18fbc68ddbc814f3de8ca Mon Sep 17 00:00:00 2001 +Message-ID: <64ae2c71b95cd25fb1e18fbc68ddbc814f3de8ca.1770203422.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Tue, 27 Jan 2026 17:00:10 +0100 +Subject: [PATCH] qemu: migration: Always offer block dirty bitmaps during + migration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Until now block dirty bitmaps were offered to destination only if +non-shared storage migration was enabled. + +Upcoming patches will want to support it also in cases when storage is +shared but the destination has a qcow2 overlay using the 'data_file' +feature where the qcow2 overlay is not actually shared. + +To support that we'll now always offer bitmaps for migration. The +destination can then decide (using existing logic) to pick only the +ones that are not present in the image on destination, which is how +it was supposed to work even now. + +The patch removes all the flag checks and simply offers bitmaps in any +case. The overhead incurred by this is one 'query-named-block-nodes' +call to qemu. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit a4f610ff3fe190058f18baea18b095d0bc69441b) + +https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2] +https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8] +--- + src/qemu/qemu_migration.c | 28 +++++++--------------------- + 1 file changed, 7 insertions(+), 21 deletions(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 723e131c98..755b9a5e1a 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -2580,16 +2580,13 @@ qemuMigrationAnyConnectionClosed(virDomainObj *vm, + * qemuMigrationSrcBeginPhaseBlockDirtyBitmaps: + * @mig: migration cookie struct + * @vm: domain object +- * @migrate_disks: disks which are being migrated +- * @nmigrage_disks: number of @migrate_disks + * + * Enumerates block dirty bitmaps on disks which will undergo storage migration + * and fills them into @mig to be offered to the destination. + */ + static int + qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(qemuMigrationCookie *mig, +- virDomainObj *vm, +- const char **migrate_disks) ++ virDomainObj *vm) + + { + GSList *disks = NULL; +@@ -2611,9 +2608,6 @@ qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(qemuMigrationCookie *mig, + if (!nodedata) + continue; + +- if (!qemuMigrationAnyCopyDisk(diskdef, migrate_disks)) +- continue; +- + for (j = 0; j < nodedata->nbitmaps; j++) { + qemuMigrationBlockDirtyBitmapsDiskBitmap *bitmap; + +@@ -2680,7 +2674,6 @@ qemuMigrationSrcBeginXML(virDomainObj *vm, + char **cookieout, + int *cookieoutlen, + unsigned int cookieFlags, +- const char **migrate_disks, + unsigned int flags) + { + qemuDomainObjPrivate *priv = vm->privateData; +@@ -2696,8 +2689,7 @@ qemuMigrationSrcBeginXML(virDomainObj *vm, + if (!(mig = qemuMigrationCookieNew(vm->def, priv->origname))) + return NULL; + +- if (cookieFlags & QEMU_MIGRATION_COOKIE_NBD && +- qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm, migrate_disks) < 0) ++ if (qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm) < 0) + return NULL; + + if (qemuMigrationCookieFormat(mig, driver, vm, +@@ -2879,8 +2871,7 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver, + return NULL; + + return qemuMigrationSrcBeginXML(vm, xmlin, +- cookieout, cookieoutlen, cookieFlags, +- migrate_disks, flags); ++ cookieout, cookieoutlen, cookieFlags, flags); + } + + +@@ -2969,8 +2960,7 @@ qemuMigrationSrcBeginResume(virDomainObj *vm, + return NULL; + } + +- return qemuMigrationSrcBeginXML(vm, xmlin, +- cookieout, cookieoutlen, 0, NULL, flags); ++ return qemuMigrationSrcBeginXML(vm, xmlin, cookieout, cookieoutlen, 0, flags); + } + + +@@ -4752,7 +4742,6 @@ qemuMigrationSrcRunPrepareBlockDirtyBitmaps(virDomainObj *vm, + + /* For VIR_MIGRATE_NON_SHARED_INC we can migrate the bitmaps directly, + * otherwise we must create merged bitmaps from the whole chain */ +- + if (!(flags & VIR_MIGRATE_NON_SHARED_INC) && + qemuMigrationSrcRunPrepareBlockDirtyBitmapsMerge(vm, mig) < 0) + return -1; +@@ -4943,7 +4932,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver, + VIR_AUTOCLOSE fd = -1; + unsigned long restore_max_bandwidth = priv->migMaxBandwidth; + virErrorPtr orig_err = NULL; +- unsigned int cookieFlags = 0; ++ unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS; + bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR); + bool storageMigration = flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC); + bool cancel = false; +@@ -4967,10 +4956,8 @@ qemuMigrationSrcRun(virQEMUDriver *driver, + storageMigration = qemuMigrationHasAnyStorageMigrationDisks(vm->def, + migrate_disks); + +- if (storageMigration) { ++ if (storageMigration) + cookieFlags |= QEMU_MIGRATION_COOKIE_NBD; +- cookieFlags |= QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS; +- } + + if (virLockManagerPluginUsesState(driver->lockManager) && + !cookieout) { +@@ -5004,8 +4991,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver, + cookiein, cookieinlen, + cookieFlags | + QEMU_MIGRATION_COOKIE_GRAPHICS | +- QEMU_MIGRATION_COOKIE_CAPS | +- QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS); ++ QEMU_MIGRATION_COOKIE_CAPS); + if (!mig) + goto error; + +-- +2.52.0 diff --git a/libvirt-qemu-monitor-Add-handlers-for-block-latency-histogram-set.patch b/libvirt-qemu-monitor-Add-handlers-for-block-latency-histogram-set.patch new file mode 100644 index 0000000..438aebd --- /dev/null +++ b/libvirt-qemu-monitor-Add-handlers-for-block-latency-histogram-set.patch @@ -0,0 +1,182 @@ +From 99b1b6fda9b4e098a7bbbbb44e02064c57bff558 Mon Sep 17 00:00:00 2001 +Message-ID: <99b1b6fda9b4e098a7bbbbb44e02064c57bff558.1771336681.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Thu, 11 Dec 2025 18:38:12 +0100 +Subject: [PATCH] qemu: monitor: Add handlers for 'block-latency-histogram-set' + +Add QMP monitor code for setting up latency histogram configuration. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit ad4830ce6844b75800685ea85b15a53b8dbc5ac6) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + src/qemu/qemu_monitor.c | 21 +++++++++++++ + src/qemu/qemu_monitor.h | 9 ++++++ + src/qemu/qemu_monitor_json.c | 60 ++++++++++++++++++++++++++++++++++++ + src/qemu/qemu_monitor_json.h | 9 ++++++ + tests/qemumonitorjsontest.c | 9 ++++++ + 5 files changed, 108 insertions(+) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index cdd08004fb..3d7477c01c 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -4612,3 +4612,24 @@ qemuMonitorBlockdevSetActive(qemuMonitor *mon, + + return qemuMonitorJSONBlockdevSetActive(mon, nodename, active); + } ++ ++ ++int ++qemuMonitorBlockLatencyHistogramSet(qemuMonitor *mon, ++ const char *id, ++ unsigned int *boundaries, ++ unsigned int *boundaries_read, ++ unsigned int *boundaries_write, ++ unsigned int *boundaries_zone, ++ unsigned int *boundaries_flush) ++{ ++ QEMU_CHECK_MONITOR(mon); ++ VIR_DEBUG("id='%s'", id); ++ ++ return qemuMonitorJSONBlockLatencyHistogramSet(mon, id, ++ boundaries, ++ boundaries_read, ++ boundaries_write, ++ boundaries_zone, ++ boundaries_flush); ++} +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index 238f7be875..bbe400003a 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -1988,3 +1988,12 @@ int + qemuMonitorBlockdevSetActive(qemuMonitor *mon, + const char *nodename, + bool active); ++ ++int ++qemuMonitorBlockLatencyHistogramSet(qemuMonitor *mon, ++ const char *id, ++ unsigned int *boundaries, ++ unsigned int *boundaries_read, ++ unsigned int *boundaries_write, ++ unsigned int *boundaries_zone, ++ unsigned int *boundaries_flush); +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index edeea22ee0..45f690d9e2 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -9130,3 +9130,63 @@ qemuMonitorJSONBlockdevSetActive(qemuMonitor *mon, + + return qemuMonitorJSONCheckError(cmd, reply); + } ++ ++ ++static virJSONValue * ++qemuMonitorJSONBlockLatencyHistogramBoundary(unsigned int *bound) ++{ ++ g_autoptr(virJSONValue) ret = virJSONValueNewArray(); ++ ++ if (!bound) ++ return NULL; ++ ++ for (; *bound > 0; bound++) { ++ g_autoptr(virJSONValue) val = virJSONValueNewNumberUint(*bound); ++ ++ /* the only error is if the first argument is not an array */ ++ ignore_value(virJSONValueArrayAppend(ret, &val)); ++ } ++ ++ return g_steal_pointer(&ret); ++} ++ ++ ++int ++qemuMonitorJSONBlockLatencyHistogramSet(qemuMonitor *mon, ++ const char *id, ++ unsigned int *boundaries, ++ unsigned int *boundaries_read, ++ unsigned int *boundaries_write, ++ unsigned int *boundaries_zone, ++ unsigned int *boundaries_flush) ++{ ++ g_autoptr(virJSONValue) cmd = NULL; ++ g_autoptr(virJSONValue) reply = NULL; ++ ++ g_autoptr(virJSONValue) bound = NULL; ++ g_autoptr(virJSONValue) bound_read = NULL; ++ g_autoptr(virJSONValue) bound_write = NULL; ++ g_autoptr(virJSONValue) bound_zone = NULL; ++ g_autoptr(virJSONValue) bound_flush = NULL; ++ ++ bound = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries); ++ bound_read = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries_read); ++ bound_write = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries_write); ++ bound_zone = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries_zone); ++ bound_flush = qemuMonitorJSONBlockLatencyHistogramBoundary(boundaries_flush); ++ ++ if (!(cmd = qemuMonitorJSONMakeCommand("block-latency-histogram-set", ++ "s:id", id, ++ "A:boundaries", &bound, ++ "A:boundaries-read", &bound_read, ++ "A:boundaries-write", &bound_write, ++ "A:boundaries-zap", &bound_zone, ++ "A:boundaries-flush", &bound_flush, ++ NULL))) ++ return -1; ++ ++ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) ++ return -1; ++ ++ return qemuMonitorJSONCheckError(cmd, reply); ++} +diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h +index db9160eb68..b418f70048 100644 +--- a/src/qemu/qemu_monitor_json.h ++++ b/src/qemu/qemu_monitor_json.h +@@ -815,3 +815,12 @@ int + qemuMonitorJSONBlockdevSetActive(qemuMonitor *mon, + const char *nodename, + bool active); ++ ++int ++qemuMonitorJSONBlockLatencyHistogramSet(qemuMonitor *mon, ++ const char *id, ++ unsigned int *boundaries, ++ unsigned int *boundaries_read, ++ unsigned int *boundaries_write, ++ unsigned int *boundaries_zone, ++ unsigned int *boundaries_flush); +diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c +index bfe81739a7..1c1aaaa586 100644 +--- a/tests/qemumonitorjsontest.c ++++ b/tests/qemumonitorjsontest.c +@@ -1130,6 +1130,14 @@ GEN_TEST_FUNC(qemuMonitorJSONSetAction, + GEN_TEST_FUNC(qemuMonitorJSONSetLaunchSecurityState, "sev_secret_header", + "sev_secret", 0, true) + ++unsigned int testHistogramBoundaries[] = {10, 30, 50, 0}; ++GEN_TEST_FUNC(qemuMonitorJSONBlockLatencyHistogramSet, "devid", ++ testHistogramBoundaries, ++ testHistogramBoundaries, ++ testHistogramBoundaries, ++ testHistogramBoundaries, ++ testHistogramBoundaries) ++ + static int + testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque) + { +@@ -2958,6 +2966,7 @@ mymain(void) + DO_TEST_GEN(qemuMonitorJSONBlockJobCancel); + DO_TEST_GEN(qemuMonitorJSONSetAction); + DO_TEST_GEN(qemuMonitorJSONSetLaunchSecurityState); ++ DO_TEST_GEN(qemuMonitorJSONBlockLatencyHistogramSet); + DO_TEST(qemuMonitorJSONGetBalloonInfo); + DO_TEST(qemuMonitorJSONGetBlockInfo); + DO_TEST(qemuMonitorJSONGetAllBlockStatsInfo); +-- +2.53.0 diff --git a/libvirt-qemu-monitor-Detect-list-of-bitmaps-from-qcow2-format-specific-data.patch b/libvirt-qemu-monitor-Detect-list-of-bitmaps-from-qcow2-format-specific-data.patch new file mode 100644 index 0000000..6c5623b --- /dev/null +++ b/libvirt-qemu-monitor-Detect-list-of-bitmaps-from-qcow2-format-specific-data.patch @@ -0,0 +1,173 @@ +From 0722d1d58171ca59ec1852026cf6df0faa0d9312 Mon Sep 17 00:00:00 2001 +Message-ID: <0722d1d58171ca59ec1852026cf6df0faa0d9312.1770203422.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Tue, 27 Jan 2026 20:07:32 +0100 +Subject: [PATCH] qemu: monitor: Detect list of bitmaps from 'qcow2' format + specific data +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We currently probe dirty block tracking bitmaps by looking at the loaded +ones ('dirty-bitmaps'). Unfortunately those may not yet be populated on +incoming migration when the image was not yet activated, but we need to +know which ones are stored in the image so that we don't migrate those +explicitly, which would fail. + +Load the list of bitmaps in a qcow2 image from the format specific data, +which is already loaded at that point. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit b2fe3465de1db033e436f38fdd24648c8c884a3d) + +https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2] +https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8] +--- + src/qemu/qemu_monitor.h | 4 ++++ + src/qemu/qemu_monitor_json.c | 17 +++++++++++++++++ + tests/qemublocktest.c | 11 +++++++++++ + tests/qemublocktestdata/bitmap/snapshots.out | 5 +++++ + tests/qemublocktestdata/bitmap/synthetic.out | 4 ++++ + 5 files changed, 41 insertions(+) + +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index d096f474c1..041aa7bc12 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -893,8 +893,12 @@ struct _qemuBlockNamedNodeData { + unsigned long long capacity; + unsigned long long physical; + ++ /* Information about change block tracking bitmaps which are active and loaded */ + qemuBlockNamedNodeDataBitmap **bitmaps; + size_t nbitmaps; ++ /* With qcow2 we have also a separate list of bitmaps present in the image ++ * but not yet activated, which happens when starting qemu during migration */ ++ char **qcow2bitmaps; + + /* hash table indexed by snapshot name containing data about snapshots + * (qemuBlockNamedNodeDataSnapshot) */ +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 494d7ef515..401a28ff9a 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -2730,6 +2730,7 @@ qemuMonitorJSONBlockNamedNodeDataFree(qemuBlockNamedNodeData *data) + qemuMonitorJSONBlockNamedNodeDataBitmapFree(data->bitmaps[i]); + g_clear_pointer(&data->snapshots, g_hash_table_unref); + g_free(data->bitmaps); ++ g_strfreev(data->qcow2bitmaps); + g_free(data); + } + G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuBlockNamedNodeData, qemuMonitorJSONBlockNamedNodeDataFree); +@@ -2854,6 +2855,9 @@ qemuMonitorJSONBlockGetNamedNodeDataWorker(size_t pos G_GNUC_UNUSED, + virJSONValue *qcow2props = virJSONValueObjectGetObject(format_specific, "data"); + + if (qcow2props) { ++ virJSONValue *bmp; ++ size_t nbmp; ++ + if (STREQ_NULLABLE(virJSONValueObjectGetString(qcow2props, "compat"), "0.10")) + ent->qcow2v2 = true; + +@@ -2862,6 +2866,19 @@ qemuMonitorJSONBlockGetNamedNodeDataWorker(size_t pos G_GNUC_UNUSED, + + ignore_value(virJSONValueObjectGetBoolean(qcow2props, "data-file-raw", + &ent->qcow2dataFileRaw)); ++ ++ if ((bmp = virJSONValueObjectGetArray(qcow2props, "bitmaps")) && ++ ((nbmp = virJSONValueArraySize(bmp)) > 0)) { ++ size_t i; ++ ++ ent->qcow2bitmaps = g_new0(char *, nbmp + 1); ++ ++ for (i = 0; i < nbmp; i++) { ++ virJSONValue *b = virJSONValueArrayGet(bmp, i); ++ ++ ent->qcow2bitmaps[i] = g_strdup(virJSONValueObjectGetString(b, "name")); ++ } ++ } + } + } + +diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c +index 51d9268cdd..18ec90edf5 100644 +--- a/tests/qemublocktest.c ++++ b/tests/qemublocktest.c +@@ -600,6 +600,17 @@ testQemuDetectBitmapsWorker(void *payload, + bitmap->granularity, bitmap->dirtybytes); + } + ++ if (data->qcow2bitmaps) { ++ char **b; ++ ++ virBufferAddLit(buf, "qcow2 bitmaps:"); ++ ++ for (b = data->qcow2bitmaps; *b; b++) ++ virBufferAsprintf(buf, " %s", *b); ++ ++ virBufferAddLit(buf, "\n"); ++ } ++ + if (data->snapshots) { + g_autofree virHashKeyValuePair *snaps = virHashGetItems(data->snapshots, NULL, true); + virHashKeyValuePair *n; +diff --git a/tests/qemublocktestdata/bitmap/snapshots.out b/tests/qemublocktestdata/bitmap/snapshots.out +index 29c586be7e..dedd77465c 100644 +--- a/tests/qemublocktestdata/bitmap/snapshots.out ++++ b/tests/qemublocktestdata/bitmap/snapshots.out +@@ -4,21 +4,26 @@ libvirt-1-format: + b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++ qcow2 bitmaps: current c b a d + libvirt-1-storage: + libvirt-2-format: + c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++ qcow2 bitmaps: d a b c + libvirt-2-storage: + libvirt-3-format: + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++ qcow2 bitmaps: c b a + libvirt-3-storage: + libvirt-4-format: + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++ qcow2 bitmaps: a + libvirt-4-storage: + libvirt-5-format: + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++ qcow2 bitmaps: a + libvirt-5-storage: +diff --git a/tests/qemublocktestdata/bitmap/synthetic.out b/tests/qemublocktestdata/bitmap/synthetic.out +index 2f4ae2b217..0a47a90107 100644 +--- a/tests/qemublocktestdata/bitmap/synthetic.out ++++ b/tests/qemublocktestdata/bitmap/synthetic.out +@@ -6,17 +6,21 @@ libvirt-1-format: + top-inactive: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + top-transient: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0 + top-transient-inactive: record:0 busy:0 persist:0 inconsist:0 gran:65536 dirty:0 ++ qcow2 bitmaps: current + libvirt-1-storage: + libvirt-2-format: + d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++ qcow2 bitmaps: d + libvirt-2-storage: + libvirt-3-format: + b: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0 + c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++ qcow2 bitmaps: c b + libvirt-3-storage: + libvirt-4-format: + libvirt-4-storage: + libvirt-5-format: + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++ qcow2 bitmaps: a + libvirt-5-storage: +-- +2.52.0 diff --git a/libvirt-qemu-monitor-Extract-block-latency-histogram-stats-into-qemuBlockStats.patch b/libvirt-qemu-monitor-Extract-block-latency-histogram-stats-into-qemuBlockStats.patch new file mode 100644 index 0000000..d64ef06 --- /dev/null +++ b/libvirt-qemu-monitor-Extract-block-latency-histogram-stats-into-qemuBlockStats.patch @@ -0,0 +1,168 @@ +From e02f5e7ca63bdaaec62c2fffa681b9354bee0792 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Thu, 29 Jan 2026 14:08:18 +0100 +Subject: [PATCH] qemu: monitor: Extract block latency histogram stats into + 'qemuBlockStats' + +Extract the 'rd_latency_histogram', 'wr_latency_histogram', +'zone_append_latency_histogram', and 'flush_latency_histogram' stats +objects into our internal data. + +Rather than storing 'boundaries' between bins we store them as start +points. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 1c77d396ea9704eae09d7fea160cfd1a897beaf3) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + src/qemu/qemu_monitor.c | 20 +++++++++++++ + src/qemu/qemu_monitor.h | 18 ++++++++++++ + src/qemu/qemu_monitor_json.c | 55 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 93 insertions(+) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 504500c864..cdd08004fb 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -1986,6 +1986,26 @@ qemuBlockStatsFinalize(GObject *object) + g_free(stats->limits); + g_free(stats->timed_stats); + ++ if (stats->histogram_read) { ++ g_free(stats->histogram_read->bins); ++ g_free(stats->histogram_read); ++ } ++ ++ if (stats->histogram_write) { ++ g_free(stats->histogram_write->bins); ++ g_free(stats->histogram_write); ++ } ++ ++ if (stats->histogram_zone) { ++ g_free(stats->histogram_zone->bins); ++ g_free(stats->histogram_zone); ++ } ++ ++ if (stats->histogram_flush) { ++ g_free(stats->histogram_flush->bins); ++ g_free(stats->histogram_flush); ++ } ++ + G_OBJECT_CLASS(qemu_block_stats_parent_class)->finalize(object); + } + +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index 041aa7bc12..238f7be875 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -806,6 +806,18 @@ struct qemuBlockStatsLimits { + }; + + ++struct qemuBlockStatsLatencyHistogramBin { ++ unsigned long long start; ++ unsigned long long value; ++}; ++ ++ ++struct qemuBlockStatsLatencyHistogram { ++ struct qemuBlockStatsLatencyHistogramBin *bins; ++ size_t nbins; ++}; ++ ++ + struct qemuBlockStatsTimed { + unsigned long long interval_length; + +@@ -858,6 +870,12 @@ struct _qemuBlockStats { + /* block accounting/timed stats from qemu - one entry per interval configured */ + size_t n_timed_stats; + struct qemuBlockStatsTimed *timed_stats; ++ ++ /* latency histograms */ ++ struct qemuBlockStatsLatencyHistogram *histogram_read; ++ struct qemuBlockStatsLatencyHistogram *histogram_write; ++ struct qemuBlockStatsLatencyHistogram *histogram_zone; ++ struct qemuBlockStatsLatencyHistogram *histogram_flush; + }; + G_DECLARE_FINAL_TYPE(qemuBlockStats, qemu_block_stats, QEMU, BLOCK_STATS, GObject); + +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 401a28ff9a..edeea22ee0 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -2425,6 +2425,52 @@ qemuMonitorJSONBlockStatsCollectDataTimed(virJSONValue *timed_stats, + } + + ++static void ++qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(virJSONValue *stats, ++ const char *histogram_field, ++ struct qemuBlockStatsLatencyHistogram **histogram_data) ++{ ++ virJSONValue *hist; ++ virJSONValue *hist_bins; ++ virJSONValue *hist_bounds; ++ g_autofree struct qemuBlockStatsLatencyHistogramBin *bins = NULL; ++ size_t nbins = 0; ++ size_t i; ++ ++ if (!(hist = virJSONValueObjectGetObject(stats, histogram_field))) ++ return; ++ ++ if (!(hist_bins = virJSONValueObjectGetArray(hist, "bins")) || ++ !(hist_bounds = virJSONValueObjectGetArray(hist, "boundaries")) || ++ virJSONValueArraySize(hist_bins) != (virJSONValueArraySize(hist_bounds) + 1)) { ++ VIR_DEBUG("malformed latency histogram container"); ++ return; ++ } ++ ++ nbins = virJSONValueArraySize(hist_bins); ++ bins = g_new0(struct qemuBlockStatsLatencyHistogramBin, nbins); ++ ++ for (i = 0; i < nbins; i++) { ++ virJSONValue *bin = virJSONValueArrayGet(hist_bins, i); ++ virJSONValue *bound = NULL; ++ ++ if (i > 0) ++ bound = virJSONValueArrayGet(hist_bounds, i - 1); ++ ++ if (!bin || ++ virJSONValueGetNumberUlong(bin, &(bins[i].value)) < 0 || ++ (bound && virJSONValueGetNumberUlong(bound, &(bins[i].start)) < 0)) { ++ VIR_DEBUG("malformed latency histogram container"); ++ return; ++ } ++ } ++ ++ *histogram_data = g_new0(struct qemuBlockStatsLatencyHistogram, 1); ++ (*histogram_data)->bins = g_steal_pointer(&bins); ++ (*histogram_data)->nbins = nbins; ++} ++ ++ + static qemuBlockStats * + qemuMonitorJSONBlockStatsCollectData(virJSONValue *dev, + int *nstats) +@@ -2469,6 +2515,15 @@ qemuMonitorJSONBlockStatsCollectData(virJSONValue *dev, + bstats->wr_highest_offset_valid = true; + } + ++ qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "rd_latency_histogram", ++ &bstats->histogram_read); ++ qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "wr_latency_histogram", ++ &bstats->histogram_write); ++ qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "zone_append_latency_histogram", ++ &bstats->histogram_zone); ++ qemuMonitorJSONBlockStatsCollectDataLatencyHistogram(stats, "flush_latency_histogram", ++ &bstats->histogram_flush); ++ + if ((timed_stats = virJSONValueObjectGetArray(stats, "timed_stats")) && + virJSONValueArraySize(timed_stats) > 0) + qemuMonitorJSONBlockStatsCollectDataTimed(timed_stats, bstats); +-- +2.53.0 diff --git a/libvirt-qemu-open-VFIO-FDs-from-libvirt-backend.patch b/libvirt-qemu-open-VFIO-FDs-from-libvirt-backend.patch new file mode 100644 index 0000000..8e5c90a --- /dev/null +++ b/libvirt-qemu-open-VFIO-FDs-from-libvirt-backend.patch @@ -0,0 +1,247 @@ +From 68a23646ba165aa45d3811d626885054ae9d9299 Mon Sep 17 00:00:00 2001 +Message-ID: <68a23646ba165aa45d3811d626885054ae9d9299.1770383182.git.jdenemar@redhat.com> +From: Nathan Chen +Date: Fri, 30 Jan 2026 10:59:15 -0800 +Subject: [PATCH] qemu: open VFIO FDs from libvirt backend +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Open VFIO FDs from libvirt backend without exposing +these FDs to XML users, i.e. one per iommufd hostdev +for /dev/vfio/devices/vfioX, and pass the FD to qemu +command line. + +Suggested-by: Ján Tomko +Signed-off-by: Nathan Chen +Reviewed-by: Pavel Hrdina +(cherry picked from commit f6230804727df834da27370e835204672218ab23) + +Resolves: https://issues.redhat.com/browse/RHEL-74202 +Resolves: https://issues.redhat.com/browse/RHEL-126346 + +Signed-off-by: Pavel Hrdina +--- + src/libvirt_private.syms | 1 + + src/qemu/qemu_command.c | 21 +++++++++++ + src/qemu/qemu_process.c | 78 ++++++++++++++++++++++++++++++++++++++++ + src/util/virpci.c | 39 ++++++++++++++++++++ + src/util/virpci.h | 2 ++ + 5 files changed, 141 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 66261ed6cf..e2a7a16347 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -3162,6 +3162,7 @@ virPCIDeviceGetStubDriverName; + virPCIDeviceGetStubDriverType; + virPCIDeviceGetUnbindFromStub; + virPCIDeviceGetUsedBy; ++virPCIDeviceGetVfioPath; + virPCIDeviceGetVPD; + virPCIDeviceHasPCIExpressLink; + virPCIDeviceIsAssignable; +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 1fb31d1721..83935e82c3 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -4803,6 +4803,18 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, + NULL) < 0) + return NULL; + ++ if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO && ++ pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_YES) { ++ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev); ++ ++ if (hostdevPriv->vfioDeviceFd != -1) { ++ g_autofree char *fdstr = g_strdup_printf("%d", hostdevPriv->vfioDeviceFd); ++ if (virJSONValueObjectAdd(&props, "S:fd", fdstr, NULL) < 0) ++ return NULL; ++ hostdevPriv->vfioDeviceFd = -1; ++ } ++ } ++ + if (qemuBuildDeviceAddressProps(props, def, dev->info) < 0) + return NULL; + +@@ -5247,6 +5259,15 @@ qemuBuildHostdevCommandLine(virCommand *cmd, + if (qemuCommandAddExtDevice(cmd, hostdev->info, def, qemuCaps) < 0) + return -1; + ++ if (subsys->u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) { ++ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); ++ ++ if (hostdevPriv->vfioDeviceFd != -1) { ++ virCommandPassFD(cmd, hostdevPriv->vfioDeviceFd, ++ VIR_COMMAND_PASS_FD_CLOSE_PARENT); ++ } ++ } ++ + if (!(devprops = qemuBuildPCIHostdevDevProps(def, hostdev))) + return -1; + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 0e50cd1ccc..1ac57a6321 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -103,6 +103,7 @@ + #include "storage_source.h" + #include "backup_conf.h" + #include "storage_file_probe.h" ++#include "virpci.h" + + #include "logging/log_manager.h" + #include "logging/log_protocol.h" +@@ -7671,6 +7672,81 @@ qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm, + return 0; + } + ++/** ++ * qemuProcessOpenVfioDeviceFd: ++ * @hostdev: host device definition ++ * @vfioFd: returned file descriptor ++ * ++ * Opens the VFIO device file descriptor for a hostdev. ++ * ++ * Returns: FD on success, -1 on failure ++ */ ++static int ++qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) ++{ ++ g_autofree char *vfioPath = NULL; ++ int fd = -1; ++ ++ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || ++ hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("VFIO FD only supported for PCI hostdevs")); ++ return -1; ++ } ++ ++ if (virPCIDeviceGetVfioPath(&hostdev->source.subsys.u.pci.addr, &vfioPath) < 0) ++ return -1; ++ ++ VIR_DEBUG("Opening VFIO device %s", vfioPath); ++ ++ if ((fd = open(vfioPath, O_RDWR | O_CLOEXEC)) < 0) { ++ if (errno == ENOENT) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("VFIO device %1$s not found - ensure device is bound to vfio-pci driver"), ++ vfioPath); ++ } else { ++ virReportSystemError(errno, ++ _("cannot open VFIO device %1$s"), vfioPath); ++ } ++ return -1; ++ } ++ ++ VIR_DEBUG("Opened VFIO device FD %d for %s", fd, vfioPath); ++ return fd; ++} ++ ++/** ++ * qemuProcessOpenVfioFds: ++ * @vm: domain object ++ * ++ * Opens all necessary VFIO file descriptors for the domain. ++ * ++ * Returns: 0 on success, -1 on failure ++ */ ++static int ++qemuProcessOpenVfioFds(virDomainObj *vm) ++{ ++ size_t i; ++ ++ /* Check if we have any hostdevs that need VFIO FDs */ ++ for (i = 0; i < vm->def->nhostdevs; i++) { ++ virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; ++ qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); ++ ++ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && ++ hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && ++ hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO && ++ hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) { ++ /* Open VFIO device FD */ ++ hostdevPriv->vfioDeviceFd = qemuProcessOpenVfioDeviceFd(hostdev); ++ if (hostdevPriv->vfioDeviceFd == -1) ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ + /** + * qemuProcessPrepareHost: + * @driver: qemu driver +@@ -7726,6 +7802,8 @@ qemuProcessPrepareHost(virQEMUDriver *driver, + hostdev_flags |= VIR_HOSTDEV_COLD_BOOT; + if (qemuHostdevPrepareDomainDevices(driver, vm->def, hostdev_flags) < 0) + return -1; ++ if (qemuProcessOpenVfioFds(vm) < 0) ++ return -1; + + VIR_DEBUG("Preparing chr device backends"); + if (qemuProcessPrepareHostBackendChardev(vm) < 0) +diff --git a/src/util/virpci.c b/src/util/virpci.c +index 90617e69c6..2348a98003 100644 +--- a/src/util/virpci.c ++++ b/src/util/virpci.c +@@ -3320,3 +3320,42 @@ virPCIDeviceAddressFree(virPCIDeviceAddress *address) + { + g_free(address); + } ++ ++/** ++ * virPCIDeviceGetVfioPath: ++ * @addr: host device PCI address ++ * @vfioPath: returned VFIO device path ++ * ++ * Constructs the VFIO device path for a PCI hostdev. ++ * ++ * Returns: 0 on success, -1 on failure ++ */ ++int ++virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, ++ char **vfioPath) ++{ ++ g_autofree char *addrStr = NULL; ++ g_autofree char *sysfsPath = NULL; ++ g_autoptr(DIR) dir = NULL; ++ struct dirent *entry = NULL; ++ ++ *vfioPath = NULL; ++ addrStr = virPCIDeviceAddressAsString(addr); ++ ++ /* Look in device's vfio-dev subdirectory */ ++ sysfsPath = g_strdup_printf("/sys/bus/pci/devices/%s/vfio-dev/", addrStr); ++ ++ if (virDirOpen(&dir, sysfsPath) == 1) { ++ while (virDirRead(dir, &entry, sysfsPath) > 0) { ++ if (STRPREFIX(entry->d_name, "vfio")) { ++ *vfioPath = g_strdup_printf("/dev/vfio/devices/%s", entry->d_name); ++ return 0; ++ } ++ } ++ } ++ ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("cannot find VFIO device for PCI device %1$s"), ++ addrStr); ++ return -1; ++} +diff --git a/src/util/virpci.h b/src/util/virpci.h +index fc538566e1..24ede10755 100644 +--- a/src/util/virpci.h ++++ b/src/util/virpci.h +@@ -296,6 +296,8 @@ void virPCIEDeviceInfoFree(virPCIEDeviceInfo *dev); + + void virPCIDeviceAddressFree(virPCIDeviceAddress *address); + ++int virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, char **vfioPath); ++ + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDevice, virPCIDeviceFree); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDeviceAddress, virPCIDeviceAddressFree); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIEDeviceInfo, virPCIEDeviceInfoFree); +-- +2.52.0 diff --git a/libvirt-qemu-open-iommufd-FD-from-libvirt-backend.patch b/libvirt-qemu-open-iommufd-FD-from-libvirt-backend.patch new file mode 100644 index 0000000..d7275f0 --- /dev/null +++ b/libvirt-qemu-open-iommufd-FD-from-libvirt-backend.patch @@ -0,0 +1,175 @@ +From a444918da5bd01fc11793c82ad33308892777c3a Mon Sep 17 00:00:00 2001 +Message-ID: +From: Nathan Chen +Date: Fri, 30 Jan 2026 10:59:16 -0800 +Subject: [PATCH] qemu: open iommufd FD from libvirt backend +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Open iommufd FD from libvirt backend without exposing +these FDs to XML users, i.e. one per domain for +/dev/iommu, and pass the FD to qemu command line. Set +per-process memory accounting for iommufd instead of +the default per-user memory accounting. + +Suggested-by: Ján Tomko +Signed-off-by: Nathan Chen +Reviewed-by: Pavel Hrdina +(cherry picked from commit 2f0999a161910e3992458902ce90d37f8b8f2642) + +Resolves: https://issues.redhat.com/browse/RHEL-74202 +Resolves: https://issues.redhat.com/browse/RHEL-126346 + +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_command.c | 13 +++++++++++-- + src/qemu/qemu_domain.c | 1 + + src/qemu/qemu_domain.h | 2 ++ + src/qemu/qemu_process.c | 43 +++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 57 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 83935e82c3..f355352018 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -5342,9 +5342,13 @@ qemuBuildHostdevCommandLine(virCommand *cmd, + + static int + qemuBuildIOMMUFDCommandLine(virCommand *cmd, +- const virDomainDef *def) ++ const virDomainDef *def, ++ virDomainObj *vm) + { + size_t i; ++ qemuDomainObjPrivate *priv = vm->privateData; ++ g_autofree char *fdstr = g_strdup_printf("%d", priv->iommufd); ++ + + for (i = 0; i < def->nhostdevs; i++) { + virDomainHostdevDef *hostdev = def->hostdevs[i]; +@@ -5363,8 +5367,13 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd, + if (subsys->u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) + continue; + ++ virCommandPassFD(cmd, priv->iommufd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); ++ ++ priv->iommufd = -1; ++ + if (qemuMonitorCreateObjectProps(&props, "iommufd", + "iommufd0", ++ "S:fd", fdstr, + NULL) < 0) + return -1; + +@@ -10990,7 +10999,7 @@ qemuBuildCommandLine(virDomainObj *vm, + if (qemuBuildRedirdevCommandLine(cmd, def, qemuCaps) < 0) + return NULL; + +- if (qemuBuildIOMMUFDCommandLine(cmd, def) < 0) ++ if (qemuBuildIOMMUFDCommandLine(cmd, def, vm) < 0) + return NULL; + + if (qemuBuildHostdevCommandLine(cmd, def, qemuCaps) < 0) +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 3366214677..8e1ebe7799 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -2042,6 +2042,7 @@ qemuDomainObjPrivateAlloc(void *opaque) + priv->blockjobs = virHashNew(virObjectUnref); + priv->fds = virHashNew(g_object_unref); + ++ priv->iommufd = -1; + priv->pidMonitored = -1; + + /* agent commands block by default, user can choose different behavior */ +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 88c8416aa4..3361e97315 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -264,6 +264,8 @@ struct _qemuDomainObjPrivate { + /* named file descriptor groups associated with the VM */ + GHashTable *fds; + ++ int iommufd; ++ + char *memoryBackingDir; + }; + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 1ac57a6321..d8f0c78fd1 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -104,6 +104,7 @@ + #include "backup_conf.h" + #include "storage_file_probe.h" + #include "virpci.h" ++#include "viriommufd.h" + + #include "logging/log_manager.h" + #include "logging/log_protocol.h" +@@ -7672,6 +7673,42 @@ qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm, + return 0; + } + ++/** ++ * qemuProcessOpenIommuFd: ++ * @vm: domain object ++ * @iommuFd: returned file descriptor ++ * ++ * Opens /dev/iommu file descriptor for the VM. ++ * ++ * Returns: FD on success, -1 on failure ++ */ ++static int ++qemuProcessOpenIommuFd(virDomainObj *vm) ++{ ++ int fd = -1; ++ ++ VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name); ++ ++ if ((fd = open(VIR_IOMMU_DEV_PATH, O_RDWR | O_CLOEXEC)) < 0) { ++ if (errno == ENOENT) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("IOMMU FD support requires /dev/iommu device")); ++ } else { ++ virReportSystemError(errno, "%s", ++ _("cannot open /dev/iommu")); ++ } ++ return -1; ++ } ++ ++ if (virIOMMUFDSetRLimitMode(fd, true) < 0) { ++ VIR_FORCE_CLOSE(fd); ++ return -1; ++ } ++ ++ VIR_DEBUG("Opened IOMMU FD %d for domain %s", fd, vm->def->name); ++ return fd; ++} ++ + /** + * qemuProcessOpenVfioDeviceFd: + * @hostdev: host device definition +@@ -7726,6 +7763,7 @@ qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) + static int + qemuProcessOpenVfioFds(virDomainObj *vm) + { ++ qemuDomainObjPrivate *priv = vm->privateData; + size_t i; + + /* Check if we have any hostdevs that need VFIO FDs */ +@@ -7741,6 +7779,11 @@ qemuProcessOpenVfioFds(virDomainObj *vm) + hostdevPriv->vfioDeviceFd = qemuProcessOpenVfioDeviceFd(hostdev); + if (hostdevPriv->vfioDeviceFd == -1) + return -1; ++ ++ /* Open IOMMU FD */ ++ priv->iommufd = qemuProcessOpenIommuFd(vm); ++ if (priv->iommufd == -1) ++ return -1; + } + } + +-- +2.52.0 diff --git a/libvirt-qemu-process-Rename-qemuProcessSetupDiskThrottling-to-qemuProcessSetupDisks.patch b/libvirt-qemu-process-Rename-qemuProcessSetupDiskThrottling-to-qemuProcessSetupDisks.patch new file mode 100644 index 0000000..ba30c18 --- /dev/null +++ b/libvirt-qemu-process-Rename-qemuProcessSetupDiskThrottling-to-qemuProcessSetupDisks.patch @@ -0,0 +1,62 @@ +From 0359b5fcf870f955bbdca998e5a02261e27c40b7 Mon Sep 17 00:00:00 2001 +Message-ID: <0359b5fcf870f955bbdca998e5a02261e27c40b7.1771336681.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Thu, 29 Jan 2026 11:21:38 +0100 +Subject: [PATCH] qemu: process: Rename 'qemuProcessSetupDiskThrottling' to + 'qemuProcessSetupDisks' + +Rename the runtime disk option setup function to be universal. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 42a39d703d98e4e48f0f9c8779884b6ac107de26) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + src/qemu/qemu_process.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index c99bb36c93..aadfaa92b0 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7964,21 +7964,19 @@ qemuProcessSetupDiskPropsRuntime(qemuMonitor *mon, + + + /** +- * qemuProcessSetupDiskThrottling: ++ * qemuProcessSetupDisks: + * +- * Sets up disk trottling for -blockdev via block_set_io_throttle monitor +- * command. This hack should be replaced by proper use of the 'throttle' +- * blockdev driver in qemu once it will support changing of the throttle group. +- * Same hack is done in qemuDomainAttachDiskGeneric. ++ * Sets up disk settings available only at runtime: ++ * - trottling for -blockdev via block_set_io_throttle QMP command + */ + static int +-qemuProcessSetupDiskThrottling(virDomainObj *vm, +- virDomainAsyncJob asyncJob) ++qemuProcessSetupDisks(virDomainObj *vm, ++ virDomainAsyncJob asyncJob) + { + size_t i; + int ret = -1; + +- VIR_DEBUG("Setting up disk throttling for -blockdev via block_set_io_throttle"); ++ VIR_DEBUG("Setting up disk config via runtime commands"); + + if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) + return -1; +@@ -8575,7 +8573,7 @@ qemuProcessLaunch(virConnectPtr conn, + if (qemuProcessSetupBalloon(vm, asyncJob) < 0) + goto cleanup; + +- if (qemuProcessSetupDiskThrottling(vm, asyncJob) < 0) ++ if (qemuProcessSetupDisks(vm, asyncJob) < 0) + goto cleanup; + + /* Since CPUs were not started yet, the balloon could not return the memory +-- +2.53.0 diff --git a/libvirt-qemu-tpm-Account-for-possible-migration-without-actually-sharing-storage.patch b/libvirt-qemu-tpm-Account-for-possible-migration-without-actually-sharing-storage.patch new file mode 100644 index 0000000..d51a8c1 --- /dev/null +++ b/libvirt-qemu-tpm-Account-for-possible-migration-without-actually-sharing-storage.patch @@ -0,0 +1,119 @@ +From 8e9dc8aed52c98c3683949dfe1127061bd9df47a Mon Sep 17 00:00:00 2001 +Message-ID: <8e9dc8aed52c98c3683949dfe1127061bd9df47a.1766070439.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Mon, 1 Dec 2025 11:35:32 +0100 +Subject: [PATCH] qemu: tpm: Account for possible migration without actually + sharing storage + +The current logic in 'qemuTPMEmulatorBuildCommand' skips all setup if +the *location* of the data is on what we'd consider shared storage. + +This means that if the location is not actually shared (e.g. it's shared +betweeh some other hosts than the two doing the migration) and the path +wasn't ever used (e.g. by migrating out) from the host where we're +migrating into the complete setup of the location would be skipped even +when it doesn't exist. + +Fix the logic by skipping only some of the setup steps so that +'qemuTPMEmulatorCreateStorage' can still create the storage if it +doesn't exist. + +The rest of the code then needs to take the 'created' flag returned from +'qemuTPMEmulatorCreateStorage' into account. + +Fixes: 68103e9daf633b789428fedef56f816c92f6ee75 +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit d56d0560946770d4364a4918cc289e6a7fe5d15c) +https://issues.redhat.com/browse/RHEL-132534 +--- + src/qemu/qemu_tpm.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c +index 4c9445d72c..660410bcba 100644 +--- a/src/qemu/qemu_tpm.c ++++ b/src/qemu/qemu_tpm.c +@@ -158,6 +158,7 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir, + /** + * qemuTPMEmulatorCreateStorage: + * @tpm: TPM definition for an emulator type ++ * @sharedStorageMigration: VM is being migrated with possibly shared storage + * @created: a pointer to a bool that will be set to true if the + * storage was created because it did not exist yet + * @swtpm_user: The uid that needs to be able to access the directory +@@ -169,6 +170,7 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir, + */ + static int + qemuTPMEmulatorCreateStorage(virDomainTPMDef *tpm, ++ bool sharedStorageMigration, + bool *created, + uid_t swtpm_user, + gid_t swtpm_group) +@@ -187,8 +189,17 @@ qemuTPMEmulatorCreateStorage(virDomainTPMDef *tpm, + *created = false; + + if (!virFileExists(source_path) || +- virDirIsEmpty(source_path, true) > 0) ++ virDirIsEmpty(source_path, true) > 0) { + *created = true; ++ } else { ++ /* If the location exists and is shared, we don't need to create it ++ * during migration */ ++ if (sharedStorageMigration) { ++ VIR_DEBUG("Skipping TPM storage creation. Path '%s' already exists and is on shared storage.", ++ source_path); ++ return 0; ++ } ++ } + + if (virDirCreate(source_path, 0700, swtpm_user, swtpm_group, + VIR_DIR_CREATE_ALLOW_EXIST) < 0) { +@@ -809,16 +820,13 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, + run_setup = true; + } + +- /* Do not create storage and run swtpm_setup on incoming migration over +- * shared storage +- */ + on_shared_storage = virFileIsSharedFS(tpm->data.emulator.source_path, + cfg->sharedFilesystems) == 1; +- if (incomingMigration && on_shared_storage) +- create_storage = false; + + if (create_storage) { +- if (qemuTPMEmulatorCreateStorage(tpm, &created, ++ if (qemuTPMEmulatorCreateStorage(tpm, ++ incomingMigration && on_shared_storage, ++ &created, + cfg->swtpm_user, cfg->swtpm_group) < 0) + return NULL; + run_setup = created; +@@ -885,6 +893,9 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, + /* If swtpm supports it and the TPM state is stored on shared storage, + * start swtpm with --migration release-lock-outgoing so it can migrate + * across shared storage if needed. ++ * ++ * Note that if 'created' is true, the location didn't exist so the storage ++ * is not actually shared. + */ + QEMU_DOMAIN_TPM_PRIVATE(tpm)->swtpm.can_migrate_shared_storage = false; + if (on_shared_storage && +@@ -892,13 +903,13 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, + + virCommandAddArg(cmd, "--migration"); + virCommandAddArgFormat(cmd, "release-lock-outgoing%s", +- incomingMigration ? ",incoming": ""); ++ incomingMigration && !created ? ",incoming": ""); + QEMU_DOMAIN_TPM_PRIVATE(tpm)->swtpm.can_migrate_shared_storage = true; + } else { + /* Report an error if there's an incoming migration across shared + * storage and swtpm does not support the --migration option. + */ +- if (incomingMigration && on_shared_storage) { ++ if (incomingMigration && on_shared_storage && !created) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, + _("%1$s (on destination side) does not support the --migration option needed for migration with shared storage"), + swtpm); +-- +2.52.0 diff --git a/libvirt-qemuDomainSetBlockIoTuneField-Move-setting-of-group_name-out-of-the-loop.patch b/libvirt-qemuDomainSetBlockIoTuneField-Move-setting-of-group_name-out-of-the-loop.patch new file mode 100644 index 0000000..a87a353 --- /dev/null +++ b/libvirt-qemuDomainSetBlockIoTuneField-Move-setting-of-group_name-out-of-the-loop.patch @@ -0,0 +1,68 @@ +From 2f60aff267af628839c90fe36cacbc9d5057509a Mon Sep 17 00:00:00 2001 +Message-ID: <2f60aff267af628839c90fe36cacbc9d5057509a.1769699749.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Fri, 16 Jan 2026 16:38:38 +0100 +Subject: [PATCH] qemuDomainSetBlockIoTuneField: Move setting of 'group_name' + out of the loop + +The refactor will simplify further change which will introduce another +source for the group name. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit fa064375668df0e67b4d68fdfc4a386862026f3f) + +https://issues.redhat.com/browse/RHEL-141820 [rhel-10.2] +https://issues.redhat.com/browse/RHEL-144010 [rhel-9.8] +--- + src/qemu/qemu_driver.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 194017a29a..ecfb65c535 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -15173,6 +15173,7 @@ qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info, + int *eventNparams, + int *eventMaxparams) + { ++ const char *param_group_name = NULL; + size_t i; + + #define SET_IOTUNE_FIELD(FIELD, BOOL, CONST) \ +@@ -15218,15 +15219,8 @@ qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info, + WRITE_IOPS_SEC_MAX); + SET_IOTUNE_FIELD(size_iops_sec, SIZE_IOPS, SIZE_IOPS_SEC); + +- /* NB: Cannot use macro since this is a value.s not a value.ul */ + if (STREQ(param->field, VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME)) { +- info->group_name = g_strdup(param->value.s); +- *set_fields |= QEMU_BLOCK_IOTUNE_SET_GROUP_NAME; +- if (virTypedParamsAddString(eventParams, eventNparams, +- eventMaxparams, +- VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME, +- param->value.s) < 0) +- return -1; ++ param_group_name = param->value.s; + continue; + } + +@@ -15244,6 +15238,16 @@ qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info, + WRITE_IOPS_SEC_MAX_LENGTH); + } + ++ if (param_group_name) { ++ info->group_name = g_strdup(param_group_name); ++ *set_fields |= QEMU_BLOCK_IOTUNE_SET_GROUP_NAME; ++ if (virTypedParamsAddString(eventParams, eventNparams, ++ eventMaxparams, ++ VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME, ++ param_group_name) < 0) ++ return -1; ++ } ++ + #undef SET_IOTUNE_FIELD + + return 0; +-- +2.52.0 diff --git a/libvirt-qemuDomainSetThrottleGroup-Always-honour-thottle-group-name-passed-as-argument.patch b/libvirt-qemuDomainSetThrottleGroup-Always-honour-thottle-group-name-passed-as-argument.patch new file mode 100644 index 0000000..0d1b945 --- /dev/null +++ b/libvirt-qemuDomainSetThrottleGroup-Always-honour-thottle-group-name-passed-as-argument.patch @@ -0,0 +1,75 @@ +From f44d3fa49e7f1507e93c1e9525dd0db4227809cc Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Fri, 16 Jan 2026 16:39:40 +0100 +Subject: [PATCH] qemuDomainSetThrottleGroup: Always honour thottle group name + passed as argument + +Due to the code share with 'qemuDomainSetBlockIoTune' the throttle group +setting code accepts the throttle group name also via typed parameters. + +In 'qemuDomainSetThrottleGroup', this means that there are 2 ways to +pass it the throttle group name and both are handled slightly +differently. Specifically the name of the group used in the list of +groups is the name taken from the typed parameters rather than the one +passed via API. We also don't validate that they match. + +Now if the name in the typed parameters is missing we'd add empty string +to the group list which would later crash when looking up the group +name. + +To avoid this problem always use the name passed via argument. This is +achieved by passing it into 'qemuDomainSetBlockIoTuneFields' so that it +overrides whatever is in the typed parameters. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 0cd13906dcf15ea5709a7b253466816a1b875640) + +https://issues.redhat.com/browse/RHEL-141820 [rhel-10.2] +https://issues.redhat.com/browse/RHEL-144010 [rhel-9.8] +--- + src/qemu/qemu_driver.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index ecfb65c535..a6d5dd6e05 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -15168,6 +15168,7 @@ static int + qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info, + virTypedParameterPtr params, + int nparams, ++ const char *group_name, + qemuBlockIoTuneSetFlags *set_fields, + virTypedParameterPtr *eventParams, + int *eventNparams, +@@ -15238,6 +15239,10 @@ qemuDomainSetBlockIoTuneFields(virDomainBlockIoTuneInfo *info, + WRITE_IOPS_SEC_MAX_LENGTH); + } + ++ /* The name of the throttle group passed via API always takes precedence */ ++ if (group_name) ++ param_group_name = group_name; ++ + if (param_group_name) { + info->group_name = g_strdup(param_group_name); + *set_fields |= QEMU_BLOCK_IOTUNE_SET_GROUP_NAME; +@@ -15385,6 +15390,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, + if (qemuDomainSetBlockIoTuneFields(&info, + params, + nparams, ++ NULL, + &set_fields, + &eventParams, + &eventNparams, +@@ -20379,6 +20385,7 @@ qemuDomainSetThrottleGroup(virDomainPtr dom, + if (qemuDomainSetBlockIoTuneFields(&info, + params, + nparams, ++ groupname, + &set_fields, + &eventParams, + &eventNparams, +-- +2.52.0 diff --git a/libvirt-qemuDomainSetThrottleGroup-Don-t-put-group-name-into-the-tunable-event-twice.patch b/libvirt-qemuDomainSetThrottleGroup-Don-t-put-group-name-into-the-tunable-event-twice.patch new file mode 100644 index 0000000..0f0a739 --- /dev/null +++ b/libvirt-qemuDomainSetThrottleGroup-Don-t-put-group-name-into-the-tunable-event-twice.patch @@ -0,0 +1,43 @@ +From e48225074a9179e73b8ce9a573a513e619ae0a65 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Fri, 16 Jan 2026 16:39:49 +0100 +Subject: [PATCH] qemuDomainSetThrottleGroup: Don't put group name into the + 'tunable' event twice + +'qemuDomainSetBlockIoTuneFields' already populates the contents of the +VIR_DOMAIN_EVENT_ID_TUNABLE params with the group name so there's no +need to do it explicitly. We'd report the group name twice: + + event 'tunable' for domain 'cd': + blkdeviotune.group_name: asdf + blkdeviotune.total_bytes_sec: 1234 + blkdeviotune.group_name: asdf + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit adcc14e1538433ec1b2f4b103cdf641917e63242) + +https://issues.redhat.com/browse/RHEL-141820 [rhel-10.2] +https://issues.redhat.com/browse/RHEL-144010 [rhel-9.8] +--- + src/qemu/qemu_driver.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index a6d5dd6e05..08a547c546 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -20378,10 +20378,6 @@ qemuDomainSetThrottleGroup(virDomainPtr dom, + if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0) + goto endjob; + +- if (virTypedParamsAddString(&eventParams, &eventNparams, &eventMaxparams, +- VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME, groupname) < 0) +- goto endjob; +- + if (qemuDomainSetBlockIoTuneFields(&info, + params, + nparams, +-- +2.52.0 diff --git a/libvirt-qemuDomainSetThrottleGroup-Enforce-non-zero-groupname-string-length.patch b/libvirt-qemuDomainSetThrottleGroup-Enforce-non-zero-groupname-string-length.patch new file mode 100644 index 0000000..62c27b6 --- /dev/null +++ b/libvirt-qemuDomainSetThrottleGroup-Enforce-non-zero-groupname-string-length.patch @@ -0,0 +1,38 @@ +From fee37458a1f93dc30a209ceeda1ec31847884fcf Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Fri, 16 Jan 2026 16:36:50 +0100 +Subject: [PATCH] qemuDomainSetThrottleGroup: Enforce non-zero 'groupname' + string length + +Having a name of 0 characters makes no sense. Reject it. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit abcdc9511b1c78df7dcdee9f01c6d55651d3a424) + +https://issues.redhat.com/browse/RHEL-141820 [rhel-10.2] +https://issues.redhat.com/browse/RHEL-144010 [rhel-9.8] +--- + src/qemu/qemu_driver.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index f2e024dae3..194017a29a 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -20345,6 +20345,12 @@ qemuDomainSetThrottleGroup(virDomainPtr dom, + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + ++ if (strlen(groupname) == 0) { ++ virReportError(VIR_ERR_INVALID_ARG, "%s", ++ _("'groupname' parameter string must have non-zero length")); ++ return -1; ++ } ++ + if (qemuDomainValidateBlockIoTune(params, nparams) < 0) + return -1; + +-- +2.52.0 diff --git a/libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Always-consider-offered-bitmaps.patch b/libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Always-consider-offered-bitmaps.patch new file mode 100644 index 0000000..36b02c6 --- /dev/null +++ b/libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Always-consider-offered-bitmaps.patch @@ -0,0 +1,98 @@ +From bbd0fde5f840726928cdcd06691da13f1093c02e Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Tue, 27 Jan 2026 17:28:48 +0100 +Subject: [PATCH] qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Always consider + offered bitmaps +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Consider bitmaps for incoming migration regardless of non-shared storage +flag. + +When bitmaps are offered from the source, consult the local image if the +bitmap is present and if not accept migration. Migration of bitmaps +which exist in the qcow2 metadata is skipped because qemu rejects such +setup (although handles it correctly in case of shared storage setup; +see below). + +This allows bitmap propagation for cases when the qcow2 image is not +actually shared between destinations but the data is (using the +data_file feature). + +At the same time this preserves existing bitmap handling semantics for +other cases. Specifically qemu, in case of shared storage properly +propagates the bitmap which was already recorded in the qcow2 metadata +on disk even if libvirt doesn't instruct migration, yet tolerates +migration instruction if the file is not yet recorded in the on-disk +metadata. In both cases the contents are preserved correctly. + +When storage is not shared (which includes even cases when we migrate +it via NBD) it's expected that the bitmaps don't exist on the +destination and thus all will be picked for migration. We can also +infer that this wasn't ever a problem by the fact that the code skipping +migration of existing bitmaps was broken until recently, and qemu +would refuse such config. + +I've tested all the above scenarios including verifying that the +resulting bitmaps capture dirtied regions before and after migration. +For testing this the following command is useful: + + virsh qemu-monitor-command --domain DOMNAME --hmp 'qemu-io -d /machine/peripheral/virtio-disk0/virtio-backend "write -P 0xcc 4M 1M"' + +Which simulates a write from the guest side without the need to interact +with the guest OS. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit bf34b90bb4e39b3a2fd22a5531f5ea5a95681015) + +https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2] +https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8] +--- + src/qemu/qemu_migration.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 755b9a5e1a..2a4df1191d 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -3183,7 +3183,6 @@ qemuMigrationDstPrepare(virQEMUDriver *driver, + * @vm: domain object + * @mig: migration cookie + * @migParams: migration parameters +- * @flags: migration flags + * + * Checks whether block dirty bitmaps offered by the migration source are + * to be migrated (e.g. they don't exist, the destination is compatible etc) +@@ -3194,16 +3193,13 @@ qemuMigrationDstPrepare(virQEMUDriver *driver, + static int + qemuMigrationDstPrepareAnyBlockDirtyBitmaps(virDomainObj *vm, + qemuMigrationCookie *mig, +- qemuMigrationParams *migParams, +- unsigned int flags) ++ qemuMigrationParams *migParams) + { + g_autoptr(virJSONValue) mapping = NULL; + g_autoptr(GHashTable) blockNamedNodeData = NULL; + GSList *nextdisk; + +- if (!mig->nbd || +- !mig->blockDirtyBitmaps || +- !(flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC))) ++ if (!mig->blockDirtyBitmaps) + return 0; + + if (qemuMigrationCookieBlockDirtyBitmapsMatchDisks(vm->def, mig->blockDirtyBitmaps) < 0) +@@ -3350,7 +3346,7 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver, + goto error; + } + +- if (qemuMigrationDstPrepareAnyBlockDirtyBitmaps(vm, mig, migParams, flags) < 0) ++ if (qemuMigrationDstPrepareAnyBlockDirtyBitmaps(vm, mig, migParams) < 0) + goto error; + + if (qemuMigrationParamsCheck(vm, VIR_ASYNC_JOB_MIGRATION_IN, migParams, +-- +2.52.0 diff --git a/libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Fix-check-for-existing-bitmaps.patch b/libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Fix-check-for-existing-bitmaps.patch new file mode 100644 index 0000000..ccaef87 --- /dev/null +++ b/libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Fix-check-for-existing-bitmaps.patch @@ -0,0 +1,68 @@ +From b99fb51812da73df754151c59c259d15fa654168 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Tue, 27 Jan 2026 19:22:08 +0100 +Subject: [PATCH] qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Fix check for + existing bitmaps +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On incoming migration qemu doesn't load bitmaps into memory (which makes +them available under the 'dirty-bitmaps' field which we parse as the +'bitmaps' array in 'qemuBlockNamedNodeData') until after actually +resuming CPUs, thus the check for existing bitmaps never actually +worked. + +We need to check the 'qcow2bitmaps' field instead which is populated +from the qcow2 headers prior to activating the image. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 0c75fc1747f039bf878ceab69cf12482ebb14095) + +https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2] +https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8] +--- + src/qemu/qemu_migration.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 9059f9aa3a..723e131c98 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -3227,6 +3227,8 @@ qemuMigrationDstPrepareAnyBlockDirtyBitmaps(virDomainObj *vm, + qemuBlockNamedNodeData *nodedata; + GSList *nextbitmap; + ++ VIR_DEBUG("offer migrate bitmaps for '%s'", disk->target); ++ + if (!(nodedata = virHashLookup(blockNamedNodeData, disk->nodename))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to find data for block node '%1$s'"), +@@ -3243,18 +3245,14 @@ qemuMigrationDstPrepareAnyBlockDirtyBitmaps(virDomainObj *vm, + + for (nextbitmap = disk->bitmaps; nextbitmap; nextbitmap = nextbitmap->next) { + qemuMigrationBlockDirtyBitmapsDiskBitmap *bitmap = nextbitmap->data; +- size_t k; + + /* don't migrate into existing bitmaps */ +- for (k = 0; k < nodedata->nbitmaps; k++) { +- if (STREQ(bitmap->bitmapname, nodedata->bitmaps[k]->name)) { +- bitmap->skip = true; +- break; +- } +- } ++ if (nodedata->qcow2bitmaps) ++ bitmap->skip = g_strv_contains((const char **) nodedata->qcow2bitmaps, bitmap->bitmapname); ++ ++ VIR_DEBUG("offer migrate bitmap '%s' disk '%s' -> skip: '%d'", ++ bitmap->bitmapname, disk->target, bitmap->skip); + +- if (bitmap->skip) +- continue; + } + } + +-- +2.52.0 diff --git a/libvirt-qemuSecurityMoveImageMetadata-Move-seclabels-only-to-virStorageSource-of-same-type.patch b/libvirt-qemuSecurityMoveImageMetadata-Move-seclabels-only-to-virStorageSource-of-same-type.patch new file mode 100644 index 0000000..6be8545 --- /dev/null +++ b/libvirt-qemuSecurityMoveImageMetadata-Move-seclabels-only-to-virStorageSource-of-same-type.patch @@ -0,0 +1,56 @@ +From 5a7cc07af8355ae117d04d357bd8b694fc2af091 Mon Sep 17 00:00:00 2001 +Message-ID: <5a7cc07af8355ae117d04d357bd8b694fc2af091.1769173967.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Mon, 12 Jan 2026 10:54:38 +0100 +Subject: [PATCH] qemuSecurityMoveImageMetadata: Move seclabels only to + virStorageSource of same type + +The concept of moving a seclabel is used e.g. when a new image is +introduced to the backing chain (or one of the existing ones becomes +active during block commit). What it does is that it moves the metedata +remembering the original seclabel to the new image. + +That idea works reasonably well if both the original and new image are +of same type e.g. a file, where they have comparable seclabel. + +It breaks down though when you e.g. create a snapshot stored in a 'file' +on top of a disk originally backed by a 'block' storage source, since +the seclabels differ quite siginificantly. + +This patch restricts the seclabel move in qemuSecurityMoveImageMetadata +to happen only if the storage sources are of same type to avoid the +issue. This means that the seclabels will not be remebered and will be +restored to the default but it's better than to transfer wrong labels. + +Resolves: https://issues.redhat.com/browse/RHEL-114412 + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 37d51c0d27692a245d7a5eeeef57748e7574de4b) +--- + src/qemu/qemu_security.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c +index 6bb0f9170d..84cb981a96 100644 +--- a/src/qemu/qemu_security.c ++++ b/src/qemu/qemu_security.c +@@ -201,6 +201,16 @@ qemuSecurityMoveImageMetadata(virQEMUDriver *driver, + if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) + pid = vm->pid; + ++ /* Moving seclabel metadata makes sense only when 'src' and 'dst' are of ++ * the same type. Otherwise 'dst' could end up with a seclabel that doesn't ++ * make sense for it (e.g. a seclabel originating from a block device /dev ++ * node moved to a file), once the seclabels are restored for it */ ++ if (src && dst && src->type != dst->type) { ++ VIR_DEBUG("dropping security label metadata instead of moving it from '%s' to '%s' due to type mismatch", ++ NULLSTR(src->path), NULLSTR(dst->path)); ++ dst = NULL; ++ } ++ + return virSecurityManagerMoveImageMetadata(driver->securityManager, + cfg->sharedFilesystems, + pid, src, dst); +-- +2.52.0 diff --git a/libvirt-qemuSnapshotDiskHasBackingDisk-Avoid-call-of-virStorageSourceIsSameLocation-with-NULL-argument.patch b/libvirt-qemuSnapshotDiskHasBackingDisk-Avoid-call-of-virStorageSourceIsSameLocation-with-NULL-argument.patch new file mode 100644 index 0000000..e551ccf --- /dev/null +++ b/libvirt-qemuSnapshotDiskHasBackingDisk-Avoid-call-of-virStorageSourceIsSameLocation-with-NULL-argument.patch @@ -0,0 +1,48 @@ +From 744a5361793546bed7976acebed669b1928e8c9d Mon Sep 17 00:00:00 2001 +Message-ID: <744a5361793546bed7976acebed669b1928e8c9d.1769699749.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Fri, 23 Jan 2026 08:42:50 +0100 +Subject: [PATCH] qemuSnapshotDiskHasBackingDisk: Avoid call of + virStorageSourceIsSameLocation with NULL argument + +When the 'backingStore' pointer is not populated the function calls +'virStorageSourceGetMetadata' to try to populate it but if the on-disk +metadata doesn't have a backing image (e.g. if it's the 'base' image of +the chain) the 'backingStore' or the metadata fetcher fails the pointer +will still be NULL. + +The function then calls 'virStorageSourceIsSameLocation' but the +internal functions for dealing with storage sources don't handle NULL +gracefully. + +Since the code calling 'qemu-img' based on the data detected here +doesn't actually raise errors if the operations fail there's no point +in raising errors here either. + +Closes: https://gitlab.com/libvirt/libvirt/-/issues/844 +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit b43aee9cc904961e0f18156c3c84a3e460bdb7be) + + https://issues.redhat.com/browse/RHEL-144089 [rhel-10.2] + https://issues.redhat.com/browse/RHEL-144090 [rhel-9.8] +--- + src/qemu/qemu_snapshot.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c +index 302775af92..dfc3f449e3 100644 +--- a/src/qemu/qemu_snapshot.c ++++ b/src/qemu/qemu_snapshot.c +@@ -3135,7 +3135,8 @@ qemuSnapshotDiskHasBackingDisk(void *payload, + if (!disk->src->backingStore) + ignore_value(virStorageSourceGetMetadata(disk->src, uid, gid, 1, false)); + +- if (virStorageSourceIsSameLocation(disk->src->backingStore, iterdata->diskSrc)) { ++ if (disk->src->backingStore && ++ virStorageSourceIsSameLocation(disk->src->backingStore, iterdata->diskSrc)) { + struct _qemuSnapshotDisksWithBackingStoreData *data = + g_new0(struct _qemuSnapshotDisksWithBackingStoreData, 1); + +-- +2.52.0 diff --git a/libvirt-qemuSnapshotDiskHasBackingDisk-Use-proper-max_depth-when-calling-virStorageSourceGetMetadata.patch b/libvirt-qemuSnapshotDiskHasBackingDisk-Use-proper-max_depth-when-calling-virStorageSourceGetMetadata.patch new file mode 100644 index 0000000..3120c50 --- /dev/null +++ b/libvirt-qemuSnapshotDiskHasBackingDisk-Use-proper-max_depth-when-calling-virStorageSourceGetMetadata.patch @@ -0,0 +1,75 @@ +From 78e9a796a24c4f60c162ee3643c4a251c97ab1d2 Mon Sep 17 00:00:00 2001 +Message-ID: <78e9a796a24c4f60c162ee3643c4a251c97ab1d2.1769699749.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Mon, 26 Jan 2026 16:39:24 +0100 +Subject: [PATCH] qemuSnapshotDiskHasBackingDisk: Use proper 'max_depth' when + calling 'virStorageSourceGetMetadata' + +The 'max_depth' argument of 'virStorageSourceGetMetadata' doesn't just +limit how far the function goes but also fails completely if the chain +is deeper than the passed value. + +In 'qemuSnapshotDiskHasBackingDisk' we only care about finding the +backing image, so just one level below, the passed path, but due to the +above setting '1' as max_depth will make the function simply fail every +time. + +Extract and reuse QEMU_DOMAIN_STORAGE_SOURCE_CHAIN_MAX_DEPTH as the +detection depth. While '200' layers is overkill for this code, we also +start a full qemu instance just to delete an snapshot so this doens't +matter and still protects from self-referential images. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 6bcdf4ee59595041c76ed2339c45503723400737) + + https://issues.redhat.com/browse/RHEL-144089 [rhel-10.2] + https://issues.redhat.com/browse/RHEL-144090 [rhel-9.8] +--- + src/qemu/qemu_domain.c | 2 -- + src/qemu/qemu_domain.h | 1 + + src/qemu/qemu_snapshot.c | 4 +++- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index ac56fc7cb4..486a0e7913 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -6297,8 +6297,6 @@ qemuDomainStorageAlias(const char *device, int depth) + } + + +-#define QEMU_DOMAIN_STORAGE_SOURCE_CHAIN_MAX_DEPTH 200 +- + /** + * qemuDomainStorageSourceValidateDepth: + * @src: storage source chain to validate +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 3396f929fd..b9bb338682 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -706,6 +706,7 @@ int qemuDomainCheckDiskStartupPolicy(virQEMUDriver *driver, + size_t diskIndex, + bool cold_boot); + ++#define QEMU_DOMAIN_STORAGE_SOURCE_CHAIN_MAX_DEPTH 200 + int qemuDomainStorageSourceValidateDepth(virStorageSource *src, + int add, + const char *diskdst); +diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c +index 942ba0d437..c23add5103 100644 +--- a/src/qemu/qemu_snapshot.c ++++ b/src/qemu/qemu_snapshot.c +@@ -3133,7 +3133,9 @@ qemuSnapshotDiskHasBackingDisk(void *payload, + NULL, &uid, &gid); + + if (!disk->src->backingStore) +- ignore_value(virStorageSourceGetMetadata(disk->src, uid, gid, 1, false)); ++ ignore_value(virStorageSourceGetMetadata(disk->src, uid, gid, ++ QEMU_DOMAIN_STORAGE_SOURCE_CHAIN_MAX_DEPTH, ++ false)); + + if (disk->src->backingStore && + virStorageSourceIsSameLocation(disk->src->backingStore, iterdata->diskSrc)) { +-- +2.52.0 diff --git a/libvirt-qemuSnapshotUpdateBackingStore-Remove-stale-comment.patch b/libvirt-qemuSnapshotUpdateBackingStore-Remove-stale-comment.patch new file mode 100644 index 0000000..c8e3ae3 --- /dev/null +++ b/libvirt-qemuSnapshotUpdateBackingStore-Remove-stale-comment.patch @@ -0,0 +1,34 @@ +From ca8a9f6b124dbfe5809c83d7f2d268bb18b9fa75 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Fri, 23 Jan 2026 08:54:32 +0100 +Subject: [PATCH] qemuSnapshotUpdateBackingStore: Remove stale comment + +The code does a 'qemu-img rebase' rather than a 'qemu-img create' what +the commit suggests. Since we enumerate all arguments right below, +there's no need for a comment. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 452c281aee7a043b59a288de043ea4e3b75a6b7c) + + https://issues.redhat.com/browse/RHEL-144089 [rhel-10.2] + https://issues.redhat.com/browse/RHEL-144090 [rhel-9.8] +--- + src/qemu/qemu_snapshot.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c +index dfc3f449e3..942ba0d437 100644 +--- a/src/qemu/qemu_snapshot.c ++++ b/src/qemu/qemu_snapshot.c +@@ -3698,7 +3698,6 @@ qemuSnapshotUpdateBackingStore(qemuSnapshotDeleteExternalData *data) + struct _qemuSnapshotDisksWithBackingStoreData *backingData = cur->data; + g_autoptr(virCommand) cmd = NULL; + +- /* creates cmd line args: qemu-img create -f qcow2 -o */ + if (!(cmd = virCommandNewArgList("qemu-img", + "rebase", + "-u", +-- +2.52.0 diff --git a/libvirt-qemuSnapshotUpdateBackingStore-Retry-as-curent-user-if-qemu-img-fails.patch b/libvirt-qemuSnapshotUpdateBackingStore-Retry-as-curent-user-if-qemu-img-fails.patch new file mode 100644 index 0000000..0b1fa87 --- /dev/null +++ b/libvirt-qemuSnapshotUpdateBackingStore-Retry-as-curent-user-if-qemu-img-fails.patch @@ -0,0 +1,97 @@ +From 7d39e57db8479f4c481636c8c41311f3eabc935f Mon Sep 17 00:00:00 2001 +Message-ID: <7d39e57db8479f4c481636c8c41311f3eabc935f.1769699749.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Mon, 26 Jan 2026 16:49:50 +0100 +Subject: [PATCH] qemuSnapshotUpdateBackingStore: Retry as curent user if + qemu-img fails + +The code calls 'qemu-img rebase' to fix the backing store references. +The 'qemu-img' process here is run as the 'qemu' user or whatever the +defaults and domain XML resolve to. Since this, in certain cases, works +also on images which are not part of the backing chain and in privileged +deployments thus can be owned by 'root:root' the update may fail +(silently). + +To preserver root-squash deployments but fix also the above case, retry +the operation on failure as current user. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 6bb982178b40768f37c5177f317e73562733530f) + + https://issues.redhat.com/browse/RHEL-144089 [rhel-10.2] + https://issues.redhat.com/browse/RHEL-144090 [rhel-9.8] +--- + src/qemu/qemu_snapshot.c | 53 ++++++++++++++++++++++++++++------------ + 1 file changed, 38 insertions(+), 15 deletions(-) + +diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c +index c23add5103..e30ade9dc8 100644 +--- a/src/qemu/qemu_snapshot.c ++++ b/src/qemu/qemu_snapshot.c +@@ -3698,25 +3698,48 @@ qemuSnapshotUpdateBackingStore(qemuSnapshotDeleteExternalData *data) + + for (cur = data->disksWithBacking; cur; cur = g_slist_next(cur)) { + struct _qemuSnapshotDisksWithBackingStoreData *backingData = cur->data; +- g_autoptr(virCommand) cmd = NULL; ++ /* Try to run the command first as the appropriate user based on the ++ * domain definition and config. If error is returned retry as current ++ * (possibly privileged) user for cases where seclabels were reset ++ * to the default */ ++ g_autoptr(virCommand) cmd_user_qemu = NULL; ++ g_autoptr(virCommand) cmd_user_curr = NULL; + +- if (!(cmd = virCommandNewArgList("qemu-img", +- "rebase", +- "-u", +- "-F", +- virStorageFileFormatTypeToString(data->parentDiskSrc->format), +- "-f", +- virStorageFileFormatTypeToString(backingData->diskSrc->format), +- "-b", +- data->parentDiskSrc->path, +- backingData->diskSrc->path, +- NULL))) ++ if (!(cmd_user_qemu = virCommandNewArgList("qemu-img", ++ "rebase", ++ "-u", ++ "-F", ++ virStorageFileFormatTypeToString(data->parentDiskSrc->format), ++ "-f", ++ virStorageFileFormatTypeToString(backingData->diskSrc->format), ++ "-b", ++ data->parentDiskSrc->path, ++ backingData->diskSrc->path, ++ NULL))) + continue; + +- virCommandSetUID(cmd, backingData->uid); +- virCommandSetGID(cmd, backingData->gid); ++ virCommandSetUID(cmd_user_qemu, backingData->uid); ++ virCommandSetGID(cmd_user_qemu, backingData->gid); + +- ignore_value(virCommandRun(cmd, NULL)); ++ /* done on success */ ++ if (virCommandRun(cmd_user_qemu, NULL) == 0) ++ continue; ++ ++ /* retry as current user */ ++ if (!(cmd_user_curr = virCommandNewArgList("qemu-img", ++ "rebase", ++ "-u", ++ "-F", ++ virStorageFileFormatTypeToString(data->parentDiskSrc->format), ++ "-f", ++ virStorageFileFormatTypeToString(backingData->diskSrc->format), ++ "-b", ++ data->parentDiskSrc->path, ++ backingData->diskSrc->path, ++ NULL))) ++ continue; ++ ++ ignore_value(virCommandRun(cmd_user_curr, NULL)); + } + } + +-- +2.52.0 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-qemublocktest-Iterate-all-nodenames-in-testQemuDetectBitmaps.patch b/libvirt-qemublocktest-Iterate-all-nodenames-in-testQemuDetectBitmaps.patch new file mode 100644 index 0000000..5cabc58 --- /dev/null +++ b/libvirt-qemublocktest-Iterate-all-nodenames-in-testQemuDetectBitmaps.patch @@ -0,0 +1,175 @@ +From 65beee7622ce4f110dbd56c631502444197756e6 Mon Sep 17 00:00:00 2001 +Message-ID: <65beee7622ce4f110dbd56c631502444197756e6.1770203422.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Tue, 27 Jan 2026 22:49:09 +0100 +Subject: [PATCH] qemublocktest: Iterate all nodenames in + 'testQemuDetectBitmaps' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Rather than looking for 30 specific nodenames (via a loop) iterate +everything in the hash table (in a sorted order). This simplifies the +code and provides more test outputs on previously-ignored nodenames. + +The listing of internal snapshots in the output was also missing a +newline, which would now cause problems with multiple images reproted. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 71643c197e86a3adc792c0b2a378a245ae6c5756) + +https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2] +https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8] +--- + tests/qemublocktest.c | 24 +++++++------------ + tests/qemublocktestdata/bitmap/basic.out | 1 + + tests/qemublocktestdata/bitmap/empty.out | 1 + + .../bitmap/snapshots-internal.out | 7 ++++++ + tests/qemublocktestdata/bitmap/snapshots.out | 5 ++++ + tests/qemublocktestdata/bitmap/synthetic.out | 5 ++++ + 6 files changed, 28 insertions(+), 15 deletions(-) + +diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c +index 47746207cc..51d9268cdd 100644 +--- a/tests/qemublocktest.c ++++ b/tests/qemublocktest.c +@@ -575,17 +575,15 @@ testQemuImageCreate(const void *opaque) + + static const char *bitmapDetectPrefix = "qemublocktestdata/bitmap/"; + +-static void +-testQemuDetectBitmapsWorker(GHashTable *nodedata, ++static int ++testQemuDetectBitmapsWorker(void *payload, + const char *nodename, +- virBuffer *buf) ++ void *opaque) + { +- qemuBlockNamedNodeData *data; ++ qemuBlockNamedNodeData *data = payload; ++ virBuffer *buf = opaque; + size_t i; + +- if (!(data = virHashLookup(nodedata, nodename))) +- return; +- + virBufferAsprintf(buf, "%s:\n", nodename); + if (data->qcow2v2) + virBufferAddLit(buf, " qcow2 v2\n"); +@@ -617,9 +615,12 @@ testQemuDetectBitmapsWorker(GHashTable *nodedata, + + virBufferAsprintf(buf, " '%s'%s", (const char *) n->key, vms); + } ++ ++ virBufferAddLit(buf, "\n"); + } + + virBufferAdjustIndent(buf, -1); ++ return 0; + } + + +@@ -632,7 +633,6 @@ testQemuDetectBitmaps(const void *opaque) + g_autofree char *actual = NULL; + g_autofree char *expectpath = NULL; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; +- size_t i; + + expectpath = g_strdup_printf("%s/%s%s.out", abs_srcdir, + bitmapDetectPrefix, name); +@@ -646,13 +646,7 @@ testQemuDetectBitmaps(const void *opaque) + return -1; + } + +- /* we detect for the first 30 nodenames for simplicity */ +- for (i = 0; i < 30; i++) { +- g_autofree char *nodename = g_strdup_printf("libvirt-%zu-format", i); +- +- testQemuDetectBitmapsWorker(nodedata, nodename, &buf); +- } +- ++ virHashForEachSorted(nodedata, testQemuDetectBitmapsWorker, &buf); + actual = virBufferContentAndReset(&buf); + + return virTestCompareToFile(actual, expectpath); +diff --git a/tests/qemublocktestdata/bitmap/basic.out b/tests/qemublocktestdata/bitmap/basic.out +index 5c4c35b3f0..b96ffe3d39 100644 +--- a/tests/qemublocktestdata/bitmap/basic.out ++++ b/tests/qemublocktestdata/bitmap/basic.out +@@ -4,3 +4,4 @@ libvirt-1-format: + c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++libvirt-1-storage: +diff --git a/tests/qemublocktestdata/bitmap/empty.out b/tests/qemublocktestdata/bitmap/empty.out +index 3787cbd354..c9a5be4f07 100644 +--- a/tests/qemublocktestdata/bitmap/empty.out ++++ b/tests/qemublocktestdata/bitmap/empty.out +@@ -1 +1,2 @@ + libvirt-1-format: ++libvirt-1-storage: +diff --git a/tests/qemublocktestdata/bitmap/snapshots-internal.out b/tests/qemublocktestdata/bitmap/snapshots-internal.out +index dbb3cfded4..cf7bde96a5 100644 +--- a/tests/qemublocktestdata/bitmap/snapshots-internal.out ++++ b/tests/qemublocktestdata/bitmap/snapshots-internal.out +@@ -1,2 +1,9 @@ + libvirt-1-format: + internal snapshots: '1727868651'(*) '1727872064'(*) ++libvirt-1-storage: ++libvirt-2-storage: ++libvirt-pflash0-format: ++libvirt-pflash0-storage: ++libvirt-pflash1-format: ++ internal snapshots: '1727868651' '1727872064' ++libvirt-pflash1-storage: +diff --git a/tests/qemublocktestdata/bitmap/snapshots.out b/tests/qemublocktestdata/bitmap/snapshots.out +index 24ca27e4d8..29c586be7e 100644 +--- a/tests/qemublocktestdata/bitmap/snapshots.out ++++ b/tests/qemublocktestdata/bitmap/snapshots.out +@@ -4,16 +4,21 @@ libvirt-1-format: + b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++libvirt-1-storage: + libvirt-2-format: + c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++libvirt-2-storage: + libvirt-3-format: + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++libvirt-3-storage: + libvirt-4-format: + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++libvirt-4-storage: + libvirt-5-format: + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++libvirt-5-storage: +diff --git a/tests/qemublocktestdata/bitmap/synthetic.out b/tests/qemublocktestdata/bitmap/synthetic.out +index 45423903a0..2f4ae2b217 100644 +--- a/tests/qemublocktestdata/bitmap/synthetic.out ++++ b/tests/qemublocktestdata/bitmap/synthetic.out +@@ -6,12 +6,17 @@ libvirt-1-format: + top-inactive: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + top-transient: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0 + top-transient-inactive: record:0 busy:0 persist:0 inconsist:0 gran:65536 dirty:0 ++libvirt-1-storage: + libvirt-2-format: + d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++libvirt-2-storage: + libvirt-3-format: + b: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0 + c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++libvirt-3-storage: + libvirt-4-format: ++libvirt-4-storage: + libvirt-5-format: + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 ++libvirt-5-storage: +-- +2.52.0 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-src-Use-device-alias-when-ifname-is-unset-in-virDomainInterfaceAddresses.patch b/libvirt-src-Use-device-alias-when-ifname-is-unset-in-virDomainInterfaceAddresses.patch new file mode 100644 index 0000000..c10a41d --- /dev/null +++ b/libvirt-src-Use-device-alias-when-ifname-is-unset-in-virDomainInterfaceAddresses.patch @@ -0,0 +1,98 @@ +From 1aa7206312b153f5209a5c161b4345e65a762c26 Mon Sep 17 00:00:00 2001 +Message-ID: <1aa7206312b153f5209a5c161b4345e65a762c26.1770714339.git.jdenemar@redhat.com> +From: Michal Privoznik +Date: Tue, 20 Jan 2026 16:19:00 +0100 +Subject: [PATCH] src: Use device alias when ifname is unset in + virDomainInterfaceAddresses() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The virDomainInterfaceAddresses() API returns an array of +_virDomainInterface structs which then describe IP addresses +associated with given domain. The struct contains 'name' member +which is documented deliberately vaguely: "interface name". This +is because depending on the source of truth used (controlled by +'source' argument) the name can be wildly different from the one +in domain XML. Now, in case of source = +VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP, the host's ARP table is +parsed and matching interfaces are found by comparing MAC +addresses. If it's a match then the 'name' is set to net->ifname +(corresponds to /interface/target/@dev). But that is not always +set and sometimes may be NULL (e.g. for hostdevs, usernet). We +can't change the API (like we did for hwaddr in v1.2.14-rc1~105) +because this is already released. So the next best thing to do is +to put the interface alias in there. + +To be on a safe side, do the same change to the +VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE case. + +Resolves: https://issues.redhat.com/browse/RHEL-141496 +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 4009126f17a19ea2f512f1952f4ea32d231ade85) +Resolves: https://issues.redhat.com/browse/RHEL-143933 +Signed-off-by: Michal Privoznik +--- + src/conf/domain_conf.c | 16 ++++++++++++++-- + src/libvirt-domain.c | 2 ++ + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index f950f7c75d..902c1188ef 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -15604,6 +15604,12 @@ virDomainNetDHCPInterfaces(virDomainDef *def, + goto error; + + if (n_leases) { ++ const char *ifname = def->nets[i]->ifname; ++ ++ if (!ifname) { ++ ifname = def->nets[i]->info.alias; ++ } ++ + ifaces_ret = g_renew(virDomainInterfacePtr, ifaces_ret, ifaces_count + 1); + ifaces_ret[ifaces_count] = g_new0(virDomainInterface, 1); + iface = ifaces_ret[ifaces_count]; +@@ -15612,7 +15618,7 @@ virDomainNetDHCPInterfaces(virDomainDef *def, + /* Assuming each lease corresponds to a separate IP */ + iface->naddrs = n_leases; + iface->addrs = g_new0(virDomainIPAddress, iface->naddrs); +- iface->name = g_strdup(def->nets[i]->ifname); ++ iface->name = g_strdup(ifname); + iface->hwaddr = g_strdup(macaddr); + } + +@@ -15666,9 +15672,15 @@ virDomainNetARPInterfaces(virDomainDef *def, + virArpTableEntry entry = table->t[j]; + + if (STREQ(entry.mac, macaddr)) { ++ const char *ifname = def->nets[i]->ifname; ++ ++ if (!ifname) { ++ ifname = def->nets[i]->info.alias; ++ } ++ + iface = g_new0(virDomainInterface, 1); + +- iface->name = g_strdup(def->nets[i]->ifname); ++ iface->name = g_strdup(ifname); + + iface->hwaddr = g_strdup(macaddr); + +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index 74c70a0a43..c7451fee05 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -12880,6 +12880,8 @@ virDomainFSInfoFree(virDomainFSInfoPtr info) + * Note that for some @source values some pieces of returned @ifaces + * might be unset (e.g. VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP does not + * set IP address prefix as ARP table does not have any notion of that). ++ * Moreover, it may happen that the interface doesn't have a name. In ++ * that case, @ifaces->name is set to the interface's device alias. + * + * @ifaces->name and @ifaces->hwaddr are never NULL. + * +-- +2.53.0 diff --git a/libvirt-src-esx-esx_vi.c-Debug-path-element-comparisons.patch b/libvirt-src-esx-esx_vi.c-Debug-path-element-comparisons.patch new file mode 100644 index 0000000..be12772 --- /dev/null +++ b/libvirt-src-esx-esx_vi.c-Debug-path-element-comparisons.patch @@ -0,0 +1,53 @@ +From d4bacfba4087228a4a509f41a02aefaaeac187a0 Mon Sep 17 00:00:00 2001 +Message-ID: +From: "Richard W.M. Jones" +Date: Thu, 5 Feb 2026 10:55:12 +0000 +Subject: [PATCH] src/esx/esx_vi.c: Debug path element comparisons + +Libvirt vpx:// and esx:// URIs are quite obscure. In particular it is +very difficult to construct a correct path to a VMware resource. +Basically you are iterating over VMware structures blindly with no way +to know what your choices are at each level in the path. + +This commit doesn't directly address this. It's still difficult. But +at least let's add the true path choices to the debug output so +someone could in theory use 'LIBVIRT_DEBUG=1' to find out what +possible choices exist at a path level. + +For example this command fails because the label (which looks like an +IPv6 address, but is really a label) should use "::" instead of ":0:": + + LIBVIRT_DEBUG=1 virsh -c 'vpx://root@.../data/aaaa:52:0:49e0:2eea:7fff:fee6:eca0/?no_verify=1' + +In the debugging output we now print: + + 2026-02-05 10:58:25.421+0000: 1528876: debug : esxVI_LookupManagedObjectHelper:4956 : comparing path element 'aaaa:52:0:49e0:2eea:7fff:fee6:eca0' with candidate name 'aaaa:52::49e0:2eea:7fff:fee6:eca0' + 2026-02-05 10:58:25.421+0000: 1528876: error : esxVI_Context_LookupManagedObjectsByPath:1098 : internal error: Could not find compute resource specified in '/data/aaaa:52:0:49e0:2eea:7fff:fee6:eca0/' + +In an ideal world we should improve the error message to show the +possible choices, but the way the code is structured makes that +prohibitive. + +Related: https://issues.redhat.com/browse/RHEL-145080 +Reviewed-by: Peter Krempa +Signed-off-by: Richard W.M. Jones +(cherry picked from commit 090223d01a8b8128543fd717920982ba9517bd34) +--- + src/esx/esx_vi.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c +index 8d2ffb3f8f..cfd783622d 100644 +--- a/src/esx/esx_vi.c ++++ b/src/esx/esx_vi.c +@@ -4953,6 +4953,8 @@ esxVI_LookupManagedObjectHelper(esxVI_Context *ctx, + goto cleanup; + } + ++ VIR_DEBUG("comparing path element '%s' with candidate name '%s'", ++ name, name_candidate); + if (STREQ(name_candidate, name)) { + /* Found item with matching name */ + break; +-- +2.53.0 diff --git a/libvirt-tests-Test-virFileIsSharedFSOverride.patch b/libvirt-tests-Test-virFileIsSharedFSOverride.patch new file mode 100644 index 0000000..d247e7d --- /dev/null +++ b/libvirt-tests-Test-virFileIsSharedFSOverride.patch @@ -0,0 +1,111 @@ +From 0bb3bb84670dbd45c6eca2d108b2d4d5a7754ef4 Mon Sep 17 00:00:00 2001 +Message-ID: <0bb3bb84670dbd45c6eca2d108b2d4d5a7754ef4.1766070439.git.jdenemar@redhat.com> +From: Jiri Denemark +Date: Fri, 5 Dec 2025 15:09:15 +0100 +Subject: [PATCH] tests: Test virFileIsSharedFSOverride + +Technically virFileIsSharedFSOverride is available on any OS, but we +need a mocked realpath() to test it. Because the virfilemock library +also mocks statfs() which is only available on Linux, we don't even try +to load the library anywhere else. Thus we need to skip testing +virFileIsSharedFSOverride on non-Linux too. + +Signed-off-by: Jiri Denemark +(cherry picked from commit 121d179e068b584f62ea2c029d89a44e67c909c0) + +https://issues.redhat.com/browse/RHEL-102925 + +Signed-off-by: Jiri Denemark +--- + tests/virfiletest.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +diff --git a/tests/virfiletest.c b/tests/virfiletest.c +index e05925a321..ccd76a3fac 100644 +--- a/tests/virfiletest.c ++++ b/tests/virfiletest.c +@@ -329,6 +329,55 @@ testFileIsSharedFSType(const void *opaque G_GNUC_UNUSED) + } + + ++static const char *shared_filesystems[] = { ++ "/run/user/501/gvfs", ++ "/nfs", ++ "/gluster", ++ "/ceph/multi", ++ "/gpfs/data/blaf", ++ "/quobyte", ++ NULL, ++}; ++ ++static int ++testFileIsSharedFSOverride(const void *opaque G_GNUC_UNUSED) ++{ ++#ifndef __linux__ ++ return EXIT_AM_SKIP; ++#else ++ const struct testFileIsSharedFSType *data = opaque; ++ g_autofree char *mtabFile = NULL; ++ bool actual; ++ int ret = -1; ++ ++ /* mtab is used by mocked realpath to decide whether a given path exists */ ++ mtabFile = g_strdup_printf(abs_srcdir "/virfiledata/%s", data->mtabFile); ++ ++ if (!g_setenv("LIBVIRT_MTAB", mtabFile, true)) { ++ fprintf(stderr, "Unable to set env variable\n"); ++ goto cleanup; ++ } ++ ++ actual = virFileIsSharedFSOverride(data->filename, ++ (char * const *) shared_filesystems); ++ ++ if (actual != data->expected) { ++ fprintf(stderr, "FS of '%s' is %s. Expected: %s\n", ++ data->filename, ++ actual ? "shared" : "not shared", ++ data->expected ? "shared" : "not shared"); ++ goto cleanup; ++ } ++ ++ ret = 0; ++ ++ cleanup: ++ g_unsetenv("LIBVIRT_MTAB"); ++ return ret; ++#endif ++} ++ ++ + static int + mymain(void) + { +@@ -439,6 +488,26 @@ mymain(void) + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gpfs/data", true); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/quobyte", true); + ++#define DO_TEST_FILE_IS_SHARED_FS_OVERRIDE(mtab, file, exp) \ ++ do { \ ++ struct testFileIsSharedFSType data = { \ ++ .mtabFile = mtab, .filename = file, .expected = exp \ ++ }; \ ++ if (virTestRun(virTestCounterNext(), testFileIsSharedFSOverride, &data) < 0) \ ++ ret = -1; \ ++ } while (0) ++ ++ virTestCounterReset("testFileIsSharedFSOverride "); ++ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts2.txt", "/boot/vmlinuz", false); ++ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts2.txt", "/run/user/501/gvfs/some/file", true); ++ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/nfs/file", true); ++ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/gluster/file", true); ++ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/some/symlink/file", true); ++ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/ceph/file", false); ++ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/ceph/multi/file", true); ++ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/gpfs/data", false); ++ DO_TEST_FILE_IS_SHARED_FS_OVERRIDE("mounts3.txt", "/quobyte", true); ++ + return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } + +-- +2.52.0 diff --git a/libvirt-tests-add-test-for-a-single-per-device-smmuv3.patch b/libvirt-tests-add-test-for-a-single-per-device-smmuv3.patch new file mode 100644 index 0000000..2941140 --- /dev/null +++ b/libvirt-tests-add-test-for-a-single-per-device-smmuv3.patch @@ -0,0 +1,201 @@ +From d30c21439f3847ecc229db9355eb802f0256a3f0 Mon Sep 17 00:00:00 2001 +Message-ID: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Fri, 5 Dec 2025 08:50:51 +0100 +Subject: [PATCH] tests: add test for a single per-device smmuv3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Ján Tomko +(cherry picked from commit 45ff1c002629dadd9d94b91742ffb985b0fe027f) + +https://issues.redhat.com/browse/RHEL-74200 +Signed-off-by: Ján Tomko +--- + ...-smmuv3-pci-bus-single.aarch64-latest.args | 40 +++++++++++++ + ...u-smmuv3-pci-bus-single.aarch64-latest.xml | 59 +++++++++++++++++++ + .../iommu-smmuv3-pci-bus-single.xml | 46 +++++++++++++++ + tests/qemuxmlconftest.c | 1 + + 4 files changed, 146 insertions(+) + create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args + create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.xml + create mode 100644 tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.xml + +diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args +new file mode 100644 +index 0000000000..976467e641 +--- /dev/null ++++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.args +@@ -0,0 +1,40 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/var/lib/libvirt/qemu/domain--1-guest \ ++USER=test \ ++LOGNAME=test \ ++XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-guest/.local/share \ ++XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-guest/.cache \ ++XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-guest/.config \ ++/usr/bin/qemu-system-aarch64 \ ++-name guest=guest,debug-threads=on \ ++-S \ ++-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-guest/master-key.aes"}' \ ++-machine virt,usb=off,gic-version=2,iommu=smmuv3,dump-guest-core=off,memory-backend=mach-virt.ram,acpi=off \ ++-accel tcg \ ++-cpu cortex-a15 \ ++-m size=1048576k \ ++-object '{"qom-type":"memory-backend-ram","id":"mach-virt.ram","size":1073741824}' \ ++-overcommit mem-lock=off \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot strict=on \ ++-device '{"driver":"pxb-pcie","bus_nr":252,"id":"pci.1","bus":"pcie.0","addr":"0x1"}' \ ++-device '{"driver":"pxb-pcie","bus_nr":248,"id":"pci.2","bus":"pcie.0","addr":"0x2"}' \ ++-device '{"driver":"pcie-root-port","port":0,"chassis":21,"id":"pci.3","bus":"pci.1","addr":"0x0"}' \ ++-device '{"driver":"pcie-root-port","port":168,"chassis":22,"id":"pci.4","bus":"pci.2","addr":"0x0"}' \ ++-device '{"driver":"arm-smmuv3","primary-bus":"pci.1","id":"iommu0"}' \ ++-audiodev '{"id":"audio1","driver":"none"}' \ ++-object '{"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"}' \ ++-device '{"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.3","addr":"0x0"}' \ ++-object '{"qom-type":"rng-random","id":"objrng1","filename":"/dev/urandom"}' \ ++-device '{"driver":"virtio-rng-pci","rng":"objrng1","id":"rng1","bus":"pci.4","addr":"0x0"}' \ ++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ ++-msg timestamp=on +diff --git a/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.xml b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.xml +new file mode 100644 +index 0000000000..e6071fd71b +--- /dev/null ++++ b/tests/qemuxmlconfdata/iommu-smmuv3-pci-bus-single.aarch64-latest.xml +@@ -0,0 +1,59 @@ ++ ++ guest ++ 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 ++ 1048576 ++ 1048576 ++ 1 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ cortex-a15 ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-aarch64 ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++
++ ++ ++ ++ ++
++ ++ ++ ++ ++
++ ++