From 209f2f84bfd139eda28d296b948784e15ea591d7 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 24 Apr 2024 05:32:21 -0400 Subject: [PATCH] * Wed Apr 24 2024 Miroslav Rezanina - 9.0.0-1 - Rebase to QEMU 9.0.0 [RHEL-28073] - Resolves: RHEL-28073 (Rebase qemu-kvm to QEMU 9.0.0 for RHEL 9.5) --- .gitignore | 1 + 0004-Initial-redhat-build.patch | 19 +- 0005-Enable-disable-devices-for-RHEL.patch | 266 +- ...Machine-type-related-general-changes.patch | 168 +- 0007-Add-aarch64-machine-types.patch | 138 +- 0008-Add-ppc64-machine-types.patch | 50 +- 0009-Add-s390x-machine-types.patch | 20 +- 0010-Add-x86_64-machine-types.patch | 100 +- 0011-Enable-make-check.patch | 20 +- ...mber-of-devices-that-can-be-assigned.patch | 19 +- ...Add-support-statement-to-help-output.patch | 8 +- ...documentation-instead-of-qemu-system.patch | 6 +- ...on-warning-when-opening-v2-images-rw.patch | 4 +- 0016-Add-upstream-compatibility-bits.patch | 121 + ....4.0-qemu-kvm-machine-type-for-aarch.patch | 44 - ...6-rhel-9.4.0-machine-type-compat-fix.patch | 30 + kvm-Compile-IOMMUFD-object-on-aarch64.patch | 37 - kvm-Compile-IOMMUFD-on-s390x.patch | 37 - kvm-Compile-IOMMUFD-on-x86_64.patch | 37 - kvm-Implement-SMBIOS-type-9-v2.6.patch | 155 - ...ent-base-of-SMBIOS-type-9-descriptor.patch | 218 - ...har-socket-Fix-TLS-io-channels-sendi.patch | 60 - ...se-a-child-source-for-qio-input-sour.patch | 216 - ...text_acquire-aio_context_release-a-n.patch | 60 - ...ontext_acquire-aio_context_release-A.patch | 102 - ...uivalence-between-AIO_WAIT_WHILE-and.patch | 81 - ...iommufd-Introduce-the-iommufd-object.patch | 476 -- ...-Remove-check-on-number-of-backend-u.patch | 47 - kvm-backends-iommufd-Remove-mutex.patch | 112 - ...end-Allow-concurrent-context-changes.patch | 104 - ...wrapper-use-qemu_get_current_aio_con.patch | 69 - ...-set-up-Linux-AIO-and-io_uring-in-th.patch | 217 - kvm-block-remove-AioContext-locking.patch | 4438 ----------------- kvm-block-remove-bdrv_co_lock.patch | 97 - ...outdated-AioContext-locking-comments.patch | 411 -- ...ket-Fix-TLS-io-channels-sending-too-.patch | 105 - ...iority-of-the-HUP-GSource-in-socket-.patch | 78 - ...utine-cap-per-thread-local-pool-size.patch | 412 -- kvm-coroutine-reserve-5-000-mappings.patch | 61 - ...-don-t-lock-AioContext-in-dma_blk_cb.patch | 75 - ...d-VFIO-iommufd-backend-documentation.patch | 228 - ...e-AioContext-lock-from-IOThread-docs.patch | 98 - ...graph-lock-remove-AioContext-locking.patch | 1190 ----- ...et_min_alignment-to-express-32-GiB-a.patch | 94 - ...m-Activate-IOMMUFD-for-virt-machines.patch | 42 - ...properties-to-disable-high-memory-re.patch | 88 - kvm-hw-arm-virt-Fix-compats.patch | 132 - ...ecate-virt-rhel9.-0-2-.0-machine-typ.patch | 41 - ...86-Activate-IOMMUFD-for-q35-machines.patch | 41 - ...-smbios_set_defaults-to-machine_done.patch | 186 - kvm-hw-ppc-Kconfig-Imply-VFIO_PCI.patch | 116 - ...teration-over-global-VFIODevice-list.patch | 73 - ....h-fix-qemu_rect_init-mis-assignment.patch | 54 - ...-for-reset-AioContext-switches-with-.patch | 133 - ...ts-add-filter_qmp_generated_node_ids.patch | 49 - ...ds-stream-Use-the-right-TimeoutError.patch | 49 - ...1-to-Python-for-reliable-QMP-testing.patch | 592 --- ...outdated-AioContext-locking-comments.patch | 105 - ...-Activate-IOMMUFD-for-s390x-machines.patch | 42 - ...reintroduce-memory-region-size-check.patch | 112 - ...all-job_pause_point-under-graph-lock.patch | 90 - ...-coroutine-commands-in-qemu_aio_cont.patch | 1630 ------ ...rver-Fix-race-in-draining-the-export.patch | 95 - ...id-per-NBDRequest-nbd_client_get-put.patch | 53 - ...duce-NBDClient-lock-to-protect-field.patch | 373 -- ...traverse-NBDExport-clients-from-main.patch | 176 - ...S-entry-point-type-to-auto-by-defaul.patch | 115 - ...manufacturer-product-version-to-matc.patch | 44 - ...adVirtQueueMappingList-property-type.patch | 167 - ...es-alias-all-object-class-properties.patch | 85 - ...-increase-NOFILE-soft-limit-on-POSIX.patch | 135 - ...i-avoid-double-enable-disable-of-aif.patch | 106 - ...drive-ISM-reset-from-subsystem-reset.patch | 137 - ...-pci-refresh-fh-before-disabling-aif.patch | 71 - kvm-scsi-Await-request-purging.patch | 124 - ...-callbacks-run-in-the-correct-AioCon.patch | 88 - ...n-t-lock-AioContext-in-I-O-code-path.patch | 245 - ...-SCSIDevice-requests-from-one-thread.patch | 307 -- kvm-scsi-remove-AioContext-locking.patch | 280 -- ...ove-outdated-AioContext-lock-comment.patch | 41 - ...-add-smbios_add_usr_blob_size-helper.patch | 62 - ...-avoid-mangling-user-provided-tables.patch | 309 -- ...legacy-mode-code-only-for-pc-machine.patch | 517 -- ...mbios_get_tables-from-legacy-handlin.patch | 65 - ...ios_type4_count-before-building-tabl.patch | 38 - ...heck-type4-structures-in-legacy-mode.patch | 133 - ...-when-building-type-4-table-is-not-p.patch | 72 - ...bios-entry-point-type-with-auto-valu.patch | 48 - ...ios-get-rid-of-global-smbios_ep_type.patch | 281 -- ...bios-get-rid-of-smbios_legacy-global.patch | 198 - ...get-rid-of-smbios_smp_sockets-global.patch | 134 - kvm-smbios-handle-errors-consistently.patch | 217 - ...f-entry-point-is-auto-try-to-build-v.patch | 131 - ...pose-structures-bitmaps-used-by-both.patch | 330 -- ...t-visitor-Fix-pseudo-struct-handling.patch | 190 - ...tput-visitor-show-structs-as-omitted.patch | 90 - ...-pv-Provide-some-more-useful-informa.patch | 205 - ...sts-remove-aio_context_acquire-tests.patch | 125 - ...test-replication-timeout-to-60-secon.patch | 46 - ...d-add-asserts-for-update-and-request.patch | 81 - ...k-type-as-not-available-when-there-i.patch | 107 - kvm-util-char_dev-Add-open_cdev.patch | 175 - ...-helper-function-to-initialize-VFIOD.patch | 154 - ...ase-object-for-VFIOContainer-and-tar.patch | 129 - ...ntainerBase-poiner-parameter-const-i.patch | 276 - ...e-selection-of-a-given-iommu-backend.patch | 75 - ...o-cdev-pre-openable-by-passing-a-fil.patch | 87 - ...ODevice-initializations-in-vfio_ap_i.patch | 81 - ...he-selection-of-a-given-iommu-backen.patch | 79 - ...io-cdev-pre-openable-by-passing-a-fi.patch | 93 - ...IODevice-initializations-in-vfio_ccw.patch | 85 - ...oduce-vfio_container_init-destroy-he.patch | 98 - ...n-Move-giommu_list-in-base-container.patch | 221 - ...on-return-early-if-space-isn-t-empty.patch | 55 - ...-Convert-functions-to-base-container.patch | 257 - ...ainer-Implement-attach-detach_device.patch | 97 - ...nitialize-VFIOIOMMUOps-under-vfio_in.patch | 65 - ...ntoduce-a-new-VFIOIOMMUClass-setup-h.patch | 55 - ...-Introduce-a-VFIOIOMMU-QOM-interface.patch | 143 - ...ntroduce-a-VFIOIOMMU-legacy-QOM-inte.patch | 168 - ...ainer-Introduce-a-empty-VFIOIOMMUOps.patch | 71 - ...ntroduce-vfio_legacy_setup-for-furth.patch | 118 - ...ove-dirty_pgsizes-and-max_dirty_bitm.patch | 102 - ...r-Move-iova_ranges-to-base-container.patch | 168 - ...iner-Move-listener-to-base-container.patch | 522 -- ...ove-per-container-device-list-in-bas.patch | 230 - ...ove-pgsizes-and-dma_max_mappings-to-.patch | 242 - ...r-Move-space-field-to-base-container.patch | 265 - ...ner-Move-vrdl_list-to-base-container.patch | 255 - ...ename-vfio_init_container-to-vfio_se.patch | 66 - ...eplace-basename-with-g_path_get_base.patch | 59 - ...witch-to-IOMMU-BE-set_dirty_page_tra.patch | 235 - ...ontainer-Switch-to-dma_map-unmap-API.patch | 303 -- ...-support-for-iova_ranges-and-pgsizes.patch | 115 - ...ble-pci-hot-reset-through-iommufd-cd.patch | 215 - ...ommufd-Implement-the-iommufd-backend.patch | 561 --- ...roduce-a-VFIOIOMMU-iommufd-QOM-inter.patch | 155 - ...lax-assert-check-for-iommufd-backend.patch | 71 - ...-iommufd-Remove-CONFIG_IOMMUFD-usage.patch | 55 - ...ove-the-use-of-stat-to-check-file-ex.patch | 56 - ...dd-helper-function-to-set-state-or-r.patch | 115 - ...he-selection-of-a-given-iommu-backen.patch | 81 - ...fio-pci-Clear-MSI-X-IRQ-index-always.patch | 69 - ...-out-a-helper-vfio_pci_get_pci_hot_r.patch | 139 - ...oduce-a-vfio-pci-hot-reset-interface.patch | 466 -- ...io-cdev-pre-openable-by-passing-a-fi.patch | 237 - ...IODevice-initializations-in-vfio_ins.patch | 70 - ...low-the-selection-of-a-given-iommu-b.patch | 77 - ...ke-vfio-cdev-pre-openable-by-passing.patch | 108 - ...ve-VFIODevice-initializations-in-vfi.patch | 64 - ...d-VFIOIOMMUOps-with-a-release-handle.patch | 129 - ...duce-a-sPAPR-VFIOIOMMU-QOM-interface.patch | 150 - ...duce-spapr-backend-and-target-interf.patch | 91 - ...ve-hostwin_list-into-spapr-container.patch | 188 - ...prereg_listener-into-spapr-container.patch | 120 - ...compile-sPAPR-IOMMU-support-when-nee.patch | 46 - ...h-to-spapr-IOMMU-BE-add-del_section_.patch | 184 - ...-Re-enable-notifications-after-drain.patch | 139 - ...otential-nullpointer-read-access-in-.patch | 47 - ...-ioeventfd_attach-in-start_ioeventfd.patch | 75 - ...lk-add-iothread-vq-mapping-parameter.patch | 464 -- kvm-virtio-blk-add-lock-to-protect-s-rq.patch | 177 - ...-always-set-ioeventfd-during-startup.patch | 63 - ...-using-ioeventfd-state-in-irqfd-cond.patch | 72 - ...-lock-AioContext-in-the-completion-c.patch | 167 - ...-lock-AioContext-in-the-submission-c.patch | 67 - ...ove-dataplane-code-into-virtio-blk.c.patch | 1009 ---- ...e-dataplane-create-destroy-functions.patch | 117 - ...io-blk-rename-dataplane-to-ioeventfd.patch | 307 -- ...-restart-s-rq-reqs-in-vq-AioContexts.patch | 106 - ...ate-failure-to-set-BlockBackend-AioC.patch | 72 - ...lock-migration-of-VMs-with-blob-true.patch | 87 - ...-mem-default-enable-dynamic-memslots.patch | 70 - ...ttach-event-vq-notifier-with-no_poll.patch | 78 - ...t-lock-AioContext-around-virtio_queu.patch | 58 - ...ace-AioContext-lock-with-tmf_bh_lock.patch | 173 - ...6-rhel-9.2.0-machine-type-compat-fix.patch | 48 - qemu-kvm.spec | 444 +- sources | 2 +- 179 files changed, 614 insertions(+), 31744 deletions(-) create mode 100644 0016-Add-upstream-compatibility-bits.patch delete mode 100644 0016-Introduce-RHEL-9.4.0-qemu-kvm-machine-type-for-aarch.patch create mode 100644 0017-x86-rhel-9.4.0-machine-type-compat-fix.patch delete mode 100644 kvm-Compile-IOMMUFD-object-on-aarch64.patch delete mode 100644 kvm-Compile-IOMMUFD-on-s390x.patch delete mode 100644 kvm-Compile-IOMMUFD-on-x86_64.patch delete mode 100644 kvm-Implement-SMBIOS-type-9-v2.6.patch delete mode 100644 kvm-Implement-base-of-SMBIOS-type-9-descriptor.patch delete mode 100644 kvm-Revert-chardev-char-socket-Fix-TLS-io-channels-sendi.patch delete mode 100644 kvm-Revert-chardev-use-a-child-source-for-qio-input-sour.patch delete mode 100644 kvm-aio-make-aio_context_acquire-aio_context_release-a-n.patch delete mode 100644 kvm-aio-remove-aio_context_acquire-aio_context_release-A.patch delete mode 100644 kvm-aio-wait-draw-equivalence-between-AIO_WAIT_WHILE-and.patch delete mode 100644 kvm-backends-iommufd-Introduce-the-iommufd-object.patch delete mode 100644 kvm-backends-iommufd-Remove-check-on-number-of-backend-u.patch delete mode 100644 kvm-backends-iommufd-Remove-mutex.patch delete mode 100644 kvm-block-backend-Allow-concurrent-context-changes.patch delete mode 100644 kvm-block-coroutine-wrapper-use-qemu_get_current_aio_con.patch delete mode 100644 kvm-block-file-posix-set-up-Linux-AIO-and-io_uring-in-th.patch delete mode 100644 kvm-block-remove-AioContext-locking.patch delete mode 100644 kvm-block-remove-bdrv_co_lock.patch delete mode 100644 kvm-block-remove-outdated-AioContext-locking-comments.patch delete mode 100644 kvm-chardev-char-socket-Fix-TLS-io-channels-sending-too-.patch delete mode 100644 kvm-chardev-lower-priority-of-the-HUP-GSource-in-socket-.patch delete mode 100644 kvm-coroutine-cap-per-thread-local-pool-size.patch delete mode 100644 kvm-coroutine-reserve-5-000-mappings.patch delete mode 100644 kvm-dma-helpers-don-t-lock-AioContext-in-dma_blk_cb.patch delete mode 100644 kvm-docs-devel-Add-VFIO-iommufd-backend-documentation.patch delete mode 100644 kvm-docs-remove-AioContext-lock-from-IOThread-docs.patch delete mode 100644 kvm-graph-lock-remove-AioContext-locking.patch delete mode 100644 kvm-hv-balloon-use-get_min_alignment-to-express-32-GiB-a.patch delete mode 100644 kvm-hw-arm-Activate-IOMMUFD-for-virt-machines.patch delete mode 100644 kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch delete mode 100644 kvm-hw-arm-virt-Fix-compats.patch delete mode 100644 kvm-hw-arm-virt-deprecate-virt-rhel9.-0-2-.0-machine-typ.patch delete mode 100644 kvm-hw-i386-Activate-IOMMUFD-for-q35-machines.patch delete mode 100644 kvm-hw-i386-pc-Defer-smbios_set_defaults-to-machine_done.patch delete mode 100644 kvm-hw-ppc-Kconfig-Imply-VFIO_PCI.patch delete mode 100644 kvm-hw-vfio-fix-iteration-over-global-VFIODevice-list.patch delete mode 100644 kvm-include-ui-rect.h-fix-qemu_rect_init-mis-assignment.patch delete mode 100644 kvm-iotests-Add-test-for-reset-AioContext-switches-with-.patch delete mode 100644 kvm-iotests-add-filter_qmp_generated_node_ids.patch delete mode 100644 kvm-iotests-iothreads-stream-Use-the-right-TimeoutError.patch delete mode 100644 kvm-iotests-port-141-to-Python-for-reliable-QMP-testing.patch delete mode 100644 kvm-job-remove-outdated-AioContext-locking-comments.patch delete mode 100644 kvm-kconfig-Activate-IOMMUFD-for-s390x-machines.patch delete mode 100644 kvm-memory-device-reintroduce-memory-region-size-check.patch delete mode 100644 kvm-mirror-Don-t-call-job_pause_point-under-graph-lock.patch delete mode 100644 kvm-monitor-only-run-coroutine-commands-in-qemu_aio_cont.patch delete mode 100644 kvm-nbd-server-Fix-race-in-draining-the-export.patch delete mode 100644 kvm-nbd-server-avoid-per-NBDRequest-nbd_client_get-put.patch delete mode 100644 kvm-nbd-server-introduce-NBDClient-lock-to-protect-field.patch delete mode 100644 kvm-nbd-server-only-traverse-NBDExport-clients-from-main.patch delete mode 100644 kvm-pc-q35-set-SMBIOS-entry-point-type-to-auto-by-defaul.patch delete mode 100644 kvm-pc-smbios-fixup-manufacturer-product-version-to-matc.patch delete mode 100644 kvm-qdev-add-IOThreadVirtQueueMappingList-property-type.patch delete mode 100644 kvm-qdev-properties-alias-all-object-class-properties.patch delete mode 100644 kvm-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch delete mode 100644 kvm-s390x-pci-avoid-double-enable-disable-of-aif.patch delete mode 100644 kvm-s390x-pci-drive-ISM-reset-from-subsystem-reset.patch delete mode 100644 kvm-s390x-pci-refresh-fh-before-disabling-aif.patch delete mode 100644 kvm-scsi-Await-request-purging.patch delete mode 100644 kvm-scsi-assert-that-callbacks-run-in-the-correct-AioCon.patch delete mode 100644 kvm-scsi-don-t-lock-AioContext-in-I-O-code-path.patch delete mode 100644 kvm-scsi-only-access-SCSIDevice-requests-from-one-thread.patch delete mode 100644 kvm-scsi-remove-AioContext-locking.patch delete mode 100644 kvm-scsi-remove-outdated-AioContext-lock-comment.patch delete mode 100644 kvm-smbios-add-smbios_add_usr_blob_size-helper.patch delete mode 100644 kvm-smbios-avoid-mangling-user-provided-tables.patch delete mode 100644 kvm-smbios-build-legacy-mode-code-only-for-pc-machine.patch delete mode 100644 kvm-smbios-cleanup-smbios_get_tables-from-legacy-handlin.patch delete mode 100644 kvm-smbios-clear-smbios_type4_count-before-building-tabl.patch delete mode 100644 kvm-smbios-don-t-check-type4-structures-in-legacy-mode.patch delete mode 100644 kvm-smbios-error-out-when-building-type-4-table-is-not-p.patch delete mode 100644 kvm-smbios-extend-smbios-entry-point-type-with-auto-valu.patch delete mode 100644 kvm-smbios-get-rid-of-global-smbios_ep_type.patch delete mode 100644 kvm-smbios-get-rid-of-smbios_legacy-global.patch delete mode 100644 kvm-smbios-get-rid-of-smbios_smp_sockets-global.patch delete mode 100644 kvm-smbios-handle-errors-consistently.patch delete mode 100644 kvm-smbios-in-case-of-entry-point-is-auto-try-to-build-v.patch delete mode 100644 kvm-smbios-rename-expose-structures-bitmaps-used-by-both.patch delete mode 100644 kvm-string-output-visitor-Fix-pseudo-struct-handling.patch delete mode 100644 kvm-string-output-visitor-show-structs-as-omitted.patch delete mode 100644 kvm-target-s390x-kvm-pv-Provide-some-more-useful-informa.patch delete mode 100644 kvm-tests-remove-aio_context_acquire-tests.patch delete mode 100644 kvm-tests-unit-Bump-test-replication-timeout-to-60-secon.patch delete mode 100644 kvm-ui-clipboard-add-asserts-for-update-and-request.patch delete mode 100644 kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch delete mode 100644 kvm-util-char_dev-Add-open_cdev.patch delete mode 100644 kvm-vfio-Introduce-a-helper-function-to-initialize-VFIOD.patch delete mode 100644 kvm-vfio-Introduce-base-object-for-VFIOContainer-and-tar.patch delete mode 100644 kvm-vfio-Make-VFIOContainerBase-poiner-parameter-const-i.patch delete mode 100644 kvm-vfio-ap-Allow-the-selection-of-a-given-iommu-backend.patch delete mode 100644 kvm-vfio-ap-Make-vfio-cdev-pre-openable-by-passing-a-fil.patch delete mode 100644 kvm-vfio-ap-Move-VFIODevice-initializations-in-vfio_ap_i.patch delete mode 100644 kvm-vfio-ccw-Allow-the-selection-of-a-given-iommu-backen.patch delete mode 100644 kvm-vfio-ccw-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch delete mode 100644 kvm-vfio-ccw-Move-VFIODevice-initializations-in-vfio_ccw.patch delete mode 100644 kvm-vfio-common-Introduce-vfio_container_init-destroy-he.patch delete mode 100644 kvm-vfio-common-Move-giommu_list-in-base-container.patch delete mode 100644 kvm-vfio-common-return-early-if-space-isn-t-empty.patch delete mode 100644 kvm-vfio-container-Convert-functions-to-base-container.patch delete mode 100644 kvm-vfio-container-Implement-attach-detach_device.patch delete mode 100644 kvm-vfio-container-Initialize-VFIOIOMMUOps-under-vfio_in.patch delete mode 100644 kvm-vfio-container-Intoduce-a-new-VFIOIOMMUClass-setup-h.patch delete mode 100644 kvm-vfio-container-Introduce-a-VFIOIOMMU-QOM-interface.patch delete mode 100644 kvm-vfio-container-Introduce-a-VFIOIOMMU-legacy-QOM-inte.patch delete mode 100644 kvm-vfio-container-Introduce-a-empty-VFIOIOMMUOps.patch delete mode 100644 kvm-vfio-container-Introduce-vfio_legacy_setup-for-furth.patch delete mode 100644 kvm-vfio-container-Move-dirty_pgsizes-and-max_dirty_bitm.patch delete mode 100644 kvm-vfio-container-Move-iova_ranges-to-base-container.patch delete mode 100644 kvm-vfio-container-Move-listener-to-base-container.patch delete mode 100644 kvm-vfio-container-Move-per-container-device-list-in-bas.patch delete mode 100644 kvm-vfio-container-Move-pgsizes-and-dma_max_mappings-to-.patch delete mode 100644 kvm-vfio-container-Move-space-field-to-base-container.patch delete mode 100644 kvm-vfio-container-Move-vrdl_list-to-base-container.patch delete mode 100644 kvm-vfio-container-Rename-vfio_init_container-to-vfio_se.patch delete mode 100644 kvm-vfio-container-Replace-basename-with-g_path_get_base.patch delete mode 100644 kvm-vfio-container-Switch-to-IOMMU-BE-set_dirty_page_tra.patch delete mode 100644 kvm-vfio-container-Switch-to-dma_map-unmap-API.patch delete mode 100644 kvm-vfio-iommufd-Add-support-for-iova_ranges-and-pgsizes.patch delete mode 100644 kvm-vfio-iommufd-Enable-pci-hot-reset-through-iommufd-cd.patch delete mode 100644 kvm-vfio-iommufd-Implement-the-iommufd-backend.patch delete mode 100644 kvm-vfio-iommufd-Introduce-a-VFIOIOMMU-iommufd-QOM-inter.patch delete mode 100644 kvm-vfio-iommufd-Relax-assert-check-for-iommufd-backend.patch delete mode 100644 kvm-vfio-iommufd-Remove-CONFIG_IOMMUFD-usage.patch delete mode 100644 kvm-vfio-iommufd-Remove-the-use-of-stat-to-check-file-ex.patch delete mode 100644 kvm-vfio-migration-Add-helper-function-to-set-state-or-r.patch delete mode 100644 kvm-vfio-pci-Allow-the-selection-of-a-given-iommu-backen.patch delete mode 100644 kvm-vfio-pci-Clear-MSI-X-IRQ-index-always.patch delete mode 100644 kvm-vfio-pci-Extract-out-a-helper-vfio_pci_get_pci_hot_r.patch delete mode 100644 kvm-vfio-pci-Introduce-a-vfio-pci-hot-reset-interface.patch delete mode 100644 kvm-vfio-pci-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch delete mode 100644 kvm-vfio-pci-Move-VFIODevice-initializations-in-vfio_ins.patch delete mode 100644 kvm-vfio-platform-Allow-the-selection-of-a-given-iommu-b.patch delete mode 100644 kvm-vfio-platform-Make-vfio-cdev-pre-openable-by-passing.patch delete mode 100644 kvm-vfio-platform-Move-VFIODevice-initializations-in-vfi.patch delete mode 100644 kvm-vfio-spapr-Extend-VFIOIOMMUOps-with-a-release-handle.patch delete mode 100644 kvm-vfio-spapr-Introduce-a-sPAPR-VFIOIOMMU-QOM-interface.patch delete mode 100644 kvm-vfio-spapr-Introduce-spapr-backend-and-target-interf.patch delete mode 100644 kvm-vfio-spapr-Move-hostwin_list-into-spapr-container.patch delete mode 100644 kvm-vfio-spapr-Move-prereg_listener-into-spapr-container.patch delete mode 100644 kvm-vfio-spapr-Only-compile-sPAPR-IOMMU-support-when-nee.patch delete mode 100644 kvm-vfio-spapr-switch-to-spapr-IOMMU-BE-add-del_section_.patch delete mode 100644 kvm-virtio-Re-enable-notifications-after-drain.patch delete mode 100644 kvm-virtio-blk-Fix-potential-nullpointer-read-access-in-.patch delete mode 100644 kvm-virtio-blk-Use-ioeventfd_attach-in-start_ioeventfd.patch delete mode 100644 kvm-virtio-blk-add-iothread-vq-mapping-parameter.patch delete mode 100644 kvm-virtio-blk-add-lock-to-protect-s-rq.patch delete mode 100644 kvm-virtio-blk-always-set-ioeventfd-during-startup.patch delete mode 100644 kvm-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch delete mode 100644 kvm-virtio-blk-don-t-lock-AioContext-in-the-completion-c.patch delete mode 100644 kvm-virtio-blk-don-t-lock-AioContext-in-the-submission-c.patch delete mode 100644 kvm-virtio-blk-move-dataplane-code-into-virtio-blk.c.patch delete mode 100644 kvm-virtio-blk-rename-dataplane-create-destroy-functions.patch delete mode 100644 kvm-virtio-blk-rename-dataplane-to-ioeventfd.patch delete mode 100644 kvm-virtio-blk-restart-s-rq-reqs-in-vq-AioContexts.patch delete mode 100644 kvm-virtio-blk-tolerate-failure-to-set-BlockBackend-AioC.patch delete mode 100644 kvm-virtio-gpu-block-migration-of-VMs-with-blob-true.patch delete mode 100644 kvm-virtio-mem-default-enable-dynamic-memslots.patch delete mode 100644 kvm-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch delete mode 100644 kvm-virtio-scsi-don-t-lock-AioContext-around-virtio_queu.patch delete mode 100644 kvm-virtio-scsi-replace-AioContext-lock-with-tmf_bh_lock.patch delete mode 100644 kvm-x86-rhel-9.2.0-machine-type-compat-fix.patch diff --git a/.gitignore b/.gitignore index 184161a..2421a3f 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ /qemu-8.0.0.tar.xz /qemu-8.1.0.tar.xz /qemu-8.2.0.tar.xz +/qemu-9.0.0.tar.xz diff --git a/0004-Initial-redhat-build.patch b/0004-Initial-redhat-build.patch index a63b5c3..49991a2 100644 --- a/0004-Initial-redhat-build.patch +++ b/0004-Initial-redhat-build.patch @@ -1,4 +1,4 @@ -From faae70a870156f86a5cf55ca967b15d7612941ff Mon Sep 17 00:00:00 2001 +From ea7dff3dbf979d7d8a85a16cf5187235143e1048 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 26 May 2021 10:56:02 +0200 Subject: Initial redhat build @@ -13,7 +13,7 @@ several issues are fixed in QEMU tree: We disable make check due to issues with some of the tests. -This rebase is based on qemu-kvm-8.1.0-5.el9 +This rebase is based on qemu-kvm-8.2.0-11.el9 Signed-off-by: Miroslav Rezanina -- @@ -83,6 +83,12 @@ Rebase changes (8.2.0): - Added --disable-plugins configure option - Fixing frh.py strings +Rebase notes (9.0.0): +- Fixed qemu-kvm binary location change +- Remove hppa-firmware64.img +- Package stp files for utilities +- Download subprojects on local build + Merged patches (6.0.0): - 605758c902 Limit build on Power to qemu-img and qemu-ga only @@ -193,14 +199,17 @@ Merged patches (8.1.0): Merged patches (8.2.0): - cd9efa221d Enable qemu-kvm-device-usb-redirec for aarch64 +Merged patches (9.0.0 rc0): +- 25de053dbf spec: Enable zstd + Signed-off-by: Miroslav Rezanina --- - .distro/Makefile | 100 + + .distro/Makefile | 101 + .distro/Makefile.common | 42 + .distro/README.tests | 39 + .distro/modules-load.conf | 4 + .distro/qemu-guest-agent.service | 1 - - .distro/qemu-kvm.spec.template | 4909 +++++++++++++++++++++++ + .distro/qemu-kvm.spec.template | 5170 +++++++++++++++++++++++ .distro/rpminspect.yaml | 6 +- .distro/scripts/extract_build_cmd.py | 12 + .distro/scripts/frh.py | 4 +- @@ -211,7 +220,7 @@ Signed-off-by: Miroslav Rezanina scripts/systemtap/conf.d/qemu_kvm.conf | 4 + scripts/systemtap/script.d/qemu_kvm.stp | 1 + ui/vnc-auth-sasl.c | 2 +- - 16 files changed, 5168 insertions(+), 6 deletions(-) + 16 files changed, 5430 insertions(+), 6 deletions(-) create mode 100644 .distro/Makefile create mode 100644 .distro/Makefile.common create mode 100644 .distro/README.tests diff --git a/0005-Enable-disable-devices-for-RHEL.patch b/0005-Enable-disable-devices-for-RHEL.patch index 97c53b4..61e84a1 100644 --- a/0005-Enable-disable-devices-for-RHEL.patch +++ b/0005-Enable-disable-devices-for-RHEL.patch @@ -1,4 +1,4 @@ -From 048067b4618ba1fa7c8c517185d4cd3a675eba72 Mon Sep 17 00:00:00 2001 +From 780c39975b059deaee106775b6e3a240155acea3 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 7 Dec 2022 03:05:48 -0500 Subject: Enable/disable devices for RHEL @@ -47,6 +47,12 @@ Rebase notes (8.2.0): - Disable new neoverse-v2 - Removed CONFIG_OPENGL from x86_64 config file +Rebase notes (9.0.0 rc0): +- Split CONFIG_IDE_QDEV to CONFIG_IDE_DEV and CONFIG_IDE_BUS (upstream change) + +Rebase notes (9.0.0 rc1): +- Do not compile armv7 cpu types + Merged patches (6.1.0): - c51bf45304 Remove SPICE and QXL from x86_64-rh-devices.mak - 02fc745601 aarch64-rh-devices: add CONFIG_PVPANIC_PCI @@ -74,36 +80,41 @@ Merged patches (8.1.0): Merged patches (8.2.0): - b29f66431f Enable igb on x86_64 + +Merged patches (9.0.0 rc0): +- 3889ede5d9 Compile IOMMUFD on x86_64 +- 0beb18451f Compile IOMMUFD on s390x +- 2b4b13f70d Compile IOMMUFD object on aarch64 --- .distro/qemu-kvm.spec.template | 18 +-- - .../aarch64-softmmu/aarch64-rh-devices.mak | 41 +++++++ + .../aarch64-softmmu/aarch64-rh-devices.mak | 42 +++++++ .../ppc64-softmmu/ppc64-rh-devices.mak | 37 ++++++ configs/devices/rh-virtio.mak | 10 ++ - .../s390x-softmmu/s390x-rh-devices.mak | 18 +++ - .../x86_64-softmmu/x86_64-rh-devices.mak | 110 ++++++++++++++++++ + .../s390x-softmmu/s390x-rh-devices.mak | 19 +++ + .../x86_64-softmmu/x86_64-rh-devices.mak | 112 ++++++++++++++++++ hw/arm/virt.c | 2 + hw/block/fdc.c | 10 ++ hw/cpu/meson.build | 3 +- hw/cxl/meson.build | 3 +- hw/display/cirrus_vga.c | 4 + hw/ide/piix.c | 5 +- - hw/ide/qdev.c | 9 ++ hw/input/pckbd.c | 2 + hw/net/e1000.c | 2 + hw/ppc/spapr_cpu_core.c | 2 + hw/usb/meson.build | 2 +- - hw/virtio/meson.build | 5 +- + hw/virtio/meson.build | 6 +- target/arm/arm-qmp-cmds.c | 2 + target/arm/cpu.c | 4 + target/arm/cpu.h | 3 + target/arm/cpu64.c | 12 +- target/arm/tcg/cpu32.c | 2 + target/arm/tcg/cpu64.c | 8 ++ + target/arm/tcg/meson.build | 4 +- target/ppc/cpu-models.c | 9 ++ target/s390x/cpu_models_sysemu.c | 3 + target/s390x/kvm/kvm.c | 8 ++ tests/qtest/arm-cpu-features.c | 4 + - 28 files changed, 323 insertions(+), 15 deletions(-) + 28 files changed, 321 insertions(+), 17 deletions(-) create mode 100644 configs/devices/aarch64-softmmu/aarch64-rh-devices.mak create mode 100644 configs/devices/ppc64-softmmu/ppc64-rh-devices.mak create mode 100644 configs/devices/rh-virtio.mak @@ -112,10 +123,10 @@ Merged patches (8.2.0): diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak new file mode 100644 -index 0000000000..aec1831199 +index 0000000000..b0191d3c69 --- /dev/null +++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak -@@ -0,0 +1,41 @@ +@@ -0,0 +1,42 @@ +include ../rh-virtio.mak + +CONFIG_ARM_GIC_KVM=y @@ -157,6 +168,7 @@ index 0000000000..aec1831199 +CONFIG_VHOST_VSOCK=y +CONFIG_VHOST_USER_VSOCK=y +CONFIG_VHOST_USER_FS=y ++CONFIG_IOMMUFD=y diff --git a/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak new file mode 100644 index 0000000000..dbb7d30829 @@ -218,10 +230,10 @@ index 0000000000..94ede1b5f6 +CONFIG_VIRTIO_SERIAL=y diff --git a/configs/devices/s390x-softmmu/s390x-rh-devices.mak b/configs/devices/s390x-softmmu/s390x-rh-devices.mak new file mode 100644 -index 0000000000..69a799adbd +index 0000000000..24cf6dbd03 --- /dev/null +++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak -@@ -0,0 +1,18 @@ +@@ -0,0 +1,19 @@ +include ../rh-virtio.mak + +CONFIG_PCI=y @@ -240,12 +252,13 @@ index 0000000000..69a799adbd +CONFIG_VHOST_VSOCK=y +CONFIG_VHOST_USER_VSOCK=y +CONFIG_VHOST_USER_FS=y ++CONFIG_IOMMUFD=y diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak new file mode 100644 -index 0000000000..ce5be73633 +index 0000000000..d60ff1bcfc --- /dev/null +++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -@@ -0,0 +1,110 @@ +@@ -0,0 +1,112 @@ +include ../rh-virtio.mak + +CONFIG_ACPI=y @@ -283,7 +296,8 @@ index 0000000000..ce5be73633 +CONFIG_IDE_CORE=y +CONFIG_IDE_PCI=y +CONFIG_IDE_PIIX=y -+CONFIG_IDE_QDEV=y ++CONFIG_IDE_DEV=y ++CONFIG_IDE_BUS=y +CONFIG_IGB_PCI_EXPRESS=y +CONFIG_IOAPIC=y +CONFIG_IOH3420=y @@ -356,28 +370,29 @@ index 0000000000..ce5be73633 +CONFIG_VHOST_VSOCK=y +CONFIG_VHOST_USER_VSOCK=y +CONFIG_VHOST_USER_FS=y ++CONFIG_IOMMUFD=y diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index be2856c018..af9ea4dd1c 100644 +index a9a913aead..6c6d155002 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c -@@ -205,6 +205,7 @@ static const int a15irqmap[] = { - }; - - static const char *valid_cpus[] = { +@@ -2954,6 +2954,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + MachineClass *mc = MACHINE_CLASS(oc); + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); + static const char * const valid_cpu_types[] = { +#if 0 /* Disabled for Red Hat Enterprise Linux */ #ifdef CONFIG_TCG - ARM_CPU_TYPE_NAME("cortex-a7"), - ARM_CPU_TYPE_NAME("cortex-a15"), -@@ -219,6 +220,7 @@ static const char *valid_cpus[] = { - ARM_CPU_TYPE_NAME("neoverse-n2"), - #endif - ARM_CPU_TYPE_NAME("cortex-a53"), + ARM_CPU_TYPE_NAME("cortex-a7"), + ARM_CPU_TYPE_NAME("cortex-a15"), +@@ -2971,6 +2972,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + #endif /* CONFIG_TCG */ + #ifdef TARGET_AARCH64 + ARM_CPU_TYPE_NAME("cortex-a53"), +#endif /* disabled for RHEL */ - ARM_CPU_TYPE_NAME("cortex-a57"), - ARM_CPU_TYPE_NAME("host"), - ARM_CPU_TYPE_NAME("max"), + ARM_CPU_TYPE_NAME("cortex-a57"), + #if defined(CONFIG_KVM) || defined(CONFIG_HVF) + ARM_CPU_TYPE_NAME("host"), diff --git a/hw/block/fdc.c b/hw/block/fdc.c -index d7cc4d3ec1..12d0a60905 100644 +index 6dd94e98bc..a05757fc9a 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -49,6 +49,8 @@ @@ -405,7 +420,7 @@ index d7cc4d3ec1..12d0a60905 100644 error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'"); return; diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build -index 6d319947ca..91962fd863 100644 +index 38cdcfbe57..e588ecfd42 100644 --- a/hw/cpu/meson.build +++ b/hw/cpu/meson.build @@ -1,4 +1,5 @@ @@ -416,7 +431,7 @@ index 6d319947ca..91962fd863 100644 system_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c')) system_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c')) diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build -index ea0aebf6e3..6878f06974 100644 +index 3e375f61a9..613adb3ebb 100644 --- a/hw/cxl/meson.build +++ b/hw/cxl/meson.build @@ -6,7 +6,8 @@ system_ss.add(when: 'CONFIG_CXL', @@ -430,7 +445,7 @@ index ea0aebf6e3..6878f06974 100644 if_false: files( 'cxl-host-stubs.c', diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c -index b80f98b6c4..0370cf8a64 100644 +index 150883a971..497365bd80 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -36,6 +36,7 @@ @@ -452,10 +467,10 @@ index b80f98b6c4..0370cf8a64 100644 * Follow real hardware, cirrus card emulated has 4 MB video memory. * Also accept 8 MB/16 MB for backward compatibility. diff --git a/hw/ide/piix.c b/hw/ide/piix.c -index 4e5e12935f..03ca06bb17 100644 +index 80efc633d3..9cb82b8eea 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c -@@ -190,7 +190,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data) +@@ -191,7 +191,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1; k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); @@ -465,7 +480,7 @@ index 4e5e12935f..03ca06bb17 100644 } static const TypeInfo piix3_ide_info = { -@@ -214,6 +215,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data) +@@ -215,6 +216,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data) k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); dc->hotpluggable = false; @@ -474,57 +489,11 @@ index 4e5e12935f..03ca06bb17 100644 } static const TypeInfo piix4_ide_info = { -diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c -index 1b3b4da01d..454bfa5783 100644 ---- a/hw/ide/qdev.c -+++ b/hw/ide/qdev.c -@@ -283,10 +283,13 @@ static void ide_cd_realize(IDEDevice *dev, Error **errp) - ide_dev_initfn(dev, IDE_CD, errp); - } - -+/* Disabled for Red Hat Enterprise Linux */ -+#if 0 - static void ide_cf_realize(IDEDevice *dev, Error **errp) - { - ide_dev_initfn(dev, IDE_CFATA, errp); - } -+#endif - - #define DEFINE_IDE_DEV_PROPERTIES() \ - DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \ -@@ -346,6 +349,8 @@ static const TypeInfo ide_cd_info = { - .class_init = ide_cd_class_init, - }; - -+/* Disabled for Red Hat Enterprise Linux */ -+#if 0 - static Property ide_cf_properties[] = { - DEFINE_IDE_DEV_PROPERTIES(), - DEFINE_BLOCK_CHS_PROPERTIES(IDEDrive, dev.conf), -@@ -371,6 +376,7 @@ static const TypeInfo ide_cf_info = { - .instance_size = sizeof(IDEDrive), - .class_init = ide_cf_class_init, - }; -+#endif - - static void ide_device_class_init(ObjectClass *klass, void *data) - { -@@ -396,7 +402,10 @@ static void ide_register_types(void) - type_register_static(&ide_bus_info); - type_register_static(&ide_hd_info); - type_register_static(&ide_cd_info); -+/* Disabled for Red Hat Enterprise Linux */ -+#if 0 - type_register_static(&ide_cf_info); -+#endif - type_register_static(&ide_device_type_info); - } - diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c -index b92b63bedc..3b6235dde6 100644 +index 74f10b640f..2e85ecf476 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c -@@ -957,6 +957,8 @@ static void i8042_class_initfn(ObjectClass *klass, void *data) +@@ -952,6 +952,8 @@ static void i8042_class_initfn(ObjectClass *klass, void *data) dc->vmsd = &vmstate_kbd_isa; adevc->build_dev_aml = i8042_build_aml; set_bit(DEVICE_CATEGORY_INPUT, dc->categories); @@ -534,7 +503,7 @@ index b92b63bedc..3b6235dde6 100644 static const TypeInfo i8042_info = { diff --git a/hw/net/e1000.c b/hw/net/e1000.c -index 8ffe1077f1..b3dfeeca4f 100644 +index 43f3a4a701..267f182883 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -1746,6 +1746,7 @@ static const E1000Info e1000_devices[] = { @@ -554,10 +523,10 @@ index 8ffe1077f1..b3dfeeca4f 100644 static void e1000_register_types(void) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c -index 91fae56573..33e0c8724c 100644 +index e7c9edd033..3b0a47a28c 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c -@@ -386,10 +386,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = { +@@ -389,10 +389,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = { .instance_size = sizeof(SpaprCpuCore), .class_size = sizeof(SpaprCpuCoreClass), }, @@ -565,16 +534,16 @@ index 91fae56573..33e0c8724c 100644 DEFINE_SPAPR_CPU_CORE_TYPE("970_v2.2"), DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.0"), DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.1"), - DEFINE_SPAPR_CPU_CORE_TYPE("power5+_v2.1"), + DEFINE_SPAPR_CPU_CORE_TYPE("power5p_v2.1"), +#endif DEFINE_SPAPR_CPU_CORE_TYPE("power7_v2.3"), - DEFINE_SPAPR_CPU_CORE_TYPE("power7+_v2.1"), + DEFINE_SPAPR_CPU_CORE_TYPE("power7p_v2.1"), DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"), diff --git a/hw/usb/meson.build b/hw/usb/meson.build -index e94149ebde..4a8adbf3dc 100644 +index aac3bb35f2..5411ff35df 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build -@@ -52,7 +52,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader +@@ -55,7 +55,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader if cacard.found() usbsmartcard_ss = ss.source_set() usbsmartcard_ss.add(when: 'CONFIG_USB_SMARTCARD', @@ -584,26 +553,34 @@ index e94149ebde..4a8adbf3dc 100644 endif diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build -index c0055a7832..12e1d6c67e 100644 +index d7f18c96e6..aaabbb8b0b 100644 --- a/hw/virtio/meson.build +++ b/hw/virtio/meson.build -@@ -17,8 +17,9 @@ if have_vhost - if have_vhost_user - # fixme - this really should be generic - specific_virtio_ss.add(files('vhost-user.c')) +@@ -20,7 +20,8 @@ if have_vhost + system_virtio_ss.add(files('vhost-user-base.c')) + + # MMIO Stubs - system_virtio_ss.add(files('vhost-user-device.c')) -- system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c')) +# Disabled for 8.2.0 rebase for RHEL 9.4.0 +# system_virtio_ss.add(files('vhost-user-device.c')) + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_GPIO', if_true: files('vhost-user-gpio.c')) + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: files('vhost-user-i2c.c')) + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c')) +@@ -28,7 +29,8 @@ if have_vhost + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c')) + + # PCI Stubs +- system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c')) ++# Disabled for 8.2.0 rebase for RHEL 9.4.0 +# system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c')) - endif - if have_vhost_vdpa - system_virtio_ss.add(files('vhost-vdpa.c')) + system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_GPIO'], + if_true: files('vhost-user-gpio-pci.c')) + system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_I2C'], diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c -index b53d5efe13..64989a02d1 100644 +index 3cc8cc738b..6f21fea1f5 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c -@@ -231,6 +231,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, +@@ -223,6 +223,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, static void arm_cpu_add_definition(gpointer data, gpointer user_data) { ObjectClass *oc = data; @@ -611,23 +588,23 @@ index b53d5efe13..64989a02d1 100644 CpuDefinitionInfoList **cpu_list = user_data; CpuDefinitionInfo *info; const char *typename; -@@ -240,6 +241,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data) - info->name = g_strndup(typename, - strlen(typename) - strlen("-" TYPE_ARM_CPU)); +@@ -231,6 +232,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data) + info = g_malloc0(sizeof(*info)); + info->name = cpu_model_from_type(typename); info->q_typename = g_strdup(typename); + info->deprecated = !!cc->deprecation_note; QAPI_LIST_PREPEND(*cpu_list, info); } diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index efb22a87f9..a32521ada9 100644 +index ab8d007a86..e5dce20f19 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c -@@ -2524,6 +2524,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data) +@@ -2546,6 +2546,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data) acc->info = data; cc->gdb_core_xml_file = "arm-core.xml"; -+ ++ + if (acc->info->deprecation_note) { + cc->deprecation_note = acc->info->deprecation_note; + } @@ -635,10 +612,10 @@ index efb22a87f9..a32521ada9 100644 void arm_cpu_register(const ARMCPUInfo *info) diff --git a/target/arm/cpu.h b/target/arm/cpu.h -index a0282e0d28..7e0f0dfea7 100644 +index bc0c84873f..e9472c8bb8 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h -@@ -34,6 +34,8 @@ +@@ -37,6 +37,8 @@ #define KVM_HAVE_MCE_INJECTION 1 #endif @@ -647,7 +624,7 @@ index a0282e0d28..7e0f0dfea7 100644 #define EXCP_UDEF 1 /* undefined instruction */ #define EXCP_SWI 2 /* software interrupt */ #define EXCP_PREFETCH_ABORT 3 -@@ -1120,6 +1122,7 @@ typedef struct ARMCPUInfo { +@@ -1092,6 +1094,7 @@ typedef struct ARMCPUInfo { const char *name; void (*initfn)(Object *obj); void (*class_init)(ObjectClass *oc, void *data); @@ -656,7 +633,7 @@ index a0282e0d28..7e0f0dfea7 100644 /** diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 1e9c6c85ae..10be900803 100644 +index 985b1efe16..46a4e80171 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -648,6 +648,7 @@ static void aarch64_a57_initfn(Object *obj) @@ -688,7 +665,7 @@ index 1e9c6c85ae..10be900803 100644 { .name = "max", .initfn = aarch64_max_initfn }, #if defined(CONFIG_KVM) || defined(CONFIG_HVF) { .name = "host", .initfn = aarch64_host_initfn }, -@@ -815,8 +820,13 @@ static void aarch64_cpu_instance_init(Object *obj) +@@ -814,8 +819,13 @@ static void aarch64_cpu_instance_init(Object *obj) static void cpu_register_class_init(ObjectClass *oc, void *data) { ARMCPUClass *acc = ARM_CPU_CLASS(oc); @@ -703,24 +680,24 @@ index 1e9c6c85ae..10be900803 100644 void aarch64_cpu_register(const ARMCPUInfo *info) diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c -index d9e0e2a4dd..c5c639a6ea 100644 +index de8f2be941..8896295ae3 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c -@@ -98,6 +98,7 @@ void aa32_max_features(ARMCPU *cpu) +@@ -92,6 +92,7 @@ void aa32_max_features(ARMCPU *cpu) + cpu->isar.id_dfr1 = t; + } + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ /* CPU models. These are not needed for the AArch64 linux-user build. */ #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - #if !defined(CONFIG_USER_ONLY) - static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) - { -@@ -1189,3 +1190,4 @@ static void arm_tcg_cpu_register_types(void) +@@ -1037,3 +1038,4 @@ static void arm_tcg_cpu_register_types(void) type_init(arm_tcg_cpu_register_types) #endif /* !CONFIG_USER_ONLY || !TARGET_AARCH64 */ +#endif /* disabled for RHEL */ diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c -index fcda99e158..bd5a993ff8 100644 +index 9f7a9f3d2c..7ec6851c9c 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -29,6 +29,7 @@ @@ -755,7 +732,7 @@ index fcda99e158..bd5a993ff8 100644 /* * -cpu max: a CPU with as many features enabled as our emulation supports. -@@ -1259,6 +1263,7 @@ void aarch64_max_tcg_initfn(Object *obj) +@@ -1271,6 +1275,7 @@ void aarch64_max_tcg_initfn(Object *obj) qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property); } @@ -763,7 +740,7 @@ index fcda99e158..bd5a993ff8 100644 static const ARMCPUInfo aarch64_cpus[] = { { .name = "cortex-a35", .initfn = aarch64_a35_initfn }, { .name = "cortex-a55", .initfn = aarch64_a55_initfn }, -@@ -1270,14 +1275,17 @@ static const ARMCPUInfo aarch64_cpus[] = { +@@ -1282,14 +1287,17 @@ static const ARMCPUInfo aarch64_cpus[] = { { .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn }, { .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn }, }; @@ -781,8 +758,20 @@ index fcda99e158..bd5a993ff8 100644 } type_init(aarch64_cpu_register_types) +diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build +index 3b1a9f0fc5..6898b4de6f 100644 +--- a/target/arm/tcg/meson.build ++++ b/target/arm/tcg/meson.build +@@ -56,5 +56,5 @@ arm_system_ss.add(files( + 'psci.c', + )) + +-arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c')) +-arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c')) ++#arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c')) ++#arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c')) diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c -index 7dbb47de64..69fddb05bc 100644 +index f2301b43f7..f77ebfcc81 100644 --- a/target/ppc/cpu-models.c +++ b/target/ppc/cpu-models.c @@ -66,6 +66,7 @@ @@ -806,13 +795,13 @@ index 7dbb47de64..69fddb05bc 100644 POWERPC_DEF("970fx_v1.0", CPU_POWERPC_970FX_v10, 970, @@ -718,6 +721,7 @@ "PowerPC 970MP v1.1") - POWERPC_DEF("power5+_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P, + POWERPC_DEF("power5p_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P, "POWER5+ v2.1") +#endif POWERPC_DEF("power7_v2.3", CPU_POWERPC_POWER7_v23, POWER7, "POWER7 v2.3") - POWERPC_DEF("power7+_v2.1", CPU_POWERPC_POWER7P_v21, POWER7, -@@ -898,12 +902,15 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { + POWERPC_DEF("power7p_v2.1", CPU_POWERPC_POWER7P_v21, POWER7, +@@ -894,13 +898,16 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { { "7447a", "7447a_v1.2" }, { "7457a", "7457a_v1.2" }, { "apollo7pm", "7457a_v1.0" }, @@ -822,13 +811,14 @@ index 7dbb47de64..69fddb05bc 100644 { "970", "970_v2.2" }, { "970fx", "970fx_v3.1" }, { "970mp", "970mp_v1.1" }, - { "power5+", "power5+_v2.1" }, + { "power5+", "power5p_v2.1" }, + { "power5+_v2.1", "power5p_v2.1" }, { "power5gs", "power5+_v2.1" }, +#endif { "power7", "power7_v2.3" }, - { "power7+", "power7+_v2.1" }, - { "power8e", "power8e_v2.1" }, -@@ -913,12 +920,14 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { + { "power7+", "power7p_v2.1" }, + { "power7+_v2.1", "power7p_v2.1" }, +@@ -911,12 +918,14 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { { "power10", "power10_v2.0" }, #endif @@ -844,10 +834,10 @@ index 7dbb47de64..69fddb05bc 100644 { NULL, NULL } }; diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c -index 63981bf36b..87a4480c05 100644 +index 2d99218069..0728bfcc20 100644 --- a/target/s390x/cpu_models_sysemu.c +++ b/target/s390x/cpu_models_sysemu.c -@@ -35,6 +35,9 @@ static void check_unavailable_features(const S390CPUModel *max_model, +@@ -34,6 +34,9 @@ static void check_unavailable_features(const S390CPUModel *max_model, (max_model->def->gen == model->def->gen && max_model->def->ec_ga < model->def->ec_ga)) { list_add_feat("type", unavailable); @@ -858,10 +848,10 @@ index 63981bf36b..87a4480c05 100644 /* detect missing features if any to properly report them */ diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c -index 33ab3551f4..912e493951 100644 +index 4ce809c5d4..55fb4855b1 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c -@@ -2567,6 +2567,14 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp) +@@ -2565,6 +2565,14 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp) error_setg(errp, "KVM doesn't support CPU models"); return; } @@ -877,10 +867,10 @@ index 33ab3551f4..912e493951 100644 prop.ibc = s390_ibc_from_cpu_model(model); /* configure cpu features indicated via STFL(e) */ diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c -index a8a4c668ad..2458cc527c 100644 +index 9d6e6190d5..f822526acb 100644 --- a/tests/qtest/arm-cpu-features.c +++ b/tests/qtest/arm-cpu-features.c -@@ -451,8 +451,10 @@ static void test_query_cpu_model_expansion(const void *data) +@@ -452,8 +452,10 @@ static void test_query_cpu_model_expansion(const void *data) assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL); /* Test expected feature presence/absence for some cpu types */ @@ -891,7 +881,7 @@ index a8a4c668ad..2458cc527c 100644 /* Enabling and disabling pmu should always work. */ assert_has_feature_enabled(qts, "max", "pmu"); -@@ -469,6 +471,7 @@ static void test_query_cpu_model_expansion(const void *data) +@@ -470,6 +472,7 @@ static void test_query_cpu_model_expansion(const void *data) assert_has_feature_enabled(qts, "cortex-a57", "pmu"); assert_has_feature_enabled(qts, "cortex-a57", "aarch64"); @@ -899,7 +889,7 @@ index a8a4c668ad..2458cc527c 100644 assert_has_feature_enabled(qts, "a64fx", "pmu"); assert_has_feature_enabled(qts, "a64fx", "aarch64"); /* -@@ -481,6 +484,7 @@ static void test_query_cpu_model_expansion(const void *data) +@@ -482,6 +485,7 @@ static void test_query_cpu_model_expansion(const void *data) "{ 'sve384': true }"); assert_error(qts, "a64fx", "cannot enable sve640", "{ 'sve640': true }"); diff --git a/0006-Machine-type-related-general-changes.patch b/0006-Machine-type-related-general-changes.patch index 4a4c6fb..e0c3795 100644 --- a/0006-Machine-type-related-general-changes.patch +++ b/0006-Machine-type-related-general-changes.patch @@ -1,4 +1,4 @@ -From d9ff466c980d219ebf230ea24becce294c196f1f Mon Sep 17 00:00:00 2001 +From 8e6a30073f9c1a5d6294b2d16556522453e227e7 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Fri, 11 Jan 2019 09:54:45 +0100 Subject: Machine type related general changes @@ -26,6 +26,12 @@ Rebase notes (7.1.0): Rebase notes (8.1.0): - Do not modify unused vga-isa.c +Rebase notes (9.0.0 rc0): +- Updated smsbios handling + +Rebase notes (9.0.0 rc4): +- Moving downstream compat changes + Merged patches (6.1.0): - f2fb42a3c6 redhat: add missing entries in hw_compat_rhel_8_4 - 1949ec258e hw/arm/virt: Disable PL011 clock migration through hw_compat_rhel_8_3 @@ -61,24 +67,27 @@ Merged patches (8.1.0): Merged patches (8.2.0): - 4ee284aca9 Add machine types compat bits. (partial) + +Merged patches (9.0.0 rc0): +- 4b8fe42abc virtio-mem: default-enable "dynamic-memslots" --- hw/acpi/piix4.c | 2 +- hw/arm/virt.c | 2 +- - hw/core/machine.c | 267 +++++++++++++++++++++++++++++++++++ - hw/i386/pc_piix.c | 2 + - hw/i386/pc_q35.c | 2 + + hw/core/machine.c | 269 +++++++++++++++++++++++++++++++++++ + hw/i386/fw_cfg.c | 3 +- hw/net/rtl8139.c | 4 +- hw/smbios/smbios.c | 46 +++++- hw/timer/i8254_common.c | 2 +- hw/usb/hcd-xhci-pci.c | 59 ++++++-- hw/usb/hcd-xhci-pci.h | 1 + + hw/virtio/virtio-mem.c | 3 +- include/hw/boards.h | 40 ++++++ - include/hw/firmware/smbios.h | 5 +- + include/hw/firmware/smbios.h | 4 +- include/hw/i386/pc.h | 3 + - 13 files changed, 413 insertions(+), 22 deletions(-) + 13 files changed, 414 insertions(+), 24 deletions(-) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c -index dd523d2e4c..5050c0ba97 100644 +index debe1adb84..e8ddcd716e 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -245,7 +245,7 @@ static bool vmstate_test_migrate_acpi_index(void *opaque, int version_id) @@ -88,28 +97,28 @@ index dd523d2e4c..5050c0ba97 100644 - .minimum_version_id = 3, + .minimum_version_id = 2, .post_load = vmstate_acpi_post_load, - .fields = (VMStateField[]) { + .fields = (const VMStateField[]) { VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState), diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index af9ea4dd1c..62f0f7d4d6 100644 +index 6c6d155002..36e9b4b4e9 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c -@@ -1638,7 +1638,7 @@ static void virt_build_smbios(VirtMachineState *vms) +@@ -1651,7 +1651,7 @@ static void virt_build_smbios(VirtMachineState *vms) smbios_set_defaults("QEMU", product, - vmc->smbios_old_sys_ver ? "1.0" : mc->name, false, -- true, SMBIOS_ENTRY_POINT_TYPE_64); -+ true, NULL, NULL, SMBIOS_ENTRY_POINT_TYPE_64); + vmc->smbios_old_sys_ver ? "1.0" : mc->name, +- true); ++ true, NULL, NULL); /* build the array of physical mem area from base_memmap */ mem_array.address = vms->memmap[VIRT_MEM].base; diff --git a/hw/core/machine.c b/hw/core/machine.c -index 0c17398141..446601ee30 100644 +index 37ede0e7d4..695cb89a46 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c -@@ -57,6 +57,273 @@ GlobalProperty hw_compat_7_2[] = { +@@ -296,6 +296,275 @@ GlobalProperty hw_compat_2_1[] = { }; - const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2); + const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1); +/* + * RHEL only: machine types for previous major releases are deprecated @@ -132,6 +141,8 @@ index 0c17398141..446601ee30 100644 + { "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }, + /* hw_compat_rhel_9_4 from hw_compat_8_1 */ + { "igb", "x-pcie-flr-init", "off" }, ++ /* hw_compat_rhel_9_4 jira RHEL-24045 */ ++ { "virtio-mem", "dynamic-memslots", "off" }, +}; +const size_t hw_compat_rhel_9_4_len = G_N_ELEMENTS(hw_compat_rhel_9_4); + @@ -378,37 +389,25 @@ index 0c17398141..446601ee30 100644 +}; +const size_t hw_compat_rhel_7_6_len = G_N_ELEMENTS(hw_compat_rhel_7_6); + - GlobalProperty hw_compat_7_1[] = { - { "virtio-device", "queue_reset", "false" }, - { "virtio-rng-pci", "vectors", "0" }, -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index eace854335..2a9f465619 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -238,6 +238,8 @@ static void pc_init1(MachineState *machine, - smbios_set_defaults("QEMU", mc->desc, - mc->name, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, -+ pcmc->smbios_stream_product, -+ pcmc->smbios_stream_version, - pcms->smbios_entry_point_type); - } - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 4f3e5412f6..912cb0c0dc 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -206,6 +206,8 @@ static void pc_q35_init(MachineState *machine) - smbios_set_defaults("QEMU", mc->desc, - mc->name, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, -+ pcmc->smbios_stream_product, -+ pcmc->smbios_stream_version, - pcms->smbios_entry_point_type); + MachineState *current_machine; + + static char *machine_get_kernel(Object *obj, Error **errp) +diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c +index d802d2787f..c7aa39a13e 100644 +--- a/hw/i386/fw_cfg.c ++++ b/hw/i386/fw_cfg.c +@@ -64,7 +64,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg, + if (pcmc->smbios_defaults) { + /* These values are guest ABI, do not change */ + smbios_set_defaults("QEMU", mc->desc, mc->name, +- pcmc->smbios_uuid_encoded); ++ pcmc->smbios_uuid_encoded, ++ pcmc->smbios_stream_product, pcmc->smbios_stream_version); } + /* tell smbios about cpuid version and features */ diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index 4af8c66266..7dc12907ab 100644 +index 897c86ec41..2d0db43f49 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -3169,7 +3169,7 @@ static int rtl8139_pre_save(void *opaque) @@ -431,20 +430,21 @@ index 4af8c66266..7dc12907ab 100644 VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State), diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 2a90601ac5..7bde23e59d 100644 +index eed5787b15..68608a3403 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c -@@ -58,6 +58,9 @@ static bool smbios_legacy = true; - static bool smbios_uuid_encoded = true; - /* end: legacy structures & constants for <= 2.0 machines */ +@@ -39,6 +39,10 @@ size_t usr_blobs_len; + static unsigned usr_table_max; + static unsigned usr_table_cnt; +/* Set to true for modern Windows 10 HardwareID-6 compat */ +static bool smbios_type2_required; + - ++ uint8_t *smbios_tables; size_t smbios_tables_len; -@@ -670,7 +673,7 @@ static void smbios_build_type_1_table(void) + unsigned smbios_table_max; +@@ -629,7 +633,7 @@ static void smbios_build_type_1_table(void) static void smbios_build_type_2_table(void) { @@ -453,21 +453,17 @@ index 2a90601ac5..7bde23e59d 100644 SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer); SMBIOS_TABLE_SET_STR(2, product_str, type2.product); -@@ -985,7 +988,10 @@ void smbios_set_cpuid(uint32_t version, uint32_t features) +@@ -1018,16 +1022,52 @@ void smbios_set_default_processor_family(uint16_t processor_family) void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, bool legacy_mode, -- bool uuid_encoded, SmbiosEntryPointType ep_type) + const char *version, +- bool uuid_encoded) + bool uuid_encoded, + const char *stream_product, -+ const char *stream_version, -+ SmbiosEntryPointType ep_type) ++ const char *stream_version) { smbios_have_defaults = true; - smbios_legacy = legacy_mode; -@@ -1006,11 +1012,45 @@ void smbios_set_defaults(const char *manufacturer, const char *product, - g_free(smbios_entries); - } + smbios_uuid_encoded = uuid_encoded; + /* + * If @stream_product & @stream_version are non-NULL, then @@ -494,12 +490,12 @@ index 2a90601ac5..7bde23e59d 100644 + * + * We get 'System Manufacturer' and 'Baseboard Manufacturer' + */ - SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer); - SMBIOS_SET_DEFAULT(type1.product, product); - SMBIOS_SET_DEFAULT(type1.version, version); -+ SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux"); + SMBIOS_SET_DEFAULT(smbios_type1.manufacturer, manufacturer); + SMBIOS_SET_DEFAULT(smbios_type1.product, product); + SMBIOS_SET_DEFAULT(smbios_type1.version, version); ++ SMBIOS_SET_DEFAULT(smbios_type1.family, "Red Hat Enterprise Linux"); + if (stream_version != NULL) { -+ SMBIOS_SET_DEFAULT(type1.sku, stream_version); ++ SMBIOS_SET_DEFAULT(smbios_type1.sku, stream_version); + } SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer); - SMBIOS_SET_DEFAULT(type2.product, product); @@ -513,20 +509,20 @@ index 2a90601ac5..7bde23e59d 100644 SMBIOS_SET_DEFAULT(type3.manufacturer, manufacturer); SMBIOS_SET_DEFAULT(type3.version, version); diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c -index b25da448c8..0331e84398 100644 +index 28fdabc321..bad13ec224 100644 --- a/hw/timer/i8254_common.c +++ b/hw/timer/i8254_common.c @@ -229,7 +229,7 @@ static const VMStateDescription vmstate_pit_common = { .pre_save = pit_dispatch_pre_save, .post_load = pit_dispatch_post_load, - .fields = (VMStateField[]) { + .fields = (const VMStateField[]) { - VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3), + VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), /* qemu-kvm's v2 had 'flags' here */ VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2, vmstate_pit_channel, PITChannelState), VMSTATE_INT64(channels[0].next_transition_time, diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c -index 643d4643e4..529bad9366 100644 +index 4423983308..43b4b71fdf 100644 --- a/hw/usb/hcd-xhci-pci.c +++ b/hw/usb/hcd-xhci-pci.c @@ -104,6 +104,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id) @@ -636,11 +632,26 @@ index 08f70ce97c..1be7527c1b 100644 } XHCIPciState; #endif +diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c +index ffd119ebac..0e2be2219c 100644 +--- a/hw/virtio/virtio-mem.c ++++ b/hw/virtio/virtio-mem.c +@@ -1694,8 +1694,9 @@ static Property virtio_mem_properties[] = { + #endif + DEFINE_PROP_BOOL(VIRTIO_MEM_EARLY_MIGRATION_PROP, VirtIOMEM, + early_migration, true), ++ /* RHEL: default-enable "dynamic-memslots" (jira RHEL-24045) */ + DEFINE_PROP_BOOL(VIRTIO_MEM_DYNAMIC_MEMSLOTS_PROP, VirtIOMEM, +- dynamic_memslots, false), ++ dynamic_memslots, true), + DEFINE_PROP_END_OF_LIST(), + }; + diff --git a/include/hw/boards.h b/include/hw/boards.h -index da85f86efb..4a21eddbf9 100644 +index 8b8f6d5c00..0466f9d0f3 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h -@@ -503,4 +503,44 @@ extern const size_t hw_compat_2_2_len; +@@ -512,4 +512,44 @@ extern const size_t hw_compat_2_2_len; extern GlobalProperty hw_compat_2_1[]; extern const size_t hw_compat_2_1_len; @@ -686,26 +697,25 @@ index da85f86efb..4a21eddbf9 100644 +extern const char *rhel_old_machine_deprecation; #endif diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index 7f3259a630..d24b3ccd32 100644 +index 8d3fb2fb3b..d9d6d7a169 100644 --- a/include/hw/firmware/smbios.h +++ b/include/hw/firmware/smbios.h -@@ -294,7 +294,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp); +@@ -332,7 +332,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp); void smbios_set_cpuid(uint32_t version, uint32_t features); void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, bool legacy_mode, -- bool uuid_encoded, SmbiosEntryPointType ep_type); + const char *version, +- bool uuid_encoded); + bool uuid_encoded, + const char *stream_product, -+ const char *stream_version, -+ SmbiosEntryPointType ep_type); - uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length); ++ const char *stream_version); + void smbios_set_default_processor_family(uint16_t processor_family); + uint8_t *smbios_get_table_legacy(size_t *length, Error **errp); void smbios_get_tables(MachineState *ms, - const struct smbios_phys_mem_area *mem_array, diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index a10ceeabbf..037942d233 100644 +index 27a68071d7..ebd8f973f2 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h -@@ -113,6 +113,9 @@ struct PCMachineClass { +@@ -112,6 +112,9 @@ struct PCMachineClass { bool smbios_legacy_mode; bool smbios_uuid_encoded; SmbiosEntryPointType default_smbios_ep_type; diff --git a/0007-Add-aarch64-machine-types.patch b/0007-Add-aarch64-machine-types.patch index fde7982..a556bb2 100644 --- a/0007-Add-aarch64-machine-types.patch +++ b/0007-Add-aarch64-machine-types.patch @@ -1,4 +1,4 @@ -From 23f614ab0b79ec1c6f65a7f0d6993bfdfc53fd23 Mon Sep 17 00:00:00 2001 +From cf398296f3fcee185a00f23de5deae57c97d648e Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Fri, 19 Oct 2018 12:53:31 +0200 Subject: Add aarch64 machine types @@ -30,6 +30,9 @@ Rebase notes (8.0.0): Rebase notes (8.1.0): - Added setting default_nic +Rebase notes (9.0.0 rc0): +- call arm_virt_compat_set on rhel type class_init + Merged patches (6.2.0): - 9a3d4fde0e hw/arm/virt: Remove 9.0 machine type - f7d04d6695 hw: arm: virt: Add hw_compat_rhel_8_5 to 8.5 machine type @@ -64,34 +67,67 @@ Merged patches (8.1.0): Merged patches (8.2.0): - 4ee284aca9 Add machine types compat bits. (partial) + +Merged patches (9.0.0 rc0): +- 117068376a hw/arm/virt: Fix compats +- 8bcccfabc4 hw/arm/virt: Add properties to disable high memory regions +- 0005a8b93a hw/arm/virt: deprecate virt-rhel9.{0,2}.0 machine types --- - hw/arm/virt.c | 250 +++++++++++++++++++++++++++++++++++++++++- + hw/arm/virt.c | 299 +++++++++++++++++++++++++++++++++++++++++- include/hw/arm/virt.h | 8 ++ - 2 files changed, 257 insertions(+), 1 deletion(-) + 2 files changed, 306 insertions(+), 1 deletion(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 62f0f7d4d6..c541efee5e 100644 +index 36e9b4b4e9..22bc345137 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c -@@ -82,6 +82,7 @@ - #include "hw/char/pl011.h" - #include "qemu/guest-random.h" +@@ -101,6 +101,7 @@ static void arm_virt_compat_set(MachineClass *mc) + arm_virt_compat_len); + } +#if 0 /* Disabled for Red Hat Enterprise Linux */ #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ void *data) \ -@@ -108,7 +109,48 @@ +@@ -128,7 +129,63 @@ static void arm_virt_compat_set(MachineClass *mc) DEFINE_VIRT_MACHINE_LATEST(major, minor, true) #define DEFINE_VIRT_MACHINE(major, minor) \ DEFINE_VIRT_MACHINE_LATEST(major, minor, false) +#endif /* disabled for RHEL */ ++ ++/* ++ * This variable is for changes to properties that are RHEL specific, ++ * different to the current upstream and to be applied to the latest ++ * machine type. They may be overriden by older machine compats. ++ * ++ * virtio-net-pci variant romfiles are not needed because edk2 does ++ * fully support the pxe boot. Besides virtio romfiles are not shipped ++ * on rhel/aarch64. ++ */ ++GlobalProperty arm_rhel_compat[] = { ++ {"virtio-net-pci", "romfile", "" }, ++ {"virtio-net-pci-transitional", "romfile", "" }, ++ {"virtio-net-pci-non-transitional", "romfile", "" }, ++}; ++const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); ++/* ++ * This cannot be called from the rhel_virt_class_init() because ++ * TYPE_RHEL_MACHINE is abstract and mc->compat_props g_ptr_array_new() ++ * only is called on virt-rhelm.n.s non abstract class init. ++ */ ++static void arm_rhel_compat_set(MachineClass *mc) ++{ ++ compat_props_add(mc->compat_props, arm_rhel_compat, ++ arm_rhel_compat_len); ++} ++ +#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \ + static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \ + void *data) \ + { \ + MachineClass *mc = MACHINE_CLASS(oc); \ ++ arm_rhel_compat_set(mc); \ + rhel##m##n##s##_virt_options(mc); \ + mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \ + if (latest) { \ @@ -114,23 +150,10 @@ index 62f0f7d4d6..c541efee5e 100644 + DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true) +#define DEFINE_RHEL_MACHINE(major, minor, subminor) \ + DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false) -+ -+/* This variable is for changes to properties that are RHEL specific, -+ * different to the current upstream and to be applied to the latest -+ * machine type. -+ */ -+GlobalProperty arm_rhel_compat[] = { -+ { -+ .driver = "virtio-net-pci", -+ .property = "romfile", -+ .value = "", -+ }, -+}; -+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); /* Number of external interrupt lines to configure the GIC with */ #define NUM_IRQS 256 -@@ -2341,6 +2383,7 @@ static void machvirt_init(MachineState *machine) +@@ -2355,6 +2412,7 @@ static void machvirt_init(MachineState *machine) qemu_add_machine_init_done_notifier(&vms->machine_done); } @@ -138,7 +161,7 @@ index 62f0f7d4d6..c541efee5e 100644 static bool virt_get_secure(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2368,6 +2411,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp) +@@ -2382,6 +2440,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp) vms->virt = value; } @@ -146,7 +169,7 @@ index 62f0f7d4d6..c541efee5e 100644 static bool virt_get_highmem(Object *obj, Error **errp) { -@@ -2383,6 +2427,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp) +@@ -2397,6 +2456,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp) vms->highmem = value; } @@ -154,16 +177,23 @@ index 62f0f7d4d6..c541efee5e 100644 static bool virt_get_compact_highmem(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2438,7 +2483,7 @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp) +@@ -2410,6 +2470,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp) - vms->highmem_mmio = value; + vms->highmem_compact = value; } -- +#endif /* disabled for RHEL */ + static bool virt_get_highmem_redists(Object *obj, Error **errp) + { +@@ -2453,7 +2514,6 @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp) + vms->highmem_mmio = value; + } + +- static bool virt_get_its(Object *obj, Error **errp) { -@@ -2454,6 +2499,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp) + VirtMachineState *vms = VIRT_MACHINE(obj); +@@ -2468,6 +2528,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp) vms->its = value; } @@ -171,7 +201,7 @@ index 62f0f7d4d6..c541efee5e 100644 static bool virt_get_dtb_randomness(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2467,6 +2513,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp) +@@ -2481,6 +2542,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp) vms->dtb_randomness = value; } @@ -179,7 +209,7 @@ index 62f0f7d4d6..c541efee5e 100644 static char *virt_get_oem_id(Object *obj, Error **errp) { -@@ -2550,6 +2597,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp) +@@ -2564,6 +2626,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp) vms->ras = value; } @@ -187,7 +217,7 @@ index 62f0f7d4d6..c541efee5e 100644 static bool virt_get_mte(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2563,6 +2611,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp) +@@ -2577,6 +2640,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp) vms->mte = value; } @@ -195,7 +225,7 @@ index 62f0f7d4d6..c541efee5e 100644 static char *virt_get_gic_version(Object *obj, Error **errp) { -@@ -2935,6 +2984,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str) +@@ -2949,6 +3013,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str) return fixed_ipa ? 0 : requested_pa_size; } @@ -203,7 +233,7 @@ index 62f0f7d4d6..c541efee5e 100644 static void virt_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); -@@ -3405,3 +3455,201 @@ static void virt_machine_2_6_options(MachineClass *mc) +@@ -3463,3 +3528,235 @@ static void virt_machine_2_6_options(MachineClass *mc) vmc->no_pmu = true; } DEFINE_VIRT_MACHINE(2, 6) @@ -213,6 +243,7 @@ index 62f0f7d4d6..c541efee5e 100644 +{ + MachineClass *mc = MACHINE_CLASS(oc); + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); ++ arm_virt_compat_set(mc); + + mc->family = "virt-rhel-Z"; + mc->init = machvirt_init; @@ -258,6 +289,28 @@ index 62f0f7d4d6..c541efee5e 100644 + "Set on/off to enable/disable using " + "physical address space above 32 bits"); + ++ object_class_property_add_bool(oc, "highmem-redists", ++ virt_get_highmem_redists, ++ virt_set_highmem_redists); ++ object_class_property_set_description(oc, "highmem-redists", ++ "Set on/off to enable/disable high " ++ "memory region for GICv3 or GICv4 " ++ "redistributor"); ++ ++ object_class_property_add_bool(oc, "highmem-ecam", ++ virt_get_highmem_ecam, ++ virt_set_highmem_ecam); ++ object_class_property_set_description(oc, "highmem-ecam", ++ "Set on/off to enable/disable high " ++ "memory region for PCI ECAM"); ++ ++ object_class_property_add_bool(oc, "highmem-mmio", ++ virt_get_highmem_mmio, ++ virt_set_highmem_mmio); ++ object_class_property_set_description(oc, "highmem-mmio", ++ "Set on/off to enable/disable high " ++ "memory region for PCI MMIO"); ++ + object_class_property_add_str(oc, "gic-version", virt_get_gic_version, + virt_set_gic_version); + object_class_property_set_description(oc, "gic-version", @@ -382,14 +435,24 @@ index 62f0f7d4d6..c541efee5e 100644 +} +type_init(rhel_machine_init); + ++static void rhel940_virt_options(MachineClass *mc) ++{ ++} ++DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0) ++ +static void rhel920_virt_options(MachineClass *mc) +{ -+ compat_props_add(mc->compat_props, arm_rhel_compat, arm_rhel_compat_len); ++ rhel940_virt_options(mc); ++ + compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len); ++ ++ /* RHEL 9.4 is the first supported release */ ++ mc->deprecation_reason = ++ "machine types for versions prior to 9.4 are deprecated"; +} -+DEFINE_RHEL_MACHINE_AS_LATEST(9, 2, 0) ++DEFINE_RHEL_MACHINE(9, 2, 0) + +static void rhel900_virt_options(MachineClass *mc) +{ @@ -398,6 +461,7 @@ index 62f0f7d4d6..c541efee5e 100644 + rhel920_virt_options(mc); + + compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len); ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len); + + /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */ + vmc->no_tcg_lpa2 = true; @@ -406,10 +470,10 @@ index 62f0f7d4d6..c541efee5e 100644 +} +DEFINE_RHEL_MACHINE(9, 0, 0) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index f69239850e..7b8abe5645 100644 +index bb486d36b1..237fc77bda 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h -@@ -177,9 +177,17 @@ struct VirtMachineState { +@@ -179,9 +179,17 @@ struct VirtMachineState { #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM) diff --git a/0008-Add-ppc64-machine-types.patch b/0008-Add-ppc64-machine-types.patch index a269adb..87fcb3a 100644 --- a/0008-Add-ppc64-machine-types.patch +++ b/0008-Add-ppc64-machine-types.patch @@ -1,4 +1,4 @@ -From d03cff85f5f1b69b1a66011ebaa974ece81d31bc Mon Sep 17 00:00:00 2001 +From fb905dbe5b51ed899062ef99a2dd7f238d3e3384 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Fri, 19 Oct 2018 13:27:13 +0200 Subject: Add ppc64 machine types @@ -34,20 +34,20 @@ Merged patches (7.1.0): 8 files changed, 314 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c -index df09aa9d6a..ff459e1a46 100644 +index e9bc97fee0..a258d81846 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c -@@ -1689,6 +1689,9 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason) - +@@ -1718,6 +1718,9 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason) pef_kvm_reset(machine->cgs, &error_fatal); spapr_caps_apply(spapr); + spapr_nested_reset(spapr); + if (spapr->svm_allowed) { + kvmppc_svm_allow(&error_fatal); + } first_ppc_cpu = POWERPC_CPU(first_cpu); if (kvm_enabled() && kvmppc_has_cap_mmu_radix() && -@@ -3397,6 +3400,20 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp) +@@ -3421,6 +3424,20 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp) spapr->host_serial = g_strdup(value); } @@ -68,7 +68,7 @@ index df09aa9d6a..ff459e1a46 100644 static void spapr_instance_init(Object *obj) { SpaprMachineState *spapr = SPAPR_MACHINE(obj); -@@ -3475,6 +3492,12 @@ static void spapr_instance_init(Object *obj) +@@ -3499,6 +3516,12 @@ static void spapr_instance_init(Object *obj) spapr_get_host_serial, spapr_set_host_serial); object_property_set_description(obj, "host-serial", "Host serial number to advertise in guest device tree"); @@ -81,7 +81,7 @@ index df09aa9d6a..ff459e1a46 100644 } static void spapr_machine_finalizefn(Object *obj) -@@ -4734,6 +4757,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) +@@ -4754,6 +4777,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) vmc->client_architecture_support = spapr_vof_client_architecture_support; vmc->quiesce = spapr_vof_quiesce; vmc->setprop = spapr_vof_setprop; @@ -89,15 +89,15 @@ index df09aa9d6a..ff459e1a46 100644 } static const TypeInfo spapr_machine_info = { -@@ -4785,6 +4809,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc) +@@ -4805,6 +4829,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc) } \ type_init(spapr_machine_register_##suffix) +#if 0 /* Disabled for Red Hat Enterprise Linux */ /* - * pseries-8.2 + * pseries-9.0 */ -@@ -4967,6 +4992,7 @@ static void spapr_machine_4_1_class_options(MachineClass *mc) +@@ -4998,6 +5023,7 @@ static void spapr_machine_4_1_class_options(MachineClass *mc) } DEFINE_SPAPR_MACHINE(4_1, "4.1", false); @@ -105,7 +105,7 @@ index df09aa9d6a..ff459e1a46 100644 /* * pseries-4.0 -@@ -4982,6 +5008,8 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index, +@@ -5013,6 +5039,8 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index, } return true; } @@ -114,7 +114,7 @@ index df09aa9d6a..ff459e1a46 100644 static void spapr_machine_4_0_class_options(MachineClass *mc) { SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -@@ -5306,6 +5334,221 @@ static void spapr_machine_2_1_class_options(MachineClass *mc) +@@ -5338,6 +5366,221 @@ static void spapr_machine_2_1_class_options(MachineClass *mc) compat_props_add(mc->compat_props, hw_compat_2_1, hw_compat_2_1_len); } DEFINE_SPAPR_MACHINE(2_1, "2.1", false); @@ -337,7 +337,7 @@ index df09aa9d6a..ff459e1a46 100644 static void spapr_machine_register_types(void) { diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c -index 33e0c8724c..9d01663f43 100644 +index 3b0a47a28c..375e0c8e45 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -25,6 +25,7 @@ @@ -348,7 +348,7 @@ index 33e0c8724c..9d01663f43 100644 static void spapr_reset_vcpu(PowerPCCPU *cpu) { -@@ -261,6 +262,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, +@@ -264,6 +265,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, { CPUPPCState *env = &cpu->env; CPUState *cs = CPU(cpu); @@ -356,7 +356,7 @@ index 33e0c8724c..9d01663f43 100644 if (!qdev_realize(DEVICE(cpu), NULL, errp)) { return false; -@@ -277,6 +279,17 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, +@@ -280,6 +282,17 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, /* Set time-base frequency to 512 MHz. vhyp must be set first. */ cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ); @@ -375,10 +375,10 @@ index 33e0c8724c..9d01663f43 100644 qdev_unrealize(DEVICE(cpu)); return false; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h -index e91791a1a9..1951d8a2a0 100644 +index 4aaf23d28f..3233c54d11 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h -@@ -154,6 +154,7 @@ struct SpaprMachineClass { +@@ -157,6 +157,7 @@ struct SpaprMachineClass { bool pre_5_2_numa_associativity; bool pre_6_2_numa_affinity; @@ -386,7 +386,7 @@ index e91791a1a9..1951d8a2a0 100644 bool (*phb_placement)(SpaprMachineState *spapr, uint32_t index, uint64_t *buid, hwaddr *pio, hwaddr *mmio32, hwaddr *mmio64, -@@ -256,6 +257,9 @@ struct SpaprMachineState { +@@ -259,6 +260,9 @@ struct SpaprMachineState { /* Set by -boot */ char *boot_device; @@ -422,10 +422,10 @@ index ebef2cccec..ff2c00c60e 100644 const CompatInfo *compat = compat_by_pvr(compat_pvr); const CompatInfo *min = compat_by_pvr(min_compat_pvr); diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c -index 69fddb05bc..64a05aaef3 100644 +index f77ebfcc81..18e9422006 100644 --- a/target/ppc/cpu-models.c +++ b/target/ppc/cpu-models.c -@@ -748,6 +748,7 @@ +@@ -744,6 +744,7 @@ /* PowerPC CPU aliases */ PowerPCCPUAlias ppc_cpu_aliases[] = { @@ -434,10 +434,10 @@ index 69fddb05bc..64a05aaef3 100644 { "405cr", "405crc" }, { "405gp", "405gpd" }, diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h -index f8101ffa29..e799a2bee6 100644 +index 67e6b2effd..11187aeb93 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h -@@ -1635,6 +1635,7 @@ static inline int cpu_mmu_index(CPUPPCState *env, bool ifetch) +@@ -1655,6 +1655,7 @@ static inline int ppc_env_mmu_index(CPUPPCState *env, bool ifetch) /* Compatibility modes */ #if defined(TARGET_PPC64) @@ -446,7 +446,7 @@ index f8101ffa29..e799a2bee6 100644 uint32_t min_compat_pvr, uint32_t max_compat_pvr); bool ppc_type_check_compat(const char *cputype, uint32_t compat_pvr, diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c -index 9b1abe2fc4..56f1c46e8e 100644 +index 8231feb2d4..59f640cf7b 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -89,6 +89,7 @@ static int cap_large_decr; @@ -465,7 +465,7 @@ index 9b1abe2fc4..56f1c46e8e 100644 cap_large_decr = kvmppc_get_dec_bits(); cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI); /* -@@ -2579,6 +2581,16 @@ bool kvmppc_supports_ail_3(void) +@@ -2564,6 +2566,16 @@ bool kvmppc_supports_ail_3(void) return cap_ail_mode_3; } @@ -482,7 +482,7 @@ index 9b1abe2fc4..56f1c46e8e 100644 PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void) { uint32_t host_pvr = mfpvr(); -@@ -2979,3 +2991,18 @@ bool kvm_arch_cpu_check_are_resettable(void) +@@ -2964,3 +2976,18 @@ bool kvm_arch_cpu_check_are_resettable(void) void kvm_arch_accel_class_init(ObjectClass *oc) { } diff --git a/0009-Add-s390x-machine-types.patch b/0009-Add-s390x-machine-types.patch index c3b9936..b9709f1 100644 --- a/0009-Add-s390x-machine-types.patch +++ b/0009-Add-s390x-machine-types.patch @@ -1,4 +1,4 @@ -From 3623043d4a923bf9f541d439c76e7874cf0fa81d Mon Sep 17 00:00:00 2001 +From 04178c77cfe188b4eed9c08a0bf66842e61fe5dc Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Fri, 19 Oct 2018 13:47:32 +0200 Subject: Add s390x machine types @@ -49,18 +49,18 @@ Merged patches (8.2.0): 4 files changed, 174 insertions(+) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 7262725d2e..984891b82a 100644 +index b1dcb3857f..ff753a29e0 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c -@@ -855,6 +855,7 @@ bool css_migration_enabled(void) +@@ -859,6 +859,7 @@ bool css_migration_enabled(void) } \ type_init(ccw_machine_register_##suffix) +#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void ccw_machine_8_2_instance_options(MachineState *machine) + static void ccw_machine_9_0_instance_options(MachineState *machine) { } -@@ -1256,6 +1257,164 @@ static void ccw_machine_2_4_class_options(MachineClass *mc) +@@ -1272,6 +1273,164 @@ static void ccw_machine_2_4_class_options(MachineClass *mc) compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); } DEFINE_CCW_MACHINE(2_4, "2.4", false); @@ -226,7 +226,7 @@ index 7262725d2e..984891b82a 100644 static void ccw_machine_register_types(void) { diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index a63d990e4e..198b81f2c0 100644 +index 8ed3bb6a27..370b3b3065 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -46,6 +46,9 @@ @@ -239,7 +239,7 @@ index a63d990e4e..198b81f2c0 100644 static S390CPUDef s390_cpu_defs[] = { CPUDEF_INIT(0x2064, 7, 1, 38, 0x00000000U, "z900", "IBM zSeries 900 GA1"), CPUDEF_INIT(0x2064, 7, 2, 38, 0x00000000U, "z900.2", "IBM zSeries 900 GA2"), -@@ -856,22 +859,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data) +@@ -866,22 +869,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data) static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data) { S390CPUClass *xcc = S390_CPU_CLASS(oc); @@ -284,10 +284,10 @@ index d7b8912989..1a806a97c4 100644 /* CPU model based on a CPU definition */ diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c -index 87a4480c05..28c1b0486c 100644 +index 0728bfcc20..ca2e5d91e2 100644 --- a/target/s390x/cpu_models_sysemu.c +++ b/target/s390x/cpu_models_sysemu.c -@@ -60,6 +60,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque) +@@ -59,6 +59,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque) CpuDefinitionInfo *info; char *name = g_strdup(object_class_get_name(klass)); S390CPUClass *scc = S390_CPU_CLASS(klass); @@ -295,7 +295,7 @@ index 87a4480c05..28c1b0486c 100644 /* strip off the -s390x-cpu */ g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0; -@@ -69,6 +70,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque) +@@ -68,6 +69,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque) info->migration_safe = scc->is_migration_safe; info->q_static = scc->is_static; info->q_typename = g_strdup(object_class_get_name(klass)); diff --git a/0010-Add-x86_64-machine-types.patch b/0010-Add-x86_64-machine-types.patch index d24bb57..83ee4a3 100644 --- a/0010-Add-x86_64-machine-types.patch +++ b/0010-Add-x86_64-machine-types.patch @@ -1,4 +1,4 @@ -From b432505cb28bc3b9b0c1849210ac6c63bca3fe37 Mon Sep 17 00:00:00 2001 +From 3c88acb005806ad2386ab6c94a8831151f624738 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Fri, 19 Oct 2018 13:10:31 +0200 Subject: Add x86_64 machine types @@ -57,23 +57,40 @@ Merged patches (8.1.0): Merged patches (8.2.0): - 4ee284aca9 Add machine types compat bits. (partial) - 719e2ac147 Fix x86 machine type compatibility for qemu-kvm 8.1.0 + +Merged patches (9.0.0 rc0): +- 9149e2bc8f x86: rhel 9.2.0 machine type compat fix --- + hw/i386/fw_cfg.c | 2 +- hw/i386/pc.c | 159 ++++++++++++++++++++- - hw/i386/pc_piix.c | 112 ++++++++++++++- - hw/i386/pc_q35.c | 285 ++++++++++++++++++++++++++++++++++++- + hw/i386/pc_piix.c | 109 ++++++++++++++ + hw/i386/pc_q35.c | 285 +++++++++++++++++++++++++++++++++++++ include/hw/boards.h | 2 + include/hw/i386/pc.h | 33 +++++ target/i386/cpu.c | 21 +++ target/i386/kvm/kvm-cpu.c | 1 + target/i386/kvm/kvm.c | 4 + tests/qtest/pvpanic-test.c | 5 +- - 9 files changed, 615 insertions(+), 7 deletions(-) + 10 files changed, 617 insertions(+), 4 deletions(-) +diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c +index c7aa39a13e..283c3f4c16 100644 +--- a/hw/i386/fw_cfg.c ++++ b/hw/i386/fw_cfg.c +@@ -63,7 +63,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg, + + if (pcmc->smbios_defaults) { + /* These values are guest ABI, do not change */ +- smbios_set_defaults("QEMU", mc->desc, mc->name, ++ smbios_set_defaults("Red Hat", "KVM", mc->desc, + pcmc->smbios_uuid_encoded, + pcmc->smbios_stream_product, pcmc->smbios_stream_version); + } diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 29b9964733..a1faa9e92c 100644 +index 5c21b0c4db..4a154c1a9a 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c -@@ -323,6 +323,161 @@ GlobalProperty pc_compat_2_0[] = { +@@ -326,6 +326,161 @@ GlobalProperty pc_compat_2_0[] = { }; const size_t pc_compat_2_0_len = G_N_ELEMENTS(pc_compat_2_0); @@ -235,15 +252,15 @@ index 29b9964733..a1faa9e92c 100644 GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled) { GSIState *s; -@@ -1826,6 +1981,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - pcmc->kvmclock_create_always = true; +@@ -1813,6 +1968,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) pcmc->resizable_acpi_blob = true; + x86mc->apic_xrupt_override = true; assert(!mc->get_hotplug_handler); + mc->async_pf_vmexit_disable = false; mc->get_hotplug_handler = pc_get_hotplug_handler; mc->hotplug_allowed = pc_hotplug_allowed; mc->cpu_index_to_instance_props = x86_cpu_index_to_props; -@@ -1836,7 +1992,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) +@@ -1823,7 +1979,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) mc->has_hotpluggable_cpus = true; mc->default_boot_order = "cad"; mc->block_default_type = IF_IDE; @@ -254,10 +271,10 @@ index 29b9964733..a1faa9e92c 100644 mc->wakeup = pc_machine_wakeup; hc->pre_plug = pc_machine_device_pre_plug_cb; diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 2a9f465619..44038391fb 100644 +index 18ba076609..a647262d63 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c -@@ -53,6 +53,7 @@ +@@ -52,6 +52,7 @@ #include "qapi/error.h" #include "qemu/error-report.h" #include "sysemu/xen.h" @@ -265,18 +282,7 @@ index 2a9f465619..44038391fb 100644 #ifdef CONFIG_XEN #include #include "hw/xen/xen_pt.h" -@@ -235,8 +236,8 @@ static void pc_init1(MachineState *machine, - if (pcmc->smbios_defaults) { - MachineClass *mc = MACHINE_GET_CLASS(machine); - /* These values are guest ABI, do not change */ -- smbios_set_defaults("QEMU", mc->desc, -- mc->name, pcmc->smbios_legacy_mode, -+ smbios_set_defaults("Red Hat", "KVM", -+ mc->desc, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, - pcmc->smbios_stream_product, - pcmc->smbios_stream_version, -@@ -453,6 +454,7 @@ static void pc_set_south_bridge(Object *obj, int value, Error **errp) +@@ -422,6 +423,7 @@ static void pc_set_south_bridge(Object *obj, int value, Error **errp) * hw_compat_*, pc_compat_*, or * pc_*_machine_options(). */ @@ -284,7 +290,7 @@ index 2a9f465619..44038391fb 100644 static void pc_compat_2_3_fn(MachineState *machine) { X86MachineState *x86ms = X86_MACHINE(machine); -@@ -970,3 +972,109 @@ static void xenfv_3_1_machine_options(MachineClass *m) +@@ -951,3 +953,110 @@ static void xenfv_3_1_machine_options(MachineClass *m) DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init, xenfv_3_1_machine_options); #endif @@ -314,8 +320,7 @@ index 2a9f465619..44038391fb 100644 + +static void pc_init_rhel760(MachineState *machine) +{ -+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ -+ TYPE_I440FX_PCI_DEVICE); ++ pc_init1(machine, TYPE_I440FX_PCI_DEVICE); +} + +static void pc_machine_rhel760_options(MachineClass *m) @@ -339,6 +344,8 @@ index 2a9f465619..44038391fb 100644 + pcmc->enforce_amd_1tb_hole = false; + /* From pc_i440fx_8_0_machine_options() */ + pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32; ++ /* From pc_i440fx_8_1_machine_options() */ ++ pcmc->broken_32bit_mem_addr_check = true; + /* Introduced in QEMU 8.2 */ + pcmc->default_south_bridge = TYPE_PIIX3_DEVICE; + @@ -395,21 +402,10 @@ index 2a9f465619..44038391fb 100644 +DEFINE_PC_MACHINE(rhel760, "pc-i440fx-rhel7.6.0", pc_init_rhel760, + pc_machine_rhel760_options); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 912cb0c0dc..6387df97c8 100644 +index c7bc8a2041..e872dc7e46 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c -@@ -203,8 +203,8 @@ static void pc_q35_init(MachineState *machine) - - if (pcmc->smbios_defaults) { - /* These values are guest ABI, do not change */ -- smbios_set_defaults("QEMU", mc->desc, -- mc->name, pcmc->smbios_legacy_mode, -+ smbios_set_defaults("Red Hat", "KVM", -+ mc->desc, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, - pcmc->smbios_stream_product, - pcmc->smbios_stream_version, -@@ -363,6 +363,7 @@ static void pc_q35_init(MachineState *machine) +@@ -341,6 +341,7 @@ static void pc_q35_init(MachineState *machine) DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn) @@ -417,7 +413,7 @@ index 912cb0c0dc..6387df97c8 100644 static void pc_q35_machine_options(MachineClass *m) { PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -@@ -699,3 +700,283 @@ static void pc_q35_2_4_machine_options(MachineClass *m) +@@ -693,3 +694,287 @@ static void pc_q35_2_4_machine_options(MachineClass *m) DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL, pc_q35_2_4_machine_options); @@ -444,6 +440,8 @@ index 912cb0c0dc..6387df97c8 100644 + m->alias = "q35"; + m->max_cpus = 710; + compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len); ++ compat_props_add(m->compat_props, ++ pc_q35_compat_defaults, pc_q35_compat_defaults_len); +} + +static void pc_q35_init_rhel940(MachineState *machine) @@ -480,6 +478,8 @@ index 912cb0c0dc..6387df97c8 100644 + + /* From pc_q35_8_0_machine_options() */ + pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32; ++ /* From pc_q35_8_1_machine_options() */ ++ pcmc->broken_32bit_mem_addr_check = true; + + compat_props_add(m->compat_props, hw_compat_rhel_9_4, + hw_compat_rhel_9_4_len); @@ -702,10 +702,10 @@ index 912cb0c0dc..6387df97c8 100644 +DEFINE_PC_MACHINE(q35_rhel760, "pc-q35-rhel7.6.0", pc_q35_init_rhel760, + pc_q35_machine_rhel760_options); diff --git a/include/hw/boards.h b/include/hw/boards.h -index 4a21eddbf9..4edfdb0ddb 100644 +index 0466f9d0f3..46b8725c41 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h -@@ -277,6 +277,8 @@ struct MachineClass { +@@ -283,6 +283,8 @@ struct MachineClass { strList *allowed_dynamic_sysbus_devices; bool auto_enable_numa_with_memhp; bool auto_enable_numa_with_memdev; @@ -715,12 +715,12 @@ index 4a21eddbf9..4edfdb0ddb 100644 bool smbus_no_migration_support; bool nvdimm_supported; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 037942d233..37644ede7e 100644 +index ebd8f973f2..a984c951ad 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h -@@ -314,6 +314,39 @@ extern const size_t pc_compat_1_4_len; - - int pc_machine_kvm_type(MachineState *machine, const char *vm_type); +@@ -291,6 +291,39 @@ extern const size_t pc_compat_2_1_len; + extern GlobalProperty pc_compat_2_0[]; + extern const size_t pc_compat_2_0_len; +extern GlobalProperty pc_rhel_compat[]; +extern const size_t pc_rhel_compat_len; @@ -759,7 +759,7 @@ index 037942d233..37644ede7e 100644 static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \ { \ diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index cd16cb893d..93203d9b91 100644 +index 33760a2ee1..be7b0663cd 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2190,9 +2190,13 @@ static const CPUCaches epyc_genoa_cache_info = { @@ -925,10 +925,10 @@ index 9c791b7b05..b91af5051f 100644 }; diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 4ce80555b4..9d41edf01e 100644 +index e68cbe9293..739f33db47 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c -@@ -3711,6 +3711,7 @@ static int kvm_get_msrs(X86CPU *cpu) +@@ -3715,6 +3715,7 @@ static int kvm_get_msrs(X86CPU *cpu) struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries; int ret, i; uint64_t mtrr_top_bits; @@ -936,7 +936,7 @@ index 4ce80555b4..9d41edf01e 100644 kvm_msr_buf_reset(cpu); -@@ -4065,6 +4066,9 @@ static int kvm_get_msrs(X86CPU *cpu) +@@ -4069,6 +4070,9 @@ static int kvm_get_msrs(X86CPU *cpu) break; case MSR_KVM_ASYNC_PF_EN: env->async_pf_en_msr = msrs[i].data; diff --git a/0011-Enable-make-check.patch b/0011-Enable-make-check.patch index 54015c0..502bc67 100644 --- a/0011-Enable-make-check.patch +++ b/0011-Enable-make-check.patch @@ -1,4 +1,4 @@ -From 66a0510405e5142a1f9e38e0770aa0f10aed3e03 Mon Sep 17 00:00:00 2001 +From 5768cf6811842e5c59da3b752f60659a9d6b5ba1 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 2 Sep 2020 09:39:41 +0200 Subject: Enable make check @@ -63,10 +63,10 @@ Merged patches (8.1.0): 13 files changed, 33 insertions(+), 30 deletions(-) diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py -index c37afa662c..61c95a2198 100644 +index 10d99403a4..c3422ea1e4 100644 --- a/tests/avocado/replay_kernel.py +++ b/tests/avocado/replay_kernel.py -@@ -153,7 +153,7 @@ def test_aarch64_virt(self): +@@ -166,7 +166,7 @@ def test_aarch64_virt(self): """ :avocado: tags=arch:aarch64 :avocado: tags=machine:virt @@ -76,7 +76,7 @@ index c37afa662c..61c95a2198 100644 kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' '/linux/releases/29/Everything/aarch64/os/images/pxeboot' diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py -index 4cce5a5598..e9248a04a2 100644 +index 92855a02a5..87822074b6 100644 --- a/tests/avocado/reverse_debugging.py +++ b/tests/avocado/reverse_debugging.py @@ -230,7 +230,7 @@ def test_aarch64_virt(self): @@ -120,7 +120,7 @@ index 15fd87b2c1..f0d9d89c93 100644 kernel_path = self._grab_aarch64_kernel() kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + diff --git a/tests/qemu-iotests/meson.build b/tests/qemu-iotests/meson.build -index 53847cb98f..a2abdb650e 100644 +index fad340ad59..3c0d5241f6 100644 --- a/tests/qemu-iotests/meson.build +++ b/tests/qemu-iotests/meson.build @@ -51,21 +51,21 @@ foreach format, speed: qemu_iotests_formats @@ -163,7 +163,7 @@ index 53847cb98f..a2abdb650e 100644 +# endforeach endforeach diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py -index 3ff38f2661..cab9a2bd6c 100644 +index 588f30a4f1..3929a3634f 100644 --- a/tests/qemu-iotests/testenv.py +++ b/tests/qemu-iotests/testenv.py @@ -244,6 +244,9 @@ def __init__(self, source_dir: str, build_dir: str, @@ -216,7 +216,7 @@ index 663bb6c485..2efc43e3f7 100644 "-device intel-hda,id=" HDA_ID CODEC_DEVICES); diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build -index 90aae42a22..9bc4e41af0 100644 +index 3aed6efcb8..119613237e 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -44,7 +44,7 @@ libqos_srcs = files( @@ -242,10 +242,10 @@ index 8ac95b89f7..cd2102555c 100644 qtest_outl(s, 0xcf8, 0x8000f840); /* PMBASE */ diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build -index 47dabf91d0..0bdfa3a821 100644 +index 36c5c13a7b..a2887d6057 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build -@@ -97,7 +97,6 @@ qtests_i386 = \ +@@ -101,7 +101,6 @@ qtests_i386 = \ 'drive_del-test', 'tco-test', 'cpu-plug-test', @@ -254,7 +254,7 @@ index 47dabf91d0..0bdfa3a821 100644 'migration-test', 'test-x86-cpuid-compat', diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c -index 0d40bc1f2d..4c633c1584 100644 +index 73dfabc272..a9dd304781 100644 --- a/tests/qtest/virtio-net-failover.c +++ b/tests/qtest/virtio-net-failover.c @@ -26,6 +26,7 @@ diff --git a/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch b/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch index 8222efd..e8bf13a 100644 --- a/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch +++ b/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch @@ -1,4 +1,4 @@ -From a27cfa0b407bd806ce389a7c69d0130bcfd35244 Mon Sep 17 00:00:00 2001 +From e06a905d726fc20ea6bd95dff1bd0ffe97ebb202 Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Tue, 3 Dec 2013 20:05:13 +0100 Subject: vfio: cap number of devices that can be assigned @@ -27,7 +27,7 @@ to 64 as some usecases require more than 32 devices. Signed-off-by: Bandan Das -Rebase changes (231025): +Rebase changes (8.2.0): - Update to upstream changes --- hw/vfio/pci.c | 31 ++++++++++++++++++++++++++++++- @@ -35,10 +35,10 @@ Rebase changes (231025): 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index c62c02f7b6..ec98080f28 100644 +index 64780d1b79..57ac63c10c 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c -@@ -48,6 +48,9 @@ +@@ -50,6 +50,9 @@ /* Protected by BQL */ static KVMRouteChange vfio_route_change; @@ -48,15 +48,14 @@ index c62c02f7b6..ec98080f28 100644 static void vfio_disable_interrupts(VFIOPCIDevice *vdev); static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled); static void vfio_msi_disable_common(VFIOPCIDevice *vdev); -@@ -3076,14 +3079,37 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - { +@@ -2946,13 +2949,36 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) + ERRP_GUARD(); VFIOPCIDevice *vdev = VFIO_PCI(pdev); VFIODevice *vbasedev = &vdev->vbasedev; + VFIODevice *vbasedev_iter; + VFIOGroup *group; char *tmp, *subsys; Error *err = NULL; - struct stat st; - int i, ret; + int ret, i = 0; bool is_mdev; @@ -84,10 +83,10 @@ index c62c02f7b6..ec98080f28 100644 + return; + } + - if (!vbasedev->sysfsdev) { + if (vbasedev->fd < 0 && !vbasedev->sysfsdev) { if (!(~vdev->host.domain || ~vdev->host.bus || ~vdev->host.slot || ~vdev->host.function)) { -@@ -3501,6 +3527,9 @@ static Property vfio_pci_dev_properties[] = { +@@ -3370,6 +3396,9 @@ static Property vfio_pci_dev_properties[] = { DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false), DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice, no_geforce_quirks, false), @@ -98,7 +97,7 @@ index c62c02f7b6..ec98080f28 100644 false), DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd, diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index fba8737ab2..eb74d9de2d 100644 +index 6e64a2654e..b7de39c010 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -142,6 +142,7 @@ struct VFIOPCIDevice { diff --git a/0013-Add-support-statement-to-help-output.patch b/0013-Add-support-statement-to-help-output.patch index bc5d9b4..0644440 100644 --- a/0013-Add-support-statement-to-help-output.patch +++ b/0013-Add-support-statement-to-help-output.patch @@ -1,4 +1,4 @@ -From 424f14d123fe1043518758605d94ed5ba50e52ad Mon Sep 17 00:00:00 2001 +From b467dc6a24ef41fa574260429807711f6802a54d Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Wed, 4 Dec 2013 18:53:17 +0100 Subject: Add support statement to -help output @@ -21,10 +21,10 @@ Signed-off-by: Eduardo Habkost 1 file changed, 9 insertions(+) diff --git a/system/vl.c b/system/vl.c -index 2bcd9efb9a..93635ffc5b 100644 +index c644222982..03c3b0aa94 100644 --- a/system/vl.c +++ b/system/vl.c -@@ -870,9 +870,17 @@ static void version(void) +@@ -869,9 +869,17 @@ static void version(void) QEMU_COPYRIGHT "\n"); } @@ -42,7 +42,7 @@ index 2bcd9efb9a..93635ffc5b 100644 printf("usage: %s [options] [disk_image]\n\n" "'disk_image' is a raw hard disk image for IDE hard disk 0\n\n", g_get_prgname()); -@@ -898,6 +906,7 @@ static void help(int exitcode) +@@ -897,6 +905,7 @@ static void help(int exitcode) "\n" QEMU_HELP_BOTTOM "\n"); diff --git a/0014-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch b/0014-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch index 7fa10b5..04adb4a 100644 --- a/0014-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch +++ b/0014-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch @@ -1,4 +1,4 @@ -From c683ff4a770b77dbe707413840918a46f67fa825 Mon Sep 17 00:00:00 2001 +From 20cc3a6d9bce3e40d165f865b5e398c300cae7bf Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 8 Jul 2020 08:35:50 +0200 Subject: Use qemu-kvm in documentation instead of qemu-system- @@ -36,10 +36,10 @@ index 52d6454b93..d74dbdeca9 100644 .. |I2C| replace:: I\ :sup:`2`\ C .. |I2S| replace:: I\ :sup:`2`\ S diff --git a/qemu-options.hx b/qemu-options.hx -index 42fd09e4de..557118cb1f 100644 +index 8ce85d4559..4fc27ee2e2 100644 --- a/qemu-options.hx +++ b/qemu-options.hx -@@ -3469,11 +3469,11 @@ SRST +@@ -3493,11 +3493,11 @@ SRST :: diff --git a/0015-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch b/0015-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch index 667d431..8518918 100644 --- a/0015-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch +++ b/0015-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch @@ -1,4 +1,4 @@ -From 776bff1be5e98982a9bbc8345ff27274ff5b8c0f Mon Sep 17 00:00:00 2001 +From 2f9fdd21ecf2810d0d83a8125ce0cc1e75dbb13a Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 20 Aug 2021 18:25:12 +0200 Subject: qcow2: Deprecation warning when opening v2 images rw @@ -44,7 +44,7 @@ Rebase notes (6.1.0): 2 files changed, 7 insertions(+) diff --git a/block/qcow2.c b/block/qcow2.c -index 13e032bd5e..7968735346 100644 +index 956128b409..0e8b2f7518 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1358,6 +1358,12 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, diff --git a/0016-Add-upstream-compatibility-bits.patch b/0016-Add-upstream-compatibility-bits.patch new file mode 100644 index 0000000..3efa22c --- /dev/null +++ b/0016-Add-upstream-compatibility-bits.patch @@ -0,0 +1,121 @@ +From 59470e8ab849f22b407f55292e540e16a8cad01a Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Wed, 20 Mar 2024 05:34:32 -0400 +Subject: Add upstream compatibility bits + +Adding new compats structure for changes introduced during rebase to QEMU 9.0.0. + +Signed-off-by: Miroslav Rezanina + +--- + +Rebase notes (9.0.0 rc2): +- Add aw-bits setting for aarch compat record (overwritten for 9.4 and older) +--- + hw/arm/virt.c | 3 +++ + hw/core/machine.c | 10 ++++++++++ + hw/i386/pc_piix.c | 3 ++- + hw/i386/pc_q35.c | 3 +++ + hw/s390x/s390-virtio-ccw.c | 1 + + include/hw/boards.h | 3 +++ + 6 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 22bc345137..f1af9495c6 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -144,6 +144,8 @@ GlobalProperty arm_rhel_compat[] = { + {"virtio-net-pci", "romfile", "" }, + {"virtio-net-pci-transitional", "romfile", "" }, + {"virtio-net-pci-non-transitional", "romfile", "" }, ++ /* arm_rhel_compat from arm_virt_compat, added for 9.0.0 rebase */ ++ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" }, + }; + const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); + +@@ -3728,6 +3730,7 @@ type_init(rhel_machine_init); + + static void rhel940_virt_options(MachineClass *mc) + { ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); + } + DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0) + +diff --git a/hw/core/machine.c b/hw/core/machine.c +index 695cb89a46..0f256d9633 100644 +--- a/hw/core/machine.c ++++ b/hw/core/machine.c +@@ -302,6 +302,16 @@ const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1); + const char *rhel_old_machine_deprecation = + "machine types for previous major releases are deprecated"; + ++GlobalProperty hw_compat_rhel_9_5[] = { ++ /* hw_compat_rhel_9_5 from hw_compat_8_2 */ ++ { "migration", "zero-page-detection", "legacy"}, ++ /* hw_compat_rhel_9_5 from hw_compat_8_2 */ ++ { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" }, ++ /* hw_compat_rhel_9_5 from hw_compat_8_2 */ ++ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" }, ++}; ++const size_t hw_compat_rhel_9_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5); ++ + GlobalProperty hw_compat_rhel_9_4[] = { + /* hw_compat_rhel_9_4 from hw_compat_8_0 */ + { TYPE_VIRTIO_NET, "host_uso", "off"}, +diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index a647262d63..6b260682eb 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -1015,7 +1015,8 @@ static void pc_machine_rhel760_options(MachineClass *m) + object_class_property_set_description(oc, "x-south-bridge", + "Use a different south bridge than PIIX3"); + +- ++ compat_props_add(m->compat_props, hw_compat_rhel_9_5, ++ hw_compat_rhel_9_5_len); + compat_props_add(m->compat_props, hw_compat_rhel_9_4, + hw_compat_rhel_9_4_len); + compat_props_add(m->compat_props, hw_compat_rhel_9_3, +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index e872dc7e46..2b54944c0f 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -733,6 +733,9 @@ static void pc_q35_machine_rhel940_options(MachineClass *m) + m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)"; + pcmc->smbios_stream_product = "RHEL"; + pcmc->smbios_stream_version = "9.4.0"; ++ ++ compat_props_add(m->compat_props, hw_compat_rhel_9_5, ++ hw_compat_rhel_9_5_len); + } + + DEFINE_PC_MACHINE(q35_rhel940, "pc-q35-rhel9.4.0", pc_q35_init_rhel940, +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index ff753a29e0..9ad54682c6 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -1282,6 +1282,7 @@ static void ccw_machine_rhel940_instance_options(MachineState *machine) + + static void ccw_machine_rhel940_class_options(MachineClass *mc) + { ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); + } + DEFINE_CCW_MACHINE(rhel940, "rhel9.4.0", true); + +diff --git a/include/hw/boards.h b/include/hw/boards.h +index 46b8725c41..cca62f906b 100644 +--- a/include/hw/boards.h ++++ b/include/hw/boards.h +@@ -514,6 +514,9 @@ extern const size_t hw_compat_2_2_len; + extern GlobalProperty hw_compat_2_1[]; + extern const size_t hw_compat_2_1_len; + ++extern GlobalProperty hw_compat_rhel_9_5[]; ++extern const size_t hw_compat_rhel_9_5_len; ++ + extern GlobalProperty hw_compat_rhel_9_4[]; + extern const size_t hw_compat_rhel_9_4_len; + +-- +2.39.3 + diff --git a/0016-Introduce-RHEL-9.4.0-qemu-kvm-machine-type-for-aarch.patch b/0016-Introduce-RHEL-9.4.0-qemu-kvm-machine-type-for-aarch.patch deleted file mode 100644 index 4e62baa..0000000 --- a/0016-Introduce-RHEL-9.4.0-qemu-kvm-machine-type-for-aarch.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 3b9b38339346ebfaf3e8ddf0822eba1cc9e78408 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Thu, 14 Dec 2023 04:42:01 -0500 -Subject: Introduce RHEL 9.4.0 qemu-kvm machine type for aarch64 - -Jira: https://issues.redhat.com/browse/RHEL-17168 - -Adding new machine type to support enabling new features. - -Signed-off-by: Miroslav Rezanina ---- - hw/arm/virt.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index c541efee5e..0b17c94ad7 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -3630,14 +3630,21 @@ static void rhel_machine_init(void) - } - type_init(rhel_machine_init); - -+static void rhel940_virt_options(MachineClass *mc) -+{ -+} -+DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0) -+ - static void rhel920_virt_options(MachineClass *mc) - { -+ rhel940_virt_options(mc); -+ - compat_props_add(mc->compat_props, arm_rhel_compat, arm_rhel_compat_len); - compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len); - compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len); - compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len); - } --DEFINE_RHEL_MACHINE_AS_LATEST(9, 2, 0) -+DEFINE_RHEL_MACHINE(9, 2, 0) - - static void rhel900_virt_options(MachineClass *mc) - { --- -2.39.3 - diff --git a/0017-x86-rhel-9.4.0-machine-type-compat-fix.patch b/0017-x86-rhel-9.4.0-machine-type-compat-fix.patch new file mode 100644 index 0000000..5befe68 --- /dev/null +++ b/0017-x86-rhel-9.4.0-machine-type-compat-fix.patch @@ -0,0 +1,30 @@ +From ba574acacf679850e337ec2d5e7836b8277cf393 Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Thu, 18 Apr 2024 15:04:28 +0200 +Subject: x86: rhel 9.4.0 machine type compat fix + +Fix up the compatibility for 9.4.0. Ensure that pc-q35-rhel9.4.0 +still uses SMBIOS 3.X by default. + +Signed-off-by: Sebastian Ott +--- + hw/i386/pc_q35.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 2b54944c0f..2f11f9af7d 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -734,6 +734,9 @@ static void pc_q35_machine_rhel940_options(MachineClass *m) + pcmc->smbios_stream_product = "RHEL"; + pcmc->smbios_stream_version = "9.4.0"; + ++ /* From pc_q35_8_2_machine_options() - use SMBIOS 3.X by default */ ++ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64; ++ + compat_props_add(m->compat_props, hw_compat_rhel_9_5, + hw_compat_rhel_9_5_len); + } +-- +2.39.3 + diff --git a/kvm-Compile-IOMMUFD-object-on-aarch64.patch b/kvm-Compile-IOMMUFD-object-on-aarch64.patch deleted file mode 100644 index ed776c0..0000000 --- a/kvm-Compile-IOMMUFD-object-on-aarch64.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 363d6aedc82314a70bdfbe9fa23b7e8fdda50138 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 11 Jan 2024 12:26:19 -0500 -Subject: [PATCH 066/101] Compile IOMMUFD object on aarch64 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [65/67] 9358030fdd499c5fe122dee3bb4f114966fac9c2 (eauger1/centos-qemu-kvm) - -Upstream: RHEL only - -Compiles the IOMMUFD object on aarch64 to be able to use -the IOMMUFD VFIO backend. - -Signed-off-by: Eric Auger ---- - configs/devices/aarch64-softmmu/aarch64-rh-devices.mak | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak -index aec1831199..b0191d3c69 100644 ---- a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak -+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak -@@ -39,3 +39,4 @@ CONFIG_PXB=y - CONFIG_VHOST_VSOCK=y - CONFIG_VHOST_USER_VSOCK=y - CONFIG_VHOST_USER_FS=y -+CONFIG_IOMMUFD=y --- -2.39.3 - diff --git a/kvm-Compile-IOMMUFD-on-s390x.patch b/kvm-Compile-IOMMUFD-on-s390x.patch deleted file mode 100644 index 9a98477..0000000 --- a/kvm-Compile-IOMMUFD-on-s390x.patch +++ /dev/null @@ -1,37 +0,0 @@ -From c1e9ddf8d0ea6d358fcaa5cacd3a91920f36e73b Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 11 Jan 2024 12:33:17 -0500 -Subject: [PATCH 067/101] Compile IOMMUFD on s390x -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [66/67] d3004aafca2bb76d817ac99c3d65973b8fbd4557 (eauger1/centos-qemu-kvm) - -Upstream: RHEL only - -Compiles the IOMMUFD object on s390x to be able to use -the IOMMUFD VFIO backend. - -Signed-off-by: Eric Auger ---- - configs/devices/s390x-softmmu/s390x-rh-devices.mak | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/configs/devices/s390x-softmmu/s390x-rh-devices.mak b/configs/devices/s390x-softmmu/s390x-rh-devices.mak -index 69a799adbd..24cf6dbd03 100644 ---- a/configs/devices/s390x-softmmu/s390x-rh-devices.mak -+++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak -@@ -16,3 +16,4 @@ CONFIG_WDT_DIAG288=y - CONFIG_VHOST_VSOCK=y - CONFIG_VHOST_USER_VSOCK=y - CONFIG_VHOST_USER_FS=y -+CONFIG_IOMMUFD=y --- -2.39.3 - diff --git a/kvm-Compile-IOMMUFD-on-x86_64.patch b/kvm-Compile-IOMMUFD-on-x86_64.patch deleted file mode 100644 index a3eb40e..0000000 --- a/kvm-Compile-IOMMUFD-on-x86_64.patch +++ /dev/null @@ -1,37 +0,0 @@ -From be2c3d9bbee1bdec061c901f507bc999fa40a53e Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 11 Jan 2024 12:34:44 -0500 -Subject: [PATCH 068/101] Compile IOMMUFD on x86_64 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [67/67] 411d48a5cc7ce1f05be793fd9a89c143ce34c91a (eauger1/centos-qemu-kvm) - -Upstream: RHEL only - -Compiles the IOMMUFD object on s390x to be able to use -the IOMMUFD VFIO backend. - -Signed-off-by: Eric Auger ---- - configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -index ce5be73633..ba41108e0c 100644 ---- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -@@ -108,3 +108,4 @@ CONFIG_SGX=y - CONFIG_VHOST_VSOCK=y - CONFIG_VHOST_USER_VSOCK=y - CONFIG_VHOST_USER_FS=y -+CONFIG_IOMMUFD=y --- -2.39.3 - diff --git a/kvm-Implement-SMBIOS-type-9-v2.6.patch b/kvm-Implement-SMBIOS-type-9-v2.6.patch deleted file mode 100644 index 31439d7..0000000 --- a/kvm-Implement-SMBIOS-type-9-v2.6.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 5c639f8ce65183ce8e44ee8e0230e9d627a440d7 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Wed, 21 Feb 2024 17:00:27 +0000 -Subject: [PATCH 05/20] Implement SMBIOS type 9 v2.6 - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [3/18] ead230527d93938907a561cf5b985ee4f54d82b1 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 -Author: Felix Wu - - Signed-off-by: Felix Wu - Signed-off-by: Nabih Estefan - Message-Id: <20240221170027.1027325-3-nabihestefan@google.com> - Reviewed-by: Michael S. Tsirkin - Signed-off-by: Michael S. Tsirkin - -(cherry picked from commit 04f143d828845d0fd52dd4a52664d81a4f5431f7) -Signed-off-by: Igor Mammedov ---- - hw/smbios/smbios.c | 49 +++++++++++++++++++++++++++++++++--- - include/hw/firmware/smbios.h | 4 +++ - qemu-options.hx | 2 +- - 3 files changed, 51 insertions(+), 4 deletions(-) - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 4f5637d445..074705fa4c 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -124,7 +124,7 @@ static QTAILQ_HEAD(, type8_instance) type8 = QTAILQ_HEAD_INITIALIZER(type8); - - /* type 9 instance for parsing */ - struct type9_instance { -- const char *slot_designation; -+ const char *slot_designation, *pcidev; - uint8_t slot_type, slot_data_bus_width, current_usage, slot_length, - slot_characteristics1, slot_characteristics2; - uint16_t slot_id; -@@ -427,6 +427,11 @@ static const QemuOptDesc qemu_smbios_type9_opts[] = { - .type = QEMU_OPT_NUMBER, - .help = "slot characteristics2, see the spec", - }, -+ { -+ .name = "pci_device", -+ .type = QEMU_OPT_STRING, -+ .help = "PCI device, if provided." -+ } - }; - - static const QemuOptDesc qemu_smbios_type11_opts[] = { -@@ -851,7 +856,7 @@ static void smbios_build_type_8_table(void) - } - } - --static void smbios_build_type_9_table(void) -+static void smbios_build_type_9_table(Error **errp) - { - unsigned instance = 0; - struct type9_instance *t9; -@@ -868,6 +873,43 @@ static void smbios_build_type_9_table(void) - t->slot_characteristics1 = t9->slot_characteristics1; - t->slot_characteristics2 = t9->slot_characteristics2; - -+ if (t9->pcidev) { -+ PCIDevice *pdev = NULL; -+ int rc = pci_qdev_find_device(t9->pcidev, &pdev); -+ if (rc != 0) { -+ error_setg(errp, -+ "No PCI device %s for SMBIOS type 9 entry %s", -+ t9->pcidev, t9->slot_designation); -+ return; -+ } -+ /* -+ * We only handle the case were the device is attached to -+ * the PCI root bus. The general case is more complex as -+ * bridges are enumerated later and the table would need -+ * to be updated at this moment. -+ */ -+ if (!pci_bus_is_root(pci_get_bus(pdev))) { -+ error_setg(errp, -+ "Cannot create type 9 entry for PCI device %s: " -+ "not attached to the root bus", -+ t9->pcidev); -+ return; -+ } -+ t->segment_group_number = cpu_to_le16(0); -+ t->bus_number = pci_dev_bus_num(pdev); -+ t->device_number = pdev->devfn; -+ } else { -+ /* -+ * Per SMBIOS spec, For slots that are not of the PCI, AGP, PCI-X, -+ * or PCI-Express type that do not have bus/device/function -+ * information, 0FFh should be populated in the fields of Segment -+ * Group Number, Bus Number, Device/Function Number. -+ */ -+ t->segment_group_number = 0xff; -+ t->bus_number = 0xff; -+ t->device_number = 0xff; -+ } -+ - SMBIOS_BUILD_TABLE_POST; - instance++; - } -@@ -1222,7 +1264,7 @@ void smbios_get_tables(MachineState *ms, - } - - smbios_build_type_8_table(); -- smbios_build_type_9_table(); -+ smbios_build_type_9_table(errp); - smbios_build_type_11_table(); - - #define MAX_DIMM_SZ (16 * GiB) -@@ -1568,6 +1610,7 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) - t->slot_id = qemu_opt_get_number(opts, "slot_id", 0); - t->slot_characteristics1 = qemu_opt_get_number(opts, "slot_characteristics1", 0); - t->slot_characteristics2 = qemu_opt_get_number(opts, "slot_characteristics2", 0); -+ save_opt(&t->pcidev, opts, "pcidev"); - QTAILQ_INSERT_TAIL(&type9, t, next); - return; - } -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index 6bbd5a4c20..f8dd07fe4c 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -222,6 +222,10 @@ struct smbios_type_9 { - uint16_t slot_id; - uint8_t slot_characteristics1; - uint8_t slot_characteristics2; -+ /* SMBIOS spec v2.6+ */ -+ uint16_t segment_group_number; -+ uint8_t bus_number; -+ uint8_t device_number; - } QEMU_PACKED; - - /* SMBIOS type 11 - OEM strings */ -diff --git a/qemu-options.hx b/qemu-options.hx -index 94cacc2c63..93364e1765 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -2710,7 +2710,7 @@ SRST - ``-smbios type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str][,asset=str][,part=str][,processor-id=%d]`` - Specify SMBIOS type 4 fields - --``-smbios type=9[,slot_designation=str][,slot_type=%d][,slot_data_bus_width=%d][,current_usage=%d][,slot_length=%d][,slot_id=%d][,slot_characteristics1=%d][,slot_characteristics12=%d]`` -+``-smbios type=9[,slot_designation=str][,slot_type=%d][,slot_data_bus_width=%d][,current_usage=%d][,slot_length=%d][,slot_id=%d][,slot_characteristics1=%d][,slot_characteristics12=%d][,pci_device=str]`` - Specify SMBIOS type 9 fields - - ``-smbios type=11[,value=str][,path=filename]`` --- -2.39.3 - diff --git a/kvm-Implement-base-of-SMBIOS-type-9-descriptor.patch b/kvm-Implement-base-of-SMBIOS-type-9-descriptor.patch deleted file mode 100644 index 89466c7..0000000 --- a/kvm-Implement-base-of-SMBIOS-type-9-descriptor.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 84fc607d678bd72397a41d706e91fa241fd97266 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Wed, 21 Feb 2024 17:00:26 +0000 -Subject: [PATCH 04/20] Implement base of SMBIOS type 9 descriptor. - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [2/18] 2678cc080bfbf3357fa2f94ceaf42fc61b690d32 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -commit: 735eee07d1f963635d3c3bf9f5e4bf1bc000870e -Author: Felix Wu - - Version 2.1+. - - Signed-off-by: Felix Wu - Signed-off-by: Nabih Estefan - Message-Id: <20240221170027.1027325-2-nabihestefan@google.com> - Reviewed-by: Michael S. Tsirkin - Signed-off-by: Michael S. Tsirkin - -Signed-off-by: Igor Mammedov ---- - hw/smbios/smbios.c | 99 ++++++++++++++++++++++++++++++++++++ - include/hw/firmware/smbios.h | 13 +++++ - qemu-options.hx | 3 ++ - 3 files changed, 115 insertions(+) - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 7bde23e59d..4f5637d445 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -122,6 +122,16 @@ struct type8_instance { - }; - static QTAILQ_HEAD(, type8_instance) type8 = QTAILQ_HEAD_INITIALIZER(type8); - -+/* type 9 instance for parsing */ -+struct type9_instance { -+ const char *slot_designation; -+ uint8_t slot_type, slot_data_bus_width, current_usage, slot_length, -+ slot_characteristics1, slot_characteristics2; -+ uint16_t slot_id; -+ QTAILQ_ENTRY(type9_instance) next; -+}; -+static QTAILQ_HEAD(, type9_instance) type9 = QTAILQ_HEAD_INITIALIZER(type9); -+ - static struct { - size_t nvalues; - char **values; -@@ -371,6 +381,54 @@ static const QemuOptDesc qemu_smbios_type8_opts[] = { - }, - }; - -+static const QemuOptDesc qemu_smbios_type9_opts[] = { -+ { -+ .name = "type", -+ .type = QEMU_OPT_NUMBER, -+ .help = "SMBIOS element type", -+ }, -+ { -+ .name = "slot_designation", -+ .type = QEMU_OPT_STRING, -+ .help = "string number for reference designation", -+ }, -+ { -+ .name = "slot_type", -+ .type = QEMU_OPT_NUMBER, -+ .help = "connector type", -+ }, -+ { -+ .name = "slot_data_bus_width", -+ .type = QEMU_OPT_NUMBER, -+ .help = "port type", -+ }, -+ { -+ .name = "current_usage", -+ .type = QEMU_OPT_NUMBER, -+ .help = "current usage", -+ }, -+ { -+ .name = "slot_length", -+ .type = QEMU_OPT_NUMBER, -+ .help = "system slot length", -+ }, -+ { -+ .name = "slot_id", -+ .type = QEMU_OPT_NUMBER, -+ .help = "system slot id", -+ }, -+ { -+ .name = "slot_characteristics1", -+ .type = QEMU_OPT_NUMBER, -+ .help = "slot characteristics1, see the spec", -+ }, -+ { -+ .name = "slot_characteristics2", -+ .type = QEMU_OPT_NUMBER, -+ .help = "slot characteristics2, see the spec", -+ }, -+}; -+ - static const QemuOptDesc qemu_smbios_type11_opts[] = { - { - .name = "value", -@@ -594,6 +652,7 @@ bool smbios_skip_table(uint8_t type, bool required_table) - #define T2_BASE 0x200 - #define T3_BASE 0x300 - #define T4_BASE 0x400 -+#define T9_BASE 0x900 - #define T11_BASE 0xe00 - - #define T16_BASE 0x1000 -@@ -792,6 +851,28 @@ static void smbios_build_type_8_table(void) - } - } - -+static void smbios_build_type_9_table(void) -+{ -+ unsigned instance = 0; -+ struct type9_instance *t9; -+ -+ QTAILQ_FOREACH(t9, &type9, next) { -+ SMBIOS_BUILD_TABLE_PRE(9, T9_BASE + instance, true); -+ -+ SMBIOS_TABLE_SET_STR(9, slot_designation, t9->slot_designation); -+ t->slot_type = t9->slot_type; -+ t->slot_data_bus_width = t9->slot_data_bus_width; -+ t->current_usage = t9->current_usage; -+ t->slot_length = t9->slot_length; -+ t->slot_id = t9->slot_id; -+ t->slot_characteristics1 = t9->slot_characteristics1; -+ t->slot_characteristics2 = t9->slot_characteristics2; -+ -+ SMBIOS_BUILD_TABLE_POST; -+ instance++; -+ } -+} -+ - static void smbios_build_type_11_table(void) - { - char count_str[128]; -@@ -1141,6 +1222,7 @@ void smbios_get_tables(MachineState *ms, - } - - smbios_build_type_8_table(); -+ smbios_build_type_9_table(); - smbios_build_type_11_table(); - - #define MAX_DIMM_SZ (16 * GiB) -@@ -1472,6 +1554,23 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) - t8_i->port_type = qemu_opt_get_number(opts, "port_type", 0); - QTAILQ_INSERT_TAIL(&type8, t8_i, next); - return; -+ case 9: { -+ if (!qemu_opts_validate(opts, qemu_smbios_type9_opts, errp)) { -+ return; -+ } -+ struct type9_instance *t; -+ t = g_new0(struct type9_instance, 1); -+ save_opt(&t->slot_designation, opts, "slot_designation"); -+ t->slot_type = qemu_opt_get_number(opts, "slot_type", 0); -+ t->slot_data_bus_width = qemu_opt_get_number(opts, "slot_data_bus_width", 0); -+ t->current_usage = qemu_opt_get_number(opts, "current_usage", 0); -+ t->slot_length = qemu_opt_get_number(opts, "slot_length", 0); -+ t->slot_id = qemu_opt_get_number(opts, "slot_id", 0); -+ t->slot_characteristics1 = qemu_opt_get_number(opts, "slot_characteristics1", 0); -+ t->slot_characteristics2 = qemu_opt_get_number(opts, "slot_characteristics2", 0); -+ QTAILQ_INSERT_TAIL(&type9, t, next); -+ return; -+ } - case 11: - if (!qemu_opts_validate(opts, qemu_smbios_type11_opts, errp)) { - return; -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index d24b3ccd32..6bbd5a4c20 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -211,6 +211,19 @@ struct smbios_type_8 { - uint8_t port_type; - } QEMU_PACKED; - -+/* SMBIOS type 9 - System Slots (v2.1+) */ -+struct smbios_type_9 { -+ struct smbios_structure_header header; -+ uint8_t slot_designation; -+ uint8_t slot_type; -+ uint8_t slot_data_bus_width; -+ uint8_t current_usage; -+ uint8_t slot_length; -+ uint16_t slot_id; -+ uint8_t slot_characteristics1; -+ uint8_t slot_characteristics2; -+} QEMU_PACKED; -+ - /* SMBIOS type 11 - OEM strings */ - struct smbios_type_11 { - struct smbios_structure_header header; -diff --git a/qemu-options.hx b/qemu-options.hx -index 0814f43066..94cacc2c63 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -2710,6 +2710,9 @@ SRST - ``-smbios type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str][,asset=str][,part=str][,processor-id=%d]`` - Specify SMBIOS type 4 fields - -+``-smbios type=9[,slot_designation=str][,slot_type=%d][,slot_data_bus_width=%d][,current_usage=%d][,slot_length=%d][,slot_id=%d][,slot_characteristics1=%d][,slot_characteristics12=%d]`` -+ Specify SMBIOS type 9 fields -+ - ``-smbios type=11[,value=str][,path=filename]`` - Specify SMBIOS type 11 fields - --- -2.39.3 - diff --git a/kvm-Revert-chardev-char-socket-Fix-TLS-io-channels-sendi.patch b/kvm-Revert-chardev-char-socket-Fix-TLS-io-channels-sendi.patch deleted file mode 100644 index bc0f15a..0000000 --- a/kvm-Revert-chardev-char-socket-Fix-TLS-io-channels-sendi.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 2e0e4355b2d4edb66b7d8c198339e17940abd682 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= -Date: Mon, 18 Mar 2024 13:03:19 +0000 -Subject: [PATCH 2/3] Revert "chardev/char-socket: Fix TLS io channels sending - too much data to the backend" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Daniel P. Berrangé -RH-MergeRequest: 233: Fix handling of TLS sessions in chardevs -RH-Jira: RHEL-24614 -RH-Acked-by: Thomas Huth -RH-Acked-by: Marc-André Lureau -RH-Commit: [2/3] 1cb3d72b86ced0f70a09dfa0d325ae8a85db1b2b (berrange/centos-src-qemu) - -This commit results in unexpected termination of the TLS connection. -When 'fd_can_read' returns 0, the code goes on to pass a zero length -buffer to qio_channel_read. The TLS impl calls into gnutls_recv() -with this zero length buffer, at which point GNUTLS returns an error -GNUTLS_E_INVALID_REQUEST. This is treated as fatal by QEMU's TLS code -resulting in the connection being torn down by the chardev. - -Simply skipping the qio_channel_read when the buffer length is zero -is also not satisfactory, as it results in a high CPU burn busy loop -massively slowing QEMU's functionality. - -The proper solution is to avoid tcp_chr_read being called at all -unless the frontend is able to accept more data. This will be done -in a followup commit. - -This reverts commit 462945cd22d2bcd233401ed3aa167d83a8e35b05 - -Reviewed-by: Thomas Huth -Signed-off-by: Daniel P. Berrangé -(cherry picked from commit e8ee827ffdb86ebbd5f5213a1f78123c25a90864) ---- - chardev/char-socket.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/chardev/char-socket.c b/chardev/char-socket.c -index f48d341ebc..51d0943fce 100644 ---- a/chardev/char-socket.c -+++ b/chardev/char-socket.c -@@ -492,9 +492,9 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) - s->max_size <= 0) { - return TRUE; - } -- len = tcp_chr_read_poll(opaque); -- if (len > sizeof(buf)) { -- len = sizeof(buf); -+ len = sizeof(buf); -+ if (len > s->max_size) { -+ len = s->max_size; - } - size = tcp_chr_recv(chr, (void *)buf, len); - if (size == 0 || (size == -1 && errno != EAGAIN)) { --- -2.39.3 - diff --git a/kvm-Revert-chardev-use-a-child-source-for-qio-input-sour.patch b/kvm-Revert-chardev-use-a-child-source-for-qio-input-sour.patch deleted file mode 100644 index 135afbe..0000000 --- a/kvm-Revert-chardev-use-a-child-source-for-qio-input-sour.patch +++ /dev/null @@ -1,216 +0,0 @@ -From ab5a33d57b48e35388928e388bb6e6479bc77651 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= -Date: Mon, 18 Mar 2024 17:08:30 +0000 -Subject: [PATCH 3/3] Revert "chardev: use a child source for qio input source" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Daniel P. Berrangé -RH-MergeRequest: 233: Fix handling of TLS sessions in chardevs -RH-Jira: RHEL-24614 -RH-Acked-by: Thomas Huth -RH-Acked-by: Marc-André Lureau -RH-Commit: [3/3] b58e6c19c2b11d5d28db31cf1386226fb01d195e (berrange/centos-src-qemu) - -This reverts commit a7077b8e354d90fec26c2921aa2dea85b90dff90, -and add comments to explain why child sources cannot be used. - -When a GSource is added as a child of another GSource, if its -'prepare' function indicates readiness, then the parent's -'prepare' function will never be run. The io_watch_poll_prepare -absolutely *must* be run on every iteration of the main loop, -to ensure that the chardev backend doesn't feed data to the -frontend that it is unable to consume. - -At the time a7077b8e354d90fec26c2921aa2dea85b90dff90 was made, -all the child GSource impls were relying on poll'ing an FD, -so their 'prepare' functions would never indicate readiness -ahead of poll() being invoked. So the buggy behaviour was -not noticed and lay dormant. - -Relatively recently the QIOChannelTLS impl introduced a -level 2 child GSource, which checks with GNUTLS whether it -has cached any data that was decoded but not yet consumed: - - commit ffda5db65aef42266a5053a4be34515106c4c7ee - Author: Antoine Damhet - Date: Tue Nov 15 15:23:29 2022 +0100 - - io/channel-tls: fix handling of bigger read buffers - - Since the TLS backend can read more data from the underlying QIOChannel - we introduce a minimal child GSource to notify if we still have more - data available to be read. - - Signed-off-by: Antoine Damhet - Signed-off-by: Charles Frey - Signed-off-by: Daniel P. Berrangé - -With this, it is now quite common for the 'prepare' function -on a QIOChannelTLS GSource to indicate immediate readiness, -bypassing the parent GSource 'prepare' function. IOW, the -critical 'io_watch_poll_prepare' is being skipped on some -iterations of the main loop. As a result chardev frontend -asserts are now being triggered as they are fed data they -are not ready to consume. - -A reproducer is as follows: - - * In terminal 1 run a GNUTLS *echo* server - - $ gnutls-serv --echo \ - --x509cafile ca-cert.pem \ - --x509keyfile server-key.pem \ - --x509certfile server-cert.pem \ - -p 9000 - - * In terminal 2 run a QEMU guest - - $ qemu-system-s390x \ - -nodefaults \ - -display none \ - -object tls-creds-x509,id=tls0,dir=$PWD,endpoint=client \ - -chardev socket,id=con0,host=localhost,port=9000,tls-creds=tls0 \ - -device sclpconsole,chardev=con0 \ - -hda Fedora-Cloud-Base-39-1.5.s390x.qcow2 - -After the previous patch revert, but before this patch revert, -this scenario will crash: - - qemu-system-s390x: ../hw/char/sclpconsole.c:73: chr_read: Assertion - `size <= SIZE_BUFFER_VT220 - scon->iov_data_len' failed. - -This assert indicates that 'tcp_chr_read' was called without -'tcp_chr_read_poll' having first been checked for ability to -receive more data - -QEMU's use of a 'prepare' function to create/delete another -GSource is rather a hack and not normally the kind of thing that -is expected to be done by a GSource. There is no mechanism to -force GLib to always run the 'prepare' function of a parent -GSource. The best option is to simply not use the child source -concept, and go back to the functional approach previously -relied on. - -Reviewed-by: Marc-André Lureau -Reviewed-by: Thomas Huth -Tested-by: Thomas Huth -Signed-off-by: Daniel P. Berrangé -(cherry picked from commit 038b4217884c6f297278bb1ec6f0463c6c8221de) ---- - chardev/char-io.c | 56 ++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 51 insertions(+), 5 deletions(-) - -diff --git a/chardev/char-io.c b/chardev/char-io.c -index 4451128cba..dab77b112e 100644 ---- a/chardev/char-io.c -+++ b/chardev/char-io.c -@@ -33,6 +33,7 @@ typedef struct IOWatchPoll { - IOCanReadHandler *fd_can_read; - GSourceFunc fd_read; - void *opaque; -+ GMainContext *context; - } IOWatchPoll; - - static IOWatchPoll *io_watch_poll_from_source(GSource *source) -@@ -50,28 +51,59 @@ static gboolean io_watch_poll_prepare(GSource *source, - return FALSE; - } - -+ /* -+ * We do not register the QIOChannel watch as a child GSource. -+ * The 'prepare' function on the parent GSource will be -+ * skipped if a child GSource's 'prepare' function indicates -+ * readiness. We need this prepare function be guaranteed -+ * to run on *every* iteration of the main loop, because -+ * it is critical to ensure we remove the QIOChannel watch -+ * if 'fd_can_read' indicates the frontend cannot receive -+ * more data. -+ */ - if (now_active) { - iwp->src = qio_channel_create_watch( - iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL); - g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL); -- g_source_add_child_source(source, iwp->src); -- g_source_unref(iwp->src); -+ g_source_attach(iwp->src, iwp->context); - } else { -- g_source_remove_child_source(source, iwp->src); -+ g_source_destroy(iwp->src); -+ g_source_unref(iwp->src); - iwp->src = NULL; - } - return FALSE; - } - -+static gboolean io_watch_poll_check(GSource *source) -+{ -+ return FALSE; -+} -+ - static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback, - gpointer user_data) - { -- return G_SOURCE_CONTINUE; -+ abort(); -+} -+ -+static void io_watch_poll_finalize(GSource *source) -+{ -+ /* -+ * Due to a glib bug, removing the last reference to a source -+ * inside a finalize callback causes recursive locking (and a -+ * deadlock). This is not a problem inside other callbacks, -+ * including dispatch callbacks, so we call io_remove_watch_poll -+ * to remove this source. At this point, iwp->src must -+ * be NULL, or we would leak it. -+ */ -+ IOWatchPoll *iwp = io_watch_poll_from_source(source); -+ assert(iwp->src == NULL); - } - - static GSourceFuncs io_watch_poll_funcs = { - .prepare = io_watch_poll_prepare, -+ .check = io_watch_poll_check, - .dispatch = io_watch_poll_dispatch, -+ .finalize = io_watch_poll_finalize, - }; - - GSource *io_add_watch_poll(Chardev *chr, -@@ -91,6 +123,7 @@ GSource *io_add_watch_poll(Chardev *chr, - iwp->ioc = ioc; - iwp->fd_read = (GSourceFunc) fd_read; - iwp->src = NULL; -+ iwp->context = context; - - name = g_strdup_printf("chardev-iowatch-%s", chr->label); - g_source_set_name((GSource *)iwp, name); -@@ -101,10 +134,23 @@ GSource *io_add_watch_poll(Chardev *chr, - return (GSource *)iwp; - } - -+static void io_remove_watch_poll(GSource *source) -+{ -+ IOWatchPoll *iwp; -+ -+ iwp = io_watch_poll_from_source(source); -+ if (iwp->src) { -+ g_source_destroy(iwp->src); -+ g_source_unref(iwp->src); -+ iwp->src = NULL; -+ } -+ g_source_destroy(&iwp->parent); -+} -+ - void remove_fd_in_watch(Chardev *chr) - { - if (chr->gsource) { -- g_source_destroy(chr->gsource); -+ io_remove_watch_poll(chr->gsource); - chr->gsource = NULL; - } - } --- -2.39.3 - diff --git a/kvm-aio-make-aio_context_acquire-aio_context_release-a-n.patch b/kvm-aio-make-aio_context_acquire-aio_context_release-a-n.patch deleted file mode 100644 index f30b81f..0000000 --- a/kvm-aio-make-aio_context_acquire-aio_context_release-a-n.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 6b5cfed21e20b372090046a934387255ff4bda58 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:01 -0500 -Subject: [PATCH 084/101] aio: make aio_context_acquire()/aio_context_release() - a no-op - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [15/26] 723dcada900aaf08862e8221921be22506b561a8 (kmwolf/centos-qemu-kvm) - -aio_context_acquire()/aio_context_release() has been replaced by -fine-grained locking to protect state shared by multiple threads. The -AioContext lock still plays the role of balancing locking in -AIO_WAIT_WHILE() and many functions in QEMU either require that the -AioContext lock is held or not held for this reason. In other words, the -AioContext lock is purely there for consistency with itself and serves -no real purpose anymore. - -Stop actually acquiring/releasing the lock in -aio_context_acquire()/aio_context_release() so that subsequent patches -can remove callers across the codebase incrementally. - -I have performed "make check" and qemu-iotests stress tests across -x86-64, ppc64le, and aarch64 to confirm that there are no failures as a -result of eliminating the lock. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Acked-by: Kevin Wolf -Message-ID: <20231205182011.1976568-5-stefanha@redhat.com> -Signed-off-by: Kevin Wolf ---- - util/async.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/util/async.c b/util/async.c -index 8f90ddc304..04ee83d220 100644 ---- a/util/async.c -+++ b/util/async.c -@@ -725,12 +725,12 @@ void aio_context_unref(AioContext *ctx) - - void aio_context_acquire(AioContext *ctx) - { -- qemu_rec_mutex_lock(&ctx->lock); -+ /* TODO remove this function */ - } - - void aio_context_release(AioContext *ctx) - { -- qemu_rec_mutex_unlock(&ctx->lock); -+ /* TODO remove this function */ - } - - QEMU_DEFINE_STATIC_CO_TLS(AioContext *, my_aiocontext) --- -2.39.3 - diff --git a/kvm-aio-remove-aio_context_acquire-aio_context_release-A.patch b/kvm-aio-remove-aio_context_acquire-aio_context_release-A.patch deleted file mode 100644 index a64e246..0000000 --- a/kvm-aio-remove-aio_context_acquire-aio_context_release-A.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 14913d8970090c8914dc19dad14f3b9f91985ec3 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:07 -0500 -Subject: [PATCH 090/101] aio: remove - aio_context_acquire()/aio_context_release() API - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [21/26] 4b6d4afcac79d3248a6722b063b5fc777dc418df (kmwolf/centos-qemu-kvm) - -Delete these functions because nothing calls these functions anymore. - -I introduced these APIs in commit 98563fc3ec44 ("aio: add -aio_context_acquire() and aio_context_release()") in 2014. It's with a -sigh of relief that I delete these APIs almost 10 years later. - -Thanks to Paolo Bonzini's vision for multi-queue QEMU, we got an -understanding of where the code needed to go in order to remove the -limitations that the original dataplane and the IOThread/AioContext -approach that followed it. - -Emanuele Giuseppe Esposito had the splendid determination to convert -large parts of the codebase so that they no longer needed the AioContext -lock. This was a painstaking process, both in the actual code changes -required and the iterations of code review that Emanuele eked out of -Kevin and me over many months. - -Kevin Wolf tackled multitudes of graph locking conversions to protect -in-flight I/O from run-time changes to the block graph as well as the -clang Thread Safety Analysis annotations that allow the compiler to -check whether the graph lock is being used correctly. - -And me, well, I'm just here to add some pizzazz to the QEMU multi-queue -block layer :). Thank you to everyone who helped with this effort, -including Eric Blake, code reviewer extraordinaire, and others who I've -forgotten to mention. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Message-ID: <20231205182011.1976568-11-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - include/block/aio.h | 17 ----------------- - util/async.c | 10 ---------- - 2 files changed, 27 deletions(-) - -diff --git a/include/block/aio.h b/include/block/aio.h -index f08b358077..af05512a7d 100644 ---- a/include/block/aio.h -+++ b/include/block/aio.h -@@ -278,23 +278,6 @@ void aio_context_ref(AioContext *ctx); - */ - void aio_context_unref(AioContext *ctx); - --/* Take ownership of the AioContext. If the AioContext will be shared between -- * threads, and a thread does not want to be interrupted, it will have to -- * take ownership around calls to aio_poll(). Otherwise, aio_poll() -- * automatically takes care of calling aio_context_acquire and -- * aio_context_release. -- * -- * Note that this is separate from bdrv_drained_begin/bdrv_drained_end. A -- * thread still has to call those to avoid being interrupted by the guest. -- * -- * Bottom halves, timers and callbacks can be created or removed without -- * acquiring the AioContext. -- */ --void aio_context_acquire(AioContext *ctx); -- --/* Relinquish ownership of the AioContext. */ --void aio_context_release(AioContext *ctx); -- - /** - * aio_bh_schedule_oneshot_full: Allocate a new bottom half structure that will - * run only once and as soon as possible. -diff --git a/util/async.c b/util/async.c -index dfd44ef612..460529057c 100644 ---- a/util/async.c -+++ b/util/async.c -@@ -719,16 +719,6 @@ void aio_context_unref(AioContext *ctx) - g_source_unref(&ctx->source); - } - --void aio_context_acquire(AioContext *ctx) --{ -- /* TODO remove this function */ --} -- --void aio_context_release(AioContext *ctx) --{ -- /* TODO remove this function */ --} -- - QEMU_DEFINE_STATIC_CO_TLS(AioContext *, my_aiocontext) - - AioContext *qemu_get_current_aio_context(void) --- -2.39.3 - diff --git a/kvm-aio-wait-draw-equivalence-between-AIO_WAIT_WHILE-and.patch b/kvm-aio-wait-draw-equivalence-between-AIO_WAIT_WHILE-and.patch deleted file mode 100644 index 7f95b67..0000000 --- a/kvm-aio-wait-draw-equivalence-between-AIO_WAIT_WHILE-and.patch +++ /dev/null @@ -1,81 +0,0 @@ -From e1e2f3972065c4b5d6fcf37e0e1c4fb92a0d5260 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:06 -0500 -Subject: [PATCH 089/101] aio-wait: draw equivalence between AIO_WAIT_WHILE() - and AIO_WAIT_WHILE_UNLOCKED() - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [20/26] 20e49777869714c99769263103f1b0c2c370cfcd (kmwolf/centos-qemu-kvm) - -Now that the AioContext lock no longer exists, AIO_WAIT_WHILE() and -AIO_WAIT_WHILE_UNLOCKED() are equivalent. - -A future patch will get rid of AIO_WAIT_WHILE_UNLOCKED(). - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Message-ID: <20231205182011.1976568-10-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - include/block/aio-wait.h | 16 ++++------------ - 1 file changed, 4 insertions(+), 12 deletions(-) - -diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h -index 5449b6d742..157f105916 100644 ---- a/include/block/aio-wait.h -+++ b/include/block/aio-wait.h -@@ -63,9 +63,6 @@ extern AioWait global_aio_wait; - * @ctx: the aio context, or NULL if multiple aio contexts (for which the - * caller does not hold a lock) are involved in the polling condition. - * @cond: wait while this conditional expression is true -- * @unlock: whether to unlock and then lock again @ctx. This applies -- * only when waiting for another AioContext from the main loop. -- * Otherwise it's ignored. - * - * Wait while a condition is true. Use this to implement synchronous - * operations that require event loop activity. -@@ -78,7 +75,7 @@ extern AioWait global_aio_wait; - * wait on conditions between two IOThreads since that could lead to deadlock, - * go via the main loop instead. - */ --#define AIO_WAIT_WHILE_INTERNAL(ctx, cond, unlock) ({ \ -+#define AIO_WAIT_WHILE_INTERNAL(ctx, cond) ({ \ - bool waited_ = false; \ - AioWait *wait_ = &global_aio_wait; \ - AioContext *ctx_ = (ctx); \ -@@ -95,13 +92,7 @@ extern AioWait global_aio_wait; - assert(qemu_get_current_aio_context() == \ - qemu_get_aio_context()); \ - while ((cond)) { \ -- if (unlock && ctx_) { \ -- aio_context_release(ctx_); \ -- } \ - aio_poll(qemu_get_aio_context(), true); \ -- if (unlock && ctx_) { \ -- aio_context_acquire(ctx_); \ -- } \ - waited_ = true; \ - } \ - } \ -@@ -109,10 +100,11 @@ extern AioWait global_aio_wait; - waited_; }) - - #define AIO_WAIT_WHILE(ctx, cond) \ -- AIO_WAIT_WHILE_INTERNAL(ctx, cond, true) -+ AIO_WAIT_WHILE_INTERNAL(ctx, cond) - -+/* TODO replace this with AIO_WAIT_WHILE() in a future patch */ - #define AIO_WAIT_WHILE_UNLOCKED(ctx, cond) \ -- AIO_WAIT_WHILE_INTERNAL(ctx, cond, false) -+ AIO_WAIT_WHILE_INTERNAL(ctx, cond) - - /** - * aio_wait_kick: --- -2.39.3 - diff --git a/kvm-backends-iommufd-Introduce-the-iommufd-object.patch b/kvm-backends-iommufd-Introduce-the-iommufd-object.patch deleted file mode 100644 index 898e35b..0000000 --- a/kvm-backends-iommufd-Introduce-the-iommufd-object.patch +++ /dev/null @@ -1,476 +0,0 @@ -From 0d8255c98b3ef6f603ff0279592d3e91de26de0e Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 21 Nov 2023 16:44:00 +0800 -Subject: [PATCH 021/101] backends/iommufd: Introduce the iommufd object -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [20/67] 8a56344ab4a2126f248bfa492ccddd19265f39be (eauger1/centos-qemu-kvm) - -Introduce an iommufd object which allows the interaction -with the host /dev/iommu device. - -The /dev/iommu can have been already pre-opened outside of qemu, -in which case the fd can be passed directly along with the -iommufd object: - -This allows the iommufd object to be shared accross several -subsystems (VFIO, VDPA, ...). For example, libvirt would open -the /dev/iommu once. - -If no fd is passed along with the iommufd object, the /dev/iommu -is opened by the qemu code. - -Suggested-by: Alex Williamson -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 6e6d8ac62b5b38dc9d4b69ffdf073f0a0b43b7be) -Signed-off-by: Eric Auger ---- - MAINTAINERS | 8 ++ - backends/Kconfig | 4 + - backends/iommufd.c | 245 +++++++++++++++++++++++++++++++++++++++ - backends/meson.build | 1 + - backends/trace-events | 10 ++ - include/sysemu/iommufd.h | 38 ++++++ - qapi/qom.json | 19 +++ - qemu-options.hx | 12 ++ - 8 files changed, 337 insertions(+) - create mode 100644 backends/iommufd.c - create mode 100644 include/sysemu/iommufd.h - -diff --git a/MAINTAINERS b/MAINTAINERS -index 695e0bd34f..a5a446914a 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2167,6 +2167,14 @@ F: hw/vfio/ap.c - F: docs/system/s390x/vfio-ap.rst - L: qemu-s390x@nongnu.org - -+iommufd -+M: Yi Liu -+M: Eric Auger -+M: Zhenzhong Duan -+S: Supported -+F: backends/iommufd.c -+F: include/sysemu/iommufd.h -+ - vhost - M: Michael S. Tsirkin - S: Supported -diff --git a/backends/Kconfig b/backends/Kconfig -index f35abc1609..2cb23f62fa 100644 ---- a/backends/Kconfig -+++ b/backends/Kconfig -@@ -1 +1,5 @@ - source tpm/Kconfig -+ -+config IOMMUFD -+ bool -+ depends on VFIO -diff --git a/backends/iommufd.c b/backends/iommufd.c -new file mode 100644 -index 0000000000..ba58a0eb0d ---- /dev/null -+++ b/backends/iommufd.c -@@ -0,0 +1,245 @@ -+/* -+ * iommufd container backend -+ * -+ * Copyright (C) 2023 Intel Corporation. -+ * Copyright Red Hat, Inc. 2023 -+ * -+ * Authors: Yi Liu -+ * Eric Auger -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+ -+#include "qemu/osdep.h" -+#include "sysemu/iommufd.h" -+#include "qapi/error.h" -+#include "qapi/qmp/qerror.h" -+#include "qemu/module.h" -+#include "qom/object_interfaces.h" -+#include "qemu/error-report.h" -+#include "monitor/monitor.h" -+#include "trace.h" -+#include -+#include -+ -+static void iommufd_backend_init(Object *obj) -+{ -+ IOMMUFDBackend *be = IOMMUFD_BACKEND(obj); -+ -+ be->fd = -1; -+ be->users = 0; -+ be->owned = true; -+ qemu_mutex_init(&be->lock); -+} -+ -+static void iommufd_backend_finalize(Object *obj) -+{ -+ IOMMUFDBackend *be = IOMMUFD_BACKEND(obj); -+ -+ if (be->owned) { -+ close(be->fd); -+ be->fd = -1; -+ } -+} -+ -+static void iommufd_backend_set_fd(Object *obj, const char *str, Error **errp) -+{ -+ IOMMUFDBackend *be = IOMMUFD_BACKEND(obj); -+ int fd = -1; -+ -+ fd = monitor_fd_param(monitor_cur(), str, errp); -+ if (fd == -1) { -+ error_prepend(errp, "Could not parse remote object fd %s:", str); -+ return; -+ } -+ qemu_mutex_lock(&be->lock); -+ be->fd = fd; -+ be->owned = false; -+ qemu_mutex_unlock(&be->lock); -+ trace_iommu_backend_set_fd(be->fd); -+} -+ -+static bool iommufd_backend_can_be_deleted(UserCreatable *uc) -+{ -+ IOMMUFDBackend *be = IOMMUFD_BACKEND(uc); -+ -+ return !be->users; -+} -+ -+static void iommufd_backend_class_init(ObjectClass *oc, void *data) -+{ -+ UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); -+ -+ ucc->can_be_deleted = iommufd_backend_can_be_deleted; -+ -+ object_class_property_add_str(oc, "fd", NULL, iommufd_backend_set_fd); -+} -+ -+int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp) -+{ -+ int fd, ret = 0; -+ -+ qemu_mutex_lock(&be->lock); -+ if (be->users == UINT32_MAX) { -+ error_setg(errp, "too many connections"); -+ ret = -E2BIG; -+ goto out; -+ } -+ if (be->owned && !be->users) { -+ fd = qemu_open_old("/dev/iommu", O_RDWR); -+ if (fd < 0) { -+ error_setg_errno(errp, errno, "/dev/iommu opening failed"); -+ ret = fd; -+ goto out; -+ } -+ be->fd = fd; -+ } -+ be->users++; -+out: -+ trace_iommufd_backend_connect(be->fd, be->owned, -+ be->users, ret); -+ qemu_mutex_unlock(&be->lock); -+ return ret; -+} -+ -+void iommufd_backend_disconnect(IOMMUFDBackend *be) -+{ -+ qemu_mutex_lock(&be->lock); -+ if (!be->users) { -+ goto out; -+ } -+ be->users--; -+ if (!be->users && be->owned) { -+ close(be->fd); -+ be->fd = -1; -+ } -+out: -+ trace_iommufd_backend_disconnect(be->fd, be->users); -+ qemu_mutex_unlock(&be->lock); -+} -+ -+int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id, -+ Error **errp) -+{ -+ int ret, fd = be->fd; -+ struct iommu_ioas_alloc alloc_data = { -+ .size = sizeof(alloc_data), -+ .flags = 0, -+ }; -+ -+ ret = ioctl(fd, IOMMU_IOAS_ALLOC, &alloc_data); -+ if (ret) { -+ error_setg_errno(errp, errno, "Failed to allocate ioas"); -+ return ret; -+ } -+ -+ *ioas_id = alloc_data.out_ioas_id; -+ trace_iommufd_backend_alloc_ioas(fd, *ioas_id, ret); -+ -+ return ret; -+} -+ -+void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id) -+{ -+ int ret, fd = be->fd; -+ struct iommu_destroy des = { -+ .size = sizeof(des), -+ .id = id, -+ }; -+ -+ ret = ioctl(fd, IOMMU_DESTROY, &des); -+ trace_iommufd_backend_free_id(fd, id, ret); -+ if (ret) { -+ error_report("Failed to free id: %u %m", id); -+ } -+} -+ -+int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova, -+ ram_addr_t size, void *vaddr, bool readonly) -+{ -+ int ret, fd = be->fd; -+ struct iommu_ioas_map map = { -+ .size = sizeof(map), -+ .flags = IOMMU_IOAS_MAP_READABLE | -+ IOMMU_IOAS_MAP_FIXED_IOVA, -+ .ioas_id = ioas_id, -+ .__reserved = 0, -+ .user_va = (uintptr_t)vaddr, -+ .iova = iova, -+ .length = size, -+ }; -+ -+ if (!readonly) { -+ map.flags |= IOMMU_IOAS_MAP_WRITEABLE; -+ } -+ -+ ret = ioctl(fd, IOMMU_IOAS_MAP, &map); -+ trace_iommufd_backend_map_dma(fd, ioas_id, iova, size, -+ vaddr, readonly, ret); -+ if (ret) { -+ ret = -errno; -+ -+ /* TODO: Not support mapping hardware PCI BAR region for now. */ -+ if (errno == EFAULT) { -+ warn_report("IOMMU_IOAS_MAP failed: %m, PCI BAR?"); -+ } else { -+ error_report("IOMMU_IOAS_MAP failed: %m"); -+ } -+ } -+ return ret; -+} -+ -+int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id, -+ hwaddr iova, ram_addr_t size) -+{ -+ int ret, fd = be->fd; -+ struct iommu_ioas_unmap unmap = { -+ .size = sizeof(unmap), -+ .ioas_id = ioas_id, -+ .iova = iova, -+ .length = size, -+ }; -+ -+ ret = ioctl(fd, IOMMU_IOAS_UNMAP, &unmap); -+ /* -+ * IOMMUFD takes mapping as some kind of object, unmapping -+ * nonexistent mapping is treated as deleting a nonexistent -+ * object and return ENOENT. This is different from legacy -+ * backend which allows it. vIOMMU may trigger a lot of -+ * redundant unmapping, to avoid flush the log, treat them -+ * as succeess for IOMMUFD just like legacy backend. -+ */ -+ if (ret && errno == ENOENT) { -+ trace_iommufd_backend_unmap_dma_non_exist(fd, ioas_id, iova, size, ret); -+ ret = 0; -+ } else { -+ trace_iommufd_backend_unmap_dma(fd, ioas_id, iova, size, ret); -+ } -+ -+ if (ret) { -+ ret = -errno; -+ error_report("IOMMU_IOAS_UNMAP failed: %m"); -+ } -+ return ret; -+} -+ -+static const TypeInfo iommufd_backend_info = { -+ .name = TYPE_IOMMUFD_BACKEND, -+ .parent = TYPE_OBJECT, -+ .instance_size = sizeof(IOMMUFDBackend), -+ .instance_init = iommufd_backend_init, -+ .instance_finalize = iommufd_backend_finalize, -+ .class_size = sizeof(IOMMUFDBackendClass), -+ .class_init = iommufd_backend_class_init, -+ .interfaces = (InterfaceInfo[]) { -+ { TYPE_USER_CREATABLE }, -+ { } -+ } -+}; -+ -+static void register_types(void) -+{ -+ type_register_static(&iommufd_backend_info); -+} -+ -+type_init(register_types); -diff --git a/backends/meson.build b/backends/meson.build -index 914c7c4afb..9a5cea480d 100644 ---- a/backends/meson.build -+++ b/backends/meson.build -@@ -20,6 +20,7 @@ if have_vhost_user - system_ss.add(when: 'CONFIG_VIRTIO', if_true: files('vhost-user.c')) - endif - system_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: files('cryptodev-vhost.c')) -+system_ss.add(when: 'CONFIG_IOMMUFD', if_true: files('iommufd.c')) - if have_vhost_user_crypto - system_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: files('cryptodev-vhost-user.c')) - endif -diff --git a/backends/trace-events b/backends/trace-events -index 652eb76a57..d45c6e31a6 100644 ---- a/backends/trace-events -+++ b/backends/trace-events -@@ -5,3 +5,13 @@ dbus_vmstate_pre_save(void) - dbus_vmstate_post_load(int version_id) "version_id: %d" - dbus_vmstate_loading(const char *id) "id: %s" - dbus_vmstate_saving(const char *id) "id: %s" -+ -+# iommufd.c -+iommufd_backend_connect(int fd, bool owned, uint32_t users, int ret) "fd=%d owned=%d users=%d (%d)" -+iommufd_backend_disconnect(int fd, uint32_t users) "fd=%d users=%d" -+iommu_backend_set_fd(int fd) "pre-opened /dev/iommu fd=%d" -+iommufd_backend_map_dma(int iommufd, uint32_t ioas, uint64_t iova, uint64_t size, void *vaddr, bool readonly, int ret) " iommufd=%d ioas=%d iova=0x%"PRIx64" size=0x%"PRIx64" addr=%p readonly=%d (%d)" -+iommufd_backend_unmap_dma_non_exist(int iommufd, uint32_t ioas, uint64_t iova, uint64_t size, int ret) " Unmap nonexistent mapping: iommufd=%d ioas=%d iova=0x%"PRIx64" size=0x%"PRIx64" (%d)" -+iommufd_backend_unmap_dma(int iommufd, uint32_t ioas, uint64_t iova, uint64_t size, int ret) " iommufd=%d ioas=%d iova=0x%"PRIx64" size=0x%"PRIx64" (%d)" -+iommufd_backend_alloc_ioas(int iommufd, uint32_t ioas, int ret) " iommufd=%d ioas=%d (%d)" -+iommufd_backend_free_id(int iommufd, uint32_t id, int ret) " iommufd=%d id=%d (%d)" -diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h -new file mode 100644 -index 0000000000..9c5524b0ed ---- /dev/null -+++ b/include/sysemu/iommufd.h -@@ -0,0 +1,38 @@ -+#ifndef SYSEMU_IOMMUFD_H -+#define SYSEMU_IOMMUFD_H -+ -+#include "qom/object.h" -+#include "qemu/thread.h" -+#include "exec/hwaddr.h" -+#include "exec/cpu-common.h" -+ -+#define TYPE_IOMMUFD_BACKEND "iommufd" -+OBJECT_DECLARE_TYPE(IOMMUFDBackend, IOMMUFDBackendClass, IOMMUFD_BACKEND) -+ -+struct IOMMUFDBackendClass { -+ ObjectClass parent_class; -+}; -+ -+struct IOMMUFDBackend { -+ Object parent; -+ -+ /*< protected >*/ -+ int fd; /* /dev/iommu file descriptor */ -+ bool owned; /* is the /dev/iommu opened internally */ -+ QemuMutex lock; -+ uint32_t users; -+ -+ /*< public >*/ -+}; -+ -+int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp); -+void iommufd_backend_disconnect(IOMMUFDBackend *be); -+ -+int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id, -+ Error **errp); -+void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id); -+int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova, -+ ram_addr_t size, void *vaddr, bool readonly); -+int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id, -+ hwaddr iova, ram_addr_t size); -+#endif -diff --git a/qapi/qom.json b/qapi/qom.json -index c53ef978ff..95516ba325 100644 ---- a/qapi/qom.json -+++ b/qapi/qom.json -@@ -794,6 +794,23 @@ - { 'struct': 'VfioUserServerProperties', - 'data': { 'socket': 'SocketAddress', 'device': 'str' } } - -+## -+# @IOMMUFDProperties: -+# -+# Properties for iommufd objects. -+# -+# @fd: file descriptor name previously passed via 'getfd' command, -+# which represents a pre-opened /dev/iommu. This allows the -+# iommufd object to be shared accross several subsystems -+# (VFIO, VDPA, ...), and the file descriptor to be shared -+# with other process, e.g. DPDK. (default: QEMU opens -+# /dev/iommu by itself) -+# -+# Since: 9.0 -+## -+{ 'struct': 'IOMMUFDProperties', -+ 'data': { '*fd': 'str' } } -+ - ## - # @RngProperties: - # -@@ -934,6 +951,7 @@ - 'input-barrier', - { 'name': 'input-linux', - 'if': 'CONFIG_LINUX' }, -+ 'iommufd', - 'iothread', - 'main-loop', - { 'name': 'memory-backend-epc', -@@ -1003,6 +1021,7 @@ - 'input-barrier': 'InputBarrierProperties', - 'input-linux': { 'type': 'InputLinuxProperties', - 'if': 'CONFIG_LINUX' }, -+ 'iommufd': 'IOMMUFDProperties', - 'iothread': 'IothreadProperties', - 'main-loop': 'MainLoopProperties', - 'memory-backend-epc': { 'type': 'MemoryBackendEpcProperties', -diff --git a/qemu-options.hx b/qemu-options.hx -index 557118cb1f..0814f43066 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -5224,6 +5224,18 @@ SRST - - The ``share`` boolean option is on by default with memfd. - -+ ``-object iommufd,id=id[,fd=fd]`` -+ Creates an iommufd backend which allows control of DMA mapping -+ through the ``/dev/iommu`` device. -+ -+ The ``id`` parameter is a unique ID which frontends (such as -+ vfio-pci of vdpa) will use to connect with the iommufd backend. -+ -+ The ``fd`` parameter is an optional pre-opened file descriptor -+ resulting from ``/dev/iommu`` opening. Usually the iommufd is shared -+ across all subsystems, bringing the benefit of centralized -+ reference counting. -+ - ``-object rng-builtin,id=id`` - Creates a random number generator backend which obtains entropy - from QEMU builtin functions. The ``id`` parameter is a unique ID --- -2.39.3 - diff --git a/kvm-backends-iommufd-Remove-check-on-number-of-backend-u.patch b/kvm-backends-iommufd-Remove-check-on-number-of-backend-u.patch deleted file mode 100644 index 5ee365b..0000000 --- a/kvm-backends-iommufd-Remove-check-on-number-of-backend-u.patch +++ /dev/null @@ -1,47 +0,0 @@ -From da9a24793e876f6f2727d57f939d882be26a47b8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Fri, 22 Dec 2023 08:55:23 +0100 -Subject: [PATCH 064/101] backends/iommufd: Remove check on number of backend - users -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [63/67] ac4d4589d1f2de5ac3f0adfd8d1f27dbf6bbfdee (eauger1/centos-qemu-kvm) - -QOM already has a ref count on objects and it will assert much -earlier, when INT_MAX is reached. - -Reviewed-by: Eric Auger -Reviewed-by: Zhenzhong Duan -Signed-off-by: Cédric Le Goater -(cherry picked from commit c2ab3a6f7411c895e538e8350fee8948ac07c1a0) -Signed-off-by: Eric Auger ---- - backends/iommufd.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/backends/iommufd.c b/backends/iommufd.c -index ba58a0eb0d..393c0d9a37 100644 ---- a/backends/iommufd.c -+++ b/backends/iommufd.c -@@ -80,11 +80,6 @@ int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp) - int fd, ret = 0; - - qemu_mutex_lock(&be->lock); -- if (be->users == UINT32_MAX) { -- error_setg(errp, "too many connections"); -- ret = -E2BIG; -- goto out; -- } - if (be->owned && !be->users) { - fd = qemu_open_old("/dev/iommu", O_RDWR); - if (fd < 0) { --- -2.39.3 - diff --git a/kvm-backends-iommufd-Remove-mutex.patch b/kvm-backends-iommufd-Remove-mutex.patch deleted file mode 100644 index 83878d5..0000000 --- a/kvm-backends-iommufd-Remove-mutex.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 92aff3cc1a412de01e9563802fa48848eae5283f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Thu, 21 Dec 2023 16:58:41 +0100 -Subject: [PATCH 065/101] backends/iommufd: Remove mutex -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [64/67] 65518432b18f18ceadafe1b0698cdaa962e84f61 (eauger1/centos-qemu-kvm) - -Coverity reports a concurrent data access violation because be->users -is being accessed in iommufd_backend_can_be_deleted() without holding -the mutex. - -However, these routines are called from the QEMU main thread when a -device is created. In this case, the code paths should be protected by -the BQL lock and it should be safe to drop the IOMMUFD backend mutex. -Simply remove it. - -Fixes: CID 1531550 -Fixes: CID 1531549 -Reviewed-by: Eric Auger -Reviewed-by: Zhenzhong Duan -Signed-off-by: Cédric Le Goater -(cherry picked from commit 19368b1905b4b917e915526fcbd5bfa3f7439451) -Signed-off-by: Eric Auger ---- - backends/iommufd.c | 7 ------- - include/sysemu/iommufd.h | 2 -- - 2 files changed, 9 deletions(-) - -diff --git a/backends/iommufd.c b/backends/iommufd.c -index 393c0d9a37..1ef683c7b0 100644 ---- a/backends/iommufd.c -+++ b/backends/iommufd.c -@@ -29,7 +29,6 @@ static void iommufd_backend_init(Object *obj) - be->fd = -1; - be->users = 0; - be->owned = true; -- qemu_mutex_init(&be->lock); - } - - static void iommufd_backend_finalize(Object *obj) -@@ -52,10 +51,8 @@ static void iommufd_backend_set_fd(Object *obj, const char *str, Error **errp) - error_prepend(errp, "Could not parse remote object fd %s:", str); - return; - } -- qemu_mutex_lock(&be->lock); - be->fd = fd; - be->owned = false; -- qemu_mutex_unlock(&be->lock); - trace_iommu_backend_set_fd(be->fd); - } - -@@ -79,7 +76,6 @@ int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp) - { - int fd, ret = 0; - -- qemu_mutex_lock(&be->lock); - if (be->owned && !be->users) { - fd = qemu_open_old("/dev/iommu", O_RDWR); - if (fd < 0) { -@@ -93,13 +89,11 @@ int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp) - out: - trace_iommufd_backend_connect(be->fd, be->owned, - be->users, ret); -- qemu_mutex_unlock(&be->lock); - return ret; - } - - void iommufd_backend_disconnect(IOMMUFDBackend *be) - { -- qemu_mutex_lock(&be->lock); - if (!be->users) { - goto out; - } -@@ -110,7 +104,6 @@ void iommufd_backend_disconnect(IOMMUFDBackend *be) - } - out: - trace_iommufd_backend_disconnect(be->fd, be->users); -- qemu_mutex_unlock(&be->lock); - } - - int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id, -diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h -index 9c5524b0ed..9af27ebd6c 100644 ---- a/include/sysemu/iommufd.h -+++ b/include/sysemu/iommufd.h -@@ -2,7 +2,6 @@ - #define SYSEMU_IOMMUFD_H - - #include "qom/object.h" --#include "qemu/thread.h" - #include "exec/hwaddr.h" - #include "exec/cpu-common.h" - -@@ -19,7 +18,6 @@ struct IOMMUFDBackend { - /*< protected >*/ - int fd; /* /dev/iommu file descriptor */ - bool owned; /* is the /dev/iommu opened internally */ -- QemuMutex lock; - uint32_t users; - - /*< public >*/ --- -2.39.3 - diff --git a/kvm-block-backend-Allow-concurrent-context-changes.patch b/kvm-block-backend-Allow-concurrent-context-changes.patch deleted file mode 100644 index 155fa19..0000000 --- a/kvm-block-backend-Allow-concurrent-context-changes.patch +++ /dev/null @@ -1,104 +0,0 @@ -From afa842e9fdf6e1d6e5d5785679a22779632142bd Mon Sep 17 00:00:00 2001 -From: Hanna Czenczek -Date: Fri, 2 Feb 2024 15:47:54 +0100 -Subject: [PATCH 03/22] block-backend: Allow concurrent context changes - -RH-Author: Hanna Czenczek -RH-MergeRequest: 222: Allow concurrent BlockBackend context changes -RH-Jira: RHEL-24593 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Kevin Wolf -RH-Commit: [1/2] 9e1b535f60f7afa94a0817dc3e71136e41631c71 (hreitz/qemu-kvm-c-9-s) - -Since AioContext locks have been removed, a BlockBackend's AioContext -may really change at any time (only exception is that it is often -confined to a drained section, as noted in this patch). Therefore, -blk_get_aio_context() cannot rely on its root node's context always -matching that of the BlockBackend. - -In practice, whether they match does not matter anymore anyway: Requests -can be sent to BDSs from any context, so anyone who requests the BB's -context should have no reason to require the root node to have the same -context. Therefore, we can and should remove the assertion to that -effect. - -In addition, because the context can be set and queried from different -threads concurrently, it has to be accessed with atomic operations. - -Buglink: https://issues.redhat.com/browse/RHEL-19381 -Suggested-by: Kevin Wolf -Signed-off-by: Hanna Czenczek -Message-ID: <20240202144755.671354-2-hreitz@redhat.com> -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit ad893672027ffe26db498947d70cde6d4f58a111) ---- - block/block-backend.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/block/block-backend.c b/block/block-backend.c -index 209eb07528..9c4de79e6b 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -44,7 +44,7 @@ struct BlockBackend { - char *name; - int refcnt; - BdrvChild *root; -- AioContext *ctx; -+ AioContext *ctx; /* access with atomic operations only */ - DriveInfo *legacy_dinfo; /* null unless created by drive_new() */ - QTAILQ_ENTRY(BlockBackend) link; /* for block_backends */ - QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */ -@@ -2414,22 +2414,22 @@ void blk_op_unblock_all(BlockBackend *blk, Error *reason) - } - } - -+/** -+ * Return BB's current AioContext. Note that this context may change -+ * concurrently at any time, with one exception: If the BB has a root node -+ * attached, its context will only change through bdrv_try_change_aio_context(), -+ * which creates a drained section. Therefore, incrementing such a BB's -+ * in-flight counter will prevent its context from changing. -+ */ - AioContext *blk_get_aio_context(BlockBackend *blk) - { -- BlockDriverState *bs; - IO_CODE(); - - if (!blk) { - return qemu_get_aio_context(); - } - -- bs = blk_bs(blk); -- if (bs) { -- AioContext *ctx = bdrv_get_aio_context(blk_bs(blk)); -- assert(ctx == blk->ctx); -- } -- -- return blk->ctx; -+ return qatomic_read(&blk->ctx); - } - - int blk_set_aio_context(BlockBackend *blk, AioContext *new_context, -@@ -2442,7 +2442,7 @@ int blk_set_aio_context(BlockBackend *blk, AioContext *new_context, - GLOBAL_STATE_CODE(); - - if (!bs) { -- blk->ctx = new_context; -+ qatomic_set(&blk->ctx, new_context); - return 0; - } - -@@ -2471,7 +2471,7 @@ static void blk_root_set_aio_ctx_commit(void *opaque) - AioContext *new_context = s->new_ctx; - ThrottleGroupMember *tgm = &blk->public.throttle_group_member; - -- blk->ctx = new_context; -+ qatomic_set(&blk->ctx, new_context); - if (tgm->throttle_state) { - throttle_group_detach_aio_context(tgm); - throttle_group_attach_aio_context(tgm, new_context); --- -2.39.3 - diff --git a/kvm-block-coroutine-wrapper-use-qemu_get_current_aio_con.patch b/kvm-block-coroutine-wrapper-use-qemu_get_current_aio_con.patch deleted file mode 100644 index df764fb..0000000 --- a/kvm-block-coroutine-wrapper-use-qemu_get_current_aio_con.patch +++ /dev/null @@ -1,69 +0,0 @@ -From b1a68aebadecd7d339cf5eaffeda15099c998528 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 12 Sep 2023 19:10:37 -0400 -Subject: [PATCH 095/101] block-coroutine-wrapper: use - qemu_get_current_aio_context() - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [26/26] cde767bcdc626e90721792e3889952057a548ac5 (kmwolf/centos-qemu-kvm) - -Use qemu_get_current_aio_context() in mixed wrappers and coroutine -wrappers so that code runs in the caller's AioContext instead of moving -to the BlockDriverState's AioContext. This change is necessary for the -multi-queue block layer where any thread can call into the block layer. - -Most wrappers are IO_CODE where it's safe to use the current AioContext -nowadays. BlockDrivers and the core block layer use their own locks and -no longer depend on the AioContext lock for thread-safety. - -The bdrv_create() wrapper invokes GLOBAL_STATE code. Using the current -AioContext is safe because this code is only called with the BQL held -from the main loop thread. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20230912231037.826804-6-stefanha@redhat.com> -Reviewed-by: Eric Blake -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - scripts/block-coroutine-wrapper.py | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/scripts/block-coroutine-wrapper.py b/scripts/block-coroutine-wrapper.py -index c9c09fcacd..dbbde99e39 100644 ---- a/scripts/block-coroutine-wrapper.py -+++ b/scripts/block-coroutine-wrapper.py -@@ -92,8 +92,6 @@ def __init__(self, wrapper_type: str, return_type: str, name: str, - f"{self.name}") - self.target_name = f'{subsystem}_{subname}' - -- self.ctx = self.gen_ctx() -- - self.get_result = 's->ret = ' - self.ret = 'return s.ret;' - self.co_ret = 'return ' -@@ -167,7 +165,7 @@ def create_mixed_wrapper(func: FuncDecl) -> str: - {func.co_ret}{name}({ func.gen_list('{name}') }); - }} else {{ - {struct_name} s = {{ -- .poll_state.ctx = {func.ctx}, -+ .poll_state.ctx = qemu_get_current_aio_context(), - .poll_state.in_progress = true, - - { func.gen_block(' .{name} = {name},') } -@@ -191,7 +189,7 @@ def create_co_wrapper(func: FuncDecl) -> str: - {func.return_type} {func.name}({ func.gen_list('{decl}') }) - {{ - {struct_name} s = {{ -- .poll_state.ctx = {func.ctx}, -+ .poll_state.ctx = qemu_get_current_aio_context(), - .poll_state.in_progress = true, - - { func.gen_block(' .{name} = {name},') } --- -2.39.3 - diff --git a/kvm-block-file-posix-set-up-Linux-AIO-and-io_uring-in-th.patch b/kvm-block-file-posix-set-up-Linux-AIO-and-io_uring-in-th.patch deleted file mode 100644 index 1783a64..0000000 --- a/kvm-block-file-posix-set-up-Linux-AIO-and-io_uring-in-th.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 25cce5df341861e8ba8ec57722558e2dee3ce56a Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 14 Sep 2023 10:00:58 -0400 -Subject: [PATCH 073/101] block/file-posix: set up Linux AIO and io_uring in - the current thread - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [4/26] 74c7daf805daefe706378308c3afeb28d861164b (kmwolf/centos-qemu-kvm) - -The file-posix block driver currently only sets up Linux AIO and -io_uring in the BDS's AioContext. In the multi-queue block layer we must -be able to submit I/O requests in AioContexts that do not have Linux AIO -and io_uring set up yet since any thread can call into the block driver. - -Set up Linux AIO and io_uring for the current AioContext during request -submission. We lose the ability to return an error from -.bdrv_file_open() when Linux AIO and io_uring setup fails (e.g. due to -resource limits). Instead the user only gets warnings and we fall back -to aio=threads. This is still better than a fatal error after startup. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20230914140101.1065008-2-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Reviewed-by: Eric Blake -Signed-off-by: Kevin Wolf ---- - block/file-posix.c | 103 ++++++++++++++++++++++----------------------- - 1 file changed, 51 insertions(+), 52 deletions(-) - -diff --git a/block/file-posix.c b/block/file-posix.c -index b862406c71..35684f7e21 100644 ---- a/block/file-posix.c -+++ b/block/file-posix.c -@@ -712,17 +712,11 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, - - #ifdef CONFIG_LINUX_AIO - /* Currently Linux does AIO only for files opened with O_DIRECT */ -- if (s->use_linux_aio) { -- if (!(s->open_flags & O_DIRECT)) { -- error_setg(errp, "aio=native was specified, but it requires " -- "cache.direct=on, which was not specified."); -- ret = -EINVAL; -- goto fail; -- } -- if (!aio_setup_linux_aio(bdrv_get_aio_context(bs), errp)) { -- error_prepend(errp, "Unable to use native AIO: "); -- goto fail; -- } -+ if (s->use_linux_aio && !(s->open_flags & O_DIRECT)) { -+ error_setg(errp, "aio=native was specified, but it requires " -+ "cache.direct=on, which was not specified."); -+ ret = -EINVAL; -+ goto fail; - } - #else - if (s->use_linux_aio) { -@@ -733,14 +727,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, - } - #endif /* !defined(CONFIG_LINUX_AIO) */ - --#ifdef CONFIG_LINUX_IO_URING -- if (s->use_linux_io_uring) { -- if (!aio_setup_linux_io_uring(bdrv_get_aio_context(bs), errp)) { -- error_prepend(errp, "Unable to use io_uring: "); -- goto fail; -- } -- } --#else -+#ifndef CONFIG_LINUX_IO_URING - if (s->use_linux_io_uring) { - error_setg(errp, "aio=io_uring was specified, but is not supported " - "in this build."); -@@ -2444,6 +2431,48 @@ static bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) - return true; - } - -+#ifdef CONFIG_LINUX_IO_URING -+static inline bool raw_check_linux_io_uring(BDRVRawState *s) -+{ -+ Error *local_err = NULL; -+ AioContext *ctx; -+ -+ if (!s->use_linux_io_uring) { -+ return false; -+ } -+ -+ ctx = qemu_get_current_aio_context(); -+ if (unlikely(!aio_setup_linux_io_uring(ctx, &local_err))) { -+ error_reportf_err(local_err, "Unable to use linux io_uring, " -+ "falling back to thread pool: "); -+ s->use_linux_io_uring = false; -+ return false; -+ } -+ return true; -+} -+#endif -+ -+#ifdef CONFIG_LINUX_AIO -+static inline bool raw_check_linux_aio(BDRVRawState *s) -+{ -+ Error *local_err = NULL; -+ AioContext *ctx; -+ -+ if (!s->use_linux_aio) { -+ return false; -+ } -+ -+ ctx = qemu_get_current_aio_context(); -+ if (unlikely(!aio_setup_linux_aio(ctx, &local_err))) { -+ error_reportf_err(local_err, "Unable to use Linux AIO, " -+ "falling back to thread pool: "); -+ s->use_linux_aio = false; -+ return false; -+ } -+ return true; -+} -+#endif -+ - static int coroutine_fn raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr, - uint64_t bytes, QEMUIOVector *qiov, int type) - { -@@ -2474,13 +2503,13 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr, - if (s->needs_alignment && !bdrv_qiov_is_aligned(bs, qiov)) { - type |= QEMU_AIO_MISALIGNED; - #ifdef CONFIG_LINUX_IO_URING -- } else if (s->use_linux_io_uring) { -+ } else if (raw_check_linux_io_uring(s)) { - assert(qiov->size == bytes); - ret = luring_co_submit(bs, s->fd, offset, qiov, type); - goto out; - #endif - #ifdef CONFIG_LINUX_AIO -- } else if (s->use_linux_aio) { -+ } else if (raw_check_linux_aio(s)) { - assert(qiov->size == bytes); - ret = laio_co_submit(s->fd, offset, qiov, type, - s->aio_max_batch); -@@ -2567,39 +2596,13 @@ static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs) - }; - - #ifdef CONFIG_LINUX_IO_URING -- if (s->use_linux_io_uring) { -+ if (raw_check_linux_io_uring(s)) { - return luring_co_submit(bs, s->fd, 0, NULL, QEMU_AIO_FLUSH); - } - #endif - return raw_thread_pool_submit(handle_aiocb_flush, &acb); - } - --static void raw_aio_attach_aio_context(BlockDriverState *bs, -- AioContext *new_context) --{ -- BDRVRawState __attribute__((unused)) *s = bs->opaque; --#ifdef CONFIG_LINUX_AIO -- if (s->use_linux_aio) { -- Error *local_err = NULL; -- if (!aio_setup_linux_aio(new_context, &local_err)) { -- error_reportf_err(local_err, "Unable to use native AIO, " -- "falling back to thread pool: "); -- s->use_linux_aio = false; -- } -- } --#endif --#ifdef CONFIG_LINUX_IO_URING -- if (s->use_linux_io_uring) { -- Error *local_err = NULL; -- if (!aio_setup_linux_io_uring(new_context, &local_err)) { -- error_reportf_err(local_err, "Unable to use linux io_uring, " -- "falling back to thread pool: "); -- s->use_linux_io_uring = false; -- } -- } --#endif --} -- - static void raw_close(BlockDriverState *bs) - { - BDRVRawState *s = bs->opaque; -@@ -3896,7 +3899,6 @@ BlockDriver bdrv_file = { - .bdrv_co_copy_range_from = raw_co_copy_range_from, - .bdrv_co_copy_range_to = raw_co_copy_range_to, - .bdrv_refresh_limits = raw_refresh_limits, -- .bdrv_attach_aio_context = raw_aio_attach_aio_context, - - .bdrv_co_truncate = raw_co_truncate, - .bdrv_co_getlength = raw_co_getlength, -@@ -4266,7 +4268,6 @@ static BlockDriver bdrv_host_device = { - .bdrv_co_copy_range_from = raw_co_copy_range_from, - .bdrv_co_copy_range_to = raw_co_copy_range_to, - .bdrv_refresh_limits = raw_refresh_limits, -- .bdrv_attach_aio_context = raw_aio_attach_aio_context, - - .bdrv_co_truncate = raw_co_truncate, - .bdrv_co_getlength = raw_co_getlength, -@@ -4402,7 +4403,6 @@ static BlockDriver bdrv_host_cdrom = { - .bdrv_co_pwritev = raw_co_pwritev, - .bdrv_co_flush_to_disk = raw_co_flush_to_disk, - .bdrv_refresh_limits = cdrom_refresh_limits, -- .bdrv_attach_aio_context = raw_aio_attach_aio_context, - - .bdrv_co_truncate = raw_co_truncate, - .bdrv_co_getlength = raw_co_getlength, -@@ -4528,7 +4528,6 @@ static BlockDriver bdrv_host_cdrom = { - .bdrv_co_pwritev = raw_co_pwritev, - .bdrv_co_flush_to_disk = raw_co_flush_to_disk, - .bdrv_refresh_limits = cdrom_refresh_limits, -- .bdrv_attach_aio_context = raw_aio_attach_aio_context, - - .bdrv_co_truncate = raw_co_truncate, - .bdrv_co_getlength = raw_co_getlength, --- -2.39.3 - diff --git a/kvm-block-remove-AioContext-locking.patch b/kvm-block-remove-AioContext-locking.patch deleted file mode 100644 index 5bcd859..0000000 --- a/kvm-block-remove-AioContext-locking.patch +++ /dev/null @@ -1,4438 +0,0 @@ -From df1400991580e8a60d711079865b56ed95830b28 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:03 -0500 -Subject: [PATCH 086/101] block: remove AioContext locking - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [17/26] b29c3ac7ea91ca356335ba047c66187317c482f9 (kmwolf/centos-qemu-kvm) - -This is the big patch that removes -aio_context_acquire()/aio_context_release() from the block layer and -affected block layer users. - -There isn't a clean way to split this patch and the reviewers are likely -the same group of people, so I decided to do it in one patch. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Reviewed-by: Kevin Wolf -Reviewed-by: Paul Durrant -Message-ID: <20231205182011.1976568-7-stefanha@redhat.com> -Signed-off-by: Kevin Wolf ---- - block.c | 234 +--------------------- - block/block-backend.c | 14 -- - block/copy-before-write.c | 22 +-- - block/export/export.c | 22 +-- - block/io.c | 45 +---- - block/mirror.c | 19 -- - block/monitor/bitmap-qmp-cmds.c | 20 +- - block/monitor/block-hmp-cmds.c | 29 --- - block/qapi-sysemu.c | 27 +-- - block/qapi.c | 18 +- - block/raw-format.c | 5 - - block/replication.c | 58 +----- - block/snapshot.c | 22 +-- - block/write-threshold.c | 6 - - blockdev.c | 307 +++++------------------------ - blockjob.c | 18 -- - hw/block/dataplane/virtio-blk.c | 10 - - hw/block/dataplane/xen-block.c | 17 +- - hw/block/virtio-blk.c | 13 -- - hw/core/qdev-properties-system.c | 9 - - include/block/block-global-state.h | 9 +- - include/block/block-io.h | 3 +- - include/block/snapshot.h | 2 - - job.c | 16 -- - migration/block.c | 34 +--- - migration/migration-hmp-cmds.c | 3 - - migration/savevm.c | 22 --- - net/colo-compare.c | 2 - - qemu-img.c | 4 - - qemu-io.c | 10 +- - qemu-nbd.c | 2 - - replay/replay-debugging.c | 4 - - scripts/block-coroutine-wrapper.py | 3 - - tests/tsan/suppressions.tsan | 1 - - tests/unit/test-bdrv-drain.c | 51 +---- - tests/unit/test-bdrv-graph-mod.c | 6 - - tests/unit/test-block-iothread.c | 31 --- - tests/unit/test-blockjob.c | 137 ------------- - tests/unit/test-replication.c | 11 -- - util/async.c | 4 - - util/vhost-user-server.c | 3 - - 41 files changed, 104 insertions(+), 1169 deletions(-) - -diff --git a/block.c b/block.c -index 25e1ebc606..91ace5d2d5 100644 ---- a/block.c -+++ b/block.c -@@ -1625,7 +1625,6 @@ static int no_coroutine_fn GRAPH_UNLOCKED - bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name, - QDict *options, int open_flags, Error **errp) - { -- AioContext *ctx; - Error *local_err = NULL; - int i, ret; - GLOBAL_STATE_CODE(); -@@ -1673,21 +1672,15 @@ bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name, - bs->supported_read_flags |= BDRV_REQ_REGISTERED_BUF; - bs->supported_write_flags |= BDRV_REQ_REGISTERED_BUF; - -- /* Get the context after .bdrv_open, it can change the context */ -- ctx = bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); -- - ret = bdrv_refresh_total_sectors(bs, bs->total_sectors); - if (ret < 0) { - error_setg_errno(errp, -ret, "Could not refresh total sector count"); -- aio_context_release(ctx); - return ret; - } - - bdrv_graph_rdlock_main_loop(); - bdrv_refresh_limits(bs, NULL, &local_err); - bdrv_graph_rdunlock_main_loop(); -- aio_context_release(ctx); - - if (local_err) { - error_propagate(errp, local_err); -@@ -3062,7 +3055,7 @@ bdrv_attach_child_common(BlockDriverState *child_bs, - Transaction *tran, Error **errp) - { - BdrvChild *new_child; -- AioContext *parent_ctx, *new_child_ctx; -+ AioContext *parent_ctx; - AioContext *child_ctx = bdrv_get_aio_context(child_bs); - - assert(child_class->get_parent_desc); -@@ -3114,12 +3107,6 @@ bdrv_attach_child_common(BlockDriverState *child_bs, - } - } - -- new_child_ctx = bdrv_get_aio_context(child_bs); -- if (new_child_ctx != child_ctx) { -- aio_context_release(child_ctx); -- aio_context_acquire(new_child_ctx); -- } -- - bdrv_ref(child_bs); - /* - * Let every new BdrvChild start with a drained parent. Inserting the child -@@ -3149,11 +3136,6 @@ bdrv_attach_child_common(BlockDriverState *child_bs, - }; - tran_add(tran, &bdrv_attach_child_common_drv, s); - -- if (new_child_ctx != child_ctx) { -- aio_context_release(new_child_ctx); -- aio_context_acquire(child_ctx); -- } -- - return new_child; - } - -@@ -3605,7 +3587,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, - int ret = 0; - bool implicit_backing = false; - BlockDriverState *backing_hd; -- AioContext *backing_hd_ctx; - QDict *options; - QDict *tmp_parent_options = NULL; - Error *local_err = NULL; -@@ -3691,11 +3672,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, - - /* Hook up the backing file link; drop our reference, bs owns the - * backing_hd reference now */ -- backing_hd_ctx = bdrv_get_aio_context(backing_hd); -- aio_context_acquire(backing_hd_ctx); - ret = bdrv_set_backing_hd(bs, backing_hd, errp); - bdrv_unref(backing_hd); -- aio_context_release(backing_hd_ctx); - - if (ret < 0) { - goto free_exit; -@@ -3780,7 +3758,6 @@ BdrvChild *bdrv_open_child(const char *filename, - { - BlockDriverState *bs; - BdrvChild *child; -- AioContext *ctx; - - GLOBAL_STATE_CODE(); - -@@ -3791,11 +3768,8 @@ BdrvChild *bdrv_open_child(const char *filename, - } - - bdrv_graph_wrlock(); -- ctx = bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); - child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, - errp); -- aio_context_release(ctx); - bdrv_graph_wrunlock(); - - return child; -@@ -3881,7 +3855,6 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, - int64_t total_size; - QemuOpts *opts = NULL; - BlockDriverState *bs_snapshot = NULL; -- AioContext *ctx = bdrv_get_aio_context(bs); - int ret; - - GLOBAL_STATE_CODE(); -@@ -3890,9 +3863,7 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, - instead of opening 'filename' directly */ - - /* Get the required size from the image */ -- aio_context_acquire(ctx); - total_size = bdrv_getlength(bs); -- aio_context_release(ctx); - - if (total_size < 0) { - error_setg_errno(errp, -total_size, "Could not get image size"); -@@ -3927,10 +3898,7 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, - goto out; - } - -- aio_context_acquire(ctx); - ret = bdrv_append(bs_snapshot, bs, errp); -- aio_context_release(ctx); -- - if (ret < 0) { - bs_snapshot = NULL; - goto out; -@@ -3974,7 +3942,6 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, - Error *local_err = NULL; - QDict *snapshot_options = NULL; - int snapshot_flags = 0; -- AioContext *ctx = qemu_get_aio_context(); - - assert(!child_class || !flags); - assert(!child_class == !parent); -@@ -4115,12 +4082,10 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, - /* Not requesting BLK_PERM_CONSISTENT_READ because we're only - * looking at the header to guess the image format. This works even - * in cases where a guest would not see a consistent state. */ -- ctx = bdrv_get_aio_context(file_bs); -- aio_context_acquire(ctx); -+ AioContext *ctx = bdrv_get_aio_context(file_bs); - file = blk_new(ctx, 0, BLK_PERM_ALL); - blk_insert_bs(file, file_bs, &local_err); - bdrv_unref(file_bs); -- aio_context_release(ctx); - - if (local_err) { - goto fail; -@@ -4167,13 +4132,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, - goto fail; - } - -- /* The AioContext could have changed during bdrv_open_common() */ -- ctx = bdrv_get_aio_context(bs); -- - if (file) { -- aio_context_acquire(ctx); - blk_unref(file); -- aio_context_release(ctx); - file = NULL; - } - -@@ -4231,16 +4191,13 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, - * (snapshot_bs); thus, we have to drop the strong reference to bs - * (which we obtained by calling bdrv_new()). bs will not be deleted, - * though, because the overlay still has a reference to it. */ -- aio_context_acquire(ctx); - bdrv_unref(bs); -- aio_context_release(ctx); - bs = snapshot_bs; - } - - return bs; - - fail: -- aio_context_acquire(ctx); - blk_unref(file); - qobject_unref(snapshot_options); - qobject_unref(bs->explicit_options); -@@ -4249,14 +4206,11 @@ fail: - bs->options = NULL; - bs->explicit_options = NULL; - bdrv_unref(bs); -- aio_context_release(ctx); - error_propagate(errp, local_err); - return NULL; - - close_and_fail: -- aio_context_acquire(ctx); - bdrv_unref(bs); -- aio_context_release(ctx); - qobject_unref(snapshot_options); - qobject_unref(options); - error_propagate(errp, local_err); -@@ -4540,12 +4494,7 @@ void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue) - if (bs_queue) { - BlockReopenQueueEntry *bs_entry, *next; - QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) { -- AioContext *ctx = bdrv_get_aio_context(bs_entry->state.bs); -- -- aio_context_acquire(ctx); - bdrv_drained_end(bs_entry->state.bs); -- aio_context_release(ctx); -- - qobject_unref(bs_entry->state.explicit_options); - qobject_unref(bs_entry->state.options); - g_free(bs_entry); -@@ -4577,7 +4526,6 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp) - { - int ret = -1; - BlockReopenQueueEntry *bs_entry, *next; -- AioContext *ctx; - Transaction *tran = tran_new(); - g_autoptr(GSList) refresh_list = NULL; - -@@ -4586,10 +4534,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp) - GLOBAL_STATE_CODE(); - - QTAILQ_FOREACH(bs_entry, bs_queue, entry) { -- ctx = bdrv_get_aio_context(bs_entry->state.bs); -- aio_context_acquire(ctx); - ret = bdrv_flush(bs_entry->state.bs); -- aio_context_release(ctx); - if (ret < 0) { - error_setg_errno(errp, -ret, "Error flushing drive"); - goto abort; -@@ -4598,10 +4543,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp) - - QTAILQ_FOREACH(bs_entry, bs_queue, entry) { - assert(bs_entry->state.bs->quiesce_counter > 0); -- ctx = bdrv_get_aio_context(bs_entry->state.bs); -- aio_context_acquire(ctx); - ret = bdrv_reopen_prepare(&bs_entry->state, bs_queue, tran, errp); -- aio_context_release(ctx); - if (ret < 0) { - goto abort; - } -@@ -4644,10 +4586,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp) - * to first element. - */ - QTAILQ_FOREACH_REVERSE(bs_entry, bs_queue, entry) { -- ctx = bdrv_get_aio_context(bs_entry->state.bs); -- aio_context_acquire(ctx); - bdrv_reopen_commit(&bs_entry->state); -- aio_context_release(ctx); - } - - bdrv_graph_wrlock(); -@@ -4658,10 +4597,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp) - BlockDriverState *bs = bs_entry->state.bs; - - if (bs->drv->bdrv_reopen_commit_post) { -- ctx = bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); - bs->drv->bdrv_reopen_commit_post(&bs_entry->state); -- aio_context_release(ctx); - } - } - -@@ -4675,10 +4611,7 @@ abort: - - QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) { - if (bs_entry->prepared) { -- ctx = bdrv_get_aio_context(bs_entry->state.bs); -- aio_context_acquire(ctx); - bdrv_reopen_abort(&bs_entry->state); -- aio_context_release(ctx); - } - } - -@@ -4691,24 +4624,13 @@ cleanup: - int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts, - Error **errp) - { -- AioContext *ctx = bdrv_get_aio_context(bs); - BlockReopenQueue *queue; -- int ret; - - GLOBAL_STATE_CODE(); - - queue = bdrv_reopen_queue(NULL, bs, opts, keep_old_opts); - -- if (ctx != qemu_get_aio_context()) { -- aio_context_release(ctx); -- } -- ret = bdrv_reopen_multiple(queue, errp); -- -- if (ctx != qemu_get_aio_context()) { -- aio_context_acquire(ctx); -- } -- -- return ret; -+ return bdrv_reopen_multiple(queue, errp); - } - - int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only, -@@ -4760,7 +4682,6 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state, - const char *child_name = is_backing ? "backing" : "file"; - QObject *value; - const char *str; -- AioContext *ctx, *old_ctx; - bool has_child; - int ret; - -@@ -4844,13 +4765,6 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state, - bdrv_drained_begin(old_child_bs); - } - -- old_ctx = bdrv_get_aio_context(bs); -- ctx = bdrv_get_aio_context(new_child_bs); -- if (old_ctx != ctx) { -- aio_context_release(old_ctx); -- aio_context_acquire(ctx); -- } -- - bdrv_graph_rdunlock_main_loop(); - bdrv_graph_wrlock(); - -@@ -4859,11 +4773,6 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state, - - bdrv_graph_wrunlock(); - -- if (old_ctx != ctx) { -- aio_context_release(ctx); -- aio_context_acquire(old_ctx); -- } -- - if (old_child_bs) { - bdrv_drained_end(old_child_bs); - bdrv_unref(old_child_bs); -@@ -5537,7 +5446,6 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, - int ret; - BdrvChild *child; - Transaction *tran = tran_new(); -- AioContext *old_context, *new_context = NULL; - - GLOBAL_STATE_CODE(); - -@@ -5545,21 +5453,8 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, - assert(!bs_new->backing); - bdrv_graph_rdunlock_main_loop(); - -- old_context = bdrv_get_aio_context(bs_top); - bdrv_drained_begin(bs_top); -- -- /* -- * bdrv_drained_begin() requires that only the AioContext of the drained -- * node is locked, and at this point it can still differ from the AioContext -- * of bs_top. -- */ -- new_context = bdrv_get_aio_context(bs_new); -- aio_context_release(old_context); -- aio_context_acquire(new_context); - bdrv_drained_begin(bs_new); -- aio_context_release(new_context); -- aio_context_acquire(old_context); -- new_context = NULL; - - bdrv_graph_wrlock(); - -@@ -5571,18 +5466,6 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, - goto out; - } - -- /* -- * bdrv_attach_child_noperm could change the AioContext of bs_top and -- * bs_new, but at least they are in the same AioContext now. This is the -- * AioContext that we need to lock for the rest of the function. -- */ -- new_context = bdrv_get_aio_context(bs_top); -- -- if (old_context != new_context) { -- aio_context_release(old_context); -- aio_context_acquire(new_context); -- } -- - ret = bdrv_replace_node_noperm(bs_top, bs_new, true, tran, errp); - if (ret < 0) { - goto out; -@@ -5598,11 +5481,6 @@ out: - bdrv_drained_end(bs_top); - bdrv_drained_end(bs_new); - -- if (new_context && old_context != new_context) { -- aio_context_release(new_context); -- aio_context_acquire(old_context); -- } -- - return ret; - } - -@@ -5697,12 +5575,8 @@ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options, - - GLOBAL_STATE_CODE(); - -- aio_context_release(ctx); -- aio_context_acquire(qemu_get_aio_context()); - new_node_bs = bdrv_new_open_driver_opts(drv, node_name, options, flags, - errp); -- aio_context_release(qemu_get_aio_context()); -- aio_context_acquire(ctx); - assert(bdrv_get_aio_context(bs) == ctx); - - options = NULL; /* bdrv_new_open_driver() eats options */ -@@ -7037,12 +6911,9 @@ void bdrv_activate_all(Error **errp) - GRAPH_RDLOCK_GUARD_MAINLOOP(); - - for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { -- AioContext *aio_context = bdrv_get_aio_context(bs); - int ret; - -- aio_context_acquire(aio_context); - ret = bdrv_activate(bs, errp); -- aio_context_release(aio_context); - if (ret < 0) { - bdrv_next_cleanup(&it); - return; -@@ -7137,20 +7008,10 @@ int bdrv_inactivate_all(void) - BlockDriverState *bs = NULL; - BdrvNextIterator it; - int ret = 0; -- GSList *aio_ctxs = NULL, *ctx; - - GLOBAL_STATE_CODE(); - GRAPH_RDLOCK_GUARD_MAINLOOP(); - -- for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { -- AioContext *aio_context = bdrv_get_aio_context(bs); -- -- if (!g_slist_find(aio_ctxs, aio_context)) { -- aio_ctxs = g_slist_prepend(aio_ctxs, aio_context); -- aio_context_acquire(aio_context); -- } -- } -- - for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { - /* Nodes with BDS parents are covered by recursion from the last - * parent that gets inactivated. Don't inactivate them a second -@@ -7161,17 +7022,10 @@ int bdrv_inactivate_all(void) - ret = bdrv_inactivate_recurse(bs); - if (ret < 0) { - bdrv_next_cleanup(&it); -- goto out; -+ break; - } - } - --out: -- for (ctx = aio_ctxs; ctx != NULL; ctx = ctx->next) { -- AioContext *aio_context = ctx->data; -- aio_context_release(aio_context); -- } -- g_slist_free(aio_ctxs); -- - return ret; - } - -@@ -7257,11 +7111,8 @@ void bdrv_unref(BlockDriverState *bs) - static void bdrv_schedule_unref_bh(void *opaque) - { - BlockDriverState *bs = opaque; -- AioContext *ctx = bdrv_get_aio_context(bs); - -- aio_context_acquire(ctx); - bdrv_unref(bs); -- aio_context_release(ctx); - } - - /* -@@ -7398,8 +7249,6 @@ void bdrv_img_create(const char *filename, const char *fmt, - return; - } - -- aio_context_acquire(qemu_get_aio_context()); -- - /* Create parameter list */ - create_opts = qemu_opts_append(create_opts, drv->create_opts); - create_opts = qemu_opts_append(create_opts, proto_drv->create_opts); -@@ -7549,7 +7398,6 @@ out: - qemu_opts_del(opts); - qemu_opts_free(create_opts); - error_propagate(errp, local_err); -- aio_context_release(qemu_get_aio_context()); - } - - AioContext *bdrv_get_aio_context(BlockDriverState *bs) -@@ -7585,29 +7433,12 @@ void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx) - - void coroutine_fn bdrv_co_lock(BlockDriverState *bs) - { -- AioContext *ctx = bdrv_get_aio_context(bs); -- -- /* In the main thread, bs->aio_context won't change concurrently */ -- assert(qemu_get_current_aio_context() == qemu_get_aio_context()); -- -- /* -- * We're in coroutine context, so we already hold the lock of the main -- * loop AioContext. Don't lock it twice to avoid deadlocks. -- */ -- assert(qemu_in_coroutine()); -- if (ctx != qemu_get_aio_context()) { -- aio_context_acquire(ctx); -- } -+ /* TODO removed in next patch */ - } - - void coroutine_fn bdrv_co_unlock(BlockDriverState *bs) - { -- AioContext *ctx = bdrv_get_aio_context(bs); -- -- assert(qemu_in_coroutine()); -- if (ctx != qemu_get_aio_context()) { -- aio_context_release(ctx); -- } -+ /* TODO removed in next patch */ - } - - static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban) -@@ -7728,21 +7559,8 @@ static void bdrv_set_aio_context_commit(void *opaque) - BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque; - BlockDriverState *bs = (BlockDriverState *) state->bs; - AioContext *new_context = state->new_ctx; -- AioContext *old_context = bdrv_get_aio_context(bs); - -- /* -- * Take the old AioContex when detaching it from bs. -- * At this point, new_context lock is already acquired, and we are now -- * also taking old_context. This is safe as long as bdrv_detach_aio_context -- * does not call AIO_POLL_WHILE(). -- */ -- if (old_context != qemu_get_aio_context()) { -- aio_context_acquire(old_context); -- } - bdrv_detach_aio_context(bs); -- if (old_context != qemu_get_aio_context()) { -- aio_context_release(old_context); -- } - bdrv_attach_aio_context(bs, new_context); - } - -@@ -7827,7 +7645,6 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, - Transaction *tran; - GHashTable *visited; - int ret; -- AioContext *old_context = bdrv_get_aio_context(bs); - GLOBAL_STATE_CODE(); - - /* -@@ -7857,34 +7674,7 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, - return -EPERM; - } - -- /* -- * Release old AioContext, it won't be needed anymore, as all -- * bdrv_drained_begin() have been called already. -- */ -- if (qemu_get_aio_context() != old_context) { -- aio_context_release(old_context); -- } -- -- /* -- * Acquire new AioContext since bdrv_drained_end() is going to be called -- * after we switched all nodes in the new AioContext, and the function -- * assumes that the lock of the bs is always taken. -- */ -- if (qemu_get_aio_context() != ctx) { -- aio_context_acquire(ctx); -- } -- - tran_commit(tran); -- -- if (qemu_get_aio_context() != ctx) { -- aio_context_release(ctx); -- } -- -- /* Re-acquire the old AioContext, since the caller takes and releases it. */ -- if (qemu_get_aio_context() != old_context) { -- aio_context_acquire(old_context); -- } -- - return 0; - } - -@@ -8006,7 +7796,6 @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, - const char *node_name, Error **errp) - { - BlockDriverState *to_replace_bs = bdrv_find_node(node_name); -- AioContext *aio_context; - - GLOBAL_STATE_CODE(); - -@@ -8015,12 +7804,8 @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, - return NULL; - } - -- aio_context = bdrv_get_aio_context(to_replace_bs); -- aio_context_acquire(aio_context); -- - if (bdrv_op_is_blocked(to_replace_bs, BLOCK_OP_TYPE_REPLACE, errp)) { -- to_replace_bs = NULL; -- goto out; -+ return NULL; - } - - /* We don't want arbitrary node of the BDS chain to be replaced only the top -@@ -8033,12 +7818,9 @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, - "because it cannot be guaranteed that doing so would not " - "lead to an abrupt change of visible data", - node_name, parent_bs->node_name); -- to_replace_bs = NULL; -- goto out; -+ return NULL; - } - --out: -- aio_context_release(aio_context); - return to_replace_bs; - } - -diff --git a/block/block-backend.c b/block/block-backend.c -index abac4e0235..f412bed274 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -429,7 +429,6 @@ BlockBackend *blk_new_open(const char *filename, const char *reference, - { - BlockBackend *blk; - BlockDriverState *bs; -- AioContext *ctx; - uint64_t perm = 0; - uint64_t shared = BLK_PERM_ALL; - -@@ -459,23 +458,18 @@ BlockBackend *blk_new_open(const char *filename, const char *reference, - shared = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED; - } - -- aio_context_acquire(qemu_get_aio_context()); - bs = bdrv_open(filename, reference, options, flags, errp); -- aio_context_release(qemu_get_aio_context()); - if (!bs) { - return NULL; - } - - /* bdrv_open() could have moved bs to a different AioContext */ -- ctx = bdrv_get_aio_context(bs); - blk = blk_new(bdrv_get_aio_context(bs), perm, shared); - blk->perm = perm; - blk->shared_perm = shared; - -- aio_context_acquire(ctx); - blk_insert_bs(blk, bs, errp); - bdrv_unref(bs); -- aio_context_release(ctx); - - if (!blk->root) { - blk_unref(blk); -@@ -577,13 +571,9 @@ void blk_remove_all_bs(void) - GLOBAL_STATE_CODE(); - - while ((blk = blk_all_next(blk)) != NULL) { -- AioContext *ctx = blk_get_aio_context(blk); -- -- aio_context_acquire(ctx); - if (blk->root) { - blk_remove_bs(blk); - } -- aio_context_release(ctx); - } - } - -@@ -2736,20 +2726,16 @@ int blk_commit_all(void) - GRAPH_RDLOCK_GUARD_MAINLOOP(); - - while ((blk = blk_all_next(blk)) != NULL) { -- AioContext *aio_context = blk_get_aio_context(blk); - BlockDriverState *unfiltered_bs = bdrv_skip_filters(blk_bs(blk)); - -- aio_context_acquire(aio_context); - if (blk_is_inserted(blk) && bdrv_cow_child(unfiltered_bs)) { - int ret; - - ret = bdrv_commit(unfiltered_bs); - if (ret < 0) { -- aio_context_release(aio_context); - return ret; - } - } -- aio_context_release(aio_context); - } - return 0; - } -diff --git a/block/copy-before-write.c b/block/copy-before-write.c -index 13972879b1..0842a1a6df 100644 ---- a/block/copy-before-write.c -+++ b/block/copy-before-write.c -@@ -412,7 +412,6 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, - int64_t cluster_size; - g_autoptr(BlockdevOptions) full_opts = NULL; - BlockdevOptionsCbw *opts; -- AioContext *ctx; - int ret; - - full_opts = cbw_parse_options(options, errp); -@@ -435,15 +434,11 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, - - GRAPH_RDLOCK_GUARD_MAINLOOP(); - -- ctx = bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); -- - if (opts->bitmap) { - bitmap = block_dirty_bitmap_lookup(opts->bitmap->node, - opts->bitmap->name, NULL, errp); - if (!bitmap) { -- ret = -EINVAL; -- goto out; -+ return -EINVAL; - } - } - s->on_cbw_error = opts->has_on_cbw_error ? opts->on_cbw_error : -@@ -461,24 +456,21 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, - s->bcs = block_copy_state_new(bs->file, s->target, bitmap, errp); - if (!s->bcs) { - error_prepend(errp, "Cannot create block-copy-state: "); -- ret = -EINVAL; -- goto out; -+ return -EINVAL; - } - - cluster_size = block_copy_cluster_size(s->bcs); - - s->done_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp); - if (!s->done_bitmap) { -- ret = -EINVAL; -- goto out; -+ return -EINVAL; - } - bdrv_disable_dirty_bitmap(s->done_bitmap); - - /* s->access_bitmap starts equal to bcs bitmap */ - s->access_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp); - if (!s->access_bitmap) { -- ret = -EINVAL; -- goto out; -+ return -EINVAL; - } - bdrv_disable_dirty_bitmap(s->access_bitmap); - bdrv_dirty_bitmap_merge_internal(s->access_bitmap, -@@ -487,11 +479,7 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, - - qemu_co_mutex_init(&s->lock); - QLIST_INIT(&s->frozen_read_reqs); -- -- ret = 0; --out: -- aio_context_release(ctx); -- return ret; -+ return 0; - } - - static void cbw_close(BlockDriverState *bs) -diff --git a/block/export/export.c b/block/export/export.c -index a8f274e526..6d51ae8ed7 100644 ---- a/block/export/export.c -+++ b/block/export/export.c -@@ -114,7 +114,6 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) - } - - ctx = bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); - - if (export->iothread) { - IOThread *iothread; -@@ -133,8 +132,6 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) - set_context_errp = fixed_iothread ? errp : NULL; - ret = bdrv_try_change_aio_context(bs, new_ctx, NULL, set_context_errp); - if (ret == 0) { -- aio_context_release(ctx); -- aio_context_acquire(new_ctx); - ctx = new_ctx; - } else if (fixed_iothread) { - goto fail; -@@ -191,8 +188,6 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) - assert(exp->blk != NULL); - - QLIST_INSERT_HEAD(&block_exports, exp, next); -- -- aio_context_release(ctx); - return exp; - - fail: -@@ -200,7 +195,6 @@ fail: - blk_set_dev_ops(blk, NULL, NULL); - blk_unref(blk); - } -- aio_context_release(ctx); - if (exp) { - g_free(exp->id); - g_free(exp); -@@ -218,9 +212,6 @@ void blk_exp_ref(BlockExport *exp) - static void blk_exp_delete_bh(void *opaque) - { - BlockExport *exp = opaque; -- AioContext *aio_context = exp->ctx; -- -- aio_context_acquire(aio_context); - - assert(exp->refcount == 0); - QLIST_REMOVE(exp, next); -@@ -230,8 +221,6 @@ static void blk_exp_delete_bh(void *opaque) - qapi_event_send_block_export_deleted(exp->id); - g_free(exp->id); - g_free(exp); -- -- aio_context_release(aio_context); - } - - void blk_exp_unref(BlockExport *exp) -@@ -249,22 +238,16 @@ void blk_exp_unref(BlockExport *exp) - * connections and other internally held references start to shut down. When - * the function returns, there may still be active references while the export - * is in the process of shutting down. -- * -- * Acquires exp->ctx internally. Callers must *not* hold the lock. - */ - void blk_exp_request_shutdown(BlockExport *exp) - { -- AioContext *aio_context = exp->ctx; -- -- aio_context_acquire(aio_context); -- - /* - * If the user doesn't own the export any more, it is already shutting - * down. We must not call .request_shutdown and decrease the refcount a - * second time. - */ - if (!exp->user_owned) { -- goto out; -+ return; - } - - exp->drv->request_shutdown(exp); -@@ -272,9 +255,6 @@ void blk_exp_request_shutdown(BlockExport *exp) - assert(exp->user_owned); - exp->user_owned = false; - blk_exp_unref(exp); -- --out: -- aio_context_release(aio_context); - } - - /* -diff --git a/block/io.c b/block/io.c -index 7e62fabbf5..8fa7670571 100644 ---- a/block/io.c -+++ b/block/io.c -@@ -294,8 +294,6 @@ static void bdrv_co_drain_bh_cb(void *opaque) - BlockDriverState *bs = data->bs; - - if (bs) { -- AioContext *ctx = bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); - bdrv_dec_in_flight(bs); - if (data->begin) { - bdrv_do_drained_begin(bs, data->parent, data->poll); -@@ -303,7 +301,6 @@ static void bdrv_co_drain_bh_cb(void *opaque) - assert(!data->poll); - bdrv_do_drained_end(bs, data->parent); - } -- aio_context_release(ctx); - } else { - assert(data->begin); - bdrv_drain_all_begin(); -@@ -320,8 +317,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, - { - BdrvCoDrainData data; - Coroutine *self = qemu_coroutine_self(); -- AioContext *ctx = bdrv_get_aio_context(bs); -- AioContext *co_ctx = qemu_coroutine_get_aio_context(self); - - /* Calling bdrv_drain() from a BH ensures the current coroutine yields and - * other coroutines run if they were queued by aio_co_enter(). */ -@@ -340,17 +335,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, - bdrv_inc_in_flight(bs); - } - -- /* -- * Temporarily drop the lock across yield or we would get deadlocks. -- * bdrv_co_drain_bh_cb() reaquires the lock as needed. -- * -- * When we yield below, the lock for the current context will be -- * released, so if this is actually the lock that protects bs, don't drop -- * it a second time. -- */ -- if (ctx != co_ctx) { -- aio_context_release(ctx); -- } - replay_bh_schedule_oneshot_event(qemu_get_aio_context(), - bdrv_co_drain_bh_cb, &data); - -@@ -358,11 +342,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, - /* If we are resumed from some other event (such as an aio completion or a - * timer callback), it is a bug in the caller that should be fixed. */ - assert(data.done); -- -- /* Reacquire the AioContext of bs if we dropped it */ -- if (ctx != co_ctx) { -- aio_context_acquire(ctx); -- } - } - - static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent, -@@ -478,13 +457,12 @@ static bool bdrv_drain_all_poll(void) - GLOBAL_STATE_CODE(); - GRAPH_RDLOCK_GUARD_MAINLOOP(); - -- /* bdrv_drain_poll() can't make changes to the graph and we are holding the -- * main AioContext lock, so iterating bdrv_next_all_states() is safe. */ -+ /* -+ * bdrv_drain_poll() can't make changes to the graph and we hold the BQL, -+ * so iterating bdrv_next_all_states() is safe. -+ */ - while ((bs = bdrv_next_all_states(bs))) { -- AioContext *aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - result |= bdrv_drain_poll(bs, NULL, true); -- aio_context_release(aio_context); - } - - return result; -@@ -525,11 +503,7 @@ void bdrv_drain_all_begin_nopoll(void) - /* Quiesce all nodes, without polling in-flight requests yet. The graph - * cannot change during this loop. */ - while ((bs = bdrv_next_all_states(bs))) { -- AioContext *aio_context = bdrv_get_aio_context(bs); -- -- aio_context_acquire(aio_context); - bdrv_do_drained_begin(bs, NULL, false); -- aio_context_release(aio_context); - } - } - -@@ -588,11 +562,7 @@ void bdrv_drain_all_end(void) - } - - while ((bs = bdrv_next_all_states(bs))) { -- AioContext *aio_context = bdrv_get_aio_context(bs); -- -- aio_context_acquire(aio_context); - bdrv_do_drained_end(bs, NULL); -- aio_context_release(aio_context); - } - - assert(qemu_get_current_aio_context() == qemu_get_aio_context()); -@@ -2368,15 +2338,10 @@ int bdrv_flush_all(void) - } - - for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { -- AioContext *aio_context = bdrv_get_aio_context(bs); -- int ret; -- -- aio_context_acquire(aio_context); -- ret = bdrv_flush(bs); -+ int ret = bdrv_flush(bs); - if (ret < 0 && !result) { - result = ret; - } -- aio_context_release(aio_context); - } - - return result; -diff --git a/block/mirror.c b/block/mirror.c -index 51f9e2f17c..5145eb53e1 100644 ---- a/block/mirror.c -+++ b/block/mirror.c -@@ -662,7 +662,6 @@ static int mirror_exit_common(Job *job) - MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job); - BlockJob *bjob = &s->common; - MirrorBDSOpaque *bs_opaque; -- AioContext *replace_aio_context = NULL; - BlockDriverState *src; - BlockDriverState *target_bs; - BlockDriverState *mirror_top_bs; -@@ -677,7 +676,6 @@ static int mirror_exit_common(Job *job) - } - s->prepared = true; - -- aio_context_acquire(qemu_get_aio_context()); - bdrv_graph_rdlock_main_loop(); - - mirror_top_bs = s->mirror_top_bs; -@@ -742,11 +740,6 @@ static int mirror_exit_common(Job *job) - } - bdrv_graph_rdunlock_main_loop(); - -- if (s->to_replace) { -- replace_aio_context = bdrv_get_aio_context(s->to_replace); -- aio_context_acquire(replace_aio_context); -- } -- - if (s->should_complete && !abort) { - BlockDriverState *to_replace = s->to_replace ?: src; - bool ro = bdrv_is_read_only(to_replace); -@@ -785,9 +778,6 @@ static int mirror_exit_common(Job *job) - error_free(s->replace_blocker); - bdrv_unref(s->to_replace); - } -- if (replace_aio_context) { -- aio_context_release(replace_aio_context); -- } - g_free(s->replaces); - - /* -@@ -811,8 +801,6 @@ static int mirror_exit_common(Job *job) - bdrv_unref(mirror_top_bs); - bdrv_unref(src); - -- aio_context_release(qemu_get_aio_context()); -- - return ret; - } - -@@ -1191,24 +1179,17 @@ static void mirror_complete(Job *job, Error **errp) - - /* block all operations on to_replace bs */ - if (s->replaces) { -- AioContext *replace_aio_context; -- - s->to_replace = bdrv_find_node(s->replaces); - if (!s->to_replace) { - error_setg(errp, "Node name '%s' not found", s->replaces); - return; - } - -- replace_aio_context = bdrv_get_aio_context(s->to_replace); -- aio_context_acquire(replace_aio_context); -- - /* TODO Translate this into child freeze system. */ - error_setg(&s->replace_blocker, - "block device is in use by block-job-complete"); - bdrv_op_block_all(s->to_replace, s->replace_blocker); - bdrv_ref(s->to_replace); -- -- aio_context_release(replace_aio_context); - } - - s->should_complete = true; -diff --git a/block/monitor/bitmap-qmp-cmds.c b/block/monitor/bitmap-qmp-cmds.c -index 70d01a3776..a738e7bbf7 100644 ---- a/block/monitor/bitmap-qmp-cmds.c -+++ b/block/monitor/bitmap-qmp-cmds.c -@@ -95,7 +95,6 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, - { - BlockDriverState *bs; - BdrvDirtyBitmap *bitmap; -- AioContext *aio_context; - - if (!name || name[0] == '\0') { - error_setg(errp, "Bitmap name cannot be empty"); -@@ -107,14 +106,11 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, - return; - } - -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- - if (has_granularity) { - if (granularity < 512 || !is_power_of_2(granularity)) { - error_setg(errp, "Granularity must be power of 2 " - "and at least 512"); -- goto out; -+ return; - } - } else { - /* Default to cluster size, if available: */ -@@ -132,12 +128,12 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, - if (persistent && - !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) - { -- goto out; -+ return; - } - - bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp); - if (bitmap == NULL) { -- goto out; -+ return; - } - - if (disabled) { -@@ -145,9 +141,6 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, - } - - bdrv_dirty_bitmap_set_persistence(bitmap, persistent); -- --out: -- aio_context_release(aio_context); - } - - BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name, -@@ -157,7 +150,6 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name, - { - BlockDriverState *bs; - BdrvDirtyBitmap *bitmap; -- AioContext *aio_context; - - GLOBAL_STATE_CODE(); - -@@ -166,19 +158,14 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name, - return NULL; - } - -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- - if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO, - errp)) { -- aio_context_release(aio_context); - return NULL; - } - - if (bdrv_dirty_bitmap_get_persistence(bitmap) && - bdrv_remove_persistent_dirty_bitmap(bs, name, errp) < 0) - { -- aio_context_release(aio_context); - return NULL; - } - -@@ -190,7 +177,6 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name, - *bitmap_bs = bs; - } - -- aio_context_release(aio_context); - return release ? NULL : bitmap; - } - -diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c -index c729cbf1eb..bdbb5cb141 100644 ---- a/block/monitor/block-hmp-cmds.c -+++ b/block/monitor/block-hmp-cmds.c -@@ -141,7 +141,6 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict) - const char *id = qdict_get_str(qdict, "id"); - BlockBackend *blk; - BlockDriverState *bs; -- AioContext *aio_context; - Error *local_err = NULL; - - GLOBAL_STATE_CODE(); -@@ -168,14 +167,10 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict) - return; - } - -- aio_context = blk_get_aio_context(blk); -- aio_context_acquire(aio_context); -- - bs = blk_bs(blk); - if (bs) { - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) { - error_report_err(local_err); -- aio_context_release(aio_context); - return; - } - -@@ -196,8 +191,6 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict) - } else { - blk_unref(blk); - } -- -- aio_context_release(aio_context); - } - - void hmp_commit(Monitor *mon, const QDict *qdict) -@@ -213,7 +206,6 @@ void hmp_commit(Monitor *mon, const QDict *qdict) - ret = blk_commit_all(); - } else { - BlockDriverState *bs; -- AioContext *aio_context; - - blk = blk_by_name(device); - if (!blk) { -@@ -222,18 +214,13 @@ void hmp_commit(Monitor *mon, const QDict *qdict) - } - - bs = bdrv_skip_implicit_filters(blk_bs(blk)); -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - - if (!blk_is_available(blk)) { - error_report("Device '%s' has no medium", device); -- aio_context_release(aio_context); - return; - } - - ret = bdrv_commit(bs); -- -- aio_context_release(aio_context); - } - if (ret < 0) { - error_report("'commit' error for '%s': %s", device, strerror(-ret)); -@@ -560,7 +547,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict) - BlockBackend *blk = NULL; - BlockDriverState *bs = NULL; - BlockBackend *local_blk = NULL; -- AioContext *ctx = NULL; - bool qdev = qdict_get_try_bool(qdict, "qdev", false); - const char *device = qdict_get_str(qdict, "device"); - const char *command = qdict_get_str(qdict, "command"); -@@ -582,9 +568,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict) - } - } - -- ctx = blk ? blk_get_aio_context(blk) : bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); -- - if (bs) { - blk = local_blk = blk_new(bdrv_get_aio_context(bs), 0, BLK_PERM_ALL); - ret = blk_insert_bs(blk, bs, &err); -@@ -622,11 +605,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict) - - fail: - blk_unref(local_blk); -- -- if (ctx) { -- aio_context_release(ctx); -- } -- - hmp_handle_error(mon, err); - } - -@@ -882,7 +860,6 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict) - int nb_sns, i; - int total; - int *global_snapshots; -- AioContext *aio_context; - - typedef struct SnapshotEntry { - QEMUSnapshotInfo sn; -@@ -909,11 +886,8 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict) - error_report_err(err); - return; - } -- aio_context = bdrv_get_aio_context(bs); - -- aio_context_acquire(aio_context); - nb_sns = bdrv_snapshot_list(bs, &sn_tab); -- aio_context_release(aio_context); - - if (nb_sns < 0) { - monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns); -@@ -924,9 +898,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict) - int bs1_nb_sns = 0; - ImageEntry *ie; - SnapshotEntry *se; -- AioContext *ctx = bdrv_get_aio_context(bs1); - -- aio_context_acquire(ctx); - if (bdrv_can_snapshot(bs1)) { - sn = NULL; - bs1_nb_sns = bdrv_snapshot_list(bs1, &sn); -@@ -944,7 +916,6 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict) - } - g_free(sn); - } -- aio_context_release(ctx); - } - - if (no_snapshot) { -diff --git a/block/qapi-sysemu.c b/block/qapi-sysemu.c -index 1618cd225a..e4282631d2 100644 ---- a/block/qapi-sysemu.c -+++ b/block/qapi-sysemu.c -@@ -174,7 +174,6 @@ blockdev_remove_medium(const char *device, const char *id, Error **errp) - { - BlockBackend *blk; - BlockDriverState *bs; -- AioContext *aio_context; - bool has_attached_device; - - GLOBAL_STATE_CODE(); -@@ -204,13 +203,10 @@ blockdev_remove_medium(const char *device, const char *id, Error **errp) - return; - } - -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- - bdrv_graph_rdlock_main_loop(); - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) { - bdrv_graph_rdunlock_main_loop(); -- goto out; -+ return; - } - bdrv_graph_rdunlock_main_loop(); - -@@ -223,9 +219,6 @@ blockdev_remove_medium(const char *device, const char *id, Error **errp) - * value passed here (i.e. false). */ - blk_dev_change_media_cb(blk, false, &error_abort); - } -- --out: -- aio_context_release(aio_context); - } - - void qmp_blockdev_remove_medium(const char *id, Error **errp) -@@ -237,7 +230,6 @@ static void qmp_blockdev_insert_anon_medium(BlockBackend *blk, - BlockDriverState *bs, Error **errp) - { - Error *local_err = NULL; -- AioContext *ctx; - bool has_device; - int ret; - -@@ -259,11 +251,7 @@ static void qmp_blockdev_insert_anon_medium(BlockBackend *blk, - return; - } - -- ctx = bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); - ret = blk_insert_bs(blk, bs, errp); -- aio_context_release(ctx); -- - if (ret < 0) { - return; - } -@@ -374,9 +362,7 @@ void qmp_blockdev_change_medium(const char *device, - qdict_put_str(options, "driver", format); - } - -- aio_context_acquire(qemu_get_aio_context()); - medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp); -- aio_context_release(qemu_get_aio_context()); - - if (!medium_bs) { - goto fail; -@@ -437,20 +423,16 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp) - ThrottleConfig cfg; - BlockDriverState *bs; - BlockBackend *blk; -- AioContext *aio_context; - - blk = qmp_get_blk(arg->device, arg->id, errp); - if (!blk) { - return; - } - -- aio_context = blk_get_aio_context(blk); -- aio_context_acquire(aio_context); -- - bs = blk_bs(blk); - if (!bs) { - error_setg(errp, "Device has no medium"); -- goto out; -+ return; - } - - throttle_config_init(&cfg); -@@ -505,7 +487,7 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp) - } - - if (!throttle_is_valid(&cfg, errp)) { -- goto out; -+ return; - } - - if (throttle_enabled(&cfg)) { -@@ -522,9 +504,6 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp) - /* If all throttling settings are set to 0, disable I/O limits */ - blk_io_limits_disable(blk); - } -- --out: -- aio_context_release(aio_context); - } - - void qmp_block_latency_histogram_set( -diff --git a/block/qapi.c b/block/qapi.c -index 82a30b38fe..9e806fa230 100644 ---- a/block/qapi.c -+++ b/block/qapi.c -@@ -234,13 +234,11 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp) - int ret; - Error *err = NULL; - -- aio_context_acquire(bdrv_get_aio_context(bs)); -- - size = bdrv_getlength(bs); - if (size < 0) { - error_setg_errno(errp, -size, "Can't get image size '%s'", - bs->exact_filename); -- goto out; -+ return; - } - - bdrv_refresh_filename(bs); -@@ -265,7 +263,7 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp) - info->format_specific = bdrv_get_specific_info(bs, &err); - if (err) { - error_propagate(errp, err); -- goto out; -+ return; - } - backing_filename = bs->backing_file; - if (backing_filename[0] != '\0') { -@@ -300,11 +298,8 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp) - break; - default: - error_propagate(errp, err); -- goto out; -+ return; - } -- --out: -- aio_context_release(bdrv_get_aio_context(bs)); - } - - /** -@@ -709,15 +704,10 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes, - /* Just to be safe if query_nodes is not always initialized */ - if (has_query_nodes && query_nodes) { - for (bs = bdrv_next_node(NULL); bs; bs = bdrv_next_node(bs)) { -- AioContext *ctx = bdrv_get_aio_context(bs); -- -- aio_context_acquire(ctx); - QAPI_LIST_APPEND(tail, bdrv_query_bds_stats(bs, false)); -- aio_context_release(ctx); - } - } else { - for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) { -- AioContext *ctx = blk_get_aio_context(blk); - BlockStats *s; - char *qdev; - -@@ -725,7 +715,6 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes, - continue; - } - -- aio_context_acquire(ctx); - s = bdrv_query_bds_stats(blk_bs(blk), true); - s->device = g_strdup(blk_name(blk)); - -@@ -737,7 +726,6 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes, - } - - bdrv_query_blk_stats(s->stats, blk); -- aio_context_release(ctx); - - QAPI_LIST_APPEND(tail, s); - } -diff --git a/block/raw-format.c b/block/raw-format.c -index 1111dffd54..ac7e8495f6 100644 ---- a/block/raw-format.c -+++ b/block/raw-format.c -@@ -470,7 +470,6 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags, - Error **errp) - { - BDRVRawState *s = bs->opaque; -- AioContext *ctx; - bool has_size; - uint64_t offset, size; - BdrvChildRole file_role; -@@ -522,11 +521,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags, - bs->file->bs->filename); - } - -- ctx = bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); - ret = raw_apply_options(bs, s, offset, has_size, size, errp); -- aio_context_release(ctx); -- - if (ret < 0) { - return ret; - } -diff --git a/block/replication.c b/block/replication.c -index 424b537ff7..ca6bd0a720 100644 ---- a/block/replication.c -+++ b/block/replication.c -@@ -394,14 +394,7 @@ static void reopen_backing_file(BlockDriverState *bs, bool writable, - } - - if (reopen_queue) { -- AioContext *ctx = bdrv_get_aio_context(bs); -- if (ctx != qemu_get_aio_context()) { -- aio_context_release(ctx); -- } - bdrv_reopen_multiple(reopen_queue, errp); -- if (ctx != qemu_get_aio_context()) { -- aio_context_acquire(ctx); -- } - } - } - -@@ -462,14 +455,11 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - BlockDriverState *top_bs; - BdrvChild *active_disk, *hidden_disk, *secondary_disk; - int64_t active_length, hidden_length, disk_length; -- AioContext *aio_context; - Error *local_err = NULL; - BackupPerf perf = { .use_copy_range = true, .max_workers = 1 }; - - GLOBAL_STATE_CODE(); - -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - s = bs->opaque; - - if (s->stage == BLOCK_REPLICATION_DONE || -@@ -479,20 +469,17 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - * Ignore the request because the secondary side of replication - * doesn't have to do anything anymore. - */ -- aio_context_release(aio_context); - return; - } - - if (s->stage != BLOCK_REPLICATION_NONE) { - error_setg(errp, "Block replication is running or done"); -- aio_context_release(aio_context); - return; - } - - if (s->mode != mode) { - error_setg(errp, "The parameter mode's value is invalid, needs %d," - " but got %d", s->mode, mode); -- aio_context_release(aio_context); - return; - } - -@@ -505,7 +492,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - if (!active_disk || !active_disk->bs || !active_disk->bs->backing) { - error_setg(errp, "Active disk doesn't have backing file"); - bdrv_graph_rdunlock_main_loop(); -- aio_context_release(aio_context); - return; - } - -@@ -513,7 +499,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - if (!hidden_disk->bs || !hidden_disk->bs->backing) { - error_setg(errp, "Hidden disk doesn't have backing file"); - bdrv_graph_rdunlock_main_loop(); -- aio_context_release(aio_context); - return; - } - -@@ -521,7 +506,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - if (!secondary_disk->bs || !bdrv_has_blk(secondary_disk->bs)) { - error_setg(errp, "The secondary disk doesn't have block backend"); - bdrv_graph_rdunlock_main_loop(); -- aio_context_release(aio_context); - return; - } - bdrv_graph_rdunlock_main_loop(); -@@ -534,7 +518,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - active_length != hidden_length || hidden_length != disk_length) { - error_setg(errp, "Active disk, hidden disk, secondary disk's length" - " are not the same"); -- aio_context_release(aio_context); - return; - } - -@@ -546,7 +529,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - !hidden_disk->bs->drv->bdrv_make_empty) { - error_setg(errp, - "Active disk or hidden disk doesn't support make_empty"); -- aio_context_release(aio_context); - bdrv_graph_rdunlock_main_loop(); - return; - } -@@ -556,7 +538,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - reopen_backing_file(bs, true, &local_err); - if (local_err) { - error_propagate(errp, local_err); -- aio_context_release(aio_context); - return; - } - -@@ -569,7 +550,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - if (local_err) { - error_propagate(errp, local_err); - bdrv_graph_wrunlock(); -- aio_context_release(aio_context); - return; - } - -@@ -580,7 +560,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - if (local_err) { - error_propagate(errp, local_err); - bdrv_graph_wrunlock(); -- aio_context_release(aio_context); - return; - } - -@@ -594,7 +573,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - error_setg(errp, "No top_bs or it is invalid"); - bdrv_graph_wrunlock(); - reopen_backing_file(bs, false, NULL); -- aio_context_release(aio_context); - return; - } - bdrv_op_block_all(top_bs, s->blocker); -@@ -612,13 +590,11 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - if (local_err) { - error_propagate(errp, local_err); - backup_job_cleanup(bs); -- aio_context_release(aio_context); - return; - } - job_start(&s->backup_job->job); - break; - default: -- aio_context_release(aio_context); - abort(); - } - -@@ -629,18 +605,12 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - } - - s->error = 0; -- aio_context_release(aio_context); - } - - static void replication_do_checkpoint(ReplicationState *rs, Error **errp) - { - BlockDriverState *bs = rs->opaque; -- BDRVReplicationState *s; -- AioContext *aio_context; -- -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- s = bs->opaque; -+ BDRVReplicationState *s = bs->opaque; - - if (s->stage == BLOCK_REPLICATION_DONE || - s->stage == BLOCK_REPLICATION_FAILOVER) { -@@ -649,38 +619,28 @@ static void replication_do_checkpoint(ReplicationState *rs, Error **errp) - * Ignore the request because the secondary side of replication - * doesn't have to do anything anymore. - */ -- aio_context_release(aio_context); - return; - } - - if (s->mode == REPLICATION_MODE_SECONDARY) { - secondary_do_checkpoint(bs, errp); - } -- aio_context_release(aio_context); - } - - static void replication_get_error(ReplicationState *rs, Error **errp) - { - BlockDriverState *bs = rs->opaque; -- BDRVReplicationState *s; -- AioContext *aio_context; -- -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- s = bs->opaque; -+ BDRVReplicationState *s = bs->opaque; - - if (s->stage == BLOCK_REPLICATION_NONE) { - error_setg(errp, "Block replication is not running"); -- aio_context_release(aio_context); - return; - } - - if (s->error) { - error_setg(errp, "I/O error occurred"); -- aio_context_release(aio_context); - return; - } -- aio_context_release(aio_context); - } - - static void replication_done(void *opaque, int ret) -@@ -708,12 +668,7 @@ static void replication_done(void *opaque, int ret) - static void replication_stop(ReplicationState *rs, bool failover, Error **errp) - { - BlockDriverState *bs = rs->opaque; -- BDRVReplicationState *s; -- AioContext *aio_context; -- -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- s = bs->opaque; -+ BDRVReplicationState *s = bs->opaque; - - if (s->stage == BLOCK_REPLICATION_DONE || - s->stage == BLOCK_REPLICATION_FAILOVER) { -@@ -722,13 +677,11 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp) - * Ignore the request because the secondary side of replication - * doesn't have to do anything anymore. - */ -- aio_context_release(aio_context); - return; - } - - if (s->stage != BLOCK_REPLICATION_RUNNING) { - error_setg(errp, "Block replication is not running"); -- aio_context_release(aio_context); - return; - } - -@@ -744,15 +697,12 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp) - * disk, secondary disk in backup_job_completed(). - */ - if (s->backup_job) { -- aio_context_release(aio_context); - job_cancel_sync(&s->backup_job->job, true); -- aio_context_acquire(aio_context); - } - - if (!failover) { - secondary_do_checkpoint(bs, errp); - s->stage = BLOCK_REPLICATION_DONE; -- aio_context_release(aio_context); - return; - } - -@@ -765,10 +715,8 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp) - bdrv_graph_rdunlock_main_loop(); - break; - default: -- aio_context_release(aio_context); - abort(); - } -- aio_context_release(aio_context); - } - - static const char *const replication_strong_runtime_opts[] = { -diff --git a/block/snapshot.c b/block/snapshot.c -index e486d3e205..a28f2b039f 100644 ---- a/block/snapshot.c -+++ b/block/snapshot.c -@@ -525,9 +525,7 @@ static bool GRAPH_RDLOCK bdrv_all_snapshots_includes_bs(BlockDriverState *bs) - return bdrv_has_blk(bs) || QLIST_EMPTY(&bs->parents); - } - --/* Group operations. All block drivers are involved. -- * These functions will properly handle dataplane (take aio_context_acquire -- * when appropriate for appropriate block drivers) */ -+/* Group operations. All block drivers are involved. */ - - bool bdrv_all_can_snapshot(bool has_devices, strList *devices, - Error **errp) -@@ -545,14 +543,11 @@ bool bdrv_all_can_snapshot(bool has_devices, strList *devices, - iterbdrvs = bdrvs; - while (iterbdrvs) { - BlockDriverState *bs = iterbdrvs->data; -- AioContext *ctx = bdrv_get_aio_context(bs); - bool ok = true; - -- aio_context_acquire(ctx); - if (devices || bdrv_all_snapshots_includes_bs(bs)) { - ok = bdrv_can_snapshot(bs); - } -- aio_context_release(ctx); - if (!ok) { - error_setg(errp, "Device '%s' is writable but does not support " - "snapshots", bdrv_get_device_or_node_name(bs)); -@@ -582,18 +577,15 @@ int bdrv_all_delete_snapshot(const char *name, - iterbdrvs = bdrvs; - while (iterbdrvs) { - BlockDriverState *bs = iterbdrvs->data; -- AioContext *ctx = bdrv_get_aio_context(bs); - QEMUSnapshotInfo sn1, *snapshot = &sn1; - int ret = 0; - -- aio_context_acquire(ctx); - if ((devices || bdrv_all_snapshots_includes_bs(bs)) && - bdrv_snapshot_find(bs, snapshot, name) >= 0) - { - ret = bdrv_snapshot_delete(bs, snapshot->id_str, - snapshot->name, errp); - } -- aio_context_release(ctx); - if (ret < 0) { - error_prepend(errp, "Could not delete snapshot '%s' on '%s': ", - name, bdrv_get_device_or_node_name(bs)); -@@ -628,17 +620,14 @@ int bdrv_all_goto_snapshot(const char *name, - iterbdrvs = bdrvs; - while (iterbdrvs) { - BlockDriverState *bs = iterbdrvs->data; -- AioContext *ctx = bdrv_get_aio_context(bs); - bool all_snapshots_includes_bs; - -- aio_context_acquire(ctx); - bdrv_graph_rdlock_main_loop(); - all_snapshots_includes_bs = bdrv_all_snapshots_includes_bs(bs); - bdrv_graph_rdunlock_main_loop(); - - ret = (devices || all_snapshots_includes_bs) ? - bdrv_snapshot_goto(bs, name, errp) : 0; -- aio_context_release(ctx); - if (ret < 0) { - bdrv_graph_rdlock_main_loop(); - error_prepend(errp, "Could not load snapshot '%s' on '%s': ", -@@ -670,15 +659,12 @@ int bdrv_all_has_snapshot(const char *name, - iterbdrvs = bdrvs; - while (iterbdrvs) { - BlockDriverState *bs = iterbdrvs->data; -- AioContext *ctx = bdrv_get_aio_context(bs); - QEMUSnapshotInfo sn; - int ret = 0; - -- aio_context_acquire(ctx); - if (devices || bdrv_all_snapshots_includes_bs(bs)) { - ret = bdrv_snapshot_find(bs, &sn, name); - } -- aio_context_release(ctx); - if (ret < 0) { - if (ret == -ENOENT) { - return 0; -@@ -715,10 +701,8 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, - iterbdrvs = bdrvs; - while (iterbdrvs) { - BlockDriverState *bs = iterbdrvs->data; -- AioContext *ctx = bdrv_get_aio_context(bs); - int ret = 0; - -- aio_context_acquire(ctx); - if (bs == vm_state_bs) { - sn->vm_state_size = vm_state_size; - ret = bdrv_snapshot_create(bs, sn); -@@ -726,7 +710,6 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, - sn->vm_state_size = 0; - ret = bdrv_snapshot_create(bs, sn); - } -- aio_context_release(ctx); - if (ret < 0) { - error_setg(errp, "Could not create snapshot '%s' on '%s'", - sn->name, bdrv_get_device_or_node_name(bs)); -@@ -757,13 +740,10 @@ BlockDriverState *bdrv_all_find_vmstate_bs(const char *vmstate_bs, - iterbdrvs = bdrvs; - while (iterbdrvs) { - BlockDriverState *bs = iterbdrvs->data; -- AioContext *ctx = bdrv_get_aio_context(bs); - bool found = false; - -- aio_context_acquire(ctx); - found = (devices || bdrv_all_snapshots_includes_bs(bs)) && - bdrv_can_snapshot(bs); -- aio_context_release(ctx); - - if (vmstate_bs) { - if (g_str_equal(vmstate_bs, -diff --git a/block/write-threshold.c b/block/write-threshold.c -index 76d8885677..56fe88de81 100644 ---- a/block/write-threshold.c -+++ b/block/write-threshold.c -@@ -33,7 +33,6 @@ void qmp_block_set_write_threshold(const char *node_name, - Error **errp) - { - BlockDriverState *bs; -- AioContext *aio_context; - - bs = bdrv_find_node(node_name); - if (!bs) { -@@ -41,12 +40,7 @@ void qmp_block_set_write_threshold(const char *node_name, - return; - } - -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- - bdrv_write_threshold_set(bs, threshold_bytes); -- -- aio_context_release(aio_context); - } - - void bdrv_write_threshold_check_write(BlockDriverState *bs, int64_t offset, -diff --git a/blockdev.c b/blockdev.c -index 9e1381169d..5d8b3a23eb 100644 ---- a/blockdev.c -+++ b/blockdev.c -@@ -662,7 +662,6 @@ err_no_opts: - /* Takes the ownership of bs_opts */ - BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp) - { -- BlockDriverState *bs; - int bdrv_flags = 0; - - GLOBAL_STATE_CODE(); -@@ -677,11 +676,7 @@ BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp) - bdrv_flags |= BDRV_O_INACTIVE; - } - -- aio_context_acquire(qemu_get_aio_context()); -- bs = bdrv_open(NULL, NULL, bs_opts, bdrv_flags, errp); -- aio_context_release(qemu_get_aio_context()); -- -- return bs; -+ return bdrv_open(NULL, NULL, bs_opts, bdrv_flags, errp); - } - - void blockdev_close_all_bdrv_states(void) -@@ -690,11 +685,7 @@ void blockdev_close_all_bdrv_states(void) - - GLOBAL_STATE_CODE(); - QTAILQ_FOREACH_SAFE(bs, &monitor_bdrv_states, monitor_list, next_bs) { -- AioContext *ctx = bdrv_get_aio_context(bs); -- -- aio_context_acquire(ctx); - bdrv_unref(bs); -- aio_context_release(ctx); - } - } - -@@ -1048,7 +1039,6 @@ fail: - static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp) - { - BlockDriverState *bs; -- AioContext *aio_context; - - GRAPH_RDLOCK_GUARD_MAINLOOP(); - -@@ -1062,16 +1052,11 @@ static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp) - return NULL; - } - -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- - if (!bdrv_is_inserted(bs)) { - error_setg(errp, "Device has no medium"); - bs = NULL; - } - -- aio_context_release(aio_context); -- - return bs; - } - -@@ -1141,7 +1126,6 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device, - Error **errp) - { - BlockDriverState *bs; -- AioContext *aio_context; - QEMUSnapshotInfo sn; - Error *local_err = NULL; - SnapshotInfo *info = NULL; -@@ -1154,39 +1138,35 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device, - if (!bs) { - return NULL; - } -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - - if (!id && !name) { - error_setg(errp, "Name or id must be provided"); -- goto out_aio_context; -+ return NULL; - } - - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, errp)) { -- goto out_aio_context; -+ return NULL; - } - - ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err); - if (local_err) { - error_propagate(errp, local_err); -- goto out_aio_context; -+ return NULL; - } - if (!ret) { - error_setg(errp, - "Snapshot with id '%s' and name '%s' does not exist on " - "device '%s'", - STR_OR_NULL(id), STR_OR_NULL(name), device); -- goto out_aio_context; -+ return NULL; - } - - bdrv_snapshot_delete(bs, id, name, &local_err); - if (local_err) { - error_propagate(errp, local_err); -- goto out_aio_context; -+ return NULL; - } - -- aio_context_release(aio_context); -- - info = g_new0(SnapshotInfo, 1); - info->id = g_strdup(sn.id_str); - info->name = g_strdup(sn.name); -@@ -1201,10 +1181,6 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device, - } - - return info; -- --out_aio_context: -- aio_context_release(aio_context); -- return NULL; - } - - /* internal snapshot private data */ -@@ -1232,7 +1208,6 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal, - bool ret; - int64_t rt; - InternalSnapshotState *state = g_new0(InternalSnapshotState, 1); -- AioContext *aio_context; - int ret1; - - GLOBAL_STATE_CODE(); -@@ -1248,33 +1223,30 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal, - return; - } - -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- - state->bs = bs; - - /* Paired with .clean() */ - bdrv_drained_begin(bs); - - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) { -- goto out; -+ return; - } - - if (bdrv_is_read_only(bs)) { - error_setg(errp, "Device '%s' is read only", device); -- goto out; -+ return; - } - - if (!bdrv_can_snapshot(bs)) { - error_setg(errp, "Block format '%s' used by device '%s' " - "does not support internal snapshots", - bs->drv->format_name, device); -- goto out; -+ return; - } - - if (!strlen(name)) { - error_setg(errp, "Name is empty"); -- goto out; -+ return; - } - - /* check whether a snapshot with name exist */ -@@ -1282,12 +1254,12 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal, - &local_err); - if (local_err) { - error_propagate(errp, local_err); -- goto out; -+ return; - } else if (ret) { - error_setg(errp, - "Snapshot with name '%s' already exists on device '%s'", - name, device); -- goto out; -+ return; - } - - /* 3. take the snapshot */ -@@ -1308,14 +1280,11 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal, - error_setg_errno(errp, -ret1, - "Failed to create snapshot '%s' on device '%s'", - name, device); -- goto out; -+ return; - } - - /* 4. succeed, mark a snapshot is created */ - state->created = true; -- --out: -- aio_context_release(aio_context); - } - - static void internal_snapshot_abort(void *opaque) -@@ -1323,7 +1292,6 @@ static void internal_snapshot_abort(void *opaque) - InternalSnapshotState *state = opaque; - BlockDriverState *bs = state->bs; - QEMUSnapshotInfo *sn = &state->sn; -- AioContext *aio_context; - Error *local_error = NULL; - - GLOBAL_STATE_CODE(); -@@ -1333,9 +1301,6 @@ static void internal_snapshot_abort(void *opaque) - return; - } - -- aio_context = bdrv_get_aio_context(state->bs); -- aio_context_acquire(aio_context); -- - if (bdrv_snapshot_delete(bs, sn->id_str, sn->name, &local_error) < 0) { - error_reportf_err(local_error, - "Failed to delete snapshot with id '%s' and " -@@ -1343,25 +1308,17 @@ static void internal_snapshot_abort(void *opaque) - sn->id_str, sn->name, - bdrv_get_device_name(bs)); - } -- -- aio_context_release(aio_context); - } - - static void internal_snapshot_clean(void *opaque) - { - g_autofree InternalSnapshotState *state = opaque; -- AioContext *aio_context; - - if (!state->bs) { - return; - } - -- aio_context = bdrv_get_aio_context(state->bs); -- aio_context_acquire(aio_context); -- - bdrv_drained_end(state->bs); -- -- aio_context_release(aio_context); - } - - /* external snapshot private data */ -@@ -1395,7 +1352,6 @@ static void external_snapshot_action(TransactionAction *action, - /* File name of the new image (for 'blockdev-snapshot-sync') */ - const char *new_image_file; - ExternalSnapshotState *state = g_new0(ExternalSnapshotState, 1); -- AioContext *aio_context; - uint64_t perm, shared; - - /* TODO We'll eventually have to take a writer lock in this function */ -@@ -1435,26 +1391,23 @@ static void external_snapshot_action(TransactionAction *action, - return; - } - -- aio_context = bdrv_get_aio_context(state->old_bs); -- aio_context_acquire(aio_context); -- - /* Paired with .clean() */ - bdrv_drained_begin(state->old_bs); - - if (!bdrv_is_inserted(state->old_bs)) { - error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device); -- goto out; -+ return; - } - - if (bdrv_op_is_blocked(state->old_bs, - BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, errp)) { -- goto out; -+ return; - } - - if (!bdrv_is_read_only(state->old_bs)) { - if (bdrv_flush(state->old_bs)) { - error_setg(errp, QERR_IO_ERROR); -- goto out; -+ return; - } - } - -@@ -1466,13 +1419,13 @@ static void external_snapshot_action(TransactionAction *action, - - if (node_name && !snapshot_node_name) { - error_setg(errp, "New overlay node-name missing"); -- goto out; -+ return; - } - - if (snapshot_node_name && - bdrv_lookup_bs(snapshot_node_name, snapshot_node_name, NULL)) { - error_setg(errp, "New overlay node-name already in use"); -- goto out; -+ return; - } - - flags = state->old_bs->open_flags; -@@ -1485,20 +1438,18 @@ static void external_snapshot_action(TransactionAction *action, - int64_t size = bdrv_getlength(state->old_bs); - if (size < 0) { - error_setg_errno(errp, -size, "bdrv_getlength failed"); -- goto out; -+ return; - } - bdrv_refresh_filename(state->old_bs); - -- aio_context_release(aio_context); - bdrv_img_create(new_image_file, format, - state->old_bs->filename, - state->old_bs->drv->format_name, - NULL, size, flags, false, &local_err); -- aio_context_acquire(aio_context); - - if (local_err) { - error_propagate(errp, local_err); -- goto out; -+ return; - } - } - -@@ -1508,20 +1459,15 @@ static void external_snapshot_action(TransactionAction *action, - } - qdict_put_str(options, "driver", format); - } -- aio_context_release(aio_context); - -- aio_context_acquire(qemu_get_aio_context()); - state->new_bs = bdrv_open(new_image_file, snapshot_ref, options, flags, - errp); -- aio_context_release(qemu_get_aio_context()); - - /* We will manually add the backing_hd field to the bs later */ - if (!state->new_bs) { - return; - } - -- aio_context_acquire(aio_context); -- - /* - * Allow attaching a backing file to an overlay that's already in use only - * if the parents don't assume that they are already seeing a valid image. -@@ -1530,41 +1476,34 @@ static void external_snapshot_action(TransactionAction *action, - bdrv_get_cumulative_perm(state->new_bs, &perm, &shared); - if (perm & BLK_PERM_CONSISTENT_READ) { - error_setg(errp, "The overlay is already in use"); -- goto out; -+ return; - } - - if (state->new_bs->drv->is_filter) { - error_setg(errp, "Filters cannot be used as overlays"); -- goto out; -+ return; - } - - if (bdrv_cow_child(state->new_bs)) { - error_setg(errp, "The overlay already has a backing image"); -- goto out; -+ return; - } - - if (!state->new_bs->drv->supports_backing) { - error_setg(errp, "The overlay does not support backing images"); -- goto out; -+ return; - } - - ret = bdrv_append(state->new_bs, state->old_bs, errp); - if (ret < 0) { -- goto out; -+ return; - } - state->overlay_appended = true; -- --out: -- aio_context_release(aio_context); - } - - static void external_snapshot_commit(void *opaque) - { - ExternalSnapshotState *state = opaque; -- AioContext *aio_context; -- -- aio_context = bdrv_get_aio_context(state->old_bs); -- aio_context_acquire(aio_context); - - /* We don't need (or want) to use the transactional - * bdrv_reopen_multiple() across all the entries at once, because we -@@ -1572,8 +1511,6 @@ static void external_snapshot_commit(void *opaque) - if (!qatomic_read(&state->old_bs->copy_on_read)) { - bdrv_reopen_set_read_only(state->old_bs, true, NULL); - } -- -- aio_context_release(aio_context); - } - - static void external_snapshot_abort(void *opaque) -@@ -1586,7 +1523,6 @@ static void external_snapshot_abort(void *opaque) - int ret; - - aio_context = bdrv_get_aio_context(state->old_bs); -- aio_context_acquire(aio_context); - - bdrv_ref(state->old_bs); /* we can't let bdrv_set_backind_hd() - close state->old_bs; we need it */ -@@ -1599,15 +1535,9 @@ static void external_snapshot_abort(void *opaque) - */ - tmp_context = bdrv_get_aio_context(state->old_bs); - if (aio_context != tmp_context) { -- aio_context_release(aio_context); -- aio_context_acquire(tmp_context); -- - ret = bdrv_try_change_aio_context(state->old_bs, - aio_context, NULL, NULL); - assert(ret == 0); -- -- aio_context_release(tmp_context); -- aio_context_acquire(aio_context); - } - - bdrv_drained_begin(state->new_bs); -@@ -1617,8 +1547,6 @@ static void external_snapshot_abort(void *opaque) - bdrv_drained_end(state->new_bs); - - bdrv_unref(state->old_bs); /* bdrv_replace_node() ref'ed old_bs */ -- -- aio_context_release(aio_context); - } - } - } -@@ -1626,19 +1554,13 @@ static void external_snapshot_abort(void *opaque) - static void external_snapshot_clean(void *opaque) - { - g_autofree ExternalSnapshotState *state = opaque; -- AioContext *aio_context; - - if (!state->old_bs) { - return; - } - -- aio_context = bdrv_get_aio_context(state->old_bs); -- aio_context_acquire(aio_context); -- - bdrv_drained_end(state->old_bs); - bdrv_unref(state->new_bs); -- -- aio_context_release(aio_context); - } - - typedef struct DriveBackupState { -@@ -1670,7 +1592,6 @@ static void drive_backup_action(DriveBackup *backup, - BlockDriverState *target_bs; - BlockDriverState *source = NULL; - AioContext *aio_context; -- AioContext *old_context; - const char *format; - QDict *options; - Error *local_err = NULL; -@@ -1698,7 +1619,6 @@ static void drive_backup_action(DriveBackup *backup, - } - - aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - - state->bs = bs; - /* Paired with .clean() */ -@@ -1713,7 +1633,7 @@ static void drive_backup_action(DriveBackup *backup, - bdrv_graph_rdlock_main_loop(); - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) { - bdrv_graph_rdunlock_main_loop(); -- goto out; -+ return; - } - - flags = bs->open_flags | BDRV_O_RDWR; -@@ -1744,7 +1664,7 @@ static void drive_backup_action(DriveBackup *backup, - size = bdrv_getlength(bs); - if (size < 0) { - error_setg_errno(errp, -size, "bdrv_getlength failed"); -- goto out; -+ return; - } - - if (backup->mode != NEW_IMAGE_MODE_EXISTING) { -@@ -1770,7 +1690,7 @@ static void drive_backup_action(DriveBackup *backup, - - if (local_err) { - error_propagate(errp, local_err); -- goto out; -+ return; - } - - options = qdict_new(); -@@ -1779,30 +1699,18 @@ static void drive_backup_action(DriveBackup *backup, - if (format) { - qdict_put_str(options, "driver", format); - } -- aio_context_release(aio_context); - -- aio_context_acquire(qemu_get_aio_context()); - target_bs = bdrv_open(backup->target, NULL, options, flags, errp); -- aio_context_release(qemu_get_aio_context()); -- - if (!target_bs) { - return; - } - -- /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ -- old_context = bdrv_get_aio_context(target_bs); -- aio_context_acquire(old_context); -- - ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); - if (ret < 0) { - bdrv_unref(target_bs); -- aio_context_release(old_context); - return; - } - -- aio_context_release(old_context); -- aio_context_acquire(aio_context); -- - if (set_backing_hd) { - if (bdrv_set_backing_hd(target_bs, source, errp) < 0) { - goto unref; -@@ -1815,22 +1723,14 @@ static void drive_backup_action(DriveBackup *backup, - - unref: - bdrv_unref(target_bs); --out: -- aio_context_release(aio_context); - } - - static void drive_backup_commit(void *opaque) - { - DriveBackupState *state = opaque; -- AioContext *aio_context; -- -- aio_context = bdrv_get_aio_context(state->bs); -- aio_context_acquire(aio_context); - - assert(state->job); - job_start(&state->job->job); -- -- aio_context_release(aio_context); - } - - static void drive_backup_abort(void *opaque) -@@ -1845,18 +1745,12 @@ static void drive_backup_abort(void *opaque) - static void drive_backup_clean(void *opaque) - { - g_autofree DriveBackupState *state = opaque; -- AioContext *aio_context; - - if (!state->bs) { - return; - } - -- aio_context = bdrv_get_aio_context(state->bs); -- aio_context_acquire(aio_context); -- - bdrv_drained_end(state->bs); -- -- aio_context_release(aio_context); - } - - typedef struct BlockdevBackupState { -@@ -1881,7 +1775,6 @@ static void blockdev_backup_action(BlockdevBackup *backup, - BlockDriverState *bs; - BlockDriverState *target_bs; - AioContext *aio_context; -- AioContext *old_context; - int ret; - - tran_add(tran, &blockdev_backup_drv, state); -@@ -1898,17 +1791,12 @@ static void blockdev_backup_action(BlockdevBackup *backup, - - /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ - aio_context = bdrv_get_aio_context(bs); -- old_context = bdrv_get_aio_context(target_bs); -- aio_context_acquire(old_context); - - ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); - if (ret < 0) { -- aio_context_release(old_context); - return; - } - -- aio_context_release(old_context); -- aio_context_acquire(aio_context); - state->bs = bs; - - /* Paired with .clean() */ -@@ -1917,22 +1805,14 @@ static void blockdev_backup_action(BlockdevBackup *backup, - state->job = do_backup_common(qapi_BlockdevBackup_base(backup), - bs, target_bs, aio_context, - block_job_txn, errp); -- -- aio_context_release(aio_context); - } - - static void blockdev_backup_commit(void *opaque) - { - BlockdevBackupState *state = opaque; -- AioContext *aio_context; -- -- aio_context = bdrv_get_aio_context(state->bs); -- aio_context_acquire(aio_context); - - assert(state->job); - job_start(&state->job->job); -- -- aio_context_release(aio_context); - } - - static void blockdev_backup_abort(void *opaque) -@@ -1947,18 +1827,12 @@ static void blockdev_backup_abort(void *opaque) - static void blockdev_backup_clean(void *opaque) - { - g_autofree BlockdevBackupState *state = opaque; -- AioContext *aio_context; - - if (!state->bs) { - return; - } - -- aio_context = bdrv_get_aio_context(state->bs); -- aio_context_acquire(aio_context); -- - bdrv_drained_end(state->bs); -- -- aio_context_release(aio_context); - } - - typedef struct BlockDirtyBitmapState { -@@ -2454,7 +2328,6 @@ void qmp_block_stream(const char *job_id, const char *device, - } - - aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - - bdrv_graph_rdlock_main_loop(); - if (base) { -@@ -2521,7 +2394,7 @@ void qmp_block_stream(const char *job_id, const char *device, - if (!base_bs && backing_file) { - error_setg(errp, "backing file specified, but streaming the " - "entire chain"); -- goto out; -+ return; - } - - if (has_auto_finalize && !auto_finalize) { -@@ -2536,18 +2409,14 @@ void qmp_block_stream(const char *job_id, const char *device, - filter_node_name, &local_err); - if (local_err) { - error_propagate(errp, local_err); -- goto out; -+ return; - } - - trace_qmp_block_stream(bs); -- --out: -- aio_context_release(aio_context); - return; - - out_rdlock: - bdrv_graph_rdunlock_main_loop(); -- aio_context_release(aio_context); - } - - void qmp_block_commit(const char *job_id, const char *device, -@@ -2606,10 +2475,9 @@ void qmp_block_commit(const char *job_id, const char *device, - } - - aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, errp)) { -- goto out; -+ return; - } - - /* default top_bs is the active layer */ -@@ -2617,16 +2485,16 @@ void qmp_block_commit(const char *job_id, const char *device, - - if (top_node && top) { - error_setg(errp, "'top-node' and 'top' are mutually exclusive"); -- goto out; -+ return; - } else if (top_node) { - top_bs = bdrv_lookup_bs(NULL, top_node, errp); - if (top_bs == NULL) { -- goto out; -+ return; - } - if (!bdrv_chain_contains(bs, top_bs)) { - error_setg(errp, "'%s' is not in this backing file chain", - top_node); -- goto out; -+ return; - } - } else if (top) { - /* This strcmp() is just a shortcut, there is no need to -@@ -2640,35 +2508,35 @@ void qmp_block_commit(const char *job_id, const char *device, - - if (top_bs == NULL) { - error_setg(errp, "Top image file %s not found", top ? top : "NULL"); -- goto out; -+ return; - } - - assert(bdrv_get_aio_context(top_bs) == aio_context); - - if (base_node && base) { - error_setg(errp, "'base-node' and 'base' are mutually exclusive"); -- goto out; -+ return; - } else if (base_node) { - base_bs = bdrv_lookup_bs(NULL, base_node, errp); - if (base_bs == NULL) { -- goto out; -+ return; - } - if (!bdrv_chain_contains(top_bs, base_bs)) { - error_setg(errp, "'%s' is not in this backing file chain", - base_node); -- goto out; -+ return; - } - } else if (base) { - base_bs = bdrv_find_backing_image(top_bs, base); - if (base_bs == NULL) { - error_setg(errp, "Can't find '%s' in the backing chain", base); -- goto out; -+ return; - } - } else { - base_bs = bdrv_find_base(top_bs); - if (base_bs == NULL) { - error_setg(errp, "There is no backimg image"); -- goto out; -+ return; - } - } - -@@ -2678,14 +2546,14 @@ void qmp_block_commit(const char *job_id, const char *device, - iter = bdrv_filter_or_cow_bs(iter)) - { - if (bdrv_op_is_blocked(iter, BLOCK_OP_TYPE_COMMIT_TARGET, errp)) { -- goto out; -+ return; - } - } - - /* Do not allow attempts to commit an image into itself */ - if (top_bs == base_bs) { - error_setg(errp, "cannot commit an image into itself"); -- goto out; -+ return; - } - - /* -@@ -2708,7 +2576,7 @@ void qmp_block_commit(const char *job_id, const char *device, - error_setg(errp, "'backing-file' specified, but 'top' has a " - "writer on it"); - } -- goto out; -+ return; - } - if (!job_id) { - /* -@@ -2724,7 +2592,7 @@ void qmp_block_commit(const char *job_id, const char *device, - } else { - BlockDriverState *overlay_bs = bdrv_find_overlay(bs, top_bs); - if (bdrv_op_is_blocked(overlay_bs, BLOCK_OP_TYPE_COMMIT_TARGET, errp)) { -- goto out; -+ return; - } - commit_start(job_id, bs, base_bs, top_bs, job_flags, - speed, on_error, backing_file, -@@ -2732,11 +2600,8 @@ void qmp_block_commit(const char *job_id, const char *device, - } - if (local_err != NULL) { - error_propagate(errp, local_err); -- goto out; -+ return; - } -- --out: -- aio_context_release(aio_context); - } - - /* Common QMP interface for drive-backup and blockdev-backup */ -@@ -2985,8 +2850,6 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, - - if (replaces) { - BlockDriverState *to_replace_bs; -- AioContext *aio_context; -- AioContext *replace_aio_context; - int64_t bs_size, replace_size; - - bs_size = bdrv_getlength(bs); -@@ -3000,19 +2863,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, - return; - } - -- aio_context = bdrv_get_aio_context(bs); -- replace_aio_context = bdrv_get_aio_context(to_replace_bs); -- /* -- * bdrv_getlength() is a co-wrapper and uses AIO_WAIT_WHILE. Be sure not -- * to acquire the same AioContext twice. -- */ -- if (replace_aio_context != aio_context) { -- aio_context_acquire(replace_aio_context); -- } - replace_size = bdrv_getlength(to_replace_bs); -- if (replace_aio_context != aio_context) { -- aio_context_release(replace_aio_context); -- } - - if (replace_size < 0) { - error_setg_errno(errp, -replace_size, -@@ -3041,7 +2892,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) - BlockDriverState *bs; - BlockDriverState *target_backing_bs, *target_bs; - AioContext *aio_context; -- AioContext *old_context; - BlockMirrorBackingMode backing_mode; - Error *local_err = NULL; - QDict *options = NULL; -@@ -3064,7 +2914,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) - } - - aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - - if (!arg->has_mode) { - arg->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS; -@@ -3088,14 +2937,14 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) - size = bdrv_getlength(bs); - if (size < 0) { - error_setg_errno(errp, -size, "bdrv_getlength failed"); -- goto out; -+ return; - } - - if (arg->replaces) { - if (!arg->node_name) { - error_setg(errp, "a node-name must be provided when replacing a" - " named node of the graph"); -- goto out; -+ return; - } - } - -@@ -3143,7 +2992,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) - - if (local_err) { - error_propagate(errp, local_err); -- goto out; -+ return; - } - - options = qdict_new(); -@@ -3153,15 +3002,11 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) - if (format) { - qdict_put_str(options, "driver", format); - } -- aio_context_release(aio_context); - - /* Mirroring takes care of copy-on-write using the source's backing - * file. - */ -- aio_context_acquire(qemu_get_aio_context()); - target_bs = bdrv_open(arg->target, NULL, options, flags, errp); -- aio_context_release(qemu_get_aio_context()); -- - if (!target_bs) { - return; - } -@@ -3173,20 +3018,12 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) - bdrv_graph_rdunlock_main_loop(); - - -- /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ -- old_context = bdrv_get_aio_context(target_bs); -- aio_context_acquire(old_context); -- - ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); - if (ret < 0) { - bdrv_unref(target_bs); -- aio_context_release(old_context); - return; - } - -- aio_context_release(old_context); -- aio_context_acquire(aio_context); -- - blockdev_mirror_common(arg->job_id, bs, target_bs, - arg->replaces, arg->sync, - backing_mode, zero_target, -@@ -3202,8 +3039,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) - arg->has_auto_dismiss, arg->auto_dismiss, - errp); - bdrv_unref(target_bs); --out: -- aio_context_release(aio_context); - } - - void qmp_blockdev_mirror(const char *job_id, -@@ -3226,7 +3061,6 @@ void qmp_blockdev_mirror(const char *job_id, - BlockDriverState *bs; - BlockDriverState *target_bs; - AioContext *aio_context; -- AioContext *old_context; - BlockMirrorBackingMode backing_mode = MIRROR_LEAVE_BACKING_CHAIN; - bool zero_target; - int ret; -@@ -3243,18 +3077,11 @@ void qmp_blockdev_mirror(const char *job_id, - - zero_target = (sync == MIRROR_SYNC_MODE_FULL); - -- /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ -- old_context = bdrv_get_aio_context(target_bs); - aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(old_context); - - ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); -- -- aio_context_release(old_context); -- aio_context_acquire(aio_context); -- - if (ret < 0) { -- goto out; -+ return; - } - - blockdev_mirror_common(job_id, bs, target_bs, -@@ -3269,8 +3096,6 @@ void qmp_blockdev_mirror(const char *job_id, - has_auto_finalize, auto_finalize, - has_auto_dismiss, auto_dismiss, - errp); --out: -- aio_context_release(aio_context); - } - - /* -@@ -3433,7 +3258,6 @@ void qmp_change_backing_file(const char *device, - Error **errp) - { - BlockDriverState *bs = NULL; -- AioContext *aio_context; - BlockDriverState *image_bs = NULL; - Error *local_err = NULL; - bool ro; -@@ -3444,9 +3268,6 @@ void qmp_change_backing_file(const char *device, - return; - } - -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- - bdrv_graph_rdlock_main_loop(); - - image_bs = bdrv_lookup_bs(NULL, image_node_name, &local_err); -@@ -3485,7 +3306,7 @@ void qmp_change_backing_file(const char *device, - - if (ro) { - if (bdrv_reopen_set_read_only(image_bs, false, errp) != 0) { -- goto out; -+ return; - } - } - -@@ -3503,14 +3324,10 @@ void qmp_change_backing_file(const char *device, - if (ro) { - bdrv_reopen_set_read_only(image_bs, true, errp); - } -- --out: -- aio_context_release(aio_context); - return; - - out_rdlock: - bdrv_graph_rdunlock_main_loop(); -- aio_context_release(aio_context); - } - - void qmp_blockdev_add(BlockdevOptions *options, Error **errp) -@@ -3550,7 +3367,6 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) - for (; reopen_list != NULL; reopen_list = reopen_list->next) { - BlockdevOptions *options = reopen_list->value; - BlockDriverState *bs; -- AioContext *ctx; - QObject *obj; - Visitor *v; - QDict *qdict; -@@ -3578,12 +3394,7 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) - - qdict_flatten(qdict); - -- ctx = bdrv_get_aio_context(bs); -- aio_context_acquire(ctx); -- - queue = bdrv_reopen_queue(queue, bs, qdict, false); -- -- aio_context_release(ctx); - } - - /* Perform the reopen operation */ -@@ -3596,7 +3407,6 @@ fail: - - void qmp_blockdev_del(const char *node_name, Error **errp) - { -- AioContext *aio_context; - BlockDriverState *bs; - - GLOBAL_STATE_CODE(); -@@ -3611,30 +3421,25 @@ void qmp_blockdev_del(const char *node_name, Error **errp) - error_setg(errp, "Node %s is in use", node_name); - return; - } -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, errp)) { -- goto out; -+ return; - } - - if (!QTAILQ_IN_USE(bs, monitor_list)) { - error_setg(errp, "Node %s is not owned by the monitor", - bs->node_name); -- goto out; -+ return; - } - - if (bs->refcnt > 1) { - error_setg(errp, "Block device %s is in use", - bdrv_get_device_or_node_name(bs)); -- goto out; -+ return; - } - - QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list); - bdrv_unref(bs); -- --out: -- aio_context_release(aio_context); - } - - static BdrvChild * GRAPH_RDLOCK -@@ -3724,7 +3529,6 @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp) - void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread, - bool has_force, bool force, Error **errp) - { -- AioContext *old_context; - AioContext *new_context; - BlockDriverState *bs; - -@@ -3756,12 +3560,7 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread, - new_context = qemu_get_aio_context(); - } - -- old_context = bdrv_get_aio_context(bs); -- aio_context_acquire(old_context); -- - bdrv_try_change_aio_context(bs, new_context, NULL, errp); -- -- aio_context_release(old_context); - } - - QemuOptsList qemu_common_drive_opts = { -diff --git a/blockjob.c b/blockjob.c -index 7310412313..d5f29e14af 100644 ---- a/blockjob.c -+++ b/blockjob.c -@@ -198,9 +198,7 @@ void block_job_remove_all_bdrv(BlockJob *job) - * one to make sure that such a concurrent access does not attempt - * to process an already freed BdrvChild. - */ -- aio_context_release(job->job.aio_context); - bdrv_graph_wrlock(); -- aio_context_acquire(job->job.aio_context); - while (job->nodes) { - GSList *l = job->nodes; - BdrvChild *c = l->data; -@@ -234,28 +232,12 @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs, - uint64_t perm, uint64_t shared_perm, Error **errp) - { - BdrvChild *c; -- AioContext *ctx = bdrv_get_aio_context(bs); -- bool need_context_ops; - GLOBAL_STATE_CODE(); - - bdrv_ref(bs); - -- need_context_ops = ctx != job->job.aio_context; -- -- if (need_context_ops) { -- if (job->job.aio_context != qemu_get_aio_context()) { -- aio_context_release(job->job.aio_context); -- } -- aio_context_acquire(ctx); -- } - c = bdrv_root_attach_child(bs, name, &child_job, 0, perm, shared_perm, job, - errp); -- if (need_context_ops) { -- aio_context_release(ctx); -- if (job->job.aio_context != qemu_get_aio_context()) { -- aio_context_acquire(job->job.aio_context); -- } -- } - if (c == NULL) { - return -EPERM; - } -diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c -index f83bb0f116..7bbbd981ad 100644 ---- a/hw/block/dataplane/virtio-blk.c -+++ b/hw/block/dataplane/virtio-blk.c -@@ -124,7 +124,6 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev) - VirtIOBlockDataPlane *s = vblk->dataplane; - BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vblk))); - VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -- AioContext *old_context; - unsigned i; - unsigned nvqs = s->conf->num_queues; - Error *local_err = NULL; -@@ -178,10 +177,7 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev) - - trace_virtio_blk_data_plane_start(s); - -- old_context = blk_get_aio_context(s->conf->conf.blk); -- aio_context_acquire(old_context); - r = blk_set_aio_context(s->conf->conf.blk, s->ctx, &local_err); -- aio_context_release(old_context); - if (r < 0) { - error_report_err(local_err); - goto fail_aio_context; -@@ -208,13 +204,11 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev) - - /* Get this show started by hooking up our callbacks */ - if (!blk_in_drain(s->conf->conf.blk)) { -- aio_context_acquire(s->ctx); - for (i = 0; i < nvqs; i++) { - VirtQueue *vq = virtio_get_queue(s->vdev, i); - - virtio_queue_aio_attach_host_notifier(vq, s->ctx); - } -- aio_context_release(s->ctx); - } - return 0; - -@@ -314,8 +308,6 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev) - */ - vblk->dataplane_started = false; - -- aio_context_acquire(s->ctx); -- - /* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */ - blk_drain(s->conf->conf.blk); - -@@ -325,8 +317,6 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev) - */ - blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context(), NULL); - -- aio_context_release(s->ctx); -- - /* Clean up guest notifier (irq) */ - k->set_guest_notifiers(qbus->parent, nvqs, false); - -diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c -index c4bb28c66f..98501e6885 100644 ---- a/hw/block/dataplane/xen-block.c -+++ b/hw/block/dataplane/xen-block.c -@@ -260,8 +260,6 @@ static void xen_block_complete_aio(void *opaque, int ret) - XenBlockRequest *request = opaque; - XenBlockDataPlane *dataplane = request->dataplane; - -- aio_context_acquire(dataplane->ctx); -- - if (ret != 0) { - error_report("%s I/O error", - request->req.operation == BLKIF_OP_READ ? -@@ -273,10 +271,10 @@ static void xen_block_complete_aio(void *opaque, int ret) - if (request->presync) { - request->presync = 0; - xen_block_do_aio(request); -- goto done; -+ return; - } - if (request->aio_inflight > 0) { -- goto done; -+ return; - } - - switch (request->req.operation) { -@@ -318,9 +316,6 @@ static void xen_block_complete_aio(void *opaque, int ret) - if (dataplane->more_work) { - qemu_bh_schedule(dataplane->bh); - } -- --done: -- aio_context_release(dataplane->ctx); - } - - static bool xen_block_split_discard(XenBlockRequest *request, -@@ -601,9 +596,7 @@ static void xen_block_dataplane_bh(void *opaque) - { - XenBlockDataPlane *dataplane = opaque; - -- aio_context_acquire(dataplane->ctx); - xen_block_handle_requests(dataplane); -- aio_context_release(dataplane->ctx); - } - - static bool xen_block_dataplane_event(void *opaque) -@@ -703,10 +696,8 @@ void xen_block_dataplane_stop(XenBlockDataPlane *dataplane) - xen_block_dataplane_detach(dataplane); - } - -- aio_context_acquire(dataplane->ctx); - /* Xen doesn't have multiple users for nodes, so this can't fail */ - blk_set_aio_context(dataplane->blk, qemu_get_aio_context(), &error_abort); -- aio_context_release(dataplane->ctx); - - /* - * Now that the context has been moved onto the main thread, cancel -@@ -752,7 +743,6 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane, - { - ERRP_GUARD(); - XenDevice *xendev = dataplane->xendev; -- AioContext *old_context; - unsigned int ring_size; - unsigned int i; - -@@ -836,11 +826,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane, - goto stop; - } - -- old_context = blk_get_aio_context(dataplane->blk); -- aio_context_acquire(old_context); - /* If other users keep the BlockBackend in the iothread, that's ok */ - blk_set_aio_context(dataplane->blk, dataplane->ctx, NULL); -- aio_context_release(old_context); - - if (!blk_in_drain(dataplane->blk)) { - xen_block_dataplane_attach(dataplane); -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index e110f9718b..ec9ed09a6a 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -1210,17 +1210,13 @@ static void virtio_blk_dma_restart_cb(void *opaque, bool running, - static void virtio_blk_reset(VirtIODevice *vdev) - { - VirtIOBlock *s = VIRTIO_BLK(vdev); -- AioContext *ctx; - VirtIOBlockReq *req; - - /* Dataplane has stopped... */ - assert(!s->dataplane_started); - - /* ...but requests may still be in flight. */ -- ctx = blk_get_aio_context(s->blk); -- aio_context_acquire(ctx); - blk_drain(s->blk); -- aio_context_release(ctx); - - /* We drop queued requests after blk_drain() because blk_drain() itself can - * produce them. */ -@@ -1250,10 +1246,6 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) - uint64_t capacity; - int64_t length; - int blk_size = conf->logical_block_size; -- AioContext *ctx; -- -- ctx = blk_get_aio_context(s->blk); -- aio_context_acquire(ctx); - - blk_get_geometry(s->blk, &capacity); - memset(&blkcfg, 0, sizeof(blkcfg)); -@@ -1277,7 +1269,6 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) - * per track (cylinder). - */ - length = blk_getlength(s->blk); -- aio_context_release(ctx); - if (length > 0 && length / conf->heads / conf->secs % blk_size) { - blkcfg.geometry.sectors = conf->secs & ~s->sector_mask; - } else { -@@ -1344,9 +1335,7 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config) - - memcpy(&blkcfg, config, s->config_size); - -- aio_context_acquire(blk_get_aio_context(s->blk)); - blk_set_enable_write_cache(s->blk, blkcfg.wce != 0); -- aio_context_release(blk_get_aio_context(s->blk)); - } - - static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features, -@@ -1414,11 +1403,9 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) - * s->blk would erroneously be placed in writethrough mode. - */ - if (!virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) { -- aio_context_acquire(blk_get_aio_context(s->blk)); - blk_set_enable_write_cache(s->blk, - virtio_vdev_has_feature(vdev, - VIRTIO_BLK_F_WCE)); -- aio_context_release(blk_get_aio_context(s->blk)); - } - } - -diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c -index 1473ab3d5e..73cced4626 100644 ---- a/hw/core/qdev-properties-system.c -+++ b/hw/core/qdev-properties-system.c -@@ -120,9 +120,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name, - "node"); - } - -- aio_context_acquire(ctx); - blk_replace_bs(blk, bs, errp); -- aio_context_release(ctx); - return; - } - -@@ -148,10 +146,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name, - 0, BLK_PERM_ALL); - blk_created = true; - -- aio_context_acquire(ctx); - ret = blk_insert_bs(blk, bs, errp); -- aio_context_release(ctx); -- - if (ret < 0) { - goto fail; - } -@@ -207,12 +202,8 @@ static void release_drive(Object *obj, const char *name, void *opaque) - BlockBackend **ptr = object_field_prop_ptr(obj, prop); - - if (*ptr) { -- AioContext *ctx = blk_get_aio_context(*ptr); -- -- aio_context_acquire(ctx); - blockdev_auto_del(*ptr); - blk_detach_dev(*ptr, dev); -- aio_context_release(ctx); - } - } - -diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h -index 6b21fbc73f..0327f1c605 100644 ---- a/include/block/block-global-state.h -+++ b/include/block/block-global-state.h -@@ -31,11 +31,10 @@ - /* - * Global state (GS) API. These functions run under the BQL. - * -- * If a function modifies the graph, it also uses drain and/or -- * aio_context_acquire/release to be sure it has unique access. -- * aio_context locking is needed together with BQL because of -- * the thread-safe I/O API that concurrently runs and accesses -- * the graph without the BQL. -+ * If a function modifies the graph, it also uses the graph lock to be sure it -+ * has unique access. The graph lock is needed together with BQL because of the -+ * thread-safe I/O API that concurrently runs and accesses the graph without -+ * the BQL. - * - * It is important to note that not all of these functions are - * necessarily limited to running under the BQL, but they would -diff --git a/include/block/block-io.h b/include/block/block-io.h -index f8729ccc55..8eb39a858b 100644 ---- a/include/block/block-io.h -+++ b/include/block/block-io.h -@@ -31,8 +31,7 @@ - - /* - * I/O API functions. These functions are thread-safe, and therefore -- * can run in any thread as long as the thread has called -- * aio_context_acquire/release(). -+ * can run in any thread. - * - * These functions can only call functions from I/O and Common categories, - * but can be invoked by GS, "I/O or GS" and I/O APIs. -diff --git a/include/block/snapshot.h b/include/block/snapshot.h -index d49c5599d9..304cc6ea61 100644 ---- a/include/block/snapshot.h -+++ b/include/block/snapshot.h -@@ -86,8 +86,6 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs, - - /* - * Group operations. All block drivers are involved. -- * These functions will properly handle dataplane (take aio_context_acquire -- * when appropriate for appropriate block drivers - */ - - bool bdrv_all_can_snapshot(bool has_devices, strList *devices, -diff --git a/job.c b/job.c -index 99a2e54b54..660ce22c56 100644 ---- a/job.c -+++ b/job.c -@@ -464,12 +464,8 @@ void job_unref_locked(Job *job) - assert(!job->txn); - - if (job->driver->free) { -- AioContext *aio_context = job->aio_context; - job_unlock(); -- /* FIXME: aiocontext lock is required because cb calls blk_unref */ -- aio_context_acquire(aio_context); - job->driver->free(job); -- aio_context_release(aio_context); - job_lock(); - } - -@@ -840,12 +836,10 @@ static void job_clean(Job *job) - - /* - * Called with job_mutex held, but releases it temporarily. -- * Takes AioContext lock internally to invoke a job->driver callback. - */ - static int job_finalize_single_locked(Job *job) - { - int job_ret; -- AioContext *ctx = job->aio_context; - - assert(job_is_completed_locked(job)); - -@@ -854,7 +848,6 @@ static int job_finalize_single_locked(Job *job) - - job_ret = job->ret; - job_unlock(); -- aio_context_acquire(ctx); - - if (!job_ret) { - job_commit(job); -@@ -867,7 +860,6 @@ static int job_finalize_single_locked(Job *job) - job->cb(job->opaque, job_ret); - } - -- aio_context_release(ctx); - job_lock(); - - /* Emit events only if we actually started */ -@@ -886,17 +878,13 @@ static int job_finalize_single_locked(Job *job) - - /* - * Called with job_mutex held, but releases it temporarily. -- * Takes AioContext lock internally to invoke a job->driver callback. - */ - static void job_cancel_async_locked(Job *job, bool force) - { -- AioContext *ctx = job->aio_context; - GLOBAL_STATE_CODE(); - if (job->driver->cancel) { - job_unlock(); -- aio_context_acquire(ctx); - force = job->driver->cancel(job, force); -- aio_context_release(ctx); - job_lock(); - } else { - /* No .cancel() means the job will behave as if force-cancelled */ -@@ -931,7 +919,6 @@ static void job_cancel_async_locked(Job *job, bool force) - - /* - * Called with job_mutex held, but releases it temporarily. -- * Takes AioContext lock internally to invoke a job->driver callback. - */ - static void job_completed_txn_abort_locked(Job *job) - { -@@ -979,15 +966,12 @@ static void job_completed_txn_abort_locked(Job *job) - static int job_prepare_locked(Job *job) - { - int ret; -- AioContext *ctx = job->aio_context; - - GLOBAL_STATE_CODE(); - - if (job->ret == 0 && job->driver->prepare) { - job_unlock(); -- aio_context_acquire(ctx); - ret = job->driver->prepare(job); -- aio_context_release(ctx); - job_lock(); - job->ret = ret; - job_update_rc_locked(job); -diff --git a/migration/block.c b/migration/block.c -index a15f9bddcb..6ec6a1d6e6 100644 ---- a/migration/block.c -+++ b/migration/block.c -@@ -66,7 +66,7 @@ typedef struct BlkMigDevState { - /* Protected by block migration lock. */ - int64_t completed_sectors; - -- /* During migration this is protected by iothread lock / AioContext. -+ /* During migration this is protected by bdrv_dirty_bitmap_lock(). - * Allocation and free happen during setup and cleanup respectively. - */ - BdrvDirtyBitmap *dirty_bitmap; -@@ -101,7 +101,7 @@ typedef struct BlkMigState { - int prev_progress; - int bulk_completed; - -- /* Lock must be taken _inside_ the iothread lock and any AioContexts. */ -+ /* Lock must be taken _inside_ the iothread lock. */ - QemuMutex lock; - } BlkMigState; - -@@ -270,7 +270,6 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) - - if (bmds->shared_base) { - qemu_mutex_lock_iothread(); -- aio_context_acquire(blk_get_aio_context(bb)); - /* Skip unallocated sectors; intentionally treats failure or - * partial sector as an allocated sector */ - while (cur_sector < total_sectors && -@@ -281,7 +280,6 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) - } - cur_sector += count >> BDRV_SECTOR_BITS; - } -- aio_context_release(blk_get_aio_context(bb)); - qemu_mutex_unlock_iothread(); - } - -@@ -313,21 +311,16 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) - block_mig_state.submitted++; - blk_mig_unlock(); - -- /* We do not know if bs is under the main thread (and thus does -- * not acquire the AioContext when doing AIO) or rather under -- * dataplane. Thus acquire both the iothread mutex and the -- * AioContext. -- * -- * This is ugly and will disappear when we make bdrv_* thread-safe, -- * without the need to acquire the AioContext. -+ /* -+ * The migration thread does not have an AioContext. Lock the BQL so that -+ * I/O runs in the main loop AioContext (see -+ * qemu_get_current_aio_context()). - */ - qemu_mutex_lock_iothread(); -- aio_context_acquire(blk_get_aio_context(bmds->blk)); - bdrv_reset_dirty_bitmap(bmds->dirty_bitmap, cur_sector * BDRV_SECTOR_SIZE, - nr_sectors * BDRV_SECTOR_SIZE); - blk->aiocb = blk_aio_preadv(bb, cur_sector * BDRV_SECTOR_SIZE, &blk->qiov, - 0, blk_mig_read_cb, blk); -- aio_context_release(blk_get_aio_context(bmds->blk)); - qemu_mutex_unlock_iothread(); - - bmds->cur_sector = cur_sector + nr_sectors; -@@ -512,7 +505,7 @@ static void blk_mig_reset_dirty_cursor(void) - } - } - --/* Called with iothread lock and AioContext taken. */ -+/* Called with iothread lock taken. */ - - static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds, - int is_async) -@@ -606,9 +599,7 @@ static int blk_mig_save_dirty_block(QEMUFile *f, int is_async) - int ret = 1; - - QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { -- aio_context_acquire(blk_get_aio_context(bmds->blk)); - ret = mig_save_device_dirty(f, bmds, is_async); -- aio_context_release(blk_get_aio_context(bmds->blk)); - if (ret <= 0) { - break; - } -@@ -666,9 +657,9 @@ static int64_t get_remaining_dirty(void) - int64_t dirty = 0; - - QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { -- aio_context_acquire(blk_get_aio_context(bmds->blk)); -+ bdrv_dirty_bitmap_lock(bmds->dirty_bitmap); - dirty += bdrv_get_dirty_count(bmds->dirty_bitmap); -- aio_context_release(blk_get_aio_context(bmds->blk)); -+ bdrv_dirty_bitmap_unlock(bmds->dirty_bitmap); - } - - return dirty; -@@ -681,7 +672,6 @@ static void block_migration_cleanup_bmds(void) - { - BlkMigDevState *bmds; - BlockDriverState *bs; -- AioContext *ctx; - - unset_dirty_tracking(); - -@@ -693,13 +683,7 @@ static void block_migration_cleanup_bmds(void) - bdrv_op_unblock_all(bs, bmds->blocker); - } - error_free(bmds->blocker); -- -- /* Save ctx, because bmds->blk can disappear during blk_unref. */ -- ctx = blk_get_aio_context(bmds->blk); -- aio_context_acquire(ctx); - blk_unref(bmds->blk); -- aio_context_release(ctx); -- - g_free(bmds->blk_name); - g_free(bmds->aio_bitmap); - g_free(bmds); -diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c -index 86ae832176..99710c8ffb 100644 ---- a/migration/migration-hmp-cmds.c -+++ b/migration/migration-hmp-cmds.c -@@ -852,14 +852,11 @@ static void vm_completion(ReadLineState *rs, const char *str) - - for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { - SnapshotInfoList *snapshots, *snapshot; -- AioContext *ctx = bdrv_get_aio_context(bs); - bool ok = false; - -- aio_context_acquire(ctx); - if (bdrv_can_snapshot(bs)) { - ok = bdrv_query_snapshot_info_list(bs, &snapshots, NULL) == 0; - } -- aio_context_release(ctx); - if (!ok) { - continue; - } -diff --git a/migration/savevm.c b/migration/savevm.c -index eec5503a42..1b9ab7b8ee 100644 ---- a/migration/savevm.c -+++ b/migration/savevm.c -@@ -3049,7 +3049,6 @@ bool save_snapshot(const char *name, bool overwrite, const char *vmstate, - int saved_vm_running; - uint64_t vm_state_size; - g_autoptr(GDateTime) now = g_date_time_new_now_local(); -- AioContext *aio_context; - - GLOBAL_STATE_CODE(); - -@@ -3092,7 +3091,6 @@ bool save_snapshot(const char *name, bool overwrite, const char *vmstate, - if (bs == NULL) { - return false; - } -- aio_context = bdrv_get_aio_context(bs); - - saved_vm_running = runstate_is_running(); - -@@ -3101,8 +3099,6 @@ bool save_snapshot(const char *name, bool overwrite, const char *vmstate, - - bdrv_drain_all_begin(); - -- aio_context_acquire(aio_context); -- - memset(sn, 0, sizeof(*sn)); - - /* fill auxiliary fields */ -@@ -3139,14 +3135,6 @@ bool save_snapshot(const char *name, bool overwrite, const char *vmstate, - goto the_end; - } - -- /* The bdrv_all_create_snapshot() call that follows acquires the AioContext -- * for itself. BDRV_POLL_WHILE() does not support nested locking because -- * it only releases the lock once. Therefore synchronous I/O will deadlock -- * unless we release the AioContext before bdrv_all_create_snapshot(). -- */ -- aio_context_release(aio_context); -- aio_context = NULL; -- - ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, - has_devices, devices, errp); - if (ret < 0) { -@@ -3157,10 +3145,6 @@ bool save_snapshot(const char *name, bool overwrite, const char *vmstate, - ret = 0; - - the_end: -- if (aio_context) { -- aio_context_release(aio_context); -- } -- - bdrv_drain_all_end(); - - if (saved_vm_running) { -@@ -3258,7 +3242,6 @@ bool load_snapshot(const char *name, const char *vmstate, - QEMUSnapshotInfo sn; - QEMUFile *f; - int ret; -- AioContext *aio_context; - MigrationIncomingState *mis = migration_incoming_get_current(); - - if (!bdrv_all_can_snapshot(has_devices, devices, errp)) { -@@ -3278,12 +3261,9 @@ bool load_snapshot(const char *name, const char *vmstate, - if (!bs_vm_state) { - return false; - } -- aio_context = bdrv_get_aio_context(bs_vm_state); - - /* Don't even try to load empty VM states */ -- aio_context_acquire(aio_context); - ret = bdrv_snapshot_find(bs_vm_state, &sn, name); -- aio_context_release(aio_context); - if (ret < 0) { - return false; - } else if (sn.vm_state_size == 0) { -@@ -3320,10 +3300,8 @@ bool load_snapshot(const char *name, const char *vmstate, - ret = -EINVAL; - goto err_drain; - } -- aio_context_acquire(aio_context); - ret = qemu_loadvm_state(f); - migration_incoming_state_destroy(); -- aio_context_release(aio_context); - - bdrv_drain_all_end(); - -diff --git a/net/colo-compare.c b/net/colo-compare.c -index 7f9e6f89ce..f2dfc0ebdc 100644 ---- a/net/colo-compare.c -+++ b/net/colo-compare.c -@@ -1439,12 +1439,10 @@ static void colo_compare_finalize(Object *obj) - qemu_bh_delete(s->event_bh); - - AioContext *ctx = iothread_get_aio_context(s->iothread); -- aio_context_acquire(ctx); - AIO_WAIT_WHILE(ctx, !s->out_sendco.done); - if (s->notify_dev) { - AIO_WAIT_WHILE(ctx, !s->notify_sendco.done); - } -- aio_context_release(ctx); - - /* Release all unhandled packets after compare thead exited */ - g_queue_foreach(&s->conn_list, colo_flush_packets, s); -diff --git a/qemu-img.c b/qemu-img.c -index 5a77f67719..7668f86769 100644 ---- a/qemu-img.c -+++ b/qemu-img.c -@@ -960,7 +960,6 @@ static int img_commit(int argc, char **argv) - Error *local_err = NULL; - CommonBlockJobCBInfo cbi; - bool image_opts = false; -- AioContext *aio_context; - int64_t rate_limit = 0; - - fmt = NULL; -@@ -1078,12 +1077,9 @@ static int img_commit(int argc, char **argv) - .bs = bs, - }; - -- aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); - commit_active_start("commit", bs, base_bs, JOB_DEFAULT, rate_limit, - BLOCKDEV_ON_ERROR_REPORT, NULL, common_block_job_cb, - &cbi, false, &local_err); -- aio_context_release(aio_context); - if (local_err) { - goto done; - } -diff --git a/qemu-io.c b/qemu-io.c -index 050c70835f..6cb1e00385 100644 ---- a/qemu-io.c -+++ b/qemu-io.c -@@ -414,15 +414,7 @@ static void prep_fetchline(void *opaque) - - static int do_qemuio_command(const char *cmd) - { -- int ret; -- AioContext *ctx = -- qemuio_blk ? blk_get_aio_context(qemuio_blk) : qemu_get_aio_context(); -- -- aio_context_acquire(ctx); -- ret = qemuio_command(qemuio_blk, cmd); -- aio_context_release(ctx); -- -- return ret; -+ return qemuio_command(qemuio_blk, cmd); - } - - static int command_loop(void) -diff --git a/qemu-nbd.c b/qemu-nbd.c -index 186e6468b1..bac0b5e3ec 100644 ---- a/qemu-nbd.c -+++ b/qemu-nbd.c -@@ -1123,9 +1123,7 @@ int main(int argc, char **argv) - qdict_put_str(raw_opts, "file", bs->node_name); - qdict_put_int(raw_opts, "offset", dev_offset); - -- aio_context_acquire(qemu_get_aio_context()); - bs = bdrv_open(NULL, NULL, raw_opts, flags, &error_fatal); -- aio_context_release(qemu_get_aio_context()); - - blk_remove_bs(blk); - blk_insert_bs(blk, bs, &error_fatal); -diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c -index 3e60549a4a..82c66fff26 100644 ---- a/replay/replay-debugging.c -+++ b/replay/replay-debugging.c -@@ -144,7 +144,6 @@ static char *replay_find_nearest_snapshot(int64_t icount, - char *ret = NULL; - int rv; - int nb_sns, i; -- AioContext *aio_context; - - *snapshot_icount = -1; - -@@ -152,11 +151,8 @@ static char *replay_find_nearest_snapshot(int64_t icount, - if (!bs) { - goto fail; - } -- aio_context = bdrv_get_aio_context(bs); - -- aio_context_acquire(aio_context); - nb_sns = bdrv_snapshot_list(bs, &sn_tab); -- aio_context_release(aio_context); - - for (i = 0; i < nb_sns; i++) { - rv = bdrv_all_has_snapshot(sn_tab[i].name, false, NULL, NULL); -diff --git a/scripts/block-coroutine-wrapper.py b/scripts/block-coroutine-wrapper.py -index 38364fa557..c9c09fcacd 100644 ---- a/scripts/block-coroutine-wrapper.py -+++ b/scripts/block-coroutine-wrapper.py -@@ -278,12 +278,9 @@ def gen_no_co_wrapper(func: FuncDecl) -> str: - static void {name}_bh(void *opaque) - {{ - {struct_name} *s = opaque; -- AioContext *ctx = {func.gen_ctx('s->')}; - - {graph_lock} -- aio_context_acquire(ctx); - {func.get_result}{name}({ func.gen_list('s->{name}') }); -- aio_context_release(ctx); - {graph_unlock} - - aio_co_wake(s->co); -diff --git a/tests/tsan/suppressions.tsan b/tests/tsan/suppressions.tsan -index d9a002a2ef..b3ef59c27c 100644 ---- a/tests/tsan/suppressions.tsan -+++ b/tests/tsan/suppressions.tsan -@@ -4,7 +4,6 @@ - - # TSan reports a double lock on RECURSIVE mutexes. - # Since the recursive lock is intentional, we choose to ignore it. --mutex:aio_context_acquire - mutex:pthread_mutex_lock - - # TSan reports a race between pthread_mutex_init() and -diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c -index d9754dfebc..17830a69c1 100644 ---- a/tests/unit/test-bdrv-drain.c -+++ b/tests/unit/test-bdrv-drain.c -@@ -179,13 +179,7 @@ static void do_drain_end(enum drain_type drain_type, BlockDriverState *bs) - - static void do_drain_begin_unlocked(enum drain_type drain_type, BlockDriverState *bs) - { -- if (drain_type != BDRV_DRAIN_ALL) { -- aio_context_acquire(bdrv_get_aio_context(bs)); -- } - do_drain_begin(drain_type, bs); -- if (drain_type != BDRV_DRAIN_ALL) { -- aio_context_release(bdrv_get_aio_context(bs)); -- } - } - - static BlockBackend * no_coroutine_fn test_setup(void) -@@ -209,13 +203,7 @@ static BlockBackend * no_coroutine_fn test_setup(void) - - static void do_drain_end_unlocked(enum drain_type drain_type, BlockDriverState *bs) - { -- if (drain_type != BDRV_DRAIN_ALL) { -- aio_context_acquire(bdrv_get_aio_context(bs)); -- } - do_drain_end(drain_type, bs); -- if (drain_type != BDRV_DRAIN_ALL) { -- aio_context_release(bdrv_get_aio_context(bs)); -- } - } - - /* -@@ -520,12 +508,8 @@ static void test_iothread_main_thread_bh(void *opaque) - { - struct test_iothread_data *data = opaque; - -- /* Test that the AioContext is not yet locked in a random BH that is -- * executed during drain, otherwise this would deadlock. */ -- aio_context_acquire(bdrv_get_aio_context(data->bs)); - bdrv_flush(data->bs); - bdrv_dec_in_flight(data->bs); /* incremented by test_iothread_common() */ -- aio_context_release(bdrv_get_aio_context(data->bs)); - } - - /* -@@ -567,7 +551,6 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) - blk_set_disable_request_queuing(blk, true); - - blk_set_aio_context(blk, ctx_a, &error_abort); -- aio_context_acquire(ctx_a); - - s->bh_indirection_ctx = ctx_b; - -@@ -582,8 +565,6 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) - g_assert(acb != NULL); - g_assert_cmpint(aio_ret, ==, -EINPROGRESS); - -- aio_context_release(ctx_a); -- - data = (struct test_iothread_data) { - .bs = bs, - .drain_type = drain_type, -@@ -592,10 +573,6 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) - - switch (drain_thread) { - case 0: -- if (drain_type != BDRV_DRAIN_ALL) { -- aio_context_acquire(ctx_a); -- } -- - /* - * Increment in_flight so that do_drain_begin() waits for - * test_iothread_main_thread_bh(). This prevents the race between -@@ -613,20 +590,10 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) - do_drain_begin(drain_type, bs); - g_assert_cmpint(bs->in_flight, ==, 0); - -- if (drain_type != BDRV_DRAIN_ALL) { -- aio_context_release(ctx_a); -- } - qemu_event_wait(&done_event); -- if (drain_type != BDRV_DRAIN_ALL) { -- aio_context_acquire(ctx_a); -- } - - g_assert_cmpint(aio_ret, ==, 0); - do_drain_end(drain_type, bs); -- -- if (drain_type != BDRV_DRAIN_ALL) { -- aio_context_release(ctx_a); -- } - break; - case 1: - co = qemu_coroutine_create(test_iothread_drain_co_entry, &data); -@@ -637,9 +604,7 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) - g_assert_not_reached(); - } - -- aio_context_acquire(ctx_a); - blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort); -- aio_context_release(ctx_a); - - bdrv_unref(bs); - blk_unref(blk); -@@ -757,7 +722,6 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, - BlockJob *job; - TestBlockJob *tjob; - IOThread *iothread = NULL; -- AioContext *ctx; - int ret; - - src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR, -@@ -787,11 +751,11 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, - } - - if (use_iothread) { -+ AioContext *ctx; -+ - iothread = iothread_new(); - ctx = iothread_get_aio_context(iothread); - blk_set_aio_context(blk_src, ctx, &error_abort); -- } else { -- ctx = qemu_get_aio_context(); - } - - target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR, -@@ -800,7 +764,6 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, - blk_insert_bs(blk_target, target, &error_abort); - blk_set_allow_aio_context_change(blk_target, true); - -- aio_context_acquire(ctx); - tjob = block_job_create("job0", &test_job_driver, NULL, src, - 0, BLK_PERM_ALL, - 0, 0, NULL, NULL, &error_abort); -@@ -821,7 +784,6 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, - tjob->prepare_ret = -EIO; - break; - } -- aio_context_release(ctx); - - job_start(&job->job); - -@@ -912,12 +874,10 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, - } - g_assert_cmpint(ret, ==, (result == TEST_JOB_SUCCESS ? 0 : -EIO)); - -- aio_context_acquire(ctx); - if (use_iothread) { - blk_set_aio_context(blk_src, qemu_get_aio_context(), &error_abort); - assert(blk_get_aio_context(blk_target) == qemu_get_aio_context()); - } -- aio_context_release(ctx); - - blk_unref(blk_src); - blk_unref(blk_target); -@@ -1401,9 +1361,7 @@ static void test_append_to_drained(void) - g_assert_cmpint(base_s->drain_count, ==, 1); - g_assert_cmpint(base->in_flight, ==, 0); - -- aio_context_acquire(qemu_get_aio_context()); - bdrv_append(overlay, base, &error_abort); -- aio_context_release(qemu_get_aio_context()); - - g_assert_cmpint(base->in_flight, ==, 0); - g_assert_cmpint(overlay->in_flight, ==, 0); -@@ -1438,16 +1396,11 @@ static void test_set_aio_context(void) - - bdrv_drained_begin(bs); - bdrv_try_change_aio_context(bs, ctx_a, NULL, &error_abort); -- -- aio_context_acquire(ctx_a); - bdrv_drained_end(bs); - - bdrv_drained_begin(bs); - bdrv_try_change_aio_context(bs, ctx_b, NULL, &error_abort); -- aio_context_release(ctx_a); -- aio_context_acquire(ctx_b); - bdrv_try_change_aio_context(bs, qemu_get_aio_context(), NULL, &error_abort); -- aio_context_release(ctx_b); - bdrv_drained_end(bs); - - bdrv_unref(bs); -diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c -index 8ee6ef38d8..cafc023db4 100644 ---- a/tests/unit/test-bdrv-graph-mod.c -+++ b/tests/unit/test-bdrv-graph-mod.c -@@ -142,10 +142,8 @@ static void test_update_perm_tree(void) - BDRV_CHILD_DATA, &error_abort); - bdrv_graph_wrunlock(); - -- aio_context_acquire(qemu_get_aio_context()); - ret = bdrv_append(filter, bs, NULL); - g_assert_cmpint(ret, <, 0); -- aio_context_release(qemu_get_aio_context()); - - bdrv_unref(filter); - blk_unref(root); -@@ -211,9 +209,7 @@ static void test_should_update_child(void) - bdrv_attach_child(filter, target, "target", &child_of_bds, - BDRV_CHILD_DATA, &error_abort); - bdrv_graph_wrunlock(); -- aio_context_acquire(qemu_get_aio_context()); - bdrv_append(filter, bs, &error_abort); -- aio_context_release(qemu_get_aio_context()); - - bdrv_graph_rdlock_main_loop(); - g_assert(target->backing->bs == bs); -@@ -440,9 +436,7 @@ static void test_append_greedy_filter(void) - &error_abort); - bdrv_graph_wrunlock(); - -- aio_context_acquire(qemu_get_aio_context()); - bdrv_append(fl, base, &error_abort); -- aio_context_release(qemu_get_aio_context()); - bdrv_unref(fl); - bdrv_unref(top); - } -diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c -index 9b15d2768c..3766d5de6b 100644 ---- a/tests/unit/test-block-iothread.c -+++ b/tests/unit/test-block-iothread.c -@@ -483,7 +483,6 @@ static void test_sync_op(const void *opaque) - bdrv_graph_rdunlock_main_loop(); - - blk_set_aio_context(blk, ctx, &error_abort); -- aio_context_acquire(ctx); - if (t->fn) { - t->fn(c); - } -@@ -491,7 +490,6 @@ static void test_sync_op(const void *opaque) - t->blkfn(blk); - } - blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort); -- aio_context_release(ctx); - - bdrv_unref(bs); - blk_unref(blk); -@@ -576,9 +574,7 @@ static void test_attach_blockjob(void) - aio_poll(qemu_get_aio_context(), false); - } - -- aio_context_acquire(ctx); - blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort); -- aio_context_release(ctx); - - tjob->n = 0; - while (tjob->n == 0) { -@@ -595,9 +591,7 @@ static void test_attach_blockjob(void) - WITH_JOB_LOCK_GUARD() { - job_complete_sync_locked(&tjob->common.job, &error_abort); - } -- aio_context_acquire(ctx); - blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort); -- aio_context_release(ctx); - - bdrv_unref(bs); - blk_unref(blk); -@@ -654,9 +648,7 @@ static void test_propagate_basic(void) - - /* Switch the AioContext back */ - main_ctx = qemu_get_aio_context(); -- aio_context_acquire(ctx); - blk_set_aio_context(blk, main_ctx, &error_abort); -- aio_context_release(ctx); - g_assert(blk_get_aio_context(blk) == main_ctx); - g_assert(bdrv_get_aio_context(bs_a) == main_ctx); - g_assert(bdrv_get_aio_context(bs_verify) == main_ctx); -@@ -732,9 +724,7 @@ static void test_propagate_diamond(void) - - /* Switch the AioContext back */ - main_ctx = qemu_get_aio_context(); -- aio_context_acquire(ctx); - blk_set_aio_context(blk, main_ctx, &error_abort); -- aio_context_release(ctx); - g_assert(blk_get_aio_context(blk) == main_ctx); - g_assert(bdrv_get_aio_context(bs_verify) == main_ctx); - g_assert(bdrv_get_aio_context(bs_a) == main_ctx); -@@ -764,13 +754,11 @@ static void test_propagate_mirror(void) - &error_abort); - - /* Start a mirror job */ -- aio_context_acquire(main_ctx); - mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0, - MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false, - BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT, - false, "filter_node", MIRROR_COPY_MODE_BACKGROUND, - &error_abort); -- aio_context_release(main_ctx); - - WITH_JOB_LOCK_GUARD() { - job = job_get_locked("job0"); -@@ -785,9 +773,7 @@ static void test_propagate_mirror(void) - g_assert(job->aio_context == ctx); - - /* Change the AioContext of target */ -- aio_context_acquire(ctx); - bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort); -- aio_context_release(ctx); - g_assert(bdrv_get_aio_context(src) == main_ctx); - g_assert(bdrv_get_aio_context(target) == main_ctx); - g_assert(bdrv_get_aio_context(filter) == main_ctx); -@@ -805,10 +791,8 @@ static void test_propagate_mirror(void) - g_assert(bdrv_get_aio_context(filter) == main_ctx); - - /* ...unless we explicitly allow it */ -- aio_context_acquire(ctx); - blk_set_allow_aio_context_change(blk, true); - bdrv_try_change_aio_context(target, ctx, NULL, &error_abort); -- aio_context_release(ctx); - - g_assert(blk_get_aio_context(blk) == ctx); - g_assert(bdrv_get_aio_context(src) == ctx); -@@ -817,10 +801,8 @@ static void test_propagate_mirror(void) - - job_cancel_sync_all(); - -- aio_context_acquire(ctx); - blk_set_aio_context(blk, main_ctx, &error_abort); - bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort); -- aio_context_release(ctx); - - blk_unref(blk); - bdrv_unref(src); -@@ -836,7 +818,6 @@ static void test_attach_second_node(void) - BlockDriverState *bs, *filter; - QDict *options; - -- aio_context_acquire(main_ctx); - blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL); - bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort); - blk_insert_bs(blk, bs, &error_abort); -@@ -846,15 +827,12 @@ static void test_attach_second_node(void) - qdict_put_str(options, "file", "base"); - - filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort); -- aio_context_release(main_ctx); - - g_assert(blk_get_aio_context(blk) == ctx); - g_assert(bdrv_get_aio_context(bs) == ctx); - g_assert(bdrv_get_aio_context(filter) == ctx); - -- aio_context_acquire(ctx); - blk_set_aio_context(blk, main_ctx, &error_abort); -- aio_context_release(ctx); - g_assert(blk_get_aio_context(blk) == main_ctx); - g_assert(bdrv_get_aio_context(bs) == main_ctx); - g_assert(bdrv_get_aio_context(filter) == main_ctx); -@@ -868,11 +846,9 @@ static void test_attach_preserve_blk_ctx(void) - { - IOThread *iothread = iothread_new(); - AioContext *ctx = iothread_get_aio_context(iothread); -- AioContext *main_ctx = qemu_get_aio_context(); - BlockBackend *blk; - BlockDriverState *bs; - -- aio_context_acquire(main_ctx); - blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL); - bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort); - bs->total_sectors = 65536 / BDRV_SECTOR_SIZE; -@@ -881,25 +857,18 @@ static void test_attach_preserve_blk_ctx(void) - blk_insert_bs(blk, bs, &error_abort); - g_assert(blk_get_aio_context(blk) == ctx); - g_assert(bdrv_get_aio_context(bs) == ctx); -- aio_context_release(main_ctx); - - /* Remove the node again */ -- aio_context_acquire(ctx); - blk_remove_bs(blk); -- aio_context_release(ctx); - g_assert(blk_get_aio_context(blk) == ctx); - g_assert(bdrv_get_aio_context(bs) == qemu_get_aio_context()); - - /* Re-attach the node */ -- aio_context_acquire(main_ctx); - blk_insert_bs(blk, bs, &error_abort); -- aio_context_release(main_ctx); - g_assert(blk_get_aio_context(blk) == ctx); - g_assert(bdrv_get_aio_context(bs) == ctx); - -- aio_context_acquire(ctx); - blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort); -- aio_context_release(ctx); - bdrv_unref(bs); - blk_unref(blk); - } -diff --git a/tests/unit/test-blockjob.c b/tests/unit/test-blockjob.c -index a130f6fefb..fe3e0d2d38 100644 ---- a/tests/unit/test-blockjob.c -+++ b/tests/unit/test-blockjob.c -@@ -228,7 +228,6 @@ static void cancel_common(CancelJob *s) - BlockJob *job = &s->common; - BlockBackend *blk = s->blk; - JobStatus sts = job->job.status; -- AioContext *ctx = job->job.aio_context; - - job_cancel_sync(&job->job, true); - WITH_JOB_LOCK_GUARD() { -@@ -240,9 +239,7 @@ static void cancel_common(CancelJob *s) - job_unref_locked(&job->job); - } - -- aio_context_acquire(ctx); - destroy_blk(blk); -- aio_context_release(ctx); - - } - -@@ -391,132 +388,6 @@ static void test_cancel_concluded(void) - cancel_common(s); - } - --/* (See test_yielding_driver for the job description) */ --typedef struct YieldingJob { -- BlockJob common; -- bool should_complete; --} YieldingJob; -- --static void yielding_job_complete(Job *job, Error **errp) --{ -- YieldingJob *s = container_of(job, YieldingJob, common.job); -- s->should_complete = true; -- job_enter(job); --} -- --static int coroutine_fn yielding_job_run(Job *job, Error **errp) --{ -- YieldingJob *s = container_of(job, YieldingJob, common.job); -- -- job_transition_to_ready(job); -- -- while (!s->should_complete) { -- job_yield(job); -- } -- -- return 0; --} -- --/* -- * This job transitions immediately to the READY state, and then -- * yields until it is to complete. -- */ --static const BlockJobDriver test_yielding_driver = { -- .job_driver = { -- .instance_size = sizeof(YieldingJob), -- .free = block_job_free, -- .user_resume = block_job_user_resume, -- .run = yielding_job_run, -- .complete = yielding_job_complete, -- }, --}; -- --/* -- * Test that job_complete_locked() works even on jobs that are in a paused -- * state (i.e., STANDBY). -- * -- * To do this, run YieldingJob in an IO thread, get it into the READY -- * state, then have a drained section. Before ending the section, -- * acquire the context so the job will not be entered and will thus -- * remain on STANDBY. -- * -- * job_complete_locked() should still work without error. -- * -- * Note that on the QMP interface, it is impossible to lock an IO -- * thread before a drained section ends. In practice, the -- * bdrv_drain_all_end() and the aio_context_acquire() will be -- * reversed. However, that makes for worse reproducibility here: -- * Sometimes, the job would no longer be in STANDBY then but already -- * be started. We cannot prevent that, because the IO thread runs -- * concurrently. We can only prevent it by taking the lock before -- * ending the drained section, so we do that. -- * -- * (You can reverse the order of operations and most of the time the -- * test will pass, but sometimes the assert(status == STANDBY) will -- * fail.) -- */ --static void test_complete_in_standby(void) --{ -- BlockBackend *blk; -- IOThread *iothread; -- AioContext *ctx; -- Job *job; -- BlockJob *bjob; -- -- /* Create a test drive, move it to an IO thread */ -- blk = create_blk(NULL); -- iothread = iothread_new(); -- -- ctx = iothread_get_aio_context(iothread); -- blk_set_aio_context(blk, ctx, &error_abort); -- -- /* Create our test job */ -- bjob = mk_job(blk, "job", &test_yielding_driver, true, -- JOB_MANUAL_FINALIZE | JOB_MANUAL_DISMISS); -- job = &bjob->job; -- assert_job_status_is(job, JOB_STATUS_CREATED); -- -- /* Wait for the job to become READY */ -- job_start(job); -- /* -- * Here we are waiting for the status to change, so don't bother -- * protecting the read every time. -- */ -- AIO_WAIT_WHILE_UNLOCKED(ctx, job->status != JOB_STATUS_READY); -- -- /* Begin the drained section, pausing the job */ -- bdrv_drain_all_begin(); -- assert_job_status_is(job, JOB_STATUS_STANDBY); -- -- /* Lock the IO thread to prevent the job from being run */ -- aio_context_acquire(ctx); -- /* This will schedule the job to resume it */ -- bdrv_drain_all_end(); -- aio_context_release(ctx); -- -- WITH_JOB_LOCK_GUARD() { -- /* But the job cannot run, so it will remain on standby */ -- assert(job->status == JOB_STATUS_STANDBY); -- -- /* Even though the job is on standby, this should work */ -- job_complete_locked(job, &error_abort); -- -- /* The test is done now, clean up. */ -- job_finish_sync_locked(job, NULL, &error_abort); -- assert(job->status == JOB_STATUS_PENDING); -- -- job_finalize_locked(job, &error_abort); -- assert(job->status == JOB_STATUS_CONCLUDED); -- -- job_dismiss_locked(&job, &error_abort); -- } -- -- aio_context_acquire(ctx); -- destroy_blk(blk); -- aio_context_release(ctx); -- iothread_join(iothread); --} -- - int main(int argc, char **argv) - { - qemu_init_main_loop(&error_abort); -@@ -531,13 +402,5 @@ int main(int argc, char **argv) - g_test_add_func("/blockjob/cancel/standby", test_cancel_standby); - g_test_add_func("/blockjob/cancel/pending", test_cancel_pending); - g_test_add_func("/blockjob/cancel/concluded", test_cancel_concluded); -- -- /* -- * This test is flaky and sometimes fails in CI and otherwise: -- * don't run unless user opts in via environment variable. -- */ -- if (getenv("QEMU_TEST_FLAKY_TESTS")) { -- g_test_add_func("/blockjob/complete_in_standby", test_complete_in_standby); -- } - return g_test_run(); - } -diff --git a/tests/unit/test-replication.c b/tests/unit/test-replication.c -index afff908d77..5d2003b8ce 100644 ---- a/tests/unit/test-replication.c -+++ b/tests/unit/test-replication.c -@@ -199,17 +199,13 @@ static BlockBackend *start_primary(void) - static void teardown_primary(void) - { - BlockBackend *blk; -- AioContext *ctx; - - /* remove P_ID */ - blk = blk_by_name(P_ID); - assert(blk); - -- ctx = blk_get_aio_context(blk); -- aio_context_acquire(ctx); - monitor_remove_blk(blk); - blk_unref(blk); -- aio_context_release(ctx); - } - - static void test_primary_read(void) -@@ -345,27 +341,20 @@ static void teardown_secondary(void) - { - /* only need to destroy two BBs */ - BlockBackend *blk; -- AioContext *ctx; - - /* remove S_LOCAL_DISK_ID */ - blk = blk_by_name(S_LOCAL_DISK_ID); - assert(blk); - -- ctx = blk_get_aio_context(blk); -- aio_context_acquire(ctx); - monitor_remove_blk(blk); - blk_unref(blk); -- aio_context_release(ctx); - - /* remove S_ID */ - blk = blk_by_name(S_ID); - assert(blk); - -- ctx = blk_get_aio_context(blk); -- aio_context_acquire(ctx); - monitor_remove_blk(blk); - blk_unref(blk); -- aio_context_release(ctx); - } - - static void test_secondary_read(void) -diff --git a/util/async.c b/util/async.c -index 04ee83d220..dfd44ef612 100644 ---- a/util/async.c -+++ b/util/async.c -@@ -562,12 +562,10 @@ static void co_schedule_bh_cb(void *opaque) - Coroutine *co = QSLIST_FIRST(&straight); - QSLIST_REMOVE_HEAD(&straight, co_scheduled_next); - trace_aio_co_schedule_bh_cb(ctx, co); -- aio_context_acquire(ctx); - - /* Protected by write barrier in qemu_aio_coroutine_enter */ - qatomic_set(&co->scheduled, NULL); - qemu_aio_coroutine_enter(ctx, co); -- aio_context_release(ctx); - } - } - -@@ -707,9 +705,7 @@ void aio_co_enter(AioContext *ctx, Coroutine *co) - assert(self != co); - QSIMPLEQ_INSERT_TAIL(&self->co_queue_wakeup, co, co_queue_next); - } else { -- aio_context_acquire(ctx); - qemu_aio_coroutine_enter(ctx, co); -- aio_context_release(ctx); - } - } - -diff --git a/util/vhost-user-server.c b/util/vhost-user-server.c -index a9a48fffb8..3bfb1ad3ec 100644 ---- a/util/vhost-user-server.c -+++ b/util/vhost-user-server.c -@@ -360,10 +360,7 @@ static void vu_accept(QIONetListener *listener, QIOChannelSocket *sioc, - - qio_channel_set_follow_coroutine_ctx(server->ioc, true); - -- /* Attaching the AioContext starts the vu_client_trip coroutine */ -- aio_context_acquire(server->ctx); - vhost_user_server_attach_aio_context(server, server->ctx); -- aio_context_release(server->ctx); - } - - /* server->ctx acquired by caller */ --- -2.39.3 - diff --git a/kvm-block-remove-bdrv_co_lock.patch b/kvm-block-remove-bdrv_co_lock.patch deleted file mode 100644 index b219c1c..0000000 --- a/kvm-block-remove-bdrv_co_lock.patch +++ /dev/null @@ -1,97 +0,0 @@ -From d0514c7d5d6cc1aa140119c95d5ea2c1591b01e9 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:04 -0500 -Subject: [PATCH 087/101] block: remove bdrv_co_lock() - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [18/26] a303f861ea5e84d8e89fd51e530fd0cb2da17b89 (kmwolf/centos-qemu-kvm) - -The bdrv_co_lock() and bdrv_co_unlock() functions are already no-ops. -Remove them. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20231205182011.1976568-8-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - block.c | 10 ---------- - blockdev.c | 5 ----- - include/block/block-global-state.h | 14 -------------- - 3 files changed, 29 deletions(-) - -diff --git a/block.c b/block.c -index 91ace5d2d5..434b7f4d72 100644 ---- a/block.c -+++ b/block.c -@@ -7431,16 +7431,6 @@ void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx) - bdrv_dec_in_flight(bs); - } - --void coroutine_fn bdrv_co_lock(BlockDriverState *bs) --{ -- /* TODO removed in next patch */ --} -- --void coroutine_fn bdrv_co_unlock(BlockDriverState *bs) --{ -- /* TODO removed in next patch */ --} -- - static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban) - { - GLOBAL_STATE_CODE(); -diff --git a/blockdev.c b/blockdev.c -index 5d8b3a23eb..3a5e7222ec 100644 ---- a/blockdev.c -+++ b/blockdev.c -@@ -2264,18 +2264,13 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name, - return; - } - -- bdrv_co_lock(bs); - bdrv_drained_begin(bs); -- bdrv_co_unlock(bs); - - old_ctx = bdrv_co_enter(bs); - blk_co_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp); - bdrv_co_leave(bs, old_ctx); - -- bdrv_co_lock(bs); - bdrv_drained_end(bs); -- bdrv_co_unlock(bs); -- - blk_co_unref(blk); - } - -diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h -index 0327f1c605..4ec0b217f0 100644 ---- a/include/block/block-global-state.h -+++ b/include/block/block-global-state.h -@@ -267,20 +267,6 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag); - int bdrv_debug_resume(BlockDriverState *bs, const char *tag); - bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); - --/** -- * Locks the AioContext of @bs if it's not the current AioContext. This avoids -- * double locking which could lead to deadlocks: This is a coroutine_fn, so we -- * know we already own the lock of the current AioContext. -- * -- * May only be called in the main thread. -- */ --void coroutine_fn bdrv_co_lock(BlockDriverState *bs); -- --/** -- * Unlocks the AioContext of @bs if it's not the current AioContext. -- */ --void coroutine_fn bdrv_co_unlock(BlockDriverState *bs); -- - bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, - GHashTable *visited, Transaction *tran, - Error **errp); --- -2.39.3 - diff --git a/kvm-block-remove-outdated-AioContext-locking-comments.patch b/kvm-block-remove-outdated-AioContext-locking-comments.patch deleted file mode 100644 index d6670c1..0000000 --- a/kvm-block-remove-outdated-AioContext-locking-comments.patch +++ /dev/null @@ -1,411 +0,0 @@ -From dc4eb64185957a01948217814478abc450ce5f26 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:11 -0500 -Subject: [PATCH 094/101] block: remove outdated AioContext locking comments - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [25/26] 395e18fb40d28d4bc961acee1a00da7f60748076 (kmwolf/centos-qemu-kvm) - -The AioContext lock no longer exists. - -There is one noteworthy change: - - - * More specifically, these functions use BDRV_POLL_WHILE(bs), which - - * requires the caller to be either in the main thread and hold - - * the BlockdriverState (bs) AioContext lock, or directly in the - - * home thread that runs the bs AioContext. Calling them from - - * another thread in another AioContext would cause deadlocks. - + * More specifically, these functions use BDRV_POLL_WHILE(bs), which requires - + * the caller to be either in the main thread or directly in the home thread - + * that runs the bs AioContext. Calling them from another thread in another - + * AioContext would cause deadlocks. - -I am not sure whether deadlocks are still possible. Maybe they have just -moved to the fine-grained locks that have replaced the AioContext. Since -I am not sure if the deadlocks are gone, I have kept the substance -unchanged and just removed mention of the AioContext. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Message-ID: <20231205182011.1976568-15-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - block.c | 73 ++++++---------------------- - block/block-backend.c | 8 --- - block/export/vhost-user-blk-server.c | 4 -- - include/block/block-common.h | 3 -- - include/block/block-io.h | 9 ++-- - include/block/block_int-common.h | 2 - - tests/qemu-iotests/202 | 2 +- - tests/qemu-iotests/203 | 3 +- - 8 files changed, 22 insertions(+), 82 deletions(-) - -diff --git a/block.c b/block.c -index 434b7f4d72..a097772238 100644 ---- a/block.c -+++ b/block.c -@@ -1616,11 +1616,6 @@ out: - g_free(gen_node_name); - } - --/* -- * The caller must always hold @bs AioContext lock, because this function calls -- * bdrv_refresh_total_sectors() which polls when called from non-coroutine -- * context. -- */ - static int no_coroutine_fn GRAPH_UNLOCKED - bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name, - QDict *options, int open_flags, Error **errp) -@@ -2901,7 +2896,7 @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm) - * Replaces the node that a BdrvChild points to without updating permissions. - * - * If @new_bs is non-NULL, the parent of @child must already be drained through -- * @child and the caller must hold the AioContext lock for @new_bs. -+ * @child. - */ - static void GRAPH_WRLOCK - bdrv_replace_child_noperm(BdrvChild *child, BlockDriverState *new_bs) -@@ -3041,9 +3036,8 @@ static TransactionActionDrv bdrv_attach_child_common_drv = { - * - * Returns new created child. - * -- * The caller must hold the AioContext lock for @child_bs. Both @parent_bs and -- * @child_bs can move to a different AioContext in this function. Callers must -- * make sure that their AioContext locking is still correct after this. -+ * Both @parent_bs and @child_bs can move to a different AioContext in this -+ * function. - */ - static BdrvChild * GRAPH_WRLOCK - bdrv_attach_child_common(BlockDriverState *child_bs, -@@ -3142,9 +3136,8 @@ bdrv_attach_child_common(BlockDriverState *child_bs, - /* - * Function doesn't update permissions, caller is responsible for this. - * -- * The caller must hold the AioContext lock for @child_bs. Both @parent_bs and -- * @child_bs can move to a different AioContext in this function. Callers must -- * make sure that their AioContext locking is still correct after this. -+ * Both @parent_bs and @child_bs can move to a different AioContext in this -+ * function. - * - * After calling this function, the transaction @tran may only be completed - * while holding a writer lock for the graph. -@@ -3184,9 +3177,6 @@ bdrv_attach_child_noperm(BlockDriverState *parent_bs, - * - * On failure NULL is returned, errp is set and the reference to - * child_bs is also dropped. -- * -- * The caller must hold the AioContext lock @child_bs, but not that of @ctx -- * (unless @child_bs is already in @ctx). - */ - BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, - const char *child_name, -@@ -3226,9 +3216,6 @@ out: - * - * On failure NULL is returned, errp is set and the reference to - * child_bs is also dropped. -- * -- * If @parent_bs and @child_bs are in different AioContexts, the caller must -- * hold the AioContext lock for @child_bs, but not for @parent_bs. - */ - BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, - BlockDriverState *child_bs, -@@ -3418,9 +3405,8 @@ static BdrvChildRole bdrv_backing_role(BlockDriverState *bs) - * - * Function doesn't update permissions, caller is responsible for this. - * -- * The caller must hold the AioContext lock for @child_bs. Both @parent_bs and -- * @child_bs can move to a different AioContext in this function. Callers must -- * make sure that their AioContext locking is still correct after this. -+ * Both @parent_bs and @child_bs can move to a different AioContext in this -+ * function. - * - * After calling this function, the transaction @tran may only be completed - * while holding a writer lock for the graph. -@@ -3513,9 +3499,8 @@ out: - } - - /* -- * The caller must hold the AioContext lock for @backing_hd. Both @bs and -- * @backing_hd can move to a different AioContext in this function. Callers must -- * make sure that their AioContext locking is still correct after this. -+ * Both @bs and @backing_hd can move to a different AioContext in this -+ * function. - * - * If a backing child is already present (i.e. we're detaching a node), that - * child node must be drained. -@@ -3574,8 +3559,6 @@ int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, - * itself, all options starting with "${bdref_key}." are considered part of the - * BlockdevRef. - * -- * The caller must hold the main AioContext lock. -- * - * TODO Can this be unified with bdrv_open_image()? - */ - int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, -@@ -3745,9 +3728,7 @@ done: - * - * The BlockdevRef will be removed from the options QDict. - * -- * The caller must hold the lock of the main AioContext and no other AioContext. -- * @parent can move to a different AioContext in this function. Callers must -- * make sure that their AioContext locking is still correct after this. -+ * @parent can move to a different AioContext in this function. - */ - BdrvChild *bdrv_open_child(const char *filename, - QDict *options, const char *bdref_key, -@@ -3778,9 +3759,7 @@ BdrvChild *bdrv_open_child(const char *filename, - /* - * Wrapper on bdrv_open_child() for most popular case: open primary child of bs. - * -- * The caller must hold the lock of the main AioContext and no other AioContext. -- * @parent can move to a different AioContext in this function. Callers must -- * make sure that their AioContext locking is still correct after this. -+ * @parent can move to a different AioContext in this function. - */ - int bdrv_open_file_child(const char *filename, - QDict *options, const char *bdref_key, -@@ -3923,8 +3902,6 @@ out: - * The reference parameter may be used to specify an existing block device which - * should be opened. If specified, neither options nor a filename may be given, - * nor can an existing BDS be reused (that is, *pbs has to be NULL). -- * -- * The caller must always hold the main AioContext lock. - */ - static BlockDriverState * no_coroutine_fn - bdrv_open_inherit(const char *filename, const char *reference, QDict *options, -@@ -4217,7 +4194,6 @@ close_and_fail: - return NULL; - } - --/* The caller must always hold the main AioContext lock. */ - BlockDriverState *bdrv_open(const char *filename, const char *reference, - QDict *options, int flags, Error **errp) - { -@@ -4665,10 +4641,7 @@ int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only, - * - * Return 0 on success, otherwise return < 0 and set @errp. - * -- * The caller must hold the AioContext lock of @reopen_state->bs. - * @reopen_state->bs can move to a different AioContext in this function. -- * Callers must make sure that their AioContext locking is still correct after -- * this. - */ - static int GRAPH_UNLOCKED - bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state, -@@ -4801,8 +4774,6 @@ out_rdlock: - * It is the responsibility of the caller to then call the abort() or - * commit() for any other BDS that have been left in a prepare() state - * -- * The caller must hold the AioContext lock of @reopen_state->bs. -- * - * After calling this function, the transaction @change_child_tran may only be - * completed while holding a writer lock for the graph. - */ -@@ -5437,8 +5408,6 @@ int bdrv_drop_filter(BlockDriverState *bs, Error **errp) - * child. - * - * This function does not create any image files. -- * -- * The caller must hold the AioContext lock for @bs_top. - */ - int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, - Error **errp) -@@ -5545,9 +5514,8 @@ static void bdrv_delete(BlockDriverState *bs) - * after the call (even on failure), so if the caller intends to reuse the - * dictionary, it needs to use qobject_ref() before calling bdrv_open. - * -- * The caller holds the AioContext lock for @bs. It must make sure that @bs -- * stays in the same AioContext, i.e. @options must not refer to nodes in a -- * different AioContext. -+ * The caller must make sure that @bs stays in the same AioContext, i.e. -+ * @options must not refer to nodes in a different AioContext. - */ - BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options, - int flags, Error **errp) -@@ -7565,10 +7533,6 @@ static TransactionActionDrv set_aio_context = { - * - * Must be called from the main AioContext. - * -- * The caller must own the AioContext lock for the old AioContext of bs, but it -- * must not own the AioContext lock for new_context (unless new_context is the -- * same as the current context of bs). -- * - * @visited will accumulate all visited BdrvChild objects. The caller is - * responsible for freeing the list afterwards. - */ -@@ -7621,13 +7585,6 @@ static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx, - * - * If ignore_child is not NULL, that child (and its subgraph) will not - * be touched. -- * -- * This function still requires the caller to take the bs current -- * AioContext lock, otherwise draining will fail since AIO_WAIT_WHILE -- * assumes the lock is always held if bs is in another AioContext. -- * For the same reason, it temporarily also holds the new AioContext, since -- * bdrv_drained_end calls BDRV_POLL_WHILE that assumes the lock is taken too. -- * Therefore the new AioContext lock must not be taken by the caller. - */ - int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, - BdrvChild *ignore_child, Error **errp) -@@ -7653,8 +7610,8 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, - - /* - * Linear phase: go through all callbacks collected in the transaction. -- * Run all callbacks collected in the recursion to switch all nodes -- * AioContext lock (transaction commit), or undo all changes done in the -+ * Run all callbacks collected in the recursion to switch every node's -+ * AioContext (transaction commit), or undo all changes done in the - * recursion (transaction abort). - */ - -diff --git a/block/block-backend.c b/block/block-backend.c -index f412bed274..209eb07528 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -390,8 +390,6 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm) - * Both sets of permissions can be changed later using blk_set_perm(). - * - * Return the new BlockBackend on success, null on failure. -- * -- * Callers must hold the AioContext lock of @bs. - */ - BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm, - uint64_t shared_perm, Error **errp) -@@ -416,8 +414,6 @@ BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm, - * Just as with bdrv_open(), after having called this function the reference to - * @options belongs to the block layer (even on failure). - * -- * Called without holding an AioContext lock. -- * - * TODO: Remove @filename and @flags; it should be possible to specify a whole - * BDS tree just by specifying the @options QDict (or @reference, - * alternatively). At the time of adding this function, this is not possible, -@@ -872,8 +868,6 @@ BlockBackend *blk_by_public(BlockBackendPublic *public) - - /* - * Disassociates the currently associated BlockDriverState from @blk. -- * -- * The caller must hold the AioContext lock for the BlockBackend. - */ - void blk_remove_bs(BlockBackend *blk) - { -@@ -915,8 +909,6 @@ void blk_remove_bs(BlockBackend *blk) - - /* - * Associates a new BlockDriverState with @blk. -- * -- * Callers must hold the AioContext lock of @bs. - */ - int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp) - { -diff --git a/block/export/vhost-user-blk-server.c b/block/export/vhost-user-blk-server.c -index 16f48388d3..50c358e8cd 100644 ---- a/block/export/vhost-user-blk-server.c -+++ b/block/export/vhost-user-blk-server.c -@@ -278,7 +278,6 @@ static void vu_blk_exp_resize(void *opaque) - vu_config_change_msg(&vexp->vu_server.vu_dev); - } - --/* Called with vexp->export.ctx acquired */ - static void vu_blk_drained_begin(void *opaque) - { - VuBlkExport *vexp = opaque; -@@ -287,7 +286,6 @@ static void vu_blk_drained_begin(void *opaque) - vhost_user_server_detach_aio_context(&vexp->vu_server); - } - --/* Called with vexp->export.blk AioContext acquired */ - static void vu_blk_drained_end(void *opaque) - { - VuBlkExport *vexp = opaque; -@@ -300,8 +298,6 @@ static void vu_blk_drained_end(void *opaque) - * Ensures that bdrv_drained_begin() waits until in-flight requests complete - * and the server->co_trip coroutine has terminated. It will be restarted in - * vhost_user_server_attach_aio_context(). -- * -- * Called with vexp->export.ctx acquired. - */ - static bool vu_blk_drained_poll(void *opaque) - { -diff --git a/include/block/block-common.h b/include/block/block-common.h -index d7599564db..a846023a09 100644 ---- a/include/block/block-common.h -+++ b/include/block/block-common.h -@@ -70,9 +70,6 @@ - * automatically takes the graph rdlock when calling the wrapped function. In - * the same way, no_co_wrapper_bdrv_wrlock functions automatically take the - * graph wrlock. -- * -- * If the first parameter of the function is a BlockDriverState, BdrvChild or -- * BlockBackend pointer, the AioContext lock for it is taken in the wrapper. - */ - #define no_co_wrapper - #define no_co_wrapper_bdrv_rdlock -diff --git a/include/block/block-io.h b/include/block/block-io.h -index 8eb39a858b..b49e0537dd 100644 ---- a/include/block/block-io.h -+++ b/include/block/block-io.h -@@ -332,11 +332,10 @@ bdrv_co_copy_range(BdrvChild *src, int64_t src_offset, - * "I/O or GS" API functions. These functions can run without - * the BQL, but only in one specific iothread/main loop. - * -- * More specifically, these functions use BDRV_POLL_WHILE(bs), which -- * requires the caller to be either in the main thread and hold -- * the BlockdriverState (bs) AioContext lock, or directly in the -- * home thread that runs the bs AioContext. Calling them from -- * another thread in another AioContext would cause deadlocks. -+ * More specifically, these functions use BDRV_POLL_WHILE(bs), which requires -+ * the caller to be either in the main thread or directly in the home thread -+ * that runs the bs AioContext. Calling them from another thread in another -+ * AioContext would cause deadlocks. - * - * Therefore, these functions are not proper I/O, because they - * can't run in *any* iothreads, but only in a specific one. -diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h -index 4e31d161c5..151279d481 100644 ---- a/include/block/block_int-common.h -+++ b/include/block/block_int-common.h -@@ -1192,8 +1192,6 @@ struct BlockDriverState { - /* The error object in use for blocking operations on backing_hd */ - Error *backing_blocker; - -- /* Protected by AioContext lock */ -- - /* - * If we are reading a disk image, give its size in sectors. - * Generally read-only; it is written to by load_snapshot and -diff --git a/tests/qemu-iotests/202 b/tests/qemu-iotests/202 -index b784dcd791..13304242e5 100755 ---- a/tests/qemu-iotests/202 -+++ b/tests/qemu-iotests/202 -@@ -21,7 +21,7 @@ - # Check that QMP 'transaction' blockdev-snapshot-sync with multiple drives on a - # single IOThread completes successfully. This particular command triggered a - # hang due to recursive AioContext locking and BDRV_POLL_WHILE(). Protect --# against regressions. -+# against regressions even though the AioContext lock no longer exists. - - import iotests - -diff --git a/tests/qemu-iotests/203 b/tests/qemu-iotests/203 -index ab80fd0e44..1ba878522b 100755 ---- a/tests/qemu-iotests/203 -+++ b/tests/qemu-iotests/203 -@@ -21,7 +21,8 @@ - # Check that QMP 'migrate' with multiple drives on a single IOThread completes - # successfully. This particular command triggered a hang in the source QEMU - # process due to recursive AioContext locking in bdrv_invalidate_all() and --# BDRV_POLL_WHILE(). -+# BDRV_POLL_WHILE(). Protect against regressions even though the AioContext -+# lock no longer exists. - - import iotests - --- -2.39.3 - diff --git a/kvm-chardev-char-socket-Fix-TLS-io-channels-sending-too-.patch b/kvm-chardev-char-socket-Fix-TLS-io-channels-sending-too-.patch deleted file mode 100644 index 34c4e8f..0000000 --- a/kvm-chardev-char-socket-Fix-TLS-io-channels-sending-too-.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 95b2ffc5f01dc4309c2e747ed883d22cd1d26347 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Sat, 2 Mar 2024 17:00:23 +0100 -Subject: [PATCH 2/2] chardev/char-socket: Fix TLS io channels sending too much - data to the backend -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 227: Fix TLS io channels sending too much data to the backend -RH-Jira: RHEL-24614 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Daniel P. Berrangé -RH-Commit: [1/1] fce871914e0ce52e16a6edae0e007513f9fec1ae (thuth/qemu-kvm-cs9) - -JIRA: https://issues.redhat.com/browse/RHEL-24614 - -commit 462945cd22d2bcd233401ed3aa167d83a8e35b05 -Author: Thomas Huth -Date: Thu Feb 29 11:43:37 2024 +0100 - - chardev/char-socket: Fix TLS io channels sending too much data to the backend - - Commit ffda5db65a ("io/channel-tls: fix handling of bigger read buffers") - changed the behavior of the TLS io channels to schedule a second reading - attempt if there is still incoming data pending. This caused a regression - with backends like the sclpconsole that check in their read function that - the sender does not try to write more bytes to it than the device can - currently handle. - - The problem can be reproduced like this: - - 1) In one terminal, do this: - - mkdir qemu-pki - cd qemu-pki - openssl genrsa 2048 > ca-key.pem - openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem - # enter some dummy value for the cert - openssl genrsa 2048 > server-key.pem - openssl req -new -x509 -nodes -days 365000 -key server-key.pem \ - -out server-cert.pem - # enter some other dummy values for the cert - - gnutls-serv --echo --x509cafile ca-cert.pem --x509keyfile server-key.pem \ - --x509certfile server-cert.pem -p 8338 - - 2) In another terminal, do this: - - wget https://download.fedoraproject.org/pub/fedora-secondary/releases/39/Cloud/s390x/images/Fedora-Cloud-Base-39-1.5.s390x.qcow2 - - qemu-system-s390x -nographic -nodefaults \ - -hda Fedora-Cloud-Base-39-1.5.s390x.qcow2 \ - -object tls-creds-x509,id=tls0,endpoint=client,verify-peer=false,dir=$PWD/qemu-pki \ - -chardev socket,id=tls_chardev,host=localhost,port=8338,tls-creds=tls0 \ - -device sclpconsole,chardev=tls_chardev,id=tls_serial - - QEMU then aborts after a second or two with: - - qemu-system-s390x: ../hw/char/sclpconsole.c:73: chr_read: Assertion - `size <= SIZE_BUFFER_VT220 - scon->iov_data_len' failed. - Aborted (core dumped) - - It looks like the second read does not trigger the chr_can_read() function - to be called before the second read, which should normally always be done - before sending bytes to a character device to see how much it can handle, - so the s->max_size in tcp_chr_read() still contains the old value from the - previous read. Let's make sure that we use the up-to-date value by calling - tcp_chr_read_poll() again here. - - Fixes: ffda5db65a ("io/channel-tls: fix handling of bigger read buffers") - Buglink: https://issues.redhat.com/browse/RHEL-24614 - Reviewed-by: "Daniel P. Berrangé" - Message-ID: <20240229104339.42574-1-thuth@redhat.com> - Reviewed-by: Antoine Damhet - Tested-by: Antoine Damhet - Reviewed-by: Marc-André Lureau - Signed-off-by: Thomas Huth - -Signed-off-by: Thomas Huth ---- - chardev/char-socket.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/chardev/char-socket.c b/chardev/char-socket.c -index 73947da188..034840593d 100644 ---- a/chardev/char-socket.c -+++ b/chardev/char-socket.c -@@ -492,9 +492,9 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) - s->max_size <= 0) { - return TRUE; - } -- len = sizeof(buf); -- if (len > s->max_size) { -- len = s->max_size; -+ len = tcp_chr_read_poll(opaque); -+ if (len > sizeof(buf)) { -+ len = sizeof(buf); - } - size = tcp_chr_recv(chr, (void *)buf, len); - if (size == 0 || (size == -1 && errno != EAGAIN)) { --- -2.39.3 - diff --git a/kvm-chardev-lower-priority-of-the-HUP-GSource-in-socket-.patch b/kvm-chardev-lower-priority-of-the-HUP-GSource-in-socket-.patch deleted file mode 100644 index 30e055f..0000000 --- a/kvm-chardev-lower-priority-of-the-HUP-GSource-in-socket-.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 4d4102f6e2f9afd6182888787ae8b570347df87d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= -Date: Mon, 18 Mar 2024 18:06:59 +0000 -Subject: [PATCH 1/3] chardev: lower priority of the HUP GSource in socket - chardev -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Daniel P. Berrangé -RH-MergeRequest: 233: Fix handling of TLS sessions in chardevs -RH-Jira: RHEL-24614 -RH-Acked-by: Thomas Huth -RH-Acked-by: Marc-André Lureau -RH-Commit: [1/3] 842f54349191b0206e68f35a7a80155f5a584942 (berrange/centos-src-qemu) - -The socket chardev often has 2 GSource object registered against the -same FD. One is registered all the time and is just intended to handle -POLLHUP events, while the other gets registered & unregistered on the -fly as the frontend is ready to receive more data or not. - -It is very common for poll() to signal a POLLHUP event at the same time -as there is pending incoming data from the disconnected client. It is -therefore essential to process incoming data prior to processing HUP. -The problem with having 2 GSource on the same FD is that there is no -guaranteed ordering of execution between them, so the chardev code may -process HUP first and thus discard data. - -This failure scenario is non-deterministic but can be seen fairly -reliably by reverting a7077b8e354d90fec26c2921aa2dea85b90dff90, and -then running 'tests/unit/test-char', which will sometimes fail with -missing data. - -Ideally QEMU would only have 1 GSource, but that's a complex code -refactoring job. The next best solution is to try to ensure ordering -between the 2 GSource objects. This can be achieved by lowering the -priority of the HUP GSource, so that it is never dispatched if the -main GSource is also ready to dispatch. Counter-intuitively, lowering -the priority of a GSource is done by raising its priority number. - -Reviewed-by: Marc-André Lureau -Reviewed-by: Thomas Huth -Signed-off-by: Daniel P. Berrangé -(cherry picked from commit 8bd8b04adc9f18904f323dff085f8b4ec77915c6) ---- - chardev/char-socket.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/chardev/char-socket.c b/chardev/char-socket.c -index 034840593d..f48d341ebc 100644 ---- a/chardev/char-socket.c -+++ b/chardev/char-socket.c -@@ -597,6 +597,22 @@ static void update_ioc_handlers(SocketChardev *s) - - remove_hup_source(s); - s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP); -+ /* -+ * poll() is liable to return POLLHUP even when there is -+ * still incoming data available to read on the FD. If -+ * we have the hup_source at the same priority as the -+ * main io_add_watch_poll GSource, then we might end up -+ * processing the POLLHUP event first, closing the FD, -+ * and as a result silently discard data we should have -+ * read. -+ * -+ * By setting the hup_source to G_PRIORITY_DEFAULT + 1, -+ * we ensure that io_add_watch_poll GSource will always -+ * be dispatched first, thus guaranteeing we will be -+ * able to process all incoming data before closing the -+ * FD -+ */ -+ g_source_set_priority(s->hup_source, G_PRIORITY_DEFAULT + 1); - g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup, - chr, NULL); - g_source_attach(s->hup_source, chr->gcontext); --- -2.39.3 - diff --git a/kvm-coroutine-cap-per-thread-local-pool-size.patch b/kvm-coroutine-cap-per-thread-local-pool-size.patch deleted file mode 100644 index 6fffc23..0000000 --- a/kvm-coroutine-cap-per-thread-local-pool-size.patch +++ /dev/null @@ -1,412 +0,0 @@ -From e99c56752a1c4021a93c92b7be78856ebefaa1b3 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 18 Mar 2024 14:34:29 -0400 -Subject: [PATCH 1/2] coroutine: cap per-thread local pool size - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 234: coroutine: cap per-thread local pool size -RH-Jira: RHEL-28947 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [1/2] 5971de1c1e238457925bfb9c4bfc932de857b28d (stefanha/centos-stream-qemu-kvm) - -The coroutine pool implementation can hit the Linux vm.max_map_count -limit, causing QEMU to abort with "failed to allocate memory for stack" -or "failed to set up stack guard page" during coroutine creation. - -This happens because per-thread pools can grow to tens of thousands of -coroutines. Each coroutine causes 2 virtual memory areas to be created. -Eventually vm.max_map_count is reached and memory-related syscalls fail. -The per-thread pool sizes are non-uniform and depend on past coroutine -usage in each thread, so it's possible for one thread to have a large -pool while another thread's pool is empty. - -Switch to a new coroutine pool implementation with a global pool that -grows to a maximum number of coroutines and per-thread local pools that -are capped at hardcoded small number of coroutines. - -This approach does not leave large numbers of coroutines pooled in a -thread that may not use them again. In order to perform well it -amortizes the cost of global pool accesses by working in batches of -coroutines instead of individual coroutines. - -The global pool is a list. Threads donate batches of coroutines to when -they have too many and take batches from when they have too few: - -.-----------------------------------. -| Batch 1 | Batch 2 | Batch 3 | ... | global_pool -`-----------------------------------' - -Each thread has up to 2 batches of coroutines: - -.-------------------. -| Batch 1 | Batch 2 | per-thread local_pool (maximum 2 batches) -`-------------------' - -The goal of this change is to reduce the excessive number of pooled -coroutines that cause QEMU to abort when vm.max_map_count is reached -without losing the performance of an adequately sized coroutine pool. - -Here are virtio-blk disk I/O benchmark results: - - RW BLKSIZE IODEPTH OLD NEW CHANGE -randread 4k 1 113725 117451 +3.3% -randread 4k 8 192968 198510 +2.9% -randread 4k 16 207138 209429 +1.1% -randread 4k 32 212399 215145 +1.3% -randread 4k 64 218319 221277 +1.4% -randread 128k 1 17587 17535 -0.3% -randread 128k 8 17614 17616 +0.0% -randread 128k 16 17608 17609 +0.0% -randread 128k 32 17552 17553 +0.0% -randread 128k 64 17484 17484 +0.0% - -See files/{fio.sh,test.xml.j2} for the benchmark configuration: -https://gitlab.com/stefanha/virt-playbooks/-/tree/coroutine-pool-fix-sizing - -Buglink: https://issues.redhat.com/browse/RHEL-28947 -Reported-by: Sanjay Rao -Reported-by: Boaz Ben Shabat -Reported-by: Joe Mario -Reviewed-by: Kevin Wolf -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240318183429.1039340-1-stefanha@redhat.com> -(cherry picked from commit 86a637e48104ae74d8be53bed6441ce32be33433) -Signed-off-by: Stefan Hajnoczi ---- - util/qemu-coroutine.c | 282 +++++++++++++++++++++++++++++++++--------- - 1 file changed, 223 insertions(+), 59 deletions(-) - -diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c -index 5fd2dbaf8b..2790959eaf 100644 ---- a/util/qemu-coroutine.c -+++ b/util/qemu-coroutine.c -@@ -18,39 +18,200 @@ - #include "qemu/atomic.h" - #include "qemu/coroutine_int.h" - #include "qemu/coroutine-tls.h" -+#include "qemu/cutils.h" - #include "block/aio.h" - --/** -- * The minimal batch size is always 64, coroutines from the release_pool are -- * reused as soon as there are 64 coroutines in it. The maximum pool size starts -- * with 64 and is increased on demand so that coroutines are not deleted even if -- * they are not immediately reused. -- */ - enum { -- POOL_MIN_BATCH_SIZE = 64, -- POOL_INITIAL_MAX_SIZE = 64, -+ COROUTINE_POOL_BATCH_MAX_SIZE = 128, - }; - --/** Free list to speed up creation */ --static QSLIST_HEAD(, Coroutine) release_pool = QSLIST_HEAD_INITIALIZER(pool); --static unsigned int pool_max_size = POOL_INITIAL_MAX_SIZE; --static unsigned int release_pool_size; -+/* -+ * Coroutine creation and deletion is expensive so a pool of unused coroutines -+ * is kept as a cache. When the pool has coroutines available, they are -+ * recycled instead of creating new ones from scratch. Coroutines are added to -+ * the pool upon termination. -+ * -+ * The pool is global but each thread maintains a small local pool to avoid -+ * global pool contention. Threads fetch and return batches of coroutines from -+ * the global pool to maintain their local pool. The local pool holds up to two -+ * batches whereas the maximum size of the global pool is controlled by the -+ * qemu_coroutine_inc_pool_size() API. -+ * -+ * .-----------------------------------. -+ * | Batch 1 | Batch 2 | Batch 3 | ... | global_pool -+ * `-----------------------------------' -+ * -+ * .-------------------. -+ * | Batch 1 | Batch 2 | per-thread local_pool (maximum 2 batches) -+ * `-------------------' -+ */ -+typedef struct CoroutinePoolBatch { -+ /* Batches are kept in a list */ -+ QSLIST_ENTRY(CoroutinePoolBatch) next; -+ -+ /* This batch holds up to @COROUTINE_POOL_BATCH_MAX_SIZE coroutines */ -+ QSLIST_HEAD(, Coroutine) list; -+ unsigned int size; -+} CoroutinePoolBatch; -+ -+typedef QSLIST_HEAD(, CoroutinePoolBatch) CoroutinePool; -+ -+/* Host operating system limit on number of pooled coroutines */ -+static unsigned int global_pool_hard_max_size; -+ -+static QemuMutex global_pool_lock; /* protects the following variables */ -+static CoroutinePool global_pool = QSLIST_HEAD_INITIALIZER(global_pool); -+static unsigned int global_pool_size; -+static unsigned int global_pool_max_size = COROUTINE_POOL_BATCH_MAX_SIZE; -+ -+QEMU_DEFINE_STATIC_CO_TLS(CoroutinePool, local_pool); -+QEMU_DEFINE_STATIC_CO_TLS(Notifier, local_pool_cleanup_notifier); - --typedef QSLIST_HEAD(, Coroutine) CoroutineQSList; --QEMU_DEFINE_STATIC_CO_TLS(CoroutineQSList, alloc_pool); --QEMU_DEFINE_STATIC_CO_TLS(unsigned int, alloc_pool_size); --QEMU_DEFINE_STATIC_CO_TLS(Notifier, coroutine_pool_cleanup_notifier); -+static CoroutinePoolBatch *coroutine_pool_batch_new(void) -+{ -+ CoroutinePoolBatch *batch = g_new(CoroutinePoolBatch, 1); -+ -+ QSLIST_INIT(&batch->list); -+ batch->size = 0; -+ return batch; -+} - --static void coroutine_pool_cleanup(Notifier *n, void *value) -+static void coroutine_pool_batch_delete(CoroutinePoolBatch *batch) - { - Coroutine *co; - Coroutine *tmp; -- CoroutineQSList *alloc_pool = get_ptr_alloc_pool(); - -- QSLIST_FOREACH_SAFE(co, alloc_pool, pool_next, tmp) { -- QSLIST_REMOVE_HEAD(alloc_pool, pool_next); -+ QSLIST_FOREACH_SAFE(co, &batch->list, pool_next, tmp) { -+ QSLIST_REMOVE_HEAD(&batch->list, pool_next); - qemu_coroutine_delete(co); - } -+ g_free(batch); -+} -+ -+static void local_pool_cleanup(Notifier *n, void *value) -+{ -+ CoroutinePool *local_pool = get_ptr_local_pool(); -+ CoroutinePoolBatch *batch; -+ CoroutinePoolBatch *tmp; -+ -+ QSLIST_FOREACH_SAFE(batch, local_pool, next, tmp) { -+ QSLIST_REMOVE_HEAD(local_pool, next); -+ coroutine_pool_batch_delete(batch); -+ } -+} -+ -+/* Ensure the atexit notifier is registered */ -+static void local_pool_cleanup_init_once(void) -+{ -+ Notifier *notifier = get_ptr_local_pool_cleanup_notifier(); -+ if (!notifier->notify) { -+ notifier->notify = local_pool_cleanup; -+ qemu_thread_atexit_add(notifier); -+ } -+} -+ -+/* Helper to get the next unused coroutine from the local pool */ -+static Coroutine *coroutine_pool_get_local(void) -+{ -+ CoroutinePool *local_pool = get_ptr_local_pool(); -+ CoroutinePoolBatch *batch = QSLIST_FIRST(local_pool); -+ Coroutine *co; -+ -+ if (unlikely(!batch)) { -+ return NULL; -+ } -+ -+ co = QSLIST_FIRST(&batch->list); -+ QSLIST_REMOVE_HEAD(&batch->list, pool_next); -+ batch->size--; -+ -+ if (batch->size == 0) { -+ QSLIST_REMOVE_HEAD(local_pool, next); -+ coroutine_pool_batch_delete(batch); -+ } -+ return co; -+} -+ -+/* Get the next batch from the global pool */ -+static void coroutine_pool_refill_local(void) -+{ -+ CoroutinePool *local_pool = get_ptr_local_pool(); -+ CoroutinePoolBatch *batch; -+ -+ WITH_QEMU_LOCK_GUARD(&global_pool_lock) { -+ batch = QSLIST_FIRST(&global_pool); -+ -+ if (batch) { -+ QSLIST_REMOVE_HEAD(&global_pool, next); -+ global_pool_size -= batch->size; -+ } -+ } -+ -+ if (batch) { -+ QSLIST_INSERT_HEAD(local_pool, batch, next); -+ local_pool_cleanup_init_once(); -+ } -+} -+ -+/* Add a batch of coroutines to the global pool */ -+static void coroutine_pool_put_global(CoroutinePoolBatch *batch) -+{ -+ WITH_QEMU_LOCK_GUARD(&global_pool_lock) { -+ unsigned int max = MIN(global_pool_max_size, -+ global_pool_hard_max_size); -+ -+ if (global_pool_size < max) { -+ QSLIST_INSERT_HEAD(&global_pool, batch, next); -+ -+ /* Overshooting the max pool size is allowed */ -+ global_pool_size += batch->size; -+ return; -+ } -+ } -+ -+ /* The global pool was full, so throw away this batch */ -+ coroutine_pool_batch_delete(batch); -+} -+ -+/* Get the next unused coroutine from the pool or return NULL */ -+static Coroutine *coroutine_pool_get(void) -+{ -+ Coroutine *co; -+ -+ co = coroutine_pool_get_local(); -+ if (!co) { -+ coroutine_pool_refill_local(); -+ co = coroutine_pool_get_local(); -+ } -+ return co; -+} -+ -+static void coroutine_pool_put(Coroutine *co) -+{ -+ CoroutinePool *local_pool = get_ptr_local_pool(); -+ CoroutinePoolBatch *batch = QSLIST_FIRST(local_pool); -+ -+ if (unlikely(!batch)) { -+ batch = coroutine_pool_batch_new(); -+ QSLIST_INSERT_HEAD(local_pool, batch, next); -+ local_pool_cleanup_init_once(); -+ } -+ -+ if (unlikely(batch->size >= COROUTINE_POOL_BATCH_MAX_SIZE)) { -+ CoroutinePoolBatch *next = QSLIST_NEXT(batch, next); -+ -+ /* Is the local pool full? */ -+ if (next) { -+ QSLIST_REMOVE_HEAD(local_pool, next); -+ coroutine_pool_put_global(batch); -+ } -+ -+ batch = coroutine_pool_batch_new(); -+ QSLIST_INSERT_HEAD(local_pool, batch, next); -+ } -+ -+ QSLIST_INSERT_HEAD(&batch->list, co, pool_next); -+ batch->size++; - } - - Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque) -@@ -58,31 +219,7 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque) - Coroutine *co = NULL; - - if (IS_ENABLED(CONFIG_COROUTINE_POOL)) { -- CoroutineQSList *alloc_pool = get_ptr_alloc_pool(); -- -- co = QSLIST_FIRST(alloc_pool); -- if (!co) { -- if (release_pool_size > POOL_MIN_BATCH_SIZE) { -- /* Slow path; a good place to register the destructor, too. */ -- Notifier *notifier = get_ptr_coroutine_pool_cleanup_notifier(); -- if (!notifier->notify) { -- notifier->notify = coroutine_pool_cleanup; -- qemu_thread_atexit_add(notifier); -- } -- -- /* This is not exact; there could be a little skew between -- * release_pool_size and the actual size of release_pool. But -- * it is just a heuristic, it does not need to be perfect. -- */ -- set_alloc_pool_size(qatomic_xchg(&release_pool_size, 0)); -- QSLIST_MOVE_ATOMIC(alloc_pool, &release_pool); -- co = QSLIST_FIRST(alloc_pool); -- } -- } -- if (co) { -- QSLIST_REMOVE_HEAD(alloc_pool, pool_next); -- set_alloc_pool_size(get_alloc_pool_size() - 1); -- } -+ co = coroutine_pool_get(); - } - - if (!co) { -@@ -100,19 +237,10 @@ static void coroutine_delete(Coroutine *co) - co->caller = NULL; - - if (IS_ENABLED(CONFIG_COROUTINE_POOL)) { -- if (release_pool_size < qatomic_read(&pool_max_size) * 2) { -- QSLIST_INSERT_HEAD_ATOMIC(&release_pool, co, pool_next); -- qatomic_inc(&release_pool_size); -- return; -- } -- if (get_alloc_pool_size() < qatomic_read(&pool_max_size)) { -- QSLIST_INSERT_HEAD(get_ptr_alloc_pool(), co, pool_next); -- set_alloc_pool_size(get_alloc_pool_size() + 1); -- return; -- } -+ coroutine_pool_put(co); -+ } else { -+ qemu_coroutine_delete(co); - } -- -- qemu_coroutine_delete(co); - } - - void qemu_aio_coroutine_enter(AioContext *ctx, Coroutine *co) -@@ -223,10 +351,46 @@ AioContext *qemu_coroutine_get_aio_context(Coroutine *co) - - void qemu_coroutine_inc_pool_size(unsigned int additional_pool_size) - { -- qatomic_add(&pool_max_size, additional_pool_size); -+ QEMU_LOCK_GUARD(&global_pool_lock); -+ global_pool_max_size += additional_pool_size; - } - - void qemu_coroutine_dec_pool_size(unsigned int removing_pool_size) - { -- qatomic_sub(&pool_max_size, removing_pool_size); -+ QEMU_LOCK_GUARD(&global_pool_lock); -+ global_pool_max_size -= removing_pool_size; -+} -+ -+static unsigned int get_global_pool_hard_max_size(void) -+{ -+#ifdef __linux__ -+ g_autofree char *contents = NULL; -+ int max_map_count; -+ -+ /* -+ * Linux processes can have up to max_map_count virtual memory areas -+ * (VMAs). mmap(2), mprotect(2), etc fail with ENOMEM beyond this limit. We -+ * must limit the coroutine pool to a safe size to avoid running out of -+ * VMAs. -+ */ -+ if (g_file_get_contents("/proc/sys/vm/max_map_count", &contents, NULL, -+ NULL) && -+ qemu_strtoi(contents, NULL, 10, &max_map_count) == 0) { -+ /* -+ * This is a conservative upper bound that avoids exceeding -+ * max_map_count. Leave half for non-coroutine users like library -+ * dependencies, vhost-user, etc. Each coroutine takes up 2 VMAs so -+ * halve the amount again. -+ */ -+ return max_map_count / 4; -+ } -+#endif -+ -+ return UINT_MAX; -+} -+ -+static void __attribute__((constructor)) qemu_coroutine_init(void) -+{ -+ qemu_mutex_init(&global_pool_lock); -+ global_pool_hard_max_size = get_global_pool_hard_max_size(); - } --- -2.39.3 - diff --git a/kvm-coroutine-reserve-5-000-mappings.patch b/kvm-coroutine-reserve-5-000-mappings.patch deleted file mode 100644 index cdbb666..0000000 --- a/kvm-coroutine-reserve-5-000-mappings.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0aa65dc3acba481f7064df936ab49e3bceb1d5bd Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 20 Mar 2024 14:12:32 -0400 -Subject: [PATCH 2/2] coroutine: reserve 5,000 mappings -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 234: coroutine: cap per-thread local pool size -RH-Jira: RHEL-28947 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [2/2] 78560c2b947471111cc16c313d6f38db42860a1c (stefanha/centos-stream-qemu-kvm) - -Daniel P. Berrangé pointed out that the coroutine -pool size heuristic is very conservative. Instead of halving -max_map_count, he suggested reserving 5,000 mappings for non-coroutine -users based on observations of guests he has access to. - -Fixes: 86a637e48104 ("coroutine: cap per-thread local pool size") -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Daniel P. Berrangé -Message-id: 20240320181232.1464819-1-stefanha@redhat.com -Signed-off-by: Stefan Hajnoczi -(cherry picked from commit 9352f80cd926fe2dde7c89b93ee33bb0356ff40e) -Signed-off-by: Stefan Hajnoczi ---- - util/qemu-coroutine.c | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - -diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c -index 2790959eaf..eb4eebefdf 100644 ---- a/util/qemu-coroutine.c -+++ b/util/qemu-coroutine.c -@@ -377,12 +377,17 @@ static unsigned int get_global_pool_hard_max_size(void) - NULL) && - qemu_strtoi(contents, NULL, 10, &max_map_count) == 0) { - /* -- * This is a conservative upper bound that avoids exceeding -- * max_map_count. Leave half for non-coroutine users like library -- * dependencies, vhost-user, etc. Each coroutine takes up 2 VMAs so -- * halve the amount again. -+ * This is an upper bound that avoids exceeding max_map_count. Leave a -+ * fixed amount for non-coroutine users like library dependencies, -+ * vhost-user, etc. Each coroutine takes up 2 VMAs so halve the -+ * remaining amount. - */ -- return max_map_count / 4; -+ if (max_map_count > 5000) { -+ return (max_map_count - 5000) / 2; -+ } else { -+ /* Disable the global pool but threads still have local pools */ -+ return 0; -+ } - } - #endif - --- -2.39.3 - diff --git a/kvm-dma-helpers-don-t-lock-AioContext-in-dma_blk_cb.patch b/kvm-dma-helpers-don-t-lock-AioContext-in-dma_blk_cb.patch deleted file mode 100644 index 735f2a3..0000000 --- a/kvm-dma-helpers-don-t-lock-AioContext-in-dma_blk_cb.patch +++ /dev/null @@ -1,75 +0,0 @@ -From ac9dc8ea241ef6d3a0447d696620d4d4053b71bf Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 4 Dec 2023 11:42:59 -0500 -Subject: [PATCH 080/101] dma-helpers: don't lock AioContext in dma_blk_cb() - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [11/26] a8580463ba6aee4ca248c0b947b9e72bd9e87aab (kmwolf/centos-qemu-kvm) - -Commit abfcd2760b3e ("dma-helpers: prevent dma_blk_cb() vs -dma_aio_cancel() race") acquired the AioContext lock inside dma_blk_cb() -to avoid a race with scsi_device_purge_requests() running in the main -loop thread. - -The SCSI code no longer calls dma_aio_cancel() from the main loop thread -while I/O is running in the IOThread AioContext. Therefore it is no -longer necessary to take this lock to protect DMAAIOCB fields. The -->cb() function also does not require the lock because blk_aio_*() and -friends do not need the AioContext lock. - -Both hw/ide/core.c and hw/ide/macio.c also call dma_blk_io() but don't -rely on it taking the AioContext lock, so this change is safe. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Reviewed-by: Kevin Wolf -Message-ID: <20231204164259.1515217-5-stefanha@redhat.com> -Signed-off-by: Kevin Wolf ---- - system/dma-helpers.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/system/dma-helpers.c b/system/dma-helpers.c -index 36211acc7e..528117f256 100644 ---- a/system/dma-helpers.c -+++ b/system/dma-helpers.c -@@ -119,13 +119,12 @@ static void dma_blk_cb(void *opaque, int ret) - - trace_dma_blk_cb(dbs, ret); - -- aio_context_acquire(ctx); - dbs->acb = NULL; - dbs->offset += dbs->iov.size; - - if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) { - dma_complete(dbs, ret); -- goto out; -+ return; - } - dma_blk_unmap(dbs); - -@@ -168,7 +167,7 @@ static void dma_blk_cb(void *opaque, int ret) - trace_dma_map_wait(dbs); - dbs->bh = aio_bh_new(ctx, reschedule_dma, dbs); - cpu_register_map_client(dbs->bh); -- goto out; -+ return; - } - - if (!QEMU_IS_ALIGNED(dbs->iov.size, dbs->align)) { -@@ -179,8 +178,6 @@ static void dma_blk_cb(void *opaque, int ret) - dbs->acb = dbs->io_func(dbs->offset, &dbs->iov, - dma_blk_cb, dbs, dbs->io_func_opaque); - assert(dbs->acb); --out: -- aio_context_release(ctx); - } - - static void dma_aio_cancel(BlockAIOCB *acb) --- -2.39.3 - diff --git a/kvm-docs-devel-Add-VFIO-iommufd-backend-documentation.patch b/kvm-docs-devel-Add-VFIO-iommufd-backend-documentation.patch deleted file mode 100644 index dbe48d7..0000000 --- a/kvm-docs-devel-Add-VFIO-iommufd-backend-documentation.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 71aa0219f7c84cbf175eb2a091d48d5fd5daa40b Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:26 +0800 -Subject: [PATCH 047/101] docs/devel: Add VFIO iommufd backend documentation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [46/67] 6cf49d00e87788f894d690a985bb6798eae24505 (eauger1/centos-qemu-kvm) - -Suggested-by: Cédric Le Goater -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Zhenzhong Duan -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 98dad2b01931f6064c6c4b48ca3c2a1d9f542cd8) -Signed-off-by: Eric Auger ---- - MAINTAINERS | 1 + - docs/devel/index-internals.rst | 1 + - docs/devel/vfio-iommufd.rst | 166 +++++++++++++++++++++++++++++++++ - 3 files changed, 168 insertions(+) - create mode 100644 docs/devel/vfio-iommufd.rst - -diff --git a/MAINTAINERS b/MAINTAINERS -index ca70bb4e64..0ddb20a35f 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2176,6 +2176,7 @@ F: backends/iommufd.c - F: include/sysemu/iommufd.h - F: include/qemu/chardev_open.h - F: util/chardev_open.c -+F: docs/devel/vfio-iommufd.rst - - vhost - M: Michael S. Tsirkin -diff --git a/docs/devel/index-internals.rst b/docs/devel/index-internals.rst -index 6f81df92bc..3def4a138b 100644 ---- a/docs/devel/index-internals.rst -+++ b/docs/devel/index-internals.rst -@@ -18,5 +18,6 @@ Details about QEMU's various subsystems including how to add features to them. - s390-dasd-ipl - tracing - vfio-migration -+ vfio-iommufd - writing-monitor-commands - virtio-backends -diff --git a/docs/devel/vfio-iommufd.rst b/docs/devel/vfio-iommufd.rst -new file mode 100644 -index 0000000000..3d1c11f175 ---- /dev/null -+++ b/docs/devel/vfio-iommufd.rst -@@ -0,0 +1,166 @@ -+=============================== -+IOMMUFD BACKEND usage with VFIO -+=============================== -+ -+(Same meaning for backend/container/BE) -+ -+With the introduction of iommufd, the Linux kernel provides a generic -+interface for user space drivers to propagate their DMA mappings to kernel -+for assigned devices. While the legacy kernel interface is group-centric, -+the new iommufd interface is device-centric, relying on device fd and iommufd. -+ -+To support both interfaces in the QEMU VFIO device, introduce a base container -+to abstract the common part of VFIO legacy and iommufd container. So that the -+generic VFIO code can use either container. -+ -+The base container implements generic functions such as memory_listener and -+address space management whereas the derived container implements callbacks -+specific to either legacy or iommufd. Each container has its own way to setup -+secure context and dma management interface. The below diagram shows how it -+looks like with both containers. -+ -+:: -+ -+ VFIO AddressSpace/Memory -+ +-------+ +----------+ +-----+ +-----+ -+ | pci | | platform | | ap | | ccw | -+ +---+---+ +----+-----+ +--+--+ +--+--+ +----------------------+ -+ | | | | | AddressSpace | -+ | | | | +------------+---------+ -+ +---V-----------V-----------V--------V----+ / -+ | VFIOAddressSpace | <------------+ -+ | | | MemoryListener -+ | VFIOContainerBase list | -+ +-------+----------------------------+----+ -+ | | -+ | | -+ +-------V------+ +--------V----------+ -+ | iommufd | | vfio legacy | -+ | container | | container | -+ +-------+------+ +--------+----------+ -+ | | -+ | /dev/iommu | /dev/vfio/vfio -+ | /dev/vfio/devices/vfioX | /dev/vfio/$group_id -+ Userspace | | -+ ============+============================+=========================== -+ Kernel | device fd | -+ +---------------+ | group/container fd -+ | (BIND_IOMMUFD | | (SET_CONTAINER/SET_IOMMU) -+ | ATTACH_IOAS) | | device fd -+ | | | -+ | +-------V------------V-----------------+ -+ iommufd | | vfio | -+ (map/unmap | +---------+--------------------+-------+ -+ ioas_copy) | | | map/unmap -+ | | | -+ +------V------+ +-----V------+ +------V--------+ -+ | iommfd core | | device | | vfio iommu | -+ +-------------+ +------------+ +---------------+ -+ -+* Secure Context setup -+ -+ - iommufd BE: uses device fd and iommufd to setup secure context -+ (bind_iommufd, attach_ioas) -+ - vfio legacy BE: uses group fd and container fd to setup secure context -+ (set_container, set_iommu) -+ -+* Device access -+ -+ - iommufd BE: device fd is opened through ``/dev/vfio/devices/vfioX`` -+ - vfio legacy BE: device fd is retrieved from group fd ioctl -+ -+* DMA Mapping flow -+ -+ 1. VFIOAddressSpace receives MemoryRegion add/del via MemoryListener -+ 2. VFIO populates DMA map/unmap via the container BEs -+ * iommufd BE: uses iommufd -+ * vfio legacy BE: uses container fd -+ -+Example configuration -+===================== -+ -+Step 1: configure the host device -+--------------------------------- -+ -+It's exactly same as the VFIO device with legacy VFIO container. -+ -+Step 2: configure QEMU -+---------------------- -+ -+Interactions with the ``/dev/iommu`` are abstracted by a new iommufd -+object (compiled in with the ``CONFIG_IOMMUFD`` option). -+ -+Any QEMU device (e.g. VFIO device) wishing to use ``/dev/iommu`` must -+be linked with an iommufd object. It gets a new optional property -+named iommufd which allows to pass an iommufd object. Take ``vfio-pci`` -+device for example: -+ -+.. code-block:: bash -+ -+ -object iommufd,id=iommufd0 -+ -device vfio-pci,host=0000:02:00.0,iommufd=iommufd0 -+ -+Note the ``/dev/iommu`` and VFIO cdev can be externally opened by a -+management layer. In such a case the fd is passed, the fd supports a -+string naming the fd or a number, for example: -+ -+.. code-block:: bash -+ -+ -object iommufd,id=iommufd0,fd=22 -+ -device vfio-pci,iommufd=iommufd0,fd=23 -+ -+If the ``fd`` property is not passed, the fd is opened by QEMU. -+ -+If no ``iommufd`` object is passed to the ``vfio-pci`` device, iommufd -+is not used and the user gets the behavior based on the legacy VFIO -+container: -+ -+.. code-block:: bash -+ -+ -device vfio-pci,host=0000:02:00.0 -+ -+Supported platform -+================== -+ -+Supports x86, ARM and s390x currently. -+ -+Caveats -+======= -+ -+Dirty page sync -+--------------- -+ -+Dirty page sync with iommufd backend is unsupported yet, live migration is -+disabled by default. But it can be force enabled like below, low efficient -+though. -+ -+.. code-block:: bash -+ -+ -object iommufd,id=iommufd0 -+ -device vfio-pci,host=0000:02:00.0,iommufd=iommufd0,enable-migration=on -+ -+P2P DMA -+------- -+ -+PCI p2p DMA is unsupported as IOMMUFD doesn't support mapping hardware PCI -+BAR region yet. Below warning shows for assigned PCI device, it's not a bug. -+ -+.. code-block:: none -+ -+ qemu-system-x86_64: warning: IOMMU_IOAS_MAP failed: Bad address, PCI BAR? -+ qemu-system-x86_64: vfio_container_dma_map(0x560cb6cb1620, 0xe000000021000, 0x3000, 0x7f32ed55c000) = -14 (Bad address) -+ -+FD passing with mdev -+-------------------- -+ -+``vfio-pci`` device checks sysfsdev property to decide if backend is a mdev. -+If FD passing is used, there is no way to know that and the mdev is treated -+like a real PCI device. There is an error as below if user wants to enable -+RAM discarding for mdev. -+ -+.. code-block:: none -+ -+ qemu-system-x86_64: -device vfio-pci,iommufd=iommufd0,x-balloon-allowed=on,fd=9: vfio VFIO_FD9: x-balloon-allowed only potentially compatible with mdev devices -+ -+``vfio-ap`` and ``vfio-ccw`` devices don't have same issue as their backend -+devices are always mdev and RAM discarding is force enabled. --- -2.39.3 - diff --git a/kvm-docs-remove-AioContext-lock-from-IOThread-docs.patch b/kvm-docs-remove-AioContext-lock-from-IOThread-docs.patch deleted file mode 100644 index 80adc69..0000000 --- a/kvm-docs-remove-AioContext-lock-from-IOThread-docs.patch +++ /dev/null @@ -1,98 +0,0 @@ -From fc69df3a70bed5722643cc16828ca20beae3a20d Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:08 -0500 -Subject: [PATCH 091/101] docs: remove AioContext lock from IOThread docs - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [22/26] ab89cda483e74ded983d26e1c6e50217405e0a55 (kmwolf/centos-qemu-kvm) - -Encourage the use of locking primitives and stop mentioning the -AioContext lock since it is being removed. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Message-ID: <20231205182011.1976568-12-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - docs/devel/multiple-iothreads.txt | 47 +++++++++++-------------------- - 1 file changed, 16 insertions(+), 31 deletions(-) - -diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt -index a3e949f6b3..4865196bde 100644 ---- a/docs/devel/multiple-iothreads.txt -+++ b/docs/devel/multiple-iothreads.txt -@@ -88,27 +88,18 @@ loop, depending on which AioContext instance the caller passes in. - - How to synchronize with an IOThread - ----------------------------------- --AioContext is not thread-safe so some rules must be followed when using file --descriptors, event notifiers, timers, or BHs across threads: -+Variables that can be accessed by multiple threads require some form of -+synchronization such as qemu_mutex_lock(), rcu_read_lock(), etc. - --1. AioContext functions can always be called safely. They handle their --own locking internally. -- --2. Other threads wishing to access the AioContext must use --aio_context_acquire()/aio_context_release() for mutual exclusion. Once the --context is acquired no other thread can access it or run event loop iterations --in this AioContext. -- --Legacy code sometimes nests aio_context_acquire()/aio_context_release() calls. --Do not use nesting anymore, it is incompatible with the BDRV_POLL_WHILE() macro --used in the block layer and can lead to hangs. -- --There is currently no lock ordering rule if a thread needs to acquire multiple --AioContexts simultaneously. Therefore, it is only safe for code holding the --QEMU global mutex to acquire other AioContexts. -+AioContext functions like aio_set_fd_handler(), aio_set_event_notifier(), -+aio_bh_new(), and aio_timer_new() are thread-safe. They can be used to trigger -+activity in an IOThread. - - Side note: the best way to schedule a function call across threads is to call --aio_bh_schedule_oneshot(). No acquire/release or locking is needed. -+aio_bh_schedule_oneshot(). -+ -+The main loop thread can wait synchronously for a condition using -+AIO_WAIT_WHILE(). - - AioContext and the block layer - ------------------------------ -@@ -124,22 +115,16 @@ Block layer code must therefore expect to run in an IOThread and avoid using - old APIs that implicitly use the main loop. See the "How to program for - IOThreads" above for information on how to do that. - --If main loop code such as a QMP function wishes to access a BlockDriverState --it must first call aio_context_acquire(bdrv_get_aio_context(bs)) to ensure --that callbacks in the IOThread do not run in parallel. -- - Code running in the monitor typically needs to ensure that past - requests from the guest are completed. When a block device is running - in an IOThread, the IOThread can also process requests from the guest - (via ioeventfd). To achieve both objects, wrap the code between - bdrv_drained_begin() and bdrv_drained_end(), thus creating a "drained --section". The functions must be called between aio_context_acquire() --and aio_context_release(). You can freely release and re-acquire the --AioContext within a drained section. -- --Long-running jobs (usually in the form of coroutines) are best scheduled in --the BlockDriverState's AioContext to avoid the need to acquire/release around --each bdrv_*() call. The functions bdrv_add/remove_aio_context_notifier, --or alternatively blk_add/remove_aio_context_notifier if you use BlockBackends, --can be used to get a notification whenever bdrv_try_change_aio_context() moves a -+section". -+ -+Long-running jobs (usually in the form of coroutines) are often scheduled in -+the BlockDriverState's AioContext. The functions -+bdrv_add/remove_aio_context_notifier, or alternatively -+blk_add/remove_aio_context_notifier if you use BlockBackends, can be used to -+get a notification whenever bdrv_try_change_aio_context() moves a - BlockDriverState to a different AioContext. --- -2.39.3 - diff --git a/kvm-graph-lock-remove-AioContext-locking.patch b/kvm-graph-lock-remove-AioContext-locking.patch deleted file mode 100644 index 2fff9ba..0000000 --- a/kvm-graph-lock-remove-AioContext-locking.patch +++ /dev/null @@ -1,1190 +0,0 @@ -From 57d96b5774fab588c6bb6812ef8ef281ffe018d7 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:02 -0500 -Subject: [PATCH 085/101] graph-lock: remove AioContext locking - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [16/26] 9575a8b834aaaa03abaf869e96f0808172e87824 (kmwolf/centos-qemu-kvm) - -Stop acquiring/releasing the AioContext lock in -bdrv_graph_wrlock()/bdrv_graph_unlock() since the lock no longer has any -effect. - -The distinction between bdrv_graph_wrunlock() and -bdrv_graph_wrunlock_ctx() becomes meaningless and they can be collapsed -into one function. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Reviewed-by: Kevin Wolf -Message-ID: <20231205182011.1976568-6-stefanha@redhat.com> -Signed-off-by: Kevin Wolf ---- - block.c | 50 +++++++++++++++--------------- - block/backup.c | 4 +-- - block/blklogwrites.c | 8 ++--- - block/blkverify.c | 4 +-- - block/block-backend.c | 11 +++---- - block/commit.c | 16 +++++----- - block/graph-lock.c | 44 ++------------------------ - block/mirror.c | 22 ++++++------- - block/qcow2.c | 4 +-- - block/quorum.c | 8 ++--- - block/replication.c | 14 ++++----- - block/snapshot.c | 4 +-- - block/stream.c | 12 +++---- - block/vmdk.c | 20 ++++++------ - blockdev.c | 8 ++--- - blockjob.c | 12 +++---- - include/block/graph-lock.h | 21 ++----------- - scripts/block-coroutine-wrapper.py | 4 +-- - tests/unit/test-bdrv-drain.c | 40 ++++++++++++------------ - tests/unit/test-bdrv-graph-mod.c | 20 ++++++------ - 20 files changed, 133 insertions(+), 193 deletions(-) - -diff --git a/block.c b/block.c -index bfb0861ec6..25e1ebc606 100644 ---- a/block.c -+++ b/block.c -@@ -1708,12 +1708,12 @@ bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name, - open_failed: - bs->drv = NULL; - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - if (bs->file != NULL) { - bdrv_unref_child(bs, bs->file); - assert(!bs->file); - } -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - g_free(bs->opaque); - bs->opaque = NULL; -@@ -3575,9 +3575,9 @@ int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, - - bdrv_ref(drain_bs); - bdrv_drained_begin(drain_bs); -- bdrv_graph_wrlock(backing_hd); -+ bdrv_graph_wrlock(); - ret = bdrv_set_backing_hd_drained(bs, backing_hd, errp); -- bdrv_graph_wrunlock(backing_hd); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(drain_bs); - bdrv_unref(drain_bs); - -@@ -3790,13 +3790,13 @@ BdrvChild *bdrv_open_child(const char *filename, - return NULL; - } - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - ctx = bdrv_get_aio_context(bs); - aio_context_acquire(ctx); - child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, - errp); - aio_context_release(ctx); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - return child; - } -@@ -4650,9 +4650,9 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp) - aio_context_release(ctx); - } - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - tran_commit(tran); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - QTAILQ_FOREACH_REVERSE(bs_entry, bs_queue, entry) { - BlockDriverState *bs = bs_entry->state.bs; -@@ -4669,9 +4669,9 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp) - goto cleanup; - - abort: -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - tran_abort(tran); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) { - if (bs_entry->prepared) { -@@ -4852,12 +4852,12 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state, - } - - bdrv_graph_rdunlock_main_loop(); -- bdrv_graph_wrlock(new_child_bs); -+ bdrv_graph_wrlock(); - - ret = bdrv_set_file_or_backing_noperm(bs, new_child_bs, is_backing, - tran, errp); - -- bdrv_graph_wrunlock_ctx(ctx); -+ bdrv_graph_wrunlock(); - - if (old_ctx != ctx) { - aio_context_release(ctx); -@@ -5209,14 +5209,14 @@ static void bdrv_close(BlockDriverState *bs) - bs->drv = NULL; - } - -- bdrv_graph_wrlock(bs); -+ bdrv_graph_wrlock(); - QLIST_FOREACH_SAFE(child, &bs->children, next, next) { - bdrv_unref_child(bs, child); - } - - assert(!bs->backing); - assert(!bs->file); -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - - g_free(bs->opaque); - bs->opaque = NULL; -@@ -5509,9 +5509,9 @@ int bdrv_drop_filter(BlockDriverState *bs, Error **errp) - bdrv_graph_rdunlock_main_loop(); - - bdrv_drained_begin(child_bs); -- bdrv_graph_wrlock(bs); -+ bdrv_graph_wrlock(); - ret = bdrv_replace_node_common(bs, child_bs, true, true, errp); -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(child_bs); - - return ret; -@@ -5561,7 +5561,7 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, - aio_context_acquire(old_context); - new_context = NULL; - -- bdrv_graph_wrlock(bs_top); -+ bdrv_graph_wrlock(); - - child = bdrv_attach_child_noperm(bs_new, bs_top, "backing", - &child_of_bds, bdrv_backing_role(bs_new), -@@ -5593,7 +5593,7 @@ out: - tran_finalize(tran, ret); - - bdrv_refresh_limits(bs_top, NULL, NULL); -- bdrv_graph_wrunlock(bs_top); -+ bdrv_graph_wrunlock(); - - bdrv_drained_end(bs_top); - bdrv_drained_end(bs_new); -@@ -5620,7 +5620,7 @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs, - bdrv_ref(old_bs); - bdrv_drained_begin(old_bs); - bdrv_drained_begin(new_bs); -- bdrv_graph_wrlock(new_bs); -+ bdrv_graph_wrlock(); - - bdrv_replace_child_tran(child, new_bs, tran); - -@@ -5631,7 +5631,7 @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs, - - tran_finalize(tran, ret); - -- bdrv_graph_wrunlock(new_bs); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(old_bs); - bdrv_drained_end(new_bs); - bdrv_unref(old_bs); -@@ -5718,9 +5718,9 @@ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options, - bdrv_ref(bs); - bdrv_drained_begin(bs); - bdrv_drained_begin(new_node_bs); -- bdrv_graph_wrlock(new_node_bs); -+ bdrv_graph_wrlock(); - ret = bdrv_replace_node(bs, new_node_bs, errp); -- bdrv_graph_wrunlock(new_node_bs); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(new_node_bs); - bdrv_drained_end(bs); - bdrv_unref(bs); -@@ -5975,7 +5975,7 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base, - - bdrv_ref(top); - bdrv_drained_begin(base); -- bdrv_graph_wrlock(base); -+ bdrv_graph_wrlock(); - - if (!top->drv || !base->drv) { - goto exit_wrlock; -@@ -6015,7 +6015,7 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base, - * That's a FIXME. - */ - bdrv_replace_node_common(top, base, false, false, &local_err); -- bdrv_graph_wrunlock(base); -+ bdrv_graph_wrunlock(); - - if (local_err) { - error_report_err(local_err); -@@ -6052,7 +6052,7 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base, - goto exit; - - exit_wrlock: -- bdrv_graph_wrunlock(base); -+ bdrv_graph_wrunlock(); - exit: - bdrv_drained_end(base); - bdrv_unref(top); -diff --git a/block/backup.c b/block/backup.c -index 8aae5836d7..ec29d6b810 100644 ---- a/block/backup.c -+++ b/block/backup.c -@@ -496,10 +496,10 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, - block_copy_set_speed(bcs, speed); - - /* Required permissions are taken by copy-before-write filter target */ -- bdrv_graph_wrlock(target); -+ bdrv_graph_wrlock(); - block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL, - &error_abort); -- bdrv_graph_wrunlock(target); -+ bdrv_graph_wrunlock(); - - return &job->common; - -diff --git a/block/blklogwrites.c b/block/blklogwrites.c -index 3678f6cf42..7207b2e757 100644 ---- a/block/blklogwrites.c -+++ b/block/blklogwrites.c -@@ -251,9 +251,9 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags, - ret = 0; - fail_log: - if (ret < 0) { -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, s->log_file); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - s->log_file = NULL; - } - fail: -@@ -265,10 +265,10 @@ static void blk_log_writes_close(BlockDriverState *bs) - { - BDRVBlkLogWritesState *s = bs->opaque; - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, s->log_file); - s->log_file = NULL; -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - } - - static int64_t coroutine_fn GRAPH_RDLOCK -diff --git a/block/blkverify.c b/block/blkverify.c -index 9b17c46644..ec45d8335e 100644 ---- a/block/blkverify.c -+++ b/block/blkverify.c -@@ -151,10 +151,10 @@ static void blkverify_close(BlockDriverState *bs) - { - BDRVBlkverifyState *s = bs->opaque; - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, s->test_file); - s->test_file = NULL; -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - } - - static int64_t coroutine_fn GRAPH_RDLOCK -diff --git a/block/block-backend.c b/block/block-backend.c -index ec21148806..abac4e0235 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -889,7 +889,6 @@ void blk_remove_bs(BlockBackend *blk) - { - ThrottleGroupMember *tgm = &blk->public.throttle_group_member; - BdrvChild *root; -- AioContext *ctx; - - GLOBAL_STATE_CODE(); - -@@ -919,10 +918,9 @@ void blk_remove_bs(BlockBackend *blk) - root = blk->root; - blk->root = NULL; - -- ctx = bdrv_get_aio_context(root->bs); -- bdrv_graph_wrlock(root->bs); -+ bdrv_graph_wrlock(); - bdrv_root_unref_child(root); -- bdrv_graph_wrunlock_ctx(ctx); -+ bdrv_graph_wrunlock(); - } - - /* -@@ -933,16 +931,15 @@ void blk_remove_bs(BlockBackend *blk) - int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp) - { - ThrottleGroupMember *tgm = &blk->public.throttle_group_member; -- AioContext *ctx = bdrv_get_aio_context(bs); - - GLOBAL_STATE_CODE(); - bdrv_ref(bs); -- bdrv_graph_wrlock(bs); -+ bdrv_graph_wrlock(); - blk->root = bdrv_root_attach_child(bs, "root", &child_root, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - blk->perm, blk->shared_perm, - blk, errp); -- bdrv_graph_wrunlock_ctx(ctx); -+ bdrv_graph_wrunlock(); - if (blk->root == NULL) { - return -EPERM; - } -diff --git a/block/commit.c b/block/commit.c -index 69cc75be0c..1dd7a65ffb 100644 ---- a/block/commit.c -+++ b/block/commit.c -@@ -100,9 +100,9 @@ static void commit_abort(Job *job) - bdrv_graph_rdunlock_main_loop(); - - bdrv_drained_begin(commit_top_backing_bs); -- bdrv_graph_wrlock(commit_top_backing_bs); -+ bdrv_graph_wrlock(); - bdrv_replace_node(s->commit_top_bs, commit_top_backing_bs, &error_abort); -- bdrv_graph_wrunlock(commit_top_backing_bs); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(commit_top_backing_bs); - - bdrv_unref(s->commit_top_bs); -@@ -339,7 +339,7 @@ void commit_start(const char *job_id, BlockDriverState *bs, - * this is the responsibility of the interface (i.e. whoever calls - * commit_start()). - */ -- bdrv_graph_wrlock(top); -+ bdrv_graph_wrlock(); - s->base_overlay = bdrv_find_overlay(top, base); - assert(s->base_overlay); - -@@ -370,19 +370,19 @@ void commit_start(const char *job_id, BlockDriverState *bs, - ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0, - iter_shared_perms, errp); - if (ret < 0) { -- bdrv_graph_wrunlock(top); -+ bdrv_graph_wrunlock(); - goto fail; - } - } - - if (bdrv_freeze_backing_chain(commit_top_bs, base, errp) < 0) { -- bdrv_graph_wrunlock(top); -+ bdrv_graph_wrunlock(); - goto fail; - } - s->chain_frozen = true; - - ret = block_job_add_bdrv(&s->common, "base", base, 0, BLK_PERM_ALL, errp); -- bdrv_graph_wrunlock(top); -+ bdrv_graph_wrunlock(); - - if (ret < 0) { - goto fail; -@@ -434,9 +434,9 @@ fail: - * otherwise this would fail because of lack of permissions. */ - if (commit_top_bs) { - bdrv_drained_begin(top); -- bdrv_graph_wrlock(top); -+ bdrv_graph_wrlock(); - bdrv_replace_node(commit_top_bs, top, &error_abort); -- bdrv_graph_wrunlock(top); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(top); - } - } -diff --git a/block/graph-lock.c b/block/graph-lock.c -index 079e878d9b..c81162b147 100644 ---- a/block/graph-lock.c -+++ b/block/graph-lock.c -@@ -106,27 +106,12 @@ static uint32_t reader_count(void) - return rd; - } - --void no_coroutine_fn bdrv_graph_wrlock(BlockDriverState *bs) -+void no_coroutine_fn bdrv_graph_wrlock(void) - { -- AioContext *ctx = NULL; -- - GLOBAL_STATE_CODE(); - assert(!qatomic_read(&has_writer)); - assert(!qemu_in_coroutine()); - -- /* -- * Release only non-mainloop AioContext. The mainloop often relies on the -- * BQL and doesn't lock the main AioContext before doing things. -- */ -- if (bs) { -- ctx = bdrv_get_aio_context(bs); -- if (ctx != qemu_get_aio_context()) { -- aio_context_release(ctx); -- } else { -- ctx = NULL; -- } -- } -- - /* Make sure that constantly arriving new I/O doesn't cause starvation */ - bdrv_drain_all_begin_nopoll(); - -@@ -155,27 +140,13 @@ void no_coroutine_fn bdrv_graph_wrlock(BlockDriverState *bs) - } while (reader_count() >= 1); - - bdrv_drain_all_end(); -- -- if (ctx) { -- aio_context_acquire(bdrv_get_aio_context(bs)); -- } - } - --void no_coroutine_fn bdrv_graph_wrunlock_ctx(AioContext *ctx) -+void no_coroutine_fn bdrv_graph_wrunlock(void) - { - GLOBAL_STATE_CODE(); - assert(qatomic_read(&has_writer)); - -- /* -- * Release only non-mainloop AioContext. The mainloop often relies on the -- * BQL and doesn't lock the main AioContext before doing things. -- */ -- if (ctx && ctx != qemu_get_aio_context()) { -- aio_context_release(ctx); -- } else { -- ctx = NULL; -- } -- - WITH_QEMU_LOCK_GUARD(&aio_context_list_lock) { - /* - * No need for memory barriers, this works in pair with -@@ -197,17 +168,6 @@ void no_coroutine_fn bdrv_graph_wrunlock_ctx(AioContext *ctx) - * progress. - */ - aio_bh_poll(qemu_get_aio_context()); -- -- if (ctx) { -- aio_context_acquire(ctx); -- } --} -- --void no_coroutine_fn bdrv_graph_wrunlock(BlockDriverState *bs) --{ -- AioContext *ctx = bs ? bdrv_get_aio_context(bs) : NULL; -- -- bdrv_graph_wrunlock_ctx(ctx); - } - - void coroutine_fn bdrv_graph_co_rdlock(void) -diff --git a/block/mirror.c b/block/mirror.c -index cd9d3ad4a8..51f9e2f17c 100644 ---- a/block/mirror.c -+++ b/block/mirror.c -@@ -764,7 +764,7 @@ static int mirror_exit_common(Job *job) - * check for an op blocker on @to_replace, and we have our own - * there. - */ -- bdrv_graph_wrlock(target_bs); -+ bdrv_graph_wrlock(); - if (bdrv_recurse_can_replace(src, to_replace)) { - bdrv_replace_node(to_replace, target_bs, &local_err); - } else { -@@ -773,7 +773,7 @@ static int mirror_exit_common(Job *job) - "would not lead to an abrupt change of visible data", - to_replace->node_name, target_bs->node_name); - } -- bdrv_graph_wrunlock(target_bs); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(to_replace); - if (local_err) { - error_report_err(local_err); -@@ -796,9 +796,9 @@ static int mirror_exit_common(Job *job) - * valid. - */ - block_job_remove_all_bdrv(bjob); -- bdrv_graph_wrlock(mirror_top_bs); -+ bdrv_graph_wrlock(); - bdrv_replace_node(mirror_top_bs, mirror_top_bs->backing->bs, &error_abort); -- bdrv_graph_wrunlock(mirror_top_bs); -+ bdrv_graph_wrunlock(); - - bdrv_drained_end(target_bs); - bdrv_unref(target_bs); -@@ -1914,13 +1914,13 @@ static BlockJob *mirror_start_job( - */ - bdrv_disable_dirty_bitmap(s->dirty_bitmap); - -- bdrv_graph_wrlock(bs); -+ bdrv_graph_wrlock(); - ret = block_job_add_bdrv(&s->common, "source", bs, 0, - BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE | - BLK_PERM_CONSISTENT_READ, - errp); - if (ret < 0) { -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - goto fail; - } - -@@ -1965,17 +1965,17 @@ static BlockJob *mirror_start_job( - ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0, - iter_shared_perms, errp); - if (ret < 0) { -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - goto fail; - } - } - - if (bdrv_freeze_backing_chain(mirror_top_bs, target, errp) < 0) { -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - goto fail; - } - } -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - - QTAILQ_INIT(&s->ops_in_flight); - -@@ -2001,12 +2001,12 @@ fail: - - bs_opaque->stop = true; - bdrv_drained_begin(bs); -- bdrv_graph_wrlock(bs); -+ bdrv_graph_wrlock(); - assert(mirror_top_bs->backing->bs == bs); - bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing, - &error_abort); - bdrv_replace_node(mirror_top_bs, bs, &error_abort); -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(bs); - - bdrv_unref(mirror_top_bs); -diff --git a/block/qcow2.c b/block/qcow2.c -index 7968735346..d91b7b91d3 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -2813,9 +2813,9 @@ qcow2_do_close(BlockDriverState *bs, bool close_data_file) - if (close_data_file && has_data_file(bs)) { - GLOBAL_STATE_CODE(); - bdrv_graph_rdunlock_main_loop(); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, s->data_file); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - s->data_file = NULL; - bdrv_graph_rdlock_main_loop(); - } -diff --git a/block/quorum.c b/block/quorum.c -index 505b8b3e18..db8fe891c4 100644 ---- a/block/quorum.c -+++ b/block/quorum.c -@@ -1037,14 +1037,14 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, - - close_exit: - /* cleanup on error */ -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - for (i = 0; i < s->num_children; i++) { - if (!opened[i]) { - continue; - } - bdrv_unref_child(bs, s->children[i]); - } -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - g_free(s->children); - g_free(opened); - exit: -@@ -1057,11 +1057,11 @@ static void quorum_close(BlockDriverState *bs) - BDRVQuorumState *s = bs->opaque; - int i; - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - for (i = 0; i < s->num_children; i++) { - bdrv_unref_child(bs, s->children[i]); - } -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - g_free(s->children); - } -diff --git a/block/replication.c b/block/replication.c -index 5ded5f1ca9..424b537ff7 100644 ---- a/block/replication.c -+++ b/block/replication.c -@@ -560,7 +560,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - return; - } - -- bdrv_graph_wrlock(bs); -+ bdrv_graph_wrlock(); - - bdrv_ref(hidden_disk->bs); - s->hidden_disk = bdrv_attach_child(bs, hidden_disk->bs, "hidden disk", -@@ -568,7 +568,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - &local_err); - if (local_err) { - error_propagate(errp, local_err); -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - aio_context_release(aio_context); - return; - } -@@ -579,7 +579,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - BDRV_CHILD_DATA, &local_err); - if (local_err) { - error_propagate(errp, local_err); -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - aio_context_release(aio_context); - return; - } -@@ -592,7 +592,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - if (!top_bs || !bdrv_is_root_node(top_bs) || - !check_top_bs(top_bs, bs)) { - error_setg(errp, "No top_bs or it is invalid"); -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - reopen_backing_file(bs, false, NULL); - aio_context_release(aio_context); - return; -@@ -600,7 +600,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, - bdrv_op_block_all(top_bs, s->blocker); - bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker); - -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - - s->backup_job = backup_job_create( - NULL, s->secondary_disk->bs, s->hidden_disk->bs, -@@ -691,12 +691,12 @@ static void replication_done(void *opaque, int ret) - if (ret == 0) { - s->stage = BLOCK_REPLICATION_DONE; - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, s->secondary_disk); - s->secondary_disk = NULL; - bdrv_unref_child(bs, s->hidden_disk); - s->hidden_disk = NULL; -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - s->error = 0; - } else { -diff --git a/block/snapshot.c b/block/snapshot.c -index ec8cf4810b..e486d3e205 100644 ---- a/block/snapshot.c -+++ b/block/snapshot.c -@@ -290,9 +290,9 @@ int bdrv_snapshot_goto(BlockDriverState *bs, - } - - /* .bdrv_open() will re-attach it */ -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, fallback); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp); - open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err); -diff --git a/block/stream.c b/block/stream.c -index 01fe7c0f16..048c2d282f 100644 ---- a/block/stream.c -+++ b/block/stream.c -@@ -99,9 +99,9 @@ static int stream_prepare(Job *job) - } - } - -- bdrv_graph_wrlock(s->target_bs); -+ bdrv_graph_wrlock(); - bdrv_set_backing_hd_drained(unfiltered_bs, base, &local_err); -- bdrv_graph_wrunlock(s->target_bs); -+ bdrv_graph_wrunlock(); - - /* - * This call will do I/O, so the graph can change again from here on. -@@ -366,10 +366,10 @@ void stream_start(const char *job_id, BlockDriverState *bs, - * already have our own plans. Also don't allow resize as the image size is - * queried only at the job start and then cached. - */ -- bdrv_graph_wrlock(bs); -+ bdrv_graph_wrlock(); - if (block_job_add_bdrv(&s->common, "active node", bs, 0, - basic_flags | BLK_PERM_WRITE, errp)) { -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - goto fail; - } - -@@ -389,11 +389,11 @@ void stream_start(const char *job_id, BlockDriverState *bs, - ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0, - basic_flags, errp); - if (ret < 0) { -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - goto fail; - } - } -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - - s->base_overlay = base_overlay; - s->above_base = above_base; -diff --git a/block/vmdk.c b/block/vmdk.c -index d6971c7067..bf78e12383 100644 ---- a/block/vmdk.c -+++ b/block/vmdk.c -@@ -272,7 +272,7 @@ static void vmdk_free_extents(BlockDriverState *bs) - BDRVVmdkState *s = bs->opaque; - VmdkExtent *e; - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - for (i = 0; i < s->num_extents; i++) { - e = &s->extents[i]; - g_free(e->l1_table); -@@ -283,7 +283,7 @@ static void vmdk_free_extents(BlockDriverState *bs) - bdrv_unref_child(bs, e->file); - } - } -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - g_free(s->extents); - } -@@ -1247,9 +1247,9 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options, - 0, 0, 0, 0, 0, &extent, errp); - if (ret < 0) { - bdrv_graph_rdunlock_main_loop(); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, extent_file); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - bdrv_graph_rdlock_main_loop(); - goto out; - } -@@ -1266,9 +1266,9 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options, - g_free(buf); - if (ret) { - bdrv_graph_rdunlock_main_loop(); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, extent_file); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - bdrv_graph_rdlock_main_loop(); - goto out; - } -@@ -1277,9 +1277,9 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options, - ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp); - if (ret) { - bdrv_graph_rdunlock_main_loop(); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, extent_file); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - bdrv_graph_rdlock_main_loop(); - goto out; - } -@@ -1287,9 +1287,9 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options, - } else { - error_setg(errp, "Unsupported extent type '%s'", type); - bdrv_graph_rdunlock_main_loop(); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(bs, extent_file); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - bdrv_graph_rdlock_main_loop(); - ret = -ENOTSUP; - goto out; -diff --git a/blockdev.c b/blockdev.c -index c91f49e7b6..9e1381169d 100644 ---- a/blockdev.c -+++ b/blockdev.c -@@ -1611,9 +1611,9 @@ static void external_snapshot_abort(void *opaque) - } - - bdrv_drained_begin(state->new_bs); -- bdrv_graph_wrlock(state->old_bs); -+ bdrv_graph_wrlock(); - bdrv_replace_node(state->new_bs, state->old_bs, &error_abort); -- bdrv_graph_wrunlock(state->old_bs); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(state->new_bs); - - bdrv_unref(state->old_bs); /* bdrv_replace_node() ref'ed old_bs */ -@@ -3657,7 +3657,7 @@ void qmp_x_blockdev_change(const char *parent, const char *child, - BlockDriverState *parent_bs, *new_bs = NULL; - BdrvChild *p_child; - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - - parent_bs = bdrv_lookup_bs(parent, parent, errp); - if (!parent_bs) { -@@ -3693,7 +3693,7 @@ void qmp_x_blockdev_change(const char *parent, const char *child, - } - - out: -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - } - - BlockJobInfoList *qmp_query_block_jobs(Error **errp) -diff --git a/blockjob.c b/blockjob.c -index b7a29052b9..7310412313 100644 ---- a/blockjob.c -+++ b/blockjob.c -@@ -199,7 +199,7 @@ void block_job_remove_all_bdrv(BlockJob *job) - * to process an already freed BdrvChild. - */ - aio_context_release(job->job.aio_context); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - aio_context_acquire(job->job.aio_context); - while (job->nodes) { - GSList *l = job->nodes; -@@ -212,7 +212,7 @@ void block_job_remove_all_bdrv(BlockJob *job) - - g_slist_free_1(l); - } -- bdrv_graph_wrunlock_ctx(job->job.aio_context); -+ bdrv_graph_wrunlock(); - } - - bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs) -@@ -514,7 +514,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, - int ret; - GLOBAL_STATE_CODE(); - -- bdrv_graph_wrlock(bs); -+ bdrv_graph_wrlock(); - - if (job_id == NULL && !(flags & JOB_INTERNAL)) { - job_id = bdrv_get_device_name(bs); -@@ -523,7 +523,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, - job = job_create(job_id, &driver->job_driver, txn, bdrv_get_aio_context(bs), - flags, cb, opaque, errp); - if (job == NULL) { -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - return NULL; - } - -@@ -563,11 +563,11 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, - goto fail; - } - -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - return job; - - fail: -- bdrv_graph_wrunlock(bs); -+ bdrv_graph_wrunlock(); - job_early_fail(&job->job); - return NULL; - } -diff --git a/include/block/graph-lock.h b/include/block/graph-lock.h -index 22b5db1ed9..d7545e82d0 100644 ---- a/include/block/graph-lock.h -+++ b/include/block/graph-lock.h -@@ -110,34 +110,17 @@ void unregister_aiocontext(AioContext *ctx); - * - * The wrlock can only be taken from the main loop, with BQL held, as only the - * main loop is allowed to modify the graph. -- * -- * If @bs is non-NULL, its AioContext is temporarily released. -- * -- * This function polls. Callers must not hold the lock of any AioContext other -- * than the current one and the one of @bs. - */ - void no_coroutine_fn TSA_ACQUIRE(graph_lock) TSA_NO_TSA --bdrv_graph_wrlock(BlockDriverState *bs); -+bdrv_graph_wrlock(void); - - /* - * bdrv_graph_wrunlock: - * Write finished, reset global has_writer to 0 and restart - * all readers that are waiting. -- * -- * If @bs is non-NULL, its AioContext is temporarily released. -- */ --void no_coroutine_fn TSA_RELEASE(graph_lock) TSA_NO_TSA --bdrv_graph_wrunlock(BlockDriverState *bs); -- --/* -- * bdrv_graph_wrunlock_ctx: -- * Write finished, reset global has_writer to 0 and restart -- * all readers that are waiting. -- * -- * If @ctx is non-NULL, its lock is temporarily released. - */ - void no_coroutine_fn TSA_RELEASE(graph_lock) TSA_NO_TSA --bdrv_graph_wrunlock_ctx(AioContext *ctx); -+bdrv_graph_wrunlock(void); - - /* - * bdrv_graph_co_rdlock: -diff --git a/scripts/block-coroutine-wrapper.py b/scripts/block-coroutine-wrapper.py -index a38e5833fb..38364fa557 100644 ---- a/scripts/block-coroutine-wrapper.py -+++ b/scripts/block-coroutine-wrapper.py -@@ -261,8 +261,8 @@ def gen_no_co_wrapper(func: FuncDecl) -> str: - graph_lock=' bdrv_graph_rdlock_main_loop();' - graph_unlock=' bdrv_graph_rdunlock_main_loop();' - elif func.graph_wrlock: -- graph_lock=' bdrv_graph_wrlock(NULL);' -- graph_unlock=' bdrv_graph_wrunlock(NULL);' -+ graph_lock=' bdrv_graph_wrlock();' -+ graph_unlock=' bdrv_graph_wrunlock();' - - return f"""\ - /* -diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c -index 704d1a3f36..d9754dfebc 100644 ---- a/tests/unit/test-bdrv-drain.c -+++ b/tests/unit/test-bdrv-drain.c -@@ -807,9 +807,9 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, - tjob->bs = src; - job = &tjob->common; - -- bdrv_graph_wrlock(target); -+ bdrv_graph_wrlock(); - block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort); -- bdrv_graph_wrunlock(target); -+ bdrv_graph_wrunlock(); - - switch (result) { - case TEST_JOB_SUCCESS: -@@ -991,11 +991,11 @@ static void bdrv_test_top_close(BlockDriverState *bs) - { - BdrvChild *c, *next_c; - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { - bdrv_unref_child(bs, c); - } -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - } - - static int coroutine_fn GRAPH_RDLOCK -@@ -1085,10 +1085,10 @@ static void do_test_delete_by_drain(bool detach_instead_of_delete, - - null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, - &error_abort); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, - BDRV_CHILD_DATA, &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - /* This child will be the one to pass to requests through to, and - * it will stall until a drain occurs */ -@@ -1096,21 +1096,21 @@ static void do_test_delete_by_drain(bool detach_instead_of_delete, - &error_abort); - child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS; - /* Takes our reference to child_bs */ -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child", - &child_of_bds, - BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY, - &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - /* This child is just there to be deleted - * (for detach_instead_of_delete == true) */ - null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, - &error_abort); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, BDRV_CHILD_DATA, - &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); - blk_insert_bs(blk, bs, &error_abort); -@@ -1193,14 +1193,14 @@ static void no_coroutine_fn detach_indirect_bh(void *opaque) - - bdrv_dec_in_flight(data->child_b->bs); - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_unref_child(data->parent_b, data->child_b); - - bdrv_ref(data->c); - data->child_c = bdrv_attach_child(data->parent_b, data->c, "PB-C", - &child_of_bds, BDRV_CHILD_DATA, - &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - } - - static void coroutine_mixed_fn detach_by_parent_aio_cb(void *opaque, int ret) -@@ -1298,7 +1298,7 @@ static void TSA_NO_TSA test_detach_indirect(bool by_parent_cb) - /* Set child relationships */ - bdrv_ref(b); - bdrv_ref(a); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_of_bds, - BDRV_CHILD_DATA, &error_abort); - child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds, -@@ -1308,7 +1308,7 @@ static void TSA_NO_TSA test_detach_indirect(bool by_parent_cb) - bdrv_attach_child(parent_a, a, "PA-A", - by_parent_cb ? &child_of_bds : &detach_by_driver_cb_class, - BDRV_CHILD_DATA, &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - g_assert_cmpint(parent_a->refcnt, ==, 1); - g_assert_cmpint(parent_b->refcnt, ==, 1); -@@ -1727,7 +1727,7 @@ static void test_drop_intermediate_poll(void) - * Establish the chain last, so the chain links are the first - * elements in the BDS.parents lists - */ -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - for (i = 0; i < 3; i++) { - if (i) { - /* Takes the reference to chain[i - 1] */ -@@ -1735,7 +1735,7 @@ static void test_drop_intermediate_poll(void) - &chain_child_class, BDRV_CHILD_COW, &error_abort); - } - } -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - job = block_job_create("job", &test_simple_job_driver, NULL, job_node, - 0, BLK_PERM_ALL, 0, 0, NULL, NULL, &error_abort); -@@ -1982,10 +1982,10 @@ static void do_test_replace_child_mid_drain(int old_drain_count, - new_child_bs->total_sectors = 1; - - bdrv_ref(old_child_bs); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_attach_child(parent_bs, old_child_bs, "child", &child_of_bds, - BDRV_CHILD_COW, &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - parent_s->setup_completed = true; - - for (i = 0; i < old_drain_count; i++) { -@@ -2016,9 +2016,9 @@ static void do_test_replace_child_mid_drain(int old_drain_count, - g_assert(parent_bs->quiesce_counter == old_drain_count); - bdrv_drained_begin(old_child_bs); - bdrv_drained_begin(new_child_bs); -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_replace_node(old_child_bs, new_child_bs, &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - bdrv_drained_end(new_child_bs); - bdrv_drained_end(old_child_bs); - g_assert(parent_bs->quiesce_counter == new_drain_count); -diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c -index 074adcbb93..8ee6ef38d8 100644 ---- a/tests/unit/test-bdrv-graph-mod.c -+++ b/tests/unit/test-bdrv-graph-mod.c -@@ -137,10 +137,10 @@ static void test_update_perm_tree(void) - - blk_insert_bs(root, bs, &error_abort); - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_attach_child(filter, bs, "child", &child_of_bds, - BDRV_CHILD_DATA, &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - aio_context_acquire(qemu_get_aio_context()); - ret = bdrv_append(filter, bs, NULL); -@@ -206,11 +206,11 @@ static void test_should_update_child(void) - - bdrv_set_backing_hd(target, bs, &error_abort); - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - g_assert(target->backing->bs == bs); - bdrv_attach_child(filter, target, "target", &child_of_bds, - BDRV_CHILD_DATA, &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - aio_context_acquire(qemu_get_aio_context()); - bdrv_append(filter, bs, &error_abort); - aio_context_release(qemu_get_aio_context()); -@@ -248,7 +248,7 @@ static void test_parallel_exclusive_write(void) - bdrv_ref(base); - bdrv_ref(fl1); - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_attach_child(top, fl1, "backing", &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - &error_abort); -@@ -260,7 +260,7 @@ static void test_parallel_exclusive_write(void) - &error_abort); - - bdrv_replace_node(fl1, fl2, &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - bdrv_drained_end(fl2); - bdrv_drained_end(fl1); -@@ -367,7 +367,7 @@ static void test_parallel_perm_update(void) - */ - bdrv_ref(base); - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_attach_child(top, ws, "file", &child_of_bds, BDRV_CHILD_DATA, - &error_abort); - c_fl1 = bdrv_attach_child(ws, fl1, "first", &child_of_bds, -@@ -380,7 +380,7 @@ static void test_parallel_perm_update(void) - bdrv_attach_child(fl2, base, "backing", &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - /* Select fl1 as first child to be active */ - s->selected = c_fl1; -@@ -434,11 +434,11 @@ static void test_append_greedy_filter(void) - BlockDriverState *base = no_perm_node("base"); - BlockDriverState *fl = exclusive_writer_node("fl1"); - -- bdrv_graph_wrlock(NULL); -+ bdrv_graph_wrlock(); - bdrv_attach_child(top, base, "backing", &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - &error_abort); -- bdrv_graph_wrunlock(NULL); -+ bdrv_graph_wrunlock(); - - aio_context_acquire(qemu_get_aio_context()); - bdrv_append(fl, base, &error_abort); --- -2.39.3 - diff --git a/kvm-hv-balloon-use-get_min_alignment-to-express-32-GiB-a.patch b/kvm-hv-balloon-use-get_min_alignment-to-express-32-GiB-a.patch deleted file mode 100644 index 4fb4844..0000000 --- a/kvm-hv-balloon-use-get_min_alignment-to-express-32-GiB-a.patch +++ /dev/null @@ -1,94 +0,0 @@ -From a5b4eec5f456b1ca3fe753e1d76f96cf3f8914ef Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Wed, 17 Jan 2024 14:55:53 +0100 -Subject: [PATCH 01/22] hv-balloon: use get_min_alignment() to express 32 GiB - alignment - -RH-Author: David Hildenbrand -RH-MergeRequest: 221: memory-device: reintroduce memory region size check -RH-Jira: RHEL-20341 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Igor Mammedov -RH-Commit: [1/2] cbe092fe549552928270892253b31cd8fe199825 - -https://issues.redhat.com/browse/RHEL-20341 - -Let's implement the get_min_alignment() callback for memory devices, and -copy for the device memory region the alignment of the host memory -region. This mimics what virtio-mem does, and allows for re-introducing -proper alignment checks for the memory region size (where we don't care -about additional device requirements) in memory device core. - -Message-ID: <20240117135554.787344-2-david@redhat.com> -Reviewed-by: Maciej S. Szmigiero -Signed-off-by: David Hildenbrand -(cherry picked from commit f77c5f38f49c71bc14cf1019ac92b0b95f572414) -Signed-off-by: David Hildenbrand ---- - hw/hyperv/hv-balloon.c | 37 +++++++++++++++++++++---------------- - 1 file changed, 21 insertions(+), 16 deletions(-) - -diff --git a/hw/hyperv/hv-balloon.c b/hw/hyperv/hv-balloon.c -index 66f297c1d7..0829c495b0 100644 ---- a/hw/hyperv/hv-balloon.c -+++ b/hw/hyperv/hv-balloon.c -@@ -1476,22 +1476,7 @@ static void hv_balloon_ensure_mr(HvBalloon *balloon) - balloon->mr = g_new0(MemoryRegion, 1); - memory_region_init(balloon->mr, OBJECT(balloon), TYPE_HV_BALLOON, - memory_region_size(hostmem_mr)); -- -- /* -- * The VM can indicate an alignment up to 32 GiB. Memory device core can -- * usually only handle/guarantee 1 GiB alignment. The user will have to -- * specify a larger maxmem eventually. -- * -- * The memory device core will warn the user in case maxmem might have to be -- * increased and will fail plugging the device if there is not sufficient -- * space after alignment. -- * -- * TODO: we could do the alignment ourselves in a slightly bigger region. -- * But this feels better, although the warning might be annoying. Maybe -- * we can optimize that in the future (e.g., with such a device on the -- * cmdline place/size the device memory region differently. -- */ -- balloon->mr->align = MAX(32 * GiB, memory_region_get_alignment(hostmem_mr)); -+ balloon->mr->align = memory_region_get_alignment(hostmem_mr); - } - - static void hv_balloon_free_mr(HvBalloon *balloon) -@@ -1653,6 +1638,25 @@ static MemoryRegion *hv_balloon_md_get_memory_region(MemoryDeviceState *md, - return balloon->mr; - } - -+static uint64_t hv_balloon_md_get_min_alignment(const MemoryDeviceState *md) -+{ -+ /* -+ * The VM can indicate an alignment up to 32 GiB. Memory device core can -+ * usually only handle/guarantee 1 GiB alignment. The user will have to -+ * specify a larger maxmem eventually. -+ * -+ * The memory device core will warn the user in case maxmem might have to be -+ * increased and will fail plugging the device if there is not sufficient -+ * space after alignment. -+ * -+ * TODO: we could do the alignment ourselves in a slightly bigger region. -+ * But this feels better, although the warning might be annoying. Maybe -+ * we can optimize that in the future (e.g., with such a device on the -+ * cmdline place/size the device memory region differently. -+ */ -+ return 32 * GiB; -+} -+ - static void hv_balloon_md_fill_device_info(const MemoryDeviceState *md, - MemoryDeviceInfo *info) - { -@@ -1765,5 +1769,6 @@ static void hv_balloon_class_init(ObjectClass *klass, void *data) - mdc->get_memory_region = hv_balloon_md_get_memory_region; - mdc->decide_memslots = hv_balloon_decide_memslots; - mdc->get_memslots = hv_balloon_get_memslots; -+ mdc->get_min_alignment = hv_balloon_md_get_min_alignment; - mdc->fill_device_info = hv_balloon_md_fill_device_info; - } --- -2.39.3 - diff --git a/kvm-hw-arm-Activate-IOMMUFD-for-virt-machines.patch b/kvm-hw-arm-Activate-IOMMUFD-for-virt-machines.patch deleted file mode 100644 index 84f6108..0000000 --- a/kvm-hw-arm-Activate-IOMMUFD-for-virt-machines.patch +++ /dev/null @@ -1,42 +0,0 @@ -From ceaee9c4372bbdc4196cb6808515047388f7aa26 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 21 Nov 2023 16:44:18 +0800 -Subject: [PATCH 039/101] hw/arm: Activate IOMMUFD for virt machines -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [38/67] 0a059ae661616e95eb8455e17f35774495cae8e7 (eauger1/centos-qemu-kvm) - -Signed-off-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Eric Auger -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 0970238343af45a8b547695bfc22f18d4eb7da7e) -Signed-off-by: Eric Auger ---- - hw/arm/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig -index 3ada335a24..660f49db49 100644 ---- a/hw/arm/Kconfig -+++ b/hw/arm/Kconfig -@@ -8,6 +8,7 @@ config ARM_VIRT - imply TPM_TIS_SYSBUS - imply TPM_TIS_I2C - imply NVDIMM -+ imply IOMMUFD - select ARM_GIC - select ACPI - select ARM_SMMUV3 --- -2.39.3 - diff --git a/kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch b/kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch deleted file mode 100644 index 76ab341..0000000 --- a/kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch +++ /dev/null @@ -1,88 +0,0 @@ -From e670722b9a6460d41497688d820d5a9a9b51d8e9 Mon Sep 17 00:00:00 2001 -From: Gavin Shan -Date: Tue, 9 Jan 2024 11:36:42 +1000 -Subject: [PATCH 001/101] hw/arm/virt: Add properties to disable high memory - regions - -RH-Author: Gavin Shan -RH-MergeRequest: 210: hw/arm/virt: Add properties to disable high memory regions -RH-Jira: RHEL-19738 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Eric Auger -RH-Commit: [1/1] 4097ba5133a67126e30b84202cb40df4e019c5f4 - -Upstream: RHEL-only -Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=57927352 - -There are 3 high memory regions for GICv3 or GICv4 redistributor, PCI -ECAM and PCI MMIO. Each of them has a property introduced by upstream -commit 6a48c64eec ("hw/arm/virt: Add properties to disable high memory -regions") so that the corresponding high memory region can be disabled. - -It's notable that another property ("compact-highmem") introduced by -upstream commit f40408a9fe ("hw/arm/virt: Add 'compact-highmem' property") -so that the compact high memory region layout during assignment can be -disabled, compatible to the old machine types. However, we don't have -the compatible issue since the compact high memory region layout is -always kept as disabled until RHEL9.2.0 machine type and onwards. - -Expose those 3 properties: "highmem-redists", "highmem-ecam" and -"highmem-mmio". The property "compact-highmem" is kept as hidden. - -Signed-off-by: Gavin Shan ---- - hw/arm/virt.c | 24 +++++++++++++++++++++++- - 1 file changed, 23 insertions(+), 1 deletion(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 5cab00b4cd..60f117f0d2 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -2456,6 +2456,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp) - - vms->highmem_compact = value; - } -+#endif /* disabled for RHEL */ - - static bool virt_get_highmem_redists(Object *obj, Error **errp) - { -@@ -2498,7 +2499,6 @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp) - - vms->highmem_mmio = value; - } --#endif /* disabled for RHEL */ - - static bool virt_get_its(Object *obj, Error **errp) - { -@@ -3521,6 +3521,28 @@ static void rhel_machine_class_init(ObjectClass *oc, void *data) - "Set on/off to enable/disable using " - "physical address space above 32 bits"); - -+ object_class_property_add_bool(oc, "highmem-redists", -+ virt_get_highmem_redists, -+ virt_set_highmem_redists); -+ object_class_property_set_description(oc, "highmem-redists", -+ "Set on/off to enable/disable high " -+ "memory region for GICv3 or GICv4 " -+ "redistributor"); -+ -+ object_class_property_add_bool(oc, "highmem-ecam", -+ virt_get_highmem_ecam, -+ virt_set_highmem_ecam); -+ object_class_property_set_description(oc, "highmem-ecam", -+ "Set on/off to enable/disable high " -+ "memory region for PCI ECAM"); -+ -+ object_class_property_add_bool(oc, "highmem-mmio", -+ virt_get_highmem_mmio, -+ virt_set_highmem_mmio); -+ object_class_property_set_description(oc, "highmem-mmio", -+ "Set on/off to enable/disable high " -+ "memory region for PCI MMIO"); -+ - object_class_property_add_str(oc, "gic-version", virt_get_gic_version, - virt_set_gic_version); - object_class_property_set_description(oc, "gic-version", --- -2.39.3 - diff --git a/kvm-hw-arm-virt-Fix-compats.patch b/kvm-hw-arm-virt-Fix-compats.patch deleted file mode 100644 index 7e3af18..0000000 --- a/kvm-hw-arm-virt-Fix-compats.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 3f58194f8642a71c47d91d3c00a34faf44ea2c11 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Wed, 3 Jan 2024 05:57:38 -0500 -Subject: [PATCH] hw/arm/virt: Fix compats - -RH-Author: Eric Auger -RH-MergeRequest: 209: hw/arm/virt: Fix compats -RH-Jira: RHEL-17168 -RH-Acked-by: Gavin Shan -RH-Acked-by: Sebastian Ott -RH-Commit: [1/1] bcdf6493bbd6d7b52b0b88ff44441d22aeddfde2 (eauger1/centos-qemu-kvm) - -arm_rhel_compat is not added for virt-rhel9.4.0 machine causing -the efi-virtio.rom to be looked for when instantiating a virtio-net-pci -device and it won't be found since not shipped on ARM. This is a -regression compared to 9.2. - -Actually we do not need any rom file for any virtio-net-pci variant -because edk2 already brings the functionality. So for 9.4 onwards, we -want to set romfiles to "" for all of them. - -However at the moment we apply arm_rhel_compat from the latest -rhel*_virt_options(). This is not aligned with the generic compat -usage which sets compats for a given machine type to accomodate for -changes that occured after its advent. Here we are somehow abusing -the compat infra to set general driver options that should apply for -all machines. On top of that this is really error prone and we have -forgotten to add arm_rhel_compat several times in the past. - -So let's introduce set_arm_rhel_compat() being called before any -*virt_options in the non abstract machine class. That way the setting -will apply to any machine type without any need to add it in any -future machine types. - -For < 9.4 machines we don't really care keeping non void romfiles -for transitional and non transitional devices because anyway this was -not working. So let's keep things simple and apply the new defaults for -all RHEL9 machine types. - -Finally, to follow the generic pattern we should set hw_compat_rhel_9_0 -in 9.0 machine as it is done on x86 or ccw. This has no consequence on -aarch64 because it only contains x86 stuff but that helps understanding -the consistency. - -Signed-off-by: Eric Auger ---- - hw/arm/virt.c | 43 +++++++++++++++++++++++++++++-------------- - 1 file changed, 29 insertions(+), 14 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 0b17c94ad7..5cab00b4cd 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -111,11 +111,39 @@ - DEFINE_VIRT_MACHINE_LATEST(major, minor, false) - #endif /* disabled for RHEL */ - -+/* -+ * This variable is for changes to properties that are RHEL specific, -+ * different to the current upstream and to be applied to the latest -+ * machine type. They may be overriden by older machine compats. -+ * -+ * virtio-net-pci variant romfiles are not needed because edk2 does -+ * fully support the pxe boot. Besides virtio romfiles are not shipped -+ * on rhel/aarch64. -+ */ -+GlobalProperty arm_rhel_compat[] = { -+ {"virtio-net-pci", "romfile", "" }, -+ {"virtio-net-pci-transitional", "romfile", "" }, -+ {"virtio-net-pci-non-transitional", "romfile", "" }, -+}; -+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); -+ -+/* -+ * This cannot be called from the rhel_virt_class_init() because -+ * TYPE_RHEL_MACHINE is abstract and mc->compat_props g_ptr_array_new() -+ * only is called on virt-rhelm.n.s non abstract class init. -+ */ -+static void arm_rhel_compat_set(MachineClass *mc) -+{ -+ compat_props_add(mc->compat_props, arm_rhel_compat, -+ arm_rhel_compat_len); -+} -+ - #define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \ - static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \ - void *data) \ - { \ - MachineClass *mc = MACHINE_CLASS(oc); \ -+ arm_rhel_compat_set(mc); \ - rhel##m##n##s##_virt_options(mc); \ - mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \ - if (latest) { \ -@@ -139,19 +167,6 @@ - #define DEFINE_RHEL_MACHINE(major, minor, subminor) \ - DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false) - --/* This variable is for changes to properties that are RHEL specific, -- * different to the current upstream and to be applied to the latest -- * machine type. -- */ --GlobalProperty arm_rhel_compat[] = { -- { -- .driver = "virtio-net-pci", -- .property = "romfile", -- .value = "", -- }, --}; --const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); -- - /* Number of external interrupt lines to configure the GIC with */ - #define NUM_IRQS 256 - -@@ -3639,7 +3654,6 @@ static void rhel920_virt_options(MachineClass *mc) - { - rhel940_virt_options(mc); - -- compat_props_add(mc->compat_props, arm_rhel_compat, arm_rhel_compat_len); - compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len); - compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len); - compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len); -@@ -3653,6 +3667,7 @@ static void rhel900_virt_options(MachineClass *mc) - rhel920_virt_options(mc); - - compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len); -+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len); - - /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */ - vmc->no_tcg_lpa2 = true; --- -2.39.3 - diff --git a/kvm-hw-arm-virt-deprecate-virt-rhel9.-0-2-.0-machine-typ.patch b/kvm-hw-arm-virt-deprecate-virt-rhel9.-0-2-.0-machine-typ.patch deleted file mode 100644 index 4770a58..0000000 --- a/kvm-hw-arm-virt-deprecate-virt-rhel9.-0-2-.0-machine-typ.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 4c1d07995a7afb6fae68a7e7a8b6b6c94fa0a7bb Mon Sep 17 00:00:00 2001 -From: Cornelia Huck -Date: Mon, 12 Feb 2024 10:37:54 +0100 -Subject: [PATCH 5/6] hw/arm/virt: deprecate virt-rhel9.{0,2}.0 machine types - -RH-Author: Cornelia Huck -RH-MergeRequest: 225: hw/arm/virt: deprecate virt-rhel9.{0,2}.0 machine types -RH-Jira: RHEL-24988 -RH-Acked-by: Sebastian Ott -RH-Acked-by: Eric Auger -RH-Commit: [1/1] f15579db44808fa8a2d7bc01b3915aa59c064411 (cohuck/qemu-kvm-c9s) - -Jira: https://issues.redhat.com/browse/RHEL-24988 -Upstream: RHEL only - -We do not plan to support any machine types prior to 9.4.0; leave them -in, but mark as deprecated. - -Signed-off-by: Cornelia Huck ---- - hw/arm/virt.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 60f117f0d2..943c563391 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -3679,6 +3679,10 @@ static void rhel920_virt_options(MachineClass *mc) - compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len); - compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len); - compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len); -+ -+ /* RHEL 9.4 is the first supported release */ -+ mc->deprecation_reason = -+ "machine types for versions prior to 9.4 are deprecated"; - } - DEFINE_RHEL_MACHINE(9, 2, 0) - --- -2.39.3 - diff --git a/kvm-hw-i386-Activate-IOMMUFD-for-q35-machines.patch b/kvm-hw-i386-Activate-IOMMUFD-for-q35-machines.patch deleted file mode 100644 index 81c20e5..0000000 --- a/kvm-hw-i386-Activate-IOMMUFD-for-q35-machines.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7a6be312c11911bdd2ce82566be22a3e014947c2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 21 Nov 2023 16:44:20 +0800 -Subject: [PATCH 041/101] hw/i386: Activate IOMMUFD for q35 machines -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [40/67] b15764ab24fd57389a8d219736613484acd7d29e (eauger1/centos-qemu-kvm) - -Signed-off-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 64ad06f6eba66c514477f490bcba409439a480d8) -Signed-off-by: Eric Auger ---- - hw/i386/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig -index 55850791df..a1846be6f7 100644 ---- a/hw/i386/Kconfig -+++ b/hw/i386/Kconfig -@@ -95,6 +95,7 @@ config Q35 - imply E1000E_PCI_EXPRESS - imply VMPORT - imply VMMOUSE -+ imply IOMMUFD - select PC_PCI - select PC_ACPI - select PCI_EXPRESS_Q35 --- -2.39.3 - diff --git a/kvm-hw-i386-pc-Defer-smbios_set_defaults-to-machine_done.patch b/kvm-hw-i386-pc-Defer-smbios_set_defaults-to-machine_done.patch deleted file mode 100644 index 5470bdf..0000000 --- a/kvm-hw-i386-pc-Defer-smbios_set_defaults-to-machine_done.patch +++ /dev/null @@ -1,186 +0,0 @@ -From ea2e2368dcf4140be47288472f2c2a094358e0c7 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Thu, 8 Feb 2024 23:03:45 +0100 -Subject: [PATCH 03/20] hw/i386/pc: Defer smbios_set_defaults() to machine_done -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [1/18] 9d4c1d1a910fec7d310429d6fc0b10c798932db7 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -commit: a0204a5ed091dfe79aced7ec8f3ce1931fd25816 -Author: Bernhard Beschow - - Handling most of smbios data generation in the machine_done notifier is similar - to how the ARM virt machine handles it which also calls smbios_set_defaults() - there. The result is that all pc machines are freed from explicitly worrying - about smbios setup. - - Signed-off-by: Bernhard Beschow - Reviewed-by: Philippe Mathieu-Daudé - Message-ID: <20240208220349.4948-6-shentey@gmail.com> - Signed-off-by: Philippe Mathieu-Daudé - -Conflicts: hw/i386/pc_q35.c, hw/i386/pc_piix.c - due to missing 4d3457fef9 (w/i386/pc: Merge pc_guest_info_init() into pc_machine_initfn()) - and different signature of smbios_set_defaults() downstream -Fixup: hw/i386/fw_cfg.c to account for downstream changes smbios_set_defaults() - -Signed-off-by: Igor Mammedov ---- - hw/i386/fw_cfg.c | 14 +++++++++++++- - hw/i386/fw_cfg.h | 3 ++- - hw/i386/pc.c | 2 +- - hw/i386/pc_piix.c | 12 ------------ - hw/i386/pc_q35.c | 11 ----------- - include/hw/i386/pc.h | 1 - - 6 files changed, 16 insertions(+), 27 deletions(-) - -diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index 7362daa45a..6a5466faf0 100644 ---- a/hw/i386/fw_cfg.c -+++ b/hw/i386/fw_cfg.c -@@ -48,15 +48,27 @@ const char *fw_cfg_arch_key_name(uint16_t key) - return NULL; - } - --void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg) -+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) - { - #ifdef CONFIG_SMBIOS - uint8_t *smbios_tables, *smbios_anchor; - size_t smbios_tables_len, smbios_anchor_len; - struct smbios_phys_mem_area *mem_array; - unsigned i, array_count; -+ MachineState *ms = MACHINE(pcms); -+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); -+ MachineClass *mc = MACHINE_GET_CLASS(pcms); - X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu); - -+ if (pcmc->smbios_defaults) { -+ /* These values are guest ABI, do not change */ -+ smbios_set_defaults("QEMU", mc->desc, mc->name, -+ pcmc->smbios_legacy_mode, pcmc->smbios_uuid_encoded, -+ pcmc->smbios_stream_product, -+ pcmc->smbios_stream_version, -+ pcms->smbios_entry_point_type); -+ } -+ - /* tell smbios about cpuid version and features */ - smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); - -diff --git a/hw/i386/fw_cfg.h b/hw/i386/fw_cfg.h -index 86ca7c1c0c..1e1de6b4a3 100644 ---- a/hw/i386/fw_cfg.h -+++ b/hw/i386/fw_cfg.h -@@ -10,6 +10,7 @@ - #define HW_I386_FW_CFG_H - - #include "hw/boards.h" -+#include "hw/i386/pc.h" - #include "hw/nvram/fw_cfg.h" - - #define FW_CFG_IO_BASE 0x510 -@@ -22,7 +23,7 @@ - FWCfgState *fw_cfg_arch_create(MachineState *ms, - uint16_t boot_cpus, - uint16_t apic_id_limit); --void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg); -+void fw_cfg_build_smbios(PCMachineState *ms, FWCfgState *fw_cfg); - void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg); - void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg); - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index a1faa9e92c..16de2a59e8 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -847,7 +847,7 @@ void pc_machine_done(Notifier *notifier, void *data) - - acpi_setup(); - if (x86ms->fw_cfg) { -- fw_cfg_build_smbios(MACHINE(pcms), x86ms->fw_cfg); -+ fw_cfg_build_smbios(pcms, x86ms->fw_cfg); - fw_cfg_build_feature_control(MACHINE(pcms), x86ms->fw_cfg); - /* update FW_CFG_NB_CPUS to account for -device added CPUs */ - fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus); -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 09d02cc91f..7344b35cf1 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -36,7 +36,6 @@ - #include "hw/rtc/mc146818rtc.h" - #include "hw/southbridge/piix.h" - #include "hw/display/ramfb.h" --#include "hw/firmware/smbios.h" - #include "hw/pci/pci.h" - #include "hw/pci/pci_ids.h" - #include "hw/usb.h" -@@ -233,17 +232,6 @@ static void pc_init1(MachineState *machine, - - pc_guest_info_init(pcms); - -- if (pcmc->smbios_defaults) { -- MachineClass *mc = MACHINE_GET_CLASS(machine); -- /* These values are guest ABI, do not change */ -- smbios_set_defaults("Red Hat", "KVM", -- mc->desc, pcmc->smbios_legacy_mode, -- pcmc->smbios_uuid_encoded, -- pcmc->smbios_stream_product, -- pcmc->smbios_stream_version, -- pcms->smbios_entry_point_type); -- } -- - /* allocate ram and load rom/bios */ - if (!xen_enabled()) { - pc_memory_init(pcms, system_memory, rom_memory, hole64_size); -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index c6967e1846..9a22ff5dd6 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -45,7 +45,6 @@ - #include "hw/i386/amd_iommu.h" - #include "hw/i386/intel_iommu.h" - #include "hw/display/ramfb.h" --#include "hw/firmware/smbios.h" - #include "hw/ide/pci.h" - #include "hw/ide/ahci.h" - #include "hw/intc/ioapic.h" -@@ -201,16 +200,6 @@ static void pc_q35_init(MachineState *machine) - - pc_guest_info_init(pcms); - -- if (pcmc->smbios_defaults) { -- /* These values are guest ABI, do not change */ -- smbios_set_defaults("Red Hat", "KVM", -- mc->desc, pcmc->smbios_legacy_mode, -- pcmc->smbios_uuid_encoded, -- pcmc->smbios_stream_product, -- pcmc->smbios_stream_version, -- pcms->smbios_entry_point_type); -- } -- - /* create pci host bus */ - phb = OBJECT(qdev_new(TYPE_Q35_HOST_DEVICE)); - -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 37644ede7e..c286c10bc3 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -12,7 +12,6 @@ - #include "hw/hotplug.h" - #include "qom/object.h" - #include "hw/i386/sgx-epc.h" --#include "hw/firmware/smbios.h" - #include "hw/cxl/cxl.h" - - #define HPET_INTCAP "hpet-intcap" --- -2.39.3 - diff --git a/kvm-hw-ppc-Kconfig-Imply-VFIO_PCI.patch b/kvm-hw-ppc-Kconfig-Imply-VFIO_PCI.patch deleted file mode 100644 index f850765..0000000 --- a/kvm-hw-ppc-Kconfig-Imply-VFIO_PCI.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 84f378c41832602dcf9bad6167b1f532c7c53e37 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 21 Nov 2023 15:03:55 +0100 -Subject: [PATCH 048/101] hw/ppc/Kconfig: Imply VFIO_PCI -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [47/67] c1a40cdab9bf62b16cb428d57a20b3e0eaa6de38 (eauger1/centos-qemu-kvm) - -When the legacy and iommufd backends were introduced, a set of common -vfio-pci routines were exported in pci.c for both backends to use : - - vfio_pci_pre_reset - vfio_pci_get_pci_hot_reset_info - vfio_pci_host_match - vfio_pci_post_reset - -This introduced a build failure on PPC when --without-default-devices -is use because VFIO is always selected in ppc/Kconfig but VFIO_PCI is -not. - -Use an 'imply VFIO_PCI' in ppc/Kconfig and bypass compilation of the -VFIO EEH hooks routines defined in hw/ppc/spapr_pci_vfio.c with -CONFIG_VFIO_PCI. - -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Zhenzhong Duan -Signed-off-by: Cédric Le Goater -(cherry picked from commit 4278df9d1d2383b738338c857406357660f11e42) -Signed-off-by: Eric Auger ---- - hw/ppc/Kconfig | 2 +- - hw/ppc/spapr_pci_vfio.c | 36 ++++++++++++++++++++++++++++++++++++ - 2 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig -index 56f0475a8e..44263a58c4 100644 ---- a/hw/ppc/Kconfig -+++ b/hw/ppc/Kconfig -@@ -3,11 +3,11 @@ config PSERIES - imply PCI_DEVICES - imply TEST_DEVICES - imply VIRTIO_VGA -+ imply VFIO_PCI if LINUX # needed by spapr_pci_vfio.c - select NVDIMM - select DIMM - select PCI - select SPAPR_VSCSI -- select VFIO if LINUX # needed by spapr_pci_vfio.c - select XICS - select XIVE - select MSI_NONBROKEN -diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c -index d1d07bec46..76b2a3487b 100644 ---- a/hw/ppc/spapr_pci_vfio.c -+++ b/hw/ppc/spapr_pci_vfio.c -@@ -26,10 +26,12 @@ - #include "hw/pci/pci_device.h" - #include "hw/vfio/vfio-common.h" - #include "qemu/error-report.h" -+#include CONFIG_DEVICES /* CONFIG_VFIO_PCI */ - - /* - * Interfaces for IBM EEH (Enhanced Error Handling) - */ -+#ifdef CONFIG_VFIO_PCI - static bool vfio_eeh_container_ok(VFIOContainer *container) - { - /* -@@ -314,3 +316,37 @@ int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb) - - return RTAS_OUT_SUCCESS; - } -+ -+#else -+ -+bool spapr_phb_eeh_available(SpaprPhbState *sphb) -+{ -+ return false; -+} -+ -+void spapr_phb_vfio_reset(DeviceState *qdev) -+{ -+} -+ -+int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb, -+ unsigned int addr, int option) -+{ -+ return RTAS_OUT_NOT_SUPPORTED; -+} -+ -+int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state) -+{ -+ return RTAS_OUT_NOT_SUPPORTED; -+} -+ -+int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option) -+{ -+ return RTAS_OUT_NOT_SUPPORTED; -+} -+ -+int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb) -+{ -+ return RTAS_OUT_NOT_SUPPORTED; -+} -+ -+#endif /* CONFIG_VFIO_PCI */ --- -2.39.3 - diff --git a/kvm-hw-vfio-fix-iteration-over-global-VFIODevice-list.patch b/kvm-hw-vfio-fix-iteration-over-global-VFIODevice-list.patch deleted file mode 100644 index 2c7f6ff..0000000 --- a/kvm-hw-vfio-fix-iteration-over-global-VFIODevice-list.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 8f27893a37e55a31180bb66cd9eae7199911881b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Volker=20R=C3=BCmelin?= -Date: Fri, 29 Dec 2023 21:38:54 +0100 -Subject: [PATCH 060/101] hw/vfio: fix iteration over global VFIODevice list -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [59/67] f926e1233c8c5ad418e8794b1a103371c9dc5eb0 (eauger1/centos-qemu-kvm) - -Commit 3d779abafe ("vfio/common: Introduce a global VFIODevice list") -introduced a global VFIODevice list, but forgot to update the list -element field name when iterating over the new list. Change the code -to use the correct list element field. - -Fixes: 3d779abafe ("vfio/common: Introduce a global VFIODevice list") -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2061 -Signed-off-by: Volker Rümelin -Reviewed-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Auger -(cherry picked from commit 9353b6da430f90e47f352dbf6dc31120c8914da6) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 0d4d8b8416..0b3352f2a9 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -73,7 +73,7 @@ bool vfio_mig_active(void) - return false; - } - -- QLIST_FOREACH(vbasedev, &vfio_device_list, next) { -+ QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { - if (vbasedev->migration_blocker) { - return false; - } -@@ -94,7 +94,7 @@ static bool vfio_multiple_devices_migration_is_supported(void) - unsigned int device_num = 0; - bool all_support_p2p = true; - -- QLIST_FOREACH(vbasedev, &vfio_device_list, next) { -+ QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { - if (vbasedev->migration) { - device_num++; - -@@ -1366,13 +1366,13 @@ void vfio_reset_handler(void *opaque) - { - VFIODevice *vbasedev; - -- QLIST_FOREACH(vbasedev, &vfio_device_list, next) { -+ QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { - if (vbasedev->dev->realized) { - vbasedev->ops->vfio_compute_needs_reset(vbasedev); - } - } - -- QLIST_FOREACH(vbasedev, &vfio_device_list, next) { -+ QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { - if (vbasedev->dev->realized && vbasedev->needs_reset) { - vbasedev->ops->vfio_hot_reset_multi(vbasedev); - } --- -2.39.3 - diff --git a/kvm-include-ui-rect.h-fix-qemu_rect_init-mis-assignment.patch b/kvm-include-ui-rect.h-fix-qemu_rect_init-mis-assignment.patch deleted file mode 100644 index 0cf782e..0000000 --- a/kvm-include-ui-rect.h-fix-qemu_rect_init-mis-assignment.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 51b8f29cddb73eb02f91af5f52a205fdd3af6583 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Wed, 17 Jan 2024 21:08:59 +0100 -Subject: [PATCH 099/101] include/ui/rect.h: fix qemu_rect_init() - mis-assignment -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 216: Fix regression in QEMU's virtio-gpu VNC sessions -RH-Jira: RHEL-21570 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Cédric Le Goater -RH-Commit: [1/1] a9d487be04e2c1847b80c479b5cc790af81e3428 (thuth/qemu-kvm-cs9) - -JIRA: https://issues.redhat.com/browse/RHEL-21570 - -commit 9d5b42beb6978dc6219d5dc029c9d453c6b8d503 -Author: Elen Avan -Date: Fri Dec 22 22:17:21 2023 +0300 - - include/ui/rect.h: fix qemu_rect_init() mis-assignment - - Signed-off-by: Elen Avan - Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2051 - Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2050 - Fixes: a200d53b1fde "virtio-gpu: replace PIXMAN for region/rect test" - Cc: qemu-stable@nongnu.org - Reviewed-by: Michael Tokarev - Reviewed-by: Marc-André Lureau - Signed-off-by: Michael Tokarev - -Signed-off-by: Thomas Huth ---- - include/ui/rect.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/ui/rect.h b/include/ui/rect.h -index 94898f92d0..68f05d78a8 100644 ---- a/include/ui/rect.h -+++ b/include/ui/rect.h -@@ -19,7 +19,7 @@ static inline void qemu_rect_init(QemuRect *rect, - uint16_t width, uint16_t height) - { - rect->x = x; -- rect->y = x; -+ rect->y = y; - rect->width = width; - rect->height = height; - } --- -2.39.3 - diff --git a/kvm-iotests-Add-test-for-reset-AioContext-switches-with-.patch b/kvm-iotests-Add-test-for-reset-AioContext-switches-with-.patch deleted file mode 100644 index 3b2841f..0000000 --- a/kvm-iotests-Add-test-for-reset-AioContext-switches-with-.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 65d58819ff7b012e43b5f1da1356b559d3f5a962 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Thu, 14 Mar 2024 17:58:25 +0100 -Subject: [PATCH 3/4] iotests: Add test for reset/AioContext switches with NBD - exports - -RH-Author: Kevin Wolf -RH-MergeRequest: 231: Fix deadlock and crash during storage migration -RH-Jira: RHEL-28125 -RH-Acked-by: Hanna Czenczek -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [3/3] 7266acdf85271d157497bfe452aa6eeb58fbe7c6 (kmwolf/centos-qemu-kvm) - -This replicates the scenario in which the bug was reported. -Unfortunately this relies on actually executing a guest (so that the -firmware initialises the virtio-blk device and moves it to its -configured iothread), so this can't make use of the qtest accelerator -like most other test cases. I tried to find a different easy way to -trigger the bug, but couldn't find one. - -Signed-off-by: Kevin Wolf -Message-ID: <20240314165825.40261-3-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit e8fce34eccf68a32f4ecf2c6f121ff2ac383d6bf) -Signed-off-by: Kevin Wolf ---- - tests/qemu-iotests/tests/iothreads-nbd-export | 66 +++++++++++++++++++ - .../tests/iothreads-nbd-export.out | 19 ++++++ - 2 files changed, 85 insertions(+) - create mode 100755 tests/qemu-iotests/tests/iothreads-nbd-export - create mode 100644 tests/qemu-iotests/tests/iothreads-nbd-export.out - -diff --git a/tests/qemu-iotests/tests/iothreads-nbd-export b/tests/qemu-iotests/tests/iothreads-nbd-export -new file mode 100755 -index 0000000000..037260729c ---- /dev/null -+++ b/tests/qemu-iotests/tests/iothreads-nbd-export -@@ -0,0 +1,66 @@ -+#!/usr/bin/env python3 -+# group: rw quick -+# -+# Copyright (C) 2024 Red Hat, Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program 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 General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+# -+# Creator/Owner: Kevin Wolf -+ -+import time -+import qemu -+import iotests -+ -+iotests.script_initialize(supported_fmts=['qcow2'], -+ supported_platforms=['linux']) -+ -+with iotests.FilePath('disk1.img') as path, \ -+ iotests.FilePath('nbd.sock', base_dir=iotests.sock_dir) as nbd_sock, \ -+ qemu.machine.QEMUMachine(iotests.qemu_prog) as vm: -+ -+ img_size = '10M' -+ -+ iotests.log('Preparing disk...') -+ iotests.qemu_img_create('-f', iotests.imgfmt, path, img_size) -+ vm.add_args('-blockdev', f'file,node-name=disk-file,filename={path}') -+ vm.add_args('-blockdev', 'qcow2,node-name=disk,file=disk-file') -+ vm.add_args('-object', 'iothread,id=iothread0') -+ vm.add_args('-device', -+ 'virtio-blk,drive=disk,iothread=iothread0,share-rw=on') -+ -+ iotests.log('Launching VM...') -+ vm.add_args('-accel', 'kvm', '-accel', 'tcg') -+ #vm.add_args('-accel', 'qtest') -+ vm.launch() -+ -+ iotests.log('Exporting to NBD...') -+ iotests.log(vm.qmp('nbd-server-start', -+ addr={'type': 'unix', 'data': {'path': nbd_sock}})) -+ iotests.log(vm.qmp('block-export-add', type='nbd', id='exp0', -+ node_name='disk', writable=True)) -+ -+ iotests.log('Connecting qemu-img...') -+ qemu_io = iotests.QemuIoInteractive('-f', 'raw', -+ f'nbd+unix:///disk?socket={nbd_sock}') -+ -+ iotests.log('Moving the NBD export to a different iothread...') -+ for i in range(0, 10): -+ iotests.log(vm.qmp('system_reset')) -+ time.sleep(0.1) -+ -+ iotests.log('Checking that it is still alive...') -+ iotests.log(vm.qmp('query-status')) -+ -+ qemu_io.close() -+ vm.shutdown() -diff --git a/tests/qemu-iotests/tests/iothreads-nbd-export.out b/tests/qemu-iotests/tests/iothreads-nbd-export.out -new file mode 100644 -index 0000000000..bc514e35e5 ---- /dev/null -+++ b/tests/qemu-iotests/tests/iothreads-nbd-export.out -@@ -0,0 +1,19 @@ -+Preparing disk... -+Launching VM... -+Exporting to NBD... -+{"return": {}} -+{"return": {}} -+Connecting qemu-img... -+Moving the NBD export to a different iothread... -+{"return": {}} -+{"return": {}} -+{"return": {}} -+{"return": {}} -+{"return": {}} -+{"return": {}} -+{"return": {}} -+{"return": {}} -+{"return": {}} -+{"return": {}} -+Checking that it is still alive... -+{"return": {"running": true, "status": "running"}} --- -2.39.3 - diff --git a/kvm-iotests-add-filter_qmp_generated_node_ids.patch b/kvm-iotests-add-filter_qmp_generated_node_ids.patch deleted file mode 100644 index d9072f5..0000000 --- a/kvm-iotests-add-filter_qmp_generated_node_ids.patch +++ /dev/null @@ -1,49 +0,0 @@ -From a9be663beaace1c31d75ca353e5d3bb0657a4f6c Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 18 Jan 2024 09:48:21 -0500 -Subject: [PATCH 11/22] iotests: add filter_qmp_generated_node_ids() - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [7/17] 8dd20acc5b1e992294ed422e80897a9c221940dd (stefanha/centos-stream-qemu-kvm) - -Add a filter function for QMP responses that contain QEMU's -automatically generated node ids. The ids change between runs and must -be masked in the reference output. - -The next commit will use this new function. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240118144823.1497953-2-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit da62b507a20510d819bcfbe8f5e573409b954006) -Signed-off-by: Stefan Hajnoczi ---- - tests/qemu-iotests/iotests.py | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py -index e5c5798c71..ea48af4a7b 100644 ---- a/tests/qemu-iotests/iotests.py -+++ b/tests/qemu-iotests/iotests.py -@@ -651,6 +651,13 @@ def _filter(_key, value): - def filter_generated_node_ids(msg): - return re.sub("#block[0-9]+", "NODE_NAME", msg) - -+def filter_qmp_generated_node_ids(qmsg): -+ def _filter(_key, value): -+ if is_str(value): -+ return filter_generated_node_ids(value) -+ return value -+ return filter_qmp(qmsg, _filter) -+ - def filter_img_info(output: str, filename: str, - drop_child_info: bool = True) -> str: - lines = [] --- -2.39.3 - diff --git a/kvm-iotests-iothreads-stream-Use-the-right-TimeoutError.patch b/kvm-iotests-iothreads-stream-Use-the-right-TimeoutError.patch deleted file mode 100644 index ab63004..0000000 --- a/kvm-iotests-iothreads-stream-Use-the-right-TimeoutError.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 453da839a7d81896d03b827a95c1991a60740dc5 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Thu, 25 Jan 2024 16:21:50 +0100 -Subject: [PATCH 21/22] iotests/iothreads-stream: Use the right TimeoutError - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [17/17] ca5a512ccccb668089b726d7499562d1e294c828 (stefanha/centos-stream-qemu-kvm) - -Since Python 3.11 asyncio.TimeoutError is an alias for TimeoutError, but -in older versions it's not. We really have to catch asyncio.TimeoutError -here, otherwise a slow test run will fail (as has happened multiple -times on CI recently). - -Signed-off-by: Kevin Wolf -Message-ID: <20240125152150.42389-1-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit c9c0b37ff4c11b712b21efabe8e5381d223d0295) -Signed-off-by: Stefan Hajnoczi ---- - tests/qemu-iotests/tests/iothreads-stream | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tests/qemu-iotests/tests/iothreads-stream b/tests/qemu-iotests/tests/iothreads-stream -index 503f221f16..231195b5e8 100755 ---- a/tests/qemu-iotests/tests/iothreads-stream -+++ b/tests/qemu-iotests/tests/iothreads-stream -@@ -18,6 +18,7 @@ - # - # Creator/Owner: Kevin Wolf - -+import asyncio - import iotests - - iotests.script_initialize(supported_fmts=['qcow2'], -@@ -69,6 +70,6 @@ with iotests.FilePath('disk1.img') as base1_path, \ - # The test is done once both jobs are gone - if finished == 2: - break -- except TimeoutError: -+ except asyncio.TimeoutError: - pass - vm.cmd('query-jobs') --- -2.39.3 - diff --git a/kvm-iotests-port-141-to-Python-for-reliable-QMP-testing.patch b/kvm-iotests-port-141-to-Python-for-reliable-QMP-testing.patch deleted file mode 100644 index 209bd1e..0000000 --- a/kvm-iotests-port-141-to-Python-for-reliable-QMP-testing.patch +++ /dev/null @@ -1,592 +0,0 @@ -From 70efc3bbf1f7d7b1b0c2475d9ce3bb70cc9d1cc7 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 18 Jan 2024 09:48:22 -0500 -Subject: [PATCH 12/22] iotests: port 141 to Python for reliable QMP testing - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [8/17] 0783f536508916feac4b4c39e41c22c24a2e52e7 (stefanha/centos-stream-qemu-kvm) - -The common.qemu bash functions allow tests to interact with the QMP -monitor of a QEMU process. I spent two days trying to update 141 when -the order of the test output changed, but found it would still fail -occassionally because printf() and QMP events race with synchronous QMP -communication. - -I gave up and ported 141 to the existing Python API for QMP tests. The -Python API is less affected by the order in which QEMU prints output -because it does not print all QMP traffic by default. - -The next commit changes the order in which QMP messages are received. -Make 141 reliable first. - -Cc: Hanna Czenczek -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240118144823.1497953-3-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 9ee2dd4c22a3639c5462b3fc20df60c005c3de64) -Signed-off-by: Stefan Hajnoczi ---- - tests/qemu-iotests/141 | 307 ++++++++++++++++--------------------- - tests/qemu-iotests/141.out | 200 ++++++------------------ - 2 files changed, 176 insertions(+), 331 deletions(-) - -diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141 -index a37030ee17..a7d3985a02 100755 ---- a/tests/qemu-iotests/141 -+++ b/tests/qemu-iotests/141 -@@ -1,9 +1,12 @@ --#!/usr/bin/env bash -+#!/usr/bin/env python3 - # group: rw auto quick - # - # Test case for ejecting BDSs with block jobs still running on them - # --# Copyright (C) 2016 Red Hat, Inc. -+# Originally written in bash by Hanna Czenczek, ported to Python by Stefan -+# Hajnoczi. -+# -+# Copyright Red Hat - # - # This program is free software; you can redistribute it and/or modify - # it under the terms of the GNU General Public License as published by -@@ -19,177 +22,129 @@ - # along with this program. If not, see . - # - --# creator --owner=hreitz@redhat.com -- --seq="$(basename $0)" --echo "QA output created by $seq" -- --status=1 # failure is the default! -- --_cleanup() --{ -- _cleanup_qemu -- _cleanup_test_img -- for img in "$TEST_DIR"/{b,m,o}.$IMGFMT; do -- _rm_test_img "$img" -- done --} --trap "_cleanup; exit \$status" 0 1 2 3 15 -- --# get standard environment, filters and checks --. ./common.rc --. ./common.filter --. ./common.qemu -- --# Needs backing file and backing format support --_supported_fmt qcow2 qed --_supported_proto file --_supported_os Linux -- -- --test_blockjob() --{ -- _send_qemu_cmd $QEMU_HANDLE \ -- "{'execute': 'blockdev-add', -- 'arguments': { -- 'node-name': 'drv0', -- 'driver': '$IMGFMT', -- 'file': { -- 'driver': 'file', -- 'filename': '$TEST_IMG' -- }}}" \ -- 'return' -- -- # If "$2" is an event, we may or may not see it before the -- # {"return": {}}. Therefore, filter the {"return": {}} out both -- # here and in the next command. (Naturally, if we do not see it -- # here, we will see it before the next command can be executed, -- # so it will appear in the next _send_qemu_cmd's output.) -- _send_qemu_cmd $QEMU_HANDLE \ -- "$1" \ -- "$2" \ -- | _filter_img_create | _filter_qmp_empty_return -- -- # We want this to return an error because the block job is still running -- _send_qemu_cmd $QEMU_HANDLE \ -- "{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}}" \ -- 'error' | _filter_generated_node_ids | _filter_qmp_empty_return -- -- _send_qemu_cmd $QEMU_HANDLE \ -- "{'execute': 'block-job-cancel', -- 'arguments': {'device': 'job0'}}" \ -- "$3" -- -- _send_qemu_cmd $QEMU_HANDLE \ -- "{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}}" \ -- 'return' --} -- -- --TEST_IMG="$TEST_DIR/b.$IMGFMT" _make_test_img 1M --TEST_IMG="$TEST_DIR/m.$IMGFMT" _make_test_img -b "$TEST_DIR/b.$IMGFMT" -F $IMGFMT 1M --_make_test_img -b "$TEST_DIR/m.$IMGFMT" 1M -F $IMGFMT -- --_launch_qemu -nodefaults -- --_send_qemu_cmd $QEMU_HANDLE \ -- "{'execute': 'qmp_capabilities'}" \ -- 'return' -- --echo --echo '=== Testing drive-backup ===' --echo -- --# drive-backup will not send BLOCK_JOB_READY by itself, and cancelling the job --# will consequently result in BLOCK_JOB_CANCELLED being emitted. -- --test_blockjob \ -- "{'execute': 'drive-backup', -- 'arguments': {'job-id': 'job0', -- 'device': 'drv0', -- 'target': '$TEST_DIR/o.$IMGFMT', -- 'format': '$IMGFMT', -- 'sync': 'none'}}" \ -- 'return' \ -- '"status": "null"' -- --echo --echo '=== Testing drive-mirror ===' --echo -- --# drive-mirror will send BLOCK_JOB_READY basically immediately, and cancelling --# the job will consequently result in BLOCK_JOB_COMPLETED being emitted. -- --test_blockjob \ -- "{'execute': 'drive-mirror', -- 'arguments': {'job-id': 'job0', -- 'device': 'drv0', -- 'target': '$TEST_DIR/o.$IMGFMT', -- 'format': '$IMGFMT', -- 'sync': 'none'}}" \ -- 'BLOCK_JOB_READY' \ -- '"status": "null"' -- --echo --echo '=== Testing active block-commit ===' --echo -- --# An active block-commit will send BLOCK_JOB_READY basically immediately, and --# cancelling the job will consequently result in BLOCK_JOB_COMPLETED being --# emitted. -- --test_blockjob \ -- "{'execute': 'block-commit', -- 'arguments': {'job-id': 'job0', 'device': 'drv0'}}" \ -- 'BLOCK_JOB_READY' \ -- '"status": "null"' -- --echo --echo '=== Testing non-active block-commit ===' --echo -- --# Give block-commit something to work on, otherwise it would be done --# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work just --# fine without the block job still running. -- --$QEMU_IO -c 'write 0 1M' "$TEST_DIR/m.$IMGFMT" | _filter_qemu_io -- --test_blockjob \ -- "{'execute': 'block-commit', -- 'arguments': {'job-id': 'job0', -- 'device': 'drv0', -- 'top': '$TEST_DIR/m.$IMGFMT', -- 'speed': 1}}" \ -- 'return' \ -- '"status": "null"' -- --echo --echo '=== Testing block-stream ===' --echo -- --# Give block-stream something to work on, otherwise it would be done --# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work just --# fine without the block job still running. -- --$QEMU_IO -c 'write 0 1M' "$TEST_DIR/b.$IMGFMT" | _filter_qemu_io -- --# With some data to stream (and @speed set to 1), block-stream will not complete --# until we send the block-job-cancel command. -- --test_blockjob \ -- "{'execute': 'block-stream', -- 'arguments': {'job-id': 'job0', -- 'device': 'drv0', -- 'speed': 1}}" \ -- 'return' \ -- '"status": "null"' -- --_cleanup_qemu -- --# success, all done --echo "*** done" --rm -f $seq.full --status=0 -+import iotests -+ -+# Common filters to mask values that vary in the test output -+QMP_FILTERS = [iotests.filter_qmp_testfiles, \ -+ iotests.filter_qmp_imgfmt] -+ -+ -+class TestCase: -+ def __init__(self, name, vm, image_path, cancel_event): -+ self.name = name -+ self.vm = vm -+ self.image_path = image_path -+ self.cancel_event = cancel_event -+ -+ def __enter__(self): -+ iotests.log(f'=== Testing {self.name} ===') -+ self.vm.qmp_log('blockdev-add', \ -+ node_name='drv0', \ -+ driver=iotests.imgfmt, \ -+ file={'driver': 'file', 'filename': self.image_path}, \ -+ filters=QMP_FILTERS) -+ -+ def __exit__(self, *exc_details): -+ # This is expected to fail because the job still exists -+ self.vm.qmp_log('blockdev-del', node_name='drv0', \ -+ filters=[iotests.filter_qmp_generated_node_ids]) -+ -+ self.vm.qmp_log('block-job-cancel', device='job0') -+ event = self.vm.event_wait(self.cancel_event) -+ iotests.log(event, filters=[iotests.filter_qmp_event]) -+ -+ # This time it succeeds -+ self.vm.qmp_log('blockdev-del', node_name='drv0') -+ -+ # Separate test cases in output -+ iotests.log('') -+ -+ -+def main() -> None: -+ with iotests.FilePath('bottom', 'middle', 'top', 'target') as \ -+ (bottom_path, middle_path, top_path, target_path), \ -+ iotests.VM() as vm: -+ -+ iotests.log('Creating bottom <- middle <- top backing file chain...') -+ IMAGE_SIZE='1M' -+ iotests.qemu_img_create('-f', iotests.imgfmt, bottom_path, IMAGE_SIZE) -+ iotests.qemu_img_create('-f', iotests.imgfmt, \ -+ '-F', iotests.imgfmt, \ -+ '-b', bottom_path, \ -+ middle_path, \ -+ IMAGE_SIZE) -+ iotests.qemu_img_create('-f', iotests.imgfmt, \ -+ '-F', iotests.imgfmt, \ -+ '-b', middle_path, \ -+ top_path, \ -+ IMAGE_SIZE) -+ -+ iotests.log('Starting VM...') -+ vm.add_args('-nodefaults') -+ vm.launch() -+ -+ # drive-backup will not send BLOCK_JOB_READY by itself, and cancelling -+ # the job will consequently result in BLOCK_JOB_CANCELLED being -+ # emitted. -+ with TestCase('drive-backup', vm, top_path, 'BLOCK_JOB_CANCELLED'): -+ vm.qmp_log('drive-backup', \ -+ job_id='job0', \ -+ device='drv0', \ -+ target=target_path, \ -+ format=iotests.imgfmt, \ -+ sync='none', \ -+ filters=QMP_FILTERS) -+ -+ # drive-mirror will send BLOCK_JOB_READY basically immediately, and -+ # cancelling the job will consequently result in BLOCK_JOB_COMPLETED -+ # being emitted. -+ with TestCase('drive-mirror', vm, top_path, 'BLOCK_JOB_COMPLETED'): -+ vm.qmp_log('drive-mirror', \ -+ job_id='job0', \ -+ device='drv0', \ -+ target=target_path, \ -+ format=iotests.imgfmt, \ -+ sync='none', \ -+ filters=QMP_FILTERS) -+ event = vm.event_wait('BLOCK_JOB_READY') -+ assert event is not None # silence mypy -+ iotests.log(event, filters=[iotests.filter_qmp_event]) -+ -+ # An active block-commit will send BLOCK_JOB_READY basically -+ # immediately, and cancelling the job will consequently result in -+ # BLOCK_JOB_COMPLETED being emitted. -+ with TestCase('active block-commit', vm, top_path, \ -+ 'BLOCK_JOB_COMPLETED'): -+ vm.qmp_log('block-commit', \ -+ job_id='job0', \ -+ device='drv0') -+ event = vm.event_wait('BLOCK_JOB_READY') -+ assert event is not None # silence mypy -+ iotests.log(event, filters=[iotests.filter_qmp_event]) -+ -+ # Give block-commit something to work on, otherwise it would be done -+ # immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would -+ # work just fine without the block job still running. -+ iotests.qemu_io(middle_path, '-c', f'write 0 {IMAGE_SIZE}') -+ with TestCase('non-active block-commit', vm, top_path, \ -+ 'BLOCK_JOB_CANCELLED'): -+ vm.qmp_log('block-commit', \ -+ job_id='job0', \ -+ device='drv0', \ -+ top=middle_path, \ -+ speed=1, \ -+ filters=[iotests.filter_qmp_testfiles]) -+ -+ # Give block-stream something to work on, otherwise it would be done -+ # immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would -+ # work just fine without the block job still running. -+ iotests.qemu_io(bottom_path, '-c', f'write 0 {IMAGE_SIZE}') -+ with TestCase('block-stream', vm, top_path, 'BLOCK_JOB_CANCELLED'): -+ vm.qmp_log('block-stream', \ -+ job_id='job0', \ -+ device='drv0', \ -+ speed=1) -+ -+if __name__ == '__main__': -+ iotests.script_main(main, supported_fmts=['qcow2', 'qed'], -+ supported_protocols=['file']) -diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out -index 63203d9944..91b7ba50af 100644 ---- a/tests/qemu-iotests/141.out -+++ b/tests/qemu-iotests/141.out -@@ -1,179 +1,69 @@ --QA output created by 141 --Formatting 'TEST_DIR/b.IMGFMT', fmt=IMGFMT size=1048576 --Formatting 'TEST_DIR/m.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/b.IMGFMT backing_fmt=IMGFMT --Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.IMGFMT backing_fmt=IMGFMT --{'execute': 'qmp_capabilities'} --{"return": {}} -- -+Creating bottom <- middle <- top backing file chain... -+Starting VM... - === Testing drive-backup === -- --{'execute': 'blockdev-add', -- 'arguments': { -- 'node-name': 'drv0', -- 'driver': 'IMGFMT', -- 'file': { -- 'driver': 'file', -- 'filename': 'TEST_DIR/t.IMGFMT' -- }}} --{"return": {}} --{'execute': 'drive-backup', --'arguments': {'job-id': 'job0', --'device': 'drv0', --'target': 'TEST_DIR/o.IMGFMT', --'format': 'IMGFMT', --'sync': 'none'}} --Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} -+{"return": {}} -+{"execute": "drive-backup", "arguments": {"device": "drv0", "format": "IMGFMT", "job-id": "job0", "sync": "none", "target": "TEST_DIR/PID-target"}} -+{"return": {}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}} --{'execute': 'block-job-cancel', -- 'arguments': {'device': 'job0'}} -+{"execute": "block-job-cancel", "arguments": {"device": "job0"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"return": {}} - - === Testing drive-mirror === -- --{'execute': 'blockdev-add', -- 'arguments': { -- 'node-name': 'drv0', -- 'driver': 'IMGFMT', -- 'file': { -- 'driver': 'file', -- 'filename': 'TEST_DIR/t.IMGFMT' -- }}} --{"return": {}} --{'execute': 'drive-mirror', --'arguments': {'job-id': 'job0', --'device': 'drv0', --'target': 'TEST_DIR/o.IMGFMT', --'format': 'IMGFMT', --'sync': 'none'}} --Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} -+{"return": {}} -+{"execute": "drive-mirror", "arguments": {"device": "drv0", "format": "IMGFMT", "job-id": "job0", "sync": "none", "target": "TEST_DIR/PID-target"}} -+{"return": {}} -+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}} --{'execute': 'block-job-cancel', -- 'arguments': {'device': 'job0'}} -+{"execute": "block-job-cancel", "arguments": {"device": "job0"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"return": {}} - - === Testing active block-commit === -- --{'execute': 'blockdev-add', -- 'arguments': { -- 'node-name': 'drv0', -- 'driver': 'IMGFMT', -- 'file': { -- 'driver': 'file', -- 'filename': 'TEST_DIR/t.IMGFMT' -- }}} --{"return": {}} --{'execute': 'block-commit', --'arguments': {'job-id': 'job0', 'device': 'drv0'}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} -+{"return": {}} -+{"execute": "block-commit", "arguments": {"device": "drv0", "job-id": "job0"}} -+{"return": {}} -+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}} --{'execute': 'block-job-cancel', -- 'arguments': {'device': 'job0'}} -+{"execute": "block-job-cancel", "arguments": {"device": "job0"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"return": {}} - - === Testing non-active block-commit === -- --wrote 1048576/1048576 bytes at offset 0 --1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) --{'execute': 'blockdev-add', -- 'arguments': { -- 'node-name': 'drv0', -- 'driver': 'IMGFMT', -- 'file': { -- 'driver': 'file', -- 'filename': 'TEST_DIR/t.IMGFMT' -- }}} --{"return": {}} --{'execute': 'block-commit', --'arguments': {'job-id': 'job0', --'device': 'drv0', --'top': 'TEST_DIR/m.IMGFMT', --'speed': 1}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} -+{"return": {}} -+{"execute": "block-commit", "arguments": {"device": "drv0", "job-id": "job0", "speed": 1, "top": "TEST_DIR/PID-middle"}} -+{"return": {}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}} --{'execute': 'block-job-cancel', -- 'arguments': {'device': 'job0'}} -+{"execute": "block-job-cancel", "arguments": {"device": "job0"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"return": {}} - - === Testing block-stream === -- --wrote 1048576/1048576 bytes at offset 0 --1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) --{'execute': 'blockdev-add', -- 'arguments': { -- 'node-name': 'drv0', -- 'driver': 'IMGFMT', -- 'file': { -- 'driver': 'file', -- 'filename': 'TEST_DIR/t.IMGFMT' -- }}} --{"return": {}} --{'execute': 'block-stream', --'arguments': {'job-id': 'job0', --'device': 'drv0', --'speed': 1}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} -+{"return": {}} -+{"execute": "block-stream", "arguments": {"device": "drv0", "job-id": "job0", "speed": 1}} -+{"return": {}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: stream"}} --{'execute': 'block-job-cancel', -- 'arguments': {'device': 'job0'}} -+{"execute": "block-job-cancel", "arguments": {"device": "job0"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} --{'execute': 'blockdev-del', -- 'arguments': {'node-name': 'drv0'}} -+{"data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} -+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} - {"return": {}} --*** done -+ --- -2.39.3 - diff --git a/kvm-job-remove-outdated-AioContext-locking-comments.patch b/kvm-job-remove-outdated-AioContext-locking-comments.patch deleted file mode 100644 index fc1c62f..0000000 --- a/kvm-job-remove-outdated-AioContext-locking-comments.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 4ab25b33831fa207500179bd30f29388d81e4cce Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:10 -0500 -Subject: [PATCH 093/101] job: remove outdated AioContext locking comments - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [24/26] 15ff2928be82d6905c22619458487fbb72d6044a (kmwolf/centos-qemu-kvm) - -The AioContext lock no longer exists. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Message-ID: <20231205182011.1976568-14-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - include/qemu/job.h | 20 -------------------- - 1 file changed, 20 deletions(-) - -diff --git a/include/qemu/job.h b/include/qemu/job.h -index e502787dd8..9ea98b5927 100644 ---- a/include/qemu/job.h -+++ b/include/qemu/job.h -@@ -67,8 +67,6 @@ typedef struct Job { - - /** - * The completion function that will be called when the job completes. -- * Called with AioContext lock held, since many callback implementations -- * use bdrv_* functions that require to hold the lock. - */ - BlockCompletionFunc *cb; - -@@ -264,9 +262,6 @@ struct JobDriver { - * - * This callback will not be invoked if the job has already failed. - * If it fails, abort and then clean will be called. -- * -- * Called with AioContext lock held, since many callbacs implementations -- * use bdrv_* functions that require to hold the lock. - */ - int (*prepare)(Job *job); - -@@ -277,9 +272,6 @@ struct JobDriver { - * - * All jobs will complete with a call to either .commit() or .abort() but - * never both. -- * -- * Called with AioContext lock held, since many callback implementations -- * use bdrv_* functions that require to hold the lock. - */ - void (*commit)(Job *job); - -@@ -290,9 +282,6 @@ struct JobDriver { - * - * All jobs will complete with a call to either .commit() or .abort() but - * never both. -- * -- * Called with AioContext lock held, since many callback implementations -- * use bdrv_* functions that require to hold the lock. - */ - void (*abort)(Job *job); - -@@ -301,9 +290,6 @@ struct JobDriver { - * .commit() or .abort(). Regardless of which callback is invoked after - * completion, .clean() will always be called, even if the job does not - * belong to a transaction group. -- * -- * Called with AioContext lock held, since many callbacs implementations -- * use bdrv_* functions that require to hold the lock. - */ - void (*clean)(Job *job); - -@@ -318,17 +304,12 @@ struct JobDriver { - * READY). - * (If the callback is NULL, the job is assumed to terminate - * without I/O.) -- * -- * Called with AioContext lock held, since many callback implementations -- * use bdrv_* functions that require to hold the lock. - */ - bool (*cancel)(Job *job, bool force); - - - /** - * Called when the job is freed. -- * Called with AioContext lock held, since many callback implementations -- * use bdrv_* functions that require to hold the lock. - */ - void (*free)(Job *job); - }; -@@ -424,7 +405,6 @@ void job_ref_locked(Job *job); - * Release a reference that was previously acquired with job_ref_locked() or - * job_create(). If it's the last reference to the object, it will be freed. - * -- * Takes AioContext lock internally to invoke a job->driver callback. - * Called with job lock held. - */ - void job_unref_locked(Job *job); --- -2.39.3 - diff --git a/kvm-kconfig-Activate-IOMMUFD-for-s390x-machines.patch b/kvm-kconfig-Activate-IOMMUFD-for-s390x-machines.patch deleted file mode 100644 index 3e562b8..0000000 --- a/kvm-kconfig-Activate-IOMMUFD-for-s390x-machines.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 9c2eb4ab03903bc084c53ac29b60b8d2121c9fed Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 21 Nov 2023 16:44:19 +0800 -Subject: [PATCH 040/101] kconfig: Activate IOMMUFD for s390x machines -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [39/67] cf0ebe770b8db5916dd35247618c0a325dc1eaab (eauger1/centos-qemu-kvm) - -Signed-off-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Matthew Rosato -Reviewed-by: Eric Farman -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 73e2df669335047b542b67d37ade060a6ae40dd8) -Signed-off-by: Eric Auger ---- - hw/s390x/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/s390x/Kconfig b/hw/s390x/Kconfig -index 4c068d7960..26ad104485 100644 ---- a/hw/s390x/Kconfig -+++ b/hw/s390x/Kconfig -@@ -6,6 +6,7 @@ config S390_CCW_VIRTIO - imply VFIO_CCW - imply WDT_DIAG288 - imply PCIE_DEVICES -+ imply IOMMUFD - select PCI_EXPRESS - select S390_FLIC - select S390_FLIC_KVM if KVM --- -2.39.3 - diff --git a/kvm-memory-device-reintroduce-memory-region-size-check.patch b/kvm-memory-device-reintroduce-memory-region-size-check.patch deleted file mode 100644 index 5b531f5..0000000 --- a/kvm-memory-device-reintroduce-memory-region-size-check.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 633c6a52ac88526534466ae311522fe5447bcf91 Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Wed, 17 Jan 2024 14:55:54 +0100 -Subject: [PATCH 02/22] memory-device: reintroduce memory region size check - -RH-Author: David Hildenbrand -RH-MergeRequest: 221: memory-device: reintroduce memory region size check -RH-Jira: RHEL-20341 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Igor Mammedov -RH-Commit: [2/2] e9ff2339b0c07c3f48f5834c9c80cd6d4cbc8f71 - -JIRA: https://issues.redhat.com/browse/RHEL-20341 - -We used to check that the memory region size is multiples of the overall -requested address alignment for the device memory address. - -We removed that check, because there are cases (i.e., hv-balloon) where -devices unconditionally request an address alignment that has a very large -alignment (i.e., 32 GiB), but the actual memory device size might not be -multiples of that alignment. - -However, this change: - -(a) allows for some practically impossible DIMM sizes, like "1GB+1 byte". -(b) allows for DIMMs that partially cover hugetlb pages, previously - reported in [1]. - -Both scenarios don't make any sense: we might even waste memory. - -So let's reintroduce that check, but only check that the -memory region size is multiples of the memory region alignment (i.e., -page size, huge page size), but not any additional memory device -requirements communicated using md->get_min_alignment(). - -The following examples now fail again as expected: - -(a) 1M with 2M THP - qemu-system-x86_64 -m 4g,maxmem=16g,slots=1 -S -nodefaults -nographic \ - -object memory-backend-ram,id=mem1,size=1M \ - -device pc-dimm,id=dimm1,memdev=mem1 - -> backend memory size must be multiple of 0x200000 - -(b) 1G+1byte - - qemu-system-x86_64 -m 4g,maxmem=16g,slots=1 -S -nodefaults -nographic \ - -object memory-backend-ram,id=mem1,size=1073741825B \ - -device pc-dimm,id=dimm1,memdev=mem1 - -> backend memory size must be multiple of 0x200000 - -(c) Unliagned hugetlb size (2M) - - qemu-system-x86_64 -m 4g,maxmem=16g,slots=1 -S -nodefaults -nographic \ - -object memory-backend-file,id=mem1,mem-path=/dev/hugepages/tmp,size=511M \ - -device pc-dimm,id=dimm1,memdev=mem1 - backend memory size must be multiple of 0x200000 - -(d) Unliagned hugetlb size (1G) - - qemu-system-x86_64 -m 4g,maxmem=16g,slots=1 -S -nodefaults -nographic \ - -object memory-backend-file,id=mem1,mem-path=/dev/hugepages1G/tmp,size=2047M \ - -device pc-dimm,id=dimm1,memdev=mem1 - -> backend memory size must be multiple of 0x40000000 - -Note that this fix depends on a hv-balloon change to communicate its -additional alignment requirements using get_min_alignment() instead of -through the memory region. - -[1] https://lkml.kernel.org/r/f77d641d500324525ac036fe1827b3070de75fc1.1701088320.git.mprivozn@redhat.com - -Message-ID: <20240117135554.787344-3-david@redhat.com> -Reported-by: Zhenyu Zhang -Reported-by: Michal Privoznik -Fixes: eb1b7c4bd413 ("memory-device: Drop size alignment check") -Tested-by: Zhenyu Zhang -Tested-by: Mario Casquero -Reviewed-by: Maciej S. Szmigiero -Signed-off-by: David Hildenbrand -(cherry picked from commit 540a1abbf0b243e4cfb4333c5d30a041f7080ba4) -Signed-off-by: David Hildenbrand ---- - hw/mem/memory-device.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c -index a1b1af26bc..e098585cda 100644 ---- a/hw/mem/memory-device.c -+++ b/hw/mem/memory-device.c -@@ -374,6 +374,20 @@ void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms, - goto out; - } - -+ /* -+ * We always want the memory region size to be multiples of the memory -+ * region alignment: for example, DIMMs with 1G+1byte size don't make -+ * any sense. Note that we don't check that the size is multiples -+ * of any additional alignment requirements the memory device might -+ * have when it comes to the address in physical address space. -+ */ -+ if (!QEMU_IS_ALIGNED(memory_region_size(mr), -+ memory_region_get_alignment(mr))) { -+ error_setg(errp, "backend memory size must be multiple of 0x%" -+ PRIx64, memory_region_get_alignment(mr)); -+ return; -+ } -+ - if (legacy_align) { - align = *legacy_align; - } else { --- -2.39.3 - diff --git a/kvm-mirror-Don-t-call-job_pause_point-under-graph-lock.patch b/kvm-mirror-Don-t-call-job_pause_point-under-graph-lock.patch deleted file mode 100644 index 871a80e..0000000 --- a/kvm-mirror-Don-t-call-job_pause_point-under-graph-lock.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 21cadc8ed200ad9af13b217b441b9f12cd2163ee Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Wed, 13 Mar 2024 16:30:00 +0100 -Subject: [PATCH 1/4] mirror: Don't call job_pause_point() under graph lock - -RH-Author: Kevin Wolf -RH-MergeRequest: 231: Fix deadlock and crash during storage migration -RH-Jira: RHEL-28125 -RH-Acked-by: Hanna Czenczek -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [1/3] 093910fcd5ea1516d0ed48a9cd73dad6170590f3 (kmwolf/centos-qemu-kvm) - -Calling job_pause_point() while holding the graph reader lock -potentially results in a deadlock: bdrv_graph_wrlock() first drains -everything, including the mirror job, which pauses it. The job is only -unpaused at the end of the drain section, which is when the graph writer -lock has been successfully taken. However, if the job happens to be -paused at a pause point where it still holds the reader lock, the writer -lock can't be taken as long as the job is still paused. - -Mark job_pause_point() as GRAPH_UNLOCKED and fix mirror accordingly. - -Cc: qemu-stable@nongnu.org -Buglink: https://issues.redhat.com/browse/RHEL-28125 -Fixes: 004915a96a7a ("block: Protect bs->backing with graph_lock") -Signed-off-by: Kevin Wolf -Message-ID: <20240313153000.33121-1-kwolf@redhat.com> -Reviewed-by: Eric Blake -Signed-off-by: Kevin Wolf -(cherry picked from commit ae5a40e8581185654a667fbbf7e4adbc2a2a3e45) -Signed-off-by: Kevin Wolf ---- - block/mirror.c | 10 ++++++---- - include/qemu/job.h | 2 +- - 2 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/block/mirror.c b/block/mirror.c -index 5145eb53e1..1bdce3b657 100644 ---- a/block/mirror.c -+++ b/block/mirror.c -@@ -479,9 +479,9 @@ static unsigned mirror_perform(MirrorBlockJob *s, int64_t offset, - return bytes_handled; - } - --static void coroutine_fn GRAPH_RDLOCK mirror_iteration(MirrorBlockJob *s) -+static void coroutine_fn GRAPH_UNLOCKED mirror_iteration(MirrorBlockJob *s) - { -- BlockDriverState *source = s->mirror_top_bs->backing->bs; -+ BlockDriverState *source; - MirrorOp *pseudo_op; - int64_t offset; - /* At least the first dirty chunk is mirrored in one iteration. */ -@@ -489,6 +489,10 @@ static void coroutine_fn GRAPH_RDLOCK mirror_iteration(MirrorBlockJob *s) - bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)); - int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES); - -+ bdrv_graph_co_rdlock(); -+ source = s->mirror_top_bs->backing->bs; -+ bdrv_graph_co_rdunlock(); -+ - bdrv_dirty_bitmap_lock(s->dirty_bitmap); - offset = bdrv_dirty_iter_next(s->dbi); - if (offset < 0) { -@@ -1066,9 +1070,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp) - mirror_wait_for_free_in_flight_slot(s); - continue; - } else if (cnt != 0) { -- bdrv_graph_co_rdlock(); - mirror_iteration(s); -- bdrv_graph_co_rdunlock(); - } - } - -diff --git a/include/qemu/job.h b/include/qemu/job.h -index 9ea98b5927..2b873f2576 100644 ---- a/include/qemu/job.h -+++ b/include/qemu/job.h -@@ -483,7 +483,7 @@ void job_enter(Job *job); - * - * Called with job_mutex *not* held. - */ --void coroutine_fn job_pause_point(Job *job); -+void coroutine_fn GRAPH_UNLOCKED job_pause_point(Job *job); - - /** - * @job: The job that calls the function. --- -2.39.3 - diff --git a/kvm-monitor-only-run-coroutine-commands-in-qemu_aio_cont.patch b/kvm-monitor-only-run-coroutine-commands-in-qemu_aio_cont.patch deleted file mode 100644 index 345a2b4..0000000 --- a/kvm-monitor-only-run-coroutine-commands-in-qemu_aio_cont.patch +++ /dev/null @@ -1,1630 +0,0 @@ -From 972e553e605e8916fc47c2d51cdbde940fd7d855 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 18 Jan 2024 09:48:23 -0500 -Subject: [PATCH 13/22] monitor: only run coroutine commands in - qemu_aio_context - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [9/17] ec5690fcade04a88bd1815bf2ae0377e80fe3d51 (stefanha/centos-stream-qemu-kvm) - -monitor_qmp_dispatcher_co() runs in the iohandler AioContext that is not -polled during nested event loops. The coroutine currently reschedules -itself in the main loop's qemu_aio_context AioContext, which is polled -during nested event loops. One known problem is that QMP device-add -calls drain_call_rcu(), which temporarily drops the BQL, leading to all -sorts of havoc like other vCPU threads re-entering device emulation code -while another vCPU thread is waiting in device emulation code with -aio_poll(). - -Paolo Bonzini suggested running non-coroutine QMP handlers in the -iohandler AioContext. This avoids trouble with nested event loops. His -original idea was to move coroutine rescheduling to -monitor_qmp_dispatch(), but I resorted to moving it to qmp_dispatch() -because we don't know if the QMP handler needs to run in coroutine -context in monitor_qmp_dispatch(). monitor_qmp_dispatch() would have -been nicer since it's associated with the monitor implementation and not -as general as qmp_dispatch(), which is also used by qemu-ga. - -A number of qemu-iotests need updated .out files because the order of -QMP events vs QMP responses has changed. - -Solves Issue #1933. - -Cc: qemu-stable@nongnu.org -Fixes: 7bed89958bfbf40df9ca681cefbdca63abdde39d ("device_core: use drain_call_rcu in in qmp_device_add") -Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2215192 -Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2214985 -Buglink: https://issues.redhat.com/browse/RHEL-17369 -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240118144823.1497953-4-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Tested-by: Fiona Ebner -Signed-off-by: Kevin Wolf -(cherry picked from commit effd60c878176bcaf97fa7ce2b12d04bb8ead6f7) -Signed-off-by: Stefan Hajnoczi ---- - monitor/qmp.c | 17 ---- - qapi/qmp-dispatch.c | 24 +++++- - tests/qemu-iotests/060.out | 4 +- - tests/qemu-iotests/071.out | 4 +- - tests/qemu-iotests/081.out | 16 ++-- - tests/qemu-iotests/087.out | 12 +-- - tests/qemu-iotests/108.out | 2 +- - tests/qemu-iotests/109 | 4 +- - tests/qemu-iotests/109.out | 78 ++++++++----------- - tests/qemu-iotests/117.out | 2 +- - tests/qemu-iotests/120.out | 2 +- - tests/qemu-iotests/127.out | 2 +- - tests/qemu-iotests/140.out | 2 +- - tests/qemu-iotests/143.out | 2 +- - tests/qemu-iotests/156.out | 2 +- - tests/qemu-iotests/176.out | 16 ++-- - tests/qemu-iotests/182.out | 2 +- - tests/qemu-iotests/183.out | 4 +- - tests/qemu-iotests/184.out | 32 ++++---- - tests/qemu-iotests/185 | 6 +- - tests/qemu-iotests/185.out | 45 +++++++++-- - tests/qemu-iotests/191.out | 16 ++-- - tests/qemu-iotests/195.out | 16 ++-- - tests/qemu-iotests/223.out | 12 +-- - tests/qemu-iotests/227.out | 32 ++++---- - tests/qemu-iotests/247.out | 2 +- - tests/qemu-iotests/273.out | 8 +- - tests/qemu-iotests/308 | 4 +- - tests/qemu-iotests/308.out | 4 +- - tests/qemu-iotests/tests/file-io-error | 5 +- - tests/qemu-iotests/tests/iothreads-resize.out | 2 +- - tests/qemu-iotests/tests/qsd-jobs.out | 4 +- - 32 files changed, 205 insertions(+), 178 deletions(-) - -diff --git a/monitor/qmp.c b/monitor/qmp.c -index 6eee450fe4..a239945e8d 100644 ---- a/monitor/qmp.c -+++ b/monitor/qmp.c -@@ -321,14 +321,6 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data) - qemu_coroutine_yield(); - } - -- /* -- * Move the coroutine from iohandler_ctx to qemu_aio_context for -- * executing the command handler so that it can make progress if it -- * involves an AIO_WAIT_WHILE(). -- */ -- aio_co_schedule(qemu_get_aio_context(), qmp_dispatcher_co); -- qemu_coroutine_yield(); -- - /* Process request */ - if (req_obj->req) { - if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_IN_BAND)) { -@@ -355,15 +347,6 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data) - } - - qmp_request_free(req_obj); -- -- /* -- * Yield and reschedule so the main loop stays responsive. -- * -- * Move back to iohandler_ctx so that nested event loops for -- * qemu_aio_context don't start new monitor commands. -- */ -- aio_co_schedule(iohandler_get_aio_context(), qmp_dispatcher_co); -- qemu_coroutine_yield(); - } - qatomic_set(&qmp_dispatcher_co, NULL); - } -diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c -index 555528b6bb..176b549473 100644 ---- a/qapi/qmp-dispatch.c -+++ b/qapi/qmp-dispatch.c -@@ -206,9 +206,31 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ - assert(!(oob && qemu_in_coroutine())); - assert(monitor_cur() == NULL); - if (!!(cmd->options & QCO_COROUTINE) == qemu_in_coroutine()) { -+ if (qemu_in_coroutine()) { -+ /* -+ * Move the coroutine from iohandler_ctx to qemu_aio_context for -+ * executing the command handler so that it can make progress if it -+ * involves an AIO_WAIT_WHILE(). -+ */ -+ aio_co_schedule(qemu_get_aio_context(), qemu_coroutine_self()); -+ qemu_coroutine_yield(); -+ } -+ - monitor_set_cur(qemu_coroutine_self(), cur_mon); - cmd->fn(args, &ret, &err); - monitor_set_cur(qemu_coroutine_self(), NULL); -+ -+ if (qemu_in_coroutine()) { -+ /* -+ * Yield and reschedule so the main loop stays responsive. -+ * -+ * Move back to iohandler_ctx so that nested event loops for -+ * qemu_aio_context don't start new monitor commands. -+ */ -+ aio_co_schedule(iohandler_get_aio_context(), -+ qemu_coroutine_self()); -+ qemu_coroutine_yield(); -+ } - } else { - /* - * Actual context doesn't match the one the command needs. -@@ -232,7 +254,7 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ - .errp = &err, - .co = qemu_coroutine_self(), - }; -- aio_bh_schedule_oneshot(qemu_get_aio_context(), do_qmp_dispatch_bh, -+ aio_bh_schedule_oneshot(iohandler_get_aio_context(), do_qmp_dispatch_bh, - &data); - qemu_coroutine_yield(); - } -diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out -index 329977d9b9..a37bf446e9 100644 ---- a/tests/qemu-iotests/060.out -+++ b/tests/qemu-iotests/060.out -@@ -421,8 +421,8 @@ QMP_VERSION - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "none0", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "node-name": "drive", "fatal": true, "size": 65536}} - write failed: Input/output error - {"return": ""} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - === Testing incoming inactive corrupted image === - -@@ -432,8 +432,8 @@ QMP_VERSION - qcow2: Image is corrupt: L2 table offset 0x2a2a2a00 unaligned (L1 index: 0); further non-fatal corruption events will be suppressed - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "node-name": "drive", "fatal": false}} - {"return": ""} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - corrupt: false - *** done -diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out -index bca0c02f5c..a2923b05c2 100644 ---- a/tests/qemu-iotests/071.out -+++ b/tests/qemu-iotests/071.out -@@ -45,8 +45,8 @@ QMP_VERSION - {"return": {}} - read failed: Input/output error - {"return": ""} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - - === Testing blkverify on existing block device === -@@ -84,9 +84,9 @@ wrote 512/512 bytes at offset 0 - {"return": ""} - read failed: Input/output error - {"return": ""} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - QEMU_PROG: Failed to flush the L2 table cache: Input/output error - QEMU_PROG: Failed to flush the refcount block cache: Input/output error -+{"return": {}} - - *** done -diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out -index 615c083549..aba85ea564 100644 ---- a/tests/qemu-iotests/081.out -+++ b/tests/qemu-iotests/081.out -@@ -35,8 +35,8 @@ QMP_VERSION - read 10485760/10485760 bytes at offset 0 - 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - {"return": ""} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - - == using quorum rewrite corrupted mode == -@@ -67,8 +67,8 @@ QMP_VERSION - read 10485760/10485760 bytes at offset 0 - 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - {"return": ""} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - -- checking that the image has been corrected -- - read 10485760/10485760 bytes at offset 0 -@@ -106,8 +106,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - Testing: - QMP_VERSION -@@ -115,8 +115,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"error": {"class": "GenericError", "desc": "Cannot add a child to a quorum in blkverify mode"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - - == dynamically removing a child from a quorum == -@@ -125,31 +125,31 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - Testing: - QMP_VERSION - {"return": {}} - {"return": {}} - {"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - Testing: - QMP_VERSION - {"return": {}} - {"error": {"class": "GenericError", "desc": "blkverify=on can only be set if there are exactly two files and vote-threshold is 2"}} - {"error": {"class": "GenericError", "desc": "Cannot find device='drive0-quorum' nor node-name='drive0-quorum'"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - Testing: - QMP_VERSION - {"return": {}} - {"return": {}} - {"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - *** done -diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out -index e1c23a6983..97b6d8036d 100644 ---- a/tests/qemu-iotests/087.out -+++ b/tests/qemu-iotests/087.out -@@ -7,8 +7,8 @@ Testing: - QMP_VERSION - {"return": {}} - {"error": {"class": "GenericError", "desc": "'node-name' must be specified for the root node"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - - === Duplicate ID === -@@ -18,8 +18,8 @@ QMP_VERSION - {"return": {}} - {"error": {"class": "GenericError", "desc": "node-name=disk is conflicting with a device id"}} - {"error": {"class": "GenericError", "desc": "Duplicate nodes with node-name='test-node'"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - - === aio=native without O_DIRECT === -@@ -28,8 +28,8 @@ Testing: - QMP_VERSION - {"return": {}} - {"error": {"class": "GenericError", "desc": "aio=native was specified, but it requires cache.direct=on, which was not specified."}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - - === Encrypted image QCow === -@@ -40,8 +40,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"error": {"class": "GenericError", "desc": "Use of AES-CBC encrypted IMGFMT images is no longer supported in system emulators"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - - === Encrypted image LUKS === -@@ -52,8 +52,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - - === Missing driver === -@@ -63,7 +63,7 @@ Testing: -S - QMP_VERSION - {"return": {}} - {"error": {"class": "GenericError", "desc": "Parameter 'driver' is missing"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - *** done -diff --git a/tests/qemu-iotests/108.out b/tests/qemu-iotests/108.out -index b5401d788d..b9c876b394 100644 ---- a/tests/qemu-iotests/108.out -+++ b/tests/qemu-iotests/108.out -@@ -173,8 +173,8 @@ OK: Reftable is where we expect it - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "create"}} - {"return": {}} - { "execute": "quit" } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - wrote 65536/65536 bytes at offset 0 - 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109 -index e207a555f3..0fb580f9a5 100755 ---- a/tests/qemu-iotests/109 -+++ b/tests/qemu-iotests/109 -@@ -57,13 +57,13 @@ run_qemu() - _launch_qemu -drive file="${source_img}",format=raw,cache=${CACHEMODE},aio=${AIOMODE},id=src - _send_qemu_cmd $QEMU_HANDLE "{ 'execute': 'qmp_capabilities' }" "return" - -- _send_qemu_cmd $QEMU_HANDLE \ -+ capture_events="$qmp_event" _send_qemu_cmd $QEMU_HANDLE \ - "{'execute':'drive-mirror', 'arguments':{ - 'device': 'src', 'target': '$raw_img', $qmp_format - 'mode': 'existing', 'sync': 'full'}}" \ - "return" - -- _send_qemu_cmd $QEMU_HANDLE '' "$qmp_event" -+ capture_events="$qmp_event JOB_STATUS_CHANGE" _wait_event $QEMU_HANDLE "$qmp_event" - if test "$qmp_event" = BLOCK_JOB_ERROR; then - _send_qemu_cmd $QEMU_HANDLE '' '"status": "null"' - fi -diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out -index 965c9a6a0a..3ae8552ff7 100644 ---- a/tests/qemu-iotests/109.out -+++ b/tests/qemu-iotests/109.out -@@ -7,7 +7,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -23,8 +23,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -35,12 +35,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 1024, "offset": 1024, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -50,6 +48,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Writing a qcow2 header into raw === -@@ -59,7 +58,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -75,8 +74,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -87,12 +86,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 197120, "offset": 197120, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -102,6 +99,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Writing a qed header into raw === -@@ -111,7 +109,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -127,8 +125,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -139,12 +137,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 327680, "offset": 327680, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -154,6 +150,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Writing a vdi header into raw === -@@ -163,7 +160,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -179,8 +176,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -191,12 +188,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 1024, "offset": 1024, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -206,6 +201,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Writing a vmdk header into raw === -@@ -215,7 +211,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -231,8 +227,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -243,12 +239,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 65536, "offset": 65536, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -258,6 +252,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Writing a vpc header into raw === -@@ -267,7 +262,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -283,8 +278,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -295,12 +290,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 2560, "offset": 2560, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -310,6 +303,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Copying sample image empty.bochs into raw === -@@ -318,7 +312,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -334,8 +328,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -346,12 +340,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 2560, "offset": 2560, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -361,6 +353,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Copying sample image iotest-dirtylog-10G-4M.vhdx into raw === -@@ -369,7 +362,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -385,8 +378,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -397,12 +390,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 31457280, "offset": 31457280, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -412,6 +403,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Copying sample image parallels-v1 into raw === -@@ -420,7 +412,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -436,8 +428,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -448,12 +440,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 327680, "offset": 327680, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -463,6 +453,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Copying sample image simple-pattern.cloop into raw === -@@ -471,7 +462,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -487,8 +478,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"execute":"query-block-jobs"} - {"return": []} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 512/512 bytes at offset 0 - 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - { 'execute': 'qmp_capabilities' } -@@ -499,12 +490,10 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 2048, "offset": 2048, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -514,6 +503,7 @@ read 512/512 bytes at offset 0 - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - - === Write legitimate MBR into raw === -@@ -522,7 +512,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE - { 'execute': 'qmp_capabilities' } - {"return": {}} - {'execute':'drive-mirror', 'arguments':{ -- 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', -+ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', - 'mode': 'existing', 'sync': 'full'}} - WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. - Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. -@@ -530,12 +520,10 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 512, "offset": 512, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -545,6 +533,7 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - { 'execute': 'qmp_capabilities' } - {"return": {}} -@@ -554,12 +543,10 @@ Images are identical. - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} - {"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} - {"execute":"query-block-jobs"} - {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 512, "offset": 512, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror", "actively-synced": false}]} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} -@@ -569,5 +556,6 @@ Images are identical. - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} -+{"return": {}} - Images are identical. - *** done -diff --git a/tests/qemu-iotests/117.out b/tests/qemu-iotests/117.out -index 735ffd25c6..1cea9e0217 100644 ---- a/tests/qemu-iotests/117.out -+++ b/tests/qemu-iotests/117.out -@@ -18,8 +18,8 @@ wrote 65536/65536 bytes at offset 0 - 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - {"return": ""} - { 'execute': 'quit' } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - No errors were found on the image. - read 65536/65536 bytes at offset 0 - 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -diff --git a/tests/qemu-iotests/120.out b/tests/qemu-iotests/120.out -index 0744c1f136..35d84a5bc5 100644 ---- a/tests/qemu-iotests/120.out -+++ b/tests/qemu-iotests/120.out -@@ -5,8 +5,8 @@ QMP_VERSION - wrote 65536/65536 bytes at offset 0 - 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - {"return": ""} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - read 65536/65536 bytes at offset 0 - 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - read 65536/65536 bytes at offset 0 -diff --git a/tests/qemu-iotests/127.out b/tests/qemu-iotests/127.out -index 1685c4850a..dd8c4a8aa9 100644 ---- a/tests/qemu-iotests/127.out -+++ b/tests/qemu-iotests/127.out -@@ -28,6 +28,6 @@ wrote 42/42 bytes at offset 0 - { 'execute': 'quit' } - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "mirror"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "mirror"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - *** done -diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out -index 312f76d5da..32866440ae 100644 ---- a/tests/qemu-iotests/140.out -+++ b/tests/qemu-iotests/140.out -@@ -19,6 +19,6 @@ read 65536/65536 bytes at offset 0 - qemu-io: can't open device nbd+unix:///drv?socket=SOCK_DIR/nbd: Requested export not available - server reported: export 'drv' not present - { 'execute': 'quit' } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - *** done -diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out -index 9ec5888e0e..d6afa32abc 100644 ---- a/tests/qemu-iotests/143.out -+++ b/tests/qemu-iotests/143.out -@@ -10,6 +10,6 @@ server reported: export 'no_such_export' not present - qemu-io: can't open device nbd+unix:///aa--aa1?socket=SOCK_DIR/nbd: Requested export not available - server reported: export 'aa--aa...' not present - { 'execute': 'quit' } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - *** done -diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out -index 4a22f0c41a..07e5e83f5d 100644 ---- a/tests/qemu-iotests/156.out -+++ b/tests/qemu-iotests/156.out -@@ -72,8 +72,8 @@ read 65536/65536 bytes at offset 196608 - {"return": ""} - - { 'execute': 'quit' } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - read 65536/65536 bytes at offset 0 - 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -diff --git a/tests/qemu-iotests/176.out b/tests/qemu-iotests/176.out -index 9d09b60452..45e9153ef3 100644 ---- a/tests/qemu-iotests/176.out -+++ b/tests/qemu-iotests/176.out -@@ -169,8 +169,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - wrote 196608/196608 bytes at offset 2147287040 - 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - wrote 131072/131072 bytes at offset 2147352576 -@@ -206,8 +206,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {"sha256": HASH}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - === Test pass bitmap.1 === - -@@ -218,8 +218,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - wrote 196608/196608 bytes at offset 2147287040 - 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - wrote 131072/131072 bytes at offset 2147352576 -@@ -256,8 +256,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {"sha256": HASH}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - === Test pass bitmap.2 === - -@@ -268,8 +268,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - wrote 196608/196608 bytes at offset 2147287040 - 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - wrote 131072/131072 bytes at offset 2147352576 -@@ -306,8 +306,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {"sha256": HASH}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - === Test pass bitmap.3 === - -@@ -318,8 +318,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - wrote 196608/196608 bytes at offset 2147287040 - 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - wrote 131072/131072 bytes at offset 2147352576 -@@ -353,6 +353,6 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {"sha256": HASH}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - *** done -diff --git a/tests/qemu-iotests/182.out b/tests/qemu-iotests/182.out -index 57f7265458..83fc1a4797 100644 ---- a/tests/qemu-iotests/182.out -+++ b/tests/qemu-iotests/182.out -@@ -53,6 +53,6 @@ Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 cluster_size=65536 extended_l2= - {'execute': 'qmp_capabilities'} - {"return": {}} - {'execute': 'quit'} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - *** done -diff --git a/tests/qemu-iotests/183.out b/tests/qemu-iotests/183.out -index fd9c2e52a5..51aa41c888 100644 ---- a/tests/qemu-iotests/183.out -+++ b/tests/qemu-iotests/183.out -@@ -53,11 +53,11 @@ wrote 65536/65536 bytes at offset 1048576 - === Shut down and check image === - - {"execute":"quit"} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"return": {}} - {"execute":"quit"} --{"return": {}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - No errors were found on the image. - No errors were found on the image. - wrote 65536/65536 bytes at offset 1048576 -diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out -index 77e5489d65..e8f631f853 100644 ---- a/tests/qemu-iotests/184.out -+++ b/tests/qemu-iotests/184.out -@@ -89,10 +89,6 @@ Testing: - "return": [ - ] - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -104,6 +100,10 @@ Testing: - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - - == property changes in ThrottleGroup == -@@ -169,10 +169,6 @@ Testing: - "iops-total-max": 0 - } - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -184,6 +180,10 @@ Testing: - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - - == object creation/set errors == -@@ -211,10 +211,6 @@ Testing: - "desc": "bps/iops/max total values and read/write values cannot be used at the same time" - } - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -226,6 +222,10 @@ Testing: - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - - == don't specify group == -@@ -247,10 +247,6 @@ Testing: - "desc": "Parameter 'throttle-group' is missing" - } - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -262,6 +258,10 @@ Testing: - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - - *** done -diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185 -index 2ae0a85bbf..17489fb91c 100755 ---- a/tests/qemu-iotests/185 -+++ b/tests/qemu-iotests/185 -@@ -344,14 +344,14 @@ wait_for_job_and_quit() { - - sleep 1 - -+ # List of expected events -+ capture_events='BLOCK_JOB_CANCELLED JOB_STATUS_CHANGE SHUTDOWN' -+ - _send_qemu_cmd $h \ - '{"execute": "quit"}' \ - 'return' - -- # List of expected events -- capture_events='BLOCK_JOB_CANCELLED JOB_STATUS_CHANGE SHUTDOWN' - _wait_event $h 'SHUTDOWN' -- QEMU_EVENTS= # Ignore all JOB_STATUS_CHANGE events that came before SHUTDOWN - _wait_event $h 'JOB_STATUS_CHANGE' # standby - _wait_event $h 'JOB_STATUS_CHANGE' # ready - _wait_event $h 'JOB_STATUS_CHANGE' # standby -diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out -index 7292c26bae..6af0953c4d 100644 ---- a/tests/qemu-iotests/185.out -+++ b/tests/qemu-iotests/185.out -@@ -40,9 +40,16 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off comp - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} - {"return": {}} - { 'execute': 'quit' } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "disk"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 524288, "speed": 65536, "type": "commit"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "disk"}} -+{"return": {}} - - === Start active commit job and exit qemu === - -@@ -56,9 +63,16 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off comp - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} - {"return": {}} - { 'execute': 'quit' } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "disk"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 4194304, "offset": 4194304, "speed": 65536, "type": "commit"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "disk"}} -+{"return": {}} - - === Start mirror job and exit qemu === - -@@ -75,9 +89,16 @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} - {"return": {}} - { 'execute': 'quit' } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "disk"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 4194304, "offset": 4194304, "speed": 65536, "type": "mirror"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "disk"}} -+{"return": {}} - - === Start backup job and exit qemu === - -@@ -97,9 +118,16 @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} - {"return": {}} - { 'execute': 'quit' } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "disk"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 65536, "speed": 65536, "type": "backup"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "disk"}} -+{"return": {}} - - === Start streaming job and exit qemu === - -@@ -112,9 +140,16 @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} - {"return": {}} - { 'execute': 'quit' } --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "disk"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 524288, "speed": 65536, "type": "stream"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "disk"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "disk"}} -+{"return": {}} - No errors were found on the image. - - === Start mirror to throttled QSD and exit qemu === -diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out -index ea88777374..c3309e4bc6 100644 ---- a/tests/qemu-iotests/191.out -+++ b/tests/qemu-iotests/191.out -@@ -378,10 +378,6 @@ wrote 65536/65536 bytes at offset 1048576 - ] - } - { 'execute': 'quit' } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -393,6 +389,10 @@ wrote 65536/65536 bytes at offset 1048576 - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - image: TEST_DIR/t.IMGFMT - file format: IMGFMT - virtual size: 64 MiB (67108864 bytes) -@@ -796,10 +796,6 @@ wrote 65536/65536 bytes at offset 1048576 - ] - } - { 'execute': 'quit' } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -811,6 +807,10 @@ wrote 65536/65536 bytes at offset 1048576 - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - image: TEST_DIR/t.IMGFMT - file format: IMGFMT - virtual size: 64 MiB (67108864 bytes) -diff --git a/tests/qemu-iotests/195.out b/tests/qemu-iotests/195.out -index ec84df5012..91717d302e 100644 ---- a/tests/qemu-iotests/195.out -+++ b/tests/qemu-iotests/195.out -@@ -17,10 +17,6 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid - "return": { - } - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -32,6 +28,10 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - image: TEST_DIR/t.IMGFMT.mid - file format: IMGFMT -@@ -55,10 +55,6 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top - "return": { - } - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -70,6 +66,10 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - image: TEST_DIR/t.IMGFMT - file format: IMGFMT -diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out -index e5e7f42caa..5f5b42e2dc 100644 ---- a/tests/qemu-iotests/223.out -+++ b/tests/qemu-iotests/223.out -@@ -11,8 +11,8 @@ QMP_VERSION - {"return": {}} - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - - === Write part of the file under active bitmap === -@@ -145,14 +145,14 @@ read 2097152/2097152 bytes at offset 2097152 - - {"execute":"nbd-server-remove", - "arguments":{"name":"n"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n"}} - {"return": {}} - {"execute":"nbd-server-remove", - "arguments":{"name":"n2"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n2"}} - {"return": {}} - {"execute":"nbd-server-remove", - "arguments":{"name":"n2"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n2"}} - {"error": {"class": "GenericError", "desc": "Export 'n2' is not found"}} - {"execute":"nbd-server-stop"} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n3"}} -@@ -267,14 +267,14 @@ read 2097152/2097152 bytes at offset 2097152 - - {"execute":"nbd-server-remove", - "arguments":{"name":"n"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n"}} - {"return": {}} - {"execute":"nbd-server-remove", - "arguments":{"name":"n2"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n2"}} - {"return": {}} - {"execute":"nbd-server-remove", - "arguments":{"name":"n2"}} --{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n2"}} - {"error": {"class": "GenericError", "desc": "Export 'n2' is not found"}} - {"execute":"nbd-server-stop"} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "n3"}} -@@ -282,8 +282,8 @@ read 2097152/2097152 bytes at offset 2097152 - {"execute":"nbd-server-stop"} - {"error": {"class": "GenericError", "desc": "NBD server not running"}} - {"execute":"quit"} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - - === Use qemu-nbd as server === - -diff --git a/tests/qemu-iotests/227.out b/tests/qemu-iotests/227.out -index a947b1a87d..d6a1d4ecb6 100644 ---- a/tests/qemu-iotests/227.out -+++ b/tests/qemu-iotests/227.out -@@ -54,10 +54,6 @@ Testing: -drive driver=null-co,read-zeroes=on,if=virtio - } - ] - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -69,6 +65,10 @@ Testing: -drive driver=null-co,read-zeroes=on,if=virtio - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - - === blockstats with -drive if=none === -@@ -124,10 +124,6 @@ Testing: -drive driver=null-co,if=none - } - ] - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -139,6 +135,10 @@ Testing: -drive driver=null-co,if=none - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - - === blockstats with -blockdev === -@@ -155,10 +155,6 @@ Testing: -blockdev driver=null-co,node-name=null - "return": [ - ] - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -170,6 +166,10 @@ Testing: -blockdev driver=null-co,node-name=null - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - - === blockstats with -blockdev and -device === -@@ -226,10 +226,6 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b - } - ] - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -241,5 +237,9 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - *** done -diff --git a/tests/qemu-iotests/247.out b/tests/qemu-iotests/247.out -index e909e83994..7d252e7fe4 100644 ---- a/tests/qemu-iotests/247.out -+++ b/tests/qemu-iotests/247.out -@@ -17,6 +17,6 @@ QMP_VERSION - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 134217728, "offset": 134217728, "speed": 0, "type": "commit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - *** done -diff --git a/tests/qemu-iotests/273.out b/tests/qemu-iotests/273.out -index 6a74a8138b..71843f02de 100644 ---- a/tests/qemu-iotests/273.out -+++ b/tests/qemu-iotests/273.out -@@ -282,10 +282,6 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev - ] - } - } --{ -- "return": { -- } --} - { - "timestamp": { - "seconds": TIMESTAMP, -@@ -297,5 +293,9 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev - "reason": "host-qmp-quit" - } - } -+{ -+ "return": { -+ } -+} - - *** done -diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308 -index de12b2b1b9..ea81dc496a 100755 ---- a/tests/qemu-iotests/308 -+++ b/tests/qemu-iotests/308 -@@ -77,6 +77,7 @@ fuse_export_add() - # $1: Export ID - fuse_export_del() - { -+ capture_events="BLOCK_EXPORT_DELETED" \ - _send_qemu_cmd $QEMU_HANDLE \ - "{'execute': 'block-export-del', - 'arguments': { -@@ -84,8 +85,7 @@ fuse_export_del() - } }" \ - 'return' - -- _send_qemu_cmd $QEMU_HANDLE \ -- '' \ -+ _wait_event $QEMU_HANDLE \ - 'BLOCK_EXPORT_DELETED' - } - -diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out -index d5767133b1..e5e233691d 100644 ---- a/tests/qemu-iotests/308.out -+++ b/tests/qemu-iotests/308.out -@@ -165,9 +165,9 @@ OK: Post-truncate image size is as expected - - === Tear down === - {'execute': 'quit'} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}} -+{"return": {}} - - === Compare copy with original === - Images are identical. -@@ -201,9 +201,9 @@ wrote 67108864/67108864 bytes at offset 0 - read 67108864/67108864 bytes at offset 0 - 64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - {'execute': 'quit'} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export"}} -+{"return": {}} - read 67108864/67108864 bytes at offset 0 - 64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - *** done -diff --git a/tests/qemu-iotests/tests/file-io-error b/tests/qemu-iotests/tests/file-io-error -index 88ee5f670c..fb8db73b31 100755 ---- a/tests/qemu-iotests/tests/file-io-error -+++ b/tests/qemu-iotests/tests/file-io-error -@@ -99,13 +99,12 @@ echo - $QEMU_IO -f file -c 'write 0 64M' "$TEST_DIR/fuse-export" | _filter_qemu_io - echo - --_send_qemu_cmd $QEMU_HANDLE \ -+capture_events=BLOCK_EXPORT_DELETED _send_qemu_cmd $QEMU_HANDLE \ - "{'execute': 'block-export-del', - 'arguments': {'id': 'exp0'}}" \ - 'return' - --_send_qemu_cmd $QEMU_HANDLE \ -- '' \ -+_wait_event $QEMU_HANDLE \ - 'BLOCK_EXPORT_DELETED' - - _send_qemu_cmd $QEMU_HANDLE \ -diff --git a/tests/qemu-iotests/tests/iothreads-resize.out b/tests/qemu-iotests/tests/iothreads-resize.out -index 2ca5a9d964..2967ac8f0d 100644 ---- a/tests/qemu-iotests/tests/iothreads-resize.out -+++ b/tests/qemu-iotests/tests/iothreads-resize.out -@@ -3,8 +3,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 - QMP_VERSION - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -+{"return": {}} - image: TEST_DIR/t.IMGFMT - file format: IMGFMT - virtual size: 128 MiB (134217728 bytes) -diff --git a/tests/qemu-iotests/tests/qsd-jobs.out b/tests/qemu-iotests/tests/qsd-jobs.out -index c1bc9b8356..aa6b6d1aef 100644 ---- a/tests/qemu-iotests/tests/qsd-jobs.out -+++ b/tests/qemu-iotests/tests/qsd-jobs.out -@@ -7,8 +7,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/ - QMP_VERSION - {"return": {}} - {"return": {}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}} -+{"return": {}} - - === Streaming can't get permission on base node === - -@@ -17,6 +17,6 @@ QMP_VERSION - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} - {"error": {"class": "GenericError", "desc": "Permission conflict on node 'fmt_base': permissions 'write' are both required by an unnamed block device (uses node 'fmt_base' as 'root' child) and unshared by stream job 'job0' (uses node 'fmt_base' as 'intermediate node' child)."}} --{"return": {}} - {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export1"}} -+{"return": {}} - *** done --- -2.39.3 - diff --git a/kvm-nbd-server-Fix-race-in-draining-the-export.patch b/kvm-nbd-server-Fix-race-in-draining-the-export.patch deleted file mode 100644 index 7298992..0000000 --- a/kvm-nbd-server-Fix-race-in-draining-the-export.patch +++ /dev/null @@ -1,95 +0,0 @@ -From dc4dd11233522d8195782a2196aaae44bd924575 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Thu, 14 Mar 2024 17:58:24 +0100 -Subject: [PATCH 2/4] nbd/server: Fix race in draining the export - -RH-Author: Kevin Wolf -RH-MergeRequest: 231: Fix deadlock and crash during storage migration -RH-Jira: RHEL-28125 -RH-Acked-by: Hanna Czenczek -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [2/3] 036e1b171986099904dee468c59d77437e3d3d61 (kmwolf/centos-qemu-kvm) - -When draining an NBD export, nbd_drained_begin() first sets -client->quiescing so that nbd_client_receive_next_request() won't start -any new request coroutines. Then nbd_drained_poll() tries to makes sure -that we wait for any existing request coroutines by checking that -client->nb_requests has become 0. - -However, there is a small window between creating a new request -coroutine and increasing client->nb_requests. If a coroutine is in this -state, it won't be waited for and drain returns too early. - -In the context of switching to a different AioContext, this means that -blk_aio_attached() will see client->recv_coroutine != NULL and fail its -assertion. - -Fix this by increasing client->nb_requests immediately when starting the -coroutine. Doing this after the checks if we should create a new -coroutine is okay because client->lock is held. - -Cc: qemu-stable@nongnu.org -Fixes: fd6afc501a01 ("nbd/server: Use drained block ops to quiesce the server") -Signed-off-by: Kevin Wolf -Message-ID: <20240314165825.40261-2-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit 9c707525cbb1dd1e56876e45c70c0c08f2876d41) -Signed-off-by: Kevin Wolf ---- - nbd/server.c | 15 +++++++-------- - 1 file changed, 7 insertions(+), 8 deletions(-) - -diff --git a/nbd/server.c b/nbd/server.c -index 941832f178..c3484cc1eb 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -3007,8 +3007,8 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, - /* Owns a reference to the NBDClient passed as opaque. */ - static coroutine_fn void nbd_trip(void *opaque) - { -- NBDClient *client = opaque; -- NBDRequestData *req = NULL; -+ NBDRequestData *req = opaque; -+ NBDClient *client = req->client; - NBDRequest request = { 0 }; /* GCC thinks it can be used uninitialized */ - int ret; - Error *local_err = NULL; -@@ -3037,8 +3037,6 @@ static coroutine_fn void nbd_trip(void *opaque) - goto done; - } - -- req = nbd_request_get(client); -- - /* - * nbd_co_receive_request() returns -EAGAIN when nbd_drained_begin() has - * set client->quiescing but by the time we get back nbd_drained_end() may -@@ -3112,9 +3110,7 @@ static coroutine_fn void nbd_trip(void *opaque) - } - - done: -- if (req) { -- nbd_request_put(req); -- } -+ nbd_request_put(req); - - qemu_mutex_unlock(&client->lock); - -@@ -3143,10 +3139,13 @@ disconnect: - */ - static void nbd_client_receive_next_request(NBDClient *client) - { -+ NBDRequestData *req; -+ - if (!client->recv_coroutine && client->nb_requests < MAX_NBD_REQUESTS && - !client->quiescing) { - nbd_client_get(client); -- client->recv_coroutine = qemu_coroutine_create(nbd_trip, client); -+ req = nbd_request_get(client); -+ client->recv_coroutine = qemu_coroutine_create(nbd_trip, req); - aio_co_schedule(client->exp->common.ctx, client->recv_coroutine); - } - } --- -2.39.3 - diff --git a/kvm-nbd-server-avoid-per-NBDRequest-nbd_client_get-put.patch b/kvm-nbd-server-avoid-per-NBDRequest-nbd_client_get-put.patch deleted file mode 100644 index 339e234..0000000 --- a/kvm-nbd-server-avoid-per-NBDRequest-nbd_client_get-put.patch +++ /dev/null @@ -1,53 +0,0 @@ -From cd7788a857a6099206c4063e3ef69cb9e4aebcbc Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 21 Dec 2023 14:24:50 -0500 -Subject: [PATCH 070/101] nbd/server: avoid per-NBDRequest nbd_client_get/put() - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [1/26] 5acb090ac4adf4260cd9e9c5605a27012b2a33aa (kmwolf/centos-qemu-kvm) - -nbd_trip() processes a single NBD request from start to finish and holds -an NBDClient reference throughout. NBDRequest does not outlive the scope -of nbd_trip(). Therefore it is unnecessary to ref/unref NBDClient for -each NBDRequest. - -Removing these nbd_client_get()/nbd_client_put() calls will make -thread-safety easier in the commits that follow. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Paolo Bonzini -Message-ID: <20231221192452.1785567-5-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - nbd/server.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/nbd/server.c b/nbd/server.c -index 895cf0a752..0b09ccc8dc 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -1557,7 +1557,6 @@ static NBDRequestData *nbd_request_get(NBDClient *client) - client->nb_requests++; - - req = g_new0(NBDRequestData, 1); -- nbd_client_get(client); - req->client = client; - return req; - } -@@ -1578,8 +1577,6 @@ static void nbd_request_put(NBDRequestData *req) - } - - nbd_client_receive_next_request(client); -- -- nbd_client_put(client); - } - - static void blk_aio_attached(AioContext *ctx, void *opaque) --- -2.39.3 - diff --git a/kvm-nbd-server-introduce-NBDClient-lock-to-protect-field.patch b/kvm-nbd-server-introduce-NBDClient-lock-to-protect-field.patch deleted file mode 100644 index e0d763d..0000000 --- a/kvm-nbd-server-introduce-NBDClient-lock-to-protect-field.patch +++ /dev/null @@ -1,373 +0,0 @@ -From bb0a6afff7f23a3ddb460dc1b2e70c06565f8a3f Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 21 Dec 2023 14:24:52 -0500 -Subject: [PATCH 072/101] nbd/server: introduce NBDClient->lock to protect - fields - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [3/26] 49b64adaaf8b1c30f339d1ecc8ea89fb9db63f1c (kmwolf/centos-qemu-kvm) - -NBDClient has a number of fields that are accessed by both the export -AioContext and the main loop thread. When the AioContext lock is removed -these fields will need another form of protection. - -Add NBDClient->lock and protect fields that are accessed by both -threads. Also add assertions where possible and otherwise add doc -comments stating assumptions about which thread and lock holding. - -Note this patch moves the client->recv_coroutine assertion from -nbd_co_receive_request() to nbd_trip() where client->lock is held. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20231221192452.1785567-7-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - nbd/server.c | 144 +++++++++++++++++++++++++++++++++++++++------------ - 1 file changed, 111 insertions(+), 33 deletions(-) - -diff --git a/nbd/server.c b/nbd/server.c -index e91e2e0903..941832f178 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -125,23 +125,25 @@ struct NBDClient { - int refcount; /* atomic */ - void (*close_fn)(NBDClient *client, bool negotiated); - -+ QemuMutex lock; -+ - NBDExport *exp; - QCryptoTLSCreds *tlscreds; - char *tlsauthz; - QIOChannelSocket *sioc; /* The underlying data channel */ - QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */ - -- Coroutine *recv_coroutine; -+ Coroutine *recv_coroutine; /* protected by lock */ - - CoMutex send_lock; - Coroutine *send_coroutine; - -- bool read_yielding; -- bool quiescing; -+ bool read_yielding; /* protected by lock */ -+ bool quiescing; /* protected by lock */ - - QTAILQ_ENTRY(NBDClient) next; -- int nb_requests; -- bool closing; -+ int nb_requests; /* protected by lock */ -+ bool closing; /* protected by lock */ - - uint32_t check_align; /* If non-zero, check for aligned client requests */ - -@@ -1415,11 +1417,18 @@ nbd_read_eof(NBDClient *client, void *buffer, size_t size, Error **errp) - - len = qio_channel_readv(client->ioc, &iov, 1, errp); - if (len == QIO_CHANNEL_ERR_BLOCK) { -- client->read_yielding = true; -+ WITH_QEMU_LOCK_GUARD(&client->lock) { -+ client->read_yielding = true; -+ -+ /* Prompt main loop thread to re-run nbd_drained_poll() */ -+ aio_wait_kick(); -+ } - qio_channel_yield(client->ioc, G_IO_IN); -- client->read_yielding = false; -- if (client->quiescing) { -- return -EAGAIN; -+ WITH_QEMU_LOCK_GUARD(&client->lock) { -+ client->read_yielding = false; -+ if (client->quiescing) { -+ return -EAGAIN; -+ } - } - continue; - } else if (len < 0) { -@@ -1528,6 +1537,7 @@ void nbd_client_put(NBDClient *client) - blk_exp_unref(&client->exp->common); - } - g_free(client->contexts.bitmaps); -+ qemu_mutex_destroy(&client->lock); - g_free(client); - } - } -@@ -1561,11 +1571,13 @@ static void client_close(NBDClient *client, bool negotiated) - { - assert(qemu_in_main_thread()); - -- if (client->closing) { -- return; -- } -+ WITH_QEMU_LOCK_GUARD(&client->lock) { -+ if (client->closing) { -+ return; -+ } - -- client->closing = true; -+ client->closing = true; -+ } - - /* Force requests to finish. They will drop their own references, - * then we'll close the socket and free the NBDClient. -@@ -1579,6 +1591,7 @@ static void client_close(NBDClient *client, bool negotiated) - } - } - -+/* Runs in export AioContext with client->lock held */ - static NBDRequestData *nbd_request_get(NBDClient *client) - { - NBDRequestData *req; -@@ -1591,6 +1604,7 @@ static NBDRequestData *nbd_request_get(NBDClient *client) - return req; - } - -+/* Runs in export AioContext with client->lock held */ - static void nbd_request_put(NBDRequestData *req) - { - NBDClient *client = req->client; -@@ -1614,14 +1628,18 @@ static void blk_aio_attached(AioContext *ctx, void *opaque) - NBDExport *exp = opaque; - NBDClient *client; - -+ assert(qemu_in_main_thread()); -+ - trace_nbd_blk_aio_attached(exp->name, ctx); - - exp->common.ctx = ctx; - - QTAILQ_FOREACH(client, &exp->clients, next) { -- assert(client->nb_requests == 0); -- assert(client->recv_coroutine == NULL); -- assert(client->send_coroutine == NULL); -+ WITH_QEMU_LOCK_GUARD(&client->lock) { -+ assert(client->nb_requests == 0); -+ assert(client->recv_coroutine == NULL); -+ assert(client->send_coroutine == NULL); -+ } - } - } - -@@ -1629,6 +1647,8 @@ static void blk_aio_detach(void *opaque) - { - NBDExport *exp = opaque; - -+ assert(qemu_in_main_thread()); -+ - trace_nbd_blk_aio_detach(exp->name, exp->common.ctx); - - exp->common.ctx = NULL; -@@ -1639,8 +1659,12 @@ static void nbd_drained_begin(void *opaque) - NBDExport *exp = opaque; - NBDClient *client; - -+ assert(qemu_in_main_thread()); -+ - QTAILQ_FOREACH(client, &exp->clients, next) { -- client->quiescing = true; -+ WITH_QEMU_LOCK_GUARD(&client->lock) { -+ client->quiescing = true; -+ } - } - } - -@@ -1649,28 +1673,48 @@ static void nbd_drained_end(void *opaque) - NBDExport *exp = opaque; - NBDClient *client; - -+ assert(qemu_in_main_thread()); -+ - QTAILQ_FOREACH(client, &exp->clients, next) { -- client->quiescing = false; -- nbd_client_receive_next_request(client); -+ WITH_QEMU_LOCK_GUARD(&client->lock) { -+ client->quiescing = false; -+ nbd_client_receive_next_request(client); -+ } - } - } - -+/* Runs in export AioContext */ -+static void nbd_wake_read_bh(void *opaque) -+{ -+ NBDClient *client = opaque; -+ qio_channel_wake_read(client->ioc); -+} -+ - static bool nbd_drained_poll(void *opaque) - { - NBDExport *exp = opaque; - NBDClient *client; - -+ assert(qemu_in_main_thread()); -+ - QTAILQ_FOREACH(client, &exp->clients, next) { -- if (client->nb_requests != 0) { -- /* -- * If there's a coroutine waiting for a request on nbd_read_eof() -- * enter it here so we don't depend on the client to wake it up. -- */ -- if (client->recv_coroutine != NULL && client->read_yielding) { -- qio_channel_wake_read(client->ioc); -- } -+ WITH_QEMU_LOCK_GUARD(&client->lock) { -+ if (client->nb_requests != 0) { -+ /* -+ * If there's a coroutine waiting for a request on nbd_read_eof() -+ * enter it here so we don't depend on the client to wake it up. -+ * -+ * Schedule a BH in the export AioContext to avoid missing the -+ * wake up due to the race between qio_channel_wake_read() and -+ * qio_channel_yield(). -+ */ -+ if (client->recv_coroutine != NULL && client->read_yielding) { -+ aio_bh_schedule_oneshot(nbd_export_aio_context(client->exp), -+ nbd_wake_read_bh, client); -+ } - -- return true; -+ return true; -+ } - } - } - -@@ -1681,6 +1725,8 @@ static void nbd_eject_notifier(Notifier *n, void *data) - { - NBDExport *exp = container_of(n, NBDExport, eject_notifier); - -+ assert(qemu_in_main_thread()); -+ - blk_exp_request_shutdown(&exp->common); - } - -@@ -2566,7 +2612,6 @@ static int coroutine_fn nbd_co_receive_request(NBDRequestData *req, - int ret; - - g_assert(qemu_in_coroutine()); -- assert(client->recv_coroutine == qemu_coroutine_self()); - ret = nbd_receive_request(client, request, errp); - if (ret < 0) { - return ret; -@@ -2975,6 +3020,9 @@ static coroutine_fn void nbd_trip(void *opaque) - */ - - trace_nbd_trip(); -+ -+ qemu_mutex_lock(&client->lock); -+ - if (client->closing) { - goto done; - } -@@ -2990,7 +3038,21 @@ static coroutine_fn void nbd_trip(void *opaque) - } - - req = nbd_request_get(client); -- ret = nbd_co_receive_request(req, &request, &local_err); -+ -+ /* -+ * nbd_co_receive_request() returns -EAGAIN when nbd_drained_begin() has -+ * set client->quiescing but by the time we get back nbd_drained_end() may -+ * have already cleared client->quiescing. In that case we try again -+ * because nothing else will spawn an nbd_trip() coroutine until we set -+ * client->recv_coroutine = NULL further down. -+ */ -+ do { -+ assert(client->recv_coroutine == qemu_coroutine_self()); -+ qemu_mutex_unlock(&client->lock); -+ ret = nbd_co_receive_request(req, &request, &local_err); -+ qemu_mutex_lock(&client->lock); -+ } while (ret == -EAGAIN && !client->quiescing); -+ - client->recv_coroutine = NULL; - - if (client->closing) { -@@ -3002,15 +3064,16 @@ static coroutine_fn void nbd_trip(void *opaque) - } - - if (ret == -EAGAIN) { -- assert(client->quiescing); - goto done; - } - - nbd_client_receive_next_request(client); -+ - if (ret == -EIO) { - goto disconnect; - } - -+ qemu_mutex_unlock(&client->lock); - qio_channel_set_cork(client->ioc, true); - - if (ret < 0) { -@@ -3030,6 +3093,10 @@ static coroutine_fn void nbd_trip(void *opaque) - g_free(request.contexts->bitmaps); - g_free(request.contexts); - } -+ -+ qio_channel_set_cork(client->ioc, false); -+ qemu_mutex_lock(&client->lock); -+ - if (ret < 0) { - error_prepend(&local_err, "Failed to send reply: "); - goto disconnect; -@@ -3044,11 +3111,13 @@ static coroutine_fn void nbd_trip(void *opaque) - goto disconnect; - } - -- qio_channel_set_cork(client->ioc, false); - done: - if (req) { - nbd_request_put(req); - } -+ -+ qemu_mutex_unlock(&client->lock); -+ - if (!nbd_client_put_nonzero(client)) { - aio_co_reschedule_self(qemu_get_aio_context()); - nbd_client_put(client); -@@ -3059,13 +3128,19 @@ disconnect: - if (local_err) { - error_reportf_err(local_err, "Disconnect client, due to: "); - } -+ - nbd_request_put(req); -+ qemu_mutex_unlock(&client->lock); - - aio_co_reschedule_self(qemu_get_aio_context()); - client_close(client, true); - nbd_client_put(client); - } - -+/* -+ * Runs in export AioContext and main loop thread. Caller must hold -+ * client->lock. -+ */ - static void nbd_client_receive_next_request(NBDClient *client) - { - if (!client->recv_coroutine && client->nb_requests < MAX_NBD_REQUESTS && -@@ -3091,7 +3166,9 @@ static coroutine_fn void nbd_co_client_start(void *opaque) - return; - } - -- nbd_client_receive_next_request(client); -+ WITH_QEMU_LOCK_GUARD(&client->lock) { -+ nbd_client_receive_next_request(client); -+ } - } - - /* -@@ -3108,6 +3185,7 @@ void nbd_client_new(QIOChannelSocket *sioc, - Coroutine *co; - - client = g_new0(NBDClient, 1); -+ qemu_mutex_init(&client->lock); - client->refcount = 1; - client->tlscreds = tlscreds; - if (tlscreds) { --- -2.39.3 - diff --git a/kvm-nbd-server-only-traverse-NBDExport-clients-from-main.patch b/kvm-nbd-server-only-traverse-NBDExport-clients-from-main.patch deleted file mode 100644 index 3ca11a9..0000000 --- a/kvm-nbd-server-only-traverse-NBDExport-clients-from-main.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 8b60d72532b6511b41d82d591fb4f509314ef15f Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 21 Dec 2023 14:24:51 -0500 -Subject: [PATCH 071/101] nbd/server: only traverse NBDExport->clients from - main loop thread - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [2/26] e7794a3a5c363c7508ee505c4ba03d9ef8862ca9 (kmwolf/centos-qemu-kvm) - -The NBD clients list is currently accessed from both the export -AioContext and the main loop thread. When the AioContext lock is removed -there will be nothing protecting the clients list. - -Adding a lock around the clients list is tricky because NBDClient -structs are refcounted and may be freed from the export AioContext or -the main loop thread. nbd_export_request_shutdown() -> client_close() -> -nbd_client_put() is also tricky because the list lock would be held -while indirectly dropping references to NDBClients. - -A simpler approach is to only allow nbd_client_put() and client_close() -calls from the main loop thread. Then the NBD clients list is only -accessed from the main loop thread and no fancy locking is needed. - -nbd_trip() just needs to reschedule itself in the main loop AioContext -before calling nbd_client_put() and client_close(). This costs more CPU -cycles per NBD request so add nbd_client_put_nonzero() to optimize the -common case where more references to NBDClient remain. - -Note that nbd_client_get() can still be called from either thread, so -make NBDClient->refcount atomic. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20231221192452.1785567-6-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - nbd/server.c | 61 +++++++++++++++++++++++++++++++++++++++++++--------- - 1 file changed, 51 insertions(+), 10 deletions(-) - -diff --git a/nbd/server.c b/nbd/server.c -index 0b09ccc8dc..e91e2e0903 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -122,7 +122,7 @@ struct NBDMetaContexts { - }; - - struct NBDClient { -- int refcount; -+ int refcount; /* atomic */ - void (*close_fn)(NBDClient *client, bool negotiated); - - NBDExport *exp; -@@ -1501,14 +1501,17 @@ static int coroutine_fn nbd_receive_request(NBDClient *client, NBDRequest *reque - - #define MAX_NBD_REQUESTS 16 - -+/* Runs in export AioContext and main loop thread */ - void nbd_client_get(NBDClient *client) - { -- client->refcount++; -+ qatomic_inc(&client->refcount); - } - - void nbd_client_put(NBDClient *client) - { -- if (--client->refcount == 0) { -+ assert(qemu_in_main_thread()); -+ -+ if (qatomic_fetch_dec(&client->refcount) == 1) { - /* The last reference should be dropped by client->close, - * which is called by client_close. - */ -@@ -1529,8 +1532,35 @@ void nbd_client_put(NBDClient *client) - } - } - -+/* -+ * Tries to release the reference to @client, but only if other references -+ * remain. This is an optimization for the common case where we want to avoid -+ * the expense of scheduling nbd_client_put() in the main loop thread. -+ * -+ * Returns true upon success or false if the reference was not released because -+ * it is the last reference. -+ */ -+static bool nbd_client_put_nonzero(NBDClient *client) -+{ -+ int old = qatomic_read(&client->refcount); -+ int expected; -+ -+ do { -+ if (old == 1) { -+ return false; -+ } -+ -+ expected = old; -+ old = qatomic_cmpxchg(&client->refcount, expected, expected - 1); -+ } while (old != expected); -+ -+ return true; -+} -+ - static void client_close(NBDClient *client, bool negotiated) - { -+ assert(qemu_in_main_thread()); -+ - if (client->closing) { - return; - } -@@ -2933,15 +2963,20 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, - static coroutine_fn void nbd_trip(void *opaque) - { - NBDClient *client = opaque; -- NBDRequestData *req; -+ NBDRequestData *req = NULL; - NBDRequest request = { 0 }; /* GCC thinks it can be used uninitialized */ - int ret; - Error *local_err = NULL; - -+ /* -+ * Note that nbd_client_put() and client_close() must be called from the -+ * main loop thread. Use aio_co_reschedule_self() to switch AioContext -+ * before calling these functions. -+ */ -+ - trace_nbd_trip(); - if (client->closing) { -- nbd_client_put(client); -- return; -+ goto done; - } - - if (client->quiescing) { -@@ -2949,10 +2984,9 @@ static coroutine_fn void nbd_trip(void *opaque) - * We're switching between AIO contexts. Don't attempt to receive a new - * request and kick the main context which may be waiting for us. - */ -- nbd_client_put(client); - client->recv_coroutine = NULL; - aio_wait_kick(); -- return; -+ goto done; - } - - req = nbd_request_get(client); -@@ -3012,8 +3046,13 @@ static coroutine_fn void nbd_trip(void *opaque) - - qio_channel_set_cork(client->ioc, false); - done: -- nbd_request_put(req); -- nbd_client_put(client); -+ if (req) { -+ nbd_request_put(req); -+ } -+ if (!nbd_client_put_nonzero(client)) { -+ aio_co_reschedule_self(qemu_get_aio_context()); -+ nbd_client_put(client); -+ } - return; - - disconnect: -@@ -3021,6 +3060,8 @@ disconnect: - error_reportf_err(local_err, "Disconnect client, due to: "); - } - nbd_request_put(req); -+ -+ aio_co_reschedule_self(qemu_get_aio_context()); - client_close(client, true); - nbd_client_put(client); - } --- -2.39.3 - diff --git a/kvm-pc-q35-set-SMBIOS-entry-point-type-to-auto-by-defaul.patch b/kvm-pc-q35-set-SMBIOS-entry-point-type-to-auto-by-defaul.patch deleted file mode 100644 index f37f65f..0000000 --- a/kvm-pc-q35-set-SMBIOS-entry-point-type-to-auto-by-defaul.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 9ca64f73238d9f1b9f13d8e941ba42771a992afb Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Fri, 29 Dec 2023 14:06:05 +0100 -Subject: [PATCH 20/20] pc/q35: set SMBIOS entry point type to 'auto' by - default - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [18/18] c7fc6ac7350bca3ff99e58620710a86218385781 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - - Use smbios-entry-point-type='auto' for newer machine types as a workaround - for Windows not detecting SMBIOS tables. Which makes QEMU pick SMBIOS tables - based on configuration (with 2.x preferred and fallback to 3.x if the former - isn't compatible with configuration) - - Default compat setting of smbios-entry-point-type after series - for pc/q35 machines: - * 9.0-newer: 'auto' - * 8.1-8.2: '64' - * 8.0-older: '32' - Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2008 - Signed-off-by: Igor Mammedov - Reviewed-by: Ani Sinha - Tested-by: Fiona Ebner - -Conflicts: hw/i386/pc_piix.c hw/i386/pc_q35.c - due to RHEL machine types - -REHL only parts: - Fix RHEL 'pc' machine types at SMBIOS 2.X - for the latest RHEL 'q35' machine type use version autoselect - which propagates to RHEL 9.4 q35 macine type while RHEL 9.2 q35 and older - are kept at SMBIOS_ENTRY_POINT_TYPE_32 (see: pc_q35_machine_rhel920_options) - -Signed-off-by: Igor Mammedov ---- - hw/i386/pc.c | 2 +- - hw/i386/pc_piix.c | 7 +++++++ - hw/i386/pc_q35.c | 5 +++++ - 3 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index ae6777fc1a..d6f267b220 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -2004,7 +2004,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - mc->nvdimm_supported = true; - mc->smp_props.dies_supported = true; - mc->default_ram_id = "pc.ram"; -- pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64; -+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_AUTO; - - object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size", - pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g, -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 7344b35cf1..54d1c58bce 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -539,9 +539,14 @@ static void pc_i440fx_machine_options(MachineClass *m) - - static void pc_i440fx_8_2_machine_options(MachineClass *m) - { -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ - pc_i440fx_machine_options(m); - m->alias = "pc"; - m->is_default = true; -+ -+ /* For pc-i44fx-8.2 and 8.1, use SMBIOS 3.X by default */ -+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64; - } - - DEFINE_I440FX_MACHINE(v8_2, "pc-i440fx-8.2", NULL, -@@ -982,6 +987,8 @@ static void pc_machine_rhel7_options(MachineClass *m) - m->alias = "pc"; - m->is_default = 1; - m->smp_props.prefer_sockets = true; -+ /* there aren't ne PC macine types in RHEL9, keep it at SMBIOS 2.X */ -+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32; - } - - static void pc_init_rhel760(MachineState *machine) -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 9a22ff5dd6..cd5fb7380e 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -377,8 +377,11 @@ static void pc_q35_machine_options(MachineClass *m) - - static void pc_q35_8_2_machine_options(MachineClass *m) - { -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); - pc_q35_machine_options(m); - m->alias = "q35"; -+ /* For pc-q35-8.2 and 8.1, use SMBIOS 3.X by default */ -+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64; - } - - DEFINE_Q35_MACHINE(v8_2, "pc-q35-8.2", NULL, -@@ -712,6 +715,8 @@ static void pc_q35_machine_rhel_options(MachineClass *m) - m->alias = "q35"; - m->max_cpus = 710; - compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len); -+ /* use SMBIOS version autoselect by default for the latest RHEL machine */ -+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_AUTO; - } - - static void pc_q35_init_rhel940(MachineState *machine) --- -2.39.3 - diff --git a/kvm-pc-smbios-fixup-manufacturer-product-version-to-matc.patch b/kvm-pc-smbios-fixup-manufacturer-product-version-to-matc.patch deleted file mode 100644 index 9d3fd29..0000000 --- a/kvm-pc-smbios-fixup-manufacturer-product-version-to-matc.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 03cad16743d9a4d377af66611d030eca9eda326d Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Tue, 19 Mar 2024 11:42:04 +0100 -Subject: [PATCH 4/4] pc: smbios: fixup manufacturer/product/version to match - downstream - -RH-Author: Igor Mammedov -RH-MergeRequest: 232: pc: smbios: fixup manufacturer/product/version to match downstream -RH-Jira: RHEL-21705 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Ani Sinha -RH-Commit: [1/1] 9235f64acb5ff46360282e889d0aedcb13374ac1 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -commit [1] discarded RHEL only change that customizes -SMBIOS values for manufacturer/product/version for pc/q35 -machine types. -Fix it up by reverting back to ("Red Hat", "KVM", mc->desc) -tuple. - -1) -Fixes: 208239eb2 (hw/i386/pc: Defer smbios_set_defaults() to machine_done) -Signed-off-by: Igor Mammedov ---- - hw/i386/fw_cfg.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index 58429bb78d..d6a24177e2 100644 ---- a/hw/i386/fw_cfg.c -+++ b/hw/i386/fw_cfg.c -@@ -63,7 +63,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg, - - if (pcmc->smbios_defaults) { - /* These values are guest ABI, do not change */ -- smbios_set_defaults("QEMU", mc->desc, mc->name, -+ smbios_set_defaults("Red Hat", "KVM", mc->desc, - pcmc->smbios_uuid_encoded, - pcmc->smbios_stream_product, - pcmc->smbios_stream_version); --- -2.39.3 - diff --git a/kvm-qdev-add-IOThreadVirtQueueMappingList-property-type.patch b/kvm-qdev-add-IOThreadVirtQueueMappingList-property-type.patch deleted file mode 100644 index b31142e..0000000 --- a/kvm-qdev-add-IOThreadVirtQueueMappingList-property-type.patch +++ /dev/null @@ -1,167 +0,0 @@ -From f1e82fe5076b4030d385dfa49b8284899386114d Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 20 Dec 2023 08:47:54 -0500 -Subject: [PATCH 08/22] qdev: add IOThreadVirtQueueMappingList property type - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [4/17] 817aa1339da8ed3814730473342ba045e66d5b51 (stefanha/centos-stream-qemu-kvm) - -virtio-blk and virtio-scsi devices will need a way to specify the -mapping between IOThreads and virtqueues. At the moment all virtqueues -are assigned to a single IOThread or the main loop. This single thread -can be a CPU bottleneck, so it is necessary to allow finer-grained -assignment to spread the load. - -Introduce DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST() so devices can take a -parameter that maps virtqueues to IOThreads. The command-line syntax for -this new property is as follows: - - --device '{"driver":"foo","iothread-vq-mapping":[{"iothread":"iothread0","vqs":[0,1,2]},...]}' - -IOThreads are specified by name and virtqueues are specified by 0-based -index. - -It will be common to simply assign virtqueues round-robin across a set -of IOThreads. A convenient syntax that does not require specifying -individual virtqueue indices is available: - - --device '{"driver":"foo","iothread-vq-mapping":[{"iothread":"iothread0"},{"iothread":"iothread1"},...]}' - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20231220134755.814917-4-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit cf03a152c5d749fd0083bfe540df9524f1d2ff1d) -Signed-off-by: Stefan Hajnoczi ---- - hw/core/qdev-properties-system.c | 46 +++++++++++++++++++++++++++++ - include/hw/qdev-properties-system.h | 5 ++++ - qapi/virtio.json | 29 ++++++++++++++++++ - 3 files changed, 80 insertions(+) - -diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c -index 73cced4626..1a396521d5 100644 ---- a/hw/core/qdev-properties-system.c -+++ b/hw/core/qdev-properties-system.c -@@ -18,6 +18,7 @@ - #include "qapi/qapi-types-block.h" - #include "qapi/qapi-types-machine.h" - #include "qapi/qapi-types-migration.h" -+#include "qapi/qapi-visit-virtio.h" - #include "qapi/qmp/qerror.h" - #include "qemu/ctype.h" - #include "qemu/cutils.h" -@@ -1160,3 +1161,48 @@ const PropertyInfo qdev_prop_cpus390entitlement = { - .set = qdev_propinfo_set_enum, - .set_default_value = qdev_propinfo_set_default_value_enum, - }; -+ -+/* --- IOThreadVirtQueueMappingList --- */ -+ -+static void get_iothread_vq_mapping_list(Object *obj, Visitor *v, -+ const char *name, void *opaque, Error **errp) -+{ -+ IOThreadVirtQueueMappingList **prop_ptr = -+ object_field_prop_ptr(obj, opaque); -+ -+ visit_type_IOThreadVirtQueueMappingList(v, name, prop_ptr, errp); -+} -+ -+static void set_iothread_vq_mapping_list(Object *obj, Visitor *v, -+ const char *name, void *opaque, Error **errp) -+{ -+ IOThreadVirtQueueMappingList **prop_ptr = -+ object_field_prop_ptr(obj, opaque); -+ IOThreadVirtQueueMappingList *list; -+ -+ if (!visit_type_IOThreadVirtQueueMappingList(v, name, &list, errp)) { -+ return; -+ } -+ -+ qapi_free_IOThreadVirtQueueMappingList(*prop_ptr); -+ *prop_ptr = list; -+} -+ -+static void release_iothread_vq_mapping_list(Object *obj, -+ const char *name, void *opaque) -+{ -+ IOThreadVirtQueueMappingList **prop_ptr = -+ object_field_prop_ptr(obj, opaque); -+ -+ qapi_free_IOThreadVirtQueueMappingList(*prop_ptr); -+ *prop_ptr = NULL; -+} -+ -+const PropertyInfo qdev_prop_iothread_vq_mapping_list = { -+ .name = "IOThreadVirtQueueMappingList", -+ .description = "IOThread virtqueue mapping list [{\"iothread\":\"\", " -+ "\"vqs\":[1,2,3,...]},...]", -+ .get = get_iothread_vq_mapping_list, -+ .set = set_iothread_vq_mapping_list, -+ .release = release_iothread_vq_mapping_list, -+}; -diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h -index 91f7a2452d..06c359c190 100644 ---- a/include/hw/qdev-properties-system.h -+++ b/include/hw/qdev-properties-system.h -@@ -24,6 +24,7 @@ extern const PropertyInfo qdev_prop_off_auto_pcibar; - extern const PropertyInfo qdev_prop_pcie_link_speed; - extern const PropertyInfo qdev_prop_pcie_link_width; - extern const PropertyInfo qdev_prop_cpus390entitlement; -+extern const PropertyInfo qdev_prop_iothread_vq_mapping_list; - - #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ - DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) -@@ -82,4 +83,8 @@ extern const PropertyInfo qdev_prop_cpus390entitlement; - DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_cpus390entitlement, \ - CpuS390Entitlement) - -+#define DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST(_name, _state, _field) \ -+ DEFINE_PROP(_name, _state, _field, qdev_prop_iothread_vq_mapping_list, \ -+ IOThreadVirtQueueMappingList *) -+ - #endif -diff --git a/qapi/virtio.json b/qapi/virtio.json -index e6dcee7b83..19c7c36e36 100644 ---- a/qapi/virtio.json -+++ b/qapi/virtio.json -@@ -928,3 +928,32 @@ - 'data': { 'path': 'str', 'queue': 'uint16', '*index': 'uint16' }, - 'returns': 'VirtioQueueElement', - 'features': [ 'unstable' ] } -+ -+## -+# @IOThreadVirtQueueMapping: -+# -+# Describes the subset of virtqueues assigned to an IOThread. -+# -+# @iothread: the id of IOThread object -+# -+# @vqs: an optional array of virtqueue indices that will be handled by this -+# IOThread. When absent, virtqueues are assigned round-robin across all -+# IOThreadVirtQueueMappings provided. Either all IOThreadVirtQueueMappings -+# must have @vqs or none of them must have it. -+# -+# Since: 9.0 -+## -+ -+{ 'struct': 'IOThreadVirtQueueMapping', -+ 'data': { 'iothread': 'str', '*vqs': ['uint16'] } } -+ -+## -+# @DummyVirtioForceArrays: -+# -+# Not used by QMP; hack to let us use IOThreadVirtQueueMappingList internally -+# -+# Since: 9.0 -+## -+ -+{ 'struct': 'DummyVirtioForceArrays', -+ 'data': { 'unused-iothread-vq-mapping': ['IOThreadVirtQueueMapping'] } } --- -2.39.3 - diff --git a/kvm-qdev-properties-alias-all-object-class-properties.patch b/kvm-qdev-properties-alias-all-object-class-properties.patch deleted file mode 100644 index 94bb716..0000000 --- a/kvm-qdev-properties-alias-all-object-class-properties.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 4251aab5b2beb68d1800cd4a329361ff6f57c430 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 20 Dec 2023 08:47:52 -0500 -Subject: [PATCH 07/22] qdev-properties: alias all object class properties - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [3/17] bc5d0aafe4645dacf9277904a2b20760d6e676e1 (stefanha/centos-stream-qemu-kvm) - -qdev_alias_all_properties() aliases a DeviceState's qdev properties onto -an Object. This is used for VirtioPCIProxy types so that --device -virtio-blk-pci has properties of its embedded --device virtio-blk-device -object. - -Currently this function is implemented using qdev properties. Change the -function to use QOM object class properties instead. This works because -qdev properties create QOM object class properties, but it also catches -any QOM object class-only properties that have no qdev properties. - -This change ensures that properties of devices are shown with --device -foo,\? even if they are QOM object class properties. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20231220134755.814917-2-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 350147a871a545ab56b4a1062c8485635d9ffc24) -Signed-off-by: Stefan Hajnoczi ---- - hw/core/qdev-properties.c | 18 ++++++++++-------- - include/hw/qdev-properties.h | 4 ++-- - 2 files changed, 12 insertions(+), 10 deletions(-) - -diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c -index 840006e953..7d6fa726fd 100644 ---- a/hw/core/qdev-properties.c -+++ b/hw/core/qdev-properties.c -@@ -1076,16 +1076,18 @@ void device_class_set_props(DeviceClass *dc, Property *props) - void qdev_alias_all_properties(DeviceState *target, Object *source) - { - ObjectClass *class; -- Property *prop; -+ ObjectPropertyIterator iter; -+ ObjectProperty *prop; - - class = object_get_class(OBJECT(target)); -- do { -- DeviceClass *dc = DEVICE_CLASS(class); - -- for (prop = dc->props_; prop && prop->name; prop++) { -- object_property_add_alias(source, prop->name, -- OBJECT(target), prop->name); -+ object_class_property_iter_init(&iter, class); -+ while ((prop = object_property_iter_next(&iter))) { -+ if (object_property_find(source, prop->name)) { -+ continue; /* skip duplicate properties */ - } -- class = object_class_get_parent(class); -- } while (class != object_class_by_name(TYPE_DEVICE)); -+ -+ object_property_add_alias(source, prop->name, -+ OBJECT(target), prop->name); -+ } - } -diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h -index 25743a29a0..09aa04ca1e 100644 ---- a/include/hw/qdev-properties.h -+++ b/include/hw/qdev-properties.h -@@ -230,8 +230,8 @@ void qdev_property_add_static(DeviceState *dev, Property *prop); - * @target: Device which has properties to be aliased - * @source: Object to add alias properties to - * -- * Add alias properties to the @source object for all qdev properties on -- * the @target DeviceState. -+ * Add alias properties to the @source object for all properties on the @target -+ * DeviceState. - * - * This is useful when @target is an internal implementation object - * owned by @source, and you want to expose all the properties of that --- -2.39.3 - diff --git a/kvm-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch b/kvm-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch deleted file mode 100644 index 7dc550c..0000000 --- a/kvm-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch +++ /dev/null @@ -1,135 +0,0 @@ -From f2fe6c7a2def488633cbb67e28ac00279d6e8de4 Mon Sep 17 00:00:00 2001 -From: Cornelia Huck -Date: Tue, 27 Feb 2024 11:17:39 +0100 -Subject: [PATCH 1/2] qemu_init: increase NOFILE soft limit on POSIX -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Cornelia Huck -RH-MergeRequest: 226: qemu_init: increase NOFILE soft limit on POSIX -RH-Jira: RHEL-26049 -RH-Acked-by: Gavin Shan -RH-Acked-by: Ani Sinha -RH-Acked-by: Shaoqin Huang -RH-Commit: [1/1] cee5404aef3f6437d45a1c43bdee73a57a528bee (cohuck/qemu-kvm-c9s) - -Jira: https://issues.redhat.com/browse/RHEL-26049 - -In many configurations, e.g. multiple vNICs with multiple queues or -with many Ceph OSDs, the default soft limit of 1024 is not enough. -QEMU is supposed to work fine with file descriptors >= 1024 and does -not use select() on POSIX. Bump the soft limit to the allowed hard -limit to avoid issues with the aforementioned configurations. - -Of course the limit could be raised from the outside, but the man page -of systemd.exec states about 'LimitNOFILE=': - -> Don't use. -> [...] -> Typically applications should increase their soft limit to the hard -> limit on their own, if they are OK with working with file -> descriptors above 1023, - -If the soft limit is already the same as the hard limit, avoid the -superfluous setrlimit call. This can avoid a warning with a strict -seccomp filter blocking setrlimit if NOFILE was already raised before -executing QEMU. - -Buglink: https://bugzilla.proxmox.com/show_bug.cgi?id=4507 -Reviewed-by: Daniel P. Berrangé -Signed-off-by: Fiona Ebner -Signed-off-by: Daniel P. Berrangé -(cherry picked from commit 03e471c41d8b1b6eb16c9714f387449f52fe5c1d) -Signed-off-by: Cornelia Huck ---- - include/sysemu/os-posix.h | 1 + - include/sysemu/os-win32.h | 5 +++++ - os-posix.c | 22 ++++++++++++++++++++++ - system/vl.c | 2 ++ - 4 files changed, 30 insertions(+) - -diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h -index dff32ae185..b881ac6c6f 100644 ---- a/include/sysemu/os-posix.h -+++ b/include/sysemu/os-posix.h -@@ -51,6 +51,7 @@ bool is_daemonized(void); - void os_daemonize(void); - bool os_set_runas(const char *user_id); - void os_set_chroot(const char *path); -+void os_setup_limits(void); - void os_setup_post(void); - int os_mlock(void); - -diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h -index 1047d260cb..b82a5d3ad9 100644 ---- a/include/sysemu/os-win32.h -+++ b/include/sysemu/os-win32.h -@@ -128,6 +128,11 @@ static inline int os_mlock(void) - return -ENOSYS; - } - -+static inline void os_setup_limits(void) -+{ -+ return; -+} -+ - #define fsync _commit - - #if !defined(lseek) -diff --git a/os-posix.c b/os-posix.c -index 52ef6990ff..a4284e2c07 100644 ---- a/os-posix.c -+++ b/os-posix.c -@@ -24,6 +24,7 @@ - */ - - #include "qemu/osdep.h" -+#include - #include - #include - #include -@@ -256,6 +257,27 @@ void os_daemonize(void) - } - } - -+void os_setup_limits(void) -+{ -+ struct rlimit nofile; -+ -+ if (getrlimit(RLIMIT_NOFILE, &nofile) < 0) { -+ warn_report("unable to query NOFILE limit: %s", strerror(errno)); -+ return; -+ } -+ -+ if (nofile.rlim_cur == nofile.rlim_max) { -+ return; -+ } -+ -+ nofile.rlim_cur = nofile.rlim_max; -+ -+ if (setrlimit(RLIMIT_NOFILE, &nofile) < 0) { -+ warn_report("unable to set NOFILE limit: %s", strerror(errno)); -+ return; -+ } -+} -+ - void os_setup_post(void) - { - int fd = 0; -diff --git a/system/vl.c b/system/vl.c -index 93635ffc5b..6443b6e469 100644 ---- a/system/vl.c -+++ b/system/vl.c -@@ -2783,6 +2783,8 @@ void qemu_init(int argc, char **argv) - error_init(argv[0]); - qemu_init_exec_dir(argv[0]); - -+ os_setup_limits(); -+ - qemu_init_arch_modules(); - - qemu_init_subsystems(); --- -2.39.3 - diff --git a/kvm-s390x-pci-avoid-double-enable-disable-of-aif.patch b/kvm-s390x-pci-avoid-double-enable-disable-of-aif.patch deleted file mode 100644 index 1b4a4ab..0000000 --- a/kvm-s390x-pci-avoid-double-enable-disable-of-aif.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 64b0180f5a52668f8ac4c444ba369231dbc4d5b9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Mon, 22 Jan 2024 09:25:53 +0100 -Subject: [PATCH 096/101] s390x/pci: avoid double enable/disable of aif -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Cédric Le Goater -RH-MergeRequest: 215: s390x: Fix reset ordering of passthrough ISM devices -RH-Jira: RHEL-21169 -RH-Acked-by: Thomas Huth -RH-Acked-by: Cornelia Huck -RH-Commit: [1/3] ebdf8a474ea21486f5ec051683f17bae6d20f675 (clegoate/qemu-kvm-c9s) - -JIRA: https://issues.redhat.com/browse/RHEL-21169 - -commit 07b2c8e034d80ff92e202405c494d2ff80fcf848 -Author: Matthew Rosato -Date: Thu Jan 18 13:51:49 2024 -0500 - - s390x/pci: avoid double enable/disable of aif - - Use a flag to keep track of whether AIF is currently enabled. This can be - used to avoid enabling/disabling AIF multiple times as well as to determine - whether or not it should be disabled during reset processing. - - Fixes: d0bc7091c2 ("s390x/pci: enable adapter event notification for interpreted devices") - Reported-by: Cédric Le Goater - Reviewed-by: Eric Farman - Signed-off-by: Matthew Rosato - Message-ID: <20240118185151.265329-2-mjrosato@linux.ibm.com> - Reviewed-by: Cédric Le Goater - Signed-off-by: Thomas Huth - -Signed-off-by: Cédric Le Goater ---- - hw/s390x/s390-pci-kvm.c | 25 +++++++++++++++++++++++-- - include/hw/s390x/s390-pci-bus.h | 1 + - 2 files changed, 24 insertions(+), 2 deletions(-) - -diff --git a/hw/s390x/s390-pci-kvm.c b/hw/s390x/s390-pci-kvm.c -index ff41e4106d..1ee510436c 100644 ---- a/hw/s390x/s390-pci-kvm.c -+++ b/hw/s390x/s390-pci-kvm.c -@@ -27,6 +27,7 @@ bool s390_pci_kvm_interp_allowed(void) - - int s390_pci_kvm_aif_enable(S390PCIBusDevice *pbdev, ZpciFib *fib, bool assist) - { -+ int rc; - struct kvm_s390_zpci_op args = { - .fh = pbdev->fh, - .op = KVM_S390_ZPCIOP_REG_AEN, -@@ -38,15 +39,35 @@ int s390_pci_kvm_aif_enable(S390PCIBusDevice *pbdev, ZpciFib *fib, bool assist) - .u.reg_aen.flags = (assist) ? 0 : KVM_S390_ZPCIOP_REGAEN_HOST - }; - -- return kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args); -+ if (pbdev->aif) { -+ return -EINVAL; -+ } -+ -+ rc = kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args); -+ if (rc == 0) { -+ pbdev->aif = true; -+ } -+ -+ return rc; - } - - int s390_pci_kvm_aif_disable(S390PCIBusDevice *pbdev) - { -+ int rc; -+ - struct kvm_s390_zpci_op args = { - .fh = pbdev->fh, - .op = KVM_S390_ZPCIOP_DEREG_AEN - }; - -- return kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args); -+ if (!pbdev->aif) { -+ return -EINVAL; -+ } -+ -+ rc = kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args); -+ if (rc == 0) { -+ pbdev->aif = false; -+ } -+ -+ return rc; - } -diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h -index b1bdbeaeb5..435e788867 100644 ---- a/include/hw/s390x/s390-pci-bus.h -+++ b/include/hw/s390x/s390-pci-bus.h -@@ -361,6 +361,7 @@ struct S390PCIBusDevice { - bool unplug_requested; - bool interp; - bool forwarding_assist; -+ bool aif; - QTAILQ_ENTRY(S390PCIBusDevice) link; - }; - --- -2.39.3 - diff --git a/kvm-s390x-pci-drive-ISM-reset-from-subsystem-reset.patch b/kvm-s390x-pci-drive-ISM-reset-from-subsystem-reset.patch deleted file mode 100644 index f3a4129..0000000 --- a/kvm-s390x-pci-drive-ISM-reset-from-subsystem-reset.patch +++ /dev/null @@ -1,137 +0,0 @@ -From c885b17e09ab19a3e8d3b2e1765963811af6f764 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Mon, 22 Jan 2024 09:25:53 +0100 -Subject: [PATCH 098/101] s390x/pci: drive ISM reset from subsystem reset -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Cédric Le Goater -RH-MergeRequest: 215: s390x: Fix reset ordering of passthrough ISM devices -RH-Jira: RHEL-21169 -RH-Acked-by: Thomas Huth -RH-Acked-by: Cornelia Huck -RH-Commit: [3/3] 426cf156a2c67e6dcd7483a769fa3741e2700504 (clegoate/qemu-kvm-c9s) - -JIRA: https://issues.redhat.com/browse/RHEL-21169 - -commit 68c691ca99a2538d6a53a70ce8a9ce06ee307ff1 -Author: Matthew Rosato -Date: Thu Jan 18 13:51:51 2024 -0500 - - s390x/pci: drive ISM reset from subsystem reset - - ISM devices are sensitive to manipulation of the IOMMU, so the ISM device - needs to be reset before the vfio-pci device is reset (triggering a full - UNMAP). In order to ensure this occurs, trigger ISM device resets from - subsystem_reset before triggering the PCI bus reset (which will also - trigger vfio-pci reset). This only needs to be done for ISM devices - which were enabled for use by the guest. - Further, ensure that AIF is disabled as part of the reset event. - - Fixes: ef1535901a ("s390x: do a subsystem reset before the unprotect on reboot") - Fixes: 03451953c7 ("s390x/pci: reset ISM passthrough devices on shutdown and system reset") - Reported-by: Cédric Le Goater - Signed-off-by: Matthew Rosato - Message-ID: <20240118185151.265329-4-mjrosato@linux.ibm.com> - Reviewed-by: Eric Farman - Reviewed-by: Cédric Le Goater - Signed-off-by: Thomas Huth - -Signed-off-by: Cédric Le Goater ---- - hw/s390x/s390-pci-bus.c | 26 +++++++++++++++++--------- - hw/s390x/s390-virtio-ccw.c | 8 ++++++++ - include/hw/s390x/s390-pci-bus.h | 1 + - 3 files changed, 26 insertions(+), 9 deletions(-) - -diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c -index 347580ebac..3e57d5faca 100644 ---- a/hw/s390x/s390-pci-bus.c -+++ b/hw/s390x/s390-pci-bus.c -@@ -151,20 +151,12 @@ static void s390_pci_shutdown_notifier(Notifier *n, void *opaque) - pci_device_reset(pbdev->pdev); - } - --static void s390_pci_reset_cb(void *opaque) --{ -- S390PCIBusDevice *pbdev = opaque; -- -- pci_device_reset(pbdev->pdev); --} -- - static void s390_pci_perform_unplug(S390PCIBusDevice *pbdev) - { - HotplugHandler *hotplug_ctrl; - - if (pbdev->pft == ZPCI_PFT_ISM) { - notifier_remove(&pbdev->shutdown_notifier); -- qemu_unregister_reset(s390_pci_reset_cb, pbdev); - } - - /* Unplug the PCI device */ -@@ -1132,7 +1124,6 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev, - if (pbdev->pft == ZPCI_PFT_ISM) { - pbdev->shutdown_notifier.notify = s390_pci_shutdown_notifier; - qemu_register_shutdown_notifier(&pbdev->shutdown_notifier); -- qemu_register_reset(s390_pci_reset_cb, pbdev); - } - } else { - pbdev->fh |= FH_SHM_EMUL; -@@ -1279,6 +1270,23 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev, - pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, s->bus_no, 1); - } - -+void s390_pci_ism_reset(void) -+{ -+ S390pciState *s = s390_get_phb(); -+ -+ S390PCIBusDevice *pbdev, *next; -+ -+ /* Trigger reset event for each passthrough ISM device currently in-use */ -+ QTAILQ_FOREACH_SAFE(pbdev, &s->zpci_devs, link, next) { -+ if (pbdev->interp && pbdev->pft == ZPCI_PFT_ISM && -+ pbdev->fh & FH_MASK_ENABLE) { -+ s390_pci_kvm_aif_disable(pbdev); -+ -+ pci_device_reset(pbdev->pdev); -+ } -+ } -+} -+ - static void s390_pcihost_reset(DeviceState *dev) - { - S390pciState *s = S390_PCI_HOST_BRIDGE(dev); -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index e26ce26f5a..24f4773179 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -118,6 +118,14 @@ static void subsystem_reset(void) - DeviceState *dev; - int i; - -+ /* -+ * ISM firmware is sensitive to unexpected changes to the IOMMU, which can -+ * occur during reset of the vfio-pci device (unmap of entire aperture). -+ * Ensure any passthrough ISM devices are reset now, while CPUs are paused -+ * but before vfio-pci cleanup occurs. -+ */ -+ s390_pci_ism_reset(); -+ - for (i = 0; i < ARRAY_SIZE(reset_dev_types); i++) { - dev = DEVICE(object_resolve_path_type("", reset_dev_types[i], NULL)); - if (dev) { -diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h -index 435e788867..2c43ea123f 100644 ---- a/include/hw/s390x/s390-pci-bus.h -+++ b/include/hw/s390x/s390-pci-bus.h -@@ -401,5 +401,6 @@ S390PCIBusDevice *s390_pci_find_dev_by_target(S390pciState *s, - const char *target); - S390PCIBusDevice *s390_pci_find_next_avail_dev(S390pciState *s, - S390PCIBusDevice *pbdev); -+void s390_pci_ism_reset(void); - - #endif --- -2.39.3 - diff --git a/kvm-s390x-pci-refresh-fh-before-disabling-aif.patch b/kvm-s390x-pci-refresh-fh-before-disabling-aif.patch deleted file mode 100644 index 845a467..0000000 --- a/kvm-s390x-pci-refresh-fh-before-disabling-aif.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 49078bdfd4c116da3e920632ec6f7041f1b38015 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Mon, 22 Jan 2024 09:25:53 +0100 -Subject: [PATCH 097/101] s390x/pci: refresh fh before disabling aif -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Cédric Le Goater -RH-MergeRequest: 215: s390x: Fix reset ordering of passthrough ISM devices -RH-Jira: RHEL-21169 -RH-Acked-by: Thomas Huth -RH-Acked-by: Cornelia Huck -RH-Commit: [2/3] 3523067909c41818dfc769abdb93930833416c11 (clegoate/qemu-kvm-c9s) - -JIRA: https://issues.redhat.com/browse/RHEL-21169 - -commit 30e35258e25c75c9d799c34fd89afcafffb37084 -Author: Matthew Rosato -Date: Thu Jan 18 13:51:50 2024 -0500 - - s390x/pci: refresh fh before disabling aif - - Typically we refresh the host fh during CLP enable, however it's possible - that the device goes through multiple reset events before the guest - performs another CLP enable. Let's handle this for now by refreshing the - host handle from vfio before disabling aif. - - Fixes: 03451953c7 ("s390x/pci: reset ISM passthrough devices on shutdown and system reset") - Reported-by: Cédric Le Goater - Reviewed-by: Eric Farman - Signed-off-by: Matthew Rosato - Message-ID: <20240118185151.265329-3-mjrosato@linux.ibm.com> - Reviewed-by: Cédric Le Goater - Signed-off-by: Thomas Huth - -Signed-off-by: Cédric Le Goater ---- - hw/s390x/s390-pci-kvm.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/hw/s390x/s390-pci-kvm.c b/hw/s390x/s390-pci-kvm.c -index 1ee510436c..9eef4fc3ec 100644 ---- a/hw/s390x/s390-pci-kvm.c -+++ b/hw/s390x/s390-pci-kvm.c -@@ -18,6 +18,7 @@ - #include "hw/s390x/s390-pci-bus.h" - #include "hw/s390x/s390-pci-kvm.h" - #include "hw/s390x/s390-pci-inst.h" -+#include "hw/s390x/s390-pci-vfio.h" - #include "cpu_models.h" - - bool s390_pci_kvm_interp_allowed(void) -@@ -64,6 +65,14 @@ int s390_pci_kvm_aif_disable(S390PCIBusDevice *pbdev) - return -EINVAL; - } - -+ /* -+ * The device may have already been reset but we still want to relinquish -+ * the guest ISC, so always be sure to use an up-to-date host fh. -+ */ -+ if (!s390_pci_get_host_fh(pbdev, &args.fh)) { -+ return -EPERM; -+ } -+ - rc = kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args); - if (rc == 0) { - pbdev->aif = false; --- -2.39.3 - diff --git a/kvm-scsi-Await-request-purging.patch b/kvm-scsi-Await-request-purging.patch deleted file mode 100644 index 9bd4399..0000000 --- a/kvm-scsi-Await-request-purging.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 94d6458a58239b52394d58b6880509041186d5a8 Mon Sep 17 00:00:00 2001 -From: Hanna Czenczek -Date: Fri, 2 Feb 2024 15:47:55 +0100 -Subject: [PATCH 04/22] scsi: Await request purging - -RH-Author: Hanna Czenczek -RH-MergeRequest: 222: Allow concurrent BlockBackend context changes -RH-Jira: RHEL-24593 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Kevin Wolf -RH-Commit: [2/2] 35a89273cab0af8f999881e67d359fe1328363a0 (hreitz/qemu-kvm-c-9-s) - -scsi_device_for_each_req_async() currently does not provide any way to -be awaited. One of its callers is scsi_device_purge_requests(), which -therefore currently does not guarantee that all requests are fully -settled when it returns. - -We want all requests to be settled, because scsi_device_purge_requests() -is called through the unrealize path, including the one invoked by -virtio_scsi_hotunplug() through qdev_simple_device_unplug_cb(), which -most likely assumes that all SCSI requests are done then. - -In fact, scsi_device_purge_requests() already contains a blk_drain(), -but this will not fully await scsi_device_for_each_req_async(), only the -I/O requests it potentially cancels (not the non-I/O requests). -However, we can have scsi_device_for_each_req_async() increment the BB -in-flight counter, and have scsi_device_for_each_req_async_bh() -decrement it when it is done. This way, the blk_drain() will fully -await all SCSI requests to be purged. - -This also removes the need for scsi_device_for_each_req_async_bh() to -double-check the current context and potentially re-schedule itself, -should it now differ from the BB's context: Changing a BB's AioContext -with a root node is done through bdrv_try_change_aio_context(), which -creates a drained section. With this patch, we keep the BB in-flight -counter elevated throughout, so we know the BB's context cannot change. - -Signed-off-by: Hanna Czenczek -Message-ID: <20240202144755.671354-3-hreitz@redhat.com> -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 1604c0493193273e4eac547f86fbd2845e7f9af4) ---- - hw/scsi/scsi-bus.c | 30 +++++++++++++++++++++--------- - 1 file changed, 21 insertions(+), 9 deletions(-) - -diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c -index 5b08cbf60a..b1bf8e6433 100644 ---- a/hw/scsi/scsi-bus.c -+++ b/hw/scsi/scsi-bus.c -@@ -120,17 +120,13 @@ static void scsi_device_for_each_req_async_bh(void *opaque) - SCSIRequest *next; - - /* -- * If the AioContext changed before this BH was called then reschedule into -- * the new AioContext before accessing ->requests. This can happen when -- * scsi_device_for_each_req_async() is called and then the AioContext is -- * changed before BHs are run. -+ * The BB cannot have changed contexts between this BH being scheduled and -+ * now: BBs' AioContexts, when they have a node attached, can only be -+ * changed via bdrv_try_change_aio_context(), in a drained section. While -+ * we have the in-flight counter incremented, that drain must block. - */ - ctx = blk_get_aio_context(s->conf.blk); -- if (ctx != qemu_get_current_aio_context()) { -- aio_bh_schedule_oneshot(ctx, scsi_device_for_each_req_async_bh, -- g_steal_pointer(&data)); -- return; -- } -+ assert(ctx == qemu_get_current_aio_context()); - - QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) { - data->fn(req, data->fn_opaque); -@@ -138,11 +134,16 @@ static void scsi_device_for_each_req_async_bh(void *opaque) - - /* Drop the reference taken by scsi_device_for_each_req_async() */ - object_unref(OBJECT(s)); -+ -+ /* Paired with blk_inc_in_flight() in scsi_device_for_each_req_async() */ -+ blk_dec_in_flight(s->conf.blk); - } - - /* - * Schedule @fn() to be invoked for each enqueued request in device @s. @fn() - * runs in the AioContext that is executing the request. -+ * Keeps the BlockBackend's in-flight counter incremented until everything is -+ * done, so draining it will settle all scheduled @fn() calls. - */ - static void scsi_device_for_each_req_async(SCSIDevice *s, - void (*fn)(SCSIRequest *, void *), -@@ -163,6 +164,8 @@ static void scsi_device_for_each_req_async(SCSIDevice *s, - */ - object_ref(OBJECT(s)); - -+ /* Paired with blk_dec_in_flight() in scsi_device_for_each_req_async_bh() */ -+ blk_inc_in_flight(s->conf.blk); - aio_bh_schedule_oneshot(blk_get_aio_context(s->conf.blk), - scsi_device_for_each_req_async_bh, - data); -@@ -1728,11 +1731,20 @@ static void scsi_device_purge_one_req(SCSIRequest *req, void *opaque) - scsi_req_cancel_async(req, NULL); - } - -+/** -+ * Cancel all requests, and block until they are deleted. -+ */ - void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense) - { - scsi_device_for_each_req_async(sdev, scsi_device_purge_one_req, NULL); - -+ /* -+ * Await all the scsi_device_purge_one_req() calls scheduled by -+ * scsi_device_for_each_req_async(), and all I/O requests that were -+ * cancelled this way, but may still take a bit of time to settle. -+ */ - blk_drain(sdev->conf.blk); -+ - scsi_device_set_ua(sdev, sense); - } - --- -2.39.3 - diff --git a/kvm-scsi-assert-that-callbacks-run-in-the-correct-AioCon.patch b/kvm-scsi-assert-that-callbacks-run-in-the-correct-AioCon.patch deleted file mode 100644 index 6d43810..0000000 --- a/kvm-scsi-assert-that-callbacks-run-in-the-correct-AioCon.patch +++ /dev/null @@ -1,88 +0,0 @@ -From cd08d22a0da022d99fe6cfddb7de680abf66c8be Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:19:59 -0500 -Subject: [PATCH 082/101] scsi: assert that callbacks run in the correct - AioContext - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [13/26] d2fd5065c3b72d9d2f4e37efee39fe12eba0f0a9 (kmwolf/centos-qemu-kvm) - -Since the removal of AioContext locking, the correctness of the code -relies on running requests from a single AioContext at any given time. - -Add assertions that verify that callbacks are invoked in the correct -AioContext. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20231205182011.1976568-3-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - hw/scsi/scsi-disk.c | 14 ++++++++++++++ - system/dma-helpers.c | 3 +++ - 2 files changed, 17 insertions(+) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index 2c1bbb3530..a5048e0aaf 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -273,6 +273,10 @@ static void scsi_aio_complete(void *opaque, int ret) - SCSIDiskReq *r = (SCSIDiskReq *)opaque; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - -+ /* The request must only run in the BlockBackend's AioContext */ -+ assert(blk_get_aio_context(s->qdev.conf.blk) == -+ qemu_get_current_aio_context()); -+ - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - -@@ -370,8 +374,13 @@ static void scsi_dma_complete(void *opaque, int ret) - - static void scsi_read_complete_noio(SCSIDiskReq *r, int ret) - { -+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - uint32_t n; - -+ /* The request must only run in the BlockBackend's AioContext */ -+ assert(blk_get_aio_context(s->qdev.conf.blk) == -+ qemu_get_current_aio_context()); -+ - assert(r->req.aiocb == NULL); - if (scsi_disk_req_check_error(r, ret, false)) { - goto done; -@@ -496,8 +505,13 @@ static void scsi_read_data(SCSIRequest *req) - - static void scsi_write_complete_noio(SCSIDiskReq *r, int ret) - { -+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - uint32_t n; - -+ /* The request must only run in the BlockBackend's AioContext */ -+ assert(blk_get_aio_context(s->qdev.conf.blk) == -+ qemu_get_current_aio_context()); -+ - assert (r->req.aiocb == NULL); - if (scsi_disk_req_check_error(r, ret, false)) { - goto done; -diff --git a/system/dma-helpers.c b/system/dma-helpers.c -index 528117f256..9b221cf94e 100644 ---- a/system/dma-helpers.c -+++ b/system/dma-helpers.c -@@ -119,6 +119,9 @@ static void dma_blk_cb(void *opaque, int ret) - - trace_dma_blk_cb(dbs, ret); - -+ /* DMAAIOCB is not thread-safe and must be accessed only from dbs->ctx */ -+ assert(ctx == qemu_get_current_aio_context()); -+ - dbs->acb = NULL; - dbs->offset += dbs->iov.size; - --- -2.39.3 - diff --git a/kvm-scsi-don-t-lock-AioContext-in-I-O-code-path.patch b/kvm-scsi-don-t-lock-AioContext-in-I-O-code-path.patch deleted file mode 100644 index 65b08ce..0000000 --- a/kvm-scsi-don-t-lock-AioContext-in-I-O-code-path.patch +++ /dev/null @@ -1,245 +0,0 @@ -From d1d384bd24a7aeb527f4abd8a0958146544ef9bb Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 4 Dec 2023 11:42:58 -0500 -Subject: [PATCH 079/101] scsi: don't lock AioContext in I/O code path - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [10/26] b5814cec94af5c254e300646d8783672b085bac3 (kmwolf/centos-qemu-kvm) - -blk_aio_*() doesn't require the AioContext lock and the SCSI subsystem's -internal state also does not anymore. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Acked-by: Kevin Wolf -Message-ID: <20231204164259.1515217-4-stefanha@redhat.com> -Signed-off-by: Kevin Wolf ---- - hw/scsi/scsi-disk.c | 23 ----------------------- - hw/scsi/scsi-generic.c | 20 +++----------------- - 2 files changed, 3 insertions(+), 40 deletions(-) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index 6691f5edb8..2c1bbb3530 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -273,8 +273,6 @@ static void scsi_aio_complete(void *opaque, int ret) - SCSIDiskReq *r = (SCSIDiskReq *)opaque; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - -- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); -- - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - -@@ -286,7 +284,6 @@ static void scsi_aio_complete(void *opaque, int ret) - scsi_req_complete(&r->req, GOOD); - - done: -- aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); - scsi_req_unref(&r->req); - } - -@@ -394,8 +391,6 @@ static void scsi_read_complete(void *opaque, int ret) - SCSIDiskReq *r = (SCSIDiskReq *)opaque; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - -- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); -- - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - -@@ -406,7 +401,6 @@ static void scsi_read_complete(void *opaque, int ret) - trace_scsi_disk_read_complete(r->req.tag, r->qiov.size); - } - scsi_read_complete_noio(r, ret); -- aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); - } - - /* Actually issue a read to the block device. */ -@@ -448,8 +442,6 @@ static void scsi_do_read_cb(void *opaque, int ret) - SCSIDiskReq *r = (SCSIDiskReq *)opaque; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - -- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); -- - assert (r->req.aiocb != NULL); - r->req.aiocb = NULL; - -@@ -459,7 +451,6 @@ static void scsi_do_read_cb(void *opaque, int ret) - block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); - } - scsi_do_read(opaque, ret); -- aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); - } - - /* Read more data from scsi device into buffer. */ -@@ -533,8 +524,6 @@ static void scsi_write_complete(void * opaque, int ret) - SCSIDiskReq *r = (SCSIDiskReq *)opaque; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - -- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); -- - assert (r->req.aiocb != NULL); - r->req.aiocb = NULL; - -@@ -544,7 +533,6 @@ static void scsi_write_complete(void * opaque, int ret) - block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); - } - scsi_write_complete_noio(r, ret); -- aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); - } - - static void scsi_write_data(SCSIRequest *req) -@@ -1742,8 +1730,6 @@ static void scsi_unmap_complete(void *opaque, int ret) - SCSIDiskReq *r = data->r; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - -- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); -- - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - -@@ -1754,7 +1740,6 @@ static void scsi_unmap_complete(void *opaque, int ret) - block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); - scsi_unmap_complete_noio(data, ret); - } -- aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); - } - - static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf) -@@ -1822,8 +1807,6 @@ static void scsi_write_same_complete(void *opaque, int ret) - SCSIDiskReq *r = data->r; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - -- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); -- - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - -@@ -1847,7 +1830,6 @@ static void scsi_write_same_complete(void *opaque, int ret) - data->sector << BDRV_SECTOR_BITS, - &data->qiov, 0, - scsi_write_same_complete, data); -- aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); - return; - } - -@@ -1857,7 +1839,6 @@ done: - scsi_req_unref(&r->req); - qemu_vfree(data->iov.iov_base); - g_free(data); -- aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); - } - - static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf) -@@ -2810,7 +2791,6 @@ static void scsi_block_sgio_complete(void *opaque, int ret) - { - SCSIBlockReq *req = (SCSIBlockReq *)opaque; - SCSIDiskReq *r = &req->req; -- SCSIDevice *s = r->req.dev; - sg_io_hdr_t *io_hdr = &req->io_header; - - if (ret == 0) { -@@ -2827,13 +2807,10 @@ static void scsi_block_sgio_complete(void *opaque, int ret) - } - - if (ret > 0) { -- aio_context_acquire(blk_get_aio_context(s->conf.blk)); - if (scsi_handle_rw_error(r, ret, true)) { -- aio_context_release(blk_get_aio_context(s->conf.blk)); - scsi_req_unref(&r->req); - return; - } -- aio_context_release(blk_get_aio_context(s->conf.blk)); - - /* Ignore error. */ - ret = 0; -diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c -index 2417f0ad84..b7b04e1d63 100644 ---- a/hw/scsi/scsi-generic.c -+++ b/hw/scsi/scsi-generic.c -@@ -109,15 +109,11 @@ done: - static void scsi_command_complete(void *opaque, int ret) - { - SCSIGenericReq *r = (SCSIGenericReq *)opaque; -- SCSIDevice *s = r->req.dev; -- -- aio_context_acquire(blk_get_aio_context(s->conf.blk)); - - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - - scsi_command_complete_noio(r, ret); -- aio_context_release(blk_get_aio_context(s->conf.blk)); - } - - static int execute_command(BlockBackend *blk, -@@ -274,14 +270,12 @@ static void scsi_read_complete(void * opaque, int ret) - SCSIDevice *s = r->req.dev; - int len; - -- aio_context_acquire(blk_get_aio_context(s->conf.blk)); -- - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - - if (ret || r->req.io_canceled) { - scsi_command_complete_noio(r, ret); -- goto done; -+ return; - } - - len = r->io_header.dxfer_len - r->io_header.resid; -@@ -320,7 +314,7 @@ static void scsi_read_complete(void * opaque, int ret) - r->io_header.status != GOOD || - len == 0) { - scsi_command_complete_noio(r, 0); -- goto done; -+ return; - } - - /* Snoop READ CAPACITY output to set the blocksize. */ -@@ -356,9 +350,6 @@ static void scsi_read_complete(void * opaque, int ret) - req_complete: - scsi_req_data(&r->req, len); - scsi_req_unref(&r->req); -- --done: -- aio_context_release(blk_get_aio_context(s->conf.blk)); - } - - /* Read more data from scsi device into buffer. */ -@@ -391,14 +382,12 @@ static void scsi_write_complete(void * opaque, int ret) - - trace_scsi_generic_write_complete(ret); - -- aio_context_acquire(blk_get_aio_context(s->conf.blk)); -- - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - - if (ret || r->req.io_canceled) { - scsi_command_complete_noio(r, ret); -- goto done; -+ return; - } - - if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 && -@@ -408,9 +397,6 @@ static void scsi_write_complete(void * opaque, int ret) - } - - scsi_command_complete_noio(r, ret); -- --done: -- aio_context_release(blk_get_aio_context(s->conf.blk)); - } - - /* Write data to a scsi device. Returns nonzero on failure. --- -2.39.3 - diff --git a/kvm-scsi-only-access-SCSIDevice-requests-from-one-thread.patch b/kvm-scsi-only-access-SCSIDevice-requests-from-one-thread.patch deleted file mode 100644 index 30f1c00..0000000 --- a/kvm-scsi-only-access-SCSIDevice-requests-from-one-thread.patch +++ /dev/null @@ -1,307 +0,0 @@ -From 42dd1357310bd1a68d6cacaa53cd5b1d1b02880d Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 4 Dec 2023 11:42:56 -0500 -Subject: [PATCH 077/101] scsi: only access SCSIDevice->requests from one - thread - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [8/26] 9df662e82a63e93d184b5763bebbe7e43bc9dabe (kmwolf/centos-qemu-kvm) - -Stop depending on the AioContext lock and instead access -SCSIDevice->requests from only one thread at a time: -- When the VM is running only the BlockBackend's AioContext may access - the requests list. -- When the VM is stopped only the main loop may access the requests - list. - -These constraints protect the requests list without the need for locking -in the I/O code path. - -Note that multiple IOThreads are not supported yet because the code -assumes all SCSIRequests are executed from a single AioContext. Leave -that as future work. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Message-ID: <20231204164259.1515217-2-stefanha@redhat.com> -Signed-off-by: Kevin Wolf ---- - hw/scsi/scsi-bus.c | 181 ++++++++++++++++++++++++++++------------- - include/hw/scsi/scsi.h | 7 +- - 2 files changed, 131 insertions(+), 57 deletions(-) - -diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c -index fc4b77fdb0..b649cdf555 100644 ---- a/hw/scsi/scsi-bus.c -+++ b/hw/scsi/scsi-bus.c -@@ -85,6 +85,89 @@ SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int id, int lun) - return d; - } - -+/* -+ * Invoke @fn() for each enqueued request in device @s. Must be called from the -+ * main loop thread while the guest is stopped. This is only suitable for -+ * vmstate ->put(), use scsi_device_for_each_req_async() for other cases. -+ */ -+static void scsi_device_for_each_req_sync(SCSIDevice *s, -+ void (*fn)(SCSIRequest *, void *), -+ void *opaque) -+{ -+ SCSIRequest *req; -+ SCSIRequest *next_req; -+ -+ assert(!runstate_is_running()); -+ assert(qemu_in_main_thread()); -+ -+ QTAILQ_FOREACH_SAFE(req, &s->requests, next, next_req) { -+ fn(req, opaque); -+ } -+} -+ -+typedef struct { -+ SCSIDevice *s; -+ void (*fn)(SCSIRequest *, void *); -+ void *fn_opaque; -+} SCSIDeviceForEachReqAsyncData; -+ -+static void scsi_device_for_each_req_async_bh(void *opaque) -+{ -+ g_autofree SCSIDeviceForEachReqAsyncData *data = opaque; -+ SCSIDevice *s = data->s; -+ AioContext *ctx; -+ SCSIRequest *req; -+ SCSIRequest *next; -+ -+ /* -+ * If the AioContext changed before this BH was called then reschedule into -+ * the new AioContext before accessing ->requests. This can happen when -+ * scsi_device_for_each_req_async() is called and then the AioContext is -+ * changed before BHs are run. -+ */ -+ ctx = blk_get_aio_context(s->conf.blk); -+ if (ctx != qemu_get_current_aio_context()) { -+ aio_bh_schedule_oneshot(ctx, scsi_device_for_each_req_async_bh, -+ g_steal_pointer(&data)); -+ return; -+ } -+ -+ QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) { -+ data->fn(req, data->fn_opaque); -+ } -+ -+ /* Drop the reference taken by scsi_device_for_each_req_async() */ -+ object_unref(OBJECT(s)); -+} -+ -+/* -+ * Schedule @fn() to be invoked for each enqueued request in device @s. @fn() -+ * runs in the AioContext that is executing the request. -+ */ -+static void scsi_device_for_each_req_async(SCSIDevice *s, -+ void (*fn)(SCSIRequest *, void *), -+ void *opaque) -+{ -+ assert(qemu_in_main_thread()); -+ -+ SCSIDeviceForEachReqAsyncData *data = -+ g_new(SCSIDeviceForEachReqAsyncData, 1); -+ -+ data->s = s; -+ data->fn = fn; -+ data->fn_opaque = opaque; -+ -+ /* -+ * Hold a reference to the SCSIDevice until -+ * scsi_device_for_each_req_async_bh() finishes. -+ */ -+ object_ref(OBJECT(s)); -+ -+ aio_bh_schedule_oneshot(blk_get_aio_context(s->conf.blk), -+ scsi_device_for_each_req_async_bh, -+ data); -+} -+ - static void scsi_device_realize(SCSIDevice *s, Error **errp) - { - SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s); -@@ -144,20 +227,18 @@ void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host, - qbus_set_bus_hotplug_handler(BUS(bus)); - } - --static void scsi_dma_restart_bh(void *opaque) -+void scsi_req_retry(SCSIRequest *req) - { -- SCSIDevice *s = opaque; -- SCSIRequest *req, *next; -- -- qemu_bh_delete(s->bh); -- s->bh = NULL; -+ req->retry = true; -+} - -- aio_context_acquire(blk_get_aio_context(s->conf.blk)); -- QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) { -- scsi_req_ref(req); -- if (req->retry) { -- req->retry = false; -- switch (req->cmd.mode) { -+/* Called in the AioContext that is executing the request */ -+static void scsi_dma_restart_req(SCSIRequest *req, void *opaque) -+{ -+ scsi_req_ref(req); -+ if (req->retry) { -+ req->retry = false; -+ switch (req->cmd.mode) { - case SCSI_XFER_FROM_DEV: - case SCSI_XFER_TO_DEV: - scsi_req_continue(req); -@@ -166,37 +247,22 @@ static void scsi_dma_restart_bh(void *opaque) - scsi_req_dequeue(req); - scsi_req_enqueue(req); - break; -- } - } -- scsi_req_unref(req); - } -- aio_context_release(blk_get_aio_context(s->conf.blk)); -- /* Drop the reference that was acquired in scsi_dma_restart_cb */ -- object_unref(OBJECT(s)); --} -- --void scsi_req_retry(SCSIRequest *req) --{ -- /* No need to save a reference, because scsi_dma_restart_bh just -- * looks at the request list. */ -- req->retry = true; -+ scsi_req_unref(req); - } - - static void scsi_dma_restart_cb(void *opaque, bool running, RunState state) - { - SCSIDevice *s = opaque; - -+ assert(qemu_in_main_thread()); -+ - if (!running) { - return; - } -- if (!s->bh) { -- AioContext *ctx = blk_get_aio_context(s->conf.blk); -- /* The reference is dropped in scsi_dma_restart_bh.*/ -- object_ref(OBJECT(s)); -- s->bh = aio_bh_new_guarded(ctx, scsi_dma_restart_bh, s, -- &DEVICE(s)->mem_reentrancy_guard); -- qemu_bh_schedule(s->bh); -- } -+ -+ scsi_device_for_each_req_async(s, scsi_dma_restart_req, NULL); - } - - static bool scsi_bus_is_address_free(SCSIBus *bus, -@@ -1657,15 +1723,16 @@ void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense) - } - } - -+static void scsi_device_purge_one_req(SCSIRequest *req, void *opaque) -+{ -+ scsi_req_cancel_async(req, NULL); -+} -+ - void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense) - { -- SCSIRequest *req; -+ scsi_device_for_each_req_async(sdev, scsi_device_purge_one_req, NULL); - - aio_context_acquire(blk_get_aio_context(sdev->conf.blk)); -- while (!QTAILQ_EMPTY(&sdev->requests)) { -- req = QTAILQ_FIRST(&sdev->requests); -- scsi_req_cancel_async(req, NULL); -- } - blk_drain(sdev->conf.blk); - aio_context_release(blk_get_aio_context(sdev->conf.blk)); - scsi_device_set_ua(sdev, sense); -@@ -1737,31 +1804,33 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev) - - /* SCSI request list. For simplicity, pv points to the whole device */ - -+static void put_scsi_req(SCSIRequest *req, void *opaque) -+{ -+ QEMUFile *f = opaque; -+ -+ assert(!req->io_canceled); -+ assert(req->status == -1 && req->host_status == -1); -+ assert(req->enqueued); -+ -+ qemu_put_sbyte(f, req->retry ? 1 : 2); -+ qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf)); -+ qemu_put_be32s(f, &req->tag); -+ qemu_put_be32s(f, &req->lun); -+ if (req->bus->info->save_request) { -+ req->bus->info->save_request(f, req); -+ } -+ if (req->ops->save_request) { -+ req->ops->save_request(f, req); -+ } -+} -+ - static int put_scsi_requests(QEMUFile *f, void *pv, size_t size, - const VMStateField *field, JSONWriter *vmdesc) - { - SCSIDevice *s = pv; -- SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus); -- SCSIRequest *req; - -- QTAILQ_FOREACH(req, &s->requests, next) { -- assert(!req->io_canceled); -- assert(req->status == -1 && req->host_status == -1); -- assert(req->enqueued); -- -- qemu_put_sbyte(f, req->retry ? 1 : 2); -- qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf)); -- qemu_put_be32s(f, &req->tag); -- qemu_put_be32s(f, &req->lun); -- if (bus->info->save_request) { -- bus->info->save_request(f, req); -- } -- if (req->ops->save_request) { -- req->ops->save_request(f, req); -- } -- } -+ scsi_device_for_each_req_sync(s, put_scsi_req, f); - qemu_put_sbyte(f, 0); -- - return 0; - } - -diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h -index 3692ca82f3..10c4e8288d 100644 ---- a/include/hw/scsi/scsi.h -+++ b/include/hw/scsi/scsi.h -@@ -69,14 +69,19 @@ struct SCSIDevice - { - DeviceState qdev; - VMChangeStateEntry *vmsentry; -- QEMUBH *bh; - uint32_t id; - BlockConf conf; - SCSISense unit_attention; - bool sense_is_ua; - uint8_t sense[SCSI_SENSE_BUF_SIZE]; - uint32_t sense_len; -+ -+ /* -+ * The requests list is only accessed from the AioContext that executes -+ * requests or from the main loop when IOThread processing is stopped. -+ */ - QTAILQ_HEAD(, SCSIRequest) requests; -+ - uint32_t channel; - uint32_t lun; - int blocksize; --- -2.39.3 - diff --git a/kvm-scsi-remove-AioContext-locking.patch b/kvm-scsi-remove-AioContext-locking.patch deleted file mode 100644 index 34a5e46..0000000 --- a/kvm-scsi-remove-AioContext-locking.patch +++ /dev/null @@ -1,280 +0,0 @@ -From 61d605433a5edfcc7fe836fd399106ed1e1907bb Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:05 -0500 -Subject: [PATCH 088/101] scsi: remove AioContext locking - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [19/26] 12a8e26670074a17dd2b0cfac06e0aea03b3068f (kmwolf/centos-qemu-kvm) - -The AioContext lock no longer has any effect. Remove it. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Message-ID: <20231205182011.1976568-9-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - hw/scsi/scsi-bus.c | 2 -- - hw/scsi/scsi-disk.c | 31 +++++-------------------------- - hw/scsi/virtio-scsi.c | 18 ------------------ - include/hw/virtio/virtio-scsi.h | 14 -------------- - 4 files changed, 5 insertions(+), 60 deletions(-) - -diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c -index b649cdf555..5b08cbf60a 100644 ---- a/hw/scsi/scsi-bus.c -+++ b/hw/scsi/scsi-bus.c -@@ -1732,9 +1732,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense) - { - scsi_device_for_each_req_async(sdev, scsi_device_purge_one_req, NULL); - -- aio_context_acquire(blk_get_aio_context(sdev->conf.blk)); - blk_drain(sdev->conf.blk); -- aio_context_release(blk_get_aio_context(sdev->conf.blk)); - scsi_device_set_ua(sdev, sense); - } - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index a5048e0aaf..61be3d395a 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -2339,14 +2339,10 @@ static void scsi_disk_reset(DeviceState *dev) - { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev); - uint64_t nb_sectors; -- AioContext *ctx; - - scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET)); - -- ctx = blk_get_aio_context(s->qdev.conf.blk); -- aio_context_acquire(ctx); - blk_get_geometry(s->qdev.conf.blk, &nb_sectors); -- aio_context_release(ctx); - - nb_sectors /= s->qdev.blocksize / BDRV_SECTOR_SIZE; - if (nb_sectors) { -@@ -2545,15 +2541,13 @@ static void scsi_unrealize(SCSIDevice *dev) - static void scsi_hd_realize(SCSIDevice *dev, Error **errp) - { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); -- AioContext *ctx = NULL; -+ - /* can happen for devices without drive. The error message for missing - * backend will be issued in scsi_realize - */ - if (s->qdev.conf.blk) { -- ctx = blk_get_aio_context(s->qdev.conf.blk); -- aio_context_acquire(ctx); - if (!blkconf_blocksizes(&s->qdev.conf, errp)) { -- goto out; -+ return; - } - } - s->qdev.blocksize = s->qdev.conf.logical_block_size; -@@ -2562,16 +2556,11 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp) - s->product = g_strdup("QEMU HARDDISK"); - } - scsi_realize(&s->qdev, errp); --out: -- if (ctx) { -- aio_context_release(ctx); -- } - } - - static void scsi_cd_realize(SCSIDevice *dev, Error **errp) - { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); -- AioContext *ctx; - int ret; - uint32_t blocksize = 2048; - -@@ -2587,8 +2576,6 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp) - blocksize = dev->conf.physical_block_size; - } - -- ctx = blk_get_aio_context(dev->conf.blk); -- aio_context_acquire(ctx); - s->qdev.blocksize = blocksize; - s->qdev.type = TYPE_ROM; - s->features |= 1 << SCSI_DISK_F_REMOVABLE; -@@ -2596,7 +2583,6 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp) - s->product = g_strdup("QEMU CD-ROM"); - } - scsi_realize(&s->qdev, errp); -- aio_context_release(ctx); - } - - -@@ -2727,7 +2713,6 @@ static int get_device_type(SCSIDiskState *s) - static void scsi_block_realize(SCSIDevice *dev, Error **errp) - { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); -- AioContext *ctx; - int sg_version; - int rc; - -@@ -2742,9 +2727,6 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) - "be removed in a future version"); - } - -- ctx = blk_get_aio_context(s->qdev.conf.blk); -- aio_context_acquire(ctx); -- - /* check we are using a driver managing SG_IO (version 3 and after) */ - rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version); - if (rc < 0) { -@@ -2752,18 +2734,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) - if (rc != -EPERM) { - error_append_hint(errp, "Is this a SCSI device?\n"); - } -- goto out; -+ return; - } - if (sg_version < 30000) { - error_setg(errp, "scsi generic interface too old"); -- goto out; -+ return; - } - - /* get device type from INQUIRY data */ - rc = get_device_type(s); - if (rc < 0) { - error_setg(errp, "INQUIRY failed"); -- goto out; -+ return; - } - - /* Make a guess for the block size, we'll fix it when the guest sends. -@@ -2783,9 +2765,6 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) - - scsi_realize(&s->qdev, errp); - scsi_generic_read_device_inquiry(&s->qdev); -- --out: -- aio_context_release(ctx); - } - - typedef struct SCSIBlockReq { -diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c -index 4f8d35facc..ca365a70e9 100644 ---- a/hw/scsi/virtio-scsi.c -+++ b/hw/scsi/virtio-scsi.c -@@ -642,9 +642,7 @@ static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) - return; - } - -- virtio_scsi_acquire(s); - virtio_scsi_handle_ctrl_vq(s, vq); -- virtio_scsi_release(s); - } - - static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req) -@@ -882,9 +880,7 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq) - return; - } - -- virtio_scsi_acquire(s); - virtio_scsi_handle_cmd_vq(s, vq); -- virtio_scsi_release(s); - } - - static void virtio_scsi_get_config(VirtIODevice *vdev, -@@ -1031,9 +1027,7 @@ static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq) - return; - } - -- virtio_scsi_acquire(s); - virtio_scsi_handle_event_vq(s, vq); -- virtio_scsi_release(s); - } - - static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense) -@@ -1052,9 +1046,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense) - }, - }; - -- virtio_scsi_acquire(s); - virtio_scsi_push_event(s, &info); -- virtio_scsi_release(s); - } - } - -@@ -1071,17 +1063,13 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, - VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev); - VirtIOSCSI *s = VIRTIO_SCSI(vdev); - SCSIDevice *sd = SCSI_DEVICE(dev); -- AioContext *old_context; - int ret; - - if (s->ctx && !s->dataplane_fenced) { - if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { - return; - } -- old_context = blk_get_aio_context(sd->conf.blk); -- aio_context_acquire(old_context); - ret = blk_set_aio_context(sd->conf.blk, s->ctx, errp); -- aio_context_release(old_context); - if (ret < 0) { - return; - } -@@ -1097,10 +1085,8 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, - }, - }; - -- virtio_scsi_acquire(s); - virtio_scsi_push_event(s, &info); - scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED)); -- virtio_scsi_release(s); - } - } - -@@ -1122,17 +1108,13 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, - qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); - - if (s->ctx) { -- virtio_scsi_acquire(s); - /* If other users keep the BlockBackend in the iothread, that's ok */ - blk_set_aio_context(sd->conf.blk, qemu_get_aio_context(), NULL); -- virtio_scsi_release(s); - } - - if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) { -- virtio_scsi_acquire(s); - virtio_scsi_push_event(s, &info); - scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED)); -- virtio_scsi_release(s); - } - } - -diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h -index da8cb928d9..7f0573b1bf 100644 ---- a/include/hw/virtio/virtio-scsi.h -+++ b/include/hw/virtio/virtio-scsi.h -@@ -101,20 +101,6 @@ struct VirtIOSCSI { - uint32_t host_features; - }; - --static inline void virtio_scsi_acquire(VirtIOSCSI *s) --{ -- if (s->ctx) { -- aio_context_acquire(s->ctx); -- } --} -- --static inline void virtio_scsi_release(VirtIOSCSI *s) --{ -- if (s->ctx) { -- aio_context_release(s->ctx); -- } --} -- - void virtio_scsi_common_realize(DeviceState *dev, - VirtIOHandleOutput ctrl, - VirtIOHandleOutput evt, --- -2.39.3 - diff --git a/kvm-scsi-remove-outdated-AioContext-lock-comment.patch b/kvm-scsi-remove-outdated-AioContext-lock-comment.patch deleted file mode 100644 index c9baf60..0000000 --- a/kvm-scsi-remove-outdated-AioContext-lock-comment.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 9f5c6dbe907fe6227006ab51179eaa50a63559cb Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:09 -0500 -Subject: [PATCH 092/101] scsi: remove outdated AioContext lock comment - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [23/26] 96e2e7d2e6a160ce4d695060f902d21030b3b1d8 (kmwolf/centos-qemu-kvm) - -The SCSI subsystem no longer uses the AioContext lock. Request -processing runs exclusively in the BlockBackend's AioContext since -"scsi: only access SCSIDevice->requests from one thread" and hence the -lock is unnecessary. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Message-ID: <20231205182011.1976568-13-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - hw/scsi/scsi-disk.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index 61be3d395a..2e7e1e9a1c 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -355,7 +355,6 @@ done: - scsi_req_unref(&r->req); - } - --/* Called with AioContext lock held */ - static void scsi_dma_complete(void *opaque, int ret) - { - SCSIDiskReq *r = (SCSIDiskReq *)opaque; --- -2.39.3 - diff --git a/kvm-smbios-add-smbios_add_usr_blob_size-helper.patch b/kvm-smbios-add-smbios_add_usr_blob_size-helper.patch deleted file mode 100644 index a9d24a0..0000000 --- a/kvm-smbios-add-smbios_add_usr_blob_size-helper.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 93cf5b82771f1d1e8182be168dae7a45d42069e9 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Mon, 4 Mar 2024 15:39:57 +0100 -Subject: [PATCH 11/20] smbios: add smbios_add_usr_blob_size() helper - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [9/18] 8c698fb9e186d2b1d2b7f75a74305f356450ad68 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -it will be used by follow up patch when legacy handling -is moved out into a separate file. - -Signed-off-by: Igor Mammedov -Reviewed-by: Ani Sinha ---- - hw/smbios/smbios.c | 18 ++++++++++++++---- - 1 file changed, 14 insertions(+), 4 deletions(-) - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 441517cf24..c48a290478 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -1426,6 +1426,14 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts, - return true; - } - -+static void smbios_add_usr_blob_size(size_t size) -+{ -+ if (!usr_blobs_sizes) { -+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t)); -+ } -+ g_array_append_val(usr_blobs_sizes, size); -+} -+ - void smbios_entry_add(QemuOpts *opts, Error **errp) - { - const char *val; -@@ -1473,10 +1481,12 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) - smbios_type4_count++; - } - -- if (!usr_blobs_sizes) { -- usr_blobs_sizes = g_array_new(false, false, sizeof(size_t)); -- } -- g_array_append_val(usr_blobs_sizes, size); -+ /* -+ * preserve blob size for legacy mode so it could build its -+ * blobs flavor from 'usr_blobs' -+ */ -+ smbios_add_usr_blob_size(size); -+ - usr_blobs_len += size; - if (size > usr_table_max) { - usr_table_max = size; --- -2.39.3 - diff --git a/kvm-smbios-avoid-mangling-user-provided-tables.patch b/kvm-smbios-avoid-mangling-user-provided-tables.patch deleted file mode 100644 index b8e4d92..0000000 --- a/kvm-smbios-avoid-mangling-user-provided-tables.patch +++ /dev/null @@ -1,309 +0,0 @@ -From 15d293b706ca6c9e6ad569becda8da5f70461c30 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Tue, 13 Feb 2024 09:25:11 +0100 -Subject: [PATCH 09/20] smbios: avoid mangling user provided tables - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [7/18] fa2c7372f55f29e5834eee94ba98f19ea02e7a82 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - - currently smbios_entry_add() preserves internally '-smbios type=' - options but tables provided with '-smbios file=' are stored directly - into blob that eventually will be exposed to VM. And then later - QEMU adds default/'-smbios type' entries on top into the same blob. - - It makes impossible to generate tables more than once, hence - 'immutable' guard was used. - Make it possible to regenerate final blob by storing user provided - blobs into a dedicated area (usr_blobs) and then copy it when - composing final blob. Which also makes handling of -smbios - options consistent. - - As side effect of this and previous commits there is no need to - generate legacy smbios_entries at the time options are parsed. - Instead compose smbios_entries on demand from usr_blobs like - it is done for non-legacy SMBIOS tables. - - Signed-off-by: Igor Mammedov - Tested-by: Fiona Ebner - Reviewed-by: Ani Sinha - -Conflicts: hw/smbios/smbios.c - caused by downstream smbios_type2_required - -Signed-off-by: Igor Mammedov ---- - hw/smbios/smbios.c | 181 +++++++++++++++++++++++---------------------- - 1 file changed, 93 insertions(+), 88 deletions(-) - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 0c8c439859..d8d68716d4 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -60,6 +60,14 @@ static bool smbios_uuid_encoded = true; - /* Set to true for modern Windows 10 HardwareID-6 compat */ - static bool smbios_type2_required; - -+/* -+ * SMBIOS tables provided by user with '-smbios file=' option -+ */ -+uint8_t *usr_blobs; -+size_t usr_blobs_len; -+static GArray *usr_blobs_sizes; -+static unsigned usr_table_max; -+static unsigned usr_table_cnt; - - uint8_t *smbios_tables; - size_t smbios_tables_len; -@@ -70,7 +78,6 @@ static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32; - static SmbiosEntryPoint ep; - - static int smbios_type4_count = 0; --static bool smbios_immutable; - static bool smbios_have_defaults; - static uint32_t smbios_cpuid_version, smbios_cpuid_features; - -@@ -617,9 +624,8 @@ static void smbios_build_type_1_fields(void) - - uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) - { -- /* drop unwanted version of command-line file blob(s) */ -- g_free(smbios_tables); -- smbios_tables = NULL; -+ int i; -+ size_t usr_offset; - - /* also complain if fields were given for types > 1 */ - if (find_next_bit(have_fields_bitmap, -@@ -629,12 +635,33 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) - exit(1); - } - -- if (!smbios_immutable) { -- smbios_build_type_0_fields(); -- smbios_build_type_1_fields(); -- smbios_validate_table(expected_t4_count); -- smbios_immutable = true; -+ g_free(smbios_entries); -+ smbios_entries_len = sizeof(uint16_t); -+ smbios_entries = g_malloc0(smbios_entries_len); -+ -+ for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len; -+ i++) -+ { -+ struct smbios_table *table; -+ struct smbios_structure_header *header; -+ size_t size = g_array_index(usr_blobs_sizes, size_t, i); -+ -+ header = (struct smbios_structure_header *)(usr_blobs + usr_offset); -+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len + -+ size + sizeof(*table)); -+ table = (struct smbios_table *)(smbios_entries + smbios_entries_len); -+ table->header.type = SMBIOS_TABLE_ENTRY; -+ table->header.length = cpu_to_le16(sizeof(*table) + size); -+ memcpy(table->data, header, size); -+ smbios_entries_len += sizeof(*table) + size; -+ (*(uint16_t *)smbios_entries) = -+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1); -+ usr_offset += size; - } -+ -+ smbios_build_type_0_fields(); -+ smbios_build_type_1_fields(); -+ smbios_validate_table(expected_t4_count); - *length = smbios_entries_len; - return smbios_entries; - } -@@ -1232,68 +1259,68 @@ void smbios_get_tables(MachineState *ms, - { - unsigned i, dimm_cnt, offset; - -- /* drop unwanted (legacy) version of command-line file blob(s) */ -- g_free(smbios_entries); -- smbios_entries = NULL; -+ g_free(smbios_tables); -+ smbios_tables = g_memdup2(usr_blobs, usr_blobs_len); -+ smbios_tables_len = usr_blobs_len; -+ smbios_table_max = usr_table_max; -+ smbios_table_cnt = usr_table_cnt; - -- if (!smbios_immutable) { -- smbios_build_type_0_table(); -- smbios_build_type_1_table(); -- smbios_build_type_2_table(); -- smbios_build_type_3_table(); -+ smbios_build_type_0_table(); -+ smbios_build_type_1_table(); -+ smbios_build_type_2_table(); -+ smbios_build_type_3_table(); - -- assert(ms->smp.sockets >= 1); -+ assert(ms->smp.sockets >= 1); - -- for (i = 0; i < ms->smp.sockets; i++) { -- smbios_build_type_4_table(ms, i); -- } -+ for (i = 0; i < ms->smp.sockets; i++) { -+ smbios_build_type_4_table(ms, i); -+ } - -- smbios_build_type_8_table(); -- smbios_build_type_9_table(errp); -- smbios_build_type_11_table(); -+ smbios_build_type_8_table(); -+ smbios_build_type_9_table(errp); -+ smbios_build_type_11_table(); - - #define MAX_DIMM_SZ (16 * GiB) - #define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \ - : ((current_machine->ram_size - 1) % MAX_DIMM_SZ) + 1) - -- dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ; -+ dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) / -+ MAX_DIMM_SZ; - -- /* -- * The offset determines if we need to keep additional space between -- * table 17 and table 19 header handle numbers so that they do -- * not overlap. For example, for a VM with larger than 8 TB guest -- * memory and DIMM like chunks of 16 GiB, the default space between -- * the two tables (T19_BASE - T17_BASE = 512) is not enough. -- */ -- offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \ -- dimm_cnt - (T19_BASE - T17_BASE) : 0; -+ /* -+ * The offset determines if we need to keep additional space between -+ * table 17 and table 19 header handle numbers so that they do -+ * not overlap. For example, for a VM with larger than 8 TB guest -+ * memory and DIMM like chunks of 16 GiB, the default space between -+ * the two tables (T19_BASE - T17_BASE = 512) is not enough. -+ */ -+ offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \ -+ dimm_cnt - (T19_BASE - T17_BASE) : 0; - -- smbios_build_type_16_table(dimm_cnt); -+ smbios_build_type_16_table(dimm_cnt); - -- for (i = 0; i < dimm_cnt; i++) { -- smbios_build_type_17_table(i, GET_DIMM_SZ); -- } -+ for (i = 0; i < dimm_cnt; i++) { -+ smbios_build_type_17_table(i, GET_DIMM_SZ); -+ } - -- for (i = 0; i < mem_array_size; i++) { -- smbios_build_type_19_table(i, offset, mem_array[i].address, -- mem_array[i].length); -- } -+ for (i = 0; i < mem_array_size; i++) { -+ smbios_build_type_19_table(i, offset, mem_array[i].address, -+ mem_array[i].length); -+ } - -- /* -- * make sure 16 bit handle numbers in the headers of tables 19 -- * and 32 do not overlap. -- */ -- assert((mem_array_size + offset) < (T32_BASE - T19_BASE)); -+ /* -+ * make sure 16 bit handle numbers in the headers of tables 19 -+ * and 32 do not overlap. -+ */ -+ assert((mem_array_size + offset) < (T32_BASE - T19_BASE)); - -- smbios_build_type_32_table(); -- smbios_build_type_38_table(); -- smbios_build_type_41_table(errp); -- smbios_build_type_127_table(); -+ smbios_build_type_32_table(); -+ smbios_build_type_38_table(); -+ smbios_build_type_41_table(errp); -+ smbios_build_type_127_table(); - -- smbios_validate_table(ms->smp.sockets); -- smbios_entry_point_setup(); -- smbios_immutable = true; -- } -+ smbios_validate_table(ms->smp.sockets); -+ smbios_entry_point_setup(); - - /* return tables blob and entry point (anchor), and their sizes */ - *tables = smbios_tables; -@@ -1393,13 +1420,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) - { - const char *val; - -- assert(!smbios_immutable); -- - val = qemu_opt_get(opts, "file"); - if (val) { - struct smbios_structure_header *header; -- int size; -- struct smbios_table *table; /* legacy mode only */ -+ size_t size; - - if (!qemu_opts_validate(opts, qemu_smbios_file_opts, errp)) { - return; -@@ -1416,9 +1440,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) - * (except in legacy mode, where the second '\0' is implicit and - * will be inserted by the BIOS). - */ -- smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size); -- header = (struct smbios_structure_header *)(smbios_tables + -- smbios_tables_len); -+ usr_blobs = g_realloc(usr_blobs, usr_blobs_len + size); -+ header = (struct smbios_structure_header *)(usr_blobs + -+ usr_blobs_len); - - if (load_image_size(val, (uint8_t *)header, size) != size) { - error_setg(errp, "Failed to load SMBIOS file %s", val); -@@ -1439,34 +1463,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) - smbios_type4_count++; - } - -- smbios_tables_len += size; -- if (size > smbios_table_max) { -- smbios_table_max = size; -+ if (!usr_blobs_sizes) { -+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t)); - } -- smbios_table_cnt++; -- -- /* add a copy of the newly loaded blob to legacy smbios_entries */ -- /* NOTE: This code runs before smbios_set_defaults(), so we don't -- * yet know which mode (legacy vs. aggregate-table) will be -- * required. We therefore add the binary blob to both legacy -- * (smbios_entries) and aggregate (smbios_tables) tables, and -- * delete the one we don't need from smbios_set_defaults(), -- * once we know which machine version has been requested. -- */ -- if (!smbios_entries) { -- smbios_entries_len = sizeof(uint16_t); -- smbios_entries = g_malloc0(smbios_entries_len); -+ g_array_append_val(usr_blobs_sizes, size); -+ usr_blobs_len += size; -+ if (size > usr_table_max) { -+ usr_table_max = size; - } -- smbios_entries = g_realloc(smbios_entries, smbios_entries_len + -- size + sizeof(*table)); -- table = (struct smbios_table *)(smbios_entries + smbios_entries_len); -- table->header.type = SMBIOS_TABLE_ENTRY; -- table->header.length = cpu_to_le16(sizeof(*table) + size); -- memcpy(table->data, header, size); -- smbios_entries_len += sizeof(*table) + size; -- (*(uint16_t *)smbios_entries) = -- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1); -- /* end: add a copy of the newly loaded blob to legacy smbios_entries */ -+ usr_table_cnt++; - - return; - } --- -2.39.3 - diff --git a/kvm-smbios-build-legacy-mode-code-only-for-pc-machine.patch b/kvm-smbios-build-legacy-mode-code-only-for-pc-machine.patch deleted file mode 100644 index 1dc4d22..0000000 --- a/kvm-smbios-build-legacy-mode-code-only-for-pc-machine.patch +++ /dev/null @@ -1,517 +0,0 @@ -From 7ebb314a4f81d6d1a7dd4980b757fb5e556f5837 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Tue, 13 Feb 2024 16:45:18 +0100 -Subject: [PATCH 13/20] smbios: build legacy mode code only for 'pc' machine - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [11/18] 06e639be03e0d151fb9bcf5f728388edcb84219a - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - - basically moving code around without functional change. - And exposing some symbols so that they could be shared - between smbbios.c and new smbios_legacy.c - - plus some meson magic to build smbios_legacy.c only - for 'pc' machine and otherwise replace it with stub - if not selected. - - Signed-off-by: Igor Mammedov - Reviewed-by: Ani Sinha - -Conflicts: hw/smbios/smbios.c - context change due to downstream smbios_type2_required - -Signed-off-by: Igor Mammedov ---- - hw/i386/Kconfig | 1 + - hw/smbios/Kconfig | 2 + - hw/smbios/meson.build | 5 + - hw/smbios/smbios.c | 163 +----------------------------- - hw/smbios/smbios_legacy.c | 179 +++++++++++++++++++++++++++++++++ - hw/smbios/smbios_legacy_stub.c | 15 +++ - include/hw/firmware/smbios.h | 5 + - 7 files changed, 208 insertions(+), 162 deletions(-) - create mode 100644 hw/smbios/smbios_legacy.c - create mode 100644 hw/smbios/smbios_legacy_stub.c - -diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig -index a1846be6f7..a6ee052f9a 100644 ---- a/hw/i386/Kconfig -+++ b/hw/i386/Kconfig -@@ -76,6 +76,7 @@ config I440FX - select PIIX - select DIMM - select SMBIOS -+ select SMBIOS_LEGACY - select FW_CFG_DMA - - config ISAPC -diff --git a/hw/smbios/Kconfig b/hw/smbios/Kconfig -index 553adf4bfc..8d989a2f1b 100644 ---- a/hw/smbios/Kconfig -+++ b/hw/smbios/Kconfig -@@ -1,2 +1,4 @@ - config SMBIOS - bool -+config SMBIOS_LEGACY -+ bool -diff --git a/hw/smbios/meson.build b/hw/smbios/meson.build -index 6eeae4b35c..fcac1d7490 100644 ---- a/hw/smbios/meson.build -+++ b/hw/smbios/meson.build -@@ -4,10 +4,15 @@ smbios_ss.add(when: 'CONFIG_IPMI', - if_true: files('smbios_type_38.c'), - if_false: files('smbios_type_38-stub.c')) - -+smbios_ss.add(when: 'CONFIG_SMBIOS_LEGACY', -+ if_true: files('smbios_legacy.c'), -+ if_false: files('smbios_legacy_stub.c')) -+ - system_ss.add_all(when: 'CONFIG_SMBIOS', if_true: smbios_ss) - system_ss.add(when: 'CONFIG_SMBIOS', if_false: files('smbios-stub.c')) - - system_ss.add(when: 'CONFIG_ALL', if_true: files( - 'smbios-stub.c', - 'smbios_type_38-stub.c', -+ 'smbios_legacy_stub.c', - )) -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index eb9927335d..e40204550e 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -31,31 +31,7 @@ - #include "hw/pci/pci_device.h" - #include "smbios_build.h" - --/* legacy structures and constants for <= 2.0 machines */ --struct smbios_header { -- uint16_t length; -- uint8_t type; --} QEMU_PACKED; -- --struct smbios_field { -- struct smbios_header header; -- uint8_t type; -- uint16_t offset; -- uint8_t data[]; --} QEMU_PACKED; -- --struct smbios_table { -- struct smbios_header header; -- uint8_t data[]; --} QEMU_PACKED; -- --#define SMBIOS_FIELD_ENTRY 0 --#define SMBIOS_TABLE_ENTRY 1 -- --static uint8_t *smbios_entries; --static size_t smbios_entries_len; - static bool smbios_uuid_encoded = true; --/* end: legacy structures & constants for <= 2.0 machines */ - - /* Set to true for modern Windows 10 HardwareID-6 compat */ - static bool smbios_type2_required; -@@ -65,7 +41,6 @@ static bool smbios_type2_required; - */ - uint8_t *usr_blobs; - size_t usr_blobs_len; --static GArray *usr_blobs_sizes; - static unsigned usr_table_max; - static unsigned usr_table_cnt; - -@@ -531,7 +506,7 @@ static void smbios_check_type4_count(uint32_t expected_t4_count) - } - } - --static void smbios_validate_table(void) -+void smbios_validate_table(void) - { - if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && - smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) { -@@ -541,134 +516,6 @@ static void smbios_validate_table(void) - } - } - -- --/* legacy setup functions for <= 2.0 machines */ --static void smbios_add_field(int type, int offset, const void *data, size_t len) --{ -- struct smbios_field *field; -- -- if (!smbios_entries) { -- smbios_entries_len = sizeof(uint16_t); -- smbios_entries = g_malloc0(smbios_entries_len); -- } -- smbios_entries = g_realloc(smbios_entries, smbios_entries_len + -- sizeof(*field) + len); -- field = (struct smbios_field *)(smbios_entries + smbios_entries_len); -- field->header.type = SMBIOS_FIELD_ENTRY; -- field->header.length = cpu_to_le16(sizeof(*field) + len); -- -- field->type = type; -- field->offset = cpu_to_le16(offset); -- memcpy(field->data, data, len); -- -- smbios_entries_len += sizeof(*field) + len; -- (*(uint16_t *)smbios_entries) = -- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1); --} -- --static void smbios_maybe_add_str(int type, int offset, const char *data) --{ -- if (data) { -- smbios_add_field(type, offset, data, strlen(data) + 1); -- } --} -- --static void smbios_build_type_0_fields(void) --{ -- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str), -- smbios_type0.vendor); -- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str), -- smbios_type0.version); -- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, -- bios_release_date_str), -- smbios_type0.date); -- if (smbios_type0.have_major_minor) { -- smbios_add_field(0, offsetof(struct smbios_type_0, -- system_bios_major_release), -- &smbios_type0.major, 1); -- smbios_add_field(0, offsetof(struct smbios_type_0, -- system_bios_minor_release), -- &smbios_type0.minor, 1); -- } --} -- --static void smbios_build_type_1_fields(void) --{ -- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str), -- smbios_type1.manufacturer); -- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str), -- smbios_type1.product); -- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str), -- smbios_type1.version); -- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str), -- smbios_type1.serial); -- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str), -- smbios_type1.sku); -- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str), -- smbios_type1.family); -- if (qemu_uuid_set) { -- /* We don't encode the UUID in the "wire format" here because this -- * function is for legacy mode and needs to keep the guest ABI, and -- * because we don't know what's the SMBIOS version advertised by the -- * BIOS. -- */ -- smbios_add_field(1, offsetof(struct smbios_type_1, uuid), -- &qemu_uuid, 16); -- } --} -- --uint8_t *smbios_get_table_legacy(size_t *length) --{ -- int i; -- size_t usr_offset; -- -- /* also complain if fields were given for types > 1 */ -- if (find_next_bit(smbios_have_fields_bitmap, -- SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) { -- error_report("can't process fields for smbios " -- "types > 1 on machine versions < 2.1!"); -- exit(1); -- } -- -- if (test_bit(4, smbios_have_binfile_bitmap)) { -- error_report("can't process table for smbios " -- "type 4 on machine versions < 2.1!"); -- exit(1); -- } -- -- g_free(smbios_entries); -- smbios_entries_len = sizeof(uint16_t); -- smbios_entries = g_malloc0(smbios_entries_len); -- -- for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len; -- i++) -- { -- struct smbios_table *table; -- struct smbios_structure_header *header; -- size_t size = g_array_index(usr_blobs_sizes, size_t, i); -- -- header = (struct smbios_structure_header *)(usr_blobs + usr_offset); -- smbios_entries = g_realloc(smbios_entries, smbios_entries_len + -- size + sizeof(*table)); -- table = (struct smbios_table *)(smbios_entries + smbios_entries_len); -- table->header.type = SMBIOS_TABLE_ENTRY; -- table->header.length = cpu_to_le16(sizeof(*table) + size); -- memcpy(table->data, header, size); -- smbios_entries_len += sizeof(*table) + size; -- (*(uint16_t *)smbios_entries) = -- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1); -- usr_offset += size; -- } -- -- smbios_build_type_0_fields(); -- smbios_build_type_1_fields(); -- smbios_validate_table(); -- *length = smbios_entries_len; -- return smbios_entries; --} --/* end: legacy setup functions for <= 2.0 machines */ -- -- - bool smbios_skip_table(uint8_t type, bool required_table) - { - if (test_bit(type, smbios_have_binfile_bitmap)) { -@@ -1418,14 +1265,6 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts, - return true; - } - --static void smbios_add_usr_blob_size(size_t size) --{ -- if (!usr_blobs_sizes) { -- usr_blobs_sizes = g_array_new(false, false, sizeof(size_t)); -- } -- g_array_append_val(usr_blobs_sizes, size); --} -- - void smbios_entry_add(QemuOpts *opts, Error **errp) - { - const char *val; -diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c -new file mode 100644 -index 0000000000..21f143e738 ---- /dev/null -+++ b/hw/smbios/smbios_legacy.c -@@ -0,0 +1,179 @@ -+/* -+ * SMBIOS legacy support -+ * -+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. -+ * Copyright (C) 2013 Red Hat, Inc. -+ * -+ * Authors: -+ * Alex Williamson -+ * Markus Armbruster -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2. See -+ * the COPYING file in the top-level directory. -+ * -+ * Contributions after 2012-01-13 are licensed under the terms of the -+ * GNU GPL, version 2 or (at your option) any later version. -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/bswap.h" -+#include "hw/firmware/smbios.h" -+#include "sysemu/sysemu.h" -+#include "qemu/error-report.h" -+ -+struct smbios_header { -+ uint16_t length; -+ uint8_t type; -+} QEMU_PACKED; -+ -+struct smbios_field { -+ struct smbios_header header; -+ uint8_t type; -+ uint16_t offset; -+ uint8_t data[]; -+} QEMU_PACKED; -+ -+struct smbios_table { -+ struct smbios_header header; -+ uint8_t data[]; -+} QEMU_PACKED; -+ -+#define SMBIOS_FIELD_ENTRY 0 -+#define SMBIOS_TABLE_ENTRY 1 -+ -+static uint8_t *smbios_entries; -+static size_t smbios_entries_len; -+GArray *usr_blobs_sizes; -+ -+void smbios_add_usr_blob_size(size_t size) -+{ -+ if (!usr_blobs_sizes) { -+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t)); -+ } -+ g_array_append_val(usr_blobs_sizes, size); -+} -+ -+static void smbios_add_field(int type, int offset, const void *data, size_t len) -+{ -+ struct smbios_field *field; -+ -+ if (!smbios_entries) { -+ smbios_entries_len = sizeof(uint16_t); -+ smbios_entries = g_malloc0(smbios_entries_len); -+ } -+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len + -+ sizeof(*field) + len); -+ field = (struct smbios_field *)(smbios_entries + smbios_entries_len); -+ field->header.type = SMBIOS_FIELD_ENTRY; -+ field->header.length = cpu_to_le16(sizeof(*field) + len); -+ -+ field->type = type; -+ field->offset = cpu_to_le16(offset); -+ memcpy(field->data, data, len); -+ -+ smbios_entries_len += sizeof(*field) + len; -+ (*(uint16_t *)smbios_entries) = -+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1); -+} -+ -+static void smbios_maybe_add_str(int type, int offset, const char *data) -+{ -+ if (data) { -+ smbios_add_field(type, offset, data, strlen(data) + 1); -+ } -+} -+ -+static void smbios_build_type_0_fields(void) -+{ -+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str), -+ smbios_type0.vendor); -+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str), -+ smbios_type0.version); -+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0, -+ bios_release_date_str), -+ smbios_type0.date); -+ if (smbios_type0.have_major_minor) { -+ smbios_add_field(0, offsetof(struct smbios_type_0, -+ system_bios_major_release), -+ &smbios_type0.major, 1); -+ smbios_add_field(0, offsetof(struct smbios_type_0, -+ system_bios_minor_release), -+ &smbios_type0.minor, 1); -+ } -+} -+ -+static void smbios_build_type_1_fields(void) -+{ -+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str), -+ smbios_type1.manufacturer); -+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str), -+ smbios_type1.product); -+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str), -+ smbios_type1.version); -+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str), -+ smbios_type1.serial); -+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str), -+ smbios_type1.sku); -+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str), -+ smbios_type1.family); -+ if (qemu_uuid_set) { -+ /* -+ * We don't encode the UUID in the "wire format" here because this -+ * function is for legacy mode and needs to keep the guest ABI, and -+ * because we don't know what's the SMBIOS version advertised by the -+ * BIOS. -+ */ -+ smbios_add_field(1, offsetof(struct smbios_type_1, uuid), -+ &qemu_uuid, 16); -+ } -+} -+ -+uint8_t *smbios_get_table_legacy(size_t *length) -+{ -+ int i; -+ size_t usr_offset; -+ -+ /* complain if fields were given for types > 1 */ -+ if (find_next_bit(smbios_have_fields_bitmap, -+ SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) { -+ error_report("can't process fields for smbios " -+ "types > 1 on machine versions < 2.1!"); -+ exit(1); -+ } -+ -+ if (test_bit(4, smbios_have_binfile_bitmap)) { -+ error_report("can't process table for smbios " -+ "type 4 on machine versions < 2.1!"); -+ exit(1); -+ } -+ -+ g_free(smbios_entries); -+ smbios_entries_len = sizeof(uint16_t); -+ smbios_entries = g_malloc0(smbios_entries_len); -+ -+ for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len; -+ i++) -+ { -+ struct smbios_table *table; -+ struct smbios_structure_header *header; -+ size_t size = g_array_index(usr_blobs_sizes, size_t, i); -+ -+ header = (struct smbios_structure_header *)(usr_blobs + usr_offset); -+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len + -+ size + sizeof(*table)); -+ table = (struct smbios_table *)(smbios_entries + smbios_entries_len); -+ table->header.type = SMBIOS_TABLE_ENTRY; -+ table->header.length = cpu_to_le16(sizeof(*table) + size); -+ memcpy(table->data, header, size); -+ smbios_entries_len += sizeof(*table) + size; -+ (*(uint16_t *)smbios_entries) = -+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1); -+ usr_offset += size; -+ } -+ -+ smbios_build_type_0_fields(); -+ smbios_build_type_1_fields(); -+ smbios_validate_table(); -+ *length = smbios_entries_len; -+ return smbios_entries; -+} -diff --git a/hw/smbios/smbios_legacy_stub.c b/hw/smbios/smbios_legacy_stub.c -new file mode 100644 -index 0000000000..f29b15316c ---- /dev/null -+++ b/hw/smbios/smbios_legacy_stub.c -@@ -0,0 +1,15 @@ -+/* -+ * IPMI SMBIOS firmware handling -+ * -+ * Copyright (c) 2024 Igor Mammedov, Red Hat, Inc. -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ */ -+ -+#include "qemu/osdep.h" -+#include "hw/firmware/smbios.h" -+ -+void smbios_add_usr_blob_size(size_t size) -+{ -+} -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index 333de0d5fc..92e9aba415 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -17,6 +17,9 @@ - * - */ - -+extern uint8_t *usr_blobs; -+extern GArray *usr_blobs_sizes; -+ - typedef struct { - const char *vendor, *version, *date; - bool have_major_minor, uefi; -@@ -323,6 +326,8 @@ struct smbios_type_127 { - struct smbios_structure_header header; - } QEMU_PACKED; - -+void smbios_validate_table(void); -+void smbios_add_usr_blob_size(size_t size); - void smbios_entry_add(QemuOpts *opts, Error **errp); - void smbios_set_cpuid(uint32_t version, uint32_t features); - void smbios_set_defaults(const char *manufacturer, const char *product, --- -2.39.3 - diff --git a/kvm-smbios-cleanup-smbios_get_tables-from-legacy-handlin.patch b/kvm-smbios-cleanup-smbios_get_tables-from-legacy-handlin.patch deleted file mode 100644 index 48a9e16..0000000 --- a/kvm-smbios-cleanup-smbios_get_tables-from-legacy-handlin.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 07f6ef2d032cda3e746ac2477c0a9bc1ac636f45 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Fri, 29 Dec 2023 14:08:13 +0100 -Subject: [PATCH 06/20] smbios: cleanup smbios_get_tables() from legacy - handling - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [4/18] a5e09ce1df72293fecad863edd146a8c4b1a734f - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -smbios_get_tables() bails out right away if leagacy mode is enabled -and won't generate any SMBIOS tables. At the same time x86 specific -fw_cfg_build_smbios() will genarate legacy tables and then proceed -to preparing temporary mem_array for useless call to -smbios_get_tables() and then discard it. - -Drop legacy related check in smbios_get_tables() and return from -fw_cfg_build_smbios() early if legacy tables where built without -proceeding to non legacy part of the function. - -Signed-off-by: Igor Mammedov -Reviewed-by: Ani Sinha -Tested-by: Fiona Ebner ---- - hw/i386/fw_cfg.c | 1 + - hw/smbios/smbios.c | 6 ------ - 2 files changed, 1 insertion(+), 6 deletions(-) - -diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index 6a5466faf0..ed72b1442d 100644 ---- a/hw/i386/fw_cfg.c -+++ b/hw/i386/fw_cfg.c -@@ -76,6 +76,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) - if (smbios_tables) { - fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, - smbios_tables, smbios_tables_len); -+ return; - } - - /* build the array of physical mem area from e820 table */ -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 074705fa4c..b13e40bae2 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -1244,12 +1244,6 @@ void smbios_get_tables(MachineState *ms, - { - unsigned i, dimm_cnt, offset; - -- if (smbios_legacy) { -- *tables = *anchor = NULL; -- *tables_len = *anchor_len = 0; -- return; -- } -- - if (!smbios_immutable) { - smbios_build_type_0_table(); - smbios_build_type_1_table(); --- -2.39.3 - diff --git a/kvm-smbios-clear-smbios_type4_count-before-building-tabl.patch b/kvm-smbios-clear-smbios_type4_count-before-building-tabl.patch deleted file mode 100644 index 38a7f95..0000000 --- a/kvm-smbios-clear-smbios_type4_count-before-building-tabl.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c0282a842a912aacac28a6ae229de5854c3fb5df Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Mon, 26 Feb 2024 13:20:22 +0100 -Subject: [PATCH 16/20] smbios: clear smbios_type4_count before building tables - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [14/18] f809595d2934ae975c0b7d17a4a79645e062ba42 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -it will help to keep type 4 tables accounting correct in case -SMBIOS tables are built multiple times. - -Signed-off-by: Igor Mammedov -Tested-by: Fiona Ebner ---- - hw/smbios/smbios.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 7e32430b85..4521ea386c 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -1111,6 +1111,7 @@ void smbios_get_tables(MachineState *ms, - ep_type == SMBIOS_ENTRY_POINT_TYPE_64); - - g_free(smbios_tables); -+ smbios_type4_count = 0; - smbios_tables = g_memdup2(usr_blobs, usr_blobs_len); - smbios_tables_len = usr_blobs_len; - smbios_table_max = usr_table_max; --- -2.39.3 - diff --git a/kvm-smbios-don-t-check-type4-structures-in-legacy-mode.patch b/kvm-smbios-don-t-check-type4-structures-in-legacy-mode.patch deleted file mode 100644 index a2c9532..0000000 --- a/kvm-smbios-don-t-check-type4-structures-in-legacy-mode.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 2b76d95ec07aba6d96070ee90c5015c1676be091 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Tue, 13 Feb 2024 16:25:54 +0100 -Subject: [PATCH 10/20] smbios: don't check type4 structures in legacy mode - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [8/18] c1f8409ea0d916f333c9373535bf21b521c62855 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - - legacy mode doesn't support structures of type 2 and more, - and CLI has a check for '-smbios type' option, however it's - still possible to sneak in type4 as a blob with '-smbios file' - option. However doing the later makes SMBIOS tables broken - since SeaBIOS doesn't expect that. - - Rather than trying to add support for type4 to legacy code - (both QEMU and SeaBIOS), simplify smbios_get_table_legacy() - by dropping not relevant check in legacy code and error out - on type4 blob. - - Signed-off-by: Igor Mammedov - Reviewed-by: Ani Sinha - Tested-by: Fiona Ebner - -Conflicts: include/hw/firmware/smbios.h -Signed-off-by: Igor Mammedov - - Please enter the commit message for your changes. Lines starting ---- - hw/i386/fw_cfg.c | 3 +-- - hw/smbios/smbios.c | 18 ++++++++++++++---- - include/hw/firmware/smbios.h | 2 +- - 3 files changed, 16 insertions(+), 7 deletions(-) - -diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index bb7149c4c3..a25793a68f 100644 ---- a/hw/i386/fw_cfg.c -+++ b/hw/i386/fw_cfg.c -@@ -73,8 +73,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) - smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); - - if (pcmc->smbios_legacy_mode) { -- smbios_tables = smbios_get_table_legacy(ms->smp.cpus, -- &smbios_tables_len); -+ smbios_tables = smbios_get_table_legacy(&smbios_tables_len); - fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, - smbios_tables, smbios_tables_len); - return; -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index d8d68716d4..441517cf24 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -530,14 +530,17 @@ opts_init(smbios_register_config); - */ - #define SMBIOS_21_MAX_TABLES_LEN 0xffff - --static void smbios_validate_table(uint32_t expected_t4_count) -+static void smbios_check_type4_count(uint32_t expected_t4_count) - { - if (smbios_type4_count && smbios_type4_count != expected_t4_count) { - error_report("Expected %d SMBIOS Type 4 tables, got %d instead", - expected_t4_count, smbios_type4_count); - exit(1); - } -+} - -+static void smbios_validate_table(void) -+{ - if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && - smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) { - error_report("SMBIOS 2.1 table length %zu exceeds %d", -@@ -622,7 +625,7 @@ static void smbios_build_type_1_fields(void) - } - } - --uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) -+uint8_t *smbios_get_table_legacy(size_t *length) - { - int i; - size_t usr_offset; -@@ -635,6 +638,12 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) - exit(1); - } - -+ if (test_bit(4, have_binfile_bitmap)) { -+ error_report("can't process table for smbios " -+ "type 4 on machine versions < 2.1!"); -+ exit(1); -+ } -+ - g_free(smbios_entries); - smbios_entries_len = sizeof(uint16_t); - smbios_entries = g_malloc0(smbios_entries_len); -@@ -661,7 +670,7 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) - - smbios_build_type_0_fields(); - smbios_build_type_1_fields(); -- smbios_validate_table(expected_t4_count); -+ smbios_validate_table(); - *length = smbios_entries_len; - return smbios_entries; - } -@@ -1319,7 +1328,8 @@ void smbios_get_tables(MachineState *ms, - smbios_build_type_41_table(errp); - smbios_build_type_127_table(); - -- smbios_validate_table(ms->smp.sockets); -+ smbios_check_type4_count(ms->smp.sockets); -+ smbios_validate_table(); - smbios_entry_point_setup(); - - /* return tables blob and entry point (anchor), and their sizes */ -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index b9fc9a0f42..d55018e5e3 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -315,7 +315,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product, - SmbiosEntryPointType ep_type, - const char *stream_product, - const char *stream_version); --uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length); -+uint8_t *smbios_get_table_legacy(size_t *length); - void smbios_get_tables(MachineState *ms, - const struct smbios_phys_mem_area *mem_array, - const unsigned int mem_array_size, --- -2.39.3 - diff --git a/kvm-smbios-error-out-when-building-type-4-table-is-not-p.patch b/kvm-smbios-error-out-when-building-type-4-table-is-not-p.patch deleted file mode 100644 index 2afbe66..0000000 --- a/kvm-smbios-error-out-when-building-type-4-table-is-not-p.patch +++ /dev/null @@ -1,72 +0,0 @@ -From bbb2d260e6f33380b9df28c74421055bd8dccda5 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Mon, 26 Feb 2024 12:59:33 +0100 -Subject: [PATCH 19/20] smbios: error out when building type 4 table is not - possible - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [17/18] 86b1c67bfbe9c0c14a190cd1204b6ccd1de1630f - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -If SMBIOS v2 version is requested but number of cores/threads -are more than it's possible to describe with v2, error out -instead of silently ignoring the fact and filling core/thread -count with bogus values. - -This will help caller to decide if it should fallback to -SMBIOSv3 when smbios-entry-point-type='auto' - -Signed-off-by: Igor Mammedov -Reviewed-by: Ani Sinha -Tested-by: Fiona Ebner ---- - hw/smbios/smbios.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 3d9dcb0d31..637aa952f5 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -655,7 +655,8 @@ static void smbios_build_type_3_table(void) - } - - static void smbios_build_type_4_table(MachineState *ms, unsigned instance, -- SmbiosEntryPointType ep_type) -+ SmbiosEntryPointType ep_type, -+ Error **errp) - { - char sock_str[128]; - size_t tbl_len = SMBIOS_TYPE_4_LEN_V28; -@@ -709,6 +710,12 @@ static void smbios_build_type_4_table(MachineState *ms, unsigned instance, - if (tbl_len == SMBIOS_TYPE_4_LEN_V30) { - t->core_count2 = t->core_enabled2 = cpu_to_le16(cores_per_socket); - t->thread_count2 = cpu_to_le16(threads_per_socket); -+ } else if (t->core_count == 0xFF || t->thread_count == 0xFF) { -+ error_setg(errp, "SMBIOS 2.0 doesn't support number of processor " -+ "cores/threads more than 255, use " -+ "-machine smbios-entry-point-type=64 option to enable " -+ "SMBIOS 3.0 support"); -+ return; - } - - SMBIOS_BUILD_TABLE_POST; -@@ -1126,7 +1133,10 @@ static bool smbios_get_tables_ep(MachineState *ms, - assert(ms->smp.sockets >= 1); - - for (i = 0; i < ms->smp.sockets; i++) { -- smbios_build_type_4_table(ms, i, ep_type); -+ smbios_build_type_4_table(ms, i, ep_type, errp); -+ if (*errp) { -+ goto err_exit; -+ } - } - - smbios_build_type_8_table(); --- -2.39.3 - diff --git a/kvm-smbios-extend-smbios-entry-point-type-with-auto-valu.patch b/kvm-smbios-extend-smbios-entry-point-type-with-auto-valu.patch deleted file mode 100644 index db012bd..0000000 --- a/kvm-smbios-extend-smbios-entry-point-type-with-auto-valu.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c083959c963fde33f4769fd4c6e122dd16ce6d3c Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Wed, 21 Feb 2024 16:04:36 +0100 -Subject: [PATCH 17/20] smbios: extend smbios-entry-point-type with 'auto' - value - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [15/18] 202563dcf77e062a238aa2a10ec14c25d3f5a7d0 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -later patches will use it to pick SMBIOS version at runtime -depending on configuration. - -Signed-off-by: Igor Mammedov -Acked-by: Markus Armbruster -Reviewed-by: Ani Sinha -Tested-by: Fiona Ebner ---- - qapi/machine.json | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/qapi/machine.json b/qapi/machine.json -index b6d634b30d..99f6368fa6 100644 ---- a/qapi/machine.json -+++ b/qapi/machine.json -@@ -1788,10 +1788,13 @@ - # - # @64: SMBIOS version 3.0 (64-bit) Entry Point - # -+# @auto: Either 2.x or 3.x SMBIOS version, 2.x if configuration can be -+# described by it and 3.x otherwise (since: 9.0) -+# - # Since: 7.0 - ## - { 'enum': 'SmbiosEntryPointType', -- 'data': [ '32', '64' ] } -+ 'data': [ '32', '64', 'auto' ] } - - ## - # @MemorySizeConfiguration: --- -2.39.3 - diff --git a/kvm-smbios-get-rid-of-global-smbios_ep_type.patch b/kvm-smbios-get-rid-of-global-smbios_ep_type.patch deleted file mode 100644 index 1896f2b..0000000 --- a/kvm-smbios-get-rid-of-global-smbios_ep_type.patch +++ /dev/null @@ -1,281 +0,0 @@ -From be0abbf3f7845847b46486704c46c5de5a2b2323 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Mon, 26 Feb 2024 13:49:14 +0100 -Subject: [PATCH 15/20] smbios: get rid of global smbios_ep_type - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [13/18] 2e838ed0d03989e2e4ee08041b5ba64d5d7f5820 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -Conflicts: hw/arm/virt.c, hw/i386/fw_cfg.c, hw/riscv/virt.c, hw/smbios/smbios.c, - include/hw/firmware/smbios.h - due to downstream specific smbios_set_defaults() - -Signed-off-by: Igor Mammedov -Acked-by: Daniel Henrique Barboza -Reviewed-by: Ani Sinha -Tested-by: Fiona Ebner -Signed-off-by: Igor Mammedov ---- - hw/arm/virt.c | 4 ++-- - hw/i386/fw_cfg.c | 6 +++--- - hw/i386/fw_cfg.h | 3 ++- - hw/i386/pc.c | 2 +- - hw/loongarch/virt.c | 7 ++++--- - hw/smbios/smbios.c | 26 ++++++++++++++------------ - hw/smbios/smbios_legacy.c | 2 +- - include/hw/firmware/smbios.h | 4 ++-- - 8 files changed, 29 insertions(+), 25 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index e5cfc19c08..e4a66affcb 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -1695,14 +1695,14 @@ static void virt_build_smbios(VirtMachineState *vms) - - smbios_set_defaults("QEMU", product, - vmc->smbios_old_sys_ver ? "1.0" : mc->name, -- true, SMBIOS_ENTRY_POINT_TYPE_64, -+ true, - NULL, NULL); - - /* build the array of physical mem area from base_memmap */ - mem_array.address = vms->memmap[VIRT_MEM].base; - mem_array.length = ms->ram_size; - -- smbios_get_tables(ms, &mem_array, 1, -+ smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64, &mem_array, 1, - &smbios_tables, &smbios_tables_len, - &smbios_anchor, &smbios_anchor_len, - &error_fatal); -diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index bdc3cc4556..58429bb78d 100644 ---- a/hw/i386/fw_cfg.c -+++ b/hw/i386/fw_cfg.c -@@ -48,7 +48,8 @@ const char *fw_cfg_arch_key_name(uint16_t key) - return NULL; - } - --void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) -+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg, -+ SmbiosEntryPointType ep_type) - { - #ifdef CONFIG_SMBIOS - uint8_t *smbios_tables, *smbios_anchor; -@@ -64,7 +65,6 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) - /* These values are guest ABI, do not change */ - smbios_set_defaults("QEMU", mc->desc, mc->name, - pcmc->smbios_uuid_encoded, -- pcms->smbios_entry_point_type, - pcmc->smbios_stream_product, - pcmc->smbios_stream_version); - } -@@ -91,7 +91,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) - array_count++; - } - } -- smbios_get_tables(ms, mem_array, array_count, -+ smbios_get_tables(ms, ep_type, mem_array, array_count, - &smbios_tables, &smbios_tables_len, - &smbios_anchor, &smbios_anchor_len, - &error_fatal); -diff --git a/hw/i386/fw_cfg.h b/hw/i386/fw_cfg.h -index 1e1de6b4a3..92e310f5fd 100644 ---- a/hw/i386/fw_cfg.h -+++ b/hw/i386/fw_cfg.h -@@ -23,7 +23,8 @@ - FWCfgState *fw_cfg_arch_create(MachineState *ms, - uint16_t boot_cpus, - uint16_t apic_id_limit); --void fw_cfg_build_smbios(PCMachineState *ms, FWCfgState *fw_cfg); -+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg, -+ SmbiosEntryPointType ep_type); - void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg); - void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg); - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 16de2a59e8..ae6777fc1a 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -847,7 +847,7 @@ void pc_machine_done(Notifier *notifier, void *data) - - acpi_setup(); - if (x86ms->fw_cfg) { -- fw_cfg_build_smbios(pcms, x86ms->fw_cfg); -+ fw_cfg_build_smbios(pcms, x86ms->fw_cfg, pcms->smbios_entry_point_type); - fw_cfg_build_feature_control(MACHINE(pcms), x86ms->fw_cfg); - /* update FW_CFG_NB_CPUS to account for -device added CPUs */ - fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus); -diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c -index 7358a023d3..77956b5ada 100644 ---- a/hw/loongarch/virt.c -+++ b/hw/loongarch/virt.c -@@ -320,10 +320,11 @@ static void virt_build_smbios(LoongArchMachineState *lams) - return; - } - -- smbios_set_defaults("QEMU", product, mc->name, -- true, SMBIOS_ENTRY_POINT_TYPE_64); -+ smbios_set_defaults("QEMU", product, mc->name, true); - -- smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len, -+ smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64, -+ NULL, 0, -+ &smbios_tables, &smbios_tables_len, - &smbios_anchor, &smbios_anchor_len, &error_fatal); - - if (smbios_anchor) { -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index b5745c6c2d..7e32430b85 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -47,7 +47,6 @@ uint8_t *smbios_tables; - size_t smbios_tables_len; - unsigned smbios_table_max; - unsigned smbios_table_cnt; --static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32; - - static SmbiosEntryPoint ep; - -@@ -506,9 +505,9 @@ static bool smbios_check_type4_count(uint32_t expected_t4_count, Error **errp) - return true; - } - --bool smbios_validate_table(Error **errp) -+bool smbios_validate_table(SmbiosEntryPointType ep_type, Error **errp) - { -- if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && -+ if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && - smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) { - error_setg(errp, "SMBIOS 2.1 table length %zu exceeds %d", - smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN); -@@ -655,14 +654,15 @@ static void smbios_build_type_3_table(void) - SMBIOS_BUILD_TABLE_POST; - } - --static void smbios_build_type_4_table(MachineState *ms, unsigned instance) -+static void smbios_build_type_4_table(MachineState *ms, unsigned instance, -+ SmbiosEntryPointType ep_type) - { - char sock_str[128]; - size_t tbl_len = SMBIOS_TYPE_4_LEN_V28; - unsigned threads_per_socket; - unsigned cores_per_socket; - -- if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_64) { -+ if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) { - tbl_len = SMBIOS_TYPE_4_LEN_V30; - } - -@@ -991,13 +991,11 @@ void smbios_set_cpuid(uint32_t version, uint32_t features) - void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, - bool uuid_encoded, -- SmbiosEntryPointType ep_type, - const char *stream_product, - const char *stream_version) - { - smbios_have_defaults = true; - smbios_uuid_encoded = uuid_encoded; -- smbios_ep_type = ep_type; - - /* - * If @stream_product & @stream_version are non-NULL, then -@@ -1048,9 +1046,9 @@ void smbios_set_defaults(const char *manufacturer, const char *product, - SMBIOS_SET_DEFAULT(type17.manufacturer, manufacturer); - } - --static void smbios_entry_point_setup(void) -+static void smbios_entry_point_setup(SmbiosEntryPointType ep_type) - { -- switch (smbios_ep_type) { -+ switch (ep_type) { - case SMBIOS_ENTRY_POINT_TYPE_32: - memcpy(ep.ep21.anchor_string, "_SM_", 4); - memcpy(ep.ep21.intermediate_anchor_string, "_DMI_", 5); -@@ -1100,6 +1098,7 @@ static void smbios_entry_point_setup(void) - } - - void smbios_get_tables(MachineState *ms, -+ SmbiosEntryPointType ep_type, - const struct smbios_phys_mem_area *mem_array, - const unsigned int mem_array_size, - uint8_t **tables, size_t *tables_len, -@@ -1108,6 +1107,9 @@ void smbios_get_tables(MachineState *ms, - { - unsigned i, dimm_cnt, offset; - -+ assert(ep_type == SMBIOS_ENTRY_POINT_TYPE_32 || -+ ep_type == SMBIOS_ENTRY_POINT_TYPE_64); -+ - g_free(smbios_tables); - smbios_tables = g_memdup2(usr_blobs, usr_blobs_len); - smbios_tables_len = usr_blobs_len; -@@ -1122,7 +1124,7 @@ void smbios_get_tables(MachineState *ms, - assert(ms->smp.sockets >= 1); - - for (i = 0; i < ms->smp.sockets; i++) { -- smbios_build_type_4_table(ms, i); -+ smbios_build_type_4_table(ms, i, ep_type); - } - - smbios_build_type_8_table(); -@@ -1171,10 +1173,10 @@ void smbios_get_tables(MachineState *ms, - if (!smbios_check_type4_count(ms->smp.sockets, errp)) { - goto err_exit; - } -- if (!smbios_validate_table(errp)) { -+ if (!smbios_validate_table(ep_type, errp)) { - goto err_exit; - } -- smbios_entry_point_setup(); -+ smbios_entry_point_setup(ep_type); - - /* return tables blob and entry point (anchor), and their sizes */ - *tables = smbios_tables; -diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c -index a6544bf55a..06907cd16c 100644 ---- a/hw/smbios/smbios_legacy.c -+++ b/hw/smbios/smbios_legacy.c -@@ -173,7 +173,7 @@ uint8_t *smbios_get_table_legacy(size_t *length, Error **errp) - - smbios_build_type_0_fields(); - smbios_build_type_1_fields(); -- if (!smbios_validate_table(errp)) { -+ if (!smbios_validate_table(SMBIOS_ENTRY_POINT_TYPE_32, errp)) { - goto err_exit; - } - -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index 44af3a0d82..781298f594 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -326,18 +326,18 @@ struct smbios_type_127 { - struct smbios_structure_header header; - } QEMU_PACKED; - --bool smbios_validate_table(Error **errp); -+bool smbios_validate_table(SmbiosEntryPointType ep_type, Error **errp); - void smbios_add_usr_blob_size(size_t size); - void smbios_entry_add(QemuOpts *opts, Error **errp); - void smbios_set_cpuid(uint32_t version, uint32_t features); - void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, - bool uuid_encoded, -- SmbiosEntryPointType ep_type, - const char *stream_product, - const char *stream_version); - uint8_t *smbios_get_table_legacy(size_t *length, Error **errp); - void smbios_get_tables(MachineState *ms, -+ SmbiosEntryPointType ep_type, - const struct smbios_phys_mem_area *mem_array, - const unsigned int mem_array_size, - uint8_t **tables, size_t *tables_len, --- -2.39.3 - diff --git a/kvm-smbios-get-rid-of-smbios_legacy-global.patch b/kvm-smbios-get-rid-of-smbios_legacy-global.patch deleted file mode 100644 index ecb730e..0000000 --- a/kvm-smbios-get-rid-of-smbios_legacy-global.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 0802fa7199c8085d018fc38dd4beaa5062d383d1 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Fri, 29 Dec 2023 15:37:29 +0100 -Subject: [PATCH 08/20] smbios: get rid of smbios_legacy global - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [6/18] 684dd1dca8d611c6de97b26ef8c1cda6ca509d54 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - - clean up smbios_set_defaults() which is reused by legacy - and non legacy machines from being aware of 'legacy' notion - and need to turn it off. And push legacy handling up to - PC machine code where it's relevant. - - Signed-off-by: Igor Mammedov - Reviewed-by: Ani Sinha - Acked-by: Daniel Henrique Barboza - Tested-by: Fiona Ebner - -Conflicts: hw/arm/virt.c, hw/i386/fw_cfg.c, hw/loongarch/virt.c, - hw/smbios/smbios.c, include/hw/firmware/smbios.h - due to downstream specifc signature of smbios_set_defaults() -PS: - while fixing conflicts move RHEL specific - smbios_stream_product/smbios_stream_version - at the end of arguments list - -Signed-off-by: Igor Mammedov ---- - hw/arm/virt.c | 5 +++-- - hw/i386/fw_cfg.c | 11 +++++----- - hw/loongarch/virt.c | 2 +- - hw/smbios/smbios.c | 39 ++++++++++++++++-------------------- - include/hw/firmware/smbios.h | 6 +++--- - 5 files changed, 30 insertions(+), 33 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 943c563391..e5cfc19c08 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -1694,8 +1694,9 @@ static void virt_build_smbios(VirtMachineState *vms) - } - - smbios_set_defaults("QEMU", product, -- vmc->smbios_old_sys_ver ? "1.0" : mc->name, false, -- true, NULL, NULL, SMBIOS_ENTRY_POINT_TYPE_64); -+ vmc->smbios_old_sys_ver ? "1.0" : mc->name, -+ true, SMBIOS_ENTRY_POINT_TYPE_64, -+ NULL, NULL); - - /* build the array of physical mem area from base_memmap */ - mem_array.address = vms->memmap[VIRT_MEM].base; -diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index 79ff7f7225..bb7149c4c3 100644 ---- a/hw/i386/fw_cfg.c -+++ b/hw/i386/fw_cfg.c -@@ -63,17 +63,18 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) - if (pcmc->smbios_defaults) { - /* These values are guest ABI, do not change */ - smbios_set_defaults("QEMU", mc->desc, mc->name, -- pcmc->smbios_legacy_mode, pcmc->smbios_uuid_encoded, -+ pcmc->smbios_uuid_encoded, -+ pcms->smbios_entry_point_type, - pcmc->smbios_stream_product, -- pcmc->smbios_stream_version, -- pcms->smbios_entry_point_type); -+ pcmc->smbios_stream_version); - } - - /* tell smbios about cpuid version and features */ - smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); - -- smbios_tables = smbios_get_table_legacy(ms->smp.cpus, &smbios_tables_len); -- if (smbios_tables) { -+ if (pcmc->smbios_legacy_mode) { -+ smbios_tables = smbios_get_table_legacy(ms->smp.cpus, -+ &smbios_tables_len); - fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, - smbios_tables, smbios_tables_len); - return; -diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c -index 4b7dc67a2d..7358a023d3 100644 ---- a/hw/loongarch/virt.c -+++ b/hw/loongarch/virt.c -@@ -320,7 +320,7 @@ static void virt_build_smbios(LoongArchMachineState *lams) - return; - } - -- smbios_set_defaults("QEMU", product, mc->name, false, -+ smbios_set_defaults("QEMU", product, mc->name, - true, SMBIOS_ENTRY_POINT_TYPE_64); - - smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len, -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 8129d396d1..0c8c439859 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -54,7 +54,6 @@ struct smbios_table { - - static uint8_t *smbios_entries; - static size_t smbios_entries_len; --static bool smbios_legacy = true; - static bool smbios_uuid_encoded = true; - /* end: legacy structures & constants for <= 2.0 machines */ - -@@ -618,9 +617,16 @@ static void smbios_build_type_1_fields(void) - - uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) - { -- if (!smbios_legacy) { -- *length = 0; -- return NULL; -+ /* drop unwanted version of command-line file blob(s) */ -+ g_free(smbios_tables); -+ smbios_tables = NULL; -+ -+ /* also complain if fields were given for types > 1 */ -+ if (find_next_bit(have_fields_bitmap, -+ SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) { -+ error_report("can't process fields for smbios " -+ "types > 1 on machine versions < 2.1!"); -+ exit(1); - } - - if (!smbios_immutable) { -@@ -1107,31 +1113,16 @@ void smbios_set_cpuid(uint32_t version, uint32_t features) - } - - void smbios_set_defaults(const char *manufacturer, const char *product, -- const char *version, bool legacy_mode, -+ const char *version, - bool uuid_encoded, -+ SmbiosEntryPointType ep_type, - const char *stream_product, -- const char *stream_version, -- SmbiosEntryPointType ep_type) -+ const char *stream_version) - { - smbios_have_defaults = true; -- smbios_legacy = legacy_mode; - smbios_uuid_encoded = uuid_encoded; - smbios_ep_type = ep_type; - -- /* drop unwanted version of command-line file blob(s) */ -- if (smbios_legacy) { -- g_free(smbios_tables); -- /* in legacy mode, also complain if fields were given for types > 1 */ -- if (find_next_bit(have_fields_bitmap, -- SMBIOS_MAX_TYPE+1, 2) < SMBIOS_MAX_TYPE+1) { -- error_report("can't process fields for smbios " -- "types > 1 on machine versions < 2.1!"); -- exit(1); -- } -- } else { -- g_free(smbios_entries); -- } -- - /* - * If @stream_product & @stream_version are non-NULL, then - * we're following rules for new Windows driver support. -@@ -1241,6 +1232,10 @@ void smbios_get_tables(MachineState *ms, - { - unsigned i, dimm_cnt, offset; - -+ /* drop unwanted (legacy) version of command-line file blob(s) */ -+ g_free(smbios_entries); -+ smbios_entries = NULL; -+ - if (!smbios_immutable) { - smbios_build_type_0_table(); - smbios_build_type_1_table(); -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index 95ec64ce2c..b9fc9a0f42 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -310,11 +310,11 @@ struct smbios_type_127 { - void smbios_entry_add(QemuOpts *opts, Error **errp); - void smbios_set_cpuid(uint32_t version, uint32_t features); - void smbios_set_defaults(const char *manufacturer, const char *product, -- const char *version, bool legacy_mode, -+ const char *version, - bool uuid_encoded, -+ SmbiosEntryPointType ep_type, - const char *stream_product, -- const char *stream_version, -- SmbiosEntryPointType ep_type); -+ const char *stream_version); - uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length); - void smbios_get_tables(MachineState *ms, - const struct smbios_phys_mem_area *mem_array, --- -2.39.3 - diff --git a/kvm-smbios-get-rid-of-smbios_smp_sockets-global.patch b/kvm-smbios-get-rid-of-smbios_smp_sockets-global.patch deleted file mode 100644 index fde17ac..0000000 --- a/kvm-smbios-get-rid-of-smbios_smp_sockets-global.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 1536f1ec00ddc1729854b381cc0d54814bb6c19f Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Fri, 29 Dec 2023 15:04:55 +0100 -Subject: [PATCH 07/20] smbios: get rid of smbios_smp_sockets global - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [5/18] f59bfeb547b7febcf1de2b6179af006e7fa0bccd - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - - it makes smbios_validate_table() independent from - smbios_smp_sockets global, which in turn lets - smbios_get_tables() avoid using not related legacy code. - - Signed-off-by: Igor Mammedov - Reviewed-by: Ani Sinha - Tested-by: Fiona Ebner - -Conflicts: - include/hw/firmware/smbios.h due to down-stream - (d9ff466c980d Machine type related general changes) - adding custom stream_product/stream_version - -Signed-off-by: Igor Mammedov ---- - hw/i386/fw_cfg.c | 2 +- - hw/smbios/smbios.c | 22 +++++++++------------- - include/hw/firmware/smbios.h | 2 +- - 3 files changed, 11 insertions(+), 15 deletions(-) - -diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index ed72b1442d..79ff7f7225 100644 ---- a/hw/i386/fw_cfg.c -+++ b/hw/i386/fw_cfg.c -@@ -72,7 +72,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) - /* tell smbios about cpuid version and features */ - smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); - -- smbios_tables = smbios_get_table_legacy(ms, &smbios_tables_len); -+ smbios_tables = smbios_get_table_legacy(ms->smp.cpus, &smbios_tables_len); - if (smbios_tables) { - fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, - smbios_tables, smbios_tables_len); -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index b13e40bae2..8129d396d1 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -73,7 +73,7 @@ static SmbiosEntryPoint ep; - static int smbios_type4_count = 0; - static bool smbios_immutable; - static bool smbios_have_defaults; --static uint32_t smbios_cpuid_version, smbios_cpuid_features, smbios_smp_sockets; -+static uint32_t smbios_cpuid_version, smbios_cpuid_features; - - static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1); - static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1); -@@ -524,14 +524,11 @@ opts_init(smbios_register_config); - */ - #define SMBIOS_21_MAX_TABLES_LEN 0xffff - --static void smbios_validate_table(MachineState *ms) -+static void smbios_validate_table(uint32_t expected_t4_count) - { -- uint32_t expect_t4_count = smbios_legacy ? -- ms->smp.cpus : smbios_smp_sockets; -- -- if (smbios_type4_count && smbios_type4_count != expect_t4_count) { -+ if (smbios_type4_count && smbios_type4_count != expected_t4_count) { - error_report("Expected %d SMBIOS Type 4 tables, got %d instead", -- expect_t4_count, smbios_type4_count); -+ expected_t4_count, smbios_type4_count); - exit(1); - } - -@@ -619,7 +616,7 @@ static void smbios_build_type_1_fields(void) - } - } - --uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length) -+uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) - { - if (!smbios_legacy) { - *length = 0; -@@ -629,7 +626,7 @@ uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length) - if (!smbios_immutable) { - smbios_build_type_0_fields(); - smbios_build_type_1_fields(); -- smbios_validate_table(ms); -+ smbios_validate_table(expected_t4_count); - smbios_immutable = true; - } - *length = smbios_entries_len; -@@ -1250,10 +1247,9 @@ void smbios_get_tables(MachineState *ms, - smbios_build_type_2_table(); - smbios_build_type_3_table(); - -- smbios_smp_sockets = ms->smp.sockets; -- assert(smbios_smp_sockets >= 1); -+ assert(ms->smp.sockets >= 1); - -- for (i = 0; i < smbios_smp_sockets; i++) { -+ for (i = 0; i < ms->smp.sockets; i++) { - smbios_build_type_4_table(ms, i); - } - -@@ -1299,7 +1295,7 @@ void smbios_get_tables(MachineState *ms, - smbios_build_type_41_table(errp); - smbios_build_type_127_table(); - -- smbios_validate_table(ms); -+ smbios_validate_table(ms->smp.sockets); - smbios_entry_point_setup(); - smbios_immutable = true; - } -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index f8dd07fe4c..95ec64ce2c 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -315,7 +315,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product, - const char *stream_product, - const char *stream_version, - SmbiosEntryPointType ep_type); --uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length); -+uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length); - void smbios_get_tables(MachineState *ms, - const struct smbios_phys_mem_area *mem_array, - const unsigned int mem_array_size, --- -2.39.3 - diff --git a/kvm-smbios-handle-errors-consistently.patch b/kvm-smbios-handle-errors-consistently.patch deleted file mode 100644 index ac75c76..0000000 --- a/kvm-smbios-handle-errors-consistently.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 7271c4424c6d90f0bb34f8090eb4e192eb2b2537 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Tue, 20 Feb 2024 10:30:28 +0100 -Subject: [PATCH 14/20] smbios: handle errors consistently - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [12/18] d8a5a70602ae0665ce35e5bf87b2d8420f9189bc - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - - Current code uses mix of error_report()+exit(1) - and error_setg() to handle errors. - Use newer error_setg() everywhere, beside consistency - it will allow to detect error condition without killing - QEMU and attempt switch-over to SMBIOS3.x tables/entrypoint - in follow up patch. - - while at it, clear smbios_tables pointer after freeing. - that will avoid double free if smbios_get_tables() is called - multiple times. - - Signed-off-by: Igor Mammedov - Reviewed-by: Ani Sinha - -Conflicts: include/hw/firmware/smbios.h - due to downstream specific smbios_set_defaults() - -Signed-off-by: Igor Mammedov ---- - hw/i386/fw_cfg.c | 3 ++- - hw/smbios/smbios.c | 34 ++++++++++++++++++++++------------ - hw/smbios/smbios_legacy.c | 22 ++++++++++++++-------- - include/hw/firmware/smbios.h | 4 ++-- - 4 files changed, 40 insertions(+), 23 deletions(-) - -diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index a25793a68f..bdc3cc4556 100644 ---- a/hw/i386/fw_cfg.c -+++ b/hw/i386/fw_cfg.c -@@ -73,7 +73,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) - smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); - - if (pcmc->smbios_legacy_mode) { -- smbios_tables = smbios_get_table_legacy(&smbios_tables_len); -+ smbios_tables = smbios_get_table_legacy(&smbios_tables_len, -+ &error_fatal); - fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, - smbios_tables, smbios_tables_len); - return; -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index e40204550e..b5745c6c2d 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -19,7 +19,6 @@ - #include "qemu/units.h" - #include "qapi/error.h" - #include "qemu/config-file.h" --#include "qemu/error-report.h" - #include "qemu/module.h" - #include "qemu/option.h" - #include "sysemu/sysemu.h" -@@ -497,23 +496,25 @@ opts_init(smbios_register_config); - */ - #define SMBIOS_21_MAX_TABLES_LEN 0xffff - --static void smbios_check_type4_count(uint32_t expected_t4_count) -+static bool smbios_check_type4_count(uint32_t expected_t4_count, Error **errp) - { - if (smbios_type4_count && smbios_type4_count != expected_t4_count) { -- error_report("Expected %d SMBIOS Type 4 tables, got %d instead", -- expected_t4_count, smbios_type4_count); -- exit(1); -+ error_setg(errp, "Expected %d SMBIOS Type 4 tables, got %d instead", -+ expected_t4_count, smbios_type4_count); -+ return false; - } -+ return true; - } - --void smbios_validate_table(void) -+bool smbios_validate_table(Error **errp) - { - if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && - smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) { -- error_report("SMBIOS 2.1 table length %zu exceeds %d", -- smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN); -- exit(1); -+ error_setg(errp, "SMBIOS 2.1 table length %zu exceeds %d", -+ smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN); -+ return false; - } -+ return true; - } - - bool smbios_skip_table(uint8_t type, bool required_table) -@@ -1167,15 +1168,18 @@ void smbios_get_tables(MachineState *ms, - smbios_build_type_41_table(errp); - smbios_build_type_127_table(); - -- smbios_check_type4_count(ms->smp.sockets); -- smbios_validate_table(); -+ if (!smbios_check_type4_count(ms->smp.sockets, errp)) { -+ goto err_exit; -+ } -+ if (!smbios_validate_table(errp)) { -+ goto err_exit; -+ } - smbios_entry_point_setup(); - - /* return tables blob and entry point (anchor), and their sizes */ - *tables = smbios_tables; - *tables_len = smbios_tables_len; - *anchor = (uint8_t *)&ep; -- - /* calculate length based on anchor string */ - if (!strncmp((char *)&ep, "_SM_", 4)) { - *anchor_len = sizeof(struct smbios_21_entry_point); -@@ -1184,6 +1188,12 @@ void smbios_get_tables(MachineState *ms, - } else { - abort(); - } -+ -+ return; -+err_exit: -+ g_free(smbios_tables); -+ smbios_tables = NULL; -+ return; - } - - static void save_opt(const char **dest, QemuOpts *opts, const char *name) -diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c -index 21f143e738..a6544bf55a 100644 ---- a/hw/smbios/smbios_legacy.c -+++ b/hw/smbios/smbios_legacy.c -@@ -19,7 +19,7 @@ - #include "qemu/bswap.h" - #include "hw/firmware/smbios.h" - #include "sysemu/sysemu.h" --#include "qemu/error-report.h" -+#include "qapi/error.h" - - struct smbios_header { - uint16_t length; -@@ -128,7 +128,7 @@ static void smbios_build_type_1_fields(void) - } - } - --uint8_t *smbios_get_table_legacy(size_t *length) -+uint8_t *smbios_get_table_legacy(size_t *length, Error **errp) - { - int i; - size_t usr_offset; -@@ -136,15 +136,15 @@ uint8_t *smbios_get_table_legacy(size_t *length) - /* complain if fields were given for types > 1 */ - if (find_next_bit(smbios_have_fields_bitmap, - SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) { -- error_report("can't process fields for smbios " -+ error_setg(errp, "can't process fields for smbios " - "types > 1 on machine versions < 2.1!"); -- exit(1); -+ goto err_exit; - } - - if (test_bit(4, smbios_have_binfile_bitmap)) { -- error_report("can't process table for smbios " -- "type 4 on machine versions < 2.1!"); -- exit(1); -+ error_setg(errp, "can't process table for smbios " -+ "type 4 on machine versions < 2.1!"); -+ goto err_exit; - } - - g_free(smbios_entries); -@@ -173,7 +173,13 @@ uint8_t *smbios_get_table_legacy(size_t *length) - - smbios_build_type_0_fields(); - smbios_build_type_1_fields(); -- smbios_validate_table(); -+ if (!smbios_validate_table(errp)) { -+ goto err_exit; -+ } -+ - *length = smbios_entries_len; - return smbios_entries; -+err_exit: -+ g_free(smbios_entries); -+ return NULL; - } -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index 92e9aba415..44af3a0d82 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -326,7 +326,7 @@ struct smbios_type_127 { - struct smbios_structure_header header; - } QEMU_PACKED; - --void smbios_validate_table(void); -+bool smbios_validate_table(Error **errp); - void smbios_add_usr_blob_size(size_t size); - void smbios_entry_add(QemuOpts *opts, Error **errp); - void smbios_set_cpuid(uint32_t version, uint32_t features); -@@ -336,7 +336,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product, - SmbiosEntryPointType ep_type, - const char *stream_product, - const char *stream_version); --uint8_t *smbios_get_table_legacy(size_t *length); -+uint8_t *smbios_get_table_legacy(size_t *length, Error **errp); - void smbios_get_tables(MachineState *ms, - const struct smbios_phys_mem_area *mem_array, - const unsigned int mem_array_size, --- -2.39.3 - diff --git a/kvm-smbios-in-case-of-entry-point-is-auto-try-to-build-v.patch b/kvm-smbios-in-case-of-entry-point-is-auto-try-to-build-v.patch deleted file mode 100644 index fd1bc19..0000000 --- a/kvm-smbios-in-case-of-entry-point-is-auto-try-to-build-v.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 38220bc61bdb1614f34a53481f7604720c9e9e5a Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Tue, 20 Feb 2024 10:41:06 +0100 -Subject: [PATCH 18/20] smbios: in case of entry point is 'auto' try to build - v2 tables 1st - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [16/18] becbcb3d8dad4842e5939bb75e21f4e737a4a325 - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - -QEMU for some time now uses SMBIOS 3.0 for PC/Q35 machines by -default, however Windows has a bug in locating SMBIOS 3.0 -entrypoint and fails to find tables when booted on SeaBIOS -(on UEFI SMBIOS 3.0 tables work fine since firmware hands -over tables in another way) - -Missing SMBIOS tables may lead to some issues for guest -though (worst are: possible reactiveation, inability to -get virtio drivers from 'Windows Update') - -It's unclear at this point if MS will fix the issue on their -side. So instead of it (or rather in addition) this patch -will try to workaround the issue. - -aka, use smbios-entry-point-type=auto to make QEMU try -generating conservative SMBIOS 2.0 tables and if that -fails (due to limits/requested configuration) fallback -to SMBIOS 3.0 tables. - -With this in place majority of users will use SMBIOS 2.0 -tables which work fine with (Windows + legacy BIOS). -The configurations that is not to possible to describe -with SMBIOS 2.0 will switch automatically to SMBIOS 3.0 -(which will trigger Windows bug but there is nothing -QEMU can do here, so go and aks Microsoft to real fix). - -Signed-off-by: Igor Mammedov -Reviewed-by: Ani Sinha -Tested-by: Fiona Ebner ---- - hw/smbios/smbios.c | 52 +++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 49 insertions(+), 3 deletions(-) - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 4521ea386c..3d9dcb0d31 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -1097,7 +1097,7 @@ static void smbios_entry_point_setup(SmbiosEntryPointType ep_type) - } - } - --void smbios_get_tables(MachineState *ms, -+static bool smbios_get_tables_ep(MachineState *ms, - SmbiosEntryPointType ep_type, - const struct smbios_phys_mem_area *mem_array, - const unsigned int mem_array_size, -@@ -1106,6 +1106,7 @@ void smbios_get_tables(MachineState *ms, - Error **errp) - { - unsigned i, dimm_cnt, offset; -+ ERRP_GUARD(); - - assert(ep_type == SMBIOS_ENTRY_POINT_TYPE_32 || - ep_type == SMBIOS_ENTRY_POINT_TYPE_64); -@@ -1192,11 +1193,56 @@ void smbios_get_tables(MachineState *ms, - abort(); - } - -- return; -+ return true; - err_exit: - g_free(smbios_tables); - smbios_tables = NULL; -- return; -+ return false; -+} -+ -+void smbios_get_tables(MachineState *ms, -+ SmbiosEntryPointType ep_type, -+ const struct smbios_phys_mem_area *mem_array, -+ const unsigned int mem_array_size, -+ uint8_t **tables, size_t *tables_len, -+ uint8_t **anchor, size_t *anchor_len, -+ Error **errp) -+{ -+ Error *local_err = NULL; -+ bool is_valid; -+ ERRP_GUARD(); -+ -+ switch (ep_type) { -+ case SMBIOS_ENTRY_POINT_TYPE_AUTO: -+ case SMBIOS_ENTRY_POINT_TYPE_32: -+ is_valid = smbios_get_tables_ep(ms, SMBIOS_ENTRY_POINT_TYPE_32, -+ mem_array, mem_array_size, -+ tables, tables_len, -+ anchor, anchor_len, -+ &local_err); -+ if (is_valid || ep_type != SMBIOS_ENTRY_POINT_TYPE_AUTO) { -+ break; -+ } -+ /* -+ * fall through in case AUTO endpoint is selected and -+ * SMBIOS 2.x tables can't be generated, to try if SMBIOS 3.x -+ * tables would work -+ */ -+ case SMBIOS_ENTRY_POINT_TYPE_64: -+ error_free(local_err); -+ local_err = NULL; -+ is_valid = smbios_get_tables_ep(ms, SMBIOS_ENTRY_POINT_TYPE_64, -+ mem_array, mem_array_size, -+ tables, tables_len, -+ anchor, anchor_len, -+ &local_err); -+ break; -+ default: -+ abort(); -+ } -+ if (!is_valid) { -+ error_propagate(errp, local_err); -+ } - } - - static void save_opt(const char **dest, QemuOpts *opts, const char *name) --- -2.39.3 - diff --git a/kvm-smbios-rename-expose-structures-bitmaps-used-by-both.patch b/kvm-smbios-rename-expose-structures-bitmaps-used-by-both.patch deleted file mode 100644 index cba6134..0000000 --- a/kvm-smbios-rename-expose-structures-bitmaps-used-by-both.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 36b0256e27f9d5268c5413891b4a7322819ae9db Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Mon, 4 Mar 2024 15:56:19 +0100 -Subject: [PATCH 12/20] smbios: rename/expose structures/bitmaps used by both - legacy and modern code - -RH-Author: Igor Mammedov -RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS -RH-Jira: RHEL-21705 -RH-Acked-by: MST -RH-Acked-by: Ani Sinha -RH-Commit: [10/18] 59fe438d5b7f6e584a6bb02597e4d4724fe2cece - -JIRA: https://issues.redhat.com/browse/RHEL-21705 - - As a preparation to move legacy handling into a separate file, - add prefix 'smbios_' to type0/type1/have_binfile_bitmap/have_fields_bitmap - and expose them in smbios.h so that they can be reused in - legacy and modern code. - - Doing it as a separate patch to avoid rename cluttering follow-up - patch which will move legacy code into a separate file. - - Signed-off-by: Igor Mammedov - Reviewed-by: Ani Sinha - -Conflicts: hw/smbios/smbios.c - due to setting downstream type1.family/type1.sku defaults - -Signed-off-by: Igor Mammedov ---- - hw/smbios/smbios.c | 117 ++++++++++++++++------------------- - include/hw/firmware/smbios.h | 16 +++++ - 2 files changed, 71 insertions(+), 62 deletions(-) - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index c48a290478..eb9927335d 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -81,19 +81,11 @@ static int smbios_type4_count = 0; - static bool smbios_have_defaults; - static uint32_t smbios_cpuid_version, smbios_cpuid_features; - --static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1); --static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1); -+DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1); -+DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1); - --static struct { -- const char *vendor, *version, *date; -- bool have_major_minor, uefi; -- uint8_t major, minor; --} type0; -- --static struct { -- const char *manufacturer, *product, *version, *serial, *sku, *family; -- /* uuid is in qemu_uuid */ --} type1; -+smbios_type0_t smbios_type0; -+smbios_type1_t smbios_type1; - - static struct { - const char *manufacturer, *product, *version, *serial, *asset, *location; -@@ -584,36 +576,36 @@ static void smbios_maybe_add_str(int type, int offset, const char *data) - static void smbios_build_type_0_fields(void) - { - smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str), -- type0.vendor); -+ smbios_type0.vendor); - smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str), -- type0.version); -+ smbios_type0.version); - smbios_maybe_add_str(0, offsetof(struct smbios_type_0, - bios_release_date_str), -- type0.date); -- if (type0.have_major_minor) { -+ smbios_type0.date); -+ if (smbios_type0.have_major_minor) { - smbios_add_field(0, offsetof(struct smbios_type_0, - system_bios_major_release), -- &type0.major, 1); -+ &smbios_type0.major, 1); - smbios_add_field(0, offsetof(struct smbios_type_0, - system_bios_minor_release), -- &type0.minor, 1); -+ &smbios_type0.minor, 1); - } - } - - static void smbios_build_type_1_fields(void) - { - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str), -- type1.manufacturer); -+ smbios_type1.manufacturer); - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str), -- type1.product); -+ smbios_type1.product); - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str), -- type1.version); -+ smbios_type1.version); - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str), -- type1.serial); -+ smbios_type1.serial); - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str), -- type1.sku); -+ smbios_type1.sku); - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str), -- type1.family); -+ smbios_type1.family); - if (qemu_uuid_set) { - /* We don't encode the UUID in the "wire format" here because this - * function is for legacy mode and needs to keep the guest ABI, and -@@ -631,14 +623,14 @@ uint8_t *smbios_get_table_legacy(size_t *length) - size_t usr_offset; - - /* also complain if fields were given for types > 1 */ -- if (find_next_bit(have_fields_bitmap, -+ if (find_next_bit(smbios_have_fields_bitmap, - SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) { - error_report("can't process fields for smbios " - "types > 1 on machine versions < 2.1!"); - exit(1); - } - -- if (test_bit(4, have_binfile_bitmap)) { -+ if (test_bit(4, smbios_have_binfile_bitmap)) { - error_report("can't process table for smbios " - "type 4 on machine versions < 2.1!"); - exit(1); -@@ -679,10 +671,10 @@ uint8_t *smbios_get_table_legacy(size_t *length) - - bool smbios_skip_table(uint8_t type, bool required_table) - { -- if (test_bit(type, have_binfile_bitmap)) { -+ if (test_bit(type, smbios_have_binfile_bitmap)) { - return true; /* user provided their own binary blob(s) */ - } -- if (test_bit(type, have_fields_bitmap)) { -+ if (test_bit(type, smbios_have_fields_bitmap)) { - return false; /* user provided fields via command line */ - } - if (smbios_have_defaults && required_table) { -@@ -710,25 +702,25 @@ static void smbios_build_type_0_table(void) - { - SMBIOS_BUILD_TABLE_PRE(0, T0_BASE, false); /* optional, leave up to BIOS */ - -- SMBIOS_TABLE_SET_STR(0, vendor_str, type0.vendor); -- SMBIOS_TABLE_SET_STR(0, bios_version_str, type0.version); -+ SMBIOS_TABLE_SET_STR(0, vendor_str, smbios_type0.vendor); -+ SMBIOS_TABLE_SET_STR(0, bios_version_str, smbios_type0.version); - - t->bios_starting_address_segment = cpu_to_le16(0xE800); /* from SeaBIOS */ - -- SMBIOS_TABLE_SET_STR(0, bios_release_date_str, type0.date); -+ SMBIOS_TABLE_SET_STR(0, bios_release_date_str, smbios_type0.date); - - t->bios_rom_size = 0; /* hardcoded in SeaBIOS with FIXME comment */ - - t->bios_characteristics = cpu_to_le64(0x08); /* Not supported */ - t->bios_characteristics_extension_bytes[0] = 0; - t->bios_characteristics_extension_bytes[1] = 0x14; /* TCD/SVVP | VM */ -- if (type0.uefi) { -+ if (smbios_type0.uefi) { - t->bios_characteristics_extension_bytes[1] |= 0x08; /* |= UEFI */ - } - -- if (type0.have_major_minor) { -- t->system_bios_major_release = type0.major; -- t->system_bios_minor_release = type0.minor; -+ if (smbios_type0.have_major_minor) { -+ t->system_bios_major_release = smbios_type0.major; -+ t->system_bios_minor_release = smbios_type0.minor; - } else { - t->system_bios_major_release = 0; - t->system_bios_minor_release = 0; -@@ -758,18 +750,18 @@ static void smbios_build_type_1_table(void) - { - SMBIOS_BUILD_TABLE_PRE(1, T1_BASE, true); /* required */ - -- SMBIOS_TABLE_SET_STR(1, manufacturer_str, type1.manufacturer); -- SMBIOS_TABLE_SET_STR(1, product_name_str, type1.product); -- SMBIOS_TABLE_SET_STR(1, version_str, type1.version); -- SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial); -+ SMBIOS_TABLE_SET_STR(1, manufacturer_str, smbios_type1.manufacturer); -+ SMBIOS_TABLE_SET_STR(1, product_name_str, smbios_type1.product); -+ SMBIOS_TABLE_SET_STR(1, version_str, smbios_type1.version); -+ SMBIOS_TABLE_SET_STR(1, serial_number_str, smbios_type1.serial); - if (qemu_uuid_set) { - smbios_encode_uuid(&t->uuid, &qemu_uuid); - } else { - memset(&t->uuid, 0, 16); - } - t->wake_up_type = 0x06; /* power switch */ -- SMBIOS_TABLE_SET_STR(1, sku_number_str, type1.sku); -- SMBIOS_TABLE_SET_STR(1, family_str, type1.family); -+ SMBIOS_TABLE_SET_STR(1, sku_number_str, smbios_type1.sku); -+ SMBIOS_TABLE_SET_STR(1, family_str, smbios_type1.family); - - SMBIOS_BUILD_TABLE_POST; - } -@@ -1184,12 +1176,12 @@ void smbios_set_defaults(const char *manufacturer, const char *product, - * - * We get 'System Manufacturer' and 'Baseboard Manufacturer' - */ -- SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer); -- SMBIOS_SET_DEFAULT(type1.product, product); -- SMBIOS_SET_DEFAULT(type1.version, version); -- SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux"); -+ SMBIOS_SET_DEFAULT(smbios_type1.manufacturer, manufacturer); -+ SMBIOS_SET_DEFAULT(smbios_type1.product, product); -+ SMBIOS_SET_DEFAULT(smbios_type1.version, version); -+ SMBIOS_SET_DEFAULT(smbios_type1.family, "Red Hat Enterprise Linux"); - if (stream_version != NULL) { -- SMBIOS_SET_DEFAULT(type1.sku, stream_version); -+ SMBIOS_SET_DEFAULT(smbios_type1.sku, stream_version); - } - SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer); - if (stream_product != NULL) { -@@ -1468,13 +1460,13 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) - } - - if (header->type <= SMBIOS_MAX_TYPE) { -- if (test_bit(header->type, have_fields_bitmap)) { -+ if (test_bit(header->type, smbios_have_fields_bitmap)) { - error_setg(errp, - "can't load type %d struct, fields already specified!", - header->type); - return; - } -- set_bit(header->type, have_binfile_bitmap); -+ set_bit(header->type, smbios_have_binfile_bitmap); - } - - if (header->type == 4) { -@@ -1505,41 +1497,42 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) - return; - } - -- if (test_bit(type, have_binfile_bitmap)) { -+ if (test_bit(type, smbios_have_binfile_bitmap)) { - error_setg(errp, "can't add fields, binary file already loaded!"); - return; - } -- set_bit(type, have_fields_bitmap); -+ set_bit(type, smbios_have_fields_bitmap); - - switch (type) { - case 0: - if (!qemu_opts_validate(opts, qemu_smbios_type0_opts, errp)) { - return; - } -- save_opt(&type0.vendor, opts, "vendor"); -- save_opt(&type0.version, opts, "version"); -- save_opt(&type0.date, opts, "date"); -- type0.uefi = qemu_opt_get_bool(opts, "uefi", false); -+ save_opt(&smbios_type0.vendor, opts, "vendor"); -+ save_opt(&smbios_type0.version, opts, "version"); -+ save_opt(&smbios_type0.date, opts, "date"); -+ smbios_type0.uefi = qemu_opt_get_bool(opts, "uefi", false); - - val = qemu_opt_get(opts, "release"); - if (val) { -- if (sscanf(val, "%hhu.%hhu", &type0.major, &type0.minor) != 2) { -+ if (sscanf(val, "%hhu.%hhu", &smbios_type0.major, -+ &smbios_type0.minor) != 2) { - error_setg(errp, "Invalid release"); - return; - } -- type0.have_major_minor = true; -+ smbios_type0.have_major_minor = true; - } - return; - case 1: - if (!qemu_opts_validate(opts, qemu_smbios_type1_opts, errp)) { - return; - } -- save_opt(&type1.manufacturer, opts, "manufacturer"); -- save_opt(&type1.product, opts, "product"); -- save_opt(&type1.version, opts, "version"); -- save_opt(&type1.serial, opts, "serial"); -- save_opt(&type1.sku, opts, "sku"); -- save_opt(&type1.family, opts, "family"); -+ save_opt(&smbios_type1.manufacturer, opts, "manufacturer"); -+ save_opt(&smbios_type1.product, opts, "product"); -+ save_opt(&smbios_type1.version, opts, "version"); -+ save_opt(&smbios_type1.serial, opts, "serial"); -+ save_opt(&smbios_type1.sku, opts, "sku"); -+ save_opt(&smbios_type1.family, opts, "family"); - - val = qemu_opt_get(opts, "uuid"); - if (val) { -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index d55018e5e3..333de0d5fc 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -2,6 +2,7 @@ - #define QEMU_SMBIOS_H - - #include "qapi/qapi-types-machine.h" -+#include "qemu/bitmap.h" - - /* - * SMBIOS Support -@@ -16,8 +17,23 @@ - * - */ - -+typedef struct { -+ const char *vendor, *version, *date; -+ bool have_major_minor, uefi; -+ uint8_t major, minor; -+} smbios_type0_t; -+extern smbios_type0_t smbios_type0; -+ -+typedef struct { -+ const char *manufacturer, *product, *version, *serial, *sku, *family; -+ /* uuid is in qemu_uuid */ -+} smbios_type1_t; -+extern smbios_type1_t smbios_type1; - - #define SMBIOS_MAX_TYPE 127 -+extern DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1); -+extern DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1); -+ - #define offsetofend(TYPE, MEMBER) \ - (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER)) - --- -2.39.3 - diff --git a/kvm-string-output-visitor-Fix-pseudo-struct-handling.patch b/kvm-string-output-visitor-Fix-pseudo-struct-handling.patch deleted file mode 100644 index 81ae2f1..0000000 --- a/kvm-string-output-visitor-Fix-pseudo-struct-handling.patch +++ /dev/null @@ -1,190 +0,0 @@ -From c5f9e92cd49a2171a5b0223cafd7fab3f45edb82 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 9 Jan 2024 19:17:17 +0100 -Subject: [PATCH 06/22] string-output-visitor: Fix (pseudo) struct handling - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [2/17] 84e226f161680dd61b6635e213203d062c1aa556 (stefanha/centos-stream-qemu-kvm) - -Commit ff32bb53 tried to get minimal struct support into the string -output visitor by just making it return "". Unfortunately, it -forgot that the caller will still make more visitor calls for the -content of the struct. - -If the struct is contained in a list, such as IOThreadVirtQueueMapping, -in the better case its fields show up as separate list entries. In the -worse case, it contains another list, and the string output visitor -doesn't support nested lists and asserts that this doesn't happen. So as -soon as the optional "vqs" field in IOThreadVirtQueueMapping is -specified, we get a crash. - -This can be reproduced with the following command line: - - echo "info qtree" | ./qemu-system-x86_64 \ - -object iothread,id=t0 \ - -blockdev null-co,node-name=disk \ - -device '{"driver": "virtio-blk-pci", "drive": "disk", - "iothread-vq-mapping": [{"iothread": "t0", "vqs": [0]}]}' \ - -monitor stdio - -Fix the problem by counting the nesting level of structs and ignoring -any visitor calls for values (apart from start/end_struct) while we're -not on the top level. - -Lists nested directly within lists remain unimplemented, as we don't -currently have a use case for them. - -Fixes: ff32bb53476539d352653f4ed56372dced73a388 -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2069 -Reported-by: Aihua Liang -Signed-off-by: Kevin Wolf -Message-ID: <20240109181717.42493-1-kwolf@redhat.com> -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf -(cherry picked from commit 014b99a8e41c8cd1e895137654b44dec5430122c) -Signed-off-by: Stefan Hajnoczi ---- - qapi/string-output-visitor.c | 46 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 46 insertions(+) - -diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c -index f0c1dea89e..5115536b15 100644 ---- a/qapi/string-output-visitor.c -+++ b/qapi/string-output-visitor.c -@@ -65,6 +65,7 @@ struct StringOutputVisitor - } range_start, range_end; - GList *ranges; - void *list; /* Only needed for sanity checking the caller */ -+ unsigned int struct_nesting; - }; - - static StringOutputVisitor *to_sov(Visitor *v) -@@ -144,6 +145,10 @@ static bool print_type_int64(Visitor *v, const char *name, int64_t *obj, - StringOutputVisitor *sov = to_sov(v); - GList *l; - -+ if (sov->struct_nesting) { -+ return true; -+ } -+ - switch (sov->list_mode) { - case LM_NONE: - string_output_append(sov, *obj); -@@ -231,6 +236,10 @@ static bool print_type_size(Visitor *v, const char *name, uint64_t *obj, - uint64_t val; - char *out, *psize; - -+ if (sov->struct_nesting) { -+ return true; -+ } -+ - if (!sov->human) { - out = g_strdup_printf("%"PRIu64, *obj); - string_output_set(sov, out); -@@ -250,6 +259,11 @@ static bool print_type_bool(Visitor *v, const char *name, bool *obj, - Error **errp) - { - StringOutputVisitor *sov = to_sov(v); -+ -+ if (sov->struct_nesting) { -+ return true; -+ } -+ - string_output_set(sov, g_strdup(*obj ? "true" : "false")); - return true; - } -@@ -260,6 +274,10 @@ static bool print_type_str(Visitor *v, const char *name, char **obj, - StringOutputVisitor *sov = to_sov(v); - char *out; - -+ if (sov->struct_nesting) { -+ return true; -+ } -+ - if (sov->human) { - out = *obj ? g_strdup_printf("\"%s\"", *obj) : g_strdup(""); - } else { -@@ -273,6 +291,11 @@ static bool print_type_number(Visitor *v, const char *name, double *obj, - Error **errp) - { - StringOutputVisitor *sov = to_sov(v); -+ -+ if (sov->struct_nesting) { -+ return true; -+ } -+ - string_output_set(sov, g_strdup_printf("%.17g", *obj)); - return true; - } -@@ -283,6 +306,10 @@ static bool print_type_null(Visitor *v, const char *name, QNull **obj, - StringOutputVisitor *sov = to_sov(v); - char *out; - -+ if (sov->struct_nesting) { -+ return true; -+ } -+ - if (sov->human) { - out = g_strdup(""); - } else { -@@ -295,6 +322,9 @@ static bool print_type_null(Visitor *v, const char *name, QNull **obj, - static bool start_struct(Visitor *v, const char *name, void **obj, - size_t size, Error **errp) - { -+ StringOutputVisitor *sov = to_sov(v); -+ -+ sov->struct_nesting++; - return true; - } - -@@ -302,6 +332,10 @@ static void end_struct(Visitor *v, void **obj) - { - StringOutputVisitor *sov = to_sov(v); - -+ if (--sov->struct_nesting) { -+ return; -+ } -+ - /* TODO actually print struct fields */ - string_output_set(sov, g_strdup("")); - } -@@ -312,6 +346,10 @@ start_list(Visitor *v, const char *name, GenericList **list, size_t size, - { - StringOutputVisitor *sov = to_sov(v); - -+ if (sov->struct_nesting) { -+ return true; -+ } -+ - /* we can't traverse a list in a list */ - assert(sov->list_mode == LM_NONE); - /* We don't support visits without a list */ -@@ -329,6 +367,10 @@ static GenericList *next_list(Visitor *v, GenericList *tail, size_t size) - StringOutputVisitor *sov = to_sov(v); - GenericList *ret = tail->next; - -+ if (sov->struct_nesting) { -+ return ret; -+ } -+ - if (ret && !ret->next) { - sov->list_mode = LM_END; - } -@@ -339,6 +381,10 @@ static void end_list(Visitor *v, void **obj) - { - StringOutputVisitor *sov = to_sov(v); - -+ if (sov->struct_nesting) { -+ return; -+ } -+ - assert(sov->list == obj); - assert(sov->list_mode == LM_STARTED || - sov->list_mode == LM_END || --- -2.39.3 - diff --git a/kvm-string-output-visitor-show-structs-as-omitted.patch b/kvm-string-output-visitor-show-structs-as-omitted.patch deleted file mode 100644 index f83635d..0000000 --- a/kvm-string-output-visitor-show-structs-as-omitted.patch +++ /dev/null @@ -1,90 +0,0 @@ -From fb2069be402ec1322834c555714f0e993778cc9d Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 12 Dec 2023 08:49:34 -0500 -Subject: [PATCH 05/22] string-output-visitor: show structs as "" - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [1/17] 0c08e8237d28fbdbdbc7576d4c17d2eeeb413c2a (stefanha/centos-stream-qemu-kvm) - -StringOutputVisitor crashes when it visits a struct because -->start_struct() is NULL. - -Show "" instead of crashing. This is necessary because the -virtio-blk-pci iothread-vq-mapping parameter that I'd like to introduce -soon is a list of IOThreadMapping structs. - -This patch is a quick fix to solve the crash, but the long-term solution -is replacing StringOutputVisitor with something that can handle the full -gamut of values in QEMU. - -Cc: Markus Armbruster -Signed-off-by: Stefan Hajnoczi -Message-ID: <20231212134934.500289-1-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Reviewed-by: Markus Armbruster -Signed-off-by: Kevin Wolf -(cherry picked from commit ff32bb53476539d352653f4ed56372dced73a388) -Signed-off-by: Stefan Hajnoczi ---- - include/qapi/string-output-visitor.h | 6 +++--- - qapi/string-output-visitor.c | 16 ++++++++++++++++ - 2 files changed, 19 insertions(+), 3 deletions(-) - -diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h -index 268dfe9986..b1ee473b30 100644 ---- a/include/qapi/string-output-visitor.h -+++ b/include/qapi/string-output-visitor.h -@@ -26,9 +26,9 @@ typedef struct StringOutputVisitor StringOutputVisitor; - * If everything else succeeds, pass @result to visit_complete() to - * collect the result of the visit. - * -- * The string output visitor does not implement support for visiting -- * QAPI structs, alternates, null, or arbitrary QTypes. It also -- * requires a non-null list argument to visit_start_list(). -+ * The string output visitor does not implement support for alternates, null, -+ * or arbitrary QTypes. Struct fields are not shown. It also requires a -+ * non-null list argument to visit_start_list(). - */ - Visitor *string_output_visitor_new(bool human, char **result); - -diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c -index c0cb72dbe4..f0c1dea89e 100644 ---- a/qapi/string-output-visitor.c -+++ b/qapi/string-output-visitor.c -@@ -292,6 +292,20 @@ static bool print_type_null(Visitor *v, const char *name, QNull **obj, - return true; - } - -+static bool start_struct(Visitor *v, const char *name, void **obj, -+ size_t size, Error **errp) -+{ -+ return true; -+} -+ -+static void end_struct(Visitor *v, void **obj) -+{ -+ StringOutputVisitor *sov = to_sov(v); -+ -+ /* TODO actually print struct fields */ -+ string_output_set(sov, g_strdup("")); -+} -+ - static bool - start_list(Visitor *v, const char *name, GenericList **list, size_t size, - Error **errp) -@@ -379,6 +393,8 @@ Visitor *string_output_visitor_new(bool human, char **result) - v->visitor.type_str = print_type_str; - v->visitor.type_number = print_type_number; - v->visitor.type_null = print_type_null; -+ v->visitor.start_struct = start_struct; -+ v->visitor.end_struct = end_struct; - v->visitor.start_list = start_list; - v->visitor.next_list = next_list; - v->visitor.end_list = end_list; --- -2.39.3 - diff --git a/kvm-target-s390x-kvm-pv-Provide-some-more-useful-informa.patch b/kvm-target-s390x-kvm-pv-Provide-some-more-useful-informa.patch deleted file mode 100644 index a2d712f..0000000 --- a/kvm-target-s390x-kvm-pv-Provide-some-more-useful-informa.patch +++ /dev/null @@ -1,205 +0,0 @@ -From cc8d794932e26df7c7f3c8cc0c1f42da8d52f12b Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Mon, 15 Jan 2024 10:26:52 +0100 -Subject: [PATCH 069/101] target/s390x/kvm/pv: Provide some more useful - information if decryption fails -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 213: s390x: Provide some more useful information if decryption of a PV image fails -RH-Jira: RHEL-18212 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Cornelia Huck -RH-Commit: [1/1] 4ffb61869f7df33e23d3e0ebf8c29e386e3f6cbc (thuth/qemu-kvm-cs9) - -JIRA: https://issues.redhat.com/browse/RHEL-18212 - -commit 7af51621b16ae86646cc2dc9dee30de8176ff761 -Author: Thomas Huth -Date: Wed Jan 10 15:29:16 2024 +0100 - - target/s390x/kvm/pv: Provide some more useful information if decryption fails - - It's a common scenario to copy guest images from one host to another - to run the guest on the other machine. This (of course) does not work - with "secure execution" guests since they are encrypted with one certain - host key. However, if you still (accidentally) do it, you only get a - very user-unfriendly error message that looks like this: - - qemu-system-s390x: KVM PV command 2 (KVM_PV_SET_SEC_PARMS) failed: - header rc 108 rrc 5 IOCTL rc: -22 - - Let's provide at least a somewhat nicer hint to the users so that they - are able to figure out what might have gone wrong. - - Buglink: https://issues.redhat.com/browse/RHEL-18212 - Message-ID: <20240110142916.850605-1-thuth@redhat.com> - Reviewed-by: Philippe Mathieu-Daudé - Reviewed-by: Cédric Le Goater - Reviewed-by: Claudio Imbrenda - Signed-off-by: Thomas Huth - -Signed-off-by: Thomas Huth ---- - hw/s390x/ipl.c | 5 ++--- - hw/s390x/ipl.h | 2 +- - hw/s390x/s390-virtio-ccw.c | 5 ++++- - target/s390x/kvm/pv.c | 25 ++++++++++++++++++++----- - target/s390x/kvm/pv.h | 5 +++-- - 5 files changed, 30 insertions(+), 12 deletions(-) - -diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c -index 515dcf51b5..b23a6a0ef3 100644 ---- a/hw/s390x/ipl.c -+++ b/hw/s390x/ipl.c -@@ -703,7 +703,7 @@ static void s390_ipl_prepare_qipl(S390CPU *cpu) - cpu_physical_memory_unmap(addr, len, 1, len); - } - --int s390_ipl_prepare_pv_header(void) -+int s390_ipl_prepare_pv_header(Error **errp) - { - IplParameterBlock *ipib = s390_ipl_get_iplb_pv(); - IPLBlockPV *ipib_pv = &ipib->pv; -@@ -712,8 +712,7 @@ int s390_ipl_prepare_pv_header(void) - - cpu_physical_memory_read(ipib_pv->pv_header_addr, hdr, - ipib_pv->pv_header_len); -- rc = s390_pv_set_sec_parms((uintptr_t)hdr, -- ipib_pv->pv_header_len); -+ rc = s390_pv_set_sec_parms((uintptr_t)hdr, ipib_pv->pv_header_len, errp); - g_free(hdr); - return rc; - } -diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h -index 7fc86e7905..57cd125769 100644 ---- a/hw/s390x/ipl.h -+++ b/hw/s390x/ipl.h -@@ -107,7 +107,7 @@ typedef union IplParameterBlock IplParameterBlock; - - int s390_ipl_set_loadparm(uint8_t *loadparm); - void s390_ipl_update_diag308(IplParameterBlock *iplb); --int s390_ipl_prepare_pv_header(void); -+int s390_ipl_prepare_pv_header(Error **errp); - int s390_ipl_pv_unpack(void); - void s390_ipl_prepare_cpu(S390CPU *cpu); - IplParameterBlock *s390_ipl_get_iplb(void); -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 984891b82a..e26ce26f5a 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -391,7 +391,7 @@ static int s390_machine_protect(S390CcwMachineState *ms) - } - - /* Set SE header and unpack */ -- rc = s390_ipl_prepare_pv_header(); -+ rc = s390_ipl_prepare_pv_header(&local_err); - if (rc) { - goto out_err; - } -@@ -410,6 +410,9 @@ static int s390_machine_protect(S390CcwMachineState *ms) - return rc; - - out_err: -+ if (local_err) { -+ error_report_err(local_err); -+ } - s390_machine_unprotect(ms); - return rc; - } -diff --git a/target/s390x/kvm/pv.c b/target/s390x/kvm/pv.c -index 6a69be7e5c..7ca7faec73 100644 ---- a/target/s390x/kvm/pv.c -+++ b/target/s390x/kvm/pv.c -@@ -29,7 +29,8 @@ static bool info_valid; - static struct kvm_s390_pv_info_vm info_vm; - static struct kvm_s390_pv_info_dump info_dump; - --static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data) -+static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data, -+ int *pvrc) - { - struct kvm_pv_cmd pv_cmd = { - .cmd = cmd, -@@ -46,6 +47,9 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data) - "IOCTL rc: %d", cmd, cmdname, pv_cmd.rc, pv_cmd.rrc, - rc); - } -+ if (pvrc) { -+ *pvrc = pv_cmd.rc; -+ } - return rc; - } - -@@ -53,12 +57,13 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data) - * This macro lets us pass the command as a string to the function so - * we can print it on an error. - */ --#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data) -+#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data, NULL) -+#define s390_pv_cmd_pvrc(cmd, data, pvrc) __s390_pv_cmd(cmd, #cmd, data, pvrc) - #define s390_pv_cmd_exit(cmd, data) \ - { \ - int rc; \ - \ -- rc = __s390_pv_cmd(cmd, #cmd, data);\ -+ rc = __s390_pv_cmd(cmd, #cmd, data, NULL); \ - if (rc) { \ - exit(1); \ - } \ -@@ -142,14 +147,24 @@ bool s390_pv_vm_try_disable_async(S390CcwMachineState *ms) - return true; - } - --int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) -+int s390_pv_set_sec_parms(uint64_t origin, uint64_t length, Error **errp) - { -+ int ret, pvrc; - struct kvm_s390_pv_sec_parm args = { - .origin = origin, - .length = length, - }; - -- return s390_pv_cmd(KVM_PV_SET_SEC_PARMS, &args); -+ ret = s390_pv_cmd_pvrc(KVM_PV_SET_SEC_PARMS, &args, &pvrc); -+ if (ret) { -+ error_setg(errp, "Failed to set secure execution parameters"); -+ if (pvrc == 0x108) { -+ error_append_hint(errp, "Please check whether the image is " -+ "correctly encrypted for this host\n"); -+ } -+ } -+ -+ return ret; - } - - /* -diff --git a/target/s390x/kvm/pv.h b/target/s390x/kvm/pv.h -index 7b935e2246..5877d28ff1 100644 ---- a/target/s390x/kvm/pv.h -+++ b/target/s390x/kvm/pv.h -@@ -42,7 +42,7 @@ int s390_pv_query_info(void); - int s390_pv_vm_enable(void); - void s390_pv_vm_disable(void); - bool s390_pv_vm_try_disable_async(S390CcwMachineState *ms); --int s390_pv_set_sec_parms(uint64_t origin, uint64_t length); -+int s390_pv_set_sec_parms(uint64_t origin, uint64_t length, Error **errp); - int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak); - void s390_pv_prep_reset(void); - int s390_pv_verify(void); -@@ -62,7 +62,8 @@ static inline int s390_pv_query_info(void) { return 0; } - static inline int s390_pv_vm_enable(void) { return 0; } - static inline void s390_pv_vm_disable(void) {} - static inline bool s390_pv_vm_try_disable_async(S390CcwMachineState *ms) { return false; } --static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) { return 0; } -+static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length, -+ Error **errp) { return 0; } - static inline int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak) { return 0; } - static inline void s390_pv_prep_reset(void) {} - static inline int s390_pv_verify(void) { return 0; } --- -2.39.3 - diff --git a/kvm-tests-remove-aio_context_acquire-tests.patch b/kvm-tests-remove-aio_context_acquire-tests.patch deleted file mode 100644 index 9b3eefb..0000000 --- a/kvm-tests-remove-aio_context_acquire-tests.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 420bf75353286324822c3bbca3b52a7a56ed668c Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:20:00 -0500 -Subject: [PATCH 083/101] tests: remove aio_context_acquire() tests - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [14/26] f6421037c1523bc957f3be0f4ad05571ae012dba (kmwolf/centos-qemu-kvm) - -The aio_context_acquire() API is being removed. Drop the test case that -calls the API. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Reviewed-by: Kevin Wolf -Message-ID: <20231205182011.1976568-4-stefanha@redhat.com> -Signed-off-by: Kevin Wolf ---- - tests/unit/test-aio.c | 67 +------------------------------------------ - 1 file changed, 1 insertion(+), 66 deletions(-) - -diff --git a/tests/unit/test-aio.c b/tests/unit/test-aio.c -index 337b6e4ea7..e77d86be87 100644 ---- a/tests/unit/test-aio.c -+++ b/tests/unit/test-aio.c -@@ -100,76 +100,12 @@ static void event_ready_cb(EventNotifier *e) - - /* Tests using aio_*. */ - --typedef struct { -- QemuMutex start_lock; -- EventNotifier notifier; -- bool thread_acquired; --} AcquireTestData; -- --static void *test_acquire_thread(void *opaque) --{ -- AcquireTestData *data = opaque; -- -- /* Wait for other thread to let us start */ -- qemu_mutex_lock(&data->start_lock); -- qemu_mutex_unlock(&data->start_lock); -- -- /* event_notifier_set might be called either before or after -- * the main thread's call to poll(). The test case's outcome -- * should be the same in either case. -- */ -- event_notifier_set(&data->notifier); -- aio_context_acquire(ctx); -- aio_context_release(ctx); -- -- data->thread_acquired = true; /* success, we got here */ -- -- return NULL; --} -- - static void set_event_notifier(AioContext *nctx, EventNotifier *notifier, - EventNotifierHandler *handler) - { - aio_set_event_notifier(nctx, notifier, handler, NULL, NULL); - } - --static void dummy_notifier_read(EventNotifier *n) --{ -- event_notifier_test_and_clear(n); --} -- --static void test_acquire(void) --{ -- QemuThread thread; -- AcquireTestData data; -- -- /* Dummy event notifier ensures aio_poll() will block */ -- event_notifier_init(&data.notifier, false); -- set_event_notifier(ctx, &data.notifier, dummy_notifier_read); -- g_assert(!aio_poll(ctx, false)); /* consume aio_notify() */ -- -- qemu_mutex_init(&data.start_lock); -- qemu_mutex_lock(&data.start_lock); -- data.thread_acquired = false; -- -- qemu_thread_create(&thread, "test_acquire_thread", -- test_acquire_thread, -- &data, QEMU_THREAD_JOINABLE); -- -- /* Block in aio_poll(), let other thread kick us and acquire context */ -- aio_context_acquire(ctx); -- qemu_mutex_unlock(&data.start_lock); /* let the thread run */ -- g_assert(aio_poll(ctx, true)); -- g_assert(!data.thread_acquired); -- aio_context_release(ctx); -- -- qemu_thread_join(&thread); -- set_event_notifier(ctx, &data.notifier, NULL); -- event_notifier_cleanup(&data.notifier); -- -- g_assert(data.thread_acquired); --} -- - static void test_bh_schedule(void) - { - BHTestData data = { .n = 0 }; -@@ -879,7 +815,7 @@ static void test_worker_thread_co_enter(void) - qemu_thread_get_self(&this_thread); - co = qemu_coroutine_create(co_check_current_thread, &this_thread); - -- qemu_thread_create(&worker_thread, "test_acquire_thread", -+ qemu_thread_create(&worker_thread, "test_aio_co_enter", - test_aio_co_enter, - co, QEMU_THREAD_JOINABLE); - -@@ -899,7 +835,6 @@ int main(int argc, char **argv) - while (g_main_context_iteration(NULL, false)); - - g_test_init(&argc, &argv, NULL); -- g_test_add_func("/aio/acquire", test_acquire); - g_test_add_func("/aio/bh/schedule", test_bh_schedule); - g_test_add_func("/aio/bh/schedule10", test_bh_schedule10); - g_test_add_func("/aio/bh/cancel", test_bh_cancel); --- -2.39.3 - diff --git a/kvm-tests-unit-Bump-test-replication-timeout-to-60-secon.patch b/kvm-tests-unit-Bump-test-replication-timeout-to-60-secon.patch deleted file mode 100644 index 0afdea2..0000000 --- a/kvm-tests-unit-Bump-test-replication-timeout-to-60-secon.patch +++ /dev/null @@ -1,46 +0,0 @@ -From bbe64d706b3cb8b10ecd22bd71cf76b21eea257f Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Thu, 25 Jan 2024 17:58:03 +0100 -Subject: [PATCH 20/22] tests/unit: Bump test-replication timeout to 60 seconds - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [16/17] 200768aedee44d10aa8d199b92a9c17a9002fc3f (stefanha/centos-stream-qemu-kvm) - -We're seeing timeouts for this test on CI runs (specifically for -ubuntu-20.04-s390x-all). It doesn't fail consistently, but even the -successful runs take about 27 or 28 seconds, which is not very far from -the 30 seconds timeout. - -Bump the timeout a bit to make failure less likely even on this CI host. - -Signed-off-by: Kevin Wolf -Message-ID: <20240125165803.48373-1-kwolf@redhat.com> -Reviewed-by: Thomas Huth -Signed-off-by: Kevin Wolf -(cherry picked from commit 63b18312d14ac984acaf13c7c55d9baa2d61496e) -Signed-off-by: Stefan Hajnoczi ---- - tests/unit/meson.build | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tests/unit/meson.build b/tests/unit/meson.build -index a05d471090..28db6adea8 100644 ---- a/tests/unit/meson.build -+++ b/tests/unit/meson.build -@@ -173,7 +173,8 @@ test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) - - slow_tests = { - 'test-crypto-tlscredsx509': 45, -- 'test-crypto-tlssession': 45 -+ 'test-crypto-tlssession': 45, -+ 'test-replication': 60, - } - - foreach test_name, extra: tests --- -2.39.3 - diff --git a/kvm-ui-clipboard-add-asserts-for-update-and-request.patch b/kvm-ui-clipboard-add-asserts-for-update-and-request.patch deleted file mode 100644 index b51961c..0000000 --- a/kvm-ui-clipboard-add-asserts-for-update-and-request.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 6e4f68e9ba3fe75ca6f200f189f96bb402f0ee8e Mon Sep 17 00:00:00 2001 -From: Fiona Ebner -Date: Wed, 24 Jan 2024 11:57:49 +0100 -Subject: [PATCH 02/20] ui/clipboard: add asserts for update and request -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Jon Maloy -RH-MergeRequest: 228: ui/clipboard: mark type as not available when there is no data -RH-Jira: RHEL-19629 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Gerd Hoffmann -RH-Commit: [2/2] 176b4b835fd8aa226f2fa93fd334b9384080cf21 (jmaloy/jmaloy-qemu-kvm-2) - -JIRA: https://issues.redhat.com/browse/RHEL-19629 -CVE: CVE-2023-6683 -Upstream: Merged - -ui/clipboard: add asserts for update and request - -commit 9c416582611b7495bdddb4c5456c7acb64b78938 -Author: Fiona Ebner -Date: Wed Jan 24 11:57:49 2024 +0100 - - ui/clipboard: add asserts for update and request - - Should an issue like CVE-2023-6683 ever appear again in the future, - it will be more obvious which assumption was violated. - - Suggested-by: Marc-André Lureau - Signed-off-by: Fiona Ebner - Reviewed-by: Marc-André Lureau - Message-ID: <20240124105749.204610-2-f.ebner@proxmox.com> - -Signed-off-by: Jon Maloy ---- - ui/clipboard.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/ui/clipboard.c b/ui/clipboard.c -index b3f6fa3c9e..4264884a6c 100644 ---- a/ui/clipboard.c -+++ b/ui/clipboard.c -@@ -65,12 +65,24 @@ bool qemu_clipboard_check_serial(QemuClipboardInfo *info, bool client) - - void qemu_clipboard_update(QemuClipboardInfo *info) - { -+ uint32_t type; - QemuClipboardNotify notify = { - .type = QEMU_CLIPBOARD_UPDATE_INFO, - .info = info, - }; - assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT); - -+ for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) { -+ /* -+ * If data is missing, the clipboard owner's 'request' callback needs to -+ * be set. Otherwise, there is no way to get the clipboard data and -+ * qemu_clipboard_request() cannot be called. -+ */ -+ if (info->types[type].available && !info->types[type].data) { -+ assert(info->owner && info->owner->request); -+ } -+ } -+ - notifier_list_notify(&clipboard_notifiers, ¬ify); - - if (cbinfo[info->selection] != info) { -@@ -132,6 +144,8 @@ void qemu_clipboard_request(QemuClipboardInfo *info, - !info->owner) - return; - -+ assert(info->owner->request); -+ - info->types[type].requested = true; - info->owner->request(info, type); - } --- -2.39.3 - diff --git a/kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch b/kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch deleted file mode 100644 index 00c9369..0000000 --- a/kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 097516bef2993d917e76d92066ca2eb067e45394 Mon Sep 17 00:00:00 2001 -From: Fiona Ebner -Date: Wed, 24 Jan 2024 11:57:48 +0100 -Subject: [PATCH 01/20] ui/clipboard: mark type as not available when there is - no data -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Jon Maloy -RH-MergeRequest: 228: ui/clipboard: mark type as not available when there is no data -RH-Jira: RHEL-19629 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Gerd Hoffmann -RH-Commit: [1/2] 74ded03d6376f9693733d673502219f76eab7099 (jmaloy/jmaloy-qemu-kvm-2) - -JIRA: https://issues.redhat.com/browse/RHEL-19629 -CVE: CVE-2023-6683 -Upstream: Merged - -commit 405484b29f6548c7b86549b0f961b906337aa68a -Author: Fiona Ebner -Date: Wed Jan 24 11:57:48 2024 +0100 - - ui/clipboard: mark type as not available when there is no data - - With VNC, a client can send a non-extended VNC_MSG_CLIENT_CUT_TEXT - message with len=0. In qemu_clipboard_set_data(), the clipboard info - will be updated setting data to NULL (because g_memdup(data, size) - returns NULL when size is 0). If the client does not set the - VNC_ENCODING_CLIPBOARD_EXT feature when setting up the encodings, then - the 'request' callback for the clipboard peer is not initialized. - Later, because data is NULL, qemu_clipboard_request() can be reached - via vdagent_chr_write() and vdagent_clipboard_recv_request() and - there, the clipboard owner's 'request' callback will be attempted to - be called, but that is a NULL pointer. - - In particular, this can happen when using the KRDC (22.12.3) VNC - client. - - Another scenario leading to the same issue is with two clients (say - noVNC and KRDC): - - The noVNC client sets the extension VNC_FEATURE_CLIPBOARD_EXT and - initializes its cbpeer. - - The KRDC client does not, but triggers a vnc_client_cut_text() (note - it's not the _ext variant)). There, a new clipboard info with it as - the 'owner' is created and via qemu_clipboard_set_data() is called, - which in turn calls qemu_clipboard_update() with that info. - - In qemu_clipboard_update(), the notifier for the noVNC client will be - called, i.e. vnc_clipboard_notify() and also set vs->cbinfo for the - noVNC client. The 'owner' in that clipboard info is the clipboard peer - for the KRDC client, which did not initialize the 'request' function. - That sounds correct to me, it is the owner of that clipboard info. - - Then when noVNC sends a VNC_MSG_CLIENT_CUT_TEXT message (it did set - the VNC_FEATURE_CLIPBOARD_EXT feature correctly, so a check for it - passes), that clipboard info is passed to qemu_clipboard_request() and - the original segfault still happens. - - Fix the issue by handling updates with size 0 differently. In - particular, mark in the clipboard info that the type is not available. - - While at it, switch to g_memdup2(), because g_memdup() is deprecated. - - Cc: qemu-stable@nongnu.org - Fixes: CVE-2023-6683 - Reported-by: Markus Frank - Suggested-by: Marc-André Lureau - Signed-off-by: Fiona Ebner - Reviewed-by: Marc-André Lureau - Tested-by: Markus Frank - Message-ID: <20240124105749.204610-1-f.ebner@proxmox.com> - -Signed-off-by: Jon Maloy ---- - ui/clipboard.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/ui/clipboard.c b/ui/clipboard.c -index 3d14bffaf8..b3f6fa3c9e 100644 ---- a/ui/clipboard.c -+++ b/ui/clipboard.c -@@ -163,9 +163,15 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer, - } - - g_free(info->types[type].data); -- info->types[type].data = g_memdup(data, size); -- info->types[type].size = size; -- info->types[type].available = true; -+ if (size) { -+ info->types[type].data = g_memdup2(data, size); -+ info->types[type].size = size; -+ info->types[type].available = true; -+ } else { -+ info->types[type].data = NULL; -+ info->types[type].size = 0; -+ info->types[type].available = false; -+ } - - if (update) { - qemu_clipboard_update(info); --- -2.39.3 - diff --git a/kvm-util-char_dev-Add-open_cdev.patch b/kvm-util-char_dev-Add-open_cdev.patch deleted file mode 100644 index 1f1e870..0000000 --- a/kvm-util-char_dev-Add-open_cdev.patch +++ /dev/null @@ -1,175 +0,0 @@ -From de167878ec4ca159cc6def5134c91c5fe9b5ab96 Mon Sep 17 00:00:00 2001 -From: Yi Liu -Date: Tue, 21 Nov 2023 16:44:01 +0800 -Subject: [PATCH 022/101] util/char_dev: Add open_cdev() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [21/67] 72bf9ec3ccc9959626235bd270ec84caa4cee435 (eauger1/centos-qemu-kvm) - -/dev/vfio/devices/vfioX may not exist. In that case it is still possible -to open /dev/char/$major:$minor instead. Add helper function to abstract -the cdev open. - -Suggested-by: Jason Gunthorpe -Signed-off-by: Yi Liu -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Auger -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit d6b5c4c1b516a8176b74ec35a0af8cf89b04b6c1) -Signed-off-by: Eric Auger ---- - MAINTAINERS | 2 + - include/qemu/chardev_open.h | 16 ++++++++ - util/chardev_open.c | 81 +++++++++++++++++++++++++++++++++++++ - util/meson.build | 1 + - 4 files changed, 100 insertions(+) - create mode 100644 include/qemu/chardev_open.h - create mode 100644 util/chardev_open.c - -diff --git a/MAINTAINERS b/MAINTAINERS -index a5a446914a..ca70bb4e64 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2174,6 +2174,8 @@ M: Zhenzhong Duan - S: Supported - F: backends/iommufd.c - F: include/sysemu/iommufd.h -+F: include/qemu/chardev_open.h -+F: util/chardev_open.c - - vhost - M: Michael S. Tsirkin -diff --git a/include/qemu/chardev_open.h b/include/qemu/chardev_open.h -new file mode 100644 -index 0000000000..64e8fcfdcb ---- /dev/null -+++ b/include/qemu/chardev_open.h -@@ -0,0 +1,16 @@ -+/* -+ * QEMU Chardev Helper -+ * -+ * Copyright (C) 2023 Intel Corporation. -+ * -+ * Authors: Yi Liu -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2. See -+ * the COPYING file in the top-level directory. -+ */ -+ -+#ifndef QEMU_CHARDEV_OPEN_H -+#define QEMU_CHARDEV_OPEN_H -+ -+int open_cdev(const char *devpath, dev_t cdev); -+#endif -diff --git a/util/chardev_open.c b/util/chardev_open.c -new file mode 100644 -index 0000000000..f776429788 ---- /dev/null -+++ b/util/chardev_open.c -@@ -0,0 +1,81 @@ -+/* -+ * Copyright (c) 2019, Mellanox Technologies. All rights reserved. -+ * Copyright (C) 2023 Intel Corporation. -+ * -+ * This software is available to you under a choice of one of two -+ * licenses. You may choose to be licensed under the terms of the GNU -+ * General Public License (GPL) Version 2, available from the file -+ * COPYING in the main directory of this source tree, or the -+ * OpenIB.org BSD license below: -+ * -+ * Redistribution and use in source and binary forms, with or -+ * without modification, are permitted provided that the following -+ * conditions are met: -+ * -+ * - Redistributions of source code must retain the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer. -+ * -+ * - Redistributions in binary form must reproduce the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer in the documentation and/or other materials -+ * provided with the distribution. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -+ * SOFTWARE. -+ * -+ * Authors: Yi Liu -+ * -+ * Copied from -+ * https://github.com/linux-rdma/rdma-core/blob/master/util/open_cdev.c -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/chardev_open.h" -+ -+static int open_cdev_internal(const char *path, dev_t cdev) -+{ -+ struct stat st; -+ int fd; -+ -+ fd = qemu_open_old(path, O_RDWR); -+ if (fd == -1) { -+ return -1; -+ } -+ if (fstat(fd, &st) || !S_ISCHR(st.st_mode) || -+ (cdev != 0 && st.st_rdev != cdev)) { -+ close(fd); -+ return -1; -+ } -+ return fd; -+} -+ -+static int open_cdev_robust(dev_t cdev) -+{ -+ g_autofree char *devpath = NULL; -+ -+ /* -+ * This assumes that udev is being used and is creating the /dev/char/ -+ * symlinks. -+ */ -+ devpath = g_strdup_printf("/dev/char/%u:%u", major(cdev), minor(cdev)); -+ return open_cdev_internal(devpath, cdev); -+} -+ -+int open_cdev(const char *devpath, dev_t cdev) -+{ -+ int fd; -+ -+ fd = open_cdev_internal(devpath, cdev); -+ if (fd == -1 && cdev != 0) { -+ return open_cdev_robust(cdev); -+ } -+ return fd; -+} -diff --git a/util/meson.build b/util/meson.build -index c2322ef6e7..174c133368 100644 ---- a/util/meson.build -+++ b/util/meson.build -@@ -108,6 +108,7 @@ if have_block - util_ss.add(files('filemonitor-stub.c')) - endif - util_ss.add(when: 'CONFIG_LINUX', if_true: files('vfio-helpers.c')) -+ util_ss.add(when: 'CONFIG_LINUX', if_true: files('chardev_open.c')) - endif - - if cpu == 'aarch64' --- -2.39.3 - diff --git a/kvm-vfio-Introduce-a-helper-function-to-initialize-VFIOD.patch b/kvm-vfio-Introduce-a-helper-function-to-initialize-VFIOD.patch deleted file mode 100644 index 040288f..0000000 --- a/kvm-vfio-Introduce-a-helper-function-to-initialize-VFIOD.patch +++ /dev/null @@ -1,154 +0,0 @@ -From f554328f6f4702743af71befcb83c25c36e4fa4d Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:25 +0800 -Subject: [PATCH 046/101] vfio: Introduce a helper function to initialize - VFIODevice -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [45/67] 73225f394540bf5aeb70c0bdb89771f19a6d286d (eauger1/centos-qemu-kvm) - -Introduce a helper function to replace the common code to initialize -VFIODevice in pci, platform, ap and ccw VFIO device. - -No functional change intended. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 6106a329141af7d47bdc3346ce9820d4714e0e5d) -Signed-off-by: Eric Auger ---- - hw/vfio/ap.c | 8 ++------ - hw/vfio/ccw.c | 8 ++------ - hw/vfio/helpers.c | 11 +++++++++++ - hw/vfio/pci.c | 6 ++---- - hw/vfio/platform.c | 6 ++---- - include/hw/vfio/vfio-common.h | 2 ++ - 6 files changed, 21 insertions(+), 20 deletions(-) - -diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c -index 95fe7cd98b..e157aa1ff7 100644 ---- a/hw/vfio/ap.c -+++ b/hw/vfio/ap.c -@@ -226,18 +226,14 @@ static void vfio_ap_instance_init(Object *obj) - VFIOAPDevice *vapdev = VFIO_AP_DEVICE(obj); - VFIODevice *vbasedev = &vapdev->vdev; - -- vbasedev->type = VFIO_DEVICE_TYPE_AP; -- vbasedev->ops = &vfio_ap_ops; -- vbasedev->dev = DEVICE(vapdev); -- vbasedev->fd = -1; -- - /* - * vfio-ap devices operate in a way compatible with discarding of - * memory in RAM blocks, as no pages are pinned in the host. - * This needs to be set before vfio_get_device() for vfio common to - * handle ram_block_discard_disable(). - */ -- vbasedev->ram_block_discard_allowed = true; -+ vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_AP, &vfio_ap_ops, -+ DEVICE(vapdev), true); - } - - #ifdef CONFIG_IOMMUFD -diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c -index 6305a4c1b8..90e4a53437 100644 ---- a/hw/vfio/ccw.c -+++ b/hw/vfio/ccw.c -@@ -683,11 +683,6 @@ static void vfio_ccw_instance_init(Object *obj) - VFIOCCWDevice *vcdev = VFIO_CCW(obj); - VFIODevice *vbasedev = &vcdev->vdev; - -- vbasedev->type = VFIO_DEVICE_TYPE_CCW; -- vbasedev->ops = &vfio_ccw_ops; -- vbasedev->dev = DEVICE(vcdev); -- vbasedev->fd = -1; -- - /* - * All vfio-ccw devices are believed to operate in a way compatible with - * discarding of memory in RAM blocks, ie. pages pinned in the host are -@@ -696,7 +691,8 @@ static void vfio_ccw_instance_init(Object *obj) - * needs to be set before vfio_get_device() for vfio common to handle - * ram_block_discard_disable(). - */ -- vbasedev->ram_block_discard_allowed = true; -+ vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_CCW, &vfio_ccw_ops, -+ DEVICE(vcdev), true); - } - - #ifdef CONFIG_IOMMUFD -diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c -index 3592c3d54e..6789870802 100644 ---- a/hw/vfio/helpers.c -+++ b/hw/vfio/helpers.c -@@ -652,3 +652,14 @@ void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp) - } - vbasedev->fd = fd; - } -+ -+void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops, -+ DeviceState *dev, bool ram_discard) -+{ -+ vbasedev->type = type; -+ vbasedev->ops = ops; -+ vbasedev->dev = dev; -+ vbasedev->fd = -1; -+ -+ vbasedev->ram_block_discard_allowed = ram_discard; -+} -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 3f5900cc46..83c3238608 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -3353,10 +3353,8 @@ static void vfio_instance_init(Object *obj) - vdev->host.slot = ~0U; - vdev->host.function = ~0U; - -- vbasedev->type = VFIO_DEVICE_TYPE_PCI; -- vbasedev->ops = &vfio_pci_ops; -- vbasedev->dev = DEVICE(vdev); -- vbasedev->fd = -1; -+ vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_PCI, &vfio_pci_ops, -+ DEVICE(vdev), false); - - vdev->nv_gpudirect_clique = 0xFF; - -diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c -index 506eb8193f..a8d9b7da63 100644 ---- a/hw/vfio/platform.c -+++ b/hw/vfio/platform.c -@@ -657,10 +657,8 @@ static void vfio_platform_instance_init(Object *obj) - VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(obj); - VFIODevice *vbasedev = &vdev->vbasedev; - -- vbasedev->type = VFIO_DEVICE_TYPE_PLATFORM; -- vbasedev->ops = &vfio_platform_ops; -- vbasedev->dev = DEVICE(vdev); -- vbasedev->fd = -1; -+ vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_PLATFORM, &vfio_platform_ops, -+ DEVICE(vdev), false); - } - - #ifdef CONFIG_IOMMUFD -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index efcba19f66..b8aa8a5495 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -257,4 +257,6 @@ int vfio_get_dirty_bitmap(const VFIOContainerBase *bcontainer, uint64_t iova, - /* Returns 0 on success, or a negative errno. */ - int vfio_device_get_name(VFIODevice *vbasedev, Error **errp); - void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp); -+void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops, -+ DeviceState *dev, bool ram_discard); - #endif /* HW_VFIO_VFIO_COMMON_H */ --- -2.39.3 - diff --git a/kvm-vfio-Introduce-base-object-for-VFIOContainer-and-tar.patch b/kvm-vfio-Introduce-base-object-for-VFIOContainer-and-tar.patch deleted file mode 100644 index d41e8fb..0000000 --- a/kvm-vfio-Introduce-base-object-for-VFIOContainer-and-tar.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 7f392385d1b865904eae4b6681e3e7a87eb3af3d Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:27 +0800 -Subject: [PATCH 002/101] vfio: Introduce base object for VFIOContainer and - targeted interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [1/67] e63af50c2cb94f286b2d91f58c2d19dd862e019d (eauger1/centos-qemu-kvm) - -Introduce a dumb VFIOContainerBase object and its targeted interface. -This is willingly not a QOM object because we don't want it to be -visible from the user interface. The VFIOContainerBase will be -smoothly populated in subsequent patches as well as interfaces. - -No functional change intended. - -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Yi Sun -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit f61dddd73232e3d82d560d1e1bca120446021f2f) -Signed-off-by: Eric Auger ---- - include/hw/vfio/vfio-common.h | 8 ++--- - include/hw/vfio/vfio-container-base.h | 50 +++++++++++++++++++++++++++ - 2 files changed, 52 insertions(+), 6 deletions(-) - create mode 100644 include/hw/vfio/vfio-container-base.h - -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index a4a22accb9..586d153c12 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -30,6 +30,7 @@ - #include - #endif - #include "sysemu/sysemu.h" -+#include "hw/vfio/vfio-container-base.h" - - #define VFIO_MSG_PREFIX "vfio %s: " - -@@ -81,6 +82,7 @@ typedef struct VFIOAddressSpace { - struct VFIOGroup; - - typedef struct VFIOContainer { -+ VFIOContainerBase bcontainer; - VFIOAddressSpace *space; - int fd; /* /dev/vfio/vfio, empowered by the attached groups */ - MemoryListener listener; -@@ -201,12 +203,6 @@ typedef struct VFIODisplay { - } dmabuf; - } VFIODisplay; - --typedef struct { -- unsigned long *bitmap; -- hwaddr size; -- hwaddr pages; --} VFIOBitmap; -- - VFIOAddressSpace *vfio_get_address_space(AddressSpace *as); - void vfio_put_address_space(VFIOAddressSpace *space); - bool vfio_devices_all_running_and_saving(VFIOContainer *container); -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -new file mode 100644 -index 0000000000..1d6daaea5d ---- /dev/null -+++ b/include/hw/vfio/vfio-container-base.h -@@ -0,0 +1,50 @@ -+/* -+ * VFIO BASE CONTAINER -+ * -+ * Copyright (C) 2023 Intel Corporation. -+ * Copyright Red Hat, Inc. 2023 -+ * -+ * Authors: Yi Liu -+ * Eric Auger -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+ -+#ifndef HW_VFIO_VFIO_CONTAINER_BASE_H -+#define HW_VFIO_VFIO_CONTAINER_BASE_H -+ -+#include "exec/memory.h" -+ -+typedef struct VFIODevice VFIODevice; -+typedef struct VFIOIOMMUOps VFIOIOMMUOps; -+ -+typedef struct { -+ unsigned long *bitmap; -+ hwaddr size; -+ hwaddr pages; -+} VFIOBitmap; -+ -+/* -+ * This is the base object for vfio container backends -+ */ -+typedef struct VFIOContainerBase { -+ const VFIOIOMMUOps *ops; -+} VFIOContainerBase; -+ -+struct VFIOIOMMUOps { -+ /* basic feature */ -+ int (*dma_map)(VFIOContainerBase *bcontainer, -+ hwaddr iova, ram_addr_t size, -+ void *vaddr, bool readonly); -+ int (*dma_unmap)(VFIOContainerBase *bcontainer, -+ hwaddr iova, ram_addr_t size, -+ IOMMUTLBEntry *iotlb); -+ int (*attach_device)(const char *name, VFIODevice *vbasedev, -+ AddressSpace *as, Error **errp); -+ void (*detach_device)(VFIODevice *vbasedev); -+ /* migration feature */ -+ int (*set_dirty_page_tracking)(VFIOContainerBase *bcontainer, bool start); -+ int (*query_dirty_bitmap)(VFIOContainerBase *bcontainer, VFIOBitmap *vbmap, -+ hwaddr iova, hwaddr size); -+}; -+#endif /* HW_VFIO_VFIO_CONTAINER_BASE_H */ --- -2.39.3 - diff --git a/kvm-vfio-Make-VFIOContainerBase-poiner-parameter-const-i.patch b/kvm-vfio-Make-VFIOContainerBase-poiner-parameter-const-i.patch deleted file mode 100644 index 03fb220..0000000 --- a/kvm-vfio-Make-VFIOContainerBase-poiner-parameter-const-i.patch +++ /dev/null @@ -1,276 +0,0 @@ -From 84b15fad1af781d06d0206d362de0801d7a18d0b Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:17 +0800 -Subject: [PATCH 038/101] vfio: Make VFIOContainerBase poiner parameter const - in VFIOIOMMUOps callbacks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [37/67] 95eb9edc7fcfefbd4b075f6f04941ed4a19ff87d (eauger1/centos-qemu-kvm) - -Some of the callbacks in VFIOIOMMUOps pass VFIOContainerBase poiner, -those callbacks only need read access to the sub object of VFIOContainerBase. -So make VFIOContainerBase, VFIOContainer and VFIOIOMMUFDContainer as const -in these callbacks. - -Local functions called by those callbacks also need same changes to avoid -build error. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Auger -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 4517c33c31d392f08fa96a9db911da1e3507be94) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 9 +++---- - hw/vfio/container-base.c | 2 +- - hw/vfio/container.c | 34 ++++++++++++++------------- - hw/vfio/iommufd.c | 8 +++---- - include/hw/vfio/vfio-common.h | 12 ++++++---- - include/hw/vfio/vfio-container-base.h | 12 ++++++---- - 6 files changed, 42 insertions(+), 35 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 6569732b7a..08a3e57672 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -204,7 +204,7 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainerBase *bcontainer) - return true; - } - --bool vfio_devices_all_device_dirty_tracking(VFIOContainerBase *bcontainer) -+bool vfio_devices_all_device_dirty_tracking(const VFIOContainerBase *bcontainer) - { - VFIODevice *vbasedev; - -@@ -221,7 +221,8 @@ bool vfio_devices_all_device_dirty_tracking(VFIOContainerBase *bcontainer) - * Check if all VFIO devices are running and migration is active, which is - * essentially equivalent to the migration being in pre-copy phase. - */ --bool vfio_devices_all_running_and_mig_active(VFIOContainerBase *bcontainer) -+bool -+vfio_devices_all_running_and_mig_active(const VFIOContainerBase *bcontainer) - { - VFIODevice *vbasedev; - -@@ -1139,7 +1140,7 @@ static int vfio_device_dma_logging_report(VFIODevice *vbasedev, hwaddr iova, - return 0; - } - --int vfio_devices_query_dirty_bitmap(VFIOContainerBase *bcontainer, -+int vfio_devices_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, hwaddr iova, - hwaddr size) - { -@@ -1162,7 +1163,7 @@ int vfio_devices_query_dirty_bitmap(VFIOContainerBase *bcontainer, - return 0; - } - --int vfio_get_dirty_bitmap(VFIOContainerBase *bcontainer, uint64_t iova, -+int vfio_get_dirty_bitmap(const VFIOContainerBase *bcontainer, uint64_t iova, - uint64_t size, ram_addr_t ram_addr) - { - bool all_device_dirty_tracking = -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index eee2dcfe76..1ffd25bbfa 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -63,7 +63,7 @@ int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, - return bcontainer->ops->set_dirty_page_tracking(bcontainer, start); - } - --int vfio_container_query_dirty_bitmap(VFIOContainerBase *bcontainer, -+int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, - hwaddr iova, hwaddr size) - { -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 1dbf9b9a17..b22feb8ded 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -61,11 +61,11 @@ static int vfio_ram_block_discard_disable(VFIOContainer *container, bool state) - } - } - --static int vfio_dma_unmap_bitmap(VFIOContainer *container, -+static int vfio_dma_unmap_bitmap(const VFIOContainer *container, - hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb) - { -- VFIOContainerBase *bcontainer = &container->bcontainer; -+ const VFIOContainerBase *bcontainer = &container->bcontainer; - struct vfio_iommu_type1_dma_unmap *unmap; - struct vfio_bitmap *bitmap; - VFIOBitmap vbmap; -@@ -117,11 +117,12 @@ unmap_exit: - /* - * DMA - Mapping and unmapping for the "type1" IOMMU interface used on x86 - */ --static int vfio_legacy_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, -- ram_addr_t size, IOMMUTLBEntry *iotlb) -+static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer, -+ hwaddr iova, ram_addr_t size, -+ IOMMUTLBEntry *iotlb) - { -- VFIOContainer *container = container_of(bcontainer, VFIOContainer, -- bcontainer); -+ const VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - struct vfio_iommu_type1_dma_unmap unmap = { - .argsz = sizeof(unmap), - .flags = 0, -@@ -174,11 +175,11 @@ static int vfio_legacy_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, - return 0; - } - --static int vfio_legacy_dma_map(VFIOContainerBase *bcontainer, hwaddr iova, -+static int vfio_legacy_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova, - ram_addr_t size, void *vaddr, bool readonly) - { -- VFIOContainer *container = container_of(bcontainer, VFIOContainer, -- bcontainer); -+ const VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - struct vfio_iommu_type1_dma_map map = { - .argsz = sizeof(map), - .flags = VFIO_DMA_MAP_FLAG_READ, -@@ -207,11 +208,12 @@ static int vfio_legacy_dma_map(VFIOContainerBase *bcontainer, hwaddr iova, - return -errno; - } - --static int vfio_legacy_set_dirty_page_tracking(VFIOContainerBase *bcontainer, -- bool start) -+static int -+vfio_legacy_set_dirty_page_tracking(const VFIOContainerBase *bcontainer, -+ bool start) - { -- VFIOContainer *container = container_of(bcontainer, VFIOContainer, -- bcontainer); -+ const VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - int ret; - struct vfio_iommu_type1_dirty_bitmap dirty = { - .argsz = sizeof(dirty), -@@ -233,12 +235,12 @@ static int vfio_legacy_set_dirty_page_tracking(VFIOContainerBase *bcontainer, - return ret; - } - --static int vfio_legacy_query_dirty_bitmap(VFIOContainerBase *bcontainer, -+static int vfio_legacy_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, - hwaddr iova, hwaddr size) - { -- VFIOContainer *container = container_of(bcontainer, VFIOContainer, -- bcontainer); -+ const VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - struct vfio_iommu_type1_dirty_bitmap *dbitmap; - struct vfio_iommu_type1_dirty_bitmap_get *range; - int ret; -diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c -index 5accd26484..87a561c545 100644 ---- a/hw/vfio/iommufd.c -+++ b/hw/vfio/iommufd.c -@@ -26,10 +26,10 @@ - #include "qemu/chardev_open.h" - #include "pci.h" - --static int iommufd_cdev_map(VFIOContainerBase *bcontainer, hwaddr iova, -+static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova, - ram_addr_t size, void *vaddr, bool readonly) - { -- VFIOIOMMUFDContainer *container = -+ const VFIOIOMMUFDContainer *container = - container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); - - return iommufd_backend_map_dma(container->be, -@@ -37,11 +37,11 @@ static int iommufd_cdev_map(VFIOContainerBase *bcontainer, hwaddr iova, - iova, size, vaddr, readonly); - } - --static int iommufd_cdev_unmap(VFIOContainerBase *bcontainer, -+static int iommufd_cdev_unmap(const VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb) - { -- VFIOIOMMUFDContainer *container = -+ const VFIOIOMMUFDContainer *container = - container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); - - /* TODO: Handle dma_unmap_bitmap with iotlb args (migration) */ -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 697bf24a35..efcba19f66 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -244,13 +244,15 @@ bool vfio_migration_realize(VFIODevice *vbasedev, Error **errp); - void vfio_migration_exit(VFIODevice *vbasedev); - - int vfio_bitmap_alloc(VFIOBitmap *vbmap, hwaddr size); --bool vfio_devices_all_running_and_mig_active(VFIOContainerBase *bcontainer); --bool vfio_devices_all_device_dirty_tracking(VFIOContainerBase *bcontainer); --int vfio_devices_query_dirty_bitmap(VFIOContainerBase *bcontainer, -+bool -+vfio_devices_all_running_and_mig_active(const VFIOContainerBase *bcontainer); -+bool -+vfio_devices_all_device_dirty_tracking(const VFIOContainerBase *bcontainer); -+int vfio_devices_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, hwaddr iova, - hwaddr size); --int vfio_get_dirty_bitmap(VFIOContainerBase *bcontainer, uint64_t iova, -- uint64_t size, ram_addr_t ram_addr); -+int vfio_get_dirty_bitmap(const VFIOContainerBase *bcontainer, uint64_t iova, -+ uint64_t size, ram_addr_t ram_addr); - - /* Returns 0 on success, or a negative errno. */ - int vfio_device_get_name(VFIODevice *vbasedev, Error **errp); -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 45bb19c767..2ae297ccda 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -82,7 +82,7 @@ void vfio_container_del_section_window(VFIOContainerBase *bcontainer, - MemoryRegionSection *section); - int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, - bool start); --int vfio_container_query_dirty_bitmap(VFIOContainerBase *bcontainer, -+int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, - hwaddr iova, hwaddr size); - -@@ -93,18 +93,20 @@ void vfio_container_destroy(VFIOContainerBase *bcontainer); - - struct VFIOIOMMUOps { - /* basic feature */ -- int (*dma_map)(VFIOContainerBase *bcontainer, -+ int (*dma_map)(const VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - void *vaddr, bool readonly); -- int (*dma_unmap)(VFIOContainerBase *bcontainer, -+ int (*dma_unmap)(const VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb); - int (*attach_device)(const char *name, VFIODevice *vbasedev, - AddressSpace *as, Error **errp); - void (*detach_device)(VFIODevice *vbasedev); - /* migration feature */ -- int (*set_dirty_page_tracking)(VFIOContainerBase *bcontainer, bool start); -- int (*query_dirty_bitmap)(VFIOContainerBase *bcontainer, VFIOBitmap *vbmap, -+ int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer, -+ bool start); -+ int (*query_dirty_bitmap)(const VFIOContainerBase *bcontainer, -+ VFIOBitmap *vbmap, - hwaddr iova, hwaddr size); - /* PCI specific */ - int (*pci_hot_reset)(VFIODevice *vbasedev, bool single); --- -2.39.3 - diff --git a/kvm-vfio-ap-Allow-the-selection-of-a-given-iommu-backend.patch b/kvm-vfio-ap-Allow-the-selection-of-a-given-iommu-backend.patch deleted file mode 100644 index ffd8b9f..0000000 --- a/kvm-vfio-ap-Allow-the-selection-of-a-given-iommu-backend.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 57bdfc821d6f4b4f9c6b1ff05bf0114e5cabc77e Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:13 +0800 -Subject: [PATCH 034/101] vfio/ap: Allow the selection of a given iommu backend -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [33/67] a12bb86e5b627ccf246fb9ce60820595589ff8e5 (eauger1/centos-qemu-kvm) - -Now we support two types of iommu backends, let's add the capability -to select one of them. This depends on whether an iommufd object has -been linked with the vfio-ap device: - -if the user wants to use the legacy backend, it shall not -link the vfio-ap device with any iommufd object: - - -device vfio-ap,sysfsdev=/sys/bus/mdev/devices/XXX - -This is called the legacy mode/backend. - -If the user wants to use the iommufd backend (/dev/iommu) it -shall pass an iommufd object id in the vfio-ap device options: - - -object iommufd,id=iommufd0 - -device vfio-ap,sysfsdev=/sys/bus/mdev/devices/XXX,iommufd=iommufd0 - -Suggested-by: Alex Williamson -Signed-off-by: Zhenzhong Duan -Reviewed-by: Matthew Rosato -Reviewed-by: Cédric Le Goater -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 336f308958d598f3db351bb7d94cc57b4b2d448d) -Signed-off-by: Eric Auger ---- - hw/vfio/ap.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c -index bbf69ff55a..80629609ae 100644 ---- a/hw/vfio/ap.c -+++ b/hw/vfio/ap.c -@@ -11,10 +11,12 @@ - */ - - #include "qemu/osdep.h" -+#include CONFIG_DEVICES /* CONFIG_IOMMUFD */ - #include - #include - #include "qapi/error.h" - #include "hw/vfio/vfio-common.h" -+#include "sysemu/iommufd.h" - #include "hw/s390x/ap-device.h" - #include "qemu/error-report.h" - #include "qemu/event_notifier.h" -@@ -204,6 +206,10 @@ static void vfio_ap_unrealize(DeviceState *dev) - - static Property vfio_ap_properties[] = { - DEFINE_PROP_STRING("sysfsdev", VFIOAPDevice, vdev.sysfsdev), -+#ifdef CONFIG_IOMMUFD -+ DEFINE_PROP_LINK("iommufd", VFIOAPDevice, vdev.iommufd, -+ TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *), -+#endif - DEFINE_PROP_END_OF_LIST(), - }; - --- -2.39.3 - diff --git a/kvm-vfio-ap-Make-vfio-cdev-pre-openable-by-passing-a-fil.patch b/kvm-vfio-ap-Make-vfio-cdev-pre-openable-by-passing-a-fil.patch deleted file mode 100644 index 1055329..0000000 --- a/kvm-vfio-ap-Make-vfio-cdev-pre-openable-by-passing-a-fil.patch +++ /dev/null @@ -1,87 +0,0 @@ -From db09b7c60c01ee75d602261ee959a96fa0d89d68 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:14 +0800 -Subject: [PATCH 035/101] vfio/ap: Make vfio cdev pre-openable by passing a - file handle -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [34/67] aaafa6088a9b0302d53aa539f67792d02ea0f663 (eauger1/centos-qemu-kvm) - -This gives management tools like libvirt a chance to open the vfio -cdev with privilege and pass FD to qemu. This way qemu never needs -to have privilege to open a VFIO or iommu cdev node. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Matthew Rosato -Reviewed-by: Cédric Le Goater -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 5e7ba401b71d18544a3e44b2a58b9e63fd5148d5) -Signed-off-by: Eric Auger ---- - hw/vfio/ap.c | 23 ++++++++++++++++++++++- - 1 file changed, 22 insertions(+), 1 deletion(-) - -diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c -index 80629609ae..f180e4a32a 100644 ---- a/hw/vfio/ap.c -+++ b/hw/vfio/ap.c -@@ -160,7 +160,10 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp) - VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev); - VFIODevice *vbasedev = &vapdev->vdev; - -- vbasedev->name = g_path_get_basename(vbasedev->sysfsdev); -+ if (vfio_device_get_name(vbasedev, errp) < 0) { -+ return; -+ } -+ - vbasedev->ops = &vfio_ap_ops; - vbasedev->type = VFIO_DEVICE_TYPE_AP; - vbasedev->dev = dev; -@@ -230,11 +233,28 @@ static const VMStateDescription vfio_ap_vmstate = { - .unmigratable = 1, - }; - -+static void vfio_ap_instance_init(Object *obj) -+{ -+ VFIOAPDevice *vapdev = VFIO_AP_DEVICE(obj); -+ -+ vapdev->vdev.fd = -1; -+} -+ -+#ifdef CONFIG_IOMMUFD -+static void vfio_ap_set_fd(Object *obj, const char *str, Error **errp) -+{ -+ vfio_device_set_fd(&VFIO_AP_DEVICE(obj)->vdev, str, errp); -+} -+#endif -+ - static void vfio_ap_class_init(ObjectClass *klass, void *data) - { - DeviceClass *dc = DEVICE_CLASS(klass); - - device_class_set_props(dc, vfio_ap_properties); -+#ifdef CONFIG_IOMMUFD -+ object_class_property_add_str(klass, "fd", NULL, vfio_ap_set_fd); -+#endif - dc->vmsd = &vfio_ap_vmstate; - dc->desc = "VFIO-based AP device assignment"; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); -@@ -249,6 +269,7 @@ static const TypeInfo vfio_ap_info = { - .name = TYPE_VFIO_AP_DEVICE, - .parent = TYPE_AP_DEVICE, - .instance_size = sizeof(VFIOAPDevice), -+ .instance_init = vfio_ap_instance_init, - .class_init = vfio_ap_class_init, - }; - --- -2.39.3 - diff --git a/kvm-vfio-ap-Move-VFIODevice-initializations-in-vfio_ap_i.patch b/kvm-vfio-ap-Move-VFIODevice-initializations-in-vfio_ap_i.patch deleted file mode 100644 index ed60920..0000000 --- a/kvm-vfio-ap-Move-VFIODevice-initializations-in-vfio_ap_i.patch +++ /dev/null @@ -1,81 +0,0 @@ -From b8630ecb698e31311089ba4e224d5e2c08c8e665 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:23 +0800 -Subject: [PATCH 044/101] vfio/ap: Move VFIODevice initializations in - vfio_ap_instance_init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [43/67] 95a527f649b28c5c78903e99735107667e8468b1 (eauger1/centos-qemu-kvm) - -Some of the VFIODevice initializations is in vfio_ap_realize, -move all of them in vfio_ap_instance_init. - -No functional change intended. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Eric Farman -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit cbbcc2f1706aa1a08637142744d2f5f6515ac93f) -Signed-off-by: Eric Auger ---- - hw/vfio/ap.c | 26 +++++++++++++------------- - 1 file changed, 13 insertions(+), 13 deletions(-) - -diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c -index f180e4a32a..95fe7cd98b 100644 ---- a/hw/vfio/ap.c -+++ b/hw/vfio/ap.c -@@ -164,18 +164,6 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp) - return; - } - -- vbasedev->ops = &vfio_ap_ops; -- vbasedev->type = VFIO_DEVICE_TYPE_AP; -- vbasedev->dev = dev; -- -- /* -- * vfio-ap devices operate in a way compatible with discarding of -- * memory in RAM blocks, as no pages are pinned in the host. -- * This needs to be set before vfio_get_device() for vfio common to -- * handle ram_block_discard_disable(). -- */ -- vapdev->vdev.ram_block_discard_allowed = true; -- - ret = vfio_attach_device(vbasedev->name, vbasedev, - &address_space_memory, errp); - if (ret) { -@@ -236,8 +224,20 @@ static const VMStateDescription vfio_ap_vmstate = { - static void vfio_ap_instance_init(Object *obj) - { - VFIOAPDevice *vapdev = VFIO_AP_DEVICE(obj); -+ VFIODevice *vbasedev = &vapdev->vdev; - -- vapdev->vdev.fd = -1; -+ vbasedev->type = VFIO_DEVICE_TYPE_AP; -+ vbasedev->ops = &vfio_ap_ops; -+ vbasedev->dev = DEVICE(vapdev); -+ vbasedev->fd = -1; -+ -+ /* -+ * vfio-ap devices operate in a way compatible with discarding of -+ * memory in RAM blocks, as no pages are pinned in the host. -+ * This needs to be set before vfio_get_device() for vfio common to -+ * handle ram_block_discard_disable(). -+ */ -+ vbasedev->ram_block_discard_allowed = true; - } - - #ifdef CONFIG_IOMMUFD --- -2.39.3 - diff --git a/kvm-vfio-ccw-Allow-the-selection-of-a-given-iommu-backen.patch b/kvm-vfio-ccw-Allow-the-selection-of-a-given-iommu-backen.patch deleted file mode 100644 index ff64a91..0000000 --- a/kvm-vfio-ccw-Allow-the-selection-of-a-given-iommu-backen.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 732115c80eb0dd672925a0737e09643d8a889abd Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:15 +0800 -Subject: [PATCH 036/101] vfio/ccw: Allow the selection of a given iommu - backend -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [35/67] 1701de023a9f3b3f0420689bf851e11aee88800d (eauger1/centos-qemu-kvm) - -Now we support two types of iommu backends, let's add the capability -to select one of them. This depends on whether an iommufd object has -been linked with the vfio-ccw device: - -If the user wants to use the legacy backend, it shall not -link the vfio-ccw device with any iommufd object: - - -device vfio-ccw,sysfsdev=/sys/bus/mdev/devices/XXX - -This is called the legacy mode/backend. - -If the user wants to use the iommufd backend (/dev/iommu) it -shall pass an iommufd object id in the vfio-ccw device options: - - -object iommufd,id=iommufd0 - -device vfio-ccw,sysfsdev=/sys/bus/mdev/devices/XXX,iommufd=iommufd0 - -Suggested-by: Alex Williamson -Signed-off-by: Zhenzhong Duan -Reviewed-by: Matthew Rosato -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Farman -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit e70f971a6c1230138843d7ab82267e4a5aaf6bda) -Signed-off-by: Eric Auger ---- - hw/vfio/ccw.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c -index d857bb8d0f..d2d58bb677 100644 ---- a/hw/vfio/ccw.c -+++ b/hw/vfio/ccw.c -@@ -15,12 +15,14 @@ - */ - - #include "qemu/osdep.h" -+#include CONFIG_DEVICES /* CONFIG_IOMMUFD */ - #include - #include - #include - - #include "qapi/error.h" - #include "hw/vfio/vfio-common.h" -+#include "sysemu/iommufd.h" - #include "hw/s390x/s390-ccw.h" - #include "hw/s390x/vfio-ccw.h" - #include "hw/qdev-properties.h" -@@ -677,6 +679,10 @@ static void vfio_ccw_unrealize(DeviceState *dev) - static Property vfio_ccw_properties[] = { - DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev), - DEFINE_PROP_BOOL("force-orb-pfch", VFIOCCWDevice, force_orb_pfch, false), -+#ifdef CONFIG_IOMMUFD -+ DEFINE_PROP_LINK("iommufd", VFIOCCWDevice, vdev.iommufd, -+ TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *), -+#endif - DEFINE_PROP_END_OF_LIST(), - }; - --- -2.39.3 - diff --git a/kvm-vfio-ccw-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch b/kvm-vfio-ccw-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch deleted file mode 100644 index 6c91d85..0000000 --- a/kvm-vfio-ccw-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0ff08afdec19f4decaf750fa7d158e0ea498ff28 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:16 +0800 -Subject: [PATCH 037/101] vfio/ccw: Make vfio cdev pre-openable by passing a - file handle -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [36/67] cc0d8f51cffa5d5a7aebc2334b908b9877179ae7 (eauger1/centos-qemu-kvm) - -This gives management tools like libvirt a chance to open the vfio -cdev with privilege and pass FD to qemu. This way qemu never needs -to have privilege to open a VFIO or iommu cdev node. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Matthew Rosato -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Farman -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 909a6254edaa8d0b0e3f1c0a623862e73d1842e9) -Signed-off-by: Eric Auger ---- - hw/vfio/ccw.c | 25 ++++++++++++++++++++++--- - 1 file changed, 22 insertions(+), 3 deletions(-) - -diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c -index d2d58bb677..2afdf17dbe 100644 ---- a/hw/vfio/ccw.c -+++ b/hw/vfio/ccw.c -@@ -590,11 +590,12 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp) - } - } - -+ if (vfio_device_get_name(vbasedev, errp) < 0) { -+ return; -+ } -+ - vbasedev->ops = &vfio_ccw_ops; - vbasedev->type = VFIO_DEVICE_TYPE_CCW; -- vbasedev->name = g_strdup_printf("%x.%x.%04x", vcdev->cdev.hostid.cssid, -- vcdev->cdev.hostid.ssid, -- vcdev->cdev.hostid.devid); - vbasedev->dev = dev; - - /* -@@ -691,12 +692,29 @@ static const VMStateDescription vfio_ccw_vmstate = { - .unmigratable = 1, - }; - -+static void vfio_ccw_instance_init(Object *obj) -+{ -+ VFIOCCWDevice *vcdev = VFIO_CCW(obj); -+ -+ vcdev->vdev.fd = -1; -+} -+ -+#ifdef CONFIG_IOMMUFD -+static void vfio_ccw_set_fd(Object *obj, const char *str, Error **errp) -+{ -+ vfio_device_set_fd(&VFIO_CCW(obj)->vdev, str, errp); -+} -+#endif -+ - static void vfio_ccw_class_init(ObjectClass *klass, void *data) - { - DeviceClass *dc = DEVICE_CLASS(klass); - S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass); - - device_class_set_props(dc, vfio_ccw_properties); -+#ifdef CONFIG_IOMMUFD -+ object_class_property_add_str(klass, "fd", NULL, vfio_ccw_set_fd); -+#endif - dc->vmsd = &vfio_ccw_vmstate; - dc->desc = "VFIO-based subchannel assignment"; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); -@@ -714,6 +732,7 @@ static const TypeInfo vfio_ccw_info = { - .name = TYPE_VFIO_CCW, - .parent = TYPE_S390_CCW, - .instance_size = sizeof(VFIOCCWDevice), -+ .instance_init = vfio_ccw_instance_init, - .class_init = vfio_ccw_class_init, - }; - --- -2.39.3 - diff --git a/kvm-vfio-ccw-Move-VFIODevice-initializations-in-vfio_ccw.patch b/kvm-vfio-ccw-Move-VFIODevice-initializations-in-vfio_ccw.patch deleted file mode 100644 index 95b85f9..0000000 --- a/kvm-vfio-ccw-Move-VFIODevice-initializations-in-vfio_ccw.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 2ef1c050722115247962e3cd4d8fcf73727e597e Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:24 +0800 -Subject: [PATCH 045/101] vfio/ccw: Move VFIODevice initializations in - vfio_ccw_instance_init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [44/67] 3345ed58f491aba8fd51bcc172af267ae53e6c8c (eauger1/centos-qemu-kvm) - -Some of the VFIODevice initializations is in vfio_ccw_realize, -move all of them in vfio_ccw_instance_init. - -No functional change intended. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Eric Farman -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit c12b55ad6f9d3b4792b590e9211bd7319e4a2d70) -Signed-off-by: Eric Auger ---- - hw/vfio/ccw.c | 30 +++++++++++++++--------------- - 1 file changed, 15 insertions(+), 15 deletions(-) - -diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c -index 2afdf17dbe..6305a4c1b8 100644 ---- a/hw/vfio/ccw.c -+++ b/hw/vfio/ccw.c -@@ -594,20 +594,6 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp) - return; - } - -- vbasedev->ops = &vfio_ccw_ops; -- vbasedev->type = VFIO_DEVICE_TYPE_CCW; -- vbasedev->dev = dev; -- -- /* -- * All vfio-ccw devices are believed to operate in a way compatible with -- * discarding of memory in RAM blocks, ie. pages pinned in the host are -- * in the current working set of the guest driver and therefore never -- * overlap e.g., with pages available to the guest balloon driver. This -- * needs to be set before vfio_get_device() for vfio common to handle -- * ram_block_discard_disable(). -- */ -- vbasedev->ram_block_discard_allowed = true; -- - ret = vfio_attach_device(cdev->mdevid, vbasedev, - &address_space_memory, errp); - if (ret) { -@@ -695,8 +681,22 @@ static const VMStateDescription vfio_ccw_vmstate = { - static void vfio_ccw_instance_init(Object *obj) - { - VFIOCCWDevice *vcdev = VFIO_CCW(obj); -+ VFIODevice *vbasedev = &vcdev->vdev; -+ -+ vbasedev->type = VFIO_DEVICE_TYPE_CCW; -+ vbasedev->ops = &vfio_ccw_ops; -+ vbasedev->dev = DEVICE(vcdev); -+ vbasedev->fd = -1; - -- vcdev->vdev.fd = -1; -+ /* -+ * All vfio-ccw devices are believed to operate in a way compatible with -+ * discarding of memory in RAM blocks, ie. pages pinned in the host are -+ * in the current working set of the guest driver and therefore never -+ * overlap e.g., with pages available to the guest balloon driver. This -+ * needs to be set before vfio_get_device() for vfio common to handle -+ * ram_block_discard_disable(). -+ */ -+ vbasedev->ram_block_discard_allowed = true; - } - - #ifdef CONFIG_IOMMUFD --- -2.39.3 - diff --git a/kvm-vfio-common-Introduce-vfio_container_init-destroy-he.patch b/kvm-vfio-common-Introduce-vfio_container_init-destroy-he.patch deleted file mode 100644 index 8615b6d..0000000 --- a/kvm-vfio-common-Introduce-vfio_container_init-destroy-he.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 7de36998dd6177380e46b8c5f3a91c3fad75483c Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:30 +0800 -Subject: [PATCH 005/101] vfio/common: Introduce vfio_container_init/destroy - helper -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [4/67] 8287f687ef19cd84afede1e8f3b16ac3caf29a1d (eauger1/centos-qemu-kvm) - -This adds two helper functions vfio_container_init/destroy which will be -used by both legacy and iommufd containers to do base container specific -initialization and release. - -No functional change intended. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit ed2f7f80170251e7cdd2965a13ee97527d1fbec8) -Signed-off-by: Eric Auger ---- - hw/vfio/container-base.c | 9 +++++++++ - hw/vfio/container.c | 4 +++- - include/hw/vfio/vfio-container-base.h | 4 ++++ - 3 files changed, 16 insertions(+), 1 deletion(-) - -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 55d3a35fa4..e929435751 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -30,3 +30,12 @@ int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, - g_assert(bcontainer->ops->dma_unmap); - return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb); - } -+ -+void vfio_container_init(VFIOContainerBase *bcontainer, const VFIOIOMMUOps *ops) -+{ -+ bcontainer->ops = ops; -+} -+ -+void vfio_container_destroy(VFIOContainerBase *bcontainer) -+{ -+} -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index c04df26323..32a0251dd1 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -559,7 +559,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - QLIST_INIT(&container->giommu_list); - QLIST_INIT(&container->vrdl_list); - bcontainer = &container->bcontainer; -- bcontainer->ops = &vfio_legacy_ops; -+ vfio_container_init(bcontainer, &vfio_legacy_ops); - - ret = vfio_init_container(container, group->fd, errp); - if (ret) { -@@ -661,6 +661,7 @@ put_space_exit: - static void vfio_disconnect_container(VFIOGroup *group) - { - VFIOContainer *container = group->container; -+ VFIOContainerBase *bcontainer = &container->bcontainer; - - QLIST_REMOVE(group, container_next); - group->container = NULL; -@@ -695,6 +696,7 @@ static void vfio_disconnect_container(VFIOGroup *group) - QLIST_REMOVE(giommu, giommu_next); - g_free(giommu); - } -+ vfio_container_destroy(bcontainer); - - trace_vfio_disconnect_container(container->fd); - close(container->fd); -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 56b033f59f..577f52ccbc 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -38,6 +38,10 @@ int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb); - -+void vfio_container_init(VFIOContainerBase *bcontainer, -+ const VFIOIOMMUOps *ops); -+void vfio_container_destroy(VFIOContainerBase *bcontainer); -+ - struct VFIOIOMMUOps { - /* basic feature */ - int (*dma_map)(VFIOContainerBase *bcontainer, --- -2.39.3 - diff --git a/kvm-vfio-common-Move-giommu_list-in-base-container.patch b/kvm-vfio-common-Move-giommu_list-in-base-container.patch deleted file mode 100644 index eec555b..0000000 --- a/kvm-vfio-common-Move-giommu_list-in-base-container.patch +++ /dev/null @@ -1,221 +0,0 @@ -From 36f4005c3dbb4c8b63a975494c75281de51c25f9 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 2 Nov 2023 15:12:31 +0800 -Subject: [PATCH 006/101] vfio/common: Move giommu_list in base container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [5/67] ba5898e96c16c7f6e8108ae461b454d3c8c35404 (eauger1/centos-qemu-kvm) - -Move the giommu_list field in the base container and store -the base container in the VFIOGuestIOMMU. - -No functional change intended. - -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Yi Sun -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit dddf83ab99eb832c449249397a1c302c6ed746bf) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 17 +++++++++++------ - hw/vfio/container-base.c | 9 +++++++++ - hw/vfio/container.c | 8 -------- - include/hw/vfio/vfio-common.h | 9 --------- - include/hw/vfio/vfio-container-base.h | 9 +++++++++ - 5 files changed, 29 insertions(+), 23 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index e610771888..43580bcc43 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -292,7 +292,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, - static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - { - VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); -- VFIOContainerBase *bcontainer = &giommu->container->bcontainer; -+ VFIOContainerBase *bcontainer = giommu->bcontainer; - hwaddr iova = iotlb->iova + giommu->iommu_offset; - void *vaddr; - int ret; -@@ -569,6 +569,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); -+ VFIOContainerBase *bcontainer = &container->bcontainer; - hwaddr iova, end; - Int128 llend, llsize; - void *vaddr; -@@ -612,7 +613,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - giommu->iommu_mr = iommu_mr; - giommu->iommu_offset = section->offset_within_address_space - - section->offset_within_region; -- giommu->container = container; -+ giommu->bcontainer = bcontainer; - llend = int128_add(int128_make64(section->offset_within_region), - section->size); - llend = int128_sub(llend, int128_one()); -@@ -647,7 +648,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - g_free(giommu); - goto fail; - } -- QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next); -+ QLIST_INSERT_HEAD(&bcontainer->giommu_list, giommu, giommu_next); - memory_region_iommu_replay(giommu->iommu_mr, &giommu->n); - - return; -@@ -732,6 +733,7 @@ static void vfio_listener_region_del(MemoryListener *listener, - MemoryRegionSection *section) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); -+ VFIOContainerBase *bcontainer = &container->bcontainer; - hwaddr iova, end; - Int128 llend, llsize; - int ret; -@@ -744,7 +746,7 @@ static void vfio_listener_region_del(MemoryListener *listener, - if (memory_region_is_iommu(section->mr)) { - VFIOGuestIOMMU *giommu; - -- QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) { -+ QLIST_FOREACH(giommu, &bcontainer->giommu_list, giommu_next) { - if (MEMORY_REGION(giommu->iommu_mr) == section->mr && - giommu->n.start == section->offset_within_region) { - memory_region_unregister_iommu_notifier(section->mr, -@@ -1206,7 +1208,9 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - vfio_giommu_dirty_notifier *gdn = container_of(n, - vfio_giommu_dirty_notifier, n); - VFIOGuestIOMMU *giommu = gdn->giommu; -- VFIOContainer *container = giommu->container; -+ VFIOContainerBase *bcontainer = giommu->bcontainer; -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - hwaddr iova = iotlb->iova + giommu->iommu_offset; - ram_addr_t translated_addr; - int ret = -EINVAL; -@@ -1284,12 +1288,13 @@ static int vfio_sync_ram_discard_listener_dirty_bitmap(VFIOContainer *container, - static int vfio_sync_dirty_bitmap(VFIOContainer *container, - MemoryRegionSection *section) - { -+ VFIOContainerBase *bcontainer = &container->bcontainer; - ram_addr_t ram_addr; - - if (memory_region_is_iommu(section->mr)) { - VFIOGuestIOMMU *giommu; - -- QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) { -+ QLIST_FOREACH(giommu, &bcontainer->giommu_list, giommu_next) { - if (MEMORY_REGION(giommu->iommu_mr) == section->mr && - giommu->n.start == section->offset_within_region) { - Int128 llend; -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index e929435751..20bcb9669a 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -34,8 +34,17 @@ int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, - void vfio_container_init(VFIOContainerBase *bcontainer, const VFIOIOMMUOps *ops) - { - bcontainer->ops = ops; -+ QLIST_INIT(&bcontainer->giommu_list); - } - - void vfio_container_destroy(VFIOContainerBase *bcontainer) - { -+ VFIOGuestIOMMU *giommu, *tmp; -+ -+ QLIST_FOREACH_SAFE(giommu, &bcontainer->giommu_list, giommu_next, tmp) { -+ memory_region_unregister_iommu_notifier( -+ MEMORY_REGION(giommu->iommu_mr), &giommu->n); -+ QLIST_REMOVE(giommu, giommu_next); -+ g_free(giommu); -+ } - } -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 32a0251dd1..133d3c8f5c 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -556,7 +556,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - container->dirty_pages_supported = false; - container->dma_max_mappings = 0; - container->iova_ranges = NULL; -- QLIST_INIT(&container->giommu_list); - QLIST_INIT(&container->vrdl_list); - bcontainer = &container->bcontainer; - vfio_container_init(bcontainer, &vfio_legacy_ops); -@@ -686,16 +685,9 @@ static void vfio_disconnect_container(VFIOGroup *group) - - if (QLIST_EMPTY(&container->group_list)) { - VFIOAddressSpace *space = container->space; -- VFIOGuestIOMMU *giommu, *tmp; - - QLIST_REMOVE(container, next); - -- QLIST_FOREACH_SAFE(giommu, &container->giommu_list, giommu_next, tmp) { -- memory_region_unregister_iommu_notifier( -- MEMORY_REGION(giommu->iommu_mr), &giommu->n); -- QLIST_REMOVE(giommu, giommu_next); -- g_free(giommu); -- } - vfio_container_destroy(bcontainer); - - trace_vfio_disconnect_container(container->fd); -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 24a26345e5..6be082b8f2 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -95,7 +95,6 @@ typedef struct VFIOContainer { - uint64_t max_dirty_bitmap_size; - unsigned long pgsizes; - unsigned int dma_max_mappings; -- QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; - QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; -@@ -104,14 +103,6 @@ typedef struct VFIOContainer { - GList *iova_ranges; - } VFIOContainer; - --typedef struct VFIOGuestIOMMU { -- VFIOContainer *container; -- IOMMUMemoryRegion *iommu_mr; -- hwaddr iommu_offset; -- IOMMUNotifier n; -- QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; --} VFIOGuestIOMMU; -- - typedef struct VFIORamDiscardListener { - VFIOContainer *container; - MemoryRegion *mr; -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 577f52ccbc..a11aec5755 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -29,8 +29,17 @@ typedef struct { - */ - typedef struct VFIOContainerBase { - const VFIOIOMMUOps *ops; -+ QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; - } VFIOContainerBase; - -+typedef struct VFIOGuestIOMMU { -+ VFIOContainerBase *bcontainer; -+ IOMMUMemoryRegion *iommu_mr; -+ hwaddr iommu_offset; -+ IOMMUNotifier n; -+ QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; -+} VFIOGuestIOMMU; -+ - int vfio_container_dma_map(VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - void *vaddr, bool readonly); --- -2.39.3 - diff --git a/kvm-vfio-common-return-early-if-space-isn-t-empty.patch b/kvm-vfio-common-return-early-if-space-isn-t-empty.patch deleted file mode 100644 index 261807a..0000000 --- a/kvm-vfio-common-return-early-if-space-isn-t-empty.patch +++ /dev/null @@ -1,55 +0,0 @@ -From e9476ee64edd81fafd409fb3ceaad80668446bff Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:02 +0800 -Subject: [PATCH 023/101] vfio/common: return early if space isn't empty -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [22/67] 239c21ae7cddc8efabc041b9c7774f15b4964631 (eauger1/centos-qemu-kvm) - -This is a trivial optimization. If there is active container in space, -vfio_reset_handler will never be unregistered. So revert the check of -space->containers and return early. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Auger -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 1eae5b7bd3ddd03b5591e9122b011c6520064a5a) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 572ae7c934..934f4f5446 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1462,10 +1462,13 @@ VFIOAddressSpace *vfio_get_address_space(AddressSpace *as) - - void vfio_put_address_space(VFIOAddressSpace *space) - { -- if (QLIST_EMPTY(&space->containers)) { -- QLIST_REMOVE(space, list); -- g_free(space); -+ if (!QLIST_EMPTY(&space->containers)) { -+ return; - } -+ -+ QLIST_REMOVE(space, list); -+ g_free(space); -+ - if (QLIST_EMPTY(&vfio_address_spaces)) { - qemu_unregister_reset(vfio_reset_handler, NULL); - } --- -2.39.3 - diff --git a/kvm-vfio-container-Convert-functions-to-base-container.patch b/kvm-vfio-container-Convert-functions-to-base-container.patch deleted file mode 100644 index 62caf8a..0000000 --- a/kvm-vfio-container-Convert-functions-to-base-container.patch +++ /dev/null @@ -1,257 +0,0 @@ -From facad966c42b1ec38b12e45f2b84bd059542b60c Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 2 Nov 2023 15:12:35 +0800 -Subject: [PATCH 010/101] vfio/container: Convert functions to base container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [9/67] a0002d6e9cb0ca76e3e2f25208ecba22dd9f9a88 (eauger1/centos-qemu-kvm) - -In the prospect to get rid of VFIOContainer refs -in common.c lets convert misc functions to use the base -container object instead: - -vfio_devices_all_dirty_tracking -vfio_devices_all_device_dirty_tracking -vfio_devices_all_running_and_mig_active -vfio_devices_query_dirty_bitmap -vfio_get_dirty_bitmap - -Signed-off-by: Eric Auger -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit e1cac6b203f45b5322e831e8d50edfdf18609b09) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 42 +++++++++++++++-------------------- - hw/vfio/container.c | 6 ++--- - hw/vfio/trace-events | 2 +- - include/hw/vfio/vfio-common.h | 9 ++++---- - 4 files changed, 26 insertions(+), 33 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 9415395ed9..cf6618f6ed 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -177,9 +177,8 @@ bool vfio_device_state_is_precopy(VFIODevice *vbasedev) - migration->device_state == VFIO_DEVICE_STATE_PRE_COPY_P2P; - } - --static bool vfio_devices_all_dirty_tracking(VFIOContainer *container) -+static bool vfio_devices_all_dirty_tracking(VFIOContainerBase *bcontainer) - { -- VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - MigrationState *ms = migrate_get_current(); - -@@ -204,9 +203,8 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer *container) - return true; - } - --bool vfio_devices_all_device_dirty_tracking(VFIOContainer *container) -+bool vfio_devices_all_device_dirty_tracking(VFIOContainerBase *bcontainer) - { -- VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - - QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { -@@ -222,9 +220,8 @@ bool vfio_devices_all_device_dirty_tracking(VFIOContainer *container) - * Check if all VFIO devices are running and migration is active, which is - * essentially equivalent to the migration being in pre-copy phase. - */ --bool vfio_devices_all_running_and_mig_active(VFIOContainer *container) -+bool vfio_devices_all_running_and_mig_active(VFIOContainerBase *bcontainer) - { -- VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - - if (!migration_is_active(migrate_get_current())) { -@@ -1082,7 +1079,7 @@ static void vfio_listener_log_global_start(MemoryListener *listener) - VFIOContainer *container = container_of(listener, VFIOContainer, listener); - int ret; - -- if (vfio_devices_all_device_dirty_tracking(container)) { -+ if (vfio_devices_all_device_dirty_tracking(&container->bcontainer)) { - ret = vfio_devices_dma_logging_start(container); - } else { - ret = vfio_container_set_dirty_page_tracking(&container->bcontainer, -@@ -1101,7 +1098,7 @@ static void vfio_listener_log_global_stop(MemoryListener *listener) - VFIOContainer *container = container_of(listener, VFIOContainer, listener); - int ret = 0; - -- if (vfio_devices_all_device_dirty_tracking(container)) { -+ if (vfio_devices_all_device_dirty_tracking(&container->bcontainer)) { - vfio_devices_dma_logging_stop(container); - } else { - ret = vfio_container_set_dirty_page_tracking(&container->bcontainer, -@@ -1141,11 +1138,10 @@ static int vfio_device_dma_logging_report(VFIODevice *vbasedev, hwaddr iova, - return 0; - } - --int vfio_devices_query_dirty_bitmap(VFIOContainer *container, -+int vfio_devices_query_dirty_bitmap(VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, hwaddr iova, - hwaddr size) - { -- VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - int ret; - -@@ -1165,17 +1161,16 @@ int vfio_devices_query_dirty_bitmap(VFIOContainer *container, - return 0; - } - --int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, -+int vfio_get_dirty_bitmap(VFIOContainerBase *bcontainer, uint64_t iova, - uint64_t size, ram_addr_t ram_addr) - { - bool all_device_dirty_tracking = -- vfio_devices_all_device_dirty_tracking(container); -+ vfio_devices_all_device_dirty_tracking(bcontainer); - uint64_t dirty_pages; - VFIOBitmap vbmap; - int ret; - -- if (!container->bcontainer.dirty_pages_supported && -- !all_device_dirty_tracking) { -+ if (!bcontainer->dirty_pages_supported && !all_device_dirty_tracking) { - cpu_physical_memory_set_dirty_range(ram_addr, size, - tcg_enabled() ? DIRTY_CLIENTS_ALL : - DIRTY_CLIENTS_NOCODE); -@@ -1188,10 +1183,9 @@ int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - } - - if (all_device_dirty_tracking) { -- ret = vfio_devices_query_dirty_bitmap(container, &vbmap, iova, size); -+ ret = vfio_devices_query_dirty_bitmap(bcontainer, &vbmap, iova, size); - } else { -- ret = vfio_container_query_dirty_bitmap(&container->bcontainer, &vbmap, -- iova, size); -+ ret = vfio_container_query_dirty_bitmap(bcontainer, &vbmap, iova, size); - } - - if (ret) { -@@ -1201,8 +1195,7 @@ int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - dirty_pages = cpu_physical_memory_set_dirty_lebitmap(vbmap.bitmap, ram_addr, - vbmap.pages); - -- trace_vfio_get_dirty_bitmap(container->fd, iova, size, vbmap.size, -- ram_addr, dirty_pages); -+ trace_vfio_get_dirty_bitmap(iova, size, vbmap.size, ram_addr, dirty_pages); - out: - g_free(vbmap.bitmap); - -@@ -1236,8 +1229,8 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - - rcu_read_lock(); - if (vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL)) { -- ret = vfio_get_dirty_bitmap(container, iova, iotlb->addr_mask + 1, -- translated_addr); -+ ret = vfio_get_dirty_bitmap(&container->bcontainer, iova, -+ iotlb->addr_mask + 1, translated_addr); - if (ret) { - error_report("vfio_iommu_map_dirty_notify(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%s)", -@@ -1266,7 +1259,8 @@ static int vfio_ram_discard_get_dirty_bitmap(MemoryRegionSection *section, - * Sync the whole mapped region (spanning multiple individual mappings) - * in one go. - */ -- return vfio_get_dirty_bitmap(vrdl->container, iova, size, ram_addr); -+ return vfio_get_dirty_bitmap(&vrdl->container->bcontainer, iova, size, -+ ram_addr); - } - - static int vfio_sync_ram_discard_listener_dirty_bitmap(VFIOContainer *container, -@@ -1335,7 +1329,7 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container, - ram_addr = memory_region_get_ram_addr(section->mr) + - section->offset_within_region; - -- return vfio_get_dirty_bitmap(container, -+ return vfio_get_dirty_bitmap(&container->bcontainer, - REAL_HOST_PAGE_ALIGN(section->offset_within_address_space), - int128_get64(section->size), ram_addr); - } -@@ -1350,7 +1344,7 @@ static void vfio_listener_log_sync(MemoryListener *listener, - return; - } - -- if (vfio_devices_all_dirty_tracking(container)) { -+ if (vfio_devices_all_dirty_tracking(&container->bcontainer)) { - ret = vfio_sync_dirty_bitmap(container, section); - if (ret) { - error_report("vfio: Failed to sync dirty bitmap, err: %d (%s)", ret, -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 63a906de93..7bd81eab09 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -129,8 +129,8 @@ static int vfio_legacy_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, - bool need_dirty_sync = false; - int ret; - -- if (iotlb && vfio_devices_all_running_and_mig_active(container)) { -- if (!vfio_devices_all_device_dirty_tracking(container) && -+ if (iotlb && vfio_devices_all_running_and_mig_active(bcontainer)) { -+ if (!vfio_devices_all_device_dirty_tracking(bcontainer) && - container->bcontainer.dirty_pages_supported) { - return vfio_dma_unmap_bitmap(container, iova, size, iotlb); - } -@@ -162,7 +162,7 @@ static int vfio_legacy_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, - } - - if (need_dirty_sync) { -- ret = vfio_get_dirty_bitmap(container, iova, size, -+ ret = vfio_get_dirty_bitmap(bcontainer, iova, size, - iotlb->translated_addr); - if (ret) { - return ret; -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 9f7fedee98..08a1f9dfa4 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -117,7 +117,7 @@ vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Devic - vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]" - vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%08x" - vfio_legacy_dma_unmap_overflow_workaround(void) "" --vfio_get_dirty_bitmap(int fd, uint64_t iova, uint64_t size, uint64_t bitmap_size, uint64_t start, uint64_t dirty_pages) "container fd=%d, iova=0x%"PRIx64" size= 0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64" dirty_pages=%"PRIu64 -+vfio_get_dirty_bitmap(uint64_t iova, uint64_t size, uint64_t bitmap_size, uint64_t start, uint64_t dirty_pages) "iova=0x%"PRIx64" size= 0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64" dirty_pages=%"PRIu64 - vfio_iommu_map_dirty_notify(uint64_t iova_start, uint64_t iova_end) "iommu dirty @ 0x%"PRIx64" - 0x%"PRIx64 - - # platform.c -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 9740cf9fbc..bc67e1316c 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -186,7 +186,6 @@ typedef struct VFIODisplay { - - VFIOAddressSpace *vfio_get_address_space(AddressSpace *as); - void vfio_put_address_space(VFIOAddressSpace *space); --bool vfio_devices_all_running_and_saving(VFIOContainer *container); - - /* SPAPR specific */ - int vfio_container_add_section_window(VFIOContainer *container, -@@ -260,11 +259,11 @@ bool vfio_migration_realize(VFIODevice *vbasedev, Error **errp); - void vfio_migration_exit(VFIODevice *vbasedev); - - int vfio_bitmap_alloc(VFIOBitmap *vbmap, hwaddr size); --bool vfio_devices_all_running_and_mig_active(VFIOContainer *container); --bool vfio_devices_all_device_dirty_tracking(VFIOContainer *container); --int vfio_devices_query_dirty_bitmap(VFIOContainer *container, -+bool vfio_devices_all_running_and_mig_active(VFIOContainerBase *bcontainer); -+bool vfio_devices_all_device_dirty_tracking(VFIOContainerBase *bcontainer); -+int vfio_devices_query_dirty_bitmap(VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, hwaddr iova, - hwaddr size); --int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, -+int vfio_get_dirty_bitmap(VFIOContainerBase *bcontainer, uint64_t iova, - uint64_t size, ram_addr_t ram_addr); - #endif /* HW_VFIO_VFIO_COMMON_H */ --- -2.39.3 - diff --git a/kvm-vfio-container-Implement-attach-detach_device.patch b/kvm-vfio-container-Implement-attach-detach_device.patch deleted file mode 100644 index 92e9a38..0000000 --- a/kvm-vfio-container-Implement-attach-detach_device.patch +++ /dev/null @@ -1,97 +0,0 @@ -From a5d19bfbfddb36fa6d68ca6282a5acd9b245d48a Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 2 Nov 2023 15:12:41 +0800 -Subject: [PATCH 016/101] vfio/container: Implement attach/detach_device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [15/67] e233c90e4af2061dc0612bc1b1d17be1a47daeae (eauger1/centos-qemu-kvm) - -No functional change intended. - -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Yi Sun -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit 1eb31f13b24c49884d8256f96a6664df2dd0824d) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 16 ++++++++++++++++ - hw/vfio/container.c | 12 +++++------- - 2 files changed, 21 insertions(+), 7 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 8ef2e7967d..483ba82089 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1498,3 +1498,19 @@ retry: - - return info; - } -+ -+int vfio_attach_device(char *name, VFIODevice *vbasedev, -+ AddressSpace *as, Error **errp) -+{ -+ const VFIOIOMMUOps *ops = &vfio_legacy_ops; -+ -+ return ops->attach_device(name, vbasedev, as, errp); -+} -+ -+void vfio_detach_device(VFIODevice *vbasedev) -+{ -+ if (!vbasedev->bcontainer) { -+ return; -+ } -+ vbasedev->bcontainer->ops->detach_device(vbasedev); -+} -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 721c0d7375..6bacf38222 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -873,8 +873,8 @@ static int vfio_device_groupid(VFIODevice *vbasedev, Error **errp) - * @name and @vbasedev->name are likely to be different depending - * on the type of the device, hence the need for passing @name - */ --int vfio_attach_device(char *name, VFIODevice *vbasedev, -- AddressSpace *as, Error **errp) -+static int vfio_legacy_attach_device(const char *name, VFIODevice *vbasedev, -+ AddressSpace *as, Error **errp) - { - int groupid = vfio_device_groupid(vbasedev, errp); - VFIODevice *vbasedev_iter; -@@ -914,14 +914,10 @@ int vfio_attach_device(char *name, VFIODevice *vbasedev, - return ret; - } - --void vfio_detach_device(VFIODevice *vbasedev) -+static void vfio_legacy_detach_device(VFIODevice *vbasedev) - { - VFIOGroup *group = vbasedev->group; - -- if (!vbasedev->bcontainer) { -- return; -- } -- - QLIST_REMOVE(vbasedev, global_next); - QLIST_REMOVE(vbasedev, container_next); - vbasedev->bcontainer = NULL; -@@ -933,6 +929,8 @@ void vfio_detach_device(VFIODevice *vbasedev) - const VFIOIOMMUOps vfio_legacy_ops = { - .dma_map = vfio_legacy_dma_map, - .dma_unmap = vfio_legacy_dma_unmap, -+ .attach_device = vfio_legacy_attach_device, -+ .detach_device = vfio_legacy_detach_device, - .set_dirty_page_tracking = vfio_legacy_set_dirty_page_tracking, - .query_dirty_bitmap = vfio_legacy_query_dirty_bitmap, - }; --- -2.39.3 - diff --git a/kvm-vfio-container-Initialize-VFIOIOMMUOps-under-vfio_in.patch b/kvm-vfio-container-Initialize-VFIOIOMMUOps-under-vfio_in.patch deleted file mode 100644 index 42b406b..0000000 --- a/kvm-vfio-container-Initialize-VFIOIOMMUOps-under-vfio_in.patch +++ /dev/null @@ -1,65 +0,0 @@ -From c3c9f366c356032fa57ff7cc664732ba87ceb3fb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:18 +0100 -Subject: [PATCH 051/101] vfio/container: Initialize VFIOIOMMUOps under - vfio_init_container() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [50/67] f325136391b22babadb1be3394c527deecdcd3ca (eauger1/centos-qemu-kvm) - -vfio_init_container() already defines the IOMMU type of the container. -Do the same for the VFIOIOMMUOps struct. This prepares ground for the -following patches that will deduce the associated VFIOIOMMUOps struct -from the IOMMU type. - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit bffe92af0e7571868d47a1d1cd2205e13054d492) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index afcfe80488..f4a0434a52 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -370,7 +370,7 @@ static int vfio_get_iommu_type(VFIOContainer *container, - } - - static int vfio_init_container(VFIOContainer *container, int group_fd, -- Error **errp) -+ VFIOAddressSpace *space, Error **errp) - { - int iommu_type, ret; - -@@ -401,6 +401,7 @@ static int vfio_init_container(VFIOContainer *container, int group_fd, - } - - container->iommu_type = iommu_type; -+ vfio_container_init(&container->bcontainer, space, &vfio_legacy_ops); - return 0; - } - -@@ -583,9 +584,8 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - container = g_malloc0(sizeof(*container)); - container->fd = fd; - bcontainer = &container->bcontainer; -- vfio_container_init(bcontainer, space, &vfio_legacy_ops); - -- ret = vfio_init_container(container, group->fd, errp); -+ ret = vfio_init_container(container, group->fd, space, errp); - if (ret) { - goto free_container_exit; - } --- -2.39.3 - diff --git a/kvm-vfio-container-Intoduce-a-new-VFIOIOMMUClass-setup-h.patch b/kvm-vfio-container-Intoduce-a-new-VFIOIOMMUClass-setup-h.patch deleted file mode 100644 index 3411ecb..0000000 --- a/kvm-vfio-container-Intoduce-a-new-VFIOIOMMUClass-setup-h.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 29f13011e62f5370ef7fb3248dc85c90ae5bb042 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:21 +0100 -Subject: [PATCH 054/101] vfio/container: Intoduce a new VFIOIOMMUClass::setup - handler -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [53/67] 8641161afc33d68795bcf51a47e89061b34d50a8 (eauger1/centos-qemu-kvm) - -This will help in converting the sPAPR IOMMU backend to a QOM interface. - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit 61d893f2cdb34a2b0255f9b5fbba6b49b94ff730) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 1 + - include/hw/vfio/vfio-container-base.h | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 220e838a91..c22bdd3216 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -1129,6 +1129,7 @@ static void vfio_iommu_legacy_class_init(ObjectClass *klass, void *data) - { - VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass); - -+ vioc->setup = vfio_legacy_setup; - vioc->dma_map = vfio_legacy_dma_map; - vioc->dma_unmap = vfio_legacy_dma_unmap; - vioc->attach_device = vfio_legacy_attach_device; -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index c60370fc5e..ce8b1fba88 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -109,6 +109,7 @@ struct VFIOIOMMUClass { - InterfaceClass parent_class; - - /* basic feature */ -+ int (*setup)(VFIOContainerBase *bcontainer, Error **errp); - int (*dma_map)(const VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - void *vaddr, bool readonly); --- -2.39.3 - diff --git a/kvm-vfio-container-Introduce-a-VFIOIOMMU-QOM-interface.patch b/kvm-vfio-container-Introduce-a-VFIOIOMMU-QOM-interface.patch deleted file mode 100644 index 7139e64..0000000 --- a/kvm-vfio-container-Introduce-a-VFIOIOMMU-QOM-interface.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 5b63e4595e106196ef922b7f762c8f4150d73979 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:19 +0100 -Subject: [PATCH 052/101] vfio/container: Introduce a VFIOIOMMU QOM interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [51/67] 7c06e2165efe94dcd203d44e422a7aa9fac9816c (eauger1/centos-qemu-kvm) - -VFIOContainerBase was not introduced as an abstract QOM object because -it felt unnecessary to expose all the IOMMU backends to the QEMU -machine and human interface. However, we can still abstract the IOMMU -backend handlers using a QOM interface class. This provides more -flexibility when referencing the various implementations. - -Simply transform the VFIOIOMMUOps struct in an InterfaceClass and do -some initial name replacements. Next changes will start converting -VFIOIOMMUOps. - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit fdaa774e67435a328c0e28006c4d749f2198294a) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 2 +- - hw/vfio/container-base.c | 12 +++++++++++- - hw/vfio/pci.c | 2 +- - include/hw/vfio/vfio-container-base.h | 23 +++++++++++++++++++---- - 4 files changed, 32 insertions(+), 7 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 08a3e57672..49dab41566 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1503,7 +1503,7 @@ retry: - int vfio_attach_device(char *name, VFIODevice *vbasedev, - AddressSpace *as, Error **errp) - { -- const VFIOIOMMUOps *ops = &vfio_legacy_ops; -+ const VFIOIOMMUClass *ops = &vfio_legacy_ops; - - #ifdef CONFIG_IOMMUFD - if (vbasedev->iommufd) { -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 1ffd25bbfa..913ae49077 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -72,7 +72,7 @@ int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - } - - void vfio_container_init(VFIOContainerBase *bcontainer, VFIOAddressSpace *space, -- const VFIOIOMMUOps *ops) -+ const VFIOIOMMUClass *ops) - { - bcontainer->ops = ops; - bcontainer->space = space; -@@ -99,3 +99,13 @@ void vfio_container_destroy(VFIOContainerBase *bcontainer) - - g_list_free_full(bcontainer->iova_ranges, g_free); - } -+ -+static const TypeInfo types[] = { -+ { -+ .name = TYPE_VFIO_IOMMU, -+ .parent = TYPE_INTERFACE, -+ .class_size = sizeof(VFIOIOMMUClass), -+ }, -+}; -+ -+DEFINE_TYPES(types) -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 83c3238608..adb7c09367 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2491,7 +2491,7 @@ int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev, - static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) - { - VFIODevice *vbasedev = &vdev->vbasedev; -- const VFIOIOMMUOps *ops = vbasedev->bcontainer->ops; -+ const VFIOIOMMUClass *ops = vbasedev->bcontainer->ops; - - return ops->pci_hot_reset(vbasedev, single); - } -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 5c9594b6c7..d6147b4aee 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -16,7 +16,8 @@ - #include "exec/memory.h" - - typedef struct VFIODevice VFIODevice; --typedef struct VFIOIOMMUOps VFIOIOMMUOps; -+typedef struct VFIOIOMMUClass VFIOIOMMUClass; -+#define VFIOIOMMUOps VFIOIOMMUClass /* To remove */ - - typedef struct { - unsigned long *bitmap; -@@ -34,7 +35,7 @@ typedef struct VFIOAddressSpace { - * This is the base object for vfio container backends - */ - typedef struct VFIOContainerBase { -- const VFIOIOMMUOps *ops; -+ const VFIOIOMMUClass *ops; - VFIOAddressSpace *space; - MemoryListener listener; - Error *error; -@@ -88,10 +89,24 @@ int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - - void vfio_container_init(VFIOContainerBase *bcontainer, - VFIOAddressSpace *space, -- const VFIOIOMMUOps *ops); -+ const VFIOIOMMUClass *ops); - void vfio_container_destroy(VFIOContainerBase *bcontainer); - --struct VFIOIOMMUOps { -+ -+#define TYPE_VFIO_IOMMU "vfio-iommu" -+ -+/* -+ * VFIOContainerBase is not an abstract QOM object because it felt -+ * unnecessary to expose all the IOMMU backends to the QEMU machine -+ * and human interface. However, we can still abstract the IOMMU -+ * backend handlers using a QOM interface class. This provides more -+ * flexibility when referencing the various implementations. -+ */ -+DECLARE_CLASS_CHECKERS(VFIOIOMMUClass, VFIO_IOMMU, TYPE_VFIO_IOMMU) -+ -+struct VFIOIOMMUClass { -+ InterfaceClass parent_class; -+ - /* basic feature */ - int (*dma_map)(const VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, --- -2.39.3 - diff --git a/kvm-vfio-container-Introduce-a-VFIOIOMMU-legacy-QOM-inte.patch b/kvm-vfio-container-Introduce-a-VFIOIOMMU-legacy-QOM-inte.patch deleted file mode 100644 index 60439ff..0000000 --- a/kvm-vfio-container-Introduce-a-VFIOIOMMU-legacy-QOM-inte.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 58927bf236541b9423f855eca1970f7a3cf864a9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:20 +0100 -Subject: [PATCH 053/101] vfio/container: Introduce a VFIOIOMMU legacy QOM - interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [52/67] a81f39d13305e84699313e17ae64d10ff4b09067 (eauger1/centos-qemu-kvm) - -Convert the legacy VFIOIOMMUOps struct to the new VFIOIOMMU QOM -interface. The set of of operations for this backend can be referenced -with a literal typename instead of a C struct. This will simplify -support of multiple backends. - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit 9812feefab3a4ff95a6cfd73aecb120b406bc98c) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 6 ++- - hw/vfio/container.c | 58 ++++++++++++++++++++++----- - include/hw/vfio/vfio-common.h | 1 - - include/hw/vfio/vfio-container-base.h | 1 + - 4 files changed, 55 insertions(+), 11 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 49dab41566..2329d0efc8 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1503,13 +1503,17 @@ retry: - int vfio_attach_device(char *name, VFIODevice *vbasedev, - AddressSpace *as, Error **errp) - { -- const VFIOIOMMUClass *ops = &vfio_legacy_ops; -+ const VFIOIOMMUClass *ops = -+ VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_LEGACY)); - - #ifdef CONFIG_IOMMUFD - if (vbasedev->iommufd) { - ops = &vfio_iommufd_ops; - } - #endif -+ -+ assert(ops); -+ - return ops->attach_device(name, vbasedev, as, errp); - } - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index f4a0434a52..220e838a91 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -369,10 +369,30 @@ static int vfio_get_iommu_type(VFIOContainer *container, - return -EINVAL; - } - -+/* -+ * vfio_get_iommu_ops - get a VFIOIOMMUClass associated with a type -+ */ -+static const VFIOIOMMUClass *vfio_get_iommu_class(int iommu_type, Error **errp) -+{ -+ ObjectClass *klass = NULL; -+ -+ switch (iommu_type) { -+ case VFIO_TYPE1v2_IOMMU: -+ case VFIO_TYPE1_IOMMU: -+ klass = object_class_by_name(TYPE_VFIO_IOMMU_LEGACY); -+ break; -+ default: -+ g_assert_not_reached(); -+ }; -+ -+ return VFIO_IOMMU_CLASS(klass); -+} -+ - static int vfio_init_container(VFIOContainer *container, int group_fd, - VFIOAddressSpace *space, Error **errp) - { - int iommu_type, ret; -+ const VFIOIOMMUClass *vioc; - - iommu_type = vfio_get_iommu_type(container, errp); - if (iommu_type < 0) { -@@ -401,7 +421,14 @@ static int vfio_init_container(VFIOContainer *container, int group_fd, - } - - container->iommu_type = iommu_type; -- vfio_container_init(&container->bcontainer, space, &vfio_legacy_ops); -+ -+ vioc = vfio_get_iommu_class(iommu_type, errp); -+ if (!vioc) { -+ error_setg(errp, "No available IOMMU models"); -+ return -EINVAL; -+ } -+ -+ vfio_container_init(&container->bcontainer, space, vioc); - return 0; - } - -@@ -1098,12 +1125,25 @@ out_single: - return ret; - } - --const VFIOIOMMUOps vfio_legacy_ops = { -- .dma_map = vfio_legacy_dma_map, -- .dma_unmap = vfio_legacy_dma_unmap, -- .attach_device = vfio_legacy_attach_device, -- .detach_device = vfio_legacy_detach_device, -- .set_dirty_page_tracking = vfio_legacy_set_dirty_page_tracking, -- .query_dirty_bitmap = vfio_legacy_query_dirty_bitmap, -- .pci_hot_reset = vfio_legacy_pci_hot_reset, -+static void vfio_iommu_legacy_class_init(ObjectClass *klass, void *data) -+{ -+ VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass); -+ -+ vioc->dma_map = vfio_legacy_dma_map; -+ vioc->dma_unmap = vfio_legacy_dma_unmap; -+ vioc->attach_device = vfio_legacy_attach_device; -+ vioc->detach_device = vfio_legacy_detach_device; -+ vioc->set_dirty_page_tracking = vfio_legacy_set_dirty_page_tracking; -+ vioc->query_dirty_bitmap = vfio_legacy_query_dirty_bitmap; -+ vioc->pci_hot_reset = vfio_legacy_pci_hot_reset; - }; -+ -+static const TypeInfo types[] = { -+ { -+ .name = TYPE_VFIO_IOMMU_LEGACY, -+ .parent = TYPE_VFIO_IOMMU, -+ .class_init = vfio_iommu_legacy_class_init, -+ }, -+}; -+ -+DEFINE_TYPES(types) -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index b8aa8a5495..14c497b6b0 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -210,7 +210,6 @@ typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList; - typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; - extern VFIOGroupList vfio_group_list; - extern VFIODeviceList vfio_device_list; --extern const VFIOIOMMUOps vfio_legacy_ops; - extern const VFIOIOMMUOps vfio_iommufd_ops; - extern const MemoryListener vfio_memory_listener; - extern int vfio_kvm_device_fd; -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index d6147b4aee..c60370fc5e 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -94,6 +94,7 @@ void vfio_container_destroy(VFIOContainerBase *bcontainer); - - - #define TYPE_VFIO_IOMMU "vfio-iommu" -+#define TYPE_VFIO_IOMMU_LEGACY TYPE_VFIO_IOMMU "-legacy" - - /* - * VFIOContainerBase is not an abstract QOM object because it felt --- -2.39.3 - diff --git a/kvm-vfio-container-Introduce-a-empty-VFIOIOMMUOps.patch b/kvm-vfio-container-Introduce-a-empty-VFIOIOMMUOps.patch deleted file mode 100644 index 2840e2c..0000000 --- a/kvm-vfio-container-Introduce-a-empty-VFIOIOMMUOps.patch +++ /dev/null @@ -1,71 +0,0 @@ -From e56f961fbe95a53a52c5eca00b4fca17d825e860 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:28 +0800 -Subject: [PATCH 003/101] vfio/container: Introduce a empty VFIOIOMMUOps -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [2/67] 0de0afffce42fa4a17f6d33a10b6162cdfbe8150 (eauger1/centos-qemu-kvm) - -This empty VFIOIOMMUOps named vfio_legacy_ops will hold all general -IOMMU ops of legacy container. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit d24668579184f4098779983724ec74cd3db62e10) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 5 +++++ - include/hw/vfio/vfio-common.h | 2 +- - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 242010036a..4bc43ddfa4 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -472,6 +472,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - Error **errp) - { - VFIOContainer *container; -+ VFIOContainerBase *bcontainer; - int ret, fd; - VFIOAddressSpace *space; - -@@ -552,6 +553,8 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - container->iova_ranges = NULL; - QLIST_INIT(&container->giommu_list); - QLIST_INIT(&container->vrdl_list); -+ bcontainer = &container->bcontainer; -+ bcontainer->ops = &vfio_legacy_ops; - - ret = vfio_init_container(container, group->fd, errp); - if (ret) { -@@ -933,3 +936,5 @@ void vfio_detach_device(VFIODevice *vbasedev) - vfio_put_base_device(vbasedev); - vfio_put_group(group); - } -+ -+const VFIOIOMMUOps vfio_legacy_ops; -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 586d153c12..678161f207 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -255,7 +255,7 @@ typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList; - typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; - extern VFIOGroupList vfio_group_list; - extern VFIODeviceList vfio_device_list; -- -+extern const VFIOIOMMUOps vfio_legacy_ops; - extern const MemoryListener vfio_memory_listener; - extern int vfio_kvm_device_fd; - --- -2.39.3 - diff --git a/kvm-vfio-container-Introduce-vfio_legacy_setup-for-furth.patch b/kvm-vfio-container-Introduce-vfio_legacy_setup-for-furth.patch deleted file mode 100644 index ae9ccd8..0000000 --- a/kvm-vfio-container-Introduce-vfio_legacy_setup-for-furth.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 6c7546756e979e4f5ba29ae51a21c63fa90492cf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:17 +0100 -Subject: [PATCH 050/101] vfio/container: Introduce vfio_legacy_setup() for - further cleanups -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [49/67] 3a621ba2605c98b7fbf7fd9f93a207f728f1202e (eauger1/centos-qemu-kvm) - -This will help subsequent patches to unify the initialization of type1 -and sPAPR IOMMU backends. - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit d3764db87531cd53849ccee9b2f72aede90ccf5b) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 63 +++++++++++++++++++++++++-------------------- - 1 file changed, 35 insertions(+), 28 deletions(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 1e77a2929e..afcfe80488 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -474,6 +474,35 @@ static void vfio_get_iommu_info_migration(VFIOContainer *container, - } - } - -+static int vfio_legacy_setup(VFIOContainerBase *bcontainer, Error **errp) -+{ -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); -+ g_autofree struct vfio_iommu_type1_info *info = NULL; -+ int ret; -+ -+ ret = vfio_get_iommu_info(container, &info); -+ if (ret) { -+ error_setg_errno(errp, -ret, "Failed to get VFIO IOMMU info"); -+ return ret; -+ } -+ -+ if (info->flags & VFIO_IOMMU_INFO_PGSIZES) { -+ bcontainer->pgsizes = info->iova_pgsizes; -+ } else { -+ bcontainer->pgsizes = qemu_real_host_page_size(); -+ } -+ -+ if (!vfio_get_info_dma_avail(info, &bcontainer->dma_max_mappings)) { -+ bcontainer->dma_max_mappings = 65535; -+ } -+ -+ vfio_get_info_iova_range(info, bcontainer); -+ -+ vfio_get_iommu_info_migration(container, info); -+ return 0; -+} -+ - static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - Error **errp) - { -@@ -570,40 +599,18 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - switch (container->iommu_type) { - case VFIO_TYPE1v2_IOMMU: - case VFIO_TYPE1_IOMMU: -- { -- struct vfio_iommu_type1_info *info; -- -- ret = vfio_get_iommu_info(container, &info); -- if (ret) { -- error_setg_errno(errp, -ret, "Failed to get VFIO IOMMU info"); -- goto enable_discards_exit; -- } -- -- if (info->flags & VFIO_IOMMU_INFO_PGSIZES) { -- bcontainer->pgsizes = info->iova_pgsizes; -- } else { -- bcontainer->pgsizes = qemu_real_host_page_size(); -- } -- -- if (!vfio_get_info_dma_avail(info, &bcontainer->dma_max_mappings)) { -- bcontainer->dma_max_mappings = 65535; -- } -- -- vfio_get_info_iova_range(info, bcontainer); -- -- vfio_get_iommu_info_migration(container, info); -- g_free(info); -+ ret = vfio_legacy_setup(bcontainer, errp); - break; -- } - case VFIO_SPAPR_TCE_v2_IOMMU: - case VFIO_SPAPR_TCE_IOMMU: -- { - ret = vfio_spapr_container_init(container, errp); -- if (ret) { -- goto enable_discards_exit; -- } - break; -+ default: -+ g_assert_not_reached(); - } -+ -+ if (ret) { -+ goto enable_discards_exit; - } - - vfio_kvm_device_add_group(group); --- -2.39.3 - diff --git a/kvm-vfio-container-Move-dirty_pgsizes-and-max_dirty_bitm.patch b/kvm-vfio-container-Move-dirty_pgsizes-and-max_dirty_bitm.patch deleted file mode 100644 index 3d46a06..0000000 --- a/kvm-vfio-container-Move-dirty_pgsizes-and-max_dirty_bitm.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 6a597d7c82a4538fa1f928db7e600ec2e5a44361 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 2 Nov 2023 15:12:39 +0800 -Subject: [PATCH 014/101] vfio/container: Move dirty_pgsizes and - max_dirty_bitmap_size to base container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [13/67] b9fe57174368e36788b017cc2ad13b748592cfc2 (eauger1/centos-qemu-kvm) - -No functional change intended. - -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Yi Sun -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit 4d6b95010c59127ac4f7230d6ee88b5d0e99738c) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 9 +++++---- - include/hw/vfio/vfio-common.h | 2 -- - include/hw/vfio/vfio-container-base.h | 2 ++ - 3 files changed, 7 insertions(+), 6 deletions(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 5c1dee8c9f..c8088a8174 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -64,6 +64,7 @@ static int vfio_dma_unmap_bitmap(VFIOContainer *container, - hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb) - { -+ VFIOContainerBase *bcontainer = &container->bcontainer; - struct vfio_iommu_type1_dma_unmap *unmap; - struct vfio_bitmap *bitmap; - VFIOBitmap vbmap; -@@ -91,7 +92,7 @@ static int vfio_dma_unmap_bitmap(VFIOContainer *container, - bitmap->size = vbmap.size; - bitmap->data = (__u64 *)vbmap.bitmap; - -- if (vbmap.size > container->max_dirty_bitmap_size) { -+ if (vbmap.size > bcontainer->max_dirty_bitmap_size) { - error_report("UNMAP: Size of bitmap too big 0x%"PRIx64, vbmap.size); - ret = -E2BIG; - goto unmap_exit; -@@ -131,7 +132,7 @@ static int vfio_legacy_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, - - if (iotlb && vfio_devices_all_running_and_mig_active(bcontainer)) { - if (!vfio_devices_all_device_dirty_tracking(bcontainer) && -- container->bcontainer.dirty_pages_supported) { -+ bcontainer->dirty_pages_supported) { - return vfio_dma_unmap_bitmap(container, iova, size, iotlb); - } - -@@ -469,8 +470,8 @@ static void vfio_get_iommu_info_migration(VFIOContainer *container, - */ - if (cap_mig->pgsize_bitmap & qemu_real_host_page_size()) { - bcontainer->dirty_pages_supported = true; -- container->max_dirty_bitmap_size = cap_mig->max_dirty_bitmap_size; -- container->dirty_pgsizes = cap_mig->pgsize_bitmap; -+ bcontainer->max_dirty_bitmap_size = cap_mig->max_dirty_bitmap_size; -+ bcontainer->dirty_pgsizes = cap_mig->pgsize_bitmap; - } - } - -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 922022cbc6..b1c9fe711b 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -80,8 +80,6 @@ typedef struct VFIOContainer { - int fd; /* /dev/vfio/vfio, empowered by the attached groups */ - MemoryListener prereg_listener; - unsigned iommu_type; -- uint64_t dirty_pgsizes; -- uint64_t max_dirty_bitmap_size; - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; - GList *iova_ranges; -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 95f8d319e0..80e4a993c5 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -39,6 +39,8 @@ typedef struct VFIOContainerBase { - MemoryListener listener; - Error *error; - bool initialized; -+ uint64_t dirty_pgsizes; -+ uint64_t max_dirty_bitmap_size; - unsigned long pgsizes; - unsigned int dma_max_mappings; - bool dirty_pages_supported; --- -2.39.3 - diff --git a/kvm-vfio-container-Move-iova_ranges-to-base-container.patch b/kvm-vfio-container-Move-iova_ranges-to-base-container.patch deleted file mode 100644 index c9c79b6..0000000 --- a/kvm-vfio-container-Move-iova_ranges-to-base-container.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 882143ef30da4182f049eb8192e0fac317c372b3 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:40 +0800 -Subject: [PATCH 015/101] vfio/container: Move iova_ranges to base container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [14/67] 49f2e3c484b4c0c63be9aa4eb1bf08804dcb1ec3 (eauger1/centos-qemu-kvm) - -Meanwhile remove the helper function vfio_free_container as it -only calls g_free now. - -No functional change intended. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit f79baf8c9575ac3193ca86ec508791c86d96b13e) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 5 +++-- - hw/vfio/container-base.c | 3 +++ - hw/vfio/container.c | 19 ++++++------------- - include/hw/vfio/vfio-common.h | 1 - - include/hw/vfio/vfio-container-base.h | 1 + - 5 files changed, 13 insertions(+), 16 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index be623e544b..8ef2e7967d 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -637,9 +637,10 @@ static void vfio_listener_region_add(MemoryListener *listener, - goto fail; - } - -- if (container->iova_ranges) { -+ if (bcontainer->iova_ranges) { - ret = memory_region_iommu_set_iova_ranges(giommu->iommu_mr, -- container->iova_ranges, &err); -+ bcontainer->iova_ranges, -+ &err); - if (ret) { - g_free(giommu); - goto fail; -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 7f508669f5..0177f43741 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -54,6 +54,7 @@ void vfio_container_init(VFIOContainerBase *bcontainer, VFIOAddressSpace *space, - bcontainer->error = NULL; - bcontainer->dirty_pages_supported = false; - bcontainer->dma_max_mappings = 0; -+ bcontainer->iova_ranges = NULL; - QLIST_INIT(&bcontainer->giommu_list); - QLIST_INIT(&bcontainer->vrdl_list); - } -@@ -70,4 +71,6 @@ void vfio_container_destroy(VFIOContainerBase *bcontainer) - QLIST_REMOVE(giommu, giommu_next); - g_free(giommu); - } -+ -+ g_list_free_full(bcontainer->iova_ranges, g_free); - } -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index c8088a8174..721c0d7375 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -308,7 +308,7 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, - } - - static bool vfio_get_info_iova_range(struct vfio_iommu_type1_info *info, -- VFIOContainer *container) -+ VFIOContainerBase *bcontainer) - { - struct vfio_info_cap_header *hdr; - struct vfio_iommu_type1_info_cap_iova_range *cap; -@@ -326,8 +326,8 @@ static bool vfio_get_info_iova_range(struct vfio_iommu_type1_info *info, - - range_set_bounds(range, cap->iova_ranges[i].start, - cap->iova_ranges[i].end); -- container->iova_ranges = -- range_list_insert(container->iova_ranges, range); -+ bcontainer->iova_ranges = -+ range_list_insert(bcontainer->iova_ranges, range); - } - - return true; -@@ -475,12 +475,6 @@ static void vfio_get_iommu_info_migration(VFIOContainer *container, - } - } - --static void vfio_free_container(VFIOContainer *container) --{ -- g_list_free_full(container->iova_ranges, g_free); -- g_free(container); --} -- - static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - Error **errp) - { -@@ -560,7 +554,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - - container = g_malloc0(sizeof(*container)); - container->fd = fd; -- container->iova_ranges = NULL; - bcontainer = &container->bcontainer; - vfio_container_init(bcontainer, space, &vfio_legacy_ops); - -@@ -597,7 +590,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - bcontainer->dma_max_mappings = 65535; - } - -- vfio_get_info_iova_range(info, container); -+ vfio_get_info_iova_range(info, bcontainer); - - vfio_get_iommu_info_migration(container, info); - g_free(info); -@@ -649,7 +642,7 @@ enable_discards_exit: - vfio_ram_block_discard_disable(container, false); - - free_container_exit: -- vfio_free_container(container); -+ g_free(container); - - close_fd_exit: - close(fd); -@@ -693,7 +686,7 @@ static void vfio_disconnect_container(VFIOGroup *group) - - trace_vfio_disconnect_container(container->fd); - close(container->fd); -- vfio_free_container(container); -+ g_free(container); - - vfio_put_address_space(space); - } -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index b1c9fe711b..b9e5a0e64b 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -82,7 +82,6 @@ typedef struct VFIOContainer { - unsigned iommu_type; - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; -- GList *iova_ranges; - } VFIOContainer; - - typedef struct VFIOHostDMAWindow { -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 80e4a993c5..9658ffb526 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -48,6 +48,7 @@ typedef struct VFIOContainerBase { - QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; - QLIST_ENTRY(VFIOContainerBase) next; - QLIST_HEAD(, VFIODevice) device_list; -+ GList *iova_ranges; - } VFIOContainerBase; - - typedef struct VFIOGuestIOMMU { --- -2.39.3 - diff --git a/kvm-vfio-container-Move-listener-to-base-container.patch b/kvm-vfio-container-Move-listener-to-base-container.patch deleted file mode 100644 index 3198bfd..0000000 --- a/kvm-vfio-container-Move-listener-to-base-container.patch +++ /dev/null @@ -1,522 +0,0 @@ -From 36bc7782bb02f81368e3e43a3947d16ad362e137 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 2 Nov 2023 15:12:38 +0800 -Subject: [PATCH 013/101] vfio/container: Move listener to base container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [12/67] f469ab126c6366170aa2520f9b4d9969d3ae0a04 (eauger1/centos-qemu-kvm) - -Move listener to base container. Also error and initialized fields -are moved at the same time. - -No functional change intended. - -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Yi Sun -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit c7b313d300f161c650d011a5c9da469bcd5d34e4) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 110 +++++++++++++------------- - hw/vfio/container-base.c | 1 + - hw/vfio/container.c | 19 +++-- - hw/vfio/spapr.c | 11 +-- - include/hw/vfio/vfio-common.h | 3 - - include/hw/vfio/vfio-container-base.h | 3 + - 6 files changed, 74 insertions(+), 73 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index f15665789f..be623e544b 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -541,7 +541,7 @@ static bool vfio_listener_valid_section(MemoryRegionSection *section, - return true; - } - --static bool vfio_get_section_iova_range(VFIOContainer *container, -+static bool vfio_get_section_iova_range(VFIOContainerBase *bcontainer, - MemoryRegionSection *section, - hwaddr *out_iova, hwaddr *out_end, - Int128 *out_llend) -@@ -569,8 +569,10 @@ static bool vfio_get_section_iova_range(VFIOContainer *container, - static void vfio_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { -- VFIOContainer *container = container_of(listener, VFIOContainer, listener); -- VFIOContainerBase *bcontainer = &container->bcontainer; -+ VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, -+ listener); -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - hwaddr iova, end; - Int128 llend, llsize; - void *vaddr; -@@ -581,7 +583,8 @@ static void vfio_listener_region_add(MemoryListener *listener, - return; - } - -- if (!vfio_get_section_iova_range(container, section, &iova, &end, &llend)) { -+ if (!vfio_get_section_iova_range(bcontainer, section, &iova, &end, -+ &llend)) { - if (memory_region_is_ram_device(section->mr)) { - trace_vfio_listener_region_add_no_dma_map( - memory_region_name(section->mr), -@@ -688,13 +691,12 @@ static void vfio_listener_region_add(MemoryListener *listener, - } - } - -- ret = vfio_container_dma_map(&container->bcontainer, -- iova, int128_get64(llsize), vaddr, -- section->readonly); -+ ret = vfio_container_dma_map(bcontainer, iova, int128_get64(llsize), -+ vaddr, section->readonly); - if (ret) { - error_setg(&err, "vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx", %p) = %d (%s)", -- container, iova, int128_get64(llsize), vaddr, ret, -+ bcontainer, iova, int128_get64(llsize), vaddr, ret, - strerror(-ret)); - if (memory_region_is_ram_device(section->mr)) { - /* Allow unexpected mappings not to be fatal for RAM devices */ -@@ -716,9 +718,9 @@ fail: - * can gracefully fail. Runtime, there's not much we can do other - * than throw a hardware error. - */ -- if (!container->initialized) { -- if (!container->error) { -- error_propagate_prepend(&container->error, err, -+ if (!bcontainer->initialized) { -+ if (!bcontainer->error) { -+ error_propagate_prepend(&bcontainer->error, err, - "Region %s: ", - memory_region_name(section->mr)); - } else { -@@ -733,8 +735,10 @@ fail: - static void vfio_listener_region_del(MemoryListener *listener, - MemoryRegionSection *section) - { -- VFIOContainer *container = container_of(listener, VFIOContainer, listener); -- VFIOContainerBase *bcontainer = &container->bcontainer; -+ VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, -+ listener); -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - hwaddr iova, end; - Int128 llend, llsize; - int ret; -@@ -767,7 +771,8 @@ static void vfio_listener_region_del(MemoryListener *listener, - */ - } - -- if (!vfio_get_section_iova_range(container, section, &iova, &end, &llend)) { -+ if (!vfio_get_section_iova_range(bcontainer, section, &iova, &end, -+ &llend)) { - return; - } - -@@ -790,22 +795,22 @@ static void vfio_listener_region_del(MemoryListener *listener, - if (int128_eq(llsize, int128_2_64())) { - /* The unmap ioctl doesn't accept a full 64-bit span. */ - llsize = int128_rshift(llsize, 1); -- ret = vfio_container_dma_unmap(&container->bcontainer, iova, -+ ret = vfio_container_dma_unmap(bcontainer, iova, - int128_get64(llsize), NULL); - if (ret) { - error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%s)", -- container, iova, int128_get64(llsize), ret, -+ bcontainer, iova, int128_get64(llsize), ret, - strerror(-ret)); - } - iova += int128_get64(llsize); - } -- ret = vfio_container_dma_unmap(&container->bcontainer, iova, -+ ret = vfio_container_dma_unmap(bcontainer, iova, - int128_get64(llsize), NULL); - if (ret) { - error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%s)", -- container, iova, int128_get64(llsize), ret, -+ bcontainer, iova, int128_get64(llsize), ret, - strerror(-ret)); - } - } -@@ -825,16 +830,15 @@ typedef struct VFIODirtyRanges { - } VFIODirtyRanges; - - typedef struct VFIODirtyRangesListener { -- VFIOContainer *container; -+ VFIOContainerBase *bcontainer; - VFIODirtyRanges ranges; - MemoryListener listener; - } VFIODirtyRangesListener; - - static bool vfio_section_is_vfio_pci(MemoryRegionSection *section, -- VFIOContainer *container) -+ VFIOContainerBase *bcontainer) - { - VFIOPCIDevice *pcidev; -- VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - Object *owner; - -@@ -863,7 +867,7 @@ static void vfio_dirty_tracking_update(MemoryListener *listener, - hwaddr iova, end, *min, *max; - - if (!vfio_listener_valid_section(section, "tracking_update") || -- !vfio_get_section_iova_range(dirty->container, section, -+ !vfio_get_section_iova_range(dirty->bcontainer, section, - &iova, &end, NULL)) { - return; - } -@@ -887,7 +891,7 @@ static void vfio_dirty_tracking_update(MemoryListener *listener, - * The alternative would be an IOVATree but that has a much bigger runtime - * overhead and unnecessary complexity. - */ -- if (vfio_section_is_vfio_pci(section, dirty->container) && -+ if (vfio_section_is_vfio_pci(section, dirty->bcontainer) && - iova >= UINT32_MAX) { - min = &range->minpci64; - max = &range->maxpci64; -@@ -911,7 +915,7 @@ static const MemoryListener vfio_dirty_tracking_listener = { - .region_add = vfio_dirty_tracking_update, - }; - --static void vfio_dirty_tracking_init(VFIOContainer *container, -+static void vfio_dirty_tracking_init(VFIOContainerBase *bcontainer, - VFIODirtyRanges *ranges) - { - VFIODirtyRangesListener dirty; -@@ -921,10 +925,10 @@ static void vfio_dirty_tracking_init(VFIOContainer *container, - dirty.ranges.min64 = UINT64_MAX; - dirty.ranges.minpci64 = UINT64_MAX; - dirty.listener = vfio_dirty_tracking_listener; -- dirty.container = container; -+ dirty.bcontainer = bcontainer; - - memory_listener_register(&dirty.listener, -- container->bcontainer.space->as); -+ bcontainer->space->as); - - *ranges = dirty.ranges; - -@@ -936,12 +940,11 @@ static void vfio_dirty_tracking_init(VFIOContainer *container, - memory_listener_unregister(&dirty.listener); - } - --static void vfio_devices_dma_logging_stop(VFIOContainer *container) -+static void vfio_devices_dma_logging_stop(VFIOContainerBase *bcontainer) - { - uint64_t buf[DIV_ROUND_UP(sizeof(struct vfio_device_feature), - sizeof(uint64_t))] = {}; - struct vfio_device_feature *feature = (struct vfio_device_feature *)buf; -- VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - - feature->argsz = sizeof(buf); -@@ -962,7 +965,7 @@ static void vfio_devices_dma_logging_stop(VFIOContainer *container) - } - - static struct vfio_device_feature * --vfio_device_feature_dma_logging_start_create(VFIOContainer *container, -+vfio_device_feature_dma_logging_start_create(VFIOContainerBase *bcontainer, - VFIODirtyRanges *tracking) - { - struct vfio_device_feature *feature; -@@ -1035,16 +1038,15 @@ static void vfio_device_feature_dma_logging_start_destroy( - g_free(feature); - } - --static int vfio_devices_dma_logging_start(VFIOContainer *container) -+static int vfio_devices_dma_logging_start(VFIOContainerBase *bcontainer) - { - struct vfio_device_feature *feature; - VFIODirtyRanges ranges; -- VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - int ret = 0; - -- vfio_dirty_tracking_init(container, &ranges); -- feature = vfio_device_feature_dma_logging_start_create(container, -+ vfio_dirty_tracking_init(bcontainer, &ranges); -+ feature = vfio_device_feature_dma_logging_start_create(bcontainer, - &ranges); - if (!feature) { - return -errno; -@@ -1067,7 +1069,7 @@ static int vfio_devices_dma_logging_start(VFIOContainer *container) - - out: - if (ret) { -- vfio_devices_dma_logging_stop(container); -+ vfio_devices_dma_logging_stop(bcontainer); - } - - vfio_device_feature_dma_logging_start_destroy(feature); -@@ -1077,14 +1079,14 @@ out: - - static void vfio_listener_log_global_start(MemoryListener *listener) - { -- VFIOContainer *container = container_of(listener, VFIOContainer, listener); -+ VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, -+ listener); - int ret; - -- if (vfio_devices_all_device_dirty_tracking(&container->bcontainer)) { -- ret = vfio_devices_dma_logging_start(container); -+ if (vfio_devices_all_device_dirty_tracking(bcontainer)) { -+ ret = vfio_devices_dma_logging_start(bcontainer); - } else { -- ret = vfio_container_set_dirty_page_tracking(&container->bcontainer, -- true); -+ ret = vfio_container_set_dirty_page_tracking(bcontainer, true); - } - - if (ret) { -@@ -1096,14 +1098,14 @@ static void vfio_listener_log_global_start(MemoryListener *listener) - - static void vfio_listener_log_global_stop(MemoryListener *listener) - { -- VFIOContainer *container = container_of(listener, VFIOContainer, listener); -+ VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, -+ listener); - int ret = 0; - -- if (vfio_devices_all_device_dirty_tracking(&container->bcontainer)) { -- vfio_devices_dma_logging_stop(container); -+ if (vfio_devices_all_device_dirty_tracking(bcontainer)) { -+ vfio_devices_dma_logging_stop(bcontainer); - } else { -- ret = vfio_container_set_dirty_page_tracking(&container->bcontainer, -- false); -+ ret = vfio_container_set_dirty_page_tracking(bcontainer, false); - } - - if (ret) { -@@ -1214,8 +1216,6 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - vfio_giommu_dirty_notifier, n); - VFIOGuestIOMMU *giommu = gdn->giommu; - VFIOContainerBase *bcontainer = giommu->bcontainer; -- VFIOContainer *container = container_of(bcontainer, VFIOContainer, -- bcontainer); - hwaddr iova = iotlb->iova + giommu->iommu_offset; - ram_addr_t translated_addr; - int ret = -EINVAL; -@@ -1230,12 +1230,12 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - - rcu_read_lock(); - if (vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL)) { -- ret = vfio_get_dirty_bitmap(&container->bcontainer, iova, -- iotlb->addr_mask + 1, translated_addr); -+ ret = vfio_get_dirty_bitmap(bcontainer, iova, iotlb->addr_mask + 1, -+ translated_addr); - if (ret) { - error_report("vfio_iommu_map_dirty_notify(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%s)", -- container, iova, iotlb->addr_mask + 1, ret, -+ bcontainer, iova, iotlb->addr_mask + 1, ret, - strerror(-ret)); - } - } -@@ -1291,10 +1291,9 @@ vfio_sync_ram_discard_listener_dirty_bitmap(VFIOContainerBase *bcontainer, - &vrdl); - } - --static int vfio_sync_dirty_bitmap(VFIOContainer *container, -+static int vfio_sync_dirty_bitmap(VFIOContainerBase *bcontainer, - MemoryRegionSection *section) - { -- VFIOContainerBase *bcontainer = &container->bcontainer; - ram_addr_t ram_addr; - - if (memory_region_is_iommu(section->mr)) { -@@ -1330,7 +1329,7 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container, - ram_addr = memory_region_get_ram_addr(section->mr) + - section->offset_within_region; - -- return vfio_get_dirty_bitmap(&container->bcontainer, -+ return vfio_get_dirty_bitmap(bcontainer, - REAL_HOST_PAGE_ALIGN(section->offset_within_address_space), - int128_get64(section->size), ram_addr); - } -@@ -1338,15 +1337,16 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container, - static void vfio_listener_log_sync(MemoryListener *listener, - MemoryRegionSection *section) - { -- VFIOContainer *container = container_of(listener, VFIOContainer, listener); -+ VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, -+ listener); - int ret; - - if (vfio_listener_skipped_section(section)) { - return; - } - -- if (vfio_devices_all_dirty_tracking(&container->bcontainer)) { -- ret = vfio_sync_dirty_bitmap(container, section); -+ if (vfio_devices_all_dirty_tracking(bcontainer)) { -+ ret = vfio_sync_dirty_bitmap(bcontainer, section); - if (ret) { - error_report("vfio: Failed to sync dirty bitmap, err: %d (%s)", ret, - strerror(-ret)); -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 584eee4ba1..7f508669f5 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -51,6 +51,7 @@ void vfio_container_init(VFIOContainerBase *bcontainer, VFIOAddressSpace *space, - { - bcontainer->ops = ops; - bcontainer->space = space; -+ bcontainer->error = NULL; - bcontainer->dirty_pages_supported = false; - bcontainer->dma_max_mappings = 0; - QLIST_INIT(&bcontainer->giommu_list); -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 6ba2e2f8c4..5c1dee8c9f 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -453,6 +453,7 @@ static void vfio_get_iommu_info_migration(VFIOContainer *container, - { - struct vfio_info_cap_header *hdr; - struct vfio_iommu_type1_info_cap_migration *cap_mig; -+ VFIOContainerBase *bcontainer = &container->bcontainer; - - hdr = vfio_get_iommu_info_cap(info, VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION); - if (!hdr) { -@@ -467,7 +468,7 @@ static void vfio_get_iommu_info_migration(VFIOContainer *container, - * qemu_real_host_page_size to mark those dirty. - */ - if (cap_mig->pgsize_bitmap & qemu_real_host_page_size()) { -- container->bcontainer.dirty_pages_supported = true; -+ bcontainer->dirty_pages_supported = true; - container->max_dirty_bitmap_size = cap_mig->max_dirty_bitmap_size; - container->dirty_pgsizes = cap_mig->pgsize_bitmap; - } -@@ -558,7 +559,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - - container = g_malloc0(sizeof(*container)); - container->fd = fd; -- container->error = NULL; - container->iova_ranges = NULL; - bcontainer = &container->bcontainer; - vfio_container_init(bcontainer, space, &vfio_legacy_ops); -@@ -621,25 +621,24 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - group->container = container; - QLIST_INSERT_HEAD(&container->group_list, group, container_next); - -- container->listener = vfio_memory_listener; -- -- memory_listener_register(&container->listener, bcontainer->space->as); -+ bcontainer->listener = vfio_memory_listener; -+ memory_listener_register(&bcontainer->listener, bcontainer->space->as); - -- if (container->error) { -+ if (bcontainer->error) { - ret = -1; -- error_propagate_prepend(errp, container->error, -+ error_propagate_prepend(errp, bcontainer->error, - "memory listener initialization failed: "); - goto listener_release_exit; - } - -- container->initialized = true; -+ bcontainer->initialized = true; - - return 0; - listener_release_exit: - QLIST_REMOVE(group, container_next); - QLIST_REMOVE(bcontainer, next); - vfio_kvm_device_del_group(group); -- memory_listener_unregister(&container->listener); -+ memory_listener_unregister(&bcontainer->listener); - if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU || - container->iommu_type == VFIO_SPAPR_TCE_IOMMU) { - vfio_spapr_container_deinit(container); -@@ -674,7 +673,7 @@ static void vfio_disconnect_container(VFIOGroup *group) - * group. - */ - if (QLIST_EMPTY(&container->group_list)) { -- memory_listener_unregister(&container->listener); -+ memory_listener_unregister(&bcontainer->listener); - if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU || - container->iommu_type == VFIO_SPAPR_TCE_IOMMU) { - vfio_spapr_container_deinit(container); -diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c -index 4f76bdd3ca..7a50975f25 100644 ---- a/hw/vfio/spapr.c -+++ b/hw/vfio/spapr.c -@@ -46,6 +46,7 @@ static void vfio_prereg_listener_region_add(MemoryListener *listener, - { - VFIOContainer *container = container_of(listener, VFIOContainer, - prereg_listener); -+ VFIOContainerBase *bcontainer = &container->bcontainer; - const hwaddr gpa = section->offset_within_address_space; - hwaddr end; - int ret; -@@ -88,9 +89,9 @@ static void vfio_prereg_listener_region_add(MemoryListener *listener, - * can gracefully fail. Runtime, there's not much we can do other - * than throw a hardware error. - */ -- if (!container->initialized) { -- if (!container->error) { -- error_setg_errno(&container->error, -ret, -+ if (!bcontainer->initialized) { -+ if (!bcontainer->error) { -+ error_setg_errno(&bcontainer->error, -ret, - "Memory registering failed"); - } - } else { -@@ -445,9 +446,9 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - - memory_listener_register(&container->prereg_listener, - &address_space_memory); -- if (container->error) { -+ if (bcontainer->error) { - ret = -1; -- error_propagate_prepend(errp, container->error, -+ error_propagate_prepend(errp, bcontainer->error, - "RAM memory listener initialization failed: "); - goto listener_unregister_exit; - } -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 8a607a4c17..922022cbc6 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -78,11 +78,8 @@ struct VFIOGroup; - typedef struct VFIOContainer { - VFIOContainerBase bcontainer; - int fd; /* /dev/vfio/vfio, empowered by the attached groups */ -- MemoryListener listener; - MemoryListener prereg_listener; - unsigned iommu_type; -- Error *error; -- bool initialized; - uint64_t dirty_pgsizes; - uint64_t max_dirty_bitmap_size; - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 8e05b5ac5a..95f8d319e0 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -36,6 +36,9 @@ typedef struct VFIOAddressSpace { - typedef struct VFIOContainerBase { - const VFIOIOMMUOps *ops; - VFIOAddressSpace *space; -+ MemoryListener listener; -+ Error *error; -+ bool initialized; - unsigned long pgsizes; - unsigned int dma_max_mappings; - bool dirty_pages_supported; --- -2.39.3 - diff --git a/kvm-vfio-container-Move-per-container-device-list-in-bas.patch b/kvm-vfio-container-Move-per-container-device-list-in-bas.patch deleted file mode 100644 index df483e3..0000000 --- a/kvm-vfio-container-Move-per-container-device-list-in-bas.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 0b3fbb6bf5c5bccec184829ff9454fd637c512b9 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:34 +0800 -Subject: [PATCH 009/101] vfio/container: Move per container device list in - base container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [8/67] d546cc25f4424b2d42356765c860fdaf4a3ba652 (eauger1/centos-qemu-kvm) - -VFIO Device is also changed to point to base container instead of -legacy container. - -No functional change intended. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit 3e6015d1117579324b456aa169dfca06da9922cf) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 23 +++++++++++++++-------- - hw/vfio/container.c | 12 ++++++------ - include/hw/vfio/vfio-common.h | 3 +-- - include/hw/vfio/vfio-container-base.h | 1 + - 4 files changed, 23 insertions(+), 16 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index b1a875ca93..9415395ed9 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -145,7 +145,7 @@ void vfio_unblock_multiple_devices_migration(void) - - bool vfio_viommu_preset(VFIODevice *vbasedev) - { -- return vbasedev->container->bcontainer.space->as != &address_space_memory; -+ return vbasedev->bcontainer->space->as != &address_space_memory; - } - - static void vfio_set_migration_error(int err) -@@ -179,6 +179,7 @@ bool vfio_device_state_is_precopy(VFIODevice *vbasedev) - - static bool vfio_devices_all_dirty_tracking(VFIOContainer *container) - { -+ VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - MigrationState *ms = migrate_get_current(); - -@@ -187,7 +188,7 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer *container) - return false; - } - -- QLIST_FOREACH(vbasedev, &container->device_list, container_next) { -+ QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - VFIOMigration *migration = vbasedev->migration; - - if (!migration) { -@@ -205,9 +206,10 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer *container) - - bool vfio_devices_all_device_dirty_tracking(VFIOContainer *container) - { -+ VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - -- QLIST_FOREACH(vbasedev, &container->device_list, container_next) { -+ QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - if (!vbasedev->dirty_pages_supported) { - return false; - } -@@ -222,13 +224,14 @@ bool vfio_devices_all_device_dirty_tracking(VFIOContainer *container) - */ - bool vfio_devices_all_running_and_mig_active(VFIOContainer *container) - { -+ VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - - if (!migration_is_active(migrate_get_current())) { - return false; - } - -- QLIST_FOREACH(vbasedev, &container->device_list, container_next) { -+ QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - VFIOMigration *migration = vbasedev->migration; - - if (!migration) { -@@ -833,12 +836,13 @@ static bool vfio_section_is_vfio_pci(MemoryRegionSection *section, - VFIOContainer *container) - { - VFIOPCIDevice *pcidev; -+ VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - Object *owner; - - owner = memory_region_owner(section->mr); - -- QLIST_FOREACH(vbasedev, &container->device_list, container_next) { -+ QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - if (vbasedev->type != VFIO_DEVICE_TYPE_PCI) { - continue; - } -@@ -939,13 +943,14 @@ static void vfio_devices_dma_logging_stop(VFIOContainer *container) - uint64_t buf[DIV_ROUND_UP(sizeof(struct vfio_device_feature), - sizeof(uint64_t))] = {}; - struct vfio_device_feature *feature = (struct vfio_device_feature *)buf; -+ VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - - feature->argsz = sizeof(buf); - feature->flags = VFIO_DEVICE_FEATURE_SET | - VFIO_DEVICE_FEATURE_DMA_LOGGING_STOP; - -- QLIST_FOREACH(vbasedev, &container->device_list, container_next) { -+ QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - if (!vbasedev->dirty_tracking) { - continue; - } -@@ -1036,6 +1041,7 @@ static int vfio_devices_dma_logging_start(VFIOContainer *container) - { - struct vfio_device_feature *feature; - VFIODirtyRanges ranges; -+ VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - int ret = 0; - -@@ -1046,7 +1052,7 @@ static int vfio_devices_dma_logging_start(VFIOContainer *container) - return -errno; - } - -- QLIST_FOREACH(vbasedev, &container->device_list, container_next) { -+ QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - if (vbasedev->dirty_tracking) { - continue; - } -@@ -1139,10 +1145,11 @@ int vfio_devices_query_dirty_bitmap(VFIOContainer *container, - VFIOBitmap *vbmap, hwaddr iova, - hwaddr size) - { -+ VFIOContainerBase *bcontainer = &container->bcontainer; - VFIODevice *vbasedev; - int ret; - -- QLIST_FOREACH(vbasedev, &container->device_list, container_next) { -+ QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - ret = vfio_device_dma_logging_report(vbasedev, iova, size, - vbmap->bitmap); - if (ret) { -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 3ab74e2615..63a906de93 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -888,7 +888,7 @@ int vfio_attach_device(char *name, VFIODevice *vbasedev, - int groupid = vfio_device_groupid(vbasedev, errp); - VFIODevice *vbasedev_iter; - VFIOGroup *group; -- VFIOContainer *container; -+ VFIOContainerBase *bcontainer; - int ret; - - if (groupid < 0) { -@@ -915,9 +915,9 @@ int vfio_attach_device(char *name, VFIODevice *vbasedev, - return ret; - } - -- container = group->container; -- vbasedev->container = container; -- QLIST_INSERT_HEAD(&container->device_list, vbasedev, container_next); -+ bcontainer = &group->container->bcontainer; -+ vbasedev->bcontainer = bcontainer; -+ QLIST_INSERT_HEAD(&bcontainer->device_list, vbasedev, container_next); - QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next); - - return ret; -@@ -927,13 +927,13 @@ void vfio_detach_device(VFIODevice *vbasedev) - { - VFIOGroup *group = vbasedev->group; - -- if (!vbasedev->container) { -+ if (!vbasedev->bcontainer) { - return; - } - - QLIST_REMOVE(vbasedev, global_next); - QLIST_REMOVE(vbasedev, container_next); -- vbasedev->container = NULL; -+ vbasedev->bcontainer = NULL; - trace_vfio_detach_device(vbasedev->name, group->groupid); - vfio_put_base_device(vbasedev); - vfio_put_group(group); -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 60f2785fe0..9740cf9fbc 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -90,7 +90,6 @@ typedef struct VFIOContainer { - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; - QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; -- QLIST_HEAD(, VFIODevice) device_list; - GList *iova_ranges; - } VFIOContainer; - -@@ -118,7 +117,7 @@ typedef struct VFIODevice { - QLIST_ENTRY(VFIODevice) container_next; - QLIST_ENTRY(VFIODevice) global_next; - struct VFIOGroup *group; -- VFIOContainer *container; -+ VFIOContainerBase *bcontainer; - char *sysfsdev; - char *name; - DeviceState *dev; -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index f244f003d0..7090962496 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -39,6 +39,7 @@ typedef struct VFIOContainerBase { - bool dirty_pages_supported; - QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; - QLIST_ENTRY(VFIOContainerBase) next; -+ QLIST_HEAD(, VFIODevice) device_list; - } VFIOContainerBase; - - typedef struct VFIOGuestIOMMU { --- -2.39.3 - diff --git a/kvm-vfio-container-Move-pgsizes-and-dma_max_mappings-to-.patch b/kvm-vfio-container-Move-pgsizes-and-dma_max_mappings-to-.patch deleted file mode 100644 index 0db20c2..0000000 --- a/kvm-vfio-container-Move-pgsizes-and-dma_max_mappings-to-.patch +++ /dev/null @@ -1,242 +0,0 @@ -From d798939fbbe6c27200c165edd6f3771413821b34 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 2 Nov 2023 15:12:36 +0800 -Subject: [PATCH 011/101] vfio/container: Move pgsizes and dma_max_mappings to - base container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [10/67] e80696175aba159a17ce9a869535db66682deb08 (eauger1/centos-qemu-kvm) - -No functional change intended. - -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Yi Sun -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit 7ab1cb74ffdbf92ef237243b41bde5c7067d5298) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 17 +++++++++-------- - hw/vfio/container-base.c | 1 + - hw/vfio/container.c | 11 +++++------ - hw/vfio/spapr.c | 10 ++++++---- - include/hw/vfio/vfio-common.h | 2 -- - include/hw/vfio/vfio-container-base.h | 2 ++ - 6 files changed, 23 insertions(+), 20 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index cf6618f6ed..1cb53d369e 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -401,6 +401,7 @@ static int vfio_ram_discard_notify_populate(RamDiscardListener *rdl, - static void vfio_register_ram_discard_listener(VFIOContainer *container, - MemoryRegionSection *section) - { -+ VFIOContainerBase *bcontainer = &container->bcontainer; - RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr); - VFIORamDiscardListener *vrdl; - -@@ -419,8 +420,8 @@ static void vfio_register_ram_discard_listener(VFIOContainer *container, - section->mr); - - g_assert(vrdl->granularity && is_power_of_2(vrdl->granularity)); -- g_assert(container->pgsizes && -- vrdl->granularity >= 1ULL << ctz64(container->pgsizes)); -+ g_assert(bcontainer->pgsizes && -+ vrdl->granularity >= 1ULL << ctz64(bcontainer->pgsizes)); - - ram_discard_listener_init(&vrdl->listener, - vfio_ram_discard_notify_populate, -@@ -441,7 +442,7 @@ static void vfio_register_ram_discard_listener(VFIOContainer *container, - * number of sections in the address space we could have over time, - * also consuming DMA mappings. - */ -- if (container->dma_max_mappings) { -+ if (bcontainer->dma_max_mappings) { - unsigned int vrdl_count = 0, vrdl_mappings = 0, max_memslots = 512; - - #ifdef CONFIG_KVM -@@ -462,11 +463,11 @@ static void vfio_register_ram_discard_listener(VFIOContainer *container, - } - - if (vrdl_mappings + max_memslots - vrdl_count > -- container->dma_max_mappings) { -+ bcontainer->dma_max_mappings) { - warn_report("%s: possibly running out of DMA mappings. E.g., try" - " increasing the 'block-size' of virtio-mem devies." - " Maximum possible DMA mappings: %d, Maximum possible" -- " memslots: %d", __func__, container->dma_max_mappings, -+ " memslots: %d", __func__, bcontainer->dma_max_mappings, - max_memslots); - } - } -@@ -626,7 +627,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - iommu_idx); - - ret = memory_region_iommu_set_page_size_mask(giommu->iommu_mr, -- container->pgsizes, -+ bcontainer->pgsizes, - &err); - if (ret) { - g_free(giommu); -@@ -675,7 +676,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - llsize = int128_sub(llend, int128_make64(iova)); - - if (memory_region_is_ram_device(section->mr)) { -- hwaddr pgmask = (1ULL << ctz64(container->pgsizes)) - 1; -+ hwaddr pgmask = (1ULL << ctz64(bcontainer->pgsizes)) - 1; - - if ((iova & pgmask) || (int128_get64(llsize) & pgmask)) { - trace_vfio_listener_region_add_no_dma_map( -@@ -777,7 +778,7 @@ static void vfio_listener_region_del(MemoryListener *listener, - if (memory_region_is_ram_device(section->mr)) { - hwaddr pgmask; - -- pgmask = (1ULL << ctz64(container->pgsizes)) - 1; -+ pgmask = (1ULL << ctz64(bcontainer->pgsizes)) - 1; - try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask)); - } else if (memory_region_has_ram_discard_manager(section->mr)) { - vfio_unregister_ram_discard_listener(container, section); -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 5d654ae172..dcce111349 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -52,6 +52,7 @@ void vfio_container_init(VFIOContainerBase *bcontainer, VFIOAddressSpace *space, - bcontainer->ops = ops; - bcontainer->space = space; - bcontainer->dirty_pages_supported = false; -+ bcontainer->dma_max_mappings = 0; - QLIST_INIT(&bcontainer->giommu_list); - } - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 7bd81eab09..c5a6262882 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -154,7 +154,7 @@ static int vfio_legacy_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, - if (errno == EINVAL && unmap.size && !(unmap.iova + unmap.size) && - container->iommu_type == VFIO_TYPE1v2_IOMMU) { - trace_vfio_legacy_dma_unmap_overflow_workaround(); -- unmap.size -= 1ULL << ctz64(container->pgsizes); -+ unmap.size -= 1ULL << ctz64(bcontainer->pgsizes); - continue; - } - error_report("VFIO_UNMAP_DMA failed: %s", strerror(errno)); -@@ -559,7 +559,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - container = g_malloc0(sizeof(*container)); - container->fd = fd; - container->error = NULL; -- container->dma_max_mappings = 0; - container->iova_ranges = NULL; - QLIST_INIT(&container->vrdl_list); - bcontainer = &container->bcontainer; -@@ -589,13 +588,13 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - } - - if (info->flags & VFIO_IOMMU_INFO_PGSIZES) { -- container->pgsizes = info->iova_pgsizes; -+ bcontainer->pgsizes = info->iova_pgsizes; - } else { -- container->pgsizes = qemu_real_host_page_size(); -+ bcontainer->pgsizes = qemu_real_host_page_size(); - } - -- if (!vfio_get_info_dma_avail(info, &container->dma_max_mappings)) { -- container->dma_max_mappings = 65535; -+ if (!vfio_get_info_dma_avail(info, &bcontainer->dma_max_mappings)) { -+ bcontainer->dma_max_mappings = 65535; - } - - vfio_get_info_iova_range(info, container); -diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c -index 83da2f7ec2..4f76bdd3ca 100644 ---- a/hw/vfio/spapr.c -+++ b/hw/vfio/spapr.c -@@ -226,6 +226,7 @@ static int vfio_spapr_create_window(VFIOContainer *container, - hwaddr *pgsize) - { - int ret = 0; -+ VFIOContainerBase *bcontainer = &container->bcontainer; - IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr); - uint64_t pagesize = memory_region_iommu_get_min_page_size(iommu_mr), pgmask; - unsigned entries, bits_total, bits_per_level, max_levels; -@@ -239,13 +240,13 @@ static int vfio_spapr_create_window(VFIOContainer *container, - if (pagesize > rampagesize) { - pagesize = rampagesize; - } -- pgmask = container->pgsizes & (pagesize | (pagesize - 1)); -+ pgmask = bcontainer->pgsizes & (pagesize | (pagesize - 1)); - pagesize = pgmask ? (1ULL << (63 - clz64(pgmask))) : 0; - if (!pagesize) { - error_report("Host doesn't support page size 0x%"PRIx64 - ", the supported mask is 0x%lx", - memory_region_iommu_get_min_page_size(iommu_mr), -- container->pgsizes); -+ bcontainer->pgsizes); - return -EINVAL; - } - -@@ -421,6 +422,7 @@ void vfio_container_del_section_window(VFIOContainer *container, - - int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - { -+ VFIOContainerBase *bcontainer = &container->bcontainer; - struct vfio_iommu_spapr_tce_info info; - bool v2 = container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU; - int ret, fd = container->fd; -@@ -461,7 +463,7 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - } - - if (v2) { -- container->pgsizes = info.ddw.pgsizes; -+ bcontainer->pgsizes = info.ddw.pgsizes; - /* - * There is a default window in just created container. - * To make region_add/del simpler, we better remove this -@@ -476,7 +478,7 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - } - } else { - /* The default table uses 4K pages */ -- container->pgsizes = 0x1000; -+ bcontainer->pgsizes = 0x1000; - vfio_host_win_add(container, info.dma32_window_start, - info.dma32_window_start + - info.dma32_window_size - 1, -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index bc67e1316c..d3dc2f9dcb 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -85,8 +85,6 @@ typedef struct VFIOContainer { - bool initialized; - uint64_t dirty_pgsizes; - uint64_t max_dirty_bitmap_size; -- unsigned long pgsizes; -- unsigned int dma_max_mappings; - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; - QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 7090962496..85ec7e1a56 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -36,6 +36,8 @@ typedef struct VFIOAddressSpace { - typedef struct VFIOContainerBase { - const VFIOIOMMUOps *ops; - VFIOAddressSpace *space; -+ unsigned long pgsizes; -+ unsigned int dma_max_mappings; - bool dirty_pages_supported; - QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; - QLIST_ENTRY(VFIOContainerBase) next; --- -2.39.3 - diff --git a/kvm-vfio-container-Move-space-field-to-base-container.patch b/kvm-vfio-container-Move-space-field-to-base-container.patch deleted file mode 100644 index edd4538..0000000 --- a/kvm-vfio-container-Move-space-field-to-base-container.patch +++ /dev/null @@ -1,265 +0,0 @@ -From 3ba43cbc5b096feed6272e070cf152d5fc74df01 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 2 Nov 2023 15:12:32 +0800 -Subject: [PATCH 007/101] vfio/container: Move space field to base container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [6/67] b0aa17d9ec4588bd64373452a30306e826234d0b (eauger1/centos-qemu-kvm) - -Move the space field to the base object. Also the VFIOAddressSpace -now contains a list of base containers. - -No functional change intended. - -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Yi Sun -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit e5597063386a0c76308ad16da31726d23f489945) -Signed-off-by: Eric Auger ---- - hw/ppc/spapr_pci_vfio.c | 10 +++++----- - hw/vfio/common.c | 4 ++-- - hw/vfio/container-base.c | 6 +++++- - hw/vfio/container.c | 18 ++++++++---------- - include/hw/vfio/vfio-common.h | 8 -------- - include/hw/vfio/vfio-container-base.h | 9 +++++++++ - 6 files changed, 29 insertions(+), 26 deletions(-) - -diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c -index f283f7e38d..d1d07bec46 100644 ---- a/hw/ppc/spapr_pci_vfio.c -+++ b/hw/ppc/spapr_pci_vfio.c -@@ -84,27 +84,27 @@ static int vfio_eeh_container_op(VFIOContainer *container, uint32_t op) - static VFIOContainer *vfio_eeh_as_container(AddressSpace *as) - { - VFIOAddressSpace *space = vfio_get_address_space(as); -- VFIOContainer *container = NULL; -+ VFIOContainerBase *bcontainer = NULL; - - if (QLIST_EMPTY(&space->containers)) { - /* No containers to act on */ - goto out; - } - -- container = QLIST_FIRST(&space->containers); -+ bcontainer = QLIST_FIRST(&space->containers); - -- if (QLIST_NEXT(container, next)) { -+ if (QLIST_NEXT(bcontainer, next)) { - /* - * We don't yet have logic to synchronize EEH state across - * multiple containers - */ -- container = NULL; -+ bcontainer = NULL; - goto out; - } - - out: - vfio_put_address_space(space); -- return container; -+ return container_of(bcontainer, VFIOContainer, bcontainer); - } - - static bool vfio_eeh_as_ok(AddressSpace *as) -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 43580bcc43..1d8202537e 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -145,7 +145,7 @@ void vfio_unblock_multiple_devices_migration(void) - - bool vfio_viommu_preset(VFIODevice *vbasedev) - { -- return vbasedev->container->space->as != &address_space_memory; -+ return vbasedev->container->bcontainer.space->as != &address_space_memory; - } - - static void vfio_set_migration_error(int err) -@@ -922,7 +922,7 @@ static void vfio_dirty_tracking_init(VFIOContainer *container, - dirty.container = container; - - memory_listener_register(&dirty.listener, -- container->space->as); -+ container->bcontainer.space->as); - - *ranges = dirty.ranges; - -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 20bcb9669a..3933391e0d 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -31,9 +31,11 @@ int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, - return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb); - } - --void vfio_container_init(VFIOContainerBase *bcontainer, const VFIOIOMMUOps *ops) -+void vfio_container_init(VFIOContainerBase *bcontainer, VFIOAddressSpace *space, -+ const VFIOIOMMUOps *ops) - { - bcontainer->ops = ops; -+ bcontainer->space = space; - QLIST_INIT(&bcontainer->giommu_list); - } - -@@ -41,6 +43,8 @@ void vfio_container_destroy(VFIOContainerBase *bcontainer) - { - VFIOGuestIOMMU *giommu, *tmp; - -+ QLIST_REMOVE(bcontainer, next); -+ - QLIST_FOREACH_SAFE(giommu, &bcontainer->giommu_list, giommu_next, tmp) { - memory_region_unregister_iommu_notifier( - MEMORY_REGION(giommu->iommu_mr), &giommu->n); -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 133d3c8f5c..f12fcb6fe1 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -514,7 +514,8 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - * details once we know which type of IOMMU we are using. - */ - -- QLIST_FOREACH(container, &space->containers, next) { -+ QLIST_FOREACH(bcontainer, &space->containers, next) { -+ container = container_of(bcontainer, VFIOContainer, bcontainer); - if (!ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) { - ret = vfio_ram_block_discard_disable(container, true); - if (ret) { -@@ -550,7 +551,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - } - - container = g_malloc0(sizeof(*container)); -- container->space = space; - container->fd = fd; - container->error = NULL; - container->dirty_pages_supported = false; -@@ -558,7 +558,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - container->iova_ranges = NULL; - QLIST_INIT(&container->vrdl_list); - bcontainer = &container->bcontainer; -- vfio_container_init(bcontainer, &vfio_legacy_ops); -+ vfio_container_init(bcontainer, space, &vfio_legacy_ops); - - ret = vfio_init_container(container, group->fd, errp); - if (ret) { -@@ -613,14 +613,14 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - vfio_kvm_device_add_group(group); - - QLIST_INIT(&container->group_list); -- QLIST_INSERT_HEAD(&space->containers, container, next); -+ QLIST_INSERT_HEAD(&space->containers, bcontainer, next); - - group->container = container; - QLIST_INSERT_HEAD(&container->group_list, group, container_next); - - container->listener = vfio_memory_listener; - -- memory_listener_register(&container->listener, container->space->as); -+ memory_listener_register(&container->listener, bcontainer->space->as); - - if (container->error) { - ret = -1; -@@ -634,7 +634,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - return 0; - listener_release_exit: - QLIST_REMOVE(group, container_next); -- QLIST_REMOVE(container, next); -+ QLIST_REMOVE(bcontainer, next); - vfio_kvm_device_del_group(group); - memory_listener_unregister(&container->listener); - if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU || -@@ -684,9 +684,7 @@ static void vfio_disconnect_container(VFIOGroup *group) - } - - if (QLIST_EMPTY(&container->group_list)) { -- VFIOAddressSpace *space = container->space; -- -- QLIST_REMOVE(container, next); -+ VFIOAddressSpace *space = bcontainer->space; - - vfio_container_destroy(bcontainer); - -@@ -707,7 +705,7 @@ static VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp) - QLIST_FOREACH(group, &vfio_group_list, next) { - if (group->groupid == groupid) { - /* Found it. Now is it already in the right context? */ -- if (group->container->space->as == as) { -+ if (group->container->bcontainer.space->as == as) { - return group; - } else { - error_setg(errp, "group %d used in multiple address spaces", -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 6be082b8f2..bd4de6cb3a 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -73,17 +73,10 @@ typedef struct VFIOMigration { - bool initial_data_sent; - } VFIOMigration; - --typedef struct VFIOAddressSpace { -- AddressSpace *as; -- QLIST_HEAD(, VFIOContainer) containers; -- QLIST_ENTRY(VFIOAddressSpace) list; --} VFIOAddressSpace; -- - struct VFIOGroup; - - typedef struct VFIOContainer { - VFIOContainerBase bcontainer; -- VFIOAddressSpace *space; - int fd; /* /dev/vfio/vfio, empowered by the attached groups */ - MemoryListener listener; - MemoryListener prereg_listener; -@@ -98,7 +91,6 @@ typedef struct VFIOContainer { - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; - QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; -- QLIST_ENTRY(VFIOContainer) next; - QLIST_HEAD(, VFIODevice) device_list; - GList *iova_ranges; - } VFIOContainer; -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index a11aec5755..c7cc6ec9c5 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -24,12 +24,20 @@ typedef struct { - hwaddr pages; - } VFIOBitmap; - -+typedef struct VFIOAddressSpace { -+ AddressSpace *as; -+ QLIST_HEAD(, VFIOContainerBase) containers; -+ QLIST_ENTRY(VFIOAddressSpace) list; -+} VFIOAddressSpace; -+ - /* - * This is the base object for vfio container backends - */ - typedef struct VFIOContainerBase { - const VFIOIOMMUOps *ops; -+ VFIOAddressSpace *space; - QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; -+ QLIST_ENTRY(VFIOContainerBase) next; - } VFIOContainerBase; - - typedef struct VFIOGuestIOMMU { -@@ -48,6 +56,7 @@ int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, - IOMMUTLBEntry *iotlb); - - void vfio_container_init(VFIOContainerBase *bcontainer, -+ VFIOAddressSpace *space, - const VFIOIOMMUOps *ops); - void vfio_container_destroy(VFIOContainerBase *bcontainer); - --- -2.39.3 - diff --git a/kvm-vfio-container-Move-vrdl_list-to-base-container.patch b/kvm-vfio-container-Move-vrdl_list-to-base-container.patch deleted file mode 100644 index 5e31d07..0000000 --- a/kvm-vfio-container-Move-vrdl_list-to-base-container.patch +++ /dev/null @@ -1,255 +0,0 @@ -From aadd055dcc06cb964ebfd2868b7e9b207d62ae0e Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:37 +0800 -Subject: [PATCH 012/101] vfio/container: Move vrdl_list to base container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [11/67] 42da5389e39291839259f0e4c020c7461b7225cc (eauger1/centos-qemu-kvm) - -No functional change intended. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit dc74a4b0056c0c803d46612a2319294921097974) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 38 +++++++++++++-------------- - hw/vfio/container-base.c | 1 + - hw/vfio/container.c | 1 - - include/hw/vfio/vfio-common.h | 11 -------- - include/hw/vfio/vfio-container-base.h | 11 ++++++++ - 5 files changed, 31 insertions(+), 31 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 1cb53d369e..f15665789f 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -351,13 +351,13 @@ static void vfio_ram_discard_notify_discard(RamDiscardListener *rdl, - { - VFIORamDiscardListener *vrdl = container_of(rdl, VFIORamDiscardListener, - listener); -+ VFIOContainerBase *bcontainer = vrdl->bcontainer; - const hwaddr size = int128_get64(section->size); - const hwaddr iova = section->offset_within_address_space; - int ret; - - /* Unmap with a single call. */ -- ret = vfio_container_dma_unmap(&vrdl->container->bcontainer, -- iova, size , NULL); -+ ret = vfio_container_dma_unmap(bcontainer, iova, size , NULL); - if (ret) { - error_report("%s: vfio_container_dma_unmap() failed: %s", __func__, - strerror(-ret)); -@@ -369,6 +369,7 @@ static int vfio_ram_discard_notify_populate(RamDiscardListener *rdl, - { - VFIORamDiscardListener *vrdl = container_of(rdl, VFIORamDiscardListener, - listener); -+ VFIOContainerBase *bcontainer = vrdl->bcontainer; - const hwaddr end = section->offset_within_region + - int128_get64(section->size); - hwaddr start, next, iova; -@@ -387,8 +388,8 @@ static int vfio_ram_discard_notify_populate(RamDiscardListener *rdl, - section->offset_within_address_space; - vaddr = memory_region_get_ram_ptr(section->mr) + start; - -- ret = vfio_container_dma_map(&vrdl->container->bcontainer, iova, -- next - start, vaddr, section->readonly); -+ ret = vfio_container_dma_map(bcontainer, iova, next - start, -+ vaddr, section->readonly); - if (ret) { - /* Rollback */ - vfio_ram_discard_notify_discard(rdl, section); -@@ -398,10 +399,9 @@ static int vfio_ram_discard_notify_populate(RamDiscardListener *rdl, - return 0; - } - --static void vfio_register_ram_discard_listener(VFIOContainer *container, -+static void vfio_register_ram_discard_listener(VFIOContainerBase *bcontainer, - MemoryRegionSection *section) - { -- VFIOContainerBase *bcontainer = &container->bcontainer; - RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr); - VFIORamDiscardListener *vrdl; - -@@ -412,7 +412,7 @@ static void vfio_register_ram_discard_listener(VFIOContainer *container, - g_assert(QEMU_IS_ALIGNED(int128_get64(section->size), TARGET_PAGE_SIZE)); - - vrdl = g_new0(VFIORamDiscardListener, 1); -- vrdl->container = container; -+ vrdl->bcontainer = bcontainer; - vrdl->mr = section->mr; - vrdl->offset_within_address_space = section->offset_within_address_space; - vrdl->size = int128_get64(section->size); -@@ -427,7 +427,7 @@ static void vfio_register_ram_discard_listener(VFIOContainer *container, - vfio_ram_discard_notify_populate, - vfio_ram_discard_notify_discard, true); - ram_discard_manager_register_listener(rdm, &vrdl->listener, section); -- QLIST_INSERT_HEAD(&container->vrdl_list, vrdl, next); -+ QLIST_INSERT_HEAD(&bcontainer->vrdl_list, vrdl, next); - - /* - * Sanity-check if we have a theoretically problematic setup where we could -@@ -451,7 +451,7 @@ static void vfio_register_ram_discard_listener(VFIOContainer *container, - } - #endif - -- QLIST_FOREACH(vrdl, &container->vrdl_list, next) { -+ QLIST_FOREACH(vrdl, &bcontainer->vrdl_list, next) { - hwaddr start, end; - - start = QEMU_ALIGN_DOWN(vrdl->offset_within_address_space, -@@ -473,13 +473,13 @@ static void vfio_register_ram_discard_listener(VFIOContainer *container, - } - } - --static void vfio_unregister_ram_discard_listener(VFIOContainer *container, -+static void vfio_unregister_ram_discard_listener(VFIOContainerBase *bcontainer, - MemoryRegionSection *section) - { - RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr); - VFIORamDiscardListener *vrdl = NULL; - -- QLIST_FOREACH(vrdl, &container->vrdl_list, next) { -+ QLIST_FOREACH(vrdl, &bcontainer->vrdl_list, next) { - if (vrdl->mr == section->mr && - vrdl->offset_within_address_space == - section->offset_within_address_space) { -@@ -663,7 +663,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - * about changes. - */ - if (memory_region_has_ram_discard_manager(section->mr)) { -- vfio_register_ram_discard_listener(container, section); -+ vfio_register_ram_discard_listener(bcontainer, section); - return; - } - -@@ -781,7 +781,7 @@ static void vfio_listener_region_del(MemoryListener *listener, - pgmask = (1ULL << ctz64(bcontainer->pgsizes)) - 1; - try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask)); - } else if (memory_region_has_ram_discard_manager(section->mr)) { -- vfio_unregister_ram_discard_listener(container, section); -+ vfio_unregister_ram_discard_listener(bcontainer, section); - /* Unregistering will trigger an unmap. */ - try_unmap = false; - } -@@ -1260,17 +1260,17 @@ static int vfio_ram_discard_get_dirty_bitmap(MemoryRegionSection *section, - * Sync the whole mapped region (spanning multiple individual mappings) - * in one go. - */ -- return vfio_get_dirty_bitmap(&vrdl->container->bcontainer, iova, size, -- ram_addr); -+ return vfio_get_dirty_bitmap(vrdl->bcontainer, iova, size, ram_addr); - } - --static int vfio_sync_ram_discard_listener_dirty_bitmap(VFIOContainer *container, -- MemoryRegionSection *section) -+static int -+vfio_sync_ram_discard_listener_dirty_bitmap(VFIOContainerBase *bcontainer, -+ MemoryRegionSection *section) - { - RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr); - VFIORamDiscardListener *vrdl = NULL; - -- QLIST_FOREACH(vrdl, &container->vrdl_list, next) { -+ QLIST_FOREACH(vrdl, &bcontainer->vrdl_list, next) { - if (vrdl->mr == section->mr && - vrdl->offset_within_address_space == - section->offset_within_address_space) { -@@ -1324,7 +1324,7 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container, - } - return 0; - } else if (memory_region_has_ram_discard_manager(section->mr)) { -- return vfio_sync_ram_discard_listener_dirty_bitmap(container, section); -+ return vfio_sync_ram_discard_listener_dirty_bitmap(bcontainer, section); - } - - ram_addr = memory_region_get_ram_addr(section->mr) + -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index dcce111349..584eee4ba1 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -54,6 +54,7 @@ void vfio_container_init(VFIOContainerBase *bcontainer, VFIOAddressSpace *space, - bcontainer->dirty_pages_supported = false; - bcontainer->dma_max_mappings = 0; - QLIST_INIT(&bcontainer->giommu_list); -+ QLIST_INIT(&bcontainer->vrdl_list); - } - - void vfio_container_destroy(VFIOContainerBase *bcontainer) -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index c5a6262882..6ba2e2f8c4 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -560,7 +560,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - container->fd = fd; - container->error = NULL; - container->iova_ranges = NULL; -- QLIST_INIT(&container->vrdl_list); - bcontainer = &container->bcontainer; - vfio_container_init(bcontainer, space, &vfio_legacy_ops); - -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index d3dc2f9dcb..8a607a4c17 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -87,20 +87,9 @@ typedef struct VFIOContainer { - uint64_t max_dirty_bitmap_size; - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; -- QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; - GList *iova_ranges; - } VFIOContainer; - --typedef struct VFIORamDiscardListener { -- VFIOContainer *container; -- MemoryRegion *mr; -- hwaddr offset_within_address_space; -- hwaddr size; -- uint64_t granularity; -- RamDiscardListener listener; -- QLIST_ENTRY(VFIORamDiscardListener) next; --} VFIORamDiscardListener; -- - typedef struct VFIOHostDMAWindow { - hwaddr min_iova; - hwaddr max_iova; -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 85ec7e1a56..8e05b5ac5a 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -40,6 +40,7 @@ typedef struct VFIOContainerBase { - unsigned int dma_max_mappings; - bool dirty_pages_supported; - QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; -+ QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; - QLIST_ENTRY(VFIOContainerBase) next; - QLIST_HEAD(, VFIODevice) device_list; - } VFIOContainerBase; -@@ -52,6 +53,16 @@ typedef struct VFIOGuestIOMMU { - QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; - } VFIOGuestIOMMU; - -+typedef struct VFIORamDiscardListener { -+ VFIOContainerBase *bcontainer; -+ MemoryRegion *mr; -+ hwaddr offset_within_address_space; -+ hwaddr size; -+ uint64_t granularity; -+ RamDiscardListener listener; -+ QLIST_ENTRY(VFIORamDiscardListener) next; -+} VFIORamDiscardListener; -+ - int vfio_container_dma_map(VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - void *vaddr, bool readonly); --- -2.39.3 - diff --git a/kvm-vfio-container-Rename-vfio_init_container-to-vfio_se.patch b/kvm-vfio-container-Rename-vfio_init_container-to-vfio_se.patch deleted file mode 100644 index f68be0b..0000000 --- a/kvm-vfio-container-Rename-vfio_init_container-to-vfio_se.patch +++ /dev/null @@ -1,66 +0,0 @@ -From edfc1ee2a1854d180ffad92e70212535a2ca668c Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 21 Dec 2023 10:45:17 +0800 -Subject: [PATCH 062/101] vfio/container: Rename vfio_init_container to - vfio_set_iommu -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [61/67] 5e7f956379b54fe6fa7e078ec17e71325aa109af (eauger1/centos-qemu-kvm) - -vfio_container_init() and vfio_init_container() names are confusing -especially when we see vfio_init_container() calls vfio_container_init(). - -vfio_container_init() operates on base container which is consistent -with all routines handling 'VFIOContainerBase *' ops. - -vfio_init_container() operates on legacy container and setup IOMMU -context with ioctl(VFIO_SET_IOMMU). - -So choose to rename vfio_init_container to vfio_set_iommu to avoid -the confusion. - -No functional change intended. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -(cherry picked from commit 9f734a117cbf63b03577b46c8cad8ad88ec6dced) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 8d334f52f2..bd25b9fbad 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -392,8 +392,8 @@ static const VFIOIOMMUClass *vfio_get_iommu_class(int iommu_type, Error **errp) - return VFIO_IOMMU_CLASS(klass); - } - --static int vfio_init_container(VFIOContainer *container, int group_fd, -- VFIOAddressSpace *space, Error **errp) -+static int vfio_set_iommu(VFIOContainer *container, int group_fd, -+ VFIOAddressSpace *space, Error **errp) - { - int iommu_type, ret; - const VFIOIOMMUClass *vioc; -@@ -616,7 +616,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - container->fd = fd; - bcontainer = &container->bcontainer; - -- ret = vfio_init_container(container, group->fd, space, errp); -+ ret = vfio_set_iommu(container, group->fd, space, errp); - if (ret) { - goto free_container_exit; - } --- -2.39.3 - diff --git a/kvm-vfio-container-Replace-basename-with-g_path_get_base.patch b/kvm-vfio-container-Replace-basename-with-g_path_get_base.patch deleted file mode 100644 index 77df179..0000000 --- a/kvm-vfio-container-Replace-basename-with-g_path_get_base.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 8d3857c7877da58ed0c6b62cf2714c4127350522 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Wed, 20 Dec 2023 14:53:02 +0100 -Subject: [PATCH 059/101] vfio/container: Replace basename with - g_path_get_basename -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [58/67] 56a90f23dadc89271b1fff014fc64ade87c1a4cb (eauger1/centos-qemu-kvm) - -g_path_get_basename() is a portable utility function that has the -advantage of not modifing the string argument. It also fixes a compile -breakage with the Musl C library reported in [1]. - -[1] https://lore.kernel.org/all/20231212010228.2701544-1-raj.khem@gmail.com/ - -Reported-by: Khem Raj -Reviewed-by: Eric Auger -Reviewed-by: Zhao Liu -Reviewed-by: Zhenzhong Duan -Signed-off-by: Cédric Le Goater -(cherry picked from commit 213ae3ffda463c0503e39e0cf827511b5298c314) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 688cf23bab..8d334f52f2 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -869,7 +869,8 @@ static void vfio_put_base_device(VFIODevice *vbasedev) - - static int vfio_device_groupid(VFIODevice *vbasedev, Error **errp) - { -- char *tmp, group_path[PATH_MAX], *group_name; -+ char *tmp, group_path[PATH_MAX]; -+ g_autofree char *group_name = NULL; - int ret, groupid; - ssize_t len; - -@@ -885,7 +886,7 @@ static int vfio_device_groupid(VFIODevice *vbasedev, Error **errp) - - group_path[len] = 0; - -- group_name = basename(group_path); -+ group_name = g_path_get_basename(group_path); - if (sscanf(group_name, "%d", &groupid) != 1) { - error_setg_errno(errp, errno, "failed to read %s", group_path); - return -errno; --- -2.39.3 - diff --git a/kvm-vfio-container-Switch-to-IOMMU-BE-set_dirty_page_tra.patch b/kvm-vfio-container-Switch-to-IOMMU-BE-set_dirty_page_tra.patch deleted file mode 100644 index 5442688..0000000 --- a/kvm-vfio-container-Switch-to-IOMMU-BE-set_dirty_page_tra.patch +++ /dev/null @@ -1,235 +0,0 @@ -From a2c8aa64b1b21a3e1d4cf2a4fe7d84dc32f69284 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 2 Nov 2023 15:12:33 +0800 -Subject: [PATCH 008/101] vfio/container: Switch to IOMMU BE - set_dirty_page_tracking/query_dirty_bitmap API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [7/67] 88368809c7990e1d9b01406e48694fe3e3fb1397 (eauger1/centos-qemu-kvm) - -dirty_pages_supported field is also moved to the base container - -No functional change intended. - -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Yi Sun -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit bb424490edcef73d07f200d53f69415b203d81df) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 12 ++++++++---- - hw/vfio/container-base.c | 16 ++++++++++++++++ - hw/vfio/container.c | 21 ++++++++++++++------- - include/hw/vfio/vfio-common.h | 6 ------ - include/hw/vfio/vfio-container-base.h | 6 ++++++ - 5 files changed, 44 insertions(+), 17 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 1d8202537e..b1a875ca93 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1079,7 +1079,8 @@ static void vfio_listener_log_global_start(MemoryListener *listener) - if (vfio_devices_all_device_dirty_tracking(container)) { - ret = vfio_devices_dma_logging_start(container); - } else { -- ret = vfio_set_dirty_page_tracking(container, true); -+ ret = vfio_container_set_dirty_page_tracking(&container->bcontainer, -+ true); - } - - if (ret) { -@@ -1097,7 +1098,8 @@ static void vfio_listener_log_global_stop(MemoryListener *listener) - if (vfio_devices_all_device_dirty_tracking(container)) { - vfio_devices_dma_logging_stop(container); - } else { -- ret = vfio_set_dirty_page_tracking(container, false); -+ ret = vfio_container_set_dirty_page_tracking(&container->bcontainer, -+ false); - } - - if (ret) { -@@ -1165,7 +1167,8 @@ int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - VFIOBitmap vbmap; - int ret; - -- if (!container->dirty_pages_supported && !all_device_dirty_tracking) { -+ if (!container->bcontainer.dirty_pages_supported && -+ !all_device_dirty_tracking) { - cpu_physical_memory_set_dirty_range(ram_addr, size, - tcg_enabled() ? DIRTY_CLIENTS_ALL : - DIRTY_CLIENTS_NOCODE); -@@ -1180,7 +1183,8 @@ int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - if (all_device_dirty_tracking) { - ret = vfio_devices_query_dirty_bitmap(container, &vbmap, iova, size); - } else { -- ret = vfio_query_dirty_bitmap(container, &vbmap, iova, size); -+ ret = vfio_container_query_dirty_bitmap(&container->bcontainer, &vbmap, -+ iova, size); - } - - if (ret) { -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 3933391e0d..5d654ae172 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -31,11 +31,27 @@ int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, - return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb); - } - -+int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, -+ bool start) -+{ -+ g_assert(bcontainer->ops->set_dirty_page_tracking); -+ return bcontainer->ops->set_dirty_page_tracking(bcontainer, start); -+} -+ -+int vfio_container_query_dirty_bitmap(VFIOContainerBase *bcontainer, -+ VFIOBitmap *vbmap, -+ hwaddr iova, hwaddr size) -+{ -+ g_assert(bcontainer->ops->query_dirty_bitmap); -+ return bcontainer->ops->query_dirty_bitmap(bcontainer, vbmap, iova, size); -+} -+ - void vfio_container_init(VFIOContainerBase *bcontainer, VFIOAddressSpace *space, - const VFIOIOMMUOps *ops) - { - bcontainer->ops = ops; - bcontainer->space = space; -+ bcontainer->dirty_pages_supported = false; - QLIST_INIT(&bcontainer->giommu_list); - } - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index f12fcb6fe1..3ab74e2615 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -131,7 +131,7 @@ static int vfio_legacy_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, - - if (iotlb && vfio_devices_all_running_and_mig_active(container)) { - if (!vfio_devices_all_device_dirty_tracking(container) && -- container->dirty_pages_supported) { -+ container->bcontainer.dirty_pages_supported) { - return vfio_dma_unmap_bitmap(container, iova, size, iotlb); - } - -@@ -205,14 +205,17 @@ static int vfio_legacy_dma_map(VFIOContainerBase *bcontainer, hwaddr iova, - return -errno; - } - --int vfio_set_dirty_page_tracking(VFIOContainer *container, bool start) -+static int vfio_legacy_set_dirty_page_tracking(VFIOContainerBase *bcontainer, -+ bool start) - { -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - int ret; - struct vfio_iommu_type1_dirty_bitmap dirty = { - .argsz = sizeof(dirty), - }; - -- if (!container->dirty_pages_supported) { -+ if (!bcontainer->dirty_pages_supported) { - return 0; - } - -@@ -232,9 +235,12 @@ int vfio_set_dirty_page_tracking(VFIOContainer *container, bool start) - return ret; - } - --int vfio_query_dirty_bitmap(VFIOContainer *container, VFIOBitmap *vbmap, -- hwaddr iova, hwaddr size) -+static int vfio_legacy_query_dirty_bitmap(VFIOContainerBase *bcontainer, -+ VFIOBitmap *vbmap, -+ hwaddr iova, hwaddr size) - { -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - struct vfio_iommu_type1_dirty_bitmap *dbitmap; - struct vfio_iommu_type1_dirty_bitmap_get *range; - int ret; -@@ -461,7 +467,7 @@ static void vfio_get_iommu_info_migration(VFIOContainer *container, - * qemu_real_host_page_size to mark those dirty. - */ - if (cap_mig->pgsize_bitmap & qemu_real_host_page_size()) { -- container->dirty_pages_supported = true; -+ container->bcontainer.dirty_pages_supported = true; - container->max_dirty_bitmap_size = cap_mig->max_dirty_bitmap_size; - container->dirty_pgsizes = cap_mig->pgsize_bitmap; - } -@@ -553,7 +559,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - container = g_malloc0(sizeof(*container)); - container->fd = fd; - container->error = NULL; -- container->dirty_pages_supported = false; - container->dma_max_mappings = 0; - container->iova_ranges = NULL; - QLIST_INIT(&container->vrdl_list); -@@ -937,4 +942,6 @@ void vfio_detach_device(VFIODevice *vbasedev) - const VFIOIOMMUOps vfio_legacy_ops = { - .dma_map = vfio_legacy_dma_map, - .dma_unmap = vfio_legacy_dma_unmap, -+ .set_dirty_page_tracking = vfio_legacy_set_dirty_page_tracking, -+ .query_dirty_bitmap = vfio_legacy_query_dirty_bitmap, - }; -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index bd4de6cb3a..60f2785fe0 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -83,7 +83,6 @@ typedef struct VFIOContainer { - unsigned iommu_type; - Error *error; - bool initialized; -- bool dirty_pages_supported; - uint64_t dirty_pgsizes; - uint64_t max_dirty_bitmap_size; - unsigned long pgsizes; -@@ -190,11 +189,6 @@ VFIOAddressSpace *vfio_get_address_space(AddressSpace *as); - void vfio_put_address_space(VFIOAddressSpace *space); - bool vfio_devices_all_running_and_saving(VFIOContainer *container); - --/* container->fd */ --int vfio_set_dirty_page_tracking(VFIOContainer *container, bool start); --int vfio_query_dirty_bitmap(VFIOContainer *container, VFIOBitmap *vbmap, -- hwaddr iova, hwaddr size); -- - /* SPAPR specific */ - int vfio_container_add_section_window(VFIOContainer *container, - MemoryRegionSection *section, -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index c7cc6ec9c5..f244f003d0 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -36,6 +36,7 @@ typedef struct VFIOAddressSpace { - typedef struct VFIOContainerBase { - const VFIOIOMMUOps *ops; - VFIOAddressSpace *space; -+ bool dirty_pages_supported; - QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; - QLIST_ENTRY(VFIOContainerBase) next; - } VFIOContainerBase; -@@ -54,6 +55,11 @@ int vfio_container_dma_map(VFIOContainerBase *bcontainer, - int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb); -+int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, -+ bool start); -+int vfio_container_query_dirty_bitmap(VFIOContainerBase *bcontainer, -+ VFIOBitmap *vbmap, -+ hwaddr iova, hwaddr size); - - void vfio_container_init(VFIOContainerBase *bcontainer, - VFIOAddressSpace *space, --- -2.39.3 - diff --git a/kvm-vfio-container-Switch-to-dma_map-unmap-API.patch b/kvm-vfio-container-Switch-to-dma_map-unmap-API.patch deleted file mode 100644 index cfb5eb1..0000000 --- a/kvm-vfio-container-Switch-to-dma_map-unmap-API.patch +++ /dev/null @@ -1,303 +0,0 @@ -From 00daef8e3f4f64b1401b2e8945c256d27fbfa960 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 2 Nov 2023 15:12:29 +0800 -Subject: [PATCH 004/101] vfio/container: Switch to dma_map|unmap API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [3/67] 9a20e2f2b277be65463f145df3309271493be6ac (eauger1/centos-qemu-kvm) - -No functional change intended. - -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Yi Sun -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit b08501a999e2448f500a46d68da503be55186b04) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 45 +++++++++++++++------------ - hw/vfio/container-base.c | 32 +++++++++++++++++++ - hw/vfio/container.c | 22 ++++++++----- - hw/vfio/meson.build | 1 + - hw/vfio/trace-events | 2 +- - include/hw/vfio/vfio-common.h | 4 --- - include/hw/vfio/vfio-container-base.h | 7 +++++ - 7 files changed, 81 insertions(+), 32 deletions(-) - create mode 100644 hw/vfio/container-base.c - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index e70fdf5e0c..e610771888 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -292,7 +292,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, - static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - { - VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); -- VFIOContainer *container = giommu->container; -+ VFIOContainerBase *bcontainer = &giommu->container->bcontainer; - hwaddr iova = iotlb->iova + giommu->iommu_offset; - void *vaddr; - int ret; -@@ -322,21 +322,22 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - * of vaddr will always be there, even if the memory object is - * destroyed and its backing memory munmap-ed. - */ -- ret = vfio_dma_map(container, iova, -- iotlb->addr_mask + 1, vaddr, -- read_only); -+ ret = vfio_container_dma_map(bcontainer, iova, -+ iotlb->addr_mask + 1, vaddr, -+ read_only); - if (ret) { -- error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", " -+ error_report("vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx", %p) = %d (%s)", -- container, iova, -+ bcontainer, iova, - iotlb->addr_mask + 1, vaddr, ret, strerror(-ret)); - } - } else { -- ret = vfio_dma_unmap(container, iova, iotlb->addr_mask + 1, iotlb); -+ ret = vfio_container_dma_unmap(bcontainer, iova, -+ iotlb->addr_mask + 1, iotlb); - if (ret) { -- error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -+ error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%s)", -- container, iova, -+ bcontainer, iova, - iotlb->addr_mask + 1, ret, strerror(-ret)); - vfio_set_migration_error(ret); - } -@@ -355,9 +356,10 @@ static void vfio_ram_discard_notify_discard(RamDiscardListener *rdl, - int ret; - - /* Unmap with a single call. */ -- ret = vfio_dma_unmap(vrdl->container, iova, size , NULL); -+ ret = vfio_container_dma_unmap(&vrdl->container->bcontainer, -+ iova, size , NULL); - if (ret) { -- error_report("%s: vfio_dma_unmap() failed: %s", __func__, -+ error_report("%s: vfio_container_dma_unmap() failed: %s", __func__, - strerror(-ret)); - } - } -@@ -385,8 +387,8 @@ static int vfio_ram_discard_notify_populate(RamDiscardListener *rdl, - section->offset_within_address_space; - vaddr = memory_region_get_ram_ptr(section->mr) + start; - -- ret = vfio_dma_map(vrdl->container, iova, next - start, -- vaddr, section->readonly); -+ ret = vfio_container_dma_map(&vrdl->container->bcontainer, iova, -+ next - start, vaddr, section->readonly); - if (ret) { - /* Rollback */ - vfio_ram_discard_notify_discard(rdl, section); -@@ -684,10 +686,11 @@ static void vfio_listener_region_add(MemoryListener *listener, - } - } - -- ret = vfio_dma_map(container, iova, int128_get64(llsize), -- vaddr, section->readonly); -+ ret = vfio_container_dma_map(&container->bcontainer, -+ iova, int128_get64(llsize), vaddr, -+ section->readonly); - if (ret) { -- error_setg(&err, "vfio_dma_map(%p, 0x%"HWADDR_PRIx", " -+ error_setg(&err, "vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx", %p) = %d (%s)", - container, iova, int128_get64(llsize), vaddr, ret, - strerror(-ret)); -@@ -784,18 +787,20 @@ static void vfio_listener_region_del(MemoryListener *listener, - if (int128_eq(llsize, int128_2_64())) { - /* The unmap ioctl doesn't accept a full 64-bit span. */ - llsize = int128_rshift(llsize, 1); -- ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -+ ret = vfio_container_dma_unmap(&container->bcontainer, iova, -+ int128_get64(llsize), NULL); - if (ret) { -- error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -+ error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%s)", - container, iova, int128_get64(llsize), ret, - strerror(-ret)); - } - iova += int128_get64(llsize); - } -- ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -+ ret = vfio_container_dma_unmap(&container->bcontainer, iova, -+ int128_get64(llsize), NULL); - if (ret) { -- error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -+ error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%s)", - container, iova, int128_get64(llsize), ret, - strerror(-ret)); -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -new file mode 100644 -index 0000000000..55d3a35fa4 ---- /dev/null -+++ b/hw/vfio/container-base.c -@@ -0,0 +1,32 @@ -+/* -+ * VFIO BASE CONTAINER -+ * -+ * Copyright (C) 2023 Intel Corporation. -+ * Copyright Red Hat, Inc. 2023 -+ * -+ * Authors: Yi Liu -+ * Eric Auger -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "qemu/error-report.h" -+#include "hw/vfio/vfio-container-base.h" -+ -+int vfio_container_dma_map(VFIOContainerBase *bcontainer, -+ hwaddr iova, ram_addr_t size, -+ void *vaddr, bool readonly) -+{ -+ g_assert(bcontainer->ops->dma_map); -+ return bcontainer->ops->dma_map(bcontainer, iova, size, vaddr, readonly); -+} -+ -+int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, -+ hwaddr iova, ram_addr_t size, -+ IOMMUTLBEntry *iotlb) -+{ -+ g_assert(bcontainer->ops->dma_unmap); -+ return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb); -+} -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 4bc43ddfa4..c04df26323 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -115,9 +115,11 @@ unmap_exit: - /* - * DMA - Mapping and unmapping for the "type1" IOMMU interface used on x86 - */ --int vfio_dma_unmap(VFIOContainer *container, hwaddr iova, -- ram_addr_t size, IOMMUTLBEntry *iotlb) -+static int vfio_legacy_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, -+ ram_addr_t size, IOMMUTLBEntry *iotlb) - { -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - struct vfio_iommu_type1_dma_unmap unmap = { - .argsz = sizeof(unmap), - .flags = 0, -@@ -151,7 +153,7 @@ int vfio_dma_unmap(VFIOContainer *container, hwaddr iova, - */ - if (errno == EINVAL && unmap.size && !(unmap.iova + unmap.size) && - container->iommu_type == VFIO_TYPE1v2_IOMMU) { -- trace_vfio_dma_unmap_overflow_workaround(); -+ trace_vfio_legacy_dma_unmap_overflow_workaround(); - unmap.size -= 1ULL << ctz64(container->pgsizes); - continue; - } -@@ -170,9 +172,11 @@ int vfio_dma_unmap(VFIOContainer *container, hwaddr iova, - return 0; - } - --int vfio_dma_map(VFIOContainer *container, hwaddr iova, -- ram_addr_t size, void *vaddr, bool readonly) -+static int vfio_legacy_dma_map(VFIOContainerBase *bcontainer, hwaddr iova, -+ ram_addr_t size, void *vaddr, bool readonly) - { -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - struct vfio_iommu_type1_dma_map map = { - .argsz = sizeof(map), - .flags = VFIO_DMA_MAP_FLAG_READ, -@@ -191,7 +195,8 @@ int vfio_dma_map(VFIOContainer *container, hwaddr iova, - * the VGA ROM space. - */ - if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0 || -- (errno == EBUSY && vfio_dma_unmap(container, iova, size, NULL) == 0 && -+ (errno == EBUSY && -+ vfio_legacy_dma_unmap(bcontainer, iova, size, NULL) == 0 && - ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0)) { - return 0; - } -@@ -937,4 +942,7 @@ void vfio_detach_device(VFIODevice *vbasedev) - vfio_put_group(group); - } - --const VFIOIOMMUOps vfio_legacy_ops; -+const VFIOIOMMUOps vfio_legacy_ops = { -+ .dma_map = vfio_legacy_dma_map, -+ .dma_unmap = vfio_legacy_dma_unmap, -+}; -diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build -index 2a6912c940..eb6ce6229d 100644 ---- a/hw/vfio/meson.build -+++ b/hw/vfio/meson.build -@@ -2,6 +2,7 @@ vfio_ss = ss.source_set() - vfio_ss.add(files( - 'helpers.c', - 'common.c', -+ 'container-base.c', - 'container.c', - 'spapr.c', - 'migration.c', -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 0eb2387cf2..9f7fedee98 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -116,7 +116,7 @@ vfio_region_unmap(const char *name, unsigned long offset, unsigned long end) "Re - vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Device %s region %d: %d sparse mmap entries" - vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]" - vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%08x" --vfio_dma_unmap_overflow_workaround(void) "" -+vfio_legacy_dma_unmap_overflow_workaround(void) "" - vfio_get_dirty_bitmap(int fd, uint64_t iova, uint64_t size, uint64_t bitmap_size, uint64_t start, uint64_t dirty_pages) "container fd=%d, iova=0x%"PRIx64" size= 0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64" dirty_pages=%"PRIu64 - vfio_iommu_map_dirty_notify(uint64_t iova_start, uint64_t iova_end) "iommu dirty @ 0x%"PRIx64" - 0x%"PRIx64 - -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 678161f207..24a26345e5 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -208,10 +208,6 @@ void vfio_put_address_space(VFIOAddressSpace *space); - bool vfio_devices_all_running_and_saving(VFIOContainer *container); - - /* container->fd */ --int vfio_dma_unmap(VFIOContainer *container, hwaddr iova, -- ram_addr_t size, IOMMUTLBEntry *iotlb); --int vfio_dma_map(VFIOContainer *container, hwaddr iova, -- ram_addr_t size, void *vaddr, bool readonly); - int vfio_set_dirty_page_tracking(VFIOContainer *container, bool start); - int vfio_query_dirty_bitmap(VFIOContainer *container, VFIOBitmap *vbmap, - hwaddr iova, hwaddr size); -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 1d6daaea5d..56b033f59f 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -31,6 +31,13 @@ typedef struct VFIOContainerBase { - const VFIOIOMMUOps *ops; - } VFIOContainerBase; - -+int vfio_container_dma_map(VFIOContainerBase *bcontainer, -+ hwaddr iova, ram_addr_t size, -+ void *vaddr, bool readonly); -+int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, -+ hwaddr iova, ram_addr_t size, -+ IOMMUTLBEntry *iotlb); -+ - struct VFIOIOMMUOps { - /* basic feature */ - int (*dma_map)(VFIOContainerBase *bcontainer, --- -2.39.3 - diff --git a/kvm-vfio-iommufd-Add-support-for-iova_ranges-and-pgsizes.patch b/kvm-vfio-iommufd-Add-support-for-iova_ranges-and-pgsizes.patch deleted file mode 100644 index 52e3d87..0000000 --- a/kvm-vfio-iommufd-Add-support-for-iova_ranges-and-pgsizes.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 49435d4d592bc890f56b69c2290f890c87b5a103 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:05 +0800 -Subject: [PATCH 026/101] vfio/iommufd: Add support for iova_ranges and pgsizes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [25/67] 578af0547d97276ccd4936b574c12118fc70d468 (eauger1/centos-qemu-kvm) - -Some vIOMMU such as virtio-iommu use IOVA ranges from host side to -setup reserved ranges for passthrough device, so that guest will not -use an IOVA range beyond host support. - -Use an uAPI of IOMMUFD to get IOVA ranges of host side and pass to -vIOMMU just like the legacy backend, if this fails, fallback to -64bit IOVA range. - -Also use out_iova_alignment returned from uAPI as pgsizes instead of -qemu_real_host_page_size() as a fallback. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Auger -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 714e9affa8ae1d84007c8afde7bb10fef9cb883d) -Signed-off-by: Eric Auger ---- - hw/vfio/iommufd.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 55 insertions(+), 1 deletion(-) - -diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c -index 6d31aeac7b..01b448e840 100644 ---- a/hw/vfio/iommufd.c -+++ b/hw/vfio/iommufd.c -@@ -261,6 +261,53 @@ static int iommufd_cdev_ram_block_discard_disable(bool state) - return ram_block_uncoordinated_discard_disable(state); - } - -+static int iommufd_cdev_get_info_iova_range(VFIOIOMMUFDContainer *container, -+ uint32_t ioas_id, Error **errp) -+{ -+ VFIOContainerBase *bcontainer = &container->bcontainer; -+ struct iommu_ioas_iova_ranges *info; -+ struct iommu_iova_range *iova_ranges; -+ int ret, sz, fd = container->be->fd; -+ -+ info = g_malloc0(sizeof(*info)); -+ info->size = sizeof(*info); -+ info->ioas_id = ioas_id; -+ -+ ret = ioctl(fd, IOMMU_IOAS_IOVA_RANGES, info); -+ if (ret && errno != EMSGSIZE) { -+ goto error; -+ } -+ -+ sz = info->num_iovas * sizeof(struct iommu_iova_range); -+ info = g_realloc(info, sizeof(*info) + sz); -+ info->allowed_iovas = (uintptr_t)(info + 1); -+ -+ ret = ioctl(fd, IOMMU_IOAS_IOVA_RANGES, info); -+ if (ret) { -+ goto error; -+ } -+ -+ iova_ranges = (struct iommu_iova_range *)(uintptr_t)info->allowed_iovas; -+ -+ for (int i = 0; i < info->num_iovas; i++) { -+ Range *range = g_new(Range, 1); -+ -+ range_set_bounds(range, iova_ranges[i].start, iova_ranges[i].last); -+ bcontainer->iova_ranges = -+ range_list_insert(bcontainer->iova_ranges, range); -+ } -+ bcontainer->pgsizes = info->out_iova_alignment; -+ -+ g_free(info); -+ return 0; -+ -+error: -+ ret = -errno; -+ g_free(info); -+ error_setg_errno(errp, errno, "Cannot get IOVA ranges"); -+ return ret; -+} -+ - static int iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, - AddressSpace *as, Error **errp) - { -@@ -335,7 +382,14 @@ static int iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, - goto err_discard_disable; - } - -- bcontainer->pgsizes = qemu_real_host_page_size(); -+ ret = iommufd_cdev_get_info_iova_range(container, ioas_id, &err); -+ if (ret) { -+ error_append_hint(&err, -+ "Fallback to default 64bit IOVA range and 4K page size\n"); -+ warn_report_err(err); -+ err = NULL; -+ bcontainer->pgsizes = qemu_real_host_page_size(); -+ } - - bcontainer->listener = vfio_memory_listener; - memory_listener_register(&bcontainer->listener, bcontainer->space->as); --- -2.39.3 - diff --git a/kvm-vfio-iommufd-Enable-pci-hot-reset-through-iommufd-cd.patch b/kvm-vfio-iommufd-Enable-pci-hot-reset-through-iommufd-cd.patch deleted file mode 100644 index 48db196..0000000 --- a/kvm-vfio-iommufd-Enable-pci-hot-reset-through-iommufd-cd.patch +++ /dev/null @@ -1,215 +0,0 @@ -From e94700896dd8fcea149d9719eccde6f485440be2 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:08 +0800 -Subject: [PATCH 029/101] vfio/iommufd: Enable pci hot reset through iommufd - cdev interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [28/67] ca1ae970138ee4a6f4b3b49817e775f3159f4c97 (eauger1/centos-qemu-kvm) - -Implement the newly introduced pci_hot_reset callback named -iommufd_cdev_pci_hot_reset to do iommufd specific check and -reset operation. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Eric Auger -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 96d6f85ff012abd7aaa35b1a2bc48b8640c898d9) -Signed-off-by: Eric Auger ---- - hw/vfio/iommufd.c | 150 +++++++++++++++++++++++++++++++++++++++++++ - hw/vfio/trace-events | 1 + - 2 files changed, 151 insertions(+) - -diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c -index 01b448e840..6e53e013ef 100644 ---- a/hw/vfio/iommufd.c -+++ b/hw/vfio/iommufd.c -@@ -24,6 +24,7 @@ - #include "sysemu/reset.h" - #include "qemu/cutils.h" - #include "qemu/chardev_open.h" -+#include "pci.h" - - static int iommufd_cdev_map(VFIOContainerBase *bcontainer, hwaddr iova, - ram_addr_t size, void *vaddr, bool readonly) -@@ -468,9 +469,158 @@ static void iommufd_cdev_detach(VFIODevice *vbasedev) - close(vbasedev->fd); - } - -+static VFIODevice *iommufd_cdev_pci_find_by_devid(__u32 devid) -+{ -+ VFIODevice *vbasedev_iter; -+ -+ QLIST_FOREACH(vbasedev_iter, &vfio_device_list, global_next) { -+ if (vbasedev_iter->bcontainer->ops != &vfio_iommufd_ops) { -+ continue; -+ } -+ if (devid == vbasedev_iter->devid) { -+ return vbasedev_iter; -+ } -+ } -+ return NULL; -+} -+ -+static VFIOPCIDevice * -+iommufd_cdev_dep_get_realized_vpdev(struct vfio_pci_dependent_device *dep_dev, -+ VFIODevice *reset_dev) -+{ -+ VFIODevice *vbasedev_tmp; -+ -+ if (dep_dev->devid == reset_dev->devid || -+ dep_dev->devid == VFIO_PCI_DEVID_OWNED) { -+ return NULL; -+ } -+ -+ vbasedev_tmp = iommufd_cdev_pci_find_by_devid(dep_dev->devid); -+ if (!vbasedev_tmp || !vbasedev_tmp->dev->realized || -+ vbasedev_tmp->type != VFIO_DEVICE_TYPE_PCI) { -+ return NULL; -+ } -+ -+ return container_of(vbasedev_tmp, VFIOPCIDevice, vbasedev); -+} -+ -+static int iommufd_cdev_pci_hot_reset(VFIODevice *vbasedev, bool single) -+{ -+ VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); -+ struct vfio_pci_hot_reset_info *info = NULL; -+ struct vfio_pci_dependent_device *devices; -+ struct vfio_pci_hot_reset *reset; -+ int ret, i; -+ bool multi = false; -+ -+ trace_vfio_pci_hot_reset(vdev->vbasedev.name, single ? "one" : "multi"); -+ -+ if (!single) { -+ vfio_pci_pre_reset(vdev); -+ } -+ vdev->vbasedev.needs_reset = false; -+ -+ ret = vfio_pci_get_pci_hot_reset_info(vdev, &info); -+ -+ if (ret) { -+ goto out_single; -+ } -+ -+ assert(info->flags & VFIO_PCI_HOT_RESET_FLAG_DEV_ID); -+ -+ devices = &info->devices[0]; -+ -+ if (!(info->flags & VFIO_PCI_HOT_RESET_FLAG_DEV_ID_OWNED)) { -+ if (!vdev->has_pm_reset) { -+ for (i = 0; i < info->count; i++) { -+ if (devices[i].devid == VFIO_PCI_DEVID_NOT_OWNED) { -+ error_report("vfio: Cannot reset device %s, " -+ "depends on device %04x:%02x:%02x.%x " -+ "which is not owned.", -+ vdev->vbasedev.name, devices[i].segment, -+ devices[i].bus, PCI_SLOT(devices[i].devfn), -+ PCI_FUNC(devices[i].devfn)); -+ } -+ } -+ } -+ ret = -EPERM; -+ goto out_single; -+ } -+ -+ trace_vfio_pci_hot_reset_has_dep_devices(vdev->vbasedev.name); -+ -+ for (i = 0; i < info->count; i++) { -+ VFIOPCIDevice *tmp; -+ -+ trace_iommufd_cdev_pci_hot_reset_dep_devices(devices[i].segment, -+ devices[i].bus, -+ PCI_SLOT(devices[i].devfn), -+ PCI_FUNC(devices[i].devfn), -+ devices[i].devid); -+ -+ /* -+ * If a VFIO cdev device is resettable, all the dependent devices -+ * are either bound to same iommufd or within same iommu_groups as -+ * one of the iommufd bound devices. -+ */ -+ assert(devices[i].devid != VFIO_PCI_DEVID_NOT_OWNED); -+ -+ tmp = iommufd_cdev_dep_get_realized_vpdev(&devices[i], &vdev->vbasedev); -+ if (!tmp) { -+ continue; -+ } -+ -+ if (single) { -+ ret = -EINVAL; -+ goto out_single; -+ } -+ vfio_pci_pre_reset(tmp); -+ tmp->vbasedev.needs_reset = false; -+ multi = true; -+ } -+ -+ if (!single && !multi) { -+ ret = -EINVAL; -+ goto out_single; -+ } -+ -+ /* Use zero length array for hot reset with iommufd backend */ -+ reset = g_malloc0(sizeof(*reset)); -+ reset->argsz = sizeof(*reset); -+ -+ /* Bus reset! */ -+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_PCI_HOT_RESET, reset); -+ g_free(reset); -+ if (ret) { -+ ret = -errno; -+ } -+ -+ trace_vfio_pci_hot_reset_result(vdev->vbasedev.name, -+ ret ? strerror(errno) : "Success"); -+ -+ /* Re-enable INTx on affected devices */ -+ for (i = 0; i < info->count; i++) { -+ VFIOPCIDevice *tmp; -+ -+ tmp = iommufd_cdev_dep_get_realized_vpdev(&devices[i], &vdev->vbasedev); -+ if (!tmp) { -+ continue; -+ } -+ vfio_pci_post_reset(tmp); -+ } -+out_single: -+ if (!single) { -+ vfio_pci_post_reset(vdev); -+ } -+ g_free(info); -+ -+ return ret; -+} -+ - const VFIOIOMMUOps vfio_iommufd_ops = { - .dma_map = iommufd_cdev_map, - .dma_unmap = iommufd_cdev_unmap, - .attach_device = iommufd_cdev_attach, - .detach_device = iommufd_cdev_detach, -+ .pci_hot_reset = iommufd_cdev_pci_hot_reset, - }; -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 3340c93af0..8fdde54456 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -174,3 +174,4 @@ iommufd_cdev_detach_ioas_hwpt(int iommufd, const char *name) " [iommufd=%d] Succ - iommufd_cdev_fail_attach_existing_container(const char *msg) " %s" - iommufd_cdev_alloc_ioas(int iommufd, int ioas_id) " [iommufd=%d] new IOMMUFD container with ioasid=%d" - iommufd_cdev_device_info(char *name, int devfd, int num_irqs, int num_regions, int flags) " %s (%d) num_irqs=%d num_regions=%d flags=%d" -+iommufd_cdev_pci_hot_reset_dep_devices(int domain, int bus, int slot, int function, int dev_id) "\t%04x:%02x:%02x.%x devid %d" --- -2.39.3 - diff --git a/kvm-vfio-iommufd-Implement-the-iommufd-backend.patch b/kvm-vfio-iommufd-Implement-the-iommufd-backend.patch deleted file mode 100644 index f00cbcd..0000000 --- a/kvm-vfio-iommufd-Implement-the-iommufd-backend.patch +++ /dev/null @@ -1,561 +0,0 @@ -From f018d0b686406256c2b5e823e4227316ee1394e9 Mon Sep 17 00:00:00 2001 -From: Yi Liu -Date: Tue, 21 Nov 2023 16:44:03 +0800 -Subject: [PATCH 024/101] vfio/iommufd: Implement the iommufd backend -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [23/67] d11046654117a690542a1e2b48b9d1994f778b2d (eauger1/centos-qemu-kvm) - -The iommufd backend is implemented based on the new /dev/iommu user API. -This backend obviously depends on CONFIG_IOMMUFD. - -So far, the iommufd backend doesn't support dirty page sync yet. - -Co-authored-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 5ee3dc7af7859e7b8aa34c10c21778101c15e812) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 6 + - hw/vfio/iommufd.c | 422 ++++++++++++++++++++++++++++++++++ - hw/vfio/meson.build | 3 + - hw/vfio/trace-events | 10 + - include/hw/vfio/vfio-common.h | 11 + - 5 files changed, 452 insertions(+) - create mode 100644 hw/vfio/iommufd.c - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 934f4f5446..6569732b7a 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -19,6 +19,7 @@ - */ - - #include "qemu/osdep.h" -+#include CONFIG_DEVICES /* CONFIG_IOMMUFD */ - #include - #ifdef CONFIG_KVM - #include -@@ -1503,6 +1504,11 @@ int vfio_attach_device(char *name, VFIODevice *vbasedev, - { - const VFIOIOMMUOps *ops = &vfio_legacy_ops; - -+#ifdef CONFIG_IOMMUFD -+ if (vbasedev->iommufd) { -+ ops = &vfio_iommufd_ops; -+ } -+#endif - return ops->attach_device(name, vbasedev, as, errp); - } - -diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c -new file mode 100644 -index 0000000000..6d31aeac7b ---- /dev/null -+++ b/hw/vfio/iommufd.c -@@ -0,0 +1,422 @@ -+/* -+ * iommufd container backend -+ * -+ * Copyright (C) 2023 Intel Corporation. -+ * Copyright Red Hat, Inc. 2023 -+ * -+ * Authors: Yi Liu -+ * Eric Auger -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+ -+#include "qemu/osdep.h" -+#include -+#include -+#include -+ -+#include "hw/vfio/vfio-common.h" -+#include "qemu/error-report.h" -+#include "trace.h" -+#include "qapi/error.h" -+#include "sysemu/iommufd.h" -+#include "hw/qdev-core.h" -+#include "sysemu/reset.h" -+#include "qemu/cutils.h" -+#include "qemu/chardev_open.h" -+ -+static int iommufd_cdev_map(VFIOContainerBase *bcontainer, hwaddr iova, -+ ram_addr_t size, void *vaddr, bool readonly) -+{ -+ VFIOIOMMUFDContainer *container = -+ container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); -+ -+ return iommufd_backend_map_dma(container->be, -+ container->ioas_id, -+ iova, size, vaddr, readonly); -+} -+ -+static int iommufd_cdev_unmap(VFIOContainerBase *bcontainer, -+ hwaddr iova, ram_addr_t size, -+ IOMMUTLBEntry *iotlb) -+{ -+ VFIOIOMMUFDContainer *container = -+ container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); -+ -+ /* TODO: Handle dma_unmap_bitmap with iotlb args (migration) */ -+ return iommufd_backend_unmap_dma(container->be, -+ container->ioas_id, iova, size); -+} -+ -+static int iommufd_cdev_kvm_device_add(VFIODevice *vbasedev, Error **errp) -+{ -+ return vfio_kvm_device_add_fd(vbasedev->fd, errp); -+} -+ -+static void iommufd_cdev_kvm_device_del(VFIODevice *vbasedev) -+{ -+ Error *err = NULL; -+ -+ if (vfio_kvm_device_del_fd(vbasedev->fd, &err)) { -+ error_report_err(err); -+ } -+} -+ -+static int iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp) -+{ -+ IOMMUFDBackend *iommufd = vbasedev->iommufd; -+ struct vfio_device_bind_iommufd bind = { -+ .argsz = sizeof(bind), -+ .flags = 0, -+ }; -+ int ret; -+ -+ ret = iommufd_backend_connect(iommufd, errp); -+ if (ret) { -+ return ret; -+ } -+ -+ /* -+ * Add device to kvm-vfio to be prepared for the tracking -+ * in KVM. Especially for some emulated devices, it requires -+ * to have kvm information in the device open. -+ */ -+ ret = iommufd_cdev_kvm_device_add(vbasedev, errp); -+ if (ret) { -+ goto err_kvm_device_add; -+ } -+ -+ /* Bind device to iommufd */ -+ bind.iommufd = iommufd->fd; -+ ret = ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, &bind); -+ if (ret) { -+ error_setg_errno(errp, errno, "error bind device fd=%d to iommufd=%d", -+ vbasedev->fd, bind.iommufd); -+ goto err_bind; -+ } -+ -+ vbasedev->devid = bind.out_devid; -+ trace_iommufd_cdev_connect_and_bind(bind.iommufd, vbasedev->name, -+ vbasedev->fd, vbasedev->devid); -+ return ret; -+err_bind: -+ iommufd_cdev_kvm_device_del(vbasedev); -+err_kvm_device_add: -+ iommufd_backend_disconnect(iommufd); -+ return ret; -+} -+ -+static void iommufd_cdev_unbind_and_disconnect(VFIODevice *vbasedev) -+{ -+ /* Unbind is automatically conducted when device fd is closed */ -+ iommufd_cdev_kvm_device_del(vbasedev); -+ iommufd_backend_disconnect(vbasedev->iommufd); -+} -+ -+static int iommufd_cdev_getfd(const char *sysfs_path, Error **errp) -+{ -+ long int ret = -ENOTTY; -+ char *path, *vfio_dev_path = NULL, *vfio_path = NULL; -+ DIR *dir = NULL; -+ struct dirent *dent; -+ gchar *contents; -+ struct stat st; -+ gsize length; -+ int major, minor; -+ dev_t vfio_devt; -+ -+ path = g_strdup_printf("%s/vfio-dev", sysfs_path); -+ if (stat(path, &st) < 0) { -+ error_setg_errno(errp, errno, "no such host device"); -+ goto out_free_path; -+ } -+ -+ dir = opendir(path); -+ if (!dir) { -+ error_setg_errno(errp, errno, "couldn't open directory %s", path); -+ goto out_free_path; -+ } -+ -+ while ((dent = readdir(dir))) { -+ if (!strncmp(dent->d_name, "vfio", 4)) { -+ vfio_dev_path = g_strdup_printf("%s/%s/dev", path, dent->d_name); -+ break; -+ } -+ } -+ -+ if (!vfio_dev_path) { -+ error_setg(errp, "failed to find vfio-dev/vfioX/dev"); -+ goto out_close_dir; -+ } -+ -+ if (!g_file_get_contents(vfio_dev_path, &contents, &length, NULL)) { -+ error_setg(errp, "failed to load \"%s\"", vfio_dev_path); -+ goto out_free_dev_path; -+ } -+ -+ if (sscanf(contents, "%d:%d", &major, &minor) != 2) { -+ error_setg(errp, "failed to get major:minor for \"%s\"", vfio_dev_path); -+ goto out_free_dev_path; -+ } -+ g_free(contents); -+ vfio_devt = makedev(major, minor); -+ -+ vfio_path = g_strdup_printf("/dev/vfio/devices/%s", dent->d_name); -+ ret = open_cdev(vfio_path, vfio_devt); -+ if (ret < 0) { -+ error_setg(errp, "Failed to open %s", vfio_path); -+ } -+ -+ trace_iommufd_cdev_getfd(vfio_path, ret); -+ g_free(vfio_path); -+ -+out_free_dev_path: -+ g_free(vfio_dev_path); -+out_close_dir: -+ closedir(dir); -+out_free_path: -+ if (*errp) { -+ error_prepend(errp, VFIO_MSG_PREFIX, path); -+ } -+ g_free(path); -+ -+ return ret; -+} -+ -+static int iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id, -+ Error **errp) -+{ -+ int ret, iommufd = vbasedev->iommufd->fd; -+ struct vfio_device_attach_iommufd_pt attach_data = { -+ .argsz = sizeof(attach_data), -+ .flags = 0, -+ .pt_id = id, -+ }; -+ -+ /* Attach device to an IOAS or hwpt within iommufd */ -+ ret = ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, &attach_data); -+ if (ret) { -+ error_setg_errno(errp, errno, -+ "[iommufd=%d] error attach %s (%d) to id=%d", -+ iommufd, vbasedev->name, vbasedev->fd, id); -+ } else { -+ trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name, -+ vbasedev->fd, id); -+ } -+ return ret; -+} -+ -+static int iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp) -+{ -+ int ret, iommufd = vbasedev->iommufd->fd; -+ struct vfio_device_detach_iommufd_pt detach_data = { -+ .argsz = sizeof(detach_data), -+ .flags = 0, -+ }; -+ -+ ret = ioctl(vbasedev->fd, VFIO_DEVICE_DETACH_IOMMUFD_PT, &detach_data); -+ if (ret) { -+ error_setg_errno(errp, errno, "detach %s failed", vbasedev->name); -+ } else { -+ trace_iommufd_cdev_detach_ioas_hwpt(iommufd, vbasedev->name); -+ } -+ return ret; -+} -+ -+static int iommufd_cdev_attach_container(VFIODevice *vbasedev, -+ VFIOIOMMUFDContainer *container, -+ Error **errp) -+{ -+ return iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp); -+} -+ -+static void iommufd_cdev_detach_container(VFIODevice *vbasedev, -+ VFIOIOMMUFDContainer *container) -+{ -+ Error *err = NULL; -+ -+ if (iommufd_cdev_detach_ioas_hwpt(vbasedev, &err)) { -+ error_report_err(err); -+ } -+} -+ -+static void iommufd_cdev_container_destroy(VFIOIOMMUFDContainer *container) -+{ -+ VFIOContainerBase *bcontainer = &container->bcontainer; -+ -+ if (!QLIST_EMPTY(&bcontainer->device_list)) { -+ return; -+ } -+ memory_listener_unregister(&bcontainer->listener); -+ vfio_container_destroy(bcontainer); -+ iommufd_backend_free_id(container->be, container->ioas_id); -+ g_free(container); -+} -+ -+static int iommufd_cdev_ram_block_discard_disable(bool state) -+{ -+ /* -+ * We support coordinated discarding of RAM via the RamDiscardManager. -+ */ -+ return ram_block_uncoordinated_discard_disable(state); -+} -+ -+static int iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, -+ AddressSpace *as, Error **errp) -+{ -+ VFIOContainerBase *bcontainer; -+ VFIOIOMMUFDContainer *container; -+ VFIOAddressSpace *space; -+ struct vfio_device_info dev_info = { .argsz = sizeof(dev_info) }; -+ int ret, devfd; -+ uint32_t ioas_id; -+ Error *err = NULL; -+ -+ devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp); -+ if (devfd < 0) { -+ return devfd; -+ } -+ vbasedev->fd = devfd; -+ -+ ret = iommufd_cdev_connect_and_bind(vbasedev, errp); -+ if (ret) { -+ goto err_connect_bind; -+ } -+ -+ space = vfio_get_address_space(as); -+ -+ /* try to attach to an existing container in this space */ -+ QLIST_FOREACH(bcontainer, &space->containers, next) { -+ container = container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); -+ if (bcontainer->ops != &vfio_iommufd_ops || -+ vbasedev->iommufd != container->be) { -+ continue; -+ } -+ if (iommufd_cdev_attach_container(vbasedev, container, &err)) { -+ const char *msg = error_get_pretty(err); -+ -+ trace_iommufd_cdev_fail_attach_existing_container(msg); -+ error_free(err); -+ err = NULL; -+ } else { -+ ret = iommufd_cdev_ram_block_discard_disable(true); -+ if (ret) { -+ error_setg(errp, -+ "Cannot set discarding of RAM broken (%d)", ret); -+ goto err_discard_disable; -+ } -+ goto found_container; -+ } -+ } -+ -+ /* Need to allocate a new dedicated container */ -+ ret = iommufd_backend_alloc_ioas(vbasedev->iommufd, &ioas_id, errp); -+ if (ret < 0) { -+ goto err_alloc_ioas; -+ } -+ -+ trace_iommufd_cdev_alloc_ioas(vbasedev->iommufd->fd, ioas_id); -+ -+ container = g_malloc0(sizeof(*container)); -+ container->be = vbasedev->iommufd; -+ container->ioas_id = ioas_id; -+ -+ bcontainer = &container->bcontainer; -+ vfio_container_init(bcontainer, space, &vfio_iommufd_ops); -+ QLIST_INSERT_HEAD(&space->containers, bcontainer, next); -+ -+ ret = iommufd_cdev_attach_container(vbasedev, container, errp); -+ if (ret) { -+ goto err_attach_container; -+ } -+ -+ ret = iommufd_cdev_ram_block_discard_disable(true); -+ if (ret) { -+ goto err_discard_disable; -+ } -+ -+ bcontainer->pgsizes = qemu_real_host_page_size(); -+ -+ bcontainer->listener = vfio_memory_listener; -+ memory_listener_register(&bcontainer->listener, bcontainer->space->as); -+ -+ if (bcontainer->error) { -+ ret = -1; -+ error_propagate_prepend(errp, bcontainer->error, -+ "memory listener initialization failed: "); -+ goto err_listener_register; -+ } -+ -+ bcontainer->initialized = true; -+ -+found_container: -+ ret = ioctl(devfd, VFIO_DEVICE_GET_INFO, &dev_info); -+ if (ret) { -+ error_setg_errno(errp, errno, "error getting device info"); -+ goto err_listener_register; -+ } -+ -+ /* -+ * TODO: examine RAM_BLOCK_DISCARD stuff, should we do group level -+ * for discarding incompatibility check as well? -+ */ -+ if (vbasedev->ram_block_discard_allowed) { -+ iommufd_cdev_ram_block_discard_disable(false); -+ } -+ -+ vbasedev->group = 0; -+ vbasedev->num_irqs = dev_info.num_irqs; -+ vbasedev->num_regions = dev_info.num_regions; -+ vbasedev->flags = dev_info.flags; -+ vbasedev->reset_works = !!(dev_info.flags & VFIO_DEVICE_FLAGS_RESET); -+ vbasedev->bcontainer = bcontainer; -+ QLIST_INSERT_HEAD(&bcontainer->device_list, vbasedev, container_next); -+ QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next); -+ -+ trace_iommufd_cdev_device_info(vbasedev->name, devfd, vbasedev->num_irqs, -+ vbasedev->num_regions, vbasedev->flags); -+ return 0; -+ -+err_listener_register: -+ iommufd_cdev_ram_block_discard_disable(false); -+err_discard_disable: -+ iommufd_cdev_detach_container(vbasedev, container); -+err_attach_container: -+ iommufd_cdev_container_destroy(container); -+err_alloc_ioas: -+ vfio_put_address_space(space); -+ iommufd_cdev_unbind_and_disconnect(vbasedev); -+err_connect_bind: -+ close(vbasedev->fd); -+ return ret; -+} -+ -+static void iommufd_cdev_detach(VFIODevice *vbasedev) -+{ -+ VFIOContainerBase *bcontainer = vbasedev->bcontainer; -+ VFIOAddressSpace *space = bcontainer->space; -+ VFIOIOMMUFDContainer *container = container_of(bcontainer, -+ VFIOIOMMUFDContainer, -+ bcontainer); -+ QLIST_REMOVE(vbasedev, global_next); -+ QLIST_REMOVE(vbasedev, container_next); -+ vbasedev->bcontainer = NULL; -+ -+ if (!vbasedev->ram_block_discard_allowed) { -+ iommufd_cdev_ram_block_discard_disable(false); -+ } -+ -+ iommufd_cdev_detach_container(vbasedev, container); -+ iommufd_cdev_container_destroy(container); -+ vfio_put_address_space(space); -+ -+ iommufd_cdev_unbind_and_disconnect(vbasedev); -+ close(vbasedev->fd); -+} -+ -+const VFIOIOMMUOps vfio_iommufd_ops = { -+ .dma_map = iommufd_cdev_map, -+ .dma_unmap = iommufd_cdev_unmap, -+ .attach_device = iommufd_cdev_attach, -+ .detach_device = iommufd_cdev_detach, -+}; -diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build -index eb6ce6229d..e5d98b6adc 100644 ---- a/hw/vfio/meson.build -+++ b/hw/vfio/meson.build -@@ -7,6 +7,9 @@ vfio_ss.add(files( - 'spapr.c', - 'migration.c', - )) -+vfio_ss.add(when: 'CONFIG_IOMMUFD', if_true: files( -+ 'iommufd.c', -+)) - vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files( - 'display.c', - 'pci-quirks.c', -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 08a1f9dfa4..3340c93af0 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -164,3 +164,13 @@ vfio_state_pending_estimate(const char *name, uint64_t precopy, uint64_t postcop - vfio_state_pending_exact(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy 0x%"PRIx64" postcopy 0x%"PRIx64" stopcopy size 0x%"PRIx64" precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64 - vfio_vmstate_change(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s" - vfio_vmstate_change_prepare(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s" -+ -+#iommufd.c -+ -+iommufd_cdev_connect_and_bind(int iommufd, const char *name, int devfd, int devid) " [iommufd=%d] Successfully bound device %s (fd=%d): output devid=%d" -+iommufd_cdev_getfd(const char *dev, int devfd) " %s (fd=%d)" -+iommufd_cdev_attach_ioas_hwpt(int iommufd, const char *name, int devfd, int id) " [iommufd=%d] Successfully attached device %s (%d) to id=%d" -+iommufd_cdev_detach_ioas_hwpt(int iommufd, const char *name) " [iommufd=%d] Successfully detached %s" -+iommufd_cdev_fail_attach_existing_container(const char *msg) " %s" -+iommufd_cdev_alloc_ioas(int iommufd, int ioas_id) " [iommufd=%d] new IOMMUFD container with ioasid=%d" -+iommufd_cdev_device_info(char *name, int devfd, int num_irqs, int num_regions, int flags) " %s (%d) num_irqs=%d num_regions=%d flags=%d" -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 24ecc0e7ee..3dac5c167e 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -89,6 +89,14 @@ typedef struct VFIOHostDMAWindow { - QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next; - } VFIOHostDMAWindow; - -+typedef struct IOMMUFDBackend IOMMUFDBackend; -+ -+typedef struct VFIOIOMMUFDContainer { -+ VFIOContainerBase bcontainer; -+ IOMMUFDBackend *be; -+ uint32_t ioas_id; -+} VFIOIOMMUFDContainer; -+ - typedef struct VFIODeviceOps VFIODeviceOps; - - typedef struct VFIODevice { -@@ -116,6 +124,8 @@ typedef struct VFIODevice { - OnOffAuto pre_copy_dirty_page_tracking; - bool dirty_pages_supported; - bool dirty_tracking; -+ int devid; -+ IOMMUFDBackend *iommufd; - } VFIODevice; - - struct VFIODeviceOps { -@@ -201,6 +211,7 @@ typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; - extern VFIOGroupList vfio_group_list; - extern VFIODeviceList vfio_device_list; - extern const VFIOIOMMUOps vfio_legacy_ops; -+extern const VFIOIOMMUOps vfio_iommufd_ops; - extern const MemoryListener vfio_memory_listener; - extern int vfio_kvm_device_fd; - --- -2.39.3 - diff --git a/kvm-vfio-iommufd-Introduce-a-VFIOIOMMU-iommufd-QOM-inter.patch b/kvm-vfio-iommufd-Introduce-a-VFIOIOMMU-iommufd-QOM-inter.patch deleted file mode 100644 index 866a437..0000000 --- a/kvm-vfio-iommufd-Introduce-a-VFIOIOMMU-iommufd-QOM-inter.patch +++ /dev/null @@ -1,155 +0,0 @@ -From f98defd6fe081bc44f5bd823d187d7d3b12832ac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:23 +0100 -Subject: [PATCH 056/101] vfio/iommufd: Introduce a VFIOIOMMU iommufd QOM - interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [55/67] 789ecf74ace326b0df5d494fd558d7d0b6294a85 (eauger1/centos-qemu-kvm) - -As previously done for the sPAPR and legacy IOMMU backends, convert -the VFIOIOMMUOps struct to a QOM interface. The set of of operations -for this backend can be referenced with a literal typename instead of -a C struct. - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit ce5f6d49f5845c3b9955cc377a5223c3f8d7ba1e) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 2 +- - hw/vfio/iommufd.c | 35 ++++++++++++++++++++------- - include/hw/vfio/vfio-common.h | 1 - - include/hw/vfio/vfio-container-base.h | 2 +- - 4 files changed, 28 insertions(+), 12 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 2329d0efc8..89ff1c7aed 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1508,7 +1508,7 @@ int vfio_attach_device(char *name, VFIODevice *vbasedev, - - #ifdef CONFIG_IOMMUFD - if (vbasedev->iommufd) { -- ops = &vfio_iommufd_ops; -+ ops = VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD)); - } - #endif - -diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c -index 87a561c545..d4c586e842 100644 ---- a/hw/vfio/iommufd.c -+++ b/hw/vfio/iommufd.c -@@ -319,6 +319,8 @@ static int iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, - int ret, devfd; - uint32_t ioas_id; - Error *err = NULL; -+ const VFIOIOMMUClass *iommufd_vioc = -+ VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD)); - - if (vbasedev->fd < 0) { - devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp); -@@ -340,7 +342,7 @@ static int iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, - /* try to attach to an existing container in this space */ - QLIST_FOREACH(bcontainer, &space->containers, next) { - container = container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); -- if (bcontainer->ops != &vfio_iommufd_ops || -+ if (bcontainer->ops != iommufd_vioc || - vbasedev->iommufd != container->be) { - continue; - } -@@ -374,7 +376,7 @@ static int iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, - container->ioas_id = ioas_id; - - bcontainer = &container->bcontainer; -- vfio_container_init(bcontainer, space, &vfio_iommufd_ops); -+ vfio_container_init(bcontainer, space, iommufd_vioc); - QLIST_INSERT_HEAD(&space->containers, bcontainer, next); - - ret = iommufd_cdev_attach_container(vbasedev, container, errp); -@@ -476,9 +478,11 @@ static void iommufd_cdev_detach(VFIODevice *vbasedev) - static VFIODevice *iommufd_cdev_pci_find_by_devid(__u32 devid) - { - VFIODevice *vbasedev_iter; -+ const VFIOIOMMUClass *iommufd_vioc = -+ VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD)); - - QLIST_FOREACH(vbasedev_iter, &vfio_device_list, global_next) { -- if (vbasedev_iter->bcontainer->ops != &vfio_iommufd_ops) { -+ if (vbasedev_iter->bcontainer->ops != iommufd_vioc) { - continue; - } - if (devid == vbasedev_iter->devid) { -@@ -621,10 +625,23 @@ out_single: - return ret; - } - --const VFIOIOMMUOps vfio_iommufd_ops = { -- .dma_map = iommufd_cdev_map, -- .dma_unmap = iommufd_cdev_unmap, -- .attach_device = iommufd_cdev_attach, -- .detach_device = iommufd_cdev_detach, -- .pci_hot_reset = iommufd_cdev_pci_hot_reset, -+static void vfio_iommu_iommufd_class_init(ObjectClass *klass, void *data) -+{ -+ VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass); -+ -+ vioc->dma_map = iommufd_cdev_map; -+ vioc->dma_unmap = iommufd_cdev_unmap; -+ vioc->attach_device = iommufd_cdev_attach; -+ vioc->detach_device = iommufd_cdev_detach; -+ vioc->pci_hot_reset = iommufd_cdev_pci_hot_reset; - }; -+ -+static const TypeInfo types[] = { -+ { -+ .name = TYPE_VFIO_IOMMU_IOMMUFD, -+ .parent = TYPE_VFIO_IOMMU, -+ .class_init = vfio_iommu_iommufd_class_init, -+ }, -+}; -+ -+DEFINE_TYPES(types) -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 14c497b6b0..9b7ef7d02b 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -210,7 +210,6 @@ typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList; - typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; - extern VFIOGroupList vfio_group_list; - extern VFIODeviceList vfio_device_list; --extern const VFIOIOMMUOps vfio_iommufd_ops; - extern const MemoryListener vfio_memory_listener; - extern int vfio_kvm_device_fd; - -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 9e21d7811f..b2813b0c11 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -17,7 +17,6 @@ - - typedef struct VFIODevice VFIODevice; - typedef struct VFIOIOMMUClass VFIOIOMMUClass; --#define VFIOIOMMUOps VFIOIOMMUClass /* To remove */ - - typedef struct { - unsigned long *bitmap; -@@ -96,6 +95,7 @@ void vfio_container_destroy(VFIOContainerBase *bcontainer); - #define TYPE_VFIO_IOMMU "vfio-iommu" - #define TYPE_VFIO_IOMMU_LEGACY TYPE_VFIO_IOMMU "-legacy" - #define TYPE_VFIO_IOMMU_SPAPR TYPE_VFIO_IOMMU "-spapr" -+#define TYPE_VFIO_IOMMU_IOMMUFD TYPE_VFIO_IOMMU "-iommufd" - - /* - * VFIOContainerBase is not an abstract QOM object because it felt --- -2.39.3 - diff --git a/kvm-vfio-iommufd-Relax-assert-check-for-iommufd-backend.patch b/kvm-vfio-iommufd-Relax-assert-check-for-iommufd-backend.patch deleted file mode 100644 index f77032b..0000000 --- a/kvm-vfio-iommufd-Relax-assert-check-for-iommufd-backend.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 5a49c5bb690d55fc88b6fb12f059ae932de0a716 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:04 +0800 -Subject: [PATCH 025/101] vfio/iommufd: Relax assert check for iommufd backend -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [24/67] 2c9e41e9ca0b67ebf807d1643a98866a0cb75768 (eauger1/centos-qemu-kvm) - -Currently iommufd doesn't support dirty page sync yet, -but it will not block us doing live migration if VFIO -migration is force enabled. - -So in this case we allow set_dirty_page_tracking to be NULL. -Note we don't need same change for query_dirty_bitmap because -when dirty page sync isn't supported, query_dirty_bitmap will -never be called. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Auger -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 36e84d0c17102fa1c887d8c650a13ec08fca0ec0) -Signed-off-by: Eric Auger ---- - hw/vfio/container-base.c | 4 ++++ - hw/vfio/container.c | 4 ---- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 71f7274973..eee2dcfe76 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -55,6 +55,10 @@ void vfio_container_del_section_window(VFIOContainerBase *bcontainer, - int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, - bool start) - { -+ if (!bcontainer->dirty_pages_supported) { -+ return 0; -+ } -+ - g_assert(bcontainer->ops->set_dirty_page_tracking); - return bcontainer->ops->set_dirty_page_tracking(bcontainer, start); - } -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 6bacf38222..ed2d721b2b 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -216,10 +216,6 @@ static int vfio_legacy_set_dirty_page_tracking(VFIOContainerBase *bcontainer, - .argsz = sizeof(dirty), - }; - -- if (!bcontainer->dirty_pages_supported) { -- return 0; -- } -- - if (start) { - dirty.flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_START; - } else { --- -2.39.3 - diff --git a/kvm-vfio-iommufd-Remove-CONFIG_IOMMUFD-usage.patch b/kvm-vfio-iommufd-Remove-CONFIG_IOMMUFD-usage.patch deleted file mode 100644 index 97d30c9..0000000 --- a/kvm-vfio-iommufd-Remove-CONFIG_IOMMUFD-usage.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5549bf1b2e07213c23e280a43ab2ab67d5b7304a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:25 +0100 -Subject: [PATCH 058/101] vfio/iommufd: Remove CONFIG_IOMMUFD usage -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [57/67] 3a6a45d379241d9412e0b8bcfeb9be0b4add59a5 (eauger1/centos-qemu-kvm) - -Availability of the IOMMUFD backend can now be fully determined at -runtime and the ifdef check was a build time protection (for PPC not -supporting it mostly). - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit c1139fa4feba8c320e4bd0a4e34af55caa5ffbb9) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 89ff1c7aed..0d4d8b8416 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -19,7 +19,6 @@ - */ - - #include "qemu/osdep.h" --#include CONFIG_DEVICES /* CONFIG_IOMMUFD */ - #include - #ifdef CONFIG_KVM - #include -@@ -1506,11 +1505,9 @@ int vfio_attach_device(char *name, VFIODevice *vbasedev, - const VFIOIOMMUClass *ops = - VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_LEGACY)); - --#ifdef CONFIG_IOMMUFD - if (vbasedev->iommufd) { - ops = VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD)); - } --#endif - - assert(ops); - --- -2.39.3 - diff --git a/kvm-vfio-iommufd-Remove-the-use-of-stat-to-check-file-ex.patch b/kvm-vfio-iommufd-Remove-the-use-of-stat-to-check-file-ex.patch deleted file mode 100644 index 7401d52..0000000 --- a/kvm-vfio-iommufd-Remove-the-use-of-stat-to-check-file-ex.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 6b36dc2a305af856af03aad2e315eea96a349153 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Thu, 21 Dec 2023 09:09:57 +0100 -Subject: [PATCH 061/101] vfio/iommufd: Remove the use of stat() to check file - existence -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [60/67] 485770e45c1a6399780939bfb8b01b615d9213c6 (eauger1/centos-qemu-kvm) - -Using stat() before opening a file or a directory can lead to a -time-of-check to time-of-use (TOCTOU) filesystem race, which is -reported by coverity as a Security best practices violations. The -sequence could be replaced by open and fdopendir but it doesn't add -much in this case. Simply use opendir to avoid the race. - -Fixes: CID 1531551 -Signed-off-by: Cédric Le Goater -Reviewed-by: Zhenzhong Duan -(cherry picked from commit 6ba254801f6bc7f3ef68a6414f1b107237c7eb26) -Signed-off-by: Eric Auger ---- - hw/vfio/iommufd.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c -index d4c586e842..9bfddc1360 100644 ---- a/hw/vfio/iommufd.c -+++ b/hw/vfio/iommufd.c -@@ -121,17 +121,11 @@ static int iommufd_cdev_getfd(const char *sysfs_path, Error **errp) - DIR *dir = NULL; - struct dirent *dent; - gchar *contents; -- struct stat st; - gsize length; - int major, minor; - dev_t vfio_devt; - - path = g_strdup_printf("%s/vfio-dev", sysfs_path); -- if (stat(path, &st) < 0) { -- error_setg_errno(errp, errno, "no such host device"); -- goto out_free_path; -- } -- - dir = opendir(path); - if (!dir) { - error_setg_errno(errp, errno, "couldn't open directory %s", path); --- -2.39.3 - diff --git a/kvm-vfio-migration-Add-helper-function-to-set-state-or-r.patch b/kvm-vfio-migration-Add-helper-function-to-set-state-or-r.patch deleted file mode 100644 index 6556a19..0000000 --- a/kvm-vfio-migration-Add-helper-function-to-set-state-or-r.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0c0435e7210b99a6bf7b8f8205f7af8277b7525b Mon Sep 17 00:00:00 2001 -From: Avihai Horon -Date: Sun, 31 Dec 2023 12:48:18 +0200 -Subject: [PATCH 063/101] vfio/migration: Add helper function to set state or - reset device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [62/67] 1a63eea289561a05a6a8527c2a9da0289a7836d9 (eauger1/centos-qemu-kvm) - -There are several places where failure in setting the device state leads -to a device reset, which is done by setting ERROR as the recover state. - -Add a helper function that sets the device state and resets the device -in case of failure. This will make the code cleaner and remove duplicate -comments. - -Signed-off-by: Avihai Horon -Reviewed-by: Cédric Le Goater -Reviewed-by: Philippe Mathieu-Daudé -(cherry picked from commit c817e5a377a334241eed149e35760aca58bdeb34) -Signed-off-by: Eric Auger ---- - hw/vfio/migration.c | 41 +++++++++++++++++------------------------ - 1 file changed, 17 insertions(+), 24 deletions(-) - -diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c -index 28d422b39f..70e6b1a709 100644 ---- a/hw/vfio/migration.c -+++ b/hw/vfio/migration.c -@@ -163,6 +163,19 @@ reset_device: - return ret; - } - -+/* -+ * Some device state transitions require resetting the device if they fail. -+ * This function sets the device in new_state and resets the device if that -+ * fails. Reset is done by using ERROR as the recover state. -+ */ -+static int -+vfio_migration_set_state_or_reset(VFIODevice *vbasedev, -+ enum vfio_device_mig_state new_state) -+{ -+ return vfio_migration_set_state(vbasedev, new_state, -+ VFIO_DEVICE_STATE_ERROR); -+} -+ - static int vfio_load_buffer(QEMUFile *f, VFIODevice *vbasedev, - uint64_t data_size) - { -@@ -422,12 +435,7 @@ static void vfio_save_cleanup(void *opaque) - * after migration has completed, so it won't increase downtime. - */ - if (migration->device_state == VFIO_DEVICE_STATE_STOP_COPY) { -- /* -- * If setting the device in STOP state fails, the device should be -- * reset. To do so, use ERROR state as a recover state. -- */ -- vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_STOP, -- VFIO_DEVICE_STATE_ERROR); -+ vfio_migration_set_state_or_reset(vbasedev, VFIO_DEVICE_STATE_STOP); - } - - g_free(migration->data_buffer); -@@ -699,12 +707,7 @@ static void vfio_vmstate_change_prepare(void *opaque, bool running, - VFIO_DEVICE_STATE_PRE_COPY_P2P : - VFIO_DEVICE_STATE_RUNNING_P2P; - -- /* -- * If setting the device in new_state fails, the device should be reset. -- * To do so, use ERROR state as a recover state. -- */ -- ret = vfio_migration_set_state(vbasedev, new_state, -- VFIO_DEVICE_STATE_ERROR); -+ ret = vfio_migration_set_state_or_reset(vbasedev, new_state); - if (ret) { - /* - * Migration should be aborted in this case, but vm_state_notify() -@@ -736,12 +739,7 @@ static void vfio_vmstate_change(void *opaque, bool running, RunState state) - VFIO_DEVICE_STATE_STOP; - } - -- /* -- * If setting the device in new_state fails, the device should be reset. -- * To do so, use ERROR state as a recover state. -- */ -- ret = vfio_migration_set_state(vbasedev, new_state, -- VFIO_DEVICE_STATE_ERROR); -+ ret = vfio_migration_set_state_or_reset(vbasedev, new_state); - if (ret) { - /* - * Migration should be aborted in this case, but vm_state_notify() -@@ -770,12 +768,7 @@ static void vfio_migration_state_notifier(Notifier *notifier, void *data) - case MIGRATION_STATUS_CANCELLING: - case MIGRATION_STATUS_CANCELLED: - case MIGRATION_STATUS_FAILED: -- /* -- * If setting the device in RUNNING state fails, the device should -- * be reset. To do so, use ERROR state as a recover state. -- */ -- vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_RUNNING, -- VFIO_DEVICE_STATE_ERROR); -+ vfio_migration_set_state_or_reset(vbasedev, VFIO_DEVICE_STATE_RUNNING); - } - } - --- -2.39.3 - diff --git a/kvm-vfio-pci-Allow-the-selection-of-a-given-iommu-backen.patch b/kvm-vfio-pci-Allow-the-selection-of-a-given-iommu-backen.patch deleted file mode 100644 index f79de18..0000000 --- a/kvm-vfio-pci-Allow-the-selection-of-a-given-iommu-backen.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 7788fdc2375e01ead0c8a705c3b3d7467dd93d67 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 21 Nov 2023 16:44:09 +0800 -Subject: [PATCH 030/101] vfio/pci: Allow the selection of a given iommu - backend -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [29/67] 363c62607a11093ea0062489e11a708117d8ffb9 (eauger1/centos-qemu-kvm) - -Now we support two types of iommu backends, let's add the capability -to select one of them. This depends on whether an iommufd object has -been linked with the vfio-pci device: - -If the user wants to use the legacy backend, it shall not -link the vfio-pci device with any iommufd object: - - -device vfio-pci,host=0000:02:00.0 - -This is called the legacy mode/backend. - -If the user wants to use the iommufd backend (/dev/iommu) it -shall pass an iommufd object id in the vfio-pci device options: - - -object iommufd,id=iommufd0 - -device vfio-pci,host=0000:02:00.0,iommufd=iommufd0 - -Suggested-by: Alex Williamson -Signed-off-by: Eric Auger -Signed-off-by: Yi Liu -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit ee42b261b0a2e465ae003ddcaf1caf117c201f74) -Signed-off-by: Eric Auger ---- - hw/vfio/pci.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 83b2561908..39e6a6678e 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -19,6 +19,7 @@ - */ - - #include "qemu/osdep.h" -+#include CONFIG_DEVICES /* CONFIG_IOMMUFD */ - #include - #include - -@@ -42,6 +43,7 @@ - #include "qapi/error.h" - #include "migration/blocker.h" - #include "migration/qemu-file.h" -+#include "sysemu/iommufd.h" - - #define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug" - -@@ -3415,6 +3417,10 @@ static Property vfio_pci_dev_properties[] = { - * DEFINE_PROP_STRING("vfiofd", VFIOPCIDevice, vfiofd_name), - * DEFINE_PROP_STRING("vfiogroupfd, VFIOPCIDevice, vfiogroupfd_name), - */ -+#ifdef CONFIG_IOMMUFD -+ DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd, -+ TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *), -+#endif - DEFINE_PROP_END_OF_LIST(), - }; - --- -2.39.3 - diff --git a/kvm-vfio-pci-Clear-MSI-X-IRQ-index-always.patch b/kvm-vfio-pci-Clear-MSI-X-IRQ-index-always.patch deleted file mode 100644 index 837e490..0000000 --- a/kvm-vfio-pci-Clear-MSI-X-IRQ-index-always.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 43236995e8ad336d366b625fb8362046be53fc34 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Mon, 29 Jan 2024 09:46:34 +0100 -Subject: [PATCH] vfio/pci: Clear MSI-X IRQ index always -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Cédric Le Goater -RH-MergeRequest: 218: vfio/pci: Clear MSI-X IRQ index always -RH-Jira: RHEL-21293 -RH-Acked-by: Eric Auger -RH-Acked-by: Alex Williamson -RH-Commit: [1/1] b4b587b13c11e350d3e5fcc11ba66a006b25a763 (clegoate/qemu-kvm-c9s) - -JIRA: https://issues.redhat.com/browse/RHEL-21293 - -commit d2b668fca5652760b435ce812a743bba03d2f316 -Author: Cédric Le Goater -Date: Thu Jan 25 14:27:36 2024 +0100 - - vfio/pci: Clear MSI-X IRQ index always - - When doing device assignment of a physical device, MSI-X can be - enabled with no vectors enabled and this sets the IRQ index to - VFIO_PCI_MSIX_IRQ_INDEX. However, when MSI-X is disabled, the IRQ - index is left untouched if no vectors are in use. Then, when INTx - is enabled, the IRQ index value is considered incompatible (set to - MSI-X) and VFIO_DEVICE_SET_IRQS fails. QEMU complains with : - - qemu-system-x86_64: vfio 0000:08:00.0: Failed to set up TRIGGER eventfd signaling for interrupt INTX-0: VFIO_DEVICE_SET_IRQS failure: Invalid argument - - To avoid that, unconditionaly clear the IRQ index when MSI-X is - disabled. - - Buglink: https://issues.redhat.com/browse/RHEL-21293 - Fixes: 5ebffa4e87e7 ("vfio/pci: use an invalid fd to enable MSI-X") - Cc: Jing Liu - Cc: Alex Williamson - Reviewed-by: Alex Williamson - Signed-off-by: Cédric Le Goater - -Signed-off-by: Cédric Le Goater ---- - hw/vfio/pci.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index adb7c09367..29bb8067eb 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -829,9 +829,11 @@ static void vfio_msix_disable(VFIOPCIDevice *vdev) - } - } - -- if (vdev->nr_vectors) { -- vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX); -- } -+ /* -+ * Always clear MSI-X IRQ index. A PF device could have enabled -+ * MSI-X with no vectors. See vfio_msix_enable(). -+ */ -+ vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX); - - vfio_msi_disable_common(vdev); - vfio_intx_enable(vdev, &err); --- -2.39.3 - diff --git a/kvm-vfio-pci-Extract-out-a-helper-vfio_pci_get_pci_hot_r.patch b/kvm-vfio-pci-Extract-out-a-helper-vfio_pci_get_pci_hot_r.patch deleted file mode 100644 index af6593c..0000000 --- a/kvm-vfio-pci-Extract-out-a-helper-vfio_pci_get_pci_hot_r.patch +++ /dev/null @@ -1,139 +0,0 @@ -From fe5ecedd452754eeb238b23eb0544ed3c5086157 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:06 +0800 -Subject: [PATCH 027/101] vfio/pci: Extract out a helper - vfio_pci_get_pci_hot_reset_info -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [26/67] 730b7f1496f4f21310fa13c79cb87f8d5e2ad2a8 (eauger1/centos-qemu-kvm) - -This helper will be used by both legacy and iommufd backends. - -No functional changes intended. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Auger -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 4d36ec23a75eb387492f4d68ff1b8eeee5d68142) -Signed-off-by: Eric Auger ---- - hw/vfio/pci.c | 54 +++++++++++++++++++++++++++++++++++---------------- - hw/vfio/pci.h | 3 +++ - 2 files changed, 40 insertions(+), 17 deletions(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index ec98080f28..b482e5479f 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2448,22 +2448,13 @@ static bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const char *name) - return (strcmp(tmp, name) == 0); - } - --static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) -+int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev, -+ struct vfio_pci_hot_reset_info **info_p) - { -- VFIOGroup *group; - struct vfio_pci_hot_reset_info *info; -- struct vfio_pci_dependent_device *devices; -- struct vfio_pci_hot_reset *reset; -- int32_t *fds; -- int ret, i, count; -- bool multi = false; -+ int ret, count; - -- trace_vfio_pci_hot_reset(vdev->vbasedev.name, single ? "one" : "multi"); -- -- if (!single) { -- vfio_pci_pre_reset(vdev); -- } -- vdev->vbasedev.needs_reset = false; -+ assert(info_p && !*info_p); - - info = g_malloc0(sizeof(*info)); - info->argsz = sizeof(*info); -@@ -2471,24 +2462,53 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info); - if (ret && errno != ENOSPC) { - ret = -errno; -+ g_free(info); - if (!vdev->has_pm_reset) { - error_report("vfio: Cannot reset device %s, " - "no available reset mechanism.", vdev->vbasedev.name); - } -- goto out_single; -+ return ret; - } - - count = info->count; -- info = g_realloc(info, sizeof(*info) + (count * sizeof(*devices))); -- info->argsz = sizeof(*info) + (count * sizeof(*devices)); -- devices = &info->devices[0]; -+ info = g_realloc(info, sizeof(*info) + (count * sizeof(info->devices[0]))); -+ info->argsz = sizeof(*info) + (count * sizeof(info->devices[0])); - - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info); - if (ret) { - ret = -errno; -+ g_free(info); - error_report("vfio: hot reset info failed: %m"); -+ return ret; -+ } -+ -+ *info_p = info; -+ return 0; -+} -+ -+static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) -+{ -+ VFIOGroup *group; -+ struct vfio_pci_hot_reset_info *info = NULL; -+ struct vfio_pci_dependent_device *devices; -+ struct vfio_pci_hot_reset *reset; -+ int32_t *fds; -+ int ret, i, count; -+ bool multi = false; -+ -+ trace_vfio_pci_hot_reset(vdev->vbasedev.name, single ? "one" : "multi"); -+ -+ if (!single) { -+ vfio_pci_pre_reset(vdev); -+ } -+ vdev->vbasedev.needs_reset = false; -+ -+ ret = vfio_pci_get_pci_hot_reset_info(vdev, &info); -+ -+ if (ret) { - goto out_single; - } -+ devices = &info->devices[0]; - - trace_vfio_pci_hot_reset_has_dep_devices(vdev->vbasedev.name); - -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index eb74d9de2d..3568a6135d 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -219,6 +219,9 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr); - - extern const PropertyInfo qdev_prop_nv_gpudirect_clique; - -+int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev, -+ struct vfio_pci_hot_reset_info **info_p); -+ - int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp); - - int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, --- -2.39.3 - diff --git a/kvm-vfio-pci-Introduce-a-vfio-pci-hot-reset-interface.patch b/kvm-vfio-pci-Introduce-a-vfio-pci-hot-reset-interface.patch deleted file mode 100644 index 2a2db5f..0000000 --- a/kvm-vfio-pci-Introduce-a-vfio-pci-hot-reset-interface.patch +++ /dev/null @@ -1,466 +0,0 @@ -From acc3e5306e184567006bc45e7f36f2473e75d08a Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:07 +0800 -Subject: [PATCH 028/101] vfio/pci: Introduce a vfio pci hot reset interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [27/67] 192088dbf2cf88663acd2416f69b7eeb175b2525 (eauger1/centos-qemu-kvm) - -Legacy vfio pci and iommufd cdev have different process to hot reset -vfio device, expand current code to abstract out pci_hot_reset callback -for legacy vfio, this same interface will also be used by iommufd -cdev vfio device. - -Rename vfio_pci_hot_reset to vfio_legacy_pci_hot_reset and move it -into container.c. - -vfio_pci_[pre/post]_reset and vfio_pci_host_match are exported so -they could be called in legacy and iommufd pci_hot_reset callback. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Eric Auger -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit c328e7e8ad1c969dbcbe90ee76afcd3cfec5e945) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 170 ++++++++++++++++++++++++++ - hw/vfio/pci.c | 168 +------------------------ - hw/vfio/pci.h | 3 + - include/hw/vfio/vfio-container-base.h | 3 + - 4 files changed, 182 insertions(+), 162 deletions(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index ed2d721b2b..1dbf9b9a17 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -33,6 +33,7 @@ - #include "trace.h" - #include "qapi/error.h" - #include "migration/migration.h" -+#include "pci.h" - - VFIOGroupList vfio_group_list = - QLIST_HEAD_INITIALIZER(vfio_group_list); -@@ -922,6 +923,174 @@ static void vfio_legacy_detach_device(VFIODevice *vbasedev) - vfio_put_group(group); - } - -+static int vfio_legacy_pci_hot_reset(VFIODevice *vbasedev, bool single) -+{ -+ VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); -+ VFIOGroup *group; -+ struct vfio_pci_hot_reset_info *info = NULL; -+ struct vfio_pci_dependent_device *devices; -+ struct vfio_pci_hot_reset *reset; -+ int32_t *fds; -+ int ret, i, count; -+ bool multi = false; -+ -+ trace_vfio_pci_hot_reset(vdev->vbasedev.name, single ? "one" : "multi"); -+ -+ if (!single) { -+ vfio_pci_pre_reset(vdev); -+ } -+ vdev->vbasedev.needs_reset = false; -+ -+ ret = vfio_pci_get_pci_hot_reset_info(vdev, &info); -+ -+ if (ret) { -+ goto out_single; -+ } -+ devices = &info->devices[0]; -+ -+ trace_vfio_pci_hot_reset_has_dep_devices(vdev->vbasedev.name); -+ -+ /* Verify that we have all the groups required */ -+ for (i = 0; i < info->count; i++) { -+ PCIHostDeviceAddress host; -+ VFIOPCIDevice *tmp; -+ VFIODevice *vbasedev_iter; -+ -+ host.domain = devices[i].segment; -+ host.bus = devices[i].bus; -+ host.slot = PCI_SLOT(devices[i].devfn); -+ host.function = PCI_FUNC(devices[i].devfn); -+ -+ trace_vfio_pci_hot_reset_dep_devices(host.domain, -+ host.bus, host.slot, host.function, devices[i].group_id); -+ -+ if (vfio_pci_host_match(&host, vdev->vbasedev.name)) { -+ continue; -+ } -+ -+ QLIST_FOREACH(group, &vfio_group_list, next) { -+ if (group->groupid == devices[i].group_id) { -+ break; -+ } -+ } -+ -+ if (!group) { -+ if (!vdev->has_pm_reset) { -+ error_report("vfio: Cannot reset device %s, " -+ "depends on group %d which is not owned.", -+ vdev->vbasedev.name, devices[i].group_id); -+ } -+ ret = -EPERM; -+ goto out; -+ } -+ -+ /* Prep dependent devices for reset and clear our marker. */ -+ QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { -+ if (!vbasedev_iter->dev->realized || -+ vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) { -+ continue; -+ } -+ tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev); -+ if (vfio_pci_host_match(&host, tmp->vbasedev.name)) { -+ if (single) { -+ ret = -EINVAL; -+ goto out_single; -+ } -+ vfio_pci_pre_reset(tmp); -+ tmp->vbasedev.needs_reset = false; -+ multi = true; -+ break; -+ } -+ } -+ } -+ -+ if (!single && !multi) { -+ ret = -EINVAL; -+ goto out_single; -+ } -+ -+ /* Determine how many group fds need to be passed */ -+ count = 0; -+ QLIST_FOREACH(group, &vfio_group_list, next) { -+ for (i = 0; i < info->count; i++) { -+ if (group->groupid == devices[i].group_id) { -+ count++; -+ break; -+ } -+ } -+ } -+ -+ reset = g_malloc0(sizeof(*reset) + (count * sizeof(*fds))); -+ reset->argsz = sizeof(*reset) + (count * sizeof(*fds)); -+ fds = &reset->group_fds[0]; -+ -+ /* Fill in group fds */ -+ QLIST_FOREACH(group, &vfio_group_list, next) { -+ for (i = 0; i < info->count; i++) { -+ if (group->groupid == devices[i].group_id) { -+ fds[reset->count++] = group->fd; -+ break; -+ } -+ } -+ } -+ -+ /* Bus reset! */ -+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_PCI_HOT_RESET, reset); -+ g_free(reset); -+ if (ret) { -+ ret = -errno; -+ } -+ -+ trace_vfio_pci_hot_reset_result(vdev->vbasedev.name, -+ ret ? strerror(errno) : "Success"); -+ -+out: -+ /* Re-enable INTx on affected devices */ -+ for (i = 0; i < info->count; i++) { -+ PCIHostDeviceAddress host; -+ VFIOPCIDevice *tmp; -+ VFIODevice *vbasedev_iter; -+ -+ host.domain = devices[i].segment; -+ host.bus = devices[i].bus; -+ host.slot = PCI_SLOT(devices[i].devfn); -+ host.function = PCI_FUNC(devices[i].devfn); -+ -+ if (vfio_pci_host_match(&host, vdev->vbasedev.name)) { -+ continue; -+ } -+ -+ QLIST_FOREACH(group, &vfio_group_list, next) { -+ if (group->groupid == devices[i].group_id) { -+ break; -+ } -+ } -+ -+ if (!group) { -+ break; -+ } -+ -+ QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { -+ if (!vbasedev_iter->dev->realized || -+ vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) { -+ continue; -+ } -+ tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev); -+ if (vfio_pci_host_match(&host, tmp->vbasedev.name)) { -+ vfio_pci_post_reset(tmp); -+ break; -+ } -+ } -+ } -+out_single: -+ if (!single) { -+ vfio_pci_post_reset(vdev); -+ } -+ g_free(info); -+ -+ return ret; -+} -+ - const VFIOIOMMUOps vfio_legacy_ops = { - .dma_map = vfio_legacy_dma_map, - .dma_unmap = vfio_legacy_dma_unmap, -@@ -929,4 +1098,5 @@ const VFIOIOMMUOps vfio_legacy_ops = { - .detach_device = vfio_legacy_detach_device, - .set_dirty_page_tracking = vfio_legacy_set_dirty_page_tracking, - .query_dirty_bitmap = vfio_legacy_query_dirty_bitmap, -+ .pci_hot_reset = vfio_legacy_pci_hot_reset, - }; -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index b482e5479f..83b2561908 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2377,7 +2377,7 @@ static int vfio_add_capabilities(VFIOPCIDevice *vdev, Error **errp) - return 0; - } - --static void vfio_pci_pre_reset(VFIOPCIDevice *vdev) -+void vfio_pci_pre_reset(VFIOPCIDevice *vdev) - { - PCIDevice *pdev = &vdev->pdev; - uint16_t cmd; -@@ -2414,7 +2414,7 @@ static void vfio_pci_pre_reset(VFIOPCIDevice *vdev) - vfio_pci_write_config(pdev, PCI_COMMAND, cmd, 2); - } - --static void vfio_pci_post_reset(VFIOPCIDevice *vdev) -+void vfio_pci_post_reset(VFIOPCIDevice *vdev) - { - Error *err = NULL; - int nr; -@@ -2438,7 +2438,7 @@ static void vfio_pci_post_reset(VFIOPCIDevice *vdev) - vfio_quirk_reset(vdev); - } - --static bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const char *name) -+bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const char *name) - { - char tmp[13]; - -@@ -2488,166 +2488,10 @@ int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev, - - static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) - { -- VFIOGroup *group; -- struct vfio_pci_hot_reset_info *info = NULL; -- struct vfio_pci_dependent_device *devices; -- struct vfio_pci_hot_reset *reset; -- int32_t *fds; -- int ret, i, count; -- bool multi = false; -- -- trace_vfio_pci_hot_reset(vdev->vbasedev.name, single ? "one" : "multi"); -- -- if (!single) { -- vfio_pci_pre_reset(vdev); -- } -- vdev->vbasedev.needs_reset = false; -- -- ret = vfio_pci_get_pci_hot_reset_info(vdev, &info); -- -- if (ret) { -- goto out_single; -- } -- devices = &info->devices[0]; -- -- trace_vfio_pci_hot_reset_has_dep_devices(vdev->vbasedev.name); -- -- /* Verify that we have all the groups required */ -- for (i = 0; i < info->count; i++) { -- PCIHostDeviceAddress host; -- VFIOPCIDevice *tmp; -- VFIODevice *vbasedev_iter; -- -- host.domain = devices[i].segment; -- host.bus = devices[i].bus; -- host.slot = PCI_SLOT(devices[i].devfn); -- host.function = PCI_FUNC(devices[i].devfn); -- -- trace_vfio_pci_hot_reset_dep_devices(host.domain, -- host.bus, host.slot, host.function, devices[i].group_id); -- -- if (vfio_pci_host_match(&host, vdev->vbasedev.name)) { -- continue; -- } -- -- QLIST_FOREACH(group, &vfio_group_list, next) { -- if (group->groupid == devices[i].group_id) { -- break; -- } -- } -- -- if (!group) { -- if (!vdev->has_pm_reset) { -- error_report("vfio: Cannot reset device %s, " -- "depends on group %d which is not owned.", -- vdev->vbasedev.name, devices[i].group_id); -- } -- ret = -EPERM; -- goto out; -- } -- -- /* Prep dependent devices for reset and clear our marker. */ -- QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { -- if (!vbasedev_iter->dev->realized || -- vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) { -- continue; -- } -- tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev); -- if (vfio_pci_host_match(&host, tmp->vbasedev.name)) { -- if (single) { -- ret = -EINVAL; -- goto out_single; -- } -- vfio_pci_pre_reset(tmp); -- tmp->vbasedev.needs_reset = false; -- multi = true; -- break; -- } -- } -- } -- -- if (!single && !multi) { -- ret = -EINVAL; -- goto out_single; -- } -- -- /* Determine how many group fds need to be passed */ -- count = 0; -- QLIST_FOREACH(group, &vfio_group_list, next) { -- for (i = 0; i < info->count; i++) { -- if (group->groupid == devices[i].group_id) { -- count++; -- break; -- } -- } -- } -- -- reset = g_malloc0(sizeof(*reset) + (count * sizeof(*fds))); -- reset->argsz = sizeof(*reset) + (count * sizeof(*fds)); -- fds = &reset->group_fds[0]; -- -- /* Fill in group fds */ -- QLIST_FOREACH(group, &vfio_group_list, next) { -- for (i = 0; i < info->count; i++) { -- if (group->groupid == devices[i].group_id) { -- fds[reset->count++] = group->fd; -- break; -- } -- } -- } -- -- /* Bus reset! */ -- ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_PCI_HOT_RESET, reset); -- g_free(reset); -- -- trace_vfio_pci_hot_reset_result(vdev->vbasedev.name, -- ret ? strerror(errno) : "Success"); -- --out: -- /* Re-enable INTx on affected devices */ -- for (i = 0; i < info->count; i++) { -- PCIHostDeviceAddress host; -- VFIOPCIDevice *tmp; -- VFIODevice *vbasedev_iter; -- -- host.domain = devices[i].segment; -- host.bus = devices[i].bus; -- host.slot = PCI_SLOT(devices[i].devfn); -- host.function = PCI_FUNC(devices[i].devfn); -- -- if (vfio_pci_host_match(&host, vdev->vbasedev.name)) { -- continue; -- } -- -- QLIST_FOREACH(group, &vfio_group_list, next) { -- if (group->groupid == devices[i].group_id) { -- break; -- } -- } -- -- if (!group) { -- break; -- } -- -- QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { -- if (!vbasedev_iter->dev->realized || -- vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) { -- continue; -- } -- tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev); -- if (vfio_pci_host_match(&host, tmp->vbasedev.name)) { -- vfio_pci_post_reset(tmp); -- break; -- } -- } -- } --out_single: -- if (!single) { -- vfio_pci_post_reset(vdev); -- } -- g_free(info); -+ VFIODevice *vbasedev = &vdev->vbasedev; -+ const VFIOIOMMUOps *ops = vbasedev->bcontainer->ops; - -- return ret; -+ return ops->pci_hot_reset(vbasedev, single); - } - - /* -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index 3568a6135d..b7de39c010 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -219,6 +219,9 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr); - - extern const PropertyInfo qdev_prop_nv_gpudirect_clique; - -+void vfio_pci_pre_reset(VFIOPCIDevice *vdev); -+void vfio_pci_post_reset(VFIOPCIDevice *vdev); -+bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const char *name); - int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev, - struct vfio_pci_hot_reset_info **info_p); - -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 4b6f017c6f..45bb19c767 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -106,6 +106,9 @@ struct VFIOIOMMUOps { - int (*set_dirty_page_tracking)(VFIOContainerBase *bcontainer, bool start); - int (*query_dirty_bitmap)(VFIOContainerBase *bcontainer, VFIOBitmap *vbmap, - hwaddr iova, hwaddr size); -+ /* PCI specific */ -+ int (*pci_hot_reset)(VFIODevice *vbasedev, bool single); -+ - /* SPAPR specific */ - int (*add_window)(VFIOContainerBase *bcontainer, - MemoryRegionSection *section, --- -2.39.3 - diff --git a/kvm-vfio-pci-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch b/kvm-vfio-pci-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch deleted file mode 100644 index 4a973b5..0000000 --- a/kvm-vfio-pci-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch +++ /dev/null @@ -1,237 +0,0 @@ -From 965a44793806fef2094906947bd3b428638bf89a Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:10 +0800 -Subject: [PATCH 031/101] vfio/pci: Make vfio cdev pre-openable by passing a - file handle -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [30/67] a14b824b700e8fb36633cd159bcc422d992a316f (eauger1/centos-qemu-kvm) - -Conflicts: contextual conflict in hw/vfio/pci.c due to -RHEL-only f73562144e492 vfio: cap number of devices that can be assigned - -This gives management tools like libvirt a chance to open the vfio -cdev with privilege and pass FD to qemu. This way qemu never needs -to have privilege to open a VFIO or iommu cdev node. - -Together with the earlier support of pre-opening /dev/iommu device, -now we have full support of passing a vfio device to unprivileged -qemu by management tool. This mode is no more considered for the -legacy backend. So let's remove the "TODO" comment. - -Add helper functions vfio_device_set_fd() and vfio_device_get_name() -to set fd and get device name, they will also be used by other vfio -devices. - -There is no easy way to check if a device is mdev with FD passing, -so fail the x-balloon-allowed check unconditionally in this case. - -There is also no easy way to get BDF as name with FD passing, so -we fake a name by VFIO_FD[fd]. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Tested-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit da3e04b26fd8d15b344944504d5ffa9c5f20b54b) -Signed-off-by: Eric Auger ---- - hw/vfio/helpers.c | 43 +++++++++++++++++++++++++++++++++++ - hw/vfio/iommufd.c | 12 ++++++---- - hw/vfio/pci.c | 28 +++++++++++++---------- - include/hw/vfio/vfio-common.h | 4 ++++ - 4 files changed, 71 insertions(+), 16 deletions(-) - -diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c -index 168847e7c5..3592c3d54e 100644 ---- a/hw/vfio/helpers.c -+++ b/hw/vfio/helpers.c -@@ -27,6 +27,7 @@ - #include "trace.h" - #include "qapi/error.h" - #include "qemu/error-report.h" -+#include "monitor/monitor.h" - - /* - * Common VFIO interrupt disable -@@ -609,3 +610,45 @@ bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type) - - return ret; - } -+ -+int vfio_device_get_name(VFIODevice *vbasedev, Error **errp) -+{ -+ struct stat st; -+ -+ if (vbasedev->fd < 0) { -+ if (stat(vbasedev->sysfsdev, &st) < 0) { -+ error_setg_errno(errp, errno, "no such host device"); -+ error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->sysfsdev); -+ return -errno; -+ } -+ /* User may specify a name, e.g: VFIO platform device */ -+ if (!vbasedev->name) { -+ vbasedev->name = g_path_get_basename(vbasedev->sysfsdev); -+ } -+ } else { -+ if (!vbasedev->iommufd) { -+ error_setg(errp, "Use FD passing only with iommufd backend"); -+ return -EINVAL; -+ } -+ /* -+ * Give a name with fd so any function printing out vbasedev->name -+ * will not break. -+ */ -+ if (!vbasedev->name) { -+ vbasedev->name = g_strdup_printf("VFIO_FD%d", vbasedev->fd); -+ } -+ } -+ -+ return 0; -+} -+ -+void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp) -+{ -+ int fd = monitor_fd_param(monitor_cur(), str, errp); -+ -+ if (fd < 0) { -+ error_prepend(errp, "Could not parse remote object fd %s:", str); -+ return; -+ } -+ vbasedev->fd = fd; -+} -diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c -index 6e53e013ef..5accd26484 100644 ---- a/hw/vfio/iommufd.c -+++ b/hw/vfio/iommufd.c -@@ -320,11 +320,15 @@ static int iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, - uint32_t ioas_id; - Error *err = NULL; - -- devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp); -- if (devfd < 0) { -- return devfd; -+ if (vbasedev->fd < 0) { -+ devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp); -+ if (devfd < 0) { -+ return devfd; -+ } -+ vbasedev->fd = devfd; -+ } else { -+ devfd = vbasedev->fd; - } -- vbasedev->fd = devfd; - - ret = iommufd_cdev_connect_and_bind(vbasedev, errp); - if (ret) { -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 39e6a6678e..3412a63bb1 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2949,7 +2949,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - VFIOGroup *group; - char *tmp, *subsys; - Error *err = NULL; -- struct stat st; - int ret, i = 0; - bool is_mdev; - char uuid[UUID_STR_LEN]; -@@ -2976,11 +2975,14 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - return; - } - -- if (!vbasedev->sysfsdev) { -+ if (vbasedev->fd < 0 && !vbasedev->sysfsdev) { - if (!(~vdev->host.domain || ~vdev->host.bus || - ~vdev->host.slot || ~vdev->host.function)) { - error_setg(errp, "No provided host device"); - error_append_hint(errp, "Use -device vfio-pci,host=DDDD:BB:DD.F " -+#ifdef CONFIG_IOMMUFD -+ "or -device vfio-pci,fd=DEVICE_FD " -+#endif - "or -device vfio-pci,sysfsdev=PATH_TO_DEVICE\n"); - return; - } -@@ -2990,13 +2992,9 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - vdev->host.slot, vdev->host.function); - } - -- if (stat(vbasedev->sysfsdev, &st) < 0) { -- error_setg_errno(errp, errno, "no such host device"); -- error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->sysfsdev); -+ if (vfio_device_get_name(vbasedev, errp) < 0) { - return; - } -- -- vbasedev->name = g_path_get_basename(vbasedev->sysfsdev); - vbasedev->ops = &vfio_pci_ops; - vbasedev->type = VFIO_DEVICE_TYPE_PCI; - vbasedev->dev = DEVICE(vdev); -@@ -3356,6 +3354,7 @@ static void vfio_instance_init(Object *obj) - vdev->host.bus = ~0U; - vdev->host.slot = ~0U; - vdev->host.function = ~0U; -+ vdev->vbasedev.fd = -1; - - vdev->nv_gpudirect_clique = 0xFF; - -@@ -3412,11 +3411,6 @@ static Property vfio_pci_dev_properties[] = { - qdev_prop_nv_gpudirect_clique, uint8_t), - DEFINE_PROP_OFF_AUTO_PCIBAR("x-msix-relocation", VFIOPCIDevice, msix_relo, - OFF_AUTOPCIBAR_OFF), -- /* -- * TODO - support passed fds... is this necessary? -- * DEFINE_PROP_STRING("vfiofd", VFIOPCIDevice, vfiofd_name), -- * DEFINE_PROP_STRING("vfiogroupfd, VFIOPCIDevice, vfiogroupfd_name), -- */ - #ifdef CONFIG_IOMMUFD - DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd, - TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *), -@@ -3424,6 +3418,13 @@ static Property vfio_pci_dev_properties[] = { - DEFINE_PROP_END_OF_LIST(), - }; - -+#ifdef CONFIG_IOMMUFD -+static void vfio_pci_set_fd(Object *obj, const char *str, Error **errp) -+{ -+ vfio_device_set_fd(&VFIO_PCI(obj)->vbasedev, str, errp); -+} -+#endif -+ - static void vfio_pci_dev_class_init(ObjectClass *klass, void *data) - { - DeviceClass *dc = DEVICE_CLASS(klass); -@@ -3431,6 +3432,9 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data) - - dc->reset = vfio_pci_reset; - device_class_set_props(dc, vfio_pci_dev_properties); -+#ifdef CONFIG_IOMMUFD -+ object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd); -+#endif - dc->desc = "VFIO-based PCI device assignment"; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); - pdc->realize = vfio_realize; -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 3dac5c167e..697bf24a35 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -251,4 +251,8 @@ int vfio_devices_query_dirty_bitmap(VFIOContainerBase *bcontainer, - hwaddr size); - int vfio_get_dirty_bitmap(VFIOContainerBase *bcontainer, uint64_t iova, - uint64_t size, ram_addr_t ram_addr); -+ -+/* Returns 0 on success, or a negative errno. */ -+int vfio_device_get_name(VFIODevice *vbasedev, Error **errp); -+void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp); - #endif /* HW_VFIO_VFIO_COMMON_H */ --- -2.39.3 - diff --git a/kvm-vfio-pci-Move-VFIODevice-initializations-in-vfio_ins.patch b/kvm-vfio-pci-Move-VFIODevice-initializations-in-vfio_ins.patch deleted file mode 100644 index d426ede..0000000 --- a/kvm-vfio-pci-Move-VFIODevice-initializations-in-vfio_ins.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 942bd7251d166f558e0e6acf7ba853e940e2fb52 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:21 +0800 -Subject: [PATCH 042/101] vfio/pci: Move VFIODevice initializations in - vfio_instance_init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [41/67] 67392d7a92a6ec2155697a355c88d295338a0785 (eauger1/centos-qemu-kvm) - -Some of the VFIODevice initializations is in vfio_realize, -move all of them in vfio_instance_init. - -No functional change intended. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Philippe Mathieu-Daudé -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit dd2fcb1716be9b89c726b3446f38446bb99d6b3a) -Signed-off-by: Eric Auger ---- - hw/vfio/pci.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 3412a63bb1..3f5900cc46 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2995,9 +2995,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - if (vfio_device_get_name(vbasedev, errp) < 0) { - return; - } -- vbasedev->ops = &vfio_pci_ops; -- vbasedev->type = VFIO_DEVICE_TYPE_PCI; -- vbasedev->dev = DEVICE(vdev); - - /* - * Mediated devices *might* operate compatibly with discarding of RAM, but -@@ -3346,6 +3343,7 @@ static void vfio_instance_init(Object *obj) - { - PCIDevice *pci_dev = PCI_DEVICE(obj); - VFIOPCIDevice *vdev = VFIO_PCI(obj); -+ VFIODevice *vbasedev = &vdev->vbasedev; - - device_add_bootindex_property(obj, &vdev->bootindex, - "bootindex", NULL, -@@ -3354,7 +3352,11 @@ static void vfio_instance_init(Object *obj) - vdev->host.bus = ~0U; - vdev->host.slot = ~0U; - vdev->host.function = ~0U; -- vdev->vbasedev.fd = -1; -+ -+ vbasedev->type = VFIO_DEVICE_TYPE_PCI; -+ vbasedev->ops = &vfio_pci_ops; -+ vbasedev->dev = DEVICE(vdev); -+ vbasedev->fd = -1; - - vdev->nv_gpudirect_clique = 0xFF; - --- -2.39.3 - diff --git a/kvm-vfio-platform-Allow-the-selection-of-a-given-iommu-b.patch b/kvm-vfio-platform-Allow-the-selection-of-a-given-iommu-b.patch deleted file mode 100644 index 06c2f0f..0000000 --- a/kvm-vfio-platform-Allow-the-selection-of-a-given-iommu-b.patch +++ /dev/null @@ -1,77 +0,0 @@ -From ede579d6d5fe5be9235d6a218efdb237192aee0e Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:11 +0800 -Subject: [PATCH 032/101] vfio/platform: Allow the selection of a given iommu - backend -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [31/67] aba1dc16cada602edd7be1a28b0f57991131e6f7 (eauger1/centos-qemu-kvm) - -Now we support two types of iommu backends, let's add the capability -to select one of them. This depends on whether an iommufd object has -been linked with the vfio-platform device: - -If the user wants to use the legacy backend, it shall not -link the vfio-platform device with any iommufd object: - - -device vfio-platform,host=XXX - -This is called the legacy mode/backend. - -If the user wants to use the iommufd backend (/dev/iommu) it -shall pass an iommufd object id in the vfio-platform device options: - - -object iommufd,id=iommufd0 - -device vfio-platform,host=XXX,iommufd=iommufd0 - -Suggested-by: Alex Williamson -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Reviewed-by: Eric Auger -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit a6c50e1c3f8d0eb77edaea392e61508bb3c516f8) -Signed-off-by: Eric Auger ---- - hw/vfio/platform.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c -index 8e3d4ac458..98ae4bc655 100644 ---- a/hw/vfio/platform.c -+++ b/hw/vfio/platform.c -@@ -15,11 +15,13 @@ - */ - - #include "qemu/osdep.h" -+#include CONFIG_DEVICES /* CONFIG_IOMMUFD */ - #include "qapi/error.h" - #include - #include - - #include "hw/vfio/vfio-platform.h" -+#include "sysemu/iommufd.h" - #include "migration/vmstate.h" - #include "qemu/error-report.h" - #include "qemu/lockable.h" -@@ -649,6 +651,10 @@ static Property vfio_platform_dev_properties[] = { - DEFINE_PROP_UINT32("mmap-timeout-ms", VFIOPlatformDevice, - mmap_timeout, 1100), - DEFINE_PROP_BOOL("x-irqfd", VFIOPlatformDevice, irqfd_allowed, true), -+#ifdef CONFIG_IOMMUFD -+ DEFINE_PROP_LINK("iommufd", VFIOPlatformDevice, vbasedev.iommufd, -+ TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *), -+#endif - DEFINE_PROP_END_OF_LIST(), - }; - --- -2.39.3 - diff --git a/kvm-vfio-platform-Make-vfio-cdev-pre-openable-by-passing.patch b/kvm-vfio-platform-Make-vfio-cdev-pre-openable-by-passing.patch deleted file mode 100644 index f931524..0000000 --- a/kvm-vfio-platform-Make-vfio-cdev-pre-openable-by-passing.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 22664f4115d9b297ef4276e48f8ba0bc195ec99e Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:12 +0800 -Subject: [PATCH 033/101] vfio/platform: Make vfio cdev pre-openable by passing - a file handle -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [32/67] 069867dce64b826e92dc2051405a4ded5261981f (eauger1/centos-qemu-kvm) - -This gives management tools like libvirt a chance to open the vfio -cdev with privilege and pass FD to qemu. This way qemu never needs -to have privilege to open a VFIO or iommu cdev node. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit 3016e60f8f715d2058a48e4956be994482c5e218) -Signed-off-by: Eric Auger ---- - hw/vfio/platform.c | 32 ++++++++++++++++++++++++-------- - 1 file changed, 24 insertions(+), 8 deletions(-) - -diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c -index 98ae4bc655..a97d9c6234 100644 ---- a/hw/vfio/platform.c -+++ b/hw/vfio/platform.c -@@ -531,14 +531,13 @@ static VFIODeviceOps vfio_platform_ops = { - */ - static int vfio_base_device_init(VFIODevice *vbasedev, Error **errp) - { -- struct stat st; - int ret; - -- /* @sysfsdev takes precedence over @host */ -- if (vbasedev->sysfsdev) { -+ /* @fd takes precedence over @sysfsdev which takes precedence over @host */ -+ if (vbasedev->fd < 0 && vbasedev->sysfsdev) { - g_free(vbasedev->name); - vbasedev->name = g_path_get_basename(vbasedev->sysfsdev); -- } else { -+ } else if (vbasedev->fd < 0) { - if (!vbasedev->name || strchr(vbasedev->name, '/')) { - error_setg(errp, "wrong host device name"); - return -EINVAL; -@@ -548,10 +547,9 @@ static int vfio_base_device_init(VFIODevice *vbasedev, Error **errp) - vbasedev->name); - } - -- if (stat(vbasedev->sysfsdev, &st) < 0) { -- error_setg_errno(errp, errno, -- "failed to get the sysfs host device file status"); -- return -errno; -+ ret = vfio_device_get_name(vbasedev, errp); -+ if (ret) { -+ return ret; - } - - ret = vfio_attach_device(vbasedev->name, vbasedev, -@@ -658,6 +656,20 @@ static Property vfio_platform_dev_properties[] = { - DEFINE_PROP_END_OF_LIST(), - }; - -+static void vfio_platform_instance_init(Object *obj) -+{ -+ VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(obj); -+ -+ vdev->vbasedev.fd = -1; -+} -+ -+#ifdef CONFIG_IOMMUFD -+static void vfio_platform_set_fd(Object *obj, const char *str, Error **errp) -+{ -+ vfio_device_set_fd(&VFIO_PLATFORM_DEVICE(obj)->vbasedev, str, errp); -+} -+#endif -+ - static void vfio_platform_class_init(ObjectClass *klass, void *data) - { - DeviceClass *dc = DEVICE_CLASS(klass); -@@ -665,6 +677,9 @@ static void vfio_platform_class_init(ObjectClass *klass, void *data) - - dc->realize = vfio_platform_realize; - device_class_set_props(dc, vfio_platform_dev_properties); -+#ifdef CONFIG_IOMMUFD -+ object_class_property_add_str(klass, "fd", NULL, vfio_platform_set_fd); -+#endif - dc->vmsd = &vfio_platform_vmstate; - dc->desc = "VFIO-based platform device assignment"; - sbc->connect_irq_notifier = vfio_start_irqfd_injection; -@@ -677,6 +692,7 @@ static const TypeInfo vfio_platform_dev_info = { - .name = TYPE_VFIO_PLATFORM, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(VFIOPlatformDevice), -+ .instance_init = vfio_platform_instance_init, - .class_init = vfio_platform_class_init, - .class_size = sizeof(VFIOPlatformDeviceClass), - }; --- -2.39.3 - diff --git a/kvm-vfio-platform-Move-VFIODevice-initializations-in-vfi.patch b/kvm-vfio-platform-Move-VFIODevice-initializations-in-vfi.patch deleted file mode 100644 index 56283a6..0000000 --- a/kvm-vfio-platform-Move-VFIODevice-initializations-in-vfi.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 2417020283532030f424fe07dfeb7477e6489640 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Tue, 21 Nov 2023 16:44:22 +0800 -Subject: [PATCH 043/101] vfio/platform: Move VFIODevice initializations in - vfio_platform_instance_init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [42/67] 53a459b6246d7d7bdc7a62ac92f02f1e775a54a6 (eauger1/centos-qemu-kvm) - -Some of the VFIODevice initializations is in vfio_platform_realize, -move all of them in vfio_platform_instance_init. - -No functional change intended. - -Suggested-by: Cédric Le Goater -Signed-off-by: Zhenzhong Duan -Reviewed-by: Philippe Mathieu-Daudé -Tested-by: Nicolin Chen -Signed-off-by: Cédric Le Goater -(cherry picked from commit a0cf44c8d618578843a65ea7f6d3db8ce52185bc) -Signed-off-by: Eric Auger ---- - hw/vfio/platform.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c -index a97d9c6234..506eb8193f 100644 ---- a/hw/vfio/platform.c -+++ b/hw/vfio/platform.c -@@ -581,10 +581,6 @@ static void vfio_platform_realize(DeviceState *dev, Error **errp) - VFIODevice *vbasedev = &vdev->vbasedev; - int i, ret; - -- vbasedev->type = VFIO_DEVICE_TYPE_PLATFORM; -- vbasedev->dev = dev; -- vbasedev->ops = &vfio_platform_ops; -- - qemu_mutex_init(&vdev->intp_mutex); - - trace_vfio_platform_realize(vbasedev->sysfsdev ? -@@ -659,8 +655,12 @@ static Property vfio_platform_dev_properties[] = { - static void vfio_platform_instance_init(Object *obj) - { - VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(obj); -+ VFIODevice *vbasedev = &vdev->vbasedev; - -- vdev->vbasedev.fd = -1; -+ vbasedev->type = VFIO_DEVICE_TYPE_PLATFORM; -+ vbasedev->ops = &vfio_platform_ops; -+ vbasedev->dev = DEVICE(vdev); -+ vbasedev->fd = -1; - } - - #ifdef CONFIG_IOMMUFD --- -2.39.3 - diff --git a/kvm-vfio-spapr-Extend-VFIOIOMMUOps-with-a-release-handle.patch b/kvm-vfio-spapr-Extend-VFIOIOMMUOps-with-a-release-handle.patch deleted file mode 100644 index fb7e707..0000000 --- a/kvm-vfio-spapr-Extend-VFIOIOMMUOps-with-a-release-handle.patch +++ /dev/null @@ -1,129 +0,0 @@ -From e75ec2aca351daabe597ca6322c1589885f30d7a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:16 +0100 -Subject: [PATCH 049/101] vfio/spapr: Extend VFIOIOMMUOps with a release - handler -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [48/67] 1c4d22a6f69324805d050767fcf178d8566f2030 (eauger1/centos-qemu-kvm) - -This allows to abstract a bit more the sPAPR IOMMU support in the -legacy IOMMU backend. - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit 001a013ea3f125d2ec0e709b5765754149d8d968) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 10 +++----- - hw/vfio/spapr.c | 35 +++++++++++++++------------ - include/hw/vfio/vfio-container-base.h | 1 + - 3 files changed, 24 insertions(+), 22 deletions(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index b22feb8ded..1e77a2929e 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -632,9 +632,8 @@ listener_release_exit: - QLIST_REMOVE(bcontainer, next); - vfio_kvm_device_del_group(group); - memory_listener_unregister(&bcontainer->listener); -- if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU || -- container->iommu_type == VFIO_SPAPR_TCE_IOMMU) { -- vfio_spapr_container_deinit(container); -+ if (bcontainer->ops->release) { -+ bcontainer->ops->release(bcontainer); - } - - enable_discards_exit: -@@ -667,9 +666,8 @@ static void vfio_disconnect_container(VFIOGroup *group) - */ - if (QLIST_EMPTY(&container->group_list)) { - memory_listener_unregister(&bcontainer->listener); -- if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU || -- container->iommu_type == VFIO_SPAPR_TCE_IOMMU) { -- vfio_spapr_container_deinit(container); -+ if (bcontainer->ops->release) { -+ bcontainer->ops->release(bcontainer); - } - } - -diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c -index 5c6426e697..44617dfc6b 100644 ---- a/hw/vfio/spapr.c -+++ b/hw/vfio/spapr.c -@@ -440,6 +440,24 @@ vfio_spapr_container_del_section_window(VFIOContainerBase *bcontainer, - } - } - -+static void vfio_spapr_container_release(VFIOContainerBase *bcontainer) -+{ -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); -+ VFIOSpaprContainer *scontainer = container_of(container, VFIOSpaprContainer, -+ container); -+ VFIOHostDMAWindow *hostwin, *next; -+ -+ if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { -+ memory_listener_unregister(&scontainer->prereg_listener); -+ } -+ QLIST_FOREACH_SAFE(hostwin, &scontainer->hostwin_list, hostwin_next, -+ next) { -+ QLIST_REMOVE(hostwin, hostwin_next); -+ g_free(hostwin); -+ } -+} -+ - static VFIOIOMMUOps vfio_iommu_spapr_ops; - - static void setup_spapr_ops(VFIOContainerBase *bcontainer) -@@ -447,6 +465,7 @@ static void setup_spapr_ops(VFIOContainerBase *bcontainer) - vfio_iommu_spapr_ops = *bcontainer->ops; - vfio_iommu_spapr_ops.add_window = vfio_spapr_container_add_section_window; - vfio_iommu_spapr_ops.del_window = vfio_spapr_container_del_section_window; -+ vfio_iommu_spapr_ops.release = vfio_spapr_container_release; - bcontainer->ops = &vfio_iommu_spapr_ops; - } - -@@ -527,19 +546,3 @@ listener_unregister_exit: - } - return ret; - } -- --void vfio_spapr_container_deinit(VFIOContainer *container) --{ -- VFIOSpaprContainer *scontainer = container_of(container, VFIOSpaprContainer, -- container); -- VFIOHostDMAWindow *hostwin, *next; -- -- if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { -- memory_listener_unregister(&scontainer->prereg_listener); -- } -- QLIST_FOREACH_SAFE(hostwin, &scontainer->hostwin_list, hostwin_next, -- next) { -- QLIST_REMOVE(hostwin, hostwin_next); -- g_free(hostwin); -- } --} -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 2ae297ccda..5c9594b6c7 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -117,5 +117,6 @@ struct VFIOIOMMUOps { - Error **errp); - void (*del_window)(VFIOContainerBase *bcontainer, - MemoryRegionSection *section); -+ void (*release)(VFIOContainerBase *bcontainer); - }; - #endif /* HW_VFIO_VFIO_CONTAINER_BASE_H */ --- -2.39.3 - diff --git a/kvm-vfio-spapr-Introduce-a-sPAPR-VFIOIOMMU-QOM-interface.patch b/kvm-vfio-spapr-Introduce-a-sPAPR-VFIOIOMMU-QOM-interface.patch deleted file mode 100644 index f835acb..0000000 --- a/kvm-vfio-spapr-Introduce-a-sPAPR-VFIOIOMMU-QOM-interface.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 645ed97633935712edcc2c56f252738b38f15e3a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:22 +0100 -Subject: [PATCH 055/101] vfio/spapr: Introduce a sPAPR VFIOIOMMU QOM interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [54/67] 2ceac3c07d71790dc3852fbbbd4084a7affb9373 (eauger1/centos-qemu-kvm) - -Move vfio_spapr_container_setup() to a VFIOIOMMUClass::setup handler -and convert the sPAPR VFIOIOMMUOps struct to a QOM interface. The -sPAPR QOM interface inherits from the legacy QOM interface because -because both have the same basic needs. The sPAPR interface is then -extended with the handlers specific to the sPAPR IOMMU. - -This allows reuse and provides better abstraction of the backends. It -will be useful to avoid compiling the sPAPR IOMMU backend on targets -not supporting it. - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit f221f641a2fe69c2ca3857759551470664b0bec8) -Signed-off-by: Eric Auger ---- - hw/vfio/container.c | 18 +++++-------- - hw/vfio/spapr.c | 39 ++++++++++++++++----------- - include/hw/vfio/vfio-container-base.h | 1 + - 3 files changed, 31 insertions(+), 27 deletions(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index c22bdd3216..688cf23bab 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -381,6 +381,10 @@ static const VFIOIOMMUClass *vfio_get_iommu_class(int iommu_type, Error **errp) - case VFIO_TYPE1_IOMMU: - klass = object_class_by_name(TYPE_VFIO_IOMMU_LEGACY); - break; -+ case VFIO_SPAPR_TCE_v2_IOMMU: -+ case VFIO_SPAPR_TCE_IOMMU: -+ klass = object_class_by_name(TYPE_VFIO_IOMMU_SPAPR); -+ break; - default: - g_assert_not_reached(); - }; -@@ -623,19 +627,9 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - goto free_container_exit; - } - -- switch (container->iommu_type) { -- case VFIO_TYPE1v2_IOMMU: -- case VFIO_TYPE1_IOMMU: -- ret = vfio_legacy_setup(bcontainer, errp); -- break; -- case VFIO_SPAPR_TCE_v2_IOMMU: -- case VFIO_SPAPR_TCE_IOMMU: -- ret = vfio_spapr_container_init(container, errp); -- break; -- default: -- g_assert_not_reached(); -- } -+ assert(bcontainer->ops->setup); - -+ ret = bcontainer->ops->setup(bcontainer, errp); - if (ret) { - goto enable_discards_exit; - } -diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c -index 44617dfc6b..0d949bb728 100644 ---- a/hw/vfio/spapr.c -+++ b/hw/vfio/spapr.c -@@ -458,20 +458,11 @@ static void vfio_spapr_container_release(VFIOContainerBase *bcontainer) - } - } - --static VFIOIOMMUOps vfio_iommu_spapr_ops; -- --static void setup_spapr_ops(VFIOContainerBase *bcontainer) --{ -- vfio_iommu_spapr_ops = *bcontainer->ops; -- vfio_iommu_spapr_ops.add_window = vfio_spapr_container_add_section_window; -- vfio_iommu_spapr_ops.del_window = vfio_spapr_container_del_section_window; -- vfio_iommu_spapr_ops.release = vfio_spapr_container_release; -- bcontainer->ops = &vfio_iommu_spapr_ops; --} -- --int vfio_spapr_container_init(VFIOContainer *container, Error **errp) -+static int vfio_spapr_container_setup(VFIOContainerBase *bcontainer, -+ Error **errp) - { -- VFIOContainerBase *bcontainer = &container->bcontainer; -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - VFIOSpaprContainer *scontainer = container_of(container, VFIOSpaprContainer, - container); - struct vfio_iommu_spapr_tce_info info; -@@ -536,8 +527,6 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - 0x1000); - } - -- setup_spapr_ops(bcontainer); -- - return 0; - - listener_unregister_exit: -@@ -546,3 +535,23 @@ listener_unregister_exit: - } - return ret; - } -+ -+static void vfio_iommu_spapr_class_init(ObjectClass *klass, void *data) -+{ -+ VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass); -+ -+ vioc->add_window = vfio_spapr_container_add_section_window; -+ vioc->del_window = vfio_spapr_container_del_section_window; -+ vioc->release = vfio_spapr_container_release; -+ vioc->setup = vfio_spapr_container_setup; -+}; -+ -+static const TypeInfo types[] = { -+ { -+ .name = TYPE_VFIO_IOMMU_SPAPR, -+ .parent = TYPE_VFIO_IOMMU_LEGACY, -+ .class_init = vfio_iommu_spapr_class_init, -+ }, -+}; -+ -+DEFINE_TYPES(types) -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index ce8b1fba88..9e21d7811f 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -95,6 +95,7 @@ void vfio_container_destroy(VFIOContainerBase *bcontainer); - - #define TYPE_VFIO_IOMMU "vfio-iommu" - #define TYPE_VFIO_IOMMU_LEGACY TYPE_VFIO_IOMMU "-legacy" -+#define TYPE_VFIO_IOMMU_SPAPR TYPE_VFIO_IOMMU "-spapr" - - /* - * VFIOContainerBase is not an abstract QOM object because it felt --- -2.39.3 - diff --git a/kvm-vfio-spapr-Introduce-spapr-backend-and-target-interf.patch b/kvm-vfio-spapr-Introduce-spapr-backend-and-target-interf.patch deleted file mode 100644 index f1ca4a2..0000000 --- a/kvm-vfio-spapr-Introduce-spapr-backend-and-target-interf.patch +++ /dev/null @@ -1,91 +0,0 @@ -From ff0c13c22878eed0f3879c0805bef5b9f9d83e04 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:42 +0800 -Subject: [PATCH 017/101] vfio/spapr: Introduce spapr backend and target - interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [16/67] e35cda157a2a1afeded3305622c861abd07edb51 (eauger1/centos-qemu-kvm) - -Introduce an empty spapr backend which will hold spapr specific -content, currently only prereg_listener and hostwin_list. - -Also introduce two spapr specific callbacks add/del_window into -VFIOIOMMUOps. Instantiate a spapr ops with a helper setup_spapr_ops -and assign it to bcontainer->ops. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit 9b7d38bf5a2c1054bfe6de08806954cdc45d8d98) -Signed-off-by: Eric Auger ---- - hw/vfio/spapr.c | 14 ++++++++++++++ - include/hw/vfio/vfio-container-base.h | 6 ++++++ - 2 files changed, 20 insertions(+) - -diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c -index 7a50975f25..e1a6b35563 100644 ---- a/hw/vfio/spapr.c -+++ b/hw/vfio/spapr.c -@@ -24,6 +24,10 @@ - #include "qapi/error.h" - #include "trace.h" - -+typedef struct VFIOSpaprContainer { -+ VFIOContainer container; -+} VFIOSpaprContainer; -+ - static bool vfio_prereg_listener_skipped_section(MemoryRegionSection *section) - { - if (memory_region_is_iommu(section->mr)) { -@@ -421,6 +425,14 @@ void vfio_container_del_section_window(VFIOContainer *container, - } - } - -+static VFIOIOMMUOps vfio_iommu_spapr_ops; -+ -+static void setup_spapr_ops(VFIOContainerBase *bcontainer) -+{ -+ vfio_iommu_spapr_ops = *bcontainer->ops; -+ bcontainer->ops = &vfio_iommu_spapr_ops; -+} -+ - int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - { - VFIOContainerBase *bcontainer = &container->bcontainer; -@@ -486,6 +498,8 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - 0x1000); - } - -+ setup_spapr_ops(bcontainer); -+ - return 0; - - listener_unregister_exit: -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index 9658ffb526..f62a14ac73 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -101,5 +101,11 @@ struct VFIOIOMMUOps { - int (*set_dirty_page_tracking)(VFIOContainerBase *bcontainer, bool start); - int (*query_dirty_bitmap)(VFIOContainerBase *bcontainer, VFIOBitmap *vbmap, - hwaddr iova, hwaddr size); -+ /* SPAPR specific */ -+ int (*add_window)(VFIOContainerBase *bcontainer, -+ MemoryRegionSection *section, -+ Error **errp); -+ void (*del_window)(VFIOContainerBase *bcontainer, -+ MemoryRegionSection *section); - }; - #endif /* HW_VFIO_VFIO_CONTAINER_BASE_H */ --- -2.39.3 - diff --git a/kvm-vfio-spapr-Move-hostwin_list-into-spapr-container.patch b/kvm-vfio-spapr-Move-hostwin_list-into-spapr-container.patch deleted file mode 100644 index 93cb6b8..0000000 --- a/kvm-vfio-spapr-Move-hostwin_list-into-spapr-container.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 3e9e7b57b15ac328f5d663b4e04df546d49f5fa6 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:45 +0800 -Subject: [PATCH 020/101] vfio/spapr: Move hostwin_list into spapr container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [19/67] 87cfeaa32ad32a260a89b2bb1866d59e20c0fe30 (eauger1/centos-qemu-kvm) - -No functional changes intended. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit dbb9d0c9691d145338686d3e0920da047f2ab3da) -Signed-off-by: Eric Auger ---- - hw/vfio/spapr.c | 36 +++++++++++++++++++---------------- - include/hw/vfio/vfio-common.h | 1 - - 2 files changed, 20 insertions(+), 17 deletions(-) - -diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c -index 68c3dd6c75..5c6426e697 100644 ---- a/hw/vfio/spapr.c -+++ b/hw/vfio/spapr.c -@@ -27,6 +27,7 @@ - typedef struct VFIOSpaprContainer { - VFIOContainer container; - MemoryListener prereg_listener; -+ QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - } VFIOSpaprContainer; - - static bool vfio_prereg_listener_skipped_section(MemoryRegionSection *section) -@@ -154,12 +155,12 @@ static const MemoryListener vfio_prereg_listener = { - .region_del = vfio_prereg_listener_region_del, - }; - --static void vfio_host_win_add(VFIOContainer *container, hwaddr min_iova, -+static void vfio_host_win_add(VFIOSpaprContainer *scontainer, hwaddr min_iova, - hwaddr max_iova, uint64_t iova_pgsizes) - { - VFIOHostDMAWindow *hostwin; - -- QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { -+ QLIST_FOREACH(hostwin, &scontainer->hostwin_list, hostwin_next) { - if (ranges_overlap(hostwin->min_iova, - hostwin->max_iova - hostwin->min_iova + 1, - min_iova, -@@ -173,15 +174,15 @@ static void vfio_host_win_add(VFIOContainer *container, hwaddr min_iova, - hostwin->min_iova = min_iova; - hostwin->max_iova = max_iova; - hostwin->iova_pgsizes = iova_pgsizes; -- QLIST_INSERT_HEAD(&container->hostwin_list, hostwin, hostwin_next); -+ QLIST_INSERT_HEAD(&scontainer->hostwin_list, hostwin, hostwin_next); - } - --static int vfio_host_win_del(VFIOContainer *container, -+static int vfio_host_win_del(VFIOSpaprContainer *scontainer, - hwaddr min_iova, hwaddr max_iova) - { - VFIOHostDMAWindow *hostwin; - -- QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { -+ QLIST_FOREACH(hostwin, &scontainer->hostwin_list, hostwin_next) { - if (hostwin->min_iova == min_iova && hostwin->max_iova == max_iova) { - QLIST_REMOVE(hostwin, hostwin_next); - g_free(hostwin); -@@ -192,7 +193,7 @@ static int vfio_host_win_del(VFIOContainer *container, - return -1; - } - --static VFIOHostDMAWindow *vfio_find_hostwin(VFIOContainer *container, -+static VFIOHostDMAWindow *vfio_find_hostwin(VFIOSpaprContainer *container, - hwaddr iova, hwaddr end) - { - VFIOHostDMAWindow *hostwin; -@@ -329,6 +330,8 @@ vfio_spapr_container_add_section_window(VFIOContainerBase *bcontainer, - { - VFIOContainer *container = container_of(bcontainer, VFIOContainer, - bcontainer); -+ VFIOSpaprContainer *scontainer = container_of(container, VFIOSpaprContainer, -+ container); - VFIOHostDMAWindow *hostwin; - hwaddr pgsize = 0; - int ret; -@@ -344,7 +347,7 @@ vfio_spapr_container_add_section_window(VFIOContainerBase *bcontainer, - iova = section->offset_within_address_space; - end = iova + int128_get64(section->size) - 1; - -- if (!vfio_find_hostwin(container, iova, end)) { -+ if (!vfio_find_hostwin(scontainer, iova, end)) { - error_setg(errp, "Container %p can't map guest IOVA region" - " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, container, - iova, end); -@@ -358,7 +361,7 @@ vfio_spapr_container_add_section_window(VFIOContainerBase *bcontainer, - } - - /* For now intersections are not allowed, we may relax this later */ -- QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { -+ QLIST_FOREACH(hostwin, &scontainer->hostwin_list, hostwin_next) { - if (ranges_overlap(hostwin->min_iova, - hostwin->max_iova - hostwin->min_iova + 1, - section->offset_within_address_space, -@@ -380,7 +383,7 @@ vfio_spapr_container_add_section_window(VFIOContainerBase *bcontainer, - return ret; - } - -- vfio_host_win_add(container, section->offset_within_address_space, -+ vfio_host_win_add(scontainer, section->offset_within_address_space, - section->offset_within_address_space + - int128_get64(section->size) - 1, pgsize); - #ifdef CONFIG_KVM -@@ -419,6 +422,8 @@ vfio_spapr_container_del_section_window(VFIOContainerBase *bcontainer, - { - VFIOContainer *container = container_of(bcontainer, VFIOContainer, - bcontainer); -+ VFIOSpaprContainer *scontainer = container_of(container, VFIOSpaprContainer, -+ container); - - if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) { - return; -@@ -426,7 +431,7 @@ vfio_spapr_container_del_section_window(VFIOContainerBase *bcontainer, - - vfio_spapr_remove_window(container, - section->offset_within_address_space); -- if (vfio_host_win_del(container, -+ if (vfio_host_win_del(scontainer, - section->offset_within_address_space, - section->offset_within_address_space + - int128_get64(section->size) - 1) < 0) { -@@ -454,7 +459,7 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - bool v2 = container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU; - int ret, fd = container->fd; - -- QLIST_INIT(&container->hostwin_list); -+ QLIST_INIT(&scontainer->hostwin_list); - - /* - * The host kernel code implementing VFIO_IOMMU_DISABLE is called -@@ -506,7 +511,7 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - } else { - /* The default table uses 4K pages */ - bcontainer->pgsizes = 0x1000; -- vfio_host_win_add(container, info.dma32_window_start, -+ vfio_host_win_add(scontainer, info.dma32_window_start, - info.dma32_window_start + - info.dma32_window_size - 1, - 0x1000); -@@ -525,15 +530,14 @@ listener_unregister_exit: - - void vfio_spapr_container_deinit(VFIOContainer *container) - { -+ VFIOSpaprContainer *scontainer = container_of(container, VFIOSpaprContainer, -+ container); - VFIOHostDMAWindow *hostwin, *next; - - if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { -- VFIOSpaprContainer *scontainer = container_of(container, -- VFIOSpaprContainer, -- container); - memory_listener_unregister(&scontainer->prereg_listener); - } -- QLIST_FOREACH_SAFE(hostwin, &container->hostwin_list, hostwin_next, -+ QLIST_FOREACH_SAFE(hostwin, &scontainer->hostwin_list, hostwin_next, - next) { - QLIST_REMOVE(hostwin, hostwin_next); - g_free(hostwin); -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index ed6148c058..24ecc0e7ee 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -79,7 +79,6 @@ typedef struct VFIOContainer { - VFIOContainerBase bcontainer; - int fd; /* /dev/vfio/vfio, empowered by the attached groups */ - unsigned iommu_type; -- QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; - } VFIOContainer; - --- -2.39.3 - diff --git a/kvm-vfio-spapr-Move-prereg_listener-into-spapr-container.patch b/kvm-vfio-spapr-Move-prereg_listener-into-spapr-container.patch deleted file mode 100644 index 1db4b55..0000000 --- a/kvm-vfio-spapr-Move-prereg_listener-into-spapr-container.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 17e6dad3e43e173147c0ca33f6f1f4f317a77d0b Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:44 +0800 -Subject: [PATCH 019/101] vfio/spapr: Move prereg_listener into spapr container -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [18/67] dbea1b0b759e91b953271da92bba4ca6853bec82 (eauger1/centos-qemu-kvm) - -No functional changes intended. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater -(cherry picked from commit 6ad359ec29af7f21dcb206c8edb26905a4925f80) -Signed-off-by: Eric Auger ---- - hw/vfio/spapr.c | 24 ++++++++++++++++-------- - include/hw/vfio/vfio-common.h | 1 - - 2 files changed, 16 insertions(+), 9 deletions(-) - -diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c -index 5be1911aad..68c3dd6c75 100644 ---- a/hw/vfio/spapr.c -+++ b/hw/vfio/spapr.c -@@ -26,6 +26,7 @@ - - typedef struct VFIOSpaprContainer { - VFIOContainer container; -+ MemoryListener prereg_listener; - } VFIOSpaprContainer; - - static bool vfio_prereg_listener_skipped_section(MemoryRegionSection *section) -@@ -48,8 +49,9 @@ static void *vfio_prereg_gpa_to_vaddr(MemoryRegionSection *section, hwaddr gpa) - static void vfio_prereg_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { -- VFIOContainer *container = container_of(listener, VFIOContainer, -- prereg_listener); -+ VFIOSpaprContainer *scontainer = container_of(listener, VFIOSpaprContainer, -+ prereg_listener); -+ VFIOContainer *container = &scontainer->container; - VFIOContainerBase *bcontainer = &container->bcontainer; - const hwaddr gpa = section->offset_within_address_space; - hwaddr end; -@@ -107,8 +109,9 @@ static void vfio_prereg_listener_region_add(MemoryListener *listener, - static void vfio_prereg_listener_region_del(MemoryListener *listener, - MemoryRegionSection *section) - { -- VFIOContainer *container = container_of(listener, VFIOContainer, -- prereg_listener); -+ VFIOSpaprContainer *scontainer = container_of(listener, VFIOSpaprContainer, -+ prereg_listener); -+ VFIOContainer *container = &scontainer->container; - const hwaddr gpa = section->offset_within_address_space; - hwaddr end; - int ret; -@@ -445,6 +448,8 @@ static void setup_spapr_ops(VFIOContainerBase *bcontainer) - int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - { - VFIOContainerBase *bcontainer = &container->bcontainer; -+ VFIOSpaprContainer *scontainer = container_of(container, VFIOSpaprContainer, -+ container); - struct vfio_iommu_spapr_tce_info info; - bool v2 = container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU; - int ret, fd = container->fd; -@@ -463,9 +468,9 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - return -errno; - } - } else { -- container->prereg_listener = vfio_prereg_listener; -+ scontainer->prereg_listener = vfio_prereg_listener; - -- memory_listener_register(&container->prereg_listener, -+ memory_listener_register(&scontainer->prereg_listener, - &address_space_memory); - if (bcontainer->error) { - ret = -1; -@@ -513,7 +518,7 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp) - - listener_unregister_exit: - if (v2) { -- memory_listener_unregister(&container->prereg_listener); -+ memory_listener_unregister(&scontainer->prereg_listener); - } - return ret; - } -@@ -523,7 +528,10 @@ void vfio_spapr_container_deinit(VFIOContainer *container) - VFIOHostDMAWindow *hostwin, *next; - - if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { -- memory_listener_unregister(&container->prereg_listener); -+ VFIOSpaprContainer *scontainer = container_of(container, -+ VFIOSpaprContainer, -+ container); -+ memory_listener_unregister(&scontainer->prereg_listener); - } - QLIST_FOREACH_SAFE(hostwin, &container->hostwin_list, hostwin_next, - next) { -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 055f679363..ed6148c058 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -78,7 +78,6 @@ struct VFIOGroup; - typedef struct VFIOContainer { - VFIOContainerBase bcontainer; - int fd; /* /dev/vfio/vfio, empowered by the attached groups */ -- MemoryListener prereg_listener; - unsigned iommu_type; - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; --- -2.39.3 - diff --git a/kvm-vfio-spapr-Only-compile-sPAPR-IOMMU-support-when-nee.patch b/kvm-vfio-spapr-Only-compile-sPAPR-IOMMU-support-when-nee.patch deleted file mode 100644 index 7762804..0000000 --- a/kvm-vfio-spapr-Only-compile-sPAPR-IOMMU-support-when-nee.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 5d485eb1442a81b51688124ce30024e96490acbf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Tue, 19 Dec 2023 07:58:24 +0100 -Subject: [PATCH 057/101] vfio/spapr: Only compile sPAPR IOMMU support when - needed -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [56/67] 4dc0cbde470f877a8aac2bf6fab6923f2f919285 (eauger1/centos-qemu-kvm) - -sPAPR IOMMU support is only needed for pseries machines. Compile out -support when CONFIG_PSERIES is not set. This saves ~7K of text. - -Reviewed-by: Zhenzhong Duan -Tested-by: Eric Farman -Signed-off-by: Cédric Le Goater -(cherry picked from commit 10164df6ed3d41cbf67105dcd954a663ef4cc3e9) -Signed-off-by: Eric Auger ---- - hw/vfio/meson.build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build -index e5d98b6adc..bb98493b53 100644 ---- a/hw/vfio/meson.build -+++ b/hw/vfio/meson.build -@@ -4,9 +4,9 @@ vfio_ss.add(files( - 'common.c', - 'container-base.c', - 'container.c', -- 'spapr.c', - 'migration.c', - )) -+vfio_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr.c')) - vfio_ss.add(when: 'CONFIG_IOMMUFD', if_true: files( - 'iommufd.c', - )) --- -2.39.3 - diff --git a/kvm-vfio-spapr-switch-to-spapr-IOMMU-BE-add-del_section_.patch b/kvm-vfio-spapr-switch-to-spapr-IOMMU-BE-add-del_section_.patch deleted file mode 100644 index 4d8db61..0000000 --- a/kvm-vfio-spapr-switch-to-spapr-IOMMU-BE-add-del_section_.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 3b7f044f15b4a9daf4ad7eda58777aba6dbe3fc0 Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Thu, 2 Nov 2023 15:12:43 +0800 -Subject: [PATCH 018/101] vfio/spapr: switch to spapr IOMMU BE - add/del_section_window -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Auger -RH-MergeRequest: 211: IOMMUFD backend backport -RH-Jira: RHEL-19302 RHEL-21057 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Sebastian Ott -RH-Commit: [17/67] a0d9f1f2d4d2592f3d9fc2ee5b2c38236a986e38 (eauger1/centos-qemu-kvm) - -No functional change intended. - -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -(cherry picked from commit 233309e8e4c158af6c6b126d5ad021bae40a918a) -Signed-off-by: Eric Auger ---- - hw/vfio/common.c | 8 ++------ - hw/vfio/container-base.c | 21 +++++++++++++++++++++ - hw/vfio/spapr.c | 19 ++++++++++++++----- - include/hw/vfio/vfio-common.h | 5 ----- - include/hw/vfio/vfio-container-base.h | 5 +++++ - 5 files changed, 42 insertions(+), 16 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 483ba82089..572ae7c934 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -571,8 +571,6 @@ static void vfio_listener_region_add(MemoryListener *listener, - { - VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, - listener); -- VFIOContainer *container = container_of(bcontainer, VFIOContainer, -- bcontainer); - hwaddr iova, end; - Int128 llend, llsize; - void *vaddr; -@@ -595,7 +593,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - return; - } - -- if (vfio_container_add_section_window(container, section, &err)) { -+ if (vfio_container_add_section_window(bcontainer, section, &err)) { - goto fail; - } - -@@ -738,8 +736,6 @@ static void vfio_listener_region_del(MemoryListener *listener, - { - VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, - listener); -- VFIOContainer *container = container_of(bcontainer, VFIOContainer, -- bcontainer); - hwaddr iova, end; - Int128 llend, llsize; - int ret; -@@ -818,7 +814,7 @@ static void vfio_listener_region_del(MemoryListener *listener, - - memory_region_unref(section->mr); - -- vfio_container_del_section_window(container, section); -+ vfio_container_del_section_window(bcontainer, section); - } - - typedef struct VFIODirtyRanges { -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 0177f43741..71f7274973 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -31,6 +31,27 @@ int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, - return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb); - } - -+int vfio_container_add_section_window(VFIOContainerBase *bcontainer, -+ MemoryRegionSection *section, -+ Error **errp) -+{ -+ if (!bcontainer->ops->add_window) { -+ return 0; -+ } -+ -+ return bcontainer->ops->add_window(bcontainer, section, errp); -+} -+ -+void vfio_container_del_section_window(VFIOContainerBase *bcontainer, -+ MemoryRegionSection *section) -+{ -+ if (!bcontainer->ops->del_window) { -+ return; -+ } -+ -+ return bcontainer->ops->del_window(bcontainer, section); -+} -+ - int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, - bool start) - { -diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c -index e1a6b35563..5be1911aad 100644 ---- a/hw/vfio/spapr.c -+++ b/hw/vfio/spapr.c -@@ -319,10 +319,13 @@ static int vfio_spapr_create_window(VFIOContainer *container, - return 0; - } - --int vfio_container_add_section_window(VFIOContainer *container, -- MemoryRegionSection *section, -- Error **errp) -+static int -+vfio_spapr_container_add_section_window(VFIOContainerBase *bcontainer, -+ MemoryRegionSection *section, -+ Error **errp) - { -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); - VFIOHostDMAWindow *hostwin; - hwaddr pgsize = 0; - int ret; -@@ -407,9 +410,13 @@ int vfio_container_add_section_window(VFIOContainer *container, - return 0; - } - --void vfio_container_del_section_window(VFIOContainer *container, -- MemoryRegionSection *section) -+static void -+vfio_spapr_container_del_section_window(VFIOContainerBase *bcontainer, -+ MemoryRegionSection *section) - { -+ VFIOContainer *container = container_of(bcontainer, VFIOContainer, -+ bcontainer); -+ - if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) { - return; - } -@@ -430,6 +437,8 @@ static VFIOIOMMUOps vfio_iommu_spapr_ops; - static void setup_spapr_ops(VFIOContainerBase *bcontainer) - { - vfio_iommu_spapr_ops = *bcontainer->ops; -+ vfio_iommu_spapr_ops.add_window = vfio_spapr_container_add_section_window; -+ vfio_iommu_spapr_ops.del_window = vfio_spapr_container_del_section_window; - bcontainer->ops = &vfio_iommu_spapr_ops; - } - -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index b9e5a0e64b..055f679363 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -169,11 +169,6 @@ VFIOAddressSpace *vfio_get_address_space(AddressSpace *as); - void vfio_put_address_space(VFIOAddressSpace *space); - - /* SPAPR specific */ --int vfio_container_add_section_window(VFIOContainer *container, -- MemoryRegionSection *section, -- Error **errp); --void vfio_container_del_section_window(VFIOContainer *container, -- MemoryRegionSection *section); - int vfio_spapr_container_init(VFIOContainer *container, Error **errp); - void vfio_spapr_container_deinit(VFIOContainer *container); - -diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h -index f62a14ac73..4b6f017c6f 100644 ---- a/include/hw/vfio/vfio-container-base.h -+++ b/include/hw/vfio/vfio-container-base.h -@@ -75,6 +75,11 @@ int vfio_container_dma_map(VFIOContainerBase *bcontainer, - int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb); -+int vfio_container_add_section_window(VFIOContainerBase *bcontainer, -+ MemoryRegionSection *section, -+ Error **errp); -+void vfio_container_del_section_window(VFIOContainerBase *bcontainer, -+ MemoryRegionSection *section); - int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, - bool start); - int vfio_container_query_dirty_bitmap(VFIOContainerBase *bcontainer, --- -2.39.3 - diff --git a/kvm-virtio-Re-enable-notifications-after-drain.patch b/kvm-virtio-Re-enable-notifications-after-drain.patch deleted file mode 100644 index ef770fd..0000000 --- a/kvm-virtio-Re-enable-notifications-after-drain.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 2a758da4e1433564998def68447008908c96e113 Mon Sep 17 00:00:00 2001 -From: Hanna Czenczek -Date: Fri, 2 Feb 2024 16:31:57 +0100 -Subject: [PATCH 2/6] virtio: Re-enable notifications after drain - -RH-Author: Hanna Czenczek -RH-MergeRequest: 223: virtio: Re-enable notifications after drain -RH-Jira: RHEL-3934 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [2/3] e3be798e6259a378fc03f4364ecaeb875b01f64c (hreitz/qemu-kvm-c-9-s) - -During drain, we do not care about virtqueue notifications, which is why -we remove the handlers on it. When removing those handlers, whether vq -notifications are enabled or not depends on whether we were in polling -mode or not; if not, they are enabled (by default); if so, they have -been disabled by the io_poll_start callback. - -Because we do not care about those notifications after removing the -handlers, this is fine. However, we have to explicitly ensure they are -enabled when re-attaching the handlers, so we will resume receiving -notifications. We do this in virtio_queue_aio_attach_host_notifier*(). -If such a function is called while we are in a polling section, -attaching the notifiers will then invoke the io_poll_start callback, -re-disabling notifications. - -Because we will always miss virtqueue updates in the drained section, we -also need to poll the virtqueue once after attaching the notifiers. - -Buglink: https://issues.redhat.com/browse/RHEL-3934 -Signed-off-by: Hanna Czenczek -Message-ID: <20240202153158.788922-3-hreitz@redhat.com> -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 5bdbaebcce18fe6a627cafad2043ec08f3de5744) ---- - hw/virtio/virtio.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - include/block/aio.h | 7 ++++++- - 2 files changed, 48 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 3a160f86ed..356d690cc9 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -3556,6 +3556,17 @@ static void virtio_queue_host_notifier_aio_poll_end(EventNotifier *n) - - void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) - { -+ /* -+ * virtio_queue_aio_detach_host_notifier() can leave notifications disabled. -+ * Re-enable them. (And if detach has not been used before, notifications -+ * being enabled is still the default state while a notifier is attached; -+ * see virtio_queue_host_notifier_aio_poll_end(), which will always leave -+ * notifications enabled once the polling section is left.) -+ */ -+ if (!virtio_queue_get_notification(vq)) { -+ virtio_queue_set_notification(vq, 1); -+ } -+ - aio_set_event_notifier(ctx, &vq->host_notifier, - virtio_queue_host_notifier_read, - virtio_queue_host_notifier_aio_poll, -@@ -3563,6 +3574,13 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) - aio_set_event_notifier_poll(ctx, &vq->host_notifier, - virtio_queue_host_notifier_aio_poll_begin, - virtio_queue_host_notifier_aio_poll_end); -+ -+ /* -+ * We will have ignored notifications about new requests from the guest -+ * while no notifiers were attached, so "kick" the virt queue to process -+ * those requests now. -+ */ -+ event_notifier_set(&vq->host_notifier); - } - - /* -@@ -3573,14 +3591,38 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) - */ - void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx) - { -+ /* See virtio_queue_aio_attach_host_notifier() */ -+ if (!virtio_queue_get_notification(vq)) { -+ virtio_queue_set_notification(vq, 1); -+ } -+ - aio_set_event_notifier(ctx, &vq->host_notifier, - virtio_queue_host_notifier_read, - NULL, NULL); -+ -+ /* -+ * See virtio_queue_aio_attach_host_notifier(). -+ * Note that this may be unnecessary for the type of virtqueues this -+ * function is used for. Still, it will not hurt to have a quick look into -+ * whether we can/should process any of the virtqueue elements. -+ */ -+ event_notifier_set(&vq->host_notifier); - } - - void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx) - { - aio_set_event_notifier(ctx, &vq->host_notifier, NULL, NULL, NULL); -+ -+ /* -+ * aio_set_event_notifier_poll() does not guarantee whether io_poll_end() -+ * will run after io_poll_begin(), so by removing the notifier, we do not -+ * know whether virtio_queue_host_notifier_aio_poll_end() has run after a -+ * previous virtio_queue_host_notifier_aio_poll_begin(), i.e. whether -+ * notifications are enabled or disabled. It does not really matter anyway; -+ * we just removed the notifier, so we do not care about notifications until -+ * we potentially re-attach it. The attach_host_notifier functions will -+ * ensure that notifications are enabled again when they are needed. -+ */ - } - - void virtio_queue_host_notifier_read(EventNotifier *n) -diff --git a/include/block/aio.h b/include/block/aio.h -index af05512a7d..261c77fd9a 100644 ---- a/include/block/aio.h -+++ b/include/block/aio.h -@@ -480,9 +480,14 @@ void aio_set_event_notifier(AioContext *ctx, - AioPollFn *io_poll, - EventNotifierHandler *io_poll_ready); - --/* Set polling begin/end callbacks for an event notifier that has already been -+/* -+ * Set polling begin/end callbacks for an event notifier that has already been - * registered with aio_set_event_notifier. Do nothing if the event notifier is - * not registered. -+ * -+ * Note that if the io_poll_end() callback (or the entire notifier) is removed -+ * during polling, it will not be called, so an io_poll_begin() is not -+ * necessarily always followed by an io_poll_end(). - */ - void aio_set_event_notifier_poll(AioContext *ctx, - EventNotifier *notifier, --- -2.39.3 - diff --git a/kvm-virtio-blk-Fix-potential-nullpointer-read-access-in-.patch b/kvm-virtio-blk-Fix-potential-nullpointer-read-access-in-.patch deleted file mode 100644 index 0565357..0000000 --- a/kvm-virtio-blk-Fix-potential-nullpointer-read-access-in-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 376df80fbba5a9bb0ec43cad083cde9de59128d7 Mon Sep 17 00:00:00 2001 -From: Stefan Weil via -Date: Sun, 24 Dec 2023 12:43:14 +0100 -Subject: [PATCH 10/22] virtio-blk: Fix potential nullpointer read access in - virtio_blk_data_plane_destroy - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [6/17] 460005fc7719b2e1dd577dfe75d18537ab2b8d06 (stefanha/centos-stream-qemu-kvm) - -Fixes: CID 1532828 -Fixes: b6948ab01d ("virtio-blk: add iothread-vq-mapping parameter") -Signed-off-by: Stefan Weil -Signed-off-by: Michael Tokarev -(cherry picked from commit d819fc9516a4ec71e37a6c9edfcd285b7f98c2dc) -Signed-off-by: Stefan Hajnoczi ---- - hw/block/dataplane/virtio-blk.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c -index 6debd4401e..97a302cf49 100644 ---- a/hw/block/dataplane/virtio-blk.c -+++ b/hw/block/dataplane/virtio-blk.c -@@ -152,7 +152,7 @@ bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, - void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s) - { - VirtIOBlock *vblk; -- VirtIOBlkConf *conf = s->conf; -+ VirtIOBlkConf *conf; - - if (!s) { - return; -@@ -160,6 +160,7 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s) - - vblk = VIRTIO_BLK(s->vdev); - assert(!vblk->dataplane_started); -+ conf = s->conf; - - if (conf->iothread_vq_mapping_list) { - IOThreadVirtQueueMappingList *node; --- -2.39.3 - diff --git a/kvm-virtio-blk-Use-ioeventfd_attach-in-start_ioeventfd.patch b/kvm-virtio-blk-Use-ioeventfd_attach-in-start_ioeventfd.patch deleted file mode 100644 index 1a3771e..0000000 --- a/kvm-virtio-blk-Use-ioeventfd_attach-in-start_ioeventfd.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 094941b2c3e66e078d93718933eb07e800a7dd60 Mon Sep 17 00:00:00 2001 -From: Hanna Czenczek -Date: Fri, 2 Feb 2024 16:31:58 +0100 -Subject: [PATCH 3/6] virtio-blk: Use ioeventfd_attach in start_ioeventfd - -RH-Author: Hanna Czenczek -RH-MergeRequest: 223: virtio: Re-enable notifications after drain -RH-Jira: RHEL-3934 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [3/3] 96d6760d1b7b12df695b6825b15a2a3b8a79a74c (hreitz/qemu-kvm-c-9-s) - -Commit d3f6f294aeadd5f88caf0155e4360808c95b3146 ("virtio-blk: always set -ioeventfd during startup") has made virtio_blk_start_ioeventfd() always -kick the virtqueue (set the ioeventfd), regardless of whether the BB is -drained. That is no longer necessary, because attaching the host -notifier will now set the ioeventfd, too; this happens either -immediately right here in virtio_blk_start_ioeventfd(), or later when -the drain ends, in virtio_blk_ioeventfd_attach(). - -With event_notifier_set() removed, the code becomes the same as the one -in virtio_blk_ioeventfd_attach(), so we can reuse that function. - -Signed-off-by: Hanna Czenczek -Message-ID: <20240202153158.788922-4-hreitz@redhat.com> -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 52bff01f64eec017ffb0d5903a0ee1d67ca7a548) ---- - hw/block/virtio-blk.c | 21 ++++++++++----------- - 1 file changed, 10 insertions(+), 11 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index 0b9100b746..7fdeaf2d12 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -37,6 +37,8 @@ - #include "hw/virtio/virtio-blk-common.h" - #include "qemu/coroutine.h" - -+static void virtio_blk_ioeventfd_attach(VirtIOBlock *s); -+ - static void virtio_blk_init_request(VirtIOBlock *s, VirtQueue *vq, - VirtIOBlockReq *req) - { -@@ -1808,17 +1810,14 @@ static int virtio_blk_start_ioeventfd(VirtIODevice *vdev) - s->ioeventfd_started = true; - smp_wmb(); /* paired with aio_notify_accept() on the read side */ - -- /* Get this show started by hooking up our callbacks */ -- for (i = 0; i < nvqs; i++) { -- VirtQueue *vq = virtio_get_queue(vdev, i); -- AioContext *ctx = s->vq_aio_context[i]; -- -- /* Kick right away to begin processing requests already in vring */ -- event_notifier_set(virtio_queue_get_host_notifier(vq)); -- -- if (!blk_in_drain(s->conf.conf.blk)) { -- virtio_queue_aio_attach_host_notifier(vq, ctx); -- } -+ /* -+ * Get this show started by hooking up our callbacks. If drained now, -+ * virtio_blk_drained_end() will do this later. -+ * Attaching the notifier also kicks the virtqueues, processing any requests -+ * they may already have. -+ */ -+ if (!blk_in_drain(s->conf.conf.blk)) { -+ virtio_blk_ioeventfd_attach(s); - } - return 0; - --- -2.39.3 - diff --git a/kvm-virtio-blk-add-iothread-vq-mapping-parameter.patch b/kvm-virtio-blk-add-iothread-vq-mapping-parameter.patch deleted file mode 100644 index 65a96a0..0000000 --- a/kvm-virtio-blk-add-iothread-vq-mapping-parameter.patch +++ /dev/null @@ -1,464 +0,0 @@ -From 733fc13f65286c849ad6618be89df450f8bc5f7e Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 20 Dec 2023 08:47:55 -0500 -Subject: [PATCH 09/22] virtio-blk: add iothread-vq-mapping parameter - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [5/17] c371fe62376c4eb54da88272a5966cec28404224 (stefanha/centos-stream-qemu-kvm) - -Add the iothread-vq-mapping parameter to assign virtqueues to IOThreads. -Store the vq:AioContext mapping in the new struct -VirtIOBlockDataPlane->vq_aio_context[] field and refactor the code to -use the per-vq AioContext instead of the BlockDriverState's AioContext. - -Reimplement --device virtio-blk-pci,iothread= and non-IOThread mode by -assigning all virtqueues to the IOThread and main loop's AioContext in -vq_aio_context[], respectively. - -The comment in struct VirtIOBlockDataPlane about EventNotifiers is -stale. Remove it. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20231220134755.814917-5-stefanha@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit b6948ab01df068bef591868c22d1f873d2d05cde) -Signed-off-by: Stefan Hajnoczi ---- - hw/block/dataplane/virtio-blk.c | 155 ++++++++++++++++++++++++-------- - hw/block/dataplane/virtio-blk.h | 3 + - hw/block/virtio-blk.c | 92 ++++++++++++++++--- - include/hw/virtio/virtio-blk.h | 2 + - 4 files changed, 202 insertions(+), 50 deletions(-) - -diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c -index 7bbbd981ad..6debd4401e 100644 ---- a/hw/block/dataplane/virtio-blk.c -+++ b/hw/block/dataplane/virtio-blk.c -@@ -32,13 +32,11 @@ struct VirtIOBlockDataPlane { - VirtIOBlkConf *conf; - VirtIODevice *vdev; - -- /* Note that these EventNotifiers are assigned by value. This is -- * fine as long as you do not call event_notifier_cleanup on them -- * (because you don't own the file descriptor or handle; you just -- * use it). -+ /* -+ * The AioContext for each virtqueue. The BlockDriverState will use the -+ * first element as its AioContext. - */ -- IOThread *iothread; -- AioContext *ctx; -+ AioContext **vq_aio_context; - }; - - /* Raise an interrupt to signal guest, if necessary */ -@@ -47,6 +45,45 @@ void virtio_blk_data_plane_notify(VirtIOBlockDataPlane *s, VirtQueue *vq) - virtio_notify_irqfd(s->vdev, vq); - } - -+/* Generate vq:AioContext mappings from a validated iothread-vq-mapping list */ -+static void -+apply_vq_mapping(IOThreadVirtQueueMappingList *iothread_vq_mapping_list, -+ AioContext **vq_aio_context, uint16_t num_queues) -+{ -+ IOThreadVirtQueueMappingList *node; -+ size_t num_iothreads = 0; -+ size_t cur_iothread = 0; -+ -+ for (node = iothread_vq_mapping_list; node; node = node->next) { -+ num_iothreads++; -+ } -+ -+ for (node = iothread_vq_mapping_list; node; node = node->next) { -+ IOThread *iothread = iothread_by_id(node->value->iothread); -+ AioContext *ctx = iothread_get_aio_context(iothread); -+ -+ /* Released in virtio_blk_data_plane_destroy() */ -+ object_ref(OBJECT(iothread)); -+ -+ if (node->value->vqs) { -+ uint16List *vq; -+ -+ /* Explicit vq:IOThread assignment */ -+ for (vq = node->value->vqs; vq; vq = vq->next) { -+ vq_aio_context[vq->value] = ctx; -+ } -+ } else { -+ /* Round-robin vq:IOThread assignment */ -+ for (unsigned i = cur_iothread; i < num_queues; -+ i += num_iothreads) { -+ vq_aio_context[i] = ctx; -+ } -+ } -+ -+ cur_iothread++; -+ } -+} -+ - /* Context: QEMU global mutex held */ - bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, - VirtIOBlockDataPlane **dataplane, -@@ -58,7 +95,7 @@ bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, - - *dataplane = NULL; - -- if (conf->iothread) { -+ if (conf->iothread || conf->iothread_vq_mapping_list) { - if (!k->set_guest_notifiers || !k->ioeventfd_assign) { - error_setg(errp, - "device is incompatible with iothread " -@@ -86,13 +123,24 @@ bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, - s = g_new0(VirtIOBlockDataPlane, 1); - s->vdev = vdev; - s->conf = conf; -+ s->vq_aio_context = g_new(AioContext *, conf->num_queues); -+ -+ if (conf->iothread_vq_mapping_list) { -+ apply_vq_mapping(conf->iothread_vq_mapping_list, s->vq_aio_context, -+ conf->num_queues); -+ } else if (conf->iothread) { -+ AioContext *ctx = iothread_get_aio_context(conf->iothread); -+ for (unsigned i = 0; i < conf->num_queues; i++) { -+ s->vq_aio_context[i] = ctx; -+ } - -- if (conf->iothread) { -- s->iothread = conf->iothread; -- object_ref(OBJECT(s->iothread)); -- s->ctx = iothread_get_aio_context(s->iothread); -+ /* Released in virtio_blk_data_plane_destroy() */ -+ object_ref(OBJECT(conf->iothread)); - } else { -- s->ctx = qemu_get_aio_context(); -+ AioContext *ctx = qemu_get_aio_context(); -+ for (unsigned i = 0; i < conf->num_queues; i++) { -+ s->vq_aio_context[i] = ctx; -+ } - } - - *dataplane = s; -@@ -104,6 +152,7 @@ bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, - void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s) - { - VirtIOBlock *vblk; -+ VirtIOBlkConf *conf = s->conf; - - if (!s) { - return; -@@ -111,9 +160,21 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s) - - vblk = VIRTIO_BLK(s->vdev); - assert(!vblk->dataplane_started); -- if (s->iothread) { -- object_unref(OBJECT(s->iothread)); -+ -+ if (conf->iothread_vq_mapping_list) { -+ IOThreadVirtQueueMappingList *node; -+ -+ for (node = conf->iothread_vq_mapping_list; node; node = node->next) { -+ IOThread *iothread = iothread_by_id(node->value->iothread); -+ object_unref(OBJECT(iothread)); -+ } -+ } -+ -+ if (conf->iothread) { -+ object_unref(OBJECT(conf->iothread)); - } -+ -+ g_free(s->vq_aio_context); - g_free(s); - } - -@@ -177,19 +238,13 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev) - - trace_virtio_blk_data_plane_start(s); - -- r = blk_set_aio_context(s->conf->conf.blk, s->ctx, &local_err); -+ r = blk_set_aio_context(s->conf->conf.blk, s->vq_aio_context[0], -+ &local_err); - if (r < 0) { - error_report_err(local_err); - goto fail_aio_context; - } - -- /* Kick right away to begin processing requests already in vring */ -- for (i = 0; i < nvqs; i++) { -- VirtQueue *vq = virtio_get_queue(s->vdev, i); -- -- event_notifier_set(virtio_queue_get_host_notifier(vq)); -- } -- - /* - * These fields must be visible to the IOThread when it processes the - * virtqueue, otherwise it will think dataplane has not started yet. -@@ -206,8 +261,12 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev) - if (!blk_in_drain(s->conf->conf.blk)) { - for (i = 0; i < nvqs; i++) { - VirtQueue *vq = virtio_get_queue(s->vdev, i); -+ AioContext *ctx = s->vq_aio_context[i]; - -- virtio_queue_aio_attach_host_notifier(vq, s->ctx); -+ /* Kick right away to begin processing requests already in vring */ -+ event_notifier_set(virtio_queue_get_host_notifier(vq)); -+ -+ virtio_queue_aio_attach_host_notifier(vq, ctx); - } - } - return 0; -@@ -236,23 +295,18 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev) - * - * Context: BH in IOThread - */ --static void virtio_blk_data_plane_stop_bh(void *opaque) -+static void virtio_blk_data_plane_stop_vq_bh(void *opaque) - { -- VirtIOBlockDataPlane *s = opaque; -- unsigned i; -- -- for (i = 0; i < s->conf->num_queues; i++) { -- VirtQueue *vq = virtio_get_queue(s->vdev, i); -- EventNotifier *host_notifier = virtio_queue_get_host_notifier(vq); -+ VirtQueue *vq = opaque; -+ EventNotifier *host_notifier = virtio_queue_get_host_notifier(vq); - -- virtio_queue_aio_detach_host_notifier(vq, s->ctx); -+ virtio_queue_aio_detach_host_notifier(vq, qemu_get_current_aio_context()); - -- /* -- * Test and clear notifier after disabling event, in case poll callback -- * didn't have time to run. -- */ -- virtio_queue_host_notifier_read(host_notifier); -- } -+ /* -+ * Test and clear notifier after disabling event, in case poll callback -+ * didn't have time to run. -+ */ -+ virtio_queue_host_notifier_read(host_notifier); - } - - /* Context: QEMU global mutex held */ -@@ -279,7 +333,12 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev) - trace_virtio_blk_data_plane_stop(s); - - if (!blk_in_drain(s->conf->conf.blk)) { -- aio_wait_bh_oneshot(s->ctx, virtio_blk_data_plane_stop_bh, s); -+ for (i = 0; i < nvqs; i++) { -+ VirtQueue *vq = virtio_get_queue(s->vdev, i); -+ AioContext *ctx = s->vq_aio_context[i]; -+ -+ aio_wait_bh_oneshot(ctx, virtio_blk_data_plane_stop_vq_bh, vq); -+ } - } - - /* -@@ -322,3 +381,23 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev) - - s->stopping = false; - } -+ -+void virtio_blk_data_plane_detach(VirtIOBlockDataPlane *s) -+{ -+ VirtIODevice *vdev = VIRTIO_DEVICE(s->vdev); -+ -+ for (uint16_t i = 0; i < s->conf->num_queues; i++) { -+ VirtQueue *vq = virtio_get_queue(vdev, i); -+ virtio_queue_aio_detach_host_notifier(vq, s->vq_aio_context[i]); -+ } -+} -+ -+void virtio_blk_data_plane_attach(VirtIOBlockDataPlane *s) -+{ -+ VirtIODevice *vdev = VIRTIO_DEVICE(s->vdev); -+ -+ for (uint16_t i = 0; i < s->conf->num_queues; i++) { -+ VirtQueue *vq = virtio_get_queue(vdev, i); -+ virtio_queue_aio_attach_host_notifier(vq, s->vq_aio_context[i]); -+ } -+} -diff --git a/hw/block/dataplane/virtio-blk.h b/hw/block/dataplane/virtio-blk.h -index 5e18bb99ae..1a806fe447 100644 ---- a/hw/block/dataplane/virtio-blk.h -+++ b/hw/block/dataplane/virtio-blk.h -@@ -28,4 +28,7 @@ void virtio_blk_data_plane_notify(VirtIOBlockDataPlane *s, VirtQueue *vq); - int virtio_blk_data_plane_start(VirtIODevice *vdev); - void virtio_blk_data_plane_stop(VirtIODevice *vdev); - -+void virtio_blk_data_plane_detach(VirtIOBlockDataPlane *s); -+void virtio_blk_data_plane_attach(VirtIOBlockDataPlane *s); -+ - #endif /* HW_DATAPLANE_VIRTIO_BLK_H */ -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index ec9ed09a6a..46e73b2c96 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -1151,6 +1151,7 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) - return; - } - } -+ - virtio_blk_handle_vq(s, vq); - } - -@@ -1463,6 +1464,68 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f, - return 0; - } - -+static bool -+validate_iothread_vq_mapping_list(IOThreadVirtQueueMappingList *list, -+ uint16_t num_queues, Error **errp) -+{ -+ g_autofree unsigned long *vqs = bitmap_new(num_queues); -+ g_autoptr(GHashTable) iothreads = -+ g_hash_table_new(g_str_hash, g_str_equal); -+ -+ for (IOThreadVirtQueueMappingList *node = list; node; node = node->next) { -+ const char *name = node->value->iothread; -+ uint16List *vq; -+ -+ if (!iothread_by_id(name)) { -+ error_setg(errp, "IOThread \"%s\" object does not exist", name); -+ return false; -+ } -+ -+ if (!g_hash_table_add(iothreads, (gpointer)name)) { -+ error_setg(errp, -+ "duplicate IOThread name \"%s\" in iothread-vq-mapping", -+ name); -+ return false; -+ } -+ -+ if (node != list) { -+ if (!!node->value->vqs != !!list->value->vqs) { -+ error_setg(errp, "either all items in iothread-vq-mapping " -+ "must have vqs or none of them must have it"); -+ return false; -+ } -+ } -+ -+ for (vq = node->value->vqs; vq; vq = vq->next) { -+ if (vq->value >= num_queues) { -+ error_setg(errp, "vq index %u for IOThread \"%s\" must be " -+ "less than num_queues %u in iothread-vq-mapping", -+ vq->value, name, num_queues); -+ return false; -+ } -+ -+ if (test_and_set_bit(vq->value, vqs)) { -+ error_setg(errp, "cannot assign vq %u to IOThread \"%s\" " -+ "because it is already assigned", vq->value, name); -+ return false; -+ } -+ } -+ } -+ -+ if (list->value->vqs) { -+ for (uint16_t i = 0; i < num_queues; i++) { -+ if (!test_bit(i, vqs)) { -+ error_setg(errp, -+ "missing vq %u IOThread assignment in iothread-vq-mapping", -+ i); -+ return false; -+ } -+ } -+ } -+ -+ return true; -+} -+ - static void virtio_resize_cb(void *opaque) - { - VirtIODevice *vdev = opaque; -@@ -1487,34 +1550,24 @@ static void virtio_blk_resize(void *opaque) - static void virtio_blk_drained_begin(void *opaque) - { - VirtIOBlock *s = opaque; -- VirtIODevice *vdev = VIRTIO_DEVICE(opaque); -- AioContext *ctx = blk_get_aio_context(s->conf.conf.blk); - - if (!s->dataplane || !s->dataplane_started) { - return; - } - -- for (uint16_t i = 0; i < s->conf.num_queues; i++) { -- VirtQueue *vq = virtio_get_queue(vdev, i); -- virtio_queue_aio_detach_host_notifier(vq, ctx); -- } -+ virtio_blk_data_plane_detach(s->dataplane); - } - - /* Resume virtqueue ioeventfd processing after drain */ - static void virtio_blk_drained_end(void *opaque) - { - VirtIOBlock *s = opaque; -- VirtIODevice *vdev = VIRTIO_DEVICE(opaque); -- AioContext *ctx = blk_get_aio_context(s->conf.conf.blk); - - if (!s->dataplane || !s->dataplane_started) { - return; - } - -- for (uint16_t i = 0; i < s->conf.num_queues; i++) { -- VirtQueue *vq = virtio_get_queue(vdev, i); -- virtio_queue_aio_attach_host_notifier(vq, ctx); -- } -+ virtio_blk_data_plane_attach(s->dataplane); - } - - static const BlockDevOps virtio_block_ops = { -@@ -1600,6 +1653,19 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) - return; - } - -+ if (conf->iothread_vq_mapping_list) { -+ if (conf->iothread) { -+ error_setg(errp, "iothread and iothread-vq-mapping properties " -+ "cannot be set at the same time"); -+ return; -+ } -+ -+ if (!validate_iothread_vq_mapping_list(conf->iothread_vq_mapping_list, -+ conf->num_queues, errp)) { -+ return; -+ } -+ } -+ - s->config_size = virtio_get_config_size(&virtio_blk_cfg_size_params, - s->host_features); - virtio_init(vdev, VIRTIO_ID_BLOCK, s->config_size); -@@ -1702,6 +1768,8 @@ static Property virtio_blk_properties[] = { - DEFINE_PROP_BOOL("seg-max-adjust", VirtIOBlock, conf.seg_max_adjust, true), - DEFINE_PROP_LINK("iothread", VirtIOBlock, conf.iothread, TYPE_IOTHREAD, - IOThread *), -+ DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST("iothread-vq-mapping", VirtIOBlock, -+ conf.iothread_vq_mapping_list), - DEFINE_PROP_BIT64("discard", VirtIOBlock, host_features, - VIRTIO_BLK_F_DISCARD, true), - DEFINE_PROP_BOOL("report-discard-granularity", VirtIOBlock, -diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h -index 9881009c22..5e4091e4da 100644 ---- a/include/hw/virtio/virtio-blk.h -+++ b/include/hw/virtio/virtio-blk.h -@@ -21,6 +21,7 @@ - #include "sysemu/block-backend.h" - #include "sysemu/block-ram-registrar.h" - #include "qom/object.h" -+#include "qapi/qapi-types-virtio.h" - - #define TYPE_VIRTIO_BLK "virtio-blk-device" - OBJECT_DECLARE_SIMPLE_TYPE(VirtIOBlock, VIRTIO_BLK) -@@ -37,6 +38,7 @@ struct VirtIOBlkConf - { - BlockConf conf; - IOThread *iothread; -+ IOThreadVirtQueueMappingList *iothread_vq_mapping_list; - char *serial; - uint32_t request_merging; - uint16_t num_queues; --- -2.39.3 - diff --git a/kvm-virtio-blk-add-lock-to-protect-s-rq.patch b/kvm-virtio-blk-add-lock-to-protect-s-rq.patch deleted file mode 100644 index 31e83a2..0000000 --- a/kvm-virtio-blk-add-lock-to-protect-s-rq.patch +++ /dev/null @@ -1,177 +0,0 @@ -From d54e88103aa76f3bf755b3f4308d8ab60367c6ef Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 14 Sep 2023 10:00:59 -0400 -Subject: [PATCH 074/101] virtio-blk: add lock to protect s->rq - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [5/26] 17dcd5ba18c03e5633a014d8d62d34d8dd7b43bf (kmwolf/centos-qemu-kvm) - -s->rq is accessed from IO_CODE and GLOBAL_STATE_CODE. Introduce a lock -to protect s->rq and eliminate reliance on the AioContext lock. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20230914140101.1065008-3-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Reviewed-by: Eric Blake -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Kevin Wolf ---- - hw/block/virtio-blk.c | 67 +++++++++++++++++++++++----------- - include/hw/virtio/virtio-blk.h | 3 +- - 2 files changed, 47 insertions(+), 23 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index a1f8e15522..ee38e089bc 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -82,8 +82,11 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, - /* Break the link as the next request is going to be parsed from the - * ring again. Otherwise we may end up doing a double completion! */ - req->mr_next = NULL; -- req->next = s->rq; -- s->rq = req; -+ -+ WITH_QEMU_LOCK_GUARD(&s->rq_lock) { -+ req->next = s->rq; -+ s->rq = req; -+ } - } else if (action == BLOCK_ERROR_ACTION_REPORT) { - virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); - if (acct_failed) { -@@ -1183,10 +1186,13 @@ static void virtio_blk_dma_restart_bh(void *opaque) - { - VirtIOBlock *s = opaque; - -- VirtIOBlockReq *req = s->rq; -+ VirtIOBlockReq *req; - MultiReqBuffer mrb = {}; - -- s->rq = NULL; -+ WITH_QEMU_LOCK_GUARD(&s->rq_lock) { -+ req = s->rq; -+ s->rq = NULL; -+ } - - aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); - while (req) { -@@ -1238,22 +1244,29 @@ static void virtio_blk_reset(VirtIODevice *vdev) - AioContext *ctx; - VirtIOBlockReq *req; - -+ /* Dataplane has stopped... */ -+ assert(!s->dataplane_started); -+ -+ /* ...but requests may still be in flight. */ - ctx = blk_get_aio_context(s->blk); - aio_context_acquire(ctx); - blk_drain(s->blk); -+ aio_context_release(ctx); - - /* We drop queued requests after blk_drain() because blk_drain() itself can - * produce them. */ -- while (s->rq) { -- req = s->rq; -- s->rq = req->next; -- virtqueue_detach_element(req->vq, &req->elem, 0); -- virtio_blk_free_request(req); -- } -+ WITH_QEMU_LOCK_GUARD(&s->rq_lock) { -+ while (s->rq) { -+ req = s->rq; -+ s->rq = req->next; - -- aio_context_release(ctx); -+ /* No other threads can access req->vq here */ -+ virtqueue_detach_element(req->vq, &req->elem, 0); -+ -+ virtio_blk_free_request(req); -+ } -+ } - -- assert(!s->dataplane_started); - blk_set_enable_write_cache(s->blk, s->original_wce); - } - -@@ -1443,18 +1456,22 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) - static void virtio_blk_save_device(VirtIODevice *vdev, QEMUFile *f) - { - VirtIOBlock *s = VIRTIO_BLK(vdev); -- VirtIOBlockReq *req = s->rq; - -- while (req) { -- qemu_put_sbyte(f, 1); -+ WITH_QEMU_LOCK_GUARD(&s->rq_lock) { -+ VirtIOBlockReq *req = s->rq; - -- if (s->conf.num_queues > 1) { -- qemu_put_be32(f, virtio_get_queue_index(req->vq)); -- } -+ while (req) { -+ qemu_put_sbyte(f, 1); - -- qemu_put_virtqueue_element(vdev, f, &req->elem); -- req = req->next; -+ if (s->conf.num_queues > 1) { -+ qemu_put_be32(f, virtio_get_queue_index(req->vq)); -+ } -+ -+ qemu_put_virtqueue_element(vdev, f, &req->elem); -+ req = req->next; -+ } - } -+ - qemu_put_sbyte(f, 0); - } - -@@ -1480,8 +1497,11 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f, - - req = qemu_get_virtqueue_element(vdev, f, sizeof(VirtIOBlockReq)); - virtio_blk_init_request(s, virtio_get_queue(vdev, vq_idx), req); -- req->next = s->rq; -- s->rq = req; -+ -+ WITH_QEMU_LOCK_GUARD(&s->rq_lock) { -+ req->next = s->rq; -+ s->rq = req; -+ } - } - - return 0; -@@ -1628,6 +1648,8 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) - s->host_features); - virtio_init(vdev, VIRTIO_ID_BLOCK, s->config_size); - -+ qemu_mutex_init(&s->rq_lock); -+ - s->blk = conf->conf.blk; - s->rq = NULL; - s->sector_mask = (s->conf.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1; -@@ -1679,6 +1701,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev) - virtio_del_queue(vdev, i); - } - qemu_coroutine_dec_pool_size(conf->num_queues * conf->queue_size / 2); -+ qemu_mutex_destroy(&s->rq_lock); - blk_ram_registrar_destroy(&s->blk_ram_registrar); - qemu_del_vm_change_state_handler(s->change); - blockdev_mark_auto_del(s->blk); -diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h -index dafec432ce..9881009c22 100644 ---- a/include/hw/virtio/virtio-blk.h -+++ b/include/hw/virtio/virtio-blk.h -@@ -54,7 +54,8 @@ struct VirtIOBlockReq; - struct VirtIOBlock { - VirtIODevice parent_obj; - BlockBackend *blk; -- void *rq; -+ QemuMutex rq_lock; -+ void *rq; /* protected by rq_lock */ - VirtIOBlkConf conf; - unsigned short sector_mask; - bool original_wce; --- -2.39.3 - diff --git a/kvm-virtio-blk-always-set-ioeventfd-during-startup.patch b/kvm-virtio-blk-always-set-ioeventfd-during-startup.patch deleted file mode 100644 index a7b518d..0000000 --- a/kvm-virtio-blk-always-set-ioeventfd-during-startup.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 22730552442003e81c8c508c3e7ebacf647e4e75 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Fri, 19 Jan 2024 08:57:48 -0500 -Subject: [PATCH 19/22] virtio-blk: always set ioeventfd during startup - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [15/17] 5f7142aeaa54fda41bd5c4fd3222fd8e3e18f370 (stefanha/centos-stream-qemu-kvm) - -When starting ioeventfd it is common practice to set the event notifier -so that the ioeventfd handler is triggered to run immediately. There may -be no requests waiting to be processed, but the idea is that if a -request snuck in then we guarantee that it will be detected. - -One scenario where self-triggering the ioeventfd is necessary is when -virtio_blk_handle_output() is called from a vCPU thread before the -VIRTIO Device Status transitions to DRIVER_OK. In that case we need to -self-trigger the ioeventfd so that the kick handled by the vCPU thread -causes the vq AioContext thread to take over handling the request(s). - -Fixes: b6948ab01df0 ("virtio-blk: add iothread-vq-mapping parameter") -Reported-by: Kevin Wolf -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240119135748.270944-7-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit d3f6f294aeadd5f88caf0155e4360808c95b3146) -Signed-off-by: Stefan Hajnoczi ---- - hw/block/virtio-blk.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index 81de06c9f6..0b9100b746 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -1809,14 +1809,14 @@ static int virtio_blk_start_ioeventfd(VirtIODevice *vdev) - smp_wmb(); /* paired with aio_notify_accept() on the read side */ - - /* Get this show started by hooking up our callbacks */ -- if (!blk_in_drain(s->conf.conf.blk)) { -- for (i = 0; i < nvqs; i++) { -- VirtQueue *vq = virtio_get_queue(vdev, i); -- AioContext *ctx = s->vq_aio_context[i]; -+ for (i = 0; i < nvqs; i++) { -+ VirtQueue *vq = virtio_get_queue(vdev, i); -+ AioContext *ctx = s->vq_aio_context[i]; - -- /* Kick right away to begin processing requests already in vring */ -- event_notifier_set(virtio_queue_get_host_notifier(vq)); -+ /* Kick right away to begin processing requests already in vring */ -+ event_notifier_set(virtio_queue_get_host_notifier(vq)); - -+ if (!blk_in_drain(s->conf.conf.blk)) { - virtio_queue_aio_attach_host_notifier(vq, ctx); - } - } --- -2.39.3 - diff --git a/kvm-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch b/kvm-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch deleted file mode 100644 index 8d93bf6..0000000 --- a/kvm-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch +++ /dev/null @@ -1,72 +0,0 @@ -From f62b56c68d50a149a07e15797bf3605e63b2c501 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 22 Jan 2024 12:26:25 -0500 -Subject: [PATCH 4/6] virtio-blk: avoid using ioeventfd state in irqfd - conditional - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 224: virtio-blk: avoid using ioeventfd state in irqfd conditional -RH-Jira: RHEL-15394 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [1/1] 8f24084669db52457e55e2523b9f56f5560dd6ce (stefanha/centos-stream-qemu-kvm) - -Requests that complete in an IOThread use irqfd to notify the guest -while requests that complete in the main loop thread use the traditional -qdev irq code path. The reason for this conditional is that the irq code -path requires the BQL: - - if (s->ioeventfd_started && !s->ioeventfd_disabled) { - virtio_notify_irqfd(vdev, req->vq); - } else { - virtio_notify(vdev, req->vq); - } - -There is a corner case where the conditional invokes the irq code path -instead of the irqfd code path: - - static void virtio_blk_stop_ioeventfd(VirtIODevice *vdev) - { - ... - /* - * Set ->ioeventfd_started to false before draining so that host notifiers - * are not detached/attached anymore. - */ - s->ioeventfd_started = false; - - /* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */ - blk_drain(s->conf.conf.blk); - -During blk_drain() the conditional produces the wrong result because -ioeventfd_started is false. - -Use qemu_in_iothread() instead of checking the ioeventfd state. - -Cc: qemu-stable@nongnu.org -Buglink: https://issues.redhat.com/browse/RHEL-15394 -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240122172625.415386-1-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit bfa36802d1704fc413c590ebdcc4e5ae0eacf439) -Signed-off-by: Stefan Hajnoczi ---- - hw/block/virtio-blk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index 7fdeaf2d12..2ae2f6a823 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -66,7 +66,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status) - iov_discard_undo(&req->inhdr_undo); - iov_discard_undo(&req->outhdr_undo); - virtqueue_push(req->vq, &req->elem, req->in_len); -- if (s->ioeventfd_started && !s->ioeventfd_disabled) { -+ if (qemu_in_iothread()) { - virtio_notify_irqfd(vdev, req->vq); - } else { - virtio_notify(vdev, req->vq); --- -2.39.3 - diff --git a/kvm-virtio-blk-don-t-lock-AioContext-in-the-completion-c.patch b/kvm-virtio-blk-don-t-lock-AioContext-in-the-completion-c.patch deleted file mode 100644 index be3c7db..0000000 --- a/kvm-virtio-blk-don-t-lock-AioContext-in-the-completion-c.patch +++ /dev/null @@ -1,167 +0,0 @@ -From a2069ff76637365cacf5b96f9427b98a6ca2c9ba Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 14 Sep 2023 10:01:00 -0400 -Subject: [PATCH 075/101] virtio-blk: don't lock AioContext in the completion - code path - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [6/26] 3426f62c2156f6967bb4ffbce75a4ff46d3312a3 (kmwolf/centos-qemu-kvm) - -Nothing in the completion code path relies on the AioContext lock -anymore. Virtqueues are only accessed from one thread at any moment and -the s->rq global state is protected by its own lock now. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20230914140101.1065008-4-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Reviewed-by: Eric Blake -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Kevin Wolf ---- - hw/block/virtio-blk.c | 34 ++++------------------------------ - 1 file changed, 4 insertions(+), 30 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index ee38e089bc..f5315df042 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -105,7 +105,6 @@ static void virtio_blk_rw_complete(void *opaque, int ret) - VirtIOBlock *s = next->dev; - VirtIODevice *vdev = VIRTIO_DEVICE(s); - -- aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); - while (next) { - VirtIOBlockReq *req = next; - next = req->mr_next; -@@ -138,7 +137,6 @@ static void virtio_blk_rw_complete(void *opaque, int ret) - block_acct_done(blk_get_stats(s->blk), &req->acct); - virtio_blk_free_request(req); - } -- aio_context_release(blk_get_aio_context(s->conf.conf.blk)); - } - - static void virtio_blk_flush_complete(void *opaque, int ret) -@@ -146,19 +144,13 @@ static void virtio_blk_flush_complete(void *opaque, int ret) - VirtIOBlockReq *req = opaque; - VirtIOBlock *s = req->dev; - -- aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); -- if (ret) { -- if (virtio_blk_handle_rw_error(req, -ret, 0, true)) { -- goto out; -- } -+ if (ret && virtio_blk_handle_rw_error(req, -ret, 0, true)) { -+ return; - } - - virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); - block_acct_done(blk_get_stats(s->blk), &req->acct); - virtio_blk_free_request(req); -- --out: -- aio_context_release(blk_get_aio_context(s->conf.conf.blk)); - } - - static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret) -@@ -168,11 +160,8 @@ static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret) - bool is_write_zeroes = (virtio_ldl_p(VIRTIO_DEVICE(s), &req->out.type) & - ~VIRTIO_BLK_T_BARRIER) == VIRTIO_BLK_T_WRITE_ZEROES; - -- aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); -- if (ret) { -- if (virtio_blk_handle_rw_error(req, -ret, false, is_write_zeroes)) { -- goto out; -- } -+ if (ret && virtio_blk_handle_rw_error(req, -ret, false, is_write_zeroes)) { -+ return; - } - - virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); -@@ -180,9 +169,6 @@ static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret) - block_acct_done(blk_get_stats(s->blk), &req->acct); - } - virtio_blk_free_request(req); -- --out: -- aio_context_release(blk_get_aio_context(s->conf.conf.blk)); - } - - #ifdef __linux__ -@@ -229,10 +215,8 @@ static void virtio_blk_ioctl_complete(void *opaque, int status) - virtio_stl_p(vdev, &scsi->data_len, hdr->dxfer_len); - - out: -- aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); - virtio_blk_req_complete(req, status); - virtio_blk_free_request(req); -- aio_context_release(blk_get_aio_context(s->conf.conf.blk)); - g_free(ioctl_req); - } - -@@ -672,7 +656,6 @@ static void virtio_blk_zone_report_complete(void *opaque, int ret) - { - ZoneCmdData *data = opaque; - VirtIOBlockReq *req = data->req; -- VirtIOBlock *s = req->dev; - VirtIODevice *vdev = VIRTIO_DEVICE(req->dev); - struct iovec *in_iov = data->in_iov; - unsigned in_num = data->in_num; -@@ -763,10 +746,8 @@ static void virtio_blk_zone_report_complete(void *opaque, int ret) - } - - out: -- aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); - virtio_blk_req_complete(req, err_status); - virtio_blk_free_request(req); -- aio_context_release(blk_get_aio_context(s->conf.conf.blk)); - g_free(data->zone_report_data.zones); - g_free(data); - } -@@ -829,10 +810,8 @@ static void virtio_blk_zone_mgmt_complete(void *opaque, int ret) - err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; - } - -- aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); - virtio_blk_req_complete(req, err_status); - virtio_blk_free_request(req); -- aio_context_release(blk_get_aio_context(s->conf.conf.blk)); - } - - static int virtio_blk_handle_zone_mgmt(VirtIOBlockReq *req, BlockZoneOp op) -@@ -882,7 +861,6 @@ static void virtio_blk_zone_append_complete(void *opaque, int ret) - { - ZoneCmdData *data = opaque; - VirtIOBlockReq *req = data->req; -- VirtIOBlock *s = req->dev; - VirtIODevice *vdev = VIRTIO_DEVICE(req->dev); - int64_t append_sector, n; - uint8_t err_status = VIRTIO_BLK_S_OK; -@@ -905,10 +883,8 @@ static void virtio_blk_zone_append_complete(void *opaque, int ret) - trace_virtio_blk_zone_append_complete(vdev, req, append_sector, ret); - - out: -- aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); - virtio_blk_req_complete(req, err_status); - virtio_blk_free_request(req); -- aio_context_release(blk_get_aio_context(s->conf.conf.blk)); - g_free(data); - } - -@@ -944,10 +920,8 @@ static int virtio_blk_handle_zone_append(VirtIOBlockReq *req, - return 0; - - out: -- aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); - virtio_blk_req_complete(req, err_status); - virtio_blk_free_request(req); -- aio_context_release(blk_get_aio_context(s->conf.conf.blk)); - return err_status; - } - --- -2.39.3 - diff --git a/kvm-virtio-blk-don-t-lock-AioContext-in-the-submission-c.patch b/kvm-virtio-blk-don-t-lock-AioContext-in-the-submission-c.patch deleted file mode 100644 index c31fcca..0000000 --- a/kvm-virtio-blk-don-t-lock-AioContext-in-the-submission-c.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 2816f6ce20c496e21947f215112be34a5cb93606 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Thu, 14 Sep 2023 10:01:01 -0400 -Subject: [PATCH 076/101] virtio-blk: don't lock AioContext in the submission - code path - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [7/26] e0de2744cb319569ea008334e45ee5fc2ba9b6d7 (kmwolf/centos-qemu-kvm) - -There is no need to acquire the AioContext lock around blk_aio_*() or -blk_get_geometry() anymore. I/O plugging (defer_call()) also does not -require the AioContext lock anymore. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20230914140101.1065008-5-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Reviewed-by: Eric Blake -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Kevin Wolf ---- - hw/block/virtio-blk.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index f5315df042..e110f9718b 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -1111,7 +1111,6 @@ void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq) - MultiReqBuffer mrb = {}; - bool suppress_notifications = virtio_queue_get_notification(vq); - -- aio_context_acquire(blk_get_aio_context(s->blk)); - defer_call_begin(); - - do { -@@ -1137,7 +1136,6 @@ void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq) - } - - defer_call_end(); -- aio_context_release(blk_get_aio_context(s->blk)); - } - - static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) -@@ -1168,7 +1166,6 @@ static void virtio_blk_dma_restart_bh(void *opaque) - s->rq = NULL; - } - -- aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); - while (req) { - VirtIOBlockReq *next = req->next; - if (virtio_blk_handle_request(req, &mrb)) { -@@ -1192,8 +1189,6 @@ static void virtio_blk_dma_restart_bh(void *opaque) - - /* Paired with inc in virtio_blk_dma_restart_cb() */ - blk_dec_in_flight(s->conf.conf.blk); -- -- aio_context_release(blk_get_aio_context(s->conf.conf.blk)); - } - - static void virtio_blk_dma_restart_cb(void *opaque, bool running, --- -2.39.3 - diff --git a/kvm-virtio-blk-move-dataplane-code-into-virtio-blk.c.patch b/kvm-virtio-blk-move-dataplane-code-into-virtio-blk.c.patch deleted file mode 100644 index 3fb8211..0000000 --- a/kvm-virtio-blk-move-dataplane-code-into-virtio-blk.c.patch +++ /dev/null @@ -1,1009 +0,0 @@ -From d9be1e1f199ee3171455636f32f3ba59b57e9351 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Fri, 19 Jan 2024 08:57:43 -0500 -Subject: [PATCH 14/22] virtio-blk: move dataplane code into virtio-blk.c - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [10/17] ad854c6c7e808da272bd07229e8c915c1ee6f296 (stefanha/centos-stream-qemu-kvm) - -The dataplane code used to be significantly different from the -non-dataplane code and therefore had a separate source file. - -Over time the difference has gotten smaller because the I/O code paths -were unified. Nowadays the distinction between the VirtIOBlock and -VirtIOBlockDataPlane structs is more of an inconvenience that hinders -code simplification. - -Move hw/block/dataplane/virtio-blk.c into hw/block/virtio-blk.c, merging -VirtIOBlockDataPlane's fields into VirtIOBlock. - -hw/block/virtio-blk.c used VirtIOBlock->dataplane to check if -virtio_blk_data_plane_create() was successful. This is not necessary -because ->dataplane_started and ->dataplane_disabled can be used -instead. This patch makes those changes in order to drop -VirtIOBlock->dataplane. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240119135748.270944-2-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 3bcc17f06526754fd675dcf601414442044fa0b6) -Signed-off-by: Stefan Hajnoczi - -Conflicts: - hw/block/dataplane/virtio-blk.c - Downstream is missing commit 0b2675c473f6 ("Rename "QEMU global mutex" - to "BQL" in comments and docs") so the source file still contains old - "QEMU global mutex held" comments instead of the new "BQL held" - phrasing. The code moved into hw/block/virtio-blk.c by this patch uses - the new "BQL held" phrasing so to minimize conflicts in future - backports. Either way, this is not a code change and therefore no risk - in introducing bugs. ---- - hw/block/dataplane/meson.build | 1 - - hw/block/dataplane/trace-events | 5 - - hw/block/dataplane/trace.h | 1 - - hw/block/dataplane/virtio-blk.c | 404 -------------------------------- - hw/block/dataplane/virtio-blk.h | 34 --- - hw/block/virtio-blk.c | 362 ++++++++++++++++++++++++++-- - include/hw/virtio/virtio-blk.h | 12 +- - meson.build | 1 - - 8 files changed, 357 insertions(+), 463 deletions(-) - delete mode 100644 hw/block/dataplane/trace-events - delete mode 100644 hw/block/dataplane/trace.h - delete mode 100644 hw/block/dataplane/virtio-blk.c - delete mode 100644 hw/block/dataplane/virtio-blk.h - -diff --git a/hw/block/dataplane/meson.build b/hw/block/dataplane/meson.build -index 025b3b061b..11a5eba2f4 100644 ---- a/hw/block/dataplane/meson.build -+++ b/hw/block/dataplane/meson.build -@@ -1,2 +1 @@ --system_ss.add(when: 'CONFIG_VIRTIO_BLK', if_true: files('virtio-blk.c')) - specific_ss.add(when: 'CONFIG_XEN_BUS', if_true: files('xen-block.c')) -diff --git a/hw/block/dataplane/trace-events b/hw/block/dataplane/trace-events -deleted file mode 100644 -index 38fc3e7507..0000000000 ---- a/hw/block/dataplane/trace-events -+++ /dev/null -@@ -1,5 +0,0 @@ --# See docs/devel/tracing.rst for syntax documentation. -- --# virtio-blk.c --virtio_blk_data_plane_start(void *s) "dataplane %p" --virtio_blk_data_plane_stop(void *s) "dataplane %p" -diff --git a/hw/block/dataplane/trace.h b/hw/block/dataplane/trace.h -deleted file mode 100644 -index 240cc59834..0000000000 ---- a/hw/block/dataplane/trace.h -+++ /dev/null -@@ -1 +0,0 @@ --#include "trace/trace-hw_block_dataplane.h" -diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c -deleted file mode 100644 -index 97a302cf49..0000000000 ---- a/hw/block/dataplane/virtio-blk.c -+++ /dev/null -@@ -1,404 +0,0 @@ --/* -- * Dedicated thread for virtio-blk I/O processing -- * -- * Copyright 2012 IBM, Corp. -- * Copyright 2012 Red Hat, Inc. and/or its affiliates -- * -- * Authors: -- * Stefan Hajnoczi -- * -- * This work is licensed under the terms of the GNU GPL, version 2 or later. -- * See the COPYING file in the top-level directory. -- * -- */ -- --#include "qemu/osdep.h" --#include "qapi/error.h" --#include "trace.h" --#include "qemu/iov.h" --#include "qemu/main-loop.h" --#include "qemu/thread.h" --#include "qemu/error-report.h" --#include "hw/virtio/virtio-blk.h" --#include "virtio-blk.h" --#include "block/aio.h" --#include "hw/virtio/virtio-bus.h" --#include "qom/object_interfaces.h" -- --struct VirtIOBlockDataPlane { -- bool starting; -- bool stopping; -- -- VirtIOBlkConf *conf; -- VirtIODevice *vdev; -- -- /* -- * The AioContext for each virtqueue. The BlockDriverState will use the -- * first element as its AioContext. -- */ -- AioContext **vq_aio_context; --}; -- --/* Raise an interrupt to signal guest, if necessary */ --void virtio_blk_data_plane_notify(VirtIOBlockDataPlane *s, VirtQueue *vq) --{ -- virtio_notify_irqfd(s->vdev, vq); --} -- --/* Generate vq:AioContext mappings from a validated iothread-vq-mapping list */ --static void --apply_vq_mapping(IOThreadVirtQueueMappingList *iothread_vq_mapping_list, -- AioContext **vq_aio_context, uint16_t num_queues) --{ -- IOThreadVirtQueueMappingList *node; -- size_t num_iothreads = 0; -- size_t cur_iothread = 0; -- -- for (node = iothread_vq_mapping_list; node; node = node->next) { -- num_iothreads++; -- } -- -- for (node = iothread_vq_mapping_list; node; node = node->next) { -- IOThread *iothread = iothread_by_id(node->value->iothread); -- AioContext *ctx = iothread_get_aio_context(iothread); -- -- /* Released in virtio_blk_data_plane_destroy() */ -- object_ref(OBJECT(iothread)); -- -- if (node->value->vqs) { -- uint16List *vq; -- -- /* Explicit vq:IOThread assignment */ -- for (vq = node->value->vqs; vq; vq = vq->next) { -- vq_aio_context[vq->value] = ctx; -- } -- } else { -- /* Round-robin vq:IOThread assignment */ -- for (unsigned i = cur_iothread; i < num_queues; -- i += num_iothreads) { -- vq_aio_context[i] = ctx; -- } -- } -- -- cur_iothread++; -- } --} -- --/* Context: QEMU global mutex held */ --bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, -- VirtIOBlockDataPlane **dataplane, -- Error **errp) --{ -- VirtIOBlockDataPlane *s; -- BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); -- VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -- -- *dataplane = NULL; -- -- if (conf->iothread || conf->iothread_vq_mapping_list) { -- if (!k->set_guest_notifiers || !k->ioeventfd_assign) { -- error_setg(errp, -- "device is incompatible with iothread " -- "(transport does not support notifiers)"); -- return false; -- } -- if (!virtio_device_ioeventfd_enabled(vdev)) { -- error_setg(errp, "ioeventfd is required for iothread"); -- return false; -- } -- -- /* If dataplane is (re-)enabled while the guest is running there could -- * be block jobs that can conflict. -- */ -- if (blk_op_is_blocked(conf->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { -- error_prepend(errp, "cannot start virtio-blk dataplane: "); -- return false; -- } -- } -- /* Don't try if transport does not support notifiers. */ -- if (!virtio_device_ioeventfd_enabled(vdev)) { -- return false; -- } -- -- s = g_new0(VirtIOBlockDataPlane, 1); -- s->vdev = vdev; -- s->conf = conf; -- s->vq_aio_context = g_new(AioContext *, conf->num_queues); -- -- if (conf->iothread_vq_mapping_list) { -- apply_vq_mapping(conf->iothread_vq_mapping_list, s->vq_aio_context, -- conf->num_queues); -- } else if (conf->iothread) { -- AioContext *ctx = iothread_get_aio_context(conf->iothread); -- for (unsigned i = 0; i < conf->num_queues; i++) { -- s->vq_aio_context[i] = ctx; -- } -- -- /* Released in virtio_blk_data_plane_destroy() */ -- object_ref(OBJECT(conf->iothread)); -- } else { -- AioContext *ctx = qemu_get_aio_context(); -- for (unsigned i = 0; i < conf->num_queues; i++) { -- s->vq_aio_context[i] = ctx; -- } -- } -- -- *dataplane = s; -- -- return true; --} -- --/* Context: QEMU global mutex held */ --void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s) --{ -- VirtIOBlock *vblk; -- VirtIOBlkConf *conf; -- -- if (!s) { -- return; -- } -- -- vblk = VIRTIO_BLK(s->vdev); -- assert(!vblk->dataplane_started); -- conf = s->conf; -- -- if (conf->iothread_vq_mapping_list) { -- IOThreadVirtQueueMappingList *node; -- -- for (node = conf->iothread_vq_mapping_list; node; node = node->next) { -- IOThread *iothread = iothread_by_id(node->value->iothread); -- object_unref(OBJECT(iothread)); -- } -- } -- -- if (conf->iothread) { -- object_unref(OBJECT(conf->iothread)); -- } -- -- g_free(s->vq_aio_context); -- g_free(s); --} -- --/* Context: QEMU global mutex held */ --int virtio_blk_data_plane_start(VirtIODevice *vdev) --{ -- VirtIOBlock *vblk = VIRTIO_BLK(vdev); -- VirtIOBlockDataPlane *s = vblk->dataplane; -- BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vblk))); -- VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -- unsigned i; -- unsigned nvqs = s->conf->num_queues; -- Error *local_err = NULL; -- int r; -- -- if (vblk->dataplane_started || s->starting) { -- return 0; -- } -- -- s->starting = true; -- -- /* Set up guest notifier (irq) */ -- r = k->set_guest_notifiers(qbus->parent, nvqs, true); -- if (r != 0) { -- error_report("virtio-blk failed to set guest notifier (%d), " -- "ensure -accel kvm is set.", r); -- goto fail_guest_notifiers; -- } -- -- /* -- * Batch all the host notifiers in a single transaction to avoid -- * quadratic time complexity in address_space_update_ioeventfds(). -- */ -- memory_region_transaction_begin(); -- -- /* Set up virtqueue notify */ -- for (i = 0; i < nvqs; i++) { -- r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, true); -- if (r != 0) { -- int j = i; -- -- fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r); -- while (i--) { -- virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false); -- } -- -- /* -- * The transaction expects the ioeventfds to be open when it -- * commits. Do it now, before the cleanup loop. -- */ -- memory_region_transaction_commit(); -- -- while (j--) { -- virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), j); -- } -- goto fail_host_notifiers; -- } -- } -- -- memory_region_transaction_commit(); -- -- trace_virtio_blk_data_plane_start(s); -- -- r = blk_set_aio_context(s->conf->conf.blk, s->vq_aio_context[0], -- &local_err); -- if (r < 0) { -- error_report_err(local_err); -- goto fail_aio_context; -- } -- -- /* -- * These fields must be visible to the IOThread when it processes the -- * virtqueue, otherwise it will think dataplane has not started yet. -- * -- * Make sure ->dataplane_started is false when blk_set_aio_context() is -- * called above so that draining does not cause the host notifier to be -- * detached/attached prematurely. -- */ -- s->starting = false; -- vblk->dataplane_started = true; -- smp_wmb(); /* paired with aio_notify_accept() on the read side */ -- -- /* Get this show started by hooking up our callbacks */ -- if (!blk_in_drain(s->conf->conf.blk)) { -- for (i = 0; i < nvqs; i++) { -- VirtQueue *vq = virtio_get_queue(s->vdev, i); -- AioContext *ctx = s->vq_aio_context[i]; -- -- /* Kick right away to begin processing requests already in vring */ -- event_notifier_set(virtio_queue_get_host_notifier(vq)); -- -- virtio_queue_aio_attach_host_notifier(vq, ctx); -- } -- } -- return 0; -- -- fail_aio_context: -- memory_region_transaction_begin(); -- -- for (i = 0; i < nvqs; i++) { -- virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false); -- } -- -- memory_region_transaction_commit(); -- -- for (i = 0; i < nvqs; i++) { -- virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i); -- } -- fail_host_notifiers: -- k->set_guest_notifiers(qbus->parent, nvqs, false); -- fail_guest_notifiers: -- vblk->dataplane_disabled = true; -- s->starting = false; -- return -ENOSYS; --} -- --/* Stop notifications for new requests from guest. -- * -- * Context: BH in IOThread -- */ --static void virtio_blk_data_plane_stop_vq_bh(void *opaque) --{ -- VirtQueue *vq = opaque; -- EventNotifier *host_notifier = virtio_queue_get_host_notifier(vq); -- -- virtio_queue_aio_detach_host_notifier(vq, qemu_get_current_aio_context()); -- -- /* -- * Test and clear notifier after disabling event, in case poll callback -- * didn't have time to run. -- */ -- virtio_queue_host_notifier_read(host_notifier); --} -- --/* Context: QEMU global mutex held */ --void virtio_blk_data_plane_stop(VirtIODevice *vdev) --{ -- VirtIOBlock *vblk = VIRTIO_BLK(vdev); -- VirtIOBlockDataPlane *s = vblk->dataplane; -- BusState *qbus = qdev_get_parent_bus(DEVICE(vblk)); -- VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -- unsigned i; -- unsigned nvqs = s->conf->num_queues; -- -- if (!vblk->dataplane_started || s->stopping) { -- return; -- } -- -- /* Better luck next time. */ -- if (vblk->dataplane_disabled) { -- vblk->dataplane_disabled = false; -- vblk->dataplane_started = false; -- return; -- } -- s->stopping = true; -- trace_virtio_blk_data_plane_stop(s); -- -- if (!blk_in_drain(s->conf->conf.blk)) { -- for (i = 0; i < nvqs; i++) { -- VirtQueue *vq = virtio_get_queue(s->vdev, i); -- AioContext *ctx = s->vq_aio_context[i]; -- -- aio_wait_bh_oneshot(ctx, virtio_blk_data_plane_stop_vq_bh, vq); -- } -- } -- -- /* -- * Batch all the host notifiers in a single transaction to avoid -- * quadratic time complexity in address_space_update_ioeventfds(). -- */ -- memory_region_transaction_begin(); -- -- for (i = 0; i < nvqs; i++) { -- virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false); -- } -- -- /* -- * The transaction expects the ioeventfds to be open when it -- * commits. Do it now, before the cleanup loop. -- */ -- memory_region_transaction_commit(); -- -- for (i = 0; i < nvqs; i++) { -- virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i); -- } -- -- /* -- * Set ->dataplane_started to false before draining so that host notifiers -- * are not detached/attached anymore. -- */ -- vblk->dataplane_started = false; -- -- /* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */ -- blk_drain(s->conf->conf.blk); -- -- /* -- * Try to switch bs back to the QEMU main loop. If other users keep the -- * BlockBackend in the iothread, that's ok -- */ -- blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context(), NULL); -- -- /* Clean up guest notifier (irq) */ -- k->set_guest_notifiers(qbus->parent, nvqs, false); -- -- s->stopping = false; --} -- --void virtio_blk_data_plane_detach(VirtIOBlockDataPlane *s) --{ -- VirtIODevice *vdev = VIRTIO_DEVICE(s->vdev); -- -- for (uint16_t i = 0; i < s->conf->num_queues; i++) { -- VirtQueue *vq = virtio_get_queue(vdev, i); -- virtio_queue_aio_detach_host_notifier(vq, s->vq_aio_context[i]); -- } --} -- --void virtio_blk_data_plane_attach(VirtIOBlockDataPlane *s) --{ -- VirtIODevice *vdev = VIRTIO_DEVICE(s->vdev); -- -- for (uint16_t i = 0; i < s->conf->num_queues; i++) { -- VirtQueue *vq = virtio_get_queue(vdev, i); -- virtio_queue_aio_attach_host_notifier(vq, s->vq_aio_context[i]); -- } --} -diff --git a/hw/block/dataplane/virtio-blk.h b/hw/block/dataplane/virtio-blk.h -deleted file mode 100644 -index 1a806fe447..0000000000 ---- a/hw/block/dataplane/virtio-blk.h -+++ /dev/null -@@ -1,34 +0,0 @@ --/* -- * Dedicated thread for virtio-blk I/O processing -- * -- * Copyright 2012 IBM, Corp. -- * Copyright 2012 Red Hat, Inc. and/or its affiliates -- * -- * Authors: -- * Stefan Hajnoczi -- * -- * This work is licensed under the terms of the GNU GPL, version 2 or later. -- * See the COPYING file in the top-level directory. -- * -- */ -- --#ifndef HW_DATAPLANE_VIRTIO_BLK_H --#define HW_DATAPLANE_VIRTIO_BLK_H -- --#include "hw/virtio/virtio.h" -- --typedef struct VirtIOBlockDataPlane VirtIOBlockDataPlane; -- --bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, -- VirtIOBlockDataPlane **dataplane, -- Error **errp); --void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s); --void virtio_blk_data_plane_notify(VirtIOBlockDataPlane *s, VirtQueue *vq); -- --int virtio_blk_data_plane_start(VirtIODevice *vdev); --void virtio_blk_data_plane_stop(VirtIODevice *vdev); -- --void virtio_blk_data_plane_detach(VirtIOBlockDataPlane *s); --void virtio_blk_data_plane_attach(VirtIOBlockDataPlane *s); -- --#endif /* HW_DATAPLANE_VIRTIO_BLK_H */ -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index 46e73b2c96..cb623069f8 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -27,7 +27,6 @@ - #include "sysemu/sysemu.h" - #include "sysemu/runstate.h" - #include "hw/virtio/virtio-blk.h" --#include "dataplane/virtio-blk.h" - #include "scsi/constants.h" - #ifdef __linux__ - # include -@@ -66,7 +65,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status) - iov_discard_undo(&req->outhdr_undo); - virtqueue_push(req->vq, &req->elem, req->in_len); - if (s->dataplane_started && !s->dataplane_disabled) { -- virtio_blk_data_plane_notify(s->dataplane, req->vq); -+ virtio_notify_irqfd(vdev, req->vq); - } else { - virtio_notify(vdev, req->vq); - } -@@ -1142,7 +1141,7 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) - { - VirtIOBlock *s = (VirtIOBlock *)vdev; - -- if (s->dataplane && !s->dataplane_started) { -+ if (!s->dataplane_disabled && !s->dataplane_started) { - /* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start - * dataplane here instead of waiting for .set_status(). - */ -@@ -1546,16 +1545,34 @@ static void virtio_blk_resize(void *opaque) - aio_bh_schedule_oneshot(qemu_get_aio_context(), virtio_resize_cb, vdev); - } - -+static void virtio_blk_data_plane_detach(VirtIOBlock *s) -+{ -+ VirtIODevice *vdev = VIRTIO_DEVICE(s); -+ -+ for (uint16_t i = 0; i < s->conf.num_queues; i++) { -+ VirtQueue *vq = virtio_get_queue(vdev, i); -+ virtio_queue_aio_detach_host_notifier(vq, s->vq_aio_context[i]); -+ } -+} -+ -+static void virtio_blk_data_plane_attach(VirtIOBlock *s) -+{ -+ VirtIODevice *vdev = VIRTIO_DEVICE(s); -+ -+ for (uint16_t i = 0; i < s->conf.num_queues; i++) { -+ VirtQueue *vq = virtio_get_queue(vdev, i); -+ virtio_queue_aio_attach_host_notifier(vq, s->vq_aio_context[i]); -+ } -+} -+ - /* Suspend virtqueue ioeventfd processing during drain */ - static void virtio_blk_drained_begin(void *opaque) - { - VirtIOBlock *s = opaque; - -- if (!s->dataplane || !s->dataplane_started) { -- return; -+ if (s->dataplane_started) { -+ virtio_blk_data_plane_detach(s); - } -- -- virtio_blk_data_plane_detach(s->dataplane); - } - - /* Resume virtqueue ioeventfd processing after drain */ -@@ -1563,11 +1580,9 @@ static void virtio_blk_drained_end(void *opaque) - { - VirtIOBlock *s = opaque; - -- if (!s->dataplane || !s->dataplane_started) { -- return; -+ if (s->dataplane_started) { -+ virtio_blk_data_plane_attach(s); - } -- -- virtio_blk_data_plane_attach(s->dataplane); - } - - static const BlockDevOps virtio_block_ops = { -@@ -1576,6 +1591,326 @@ static const BlockDevOps virtio_block_ops = { - .drained_end = virtio_blk_drained_end, - }; - -+/* Generate vq:AioContext mappings from a validated iothread-vq-mapping list */ -+static void -+apply_vq_mapping(IOThreadVirtQueueMappingList *iothread_vq_mapping_list, -+ AioContext **vq_aio_context, uint16_t num_queues) -+{ -+ IOThreadVirtQueueMappingList *node; -+ size_t num_iothreads = 0; -+ size_t cur_iothread = 0; -+ -+ for (node = iothread_vq_mapping_list; node; node = node->next) { -+ num_iothreads++; -+ } -+ -+ for (node = iothread_vq_mapping_list; node; node = node->next) { -+ IOThread *iothread = iothread_by_id(node->value->iothread); -+ AioContext *ctx = iothread_get_aio_context(iothread); -+ -+ /* Released in virtio_blk_data_plane_destroy() */ -+ object_ref(OBJECT(iothread)); -+ -+ if (node->value->vqs) { -+ uint16List *vq; -+ -+ /* Explicit vq:IOThread assignment */ -+ for (vq = node->value->vqs; vq; vq = vq->next) { -+ vq_aio_context[vq->value] = ctx; -+ } -+ } else { -+ /* Round-robin vq:IOThread assignment */ -+ for (unsigned i = cur_iothread; i < num_queues; -+ i += num_iothreads) { -+ vq_aio_context[i] = ctx; -+ } -+ } -+ -+ cur_iothread++; -+ } -+} -+ -+/* Context: BQL held */ -+static bool virtio_blk_data_plane_create(VirtIOBlock *s, Error **errp) -+{ -+ VirtIODevice *vdev = VIRTIO_DEVICE(s); -+ VirtIOBlkConf *conf = &s->conf; -+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); -+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -+ -+ if (conf->iothread || conf->iothread_vq_mapping_list) { -+ if (!k->set_guest_notifiers || !k->ioeventfd_assign) { -+ error_setg(errp, -+ "device is incompatible with iothread " -+ "(transport does not support notifiers)"); -+ return false; -+ } -+ if (!virtio_device_ioeventfd_enabled(vdev)) { -+ error_setg(errp, "ioeventfd is required for iothread"); -+ return false; -+ } -+ -+ /* -+ * If dataplane is (re-)enabled while the guest is running there could -+ * be block jobs that can conflict. -+ */ -+ if (blk_op_is_blocked(conf->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { -+ error_prepend(errp, "cannot start virtio-blk dataplane: "); -+ return false; -+ } -+ } -+ /* Don't try if transport does not support notifiers. */ -+ if (!virtio_device_ioeventfd_enabled(vdev)) { -+ s->dataplane_disabled = true; -+ return false; -+ } -+ -+ s->vq_aio_context = g_new(AioContext *, conf->num_queues); -+ -+ if (conf->iothread_vq_mapping_list) { -+ apply_vq_mapping(conf->iothread_vq_mapping_list, s->vq_aio_context, -+ conf->num_queues); -+ } else if (conf->iothread) { -+ AioContext *ctx = iothread_get_aio_context(conf->iothread); -+ for (unsigned i = 0; i < conf->num_queues; i++) { -+ s->vq_aio_context[i] = ctx; -+ } -+ -+ /* Released in virtio_blk_data_plane_destroy() */ -+ object_ref(OBJECT(conf->iothread)); -+ } else { -+ AioContext *ctx = qemu_get_aio_context(); -+ for (unsigned i = 0; i < conf->num_queues; i++) { -+ s->vq_aio_context[i] = ctx; -+ } -+ } -+ -+ return true; -+} -+ -+/* Context: BQL held */ -+static void virtio_blk_data_plane_destroy(VirtIOBlock *s) -+{ -+ VirtIOBlkConf *conf = &s->conf; -+ -+ assert(!s->dataplane_started); -+ -+ if (conf->iothread_vq_mapping_list) { -+ IOThreadVirtQueueMappingList *node; -+ -+ for (node = conf->iothread_vq_mapping_list; node; node = node->next) { -+ IOThread *iothread = iothread_by_id(node->value->iothread); -+ object_unref(OBJECT(iothread)); -+ } -+ } -+ -+ if (conf->iothread) { -+ object_unref(OBJECT(conf->iothread)); -+ } -+ -+ g_free(s->vq_aio_context); -+ s->vq_aio_context = NULL; -+} -+ -+/* Context: BQL held */ -+static int virtio_blk_data_plane_start(VirtIODevice *vdev) -+{ -+ VirtIOBlock *s = VIRTIO_BLK(vdev); -+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s))); -+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -+ unsigned i; -+ unsigned nvqs = s->conf.num_queues; -+ Error *local_err = NULL; -+ int r; -+ -+ if (s->dataplane_started || s->dataplane_starting) { -+ return 0; -+ } -+ -+ s->dataplane_starting = true; -+ -+ /* Set up guest notifier (irq) */ -+ r = k->set_guest_notifiers(qbus->parent, nvqs, true); -+ if (r != 0) { -+ error_report("virtio-blk failed to set guest notifier (%d), " -+ "ensure -accel kvm is set.", r); -+ goto fail_guest_notifiers; -+ } -+ -+ /* -+ * Batch all the host notifiers in a single transaction to avoid -+ * quadratic time complexity in address_space_update_ioeventfds(). -+ */ -+ memory_region_transaction_begin(); -+ -+ /* Set up virtqueue notify */ -+ for (i = 0; i < nvqs; i++) { -+ r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, true); -+ if (r != 0) { -+ int j = i; -+ -+ fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r); -+ while (i--) { -+ virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false); -+ } -+ -+ /* -+ * The transaction expects the ioeventfds to be open when it -+ * commits. Do it now, before the cleanup loop. -+ */ -+ memory_region_transaction_commit(); -+ -+ while (j--) { -+ virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), j); -+ } -+ goto fail_host_notifiers; -+ } -+ } -+ -+ memory_region_transaction_commit(); -+ -+ r = blk_set_aio_context(s->conf.conf.blk, s->vq_aio_context[0], -+ &local_err); -+ if (r < 0) { -+ error_report_err(local_err); -+ goto fail_aio_context; -+ } -+ -+ /* -+ * These fields must be visible to the IOThread when it processes the -+ * virtqueue, otherwise it will think dataplane has not started yet. -+ * -+ * Make sure ->dataplane_started is false when blk_set_aio_context() is -+ * called above so that draining does not cause the host notifier to be -+ * detached/attached prematurely. -+ */ -+ s->dataplane_starting = false; -+ s->dataplane_started = true; -+ smp_wmb(); /* paired with aio_notify_accept() on the read side */ -+ -+ /* Get this show started by hooking up our callbacks */ -+ if (!blk_in_drain(s->conf.conf.blk)) { -+ for (i = 0; i < nvqs; i++) { -+ VirtQueue *vq = virtio_get_queue(vdev, i); -+ AioContext *ctx = s->vq_aio_context[i]; -+ -+ /* Kick right away to begin processing requests already in vring */ -+ event_notifier_set(virtio_queue_get_host_notifier(vq)); -+ -+ virtio_queue_aio_attach_host_notifier(vq, ctx); -+ } -+ } -+ return 0; -+ -+ fail_aio_context: -+ memory_region_transaction_begin(); -+ -+ for (i = 0; i < nvqs; i++) { -+ virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false); -+ } -+ -+ memory_region_transaction_commit(); -+ -+ for (i = 0; i < nvqs; i++) { -+ virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i); -+ } -+ fail_host_notifiers: -+ k->set_guest_notifiers(qbus->parent, nvqs, false); -+ fail_guest_notifiers: -+ s->dataplane_disabled = true; -+ s->dataplane_starting = false; -+ return -ENOSYS; -+} -+ -+/* Stop notifications for new requests from guest. -+ * -+ * Context: BH in IOThread -+ */ -+static void virtio_blk_data_plane_stop_vq_bh(void *opaque) -+{ -+ VirtQueue *vq = opaque; -+ EventNotifier *host_notifier = virtio_queue_get_host_notifier(vq); -+ -+ virtio_queue_aio_detach_host_notifier(vq, qemu_get_current_aio_context()); -+ -+ /* -+ * Test and clear notifier after disabling event, in case poll callback -+ * didn't have time to run. -+ */ -+ virtio_queue_host_notifier_read(host_notifier); -+} -+ -+/* Context: BQL held */ -+static void virtio_blk_data_plane_stop(VirtIODevice *vdev) -+{ -+ VirtIOBlock *s = VIRTIO_BLK(vdev); -+ BusState *qbus = qdev_get_parent_bus(DEVICE(s)); -+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -+ unsigned i; -+ unsigned nvqs = s->conf.num_queues; -+ -+ if (!s->dataplane_started || s->dataplane_stopping) { -+ return; -+ } -+ -+ /* Better luck next time. */ -+ if (s->dataplane_disabled) { -+ s->dataplane_disabled = false; -+ s->dataplane_started = false; -+ return; -+ } -+ s->dataplane_stopping = true; -+ -+ if (!blk_in_drain(s->conf.conf.blk)) { -+ for (i = 0; i < nvqs; i++) { -+ VirtQueue *vq = virtio_get_queue(vdev, i); -+ AioContext *ctx = s->vq_aio_context[i]; -+ -+ aio_wait_bh_oneshot(ctx, virtio_blk_data_plane_stop_vq_bh, vq); -+ } -+ } -+ -+ /* -+ * Batch all the host notifiers in a single transaction to avoid -+ * quadratic time complexity in address_space_update_ioeventfds(). -+ */ -+ memory_region_transaction_begin(); -+ -+ for (i = 0; i < nvqs; i++) { -+ virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false); -+ } -+ -+ /* -+ * The transaction expects the ioeventfds to be open when it -+ * commits. Do it now, before the cleanup loop. -+ */ -+ memory_region_transaction_commit(); -+ -+ for (i = 0; i < nvqs; i++) { -+ virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i); -+ } -+ -+ /* -+ * Set ->dataplane_started to false before draining so that host notifiers -+ * are not detached/attached anymore. -+ */ -+ s->dataplane_started = false; -+ -+ /* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */ -+ blk_drain(s->conf.conf.blk); -+ -+ /* -+ * Try to switch bs back to the QEMU main loop. If other users keep the -+ * BlockBackend in the iothread, that's ok -+ */ -+ blk_set_aio_context(s->conf.conf.blk, qemu_get_aio_context(), NULL); -+ -+ /* Clean up guest notifier (irq) */ -+ k->set_guest_notifiers(qbus->parent, nvqs, false); -+ -+ s->dataplane_stopping = false; -+} -+ - static void virtio_blk_device_realize(DeviceState *dev, Error **errp) - { - VirtIODevice *vdev = VIRTIO_DEVICE(dev); -@@ -1680,7 +2015,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) - virtio_add_queue(vdev, conf->queue_size, virtio_blk_handle_output); - } - qemu_coroutine_inc_pool_size(conf->num_queues * conf->queue_size / 2); -- virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err); -+ virtio_blk_data_plane_create(s, &err); - if (err != NULL) { - error_propagate(errp, err); - for (i = 0; i < conf->num_queues; i++) { -@@ -1717,8 +2052,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev) - - blk_drain(s->blk); - del_boot_device_lchs(dev, "/disk@0,0"); -- virtio_blk_data_plane_destroy(s->dataplane); -- s->dataplane = NULL; -+ virtio_blk_data_plane_destroy(s); - for (i = 0; i < conf->num_queues; i++) { - virtio_del_queue(vdev, i); - } -diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h -index 5e4091e4da..fecffdc303 100644 ---- a/include/hw/virtio/virtio-blk.h -+++ b/include/hw/virtio/virtio-blk.h -@@ -50,8 +50,6 @@ struct VirtIOBlkConf - bool x_enable_wce_if_config_wce; - }; - --struct VirtIOBlockDataPlane; -- - struct VirtIOBlockReq; - struct VirtIOBlock { - VirtIODevice parent_obj; -@@ -64,7 +62,15 @@ struct VirtIOBlock { - VMChangeStateEntry *change; - bool dataplane_disabled; - bool dataplane_started; -- struct VirtIOBlockDataPlane *dataplane; -+ bool dataplane_starting; -+ bool dataplane_stopping; -+ -+ /* -+ * The AioContext for each virtqueue. The BlockDriverState will use the -+ * first element as its AioContext. -+ */ -+ AioContext **vq_aio_context; -+ - uint64_t host_features; - size_t config_size; - BlockRAMRegistrar blk_ram_registrar; -diff --git a/meson.build b/meson.build -index 6c77d9687d..47c65d0f53 100644 ---- a/meson.build -+++ b/meson.build -@@ -3298,7 +3298,6 @@ if have_system - 'hw/arm', - 'hw/audio', - 'hw/block', -- 'hw/block/dataplane', - 'hw/char', - 'hw/display', - 'hw/dma', --- -2.39.3 - diff --git a/kvm-virtio-blk-rename-dataplane-create-destroy-functions.patch b/kvm-virtio-blk-rename-dataplane-create-destroy-functions.patch deleted file mode 100644 index 5f45b9d..0000000 --- a/kvm-virtio-blk-rename-dataplane-create-destroy-functions.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 71257c2f320f1511de1e275779cf4b90effc1f02 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Fri, 19 Jan 2024 08:57:44 -0500 -Subject: [PATCH 15/22] virtio-blk: rename dataplane create/destroy functions - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [11/17] 60e7016d5f3e4e9e89945578279b12f812f85ddf (stefanha/centos-stream-qemu-kvm) - -virtio_blk_data_plane_create() and virtio_blk_data_plane_destroy() are -actually about s->vq_aio_context[] rather than managing -dataplane-specific state. - -As a prerequisite to using s->vq_aio_context[] in all code paths (even -when dataplane is not used), rename these functions to reflect that they -just manage s->vq_aio_context and call them regardless of whether or not -dataplane is in use. - -Note that virtio-blk supports running with -device -virtio-blk-pci,ioevent=off where the vCPU thread enters the device -emulation code. In this mode ioeventfd is not used for virtqueue -processing. However, we still want to initialize s->vq_aio_context[] to -qemu_aio_context in that case since I/O completion callbacks will be -invoked in the main loop thread. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240119135748.270944-3-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 57bc2658935778d1ae0edbcd4402763da8c7bae2) -Signed-off-by: Stefan Hajnoczi ---- - hw/block/virtio-blk.c | 23 ++++++++++++----------- - 1 file changed, 12 insertions(+), 11 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index cb623069f8..4d6f9377c6 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -1608,7 +1608,7 @@ apply_vq_mapping(IOThreadVirtQueueMappingList *iothread_vq_mapping_list, - IOThread *iothread = iothread_by_id(node->value->iothread); - AioContext *ctx = iothread_get_aio_context(iothread); - -- /* Released in virtio_blk_data_plane_destroy() */ -+ /* Released in virtio_blk_vq_aio_context_cleanup() */ - object_ref(OBJECT(iothread)); - - if (node->value->vqs) { -@@ -1631,7 +1631,7 @@ apply_vq_mapping(IOThreadVirtQueueMappingList *iothread_vq_mapping_list, - } - - /* Context: BQL held */ --static bool virtio_blk_data_plane_create(VirtIOBlock *s, Error **errp) -+static bool virtio_blk_vq_aio_context_init(VirtIOBlock *s, Error **errp) - { - VirtIODevice *vdev = VIRTIO_DEVICE(s); - VirtIOBlkConf *conf = &s->conf; -@@ -1659,11 +1659,6 @@ static bool virtio_blk_data_plane_create(VirtIOBlock *s, Error **errp) - return false; - } - } -- /* Don't try if transport does not support notifiers. */ -- if (!virtio_device_ioeventfd_enabled(vdev)) { -- s->dataplane_disabled = true; -- return false; -- } - - s->vq_aio_context = g_new(AioContext *, conf->num_queues); - -@@ -1676,7 +1671,7 @@ static bool virtio_blk_data_plane_create(VirtIOBlock *s, Error **errp) - s->vq_aio_context[i] = ctx; - } - -- /* Released in virtio_blk_data_plane_destroy() */ -+ /* Released in virtio_blk_vq_aio_context_cleanup() */ - object_ref(OBJECT(conf->iothread)); - } else { - AioContext *ctx = qemu_get_aio_context(); -@@ -1689,7 +1684,7 @@ static bool virtio_blk_data_plane_create(VirtIOBlock *s, Error **errp) - } - - /* Context: BQL held */ --static void virtio_blk_data_plane_destroy(VirtIOBlock *s) -+static void virtio_blk_vq_aio_context_cleanup(VirtIOBlock *s) - { - VirtIOBlkConf *conf = &s->conf; - -@@ -2015,7 +2010,13 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) - virtio_add_queue(vdev, conf->queue_size, virtio_blk_handle_output); - } - qemu_coroutine_inc_pool_size(conf->num_queues * conf->queue_size / 2); -- virtio_blk_data_plane_create(s, &err); -+ -+ /* Don't start dataplane if transport does not support notifiers. */ -+ if (!virtio_device_ioeventfd_enabled(vdev)) { -+ s->dataplane_disabled = true; -+ } -+ -+ virtio_blk_vq_aio_context_init(s, &err); - if (err != NULL) { - error_propagate(errp, err); - for (i = 0; i < conf->num_queues; i++) { -@@ -2052,7 +2053,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev) - - blk_drain(s->blk); - del_boot_device_lchs(dev, "/disk@0,0"); -- virtio_blk_data_plane_destroy(s); -+ virtio_blk_vq_aio_context_cleanup(s); - for (i = 0; i < conf->num_queues; i++) { - virtio_del_queue(vdev, i); - } --- -2.39.3 - diff --git a/kvm-virtio-blk-rename-dataplane-to-ioeventfd.patch b/kvm-virtio-blk-rename-dataplane-to-ioeventfd.patch deleted file mode 100644 index a0c0b67..0000000 --- a/kvm-virtio-blk-rename-dataplane-to-ioeventfd.patch +++ /dev/null @@ -1,307 +0,0 @@ -From ba80cdcd5604b9b9efc4682ade9828ab74ebf5e6 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Fri, 19 Jan 2024 08:57:45 -0500 -Subject: [PATCH 16/22] virtio-blk: rename dataplane to ioeventfd - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [12/17] 4230005e0d1b4629fe4540f1f63cd705e58618da (stefanha/centos-stream-qemu-kvm) - -The dataplane code is really about using ioeventfd. It's used both for -IOThreads (what we think of as dataplane) and for the core virtio-pci -code's ioeventfd feature (which is enabled by default and used when no -IOThread has been specified). Rename the code to reflect this. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240119135748.270944-4-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 3cdaf3dd4a4ca94ebabe7eab23b432f1a6c547cc) -Signed-off-by: Stefan Hajnoczi ---- - hw/block/virtio-blk.c | 78 +++++++++++++++++----------------- - include/hw/virtio/virtio-blk.h | 8 ++-- - 2 files changed, 43 insertions(+), 43 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index 4d6f9377c6..08c566946a 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -64,7 +64,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status) - iov_discard_undo(&req->inhdr_undo); - iov_discard_undo(&req->outhdr_undo); - virtqueue_push(req->vq, &req->elem, req->in_len); -- if (s->dataplane_started && !s->dataplane_disabled) { -+ if (s->ioeventfd_started && !s->ioeventfd_disabled) { - virtio_notify_irqfd(vdev, req->vq); - } else { - virtio_notify(vdev, req->vq); -@@ -1141,12 +1141,12 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) - { - VirtIOBlock *s = (VirtIOBlock *)vdev; - -- if (!s->dataplane_disabled && !s->dataplane_started) { -+ if (!s->ioeventfd_disabled && !s->ioeventfd_started) { - /* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start -- * dataplane here instead of waiting for .set_status(). -+ * ioeventfd here instead of waiting for .set_status(). - */ - virtio_device_start_ioeventfd(vdev); -- if (!s->dataplane_disabled) { -+ if (!s->ioeventfd_disabled) { - return; - } - } -@@ -1213,7 +1213,7 @@ static void virtio_blk_reset(VirtIODevice *vdev) - VirtIOBlockReq *req; - - /* Dataplane has stopped... */ -- assert(!s->dataplane_started); -+ assert(!s->ioeventfd_started); - - /* ...but requests may still be in flight. */ - blk_drain(s->blk); -@@ -1380,7 +1380,7 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) - VirtIOBlock *s = VIRTIO_BLK(vdev); - - if (!(status & (VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK))) { -- assert(!s->dataplane_started); -+ assert(!s->ioeventfd_started); - } - - if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) { -@@ -1545,7 +1545,7 @@ static void virtio_blk_resize(void *opaque) - aio_bh_schedule_oneshot(qemu_get_aio_context(), virtio_resize_cb, vdev); - } - --static void virtio_blk_data_plane_detach(VirtIOBlock *s) -+static void virtio_blk_ioeventfd_detach(VirtIOBlock *s) - { - VirtIODevice *vdev = VIRTIO_DEVICE(s); - -@@ -1555,7 +1555,7 @@ static void virtio_blk_data_plane_detach(VirtIOBlock *s) - } - } - --static void virtio_blk_data_plane_attach(VirtIOBlock *s) -+static void virtio_blk_ioeventfd_attach(VirtIOBlock *s) - { - VirtIODevice *vdev = VIRTIO_DEVICE(s); - -@@ -1570,8 +1570,8 @@ static void virtio_blk_drained_begin(void *opaque) - { - VirtIOBlock *s = opaque; - -- if (s->dataplane_started) { -- virtio_blk_data_plane_detach(s); -+ if (s->ioeventfd_started) { -+ virtio_blk_ioeventfd_detach(s); - } - } - -@@ -1580,8 +1580,8 @@ static void virtio_blk_drained_end(void *opaque) - { - VirtIOBlock *s = opaque; - -- if (s->dataplane_started) { -- virtio_blk_data_plane_attach(s); -+ if (s->ioeventfd_started) { -+ virtio_blk_ioeventfd_attach(s); - } - } - -@@ -1651,11 +1651,11 @@ static bool virtio_blk_vq_aio_context_init(VirtIOBlock *s, Error **errp) - } - - /* -- * If dataplane is (re-)enabled while the guest is running there could -+ * If ioeventfd is (re-)enabled while the guest is running there could - * be block jobs that can conflict. - */ - if (blk_op_is_blocked(conf->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { -- error_prepend(errp, "cannot start virtio-blk dataplane: "); -+ error_prepend(errp, "cannot start virtio-blk ioeventfd: "); - return false; - } - } -@@ -1688,7 +1688,7 @@ static void virtio_blk_vq_aio_context_cleanup(VirtIOBlock *s) - { - VirtIOBlkConf *conf = &s->conf; - -- assert(!s->dataplane_started); -+ assert(!s->ioeventfd_started); - - if (conf->iothread_vq_mapping_list) { - IOThreadVirtQueueMappingList *node; -@@ -1708,7 +1708,7 @@ static void virtio_blk_vq_aio_context_cleanup(VirtIOBlock *s) - } - - /* Context: BQL held */ --static int virtio_blk_data_plane_start(VirtIODevice *vdev) -+static int virtio_blk_start_ioeventfd(VirtIODevice *vdev) - { - VirtIOBlock *s = VIRTIO_BLK(vdev); - BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s))); -@@ -1718,11 +1718,11 @@ static int virtio_blk_data_plane_start(VirtIODevice *vdev) - Error *local_err = NULL; - int r; - -- if (s->dataplane_started || s->dataplane_starting) { -+ if (s->ioeventfd_started || s->ioeventfd_starting) { - return 0; - } - -- s->dataplane_starting = true; -+ s->ioeventfd_starting = true; - - /* Set up guest notifier (irq) */ - r = k->set_guest_notifiers(qbus->parent, nvqs, true); -@@ -1773,14 +1773,14 @@ static int virtio_blk_data_plane_start(VirtIODevice *vdev) - - /* - * These fields must be visible to the IOThread when it processes the -- * virtqueue, otherwise it will think dataplane has not started yet. -+ * virtqueue, otherwise it will think ioeventfd has not started yet. - * -- * Make sure ->dataplane_started is false when blk_set_aio_context() is -+ * Make sure ->ioeventfd_started is false when blk_set_aio_context() is - * called above so that draining does not cause the host notifier to be - * detached/attached prematurely. - */ -- s->dataplane_starting = false; -- s->dataplane_started = true; -+ s->ioeventfd_starting = false; -+ s->ioeventfd_started = true; - smp_wmb(); /* paired with aio_notify_accept() on the read side */ - - /* Get this show started by hooking up our callbacks */ -@@ -1812,8 +1812,8 @@ static int virtio_blk_data_plane_start(VirtIODevice *vdev) - fail_host_notifiers: - k->set_guest_notifiers(qbus->parent, nvqs, false); - fail_guest_notifiers: -- s->dataplane_disabled = true; -- s->dataplane_starting = false; -+ s->ioeventfd_disabled = true; -+ s->ioeventfd_starting = false; - return -ENOSYS; - } - -@@ -1821,7 +1821,7 @@ static int virtio_blk_data_plane_start(VirtIODevice *vdev) - * - * Context: BH in IOThread - */ --static void virtio_blk_data_plane_stop_vq_bh(void *opaque) -+static void virtio_blk_ioeventfd_stop_vq_bh(void *opaque) - { - VirtQueue *vq = opaque; - EventNotifier *host_notifier = virtio_queue_get_host_notifier(vq); -@@ -1836,7 +1836,7 @@ static void virtio_blk_data_plane_stop_vq_bh(void *opaque) - } - - /* Context: BQL held */ --static void virtio_blk_data_plane_stop(VirtIODevice *vdev) -+static void virtio_blk_stop_ioeventfd(VirtIODevice *vdev) - { - VirtIOBlock *s = VIRTIO_BLK(vdev); - BusState *qbus = qdev_get_parent_bus(DEVICE(s)); -@@ -1844,24 +1844,24 @@ static void virtio_blk_data_plane_stop(VirtIODevice *vdev) - unsigned i; - unsigned nvqs = s->conf.num_queues; - -- if (!s->dataplane_started || s->dataplane_stopping) { -+ if (!s->ioeventfd_started || s->ioeventfd_stopping) { - return; - } - - /* Better luck next time. */ -- if (s->dataplane_disabled) { -- s->dataplane_disabled = false; -- s->dataplane_started = false; -+ if (s->ioeventfd_disabled) { -+ s->ioeventfd_disabled = false; -+ s->ioeventfd_started = false; - return; - } -- s->dataplane_stopping = true; -+ s->ioeventfd_stopping = true; - - if (!blk_in_drain(s->conf.conf.blk)) { - for (i = 0; i < nvqs; i++) { - VirtQueue *vq = virtio_get_queue(vdev, i); - AioContext *ctx = s->vq_aio_context[i]; - -- aio_wait_bh_oneshot(ctx, virtio_blk_data_plane_stop_vq_bh, vq); -+ aio_wait_bh_oneshot(ctx, virtio_blk_ioeventfd_stop_vq_bh, vq); - } - } - -@@ -1886,10 +1886,10 @@ static void virtio_blk_data_plane_stop(VirtIODevice *vdev) - } - - /* -- * Set ->dataplane_started to false before draining so that host notifiers -+ * Set ->ioeventfd_started to false before draining so that host notifiers - * are not detached/attached anymore. - */ -- s->dataplane_started = false; -+ s->ioeventfd_started = false; - - /* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */ - blk_drain(s->conf.conf.blk); -@@ -1903,7 +1903,7 @@ static void virtio_blk_data_plane_stop(VirtIODevice *vdev) - /* Clean up guest notifier (irq) */ - k->set_guest_notifiers(qbus->parent, nvqs, false); - -- s->dataplane_stopping = false; -+ s->ioeventfd_stopping = false; - } - - static void virtio_blk_device_realize(DeviceState *dev, Error **errp) -@@ -2011,9 +2011,9 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) - } - qemu_coroutine_inc_pool_size(conf->num_queues * conf->queue_size / 2); - -- /* Don't start dataplane if transport does not support notifiers. */ -+ /* Don't start ioeventfd if transport does not support notifiers. */ - if (!virtio_device_ioeventfd_enabled(vdev)) { -- s->dataplane_disabled = true; -+ s->ioeventfd_disabled = true; - } - - virtio_blk_vq_aio_context_init(s, &err); -@@ -2137,8 +2137,8 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data) - vdc->reset = virtio_blk_reset; - vdc->save = virtio_blk_save_device; - vdc->load = virtio_blk_load_device; -- vdc->start_ioeventfd = virtio_blk_data_plane_start; -- vdc->stop_ioeventfd = virtio_blk_data_plane_stop; -+ vdc->start_ioeventfd = virtio_blk_start_ioeventfd; -+ vdc->stop_ioeventfd = virtio_blk_stop_ioeventfd; - } - - static const TypeInfo virtio_blk_info = { -diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h -index fecffdc303..833a9a344f 100644 ---- a/include/hw/virtio/virtio-blk.h -+++ b/include/hw/virtio/virtio-blk.h -@@ -60,10 +60,10 @@ struct VirtIOBlock { - unsigned short sector_mask; - bool original_wce; - VMChangeStateEntry *change; -- bool dataplane_disabled; -- bool dataplane_started; -- bool dataplane_starting; -- bool dataplane_stopping; -+ bool ioeventfd_disabled; -+ bool ioeventfd_started; -+ bool ioeventfd_starting; -+ bool ioeventfd_stopping; - - /* - * The AioContext for each virtqueue. The BlockDriverState will use the --- -2.39.3 - diff --git a/kvm-virtio-blk-restart-s-rq-reqs-in-vq-AioContexts.patch b/kvm-virtio-blk-restart-s-rq-reqs-in-vq-AioContexts.patch deleted file mode 100644 index 611b881..0000000 --- a/kvm-virtio-blk-restart-s-rq-reqs-in-vq-AioContexts.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 9311035821b3fea3f78c7f06ddb8a3861584f907 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Fri, 19 Jan 2024 08:57:46 -0500 -Subject: [PATCH 17/22] virtio-blk: restart s->rq reqs in vq AioContexts - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [13/17] cf5ad0352a78458ffc7588f967963f62b267fd64 (stefanha/centos-stream-qemu-kvm) - -A virtio-blk device with the iothread-vq-mapping parameter has -per-virtqueue AioContexts. It is not thread-safe to process s->rq -requests in the BlockBackend AioContext since that may be different from -the virtqueue's AioContext to which this request belongs. The code -currently races and could crash. - -Adapt virtio_blk_dma_restart_cb() to first split s->rq into per-vq lists -and then schedule a BH each vq's AioContext as necessary. This way -requests are safely processed in their vq's AioContext. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240119135748.270944-5-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 71ee0cdd14cc01a8b51aa4e9577dd0a1bb2f8e19) -Signed-off-by: Stefan Hajnoczi ---- - hw/block/virtio-blk.c | 44 ++++++++++++++++++++++++++++++++----------- - 1 file changed, 33 insertions(+), 11 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index 08c566946a..f48ce5cbb8 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -1156,16 +1156,11 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) - - static void virtio_blk_dma_restart_bh(void *opaque) - { -- VirtIOBlock *s = opaque; -+ VirtIOBlockReq *req = opaque; -+ VirtIOBlock *s = req->dev; /* we're called with at least one request */ - -- VirtIOBlockReq *req; - MultiReqBuffer mrb = {}; - -- WITH_QEMU_LOCK_GUARD(&s->rq_lock) { -- req = s->rq; -- s->rq = NULL; -- } -- - while (req) { - VirtIOBlockReq *next = req->next; - if (virtio_blk_handle_request(req, &mrb)) { -@@ -1195,16 +1190,43 @@ static void virtio_blk_dma_restart_cb(void *opaque, bool running, - RunState state) - { - VirtIOBlock *s = opaque; -+ uint16_t num_queues = s->conf.num_queues; - - if (!running) { - return; - } - -- /* Paired with dec in virtio_blk_dma_restart_bh() */ -- blk_inc_in_flight(s->conf.conf.blk); -+ /* Split the device-wide s->rq request list into per-vq request lists */ -+ g_autofree VirtIOBlockReq **vq_rq = g_new0(VirtIOBlockReq *, num_queues); -+ VirtIOBlockReq *rq; -+ -+ WITH_QEMU_LOCK_GUARD(&s->rq_lock) { -+ rq = s->rq; -+ s->rq = NULL; -+ } -+ -+ while (rq) { -+ VirtIOBlockReq *next = rq->next; -+ uint16_t idx = virtio_get_queue_index(rq->vq); -+ -+ rq->next = vq_rq[idx]; -+ vq_rq[idx] = rq; -+ rq = next; -+ } - -- aio_bh_schedule_oneshot(blk_get_aio_context(s->conf.conf.blk), -- virtio_blk_dma_restart_bh, s); -+ /* Schedule a BH to submit the requests in each vq's AioContext */ -+ for (uint16_t i = 0; i < num_queues; i++) { -+ if (!vq_rq[i]) { -+ continue; -+ } -+ -+ /* Paired with dec in virtio_blk_dma_restart_bh() */ -+ blk_inc_in_flight(s->conf.conf.blk); -+ -+ aio_bh_schedule_oneshot(s->vq_aio_context[i], -+ virtio_blk_dma_restart_bh, -+ vq_rq[i]); -+ } - } - - static void virtio_blk_reset(VirtIODevice *vdev) --- -2.39.3 - diff --git a/kvm-virtio-blk-tolerate-failure-to-set-BlockBackend-AioC.patch b/kvm-virtio-blk-tolerate-failure-to-set-BlockBackend-AioC.patch deleted file mode 100644 index 303c007..0000000 --- a/kvm-virtio-blk-tolerate-failure-to-set-BlockBackend-AioC.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 282cebc22987958d11efc76e4f6ddb9601e709d9 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Fri, 19 Jan 2024 08:57:47 -0500 -Subject: [PATCH 18/22] virtio-blk: tolerate failure to set BlockBackend - AioContext - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter -RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [14/17] edb113ce9fea0c1a88ae7b5d61c35c1981e6993f (stefanha/centos-stream-qemu-kvm) - -We no longer rely on setting the AioContext since the block layer -IO_CODE APIs can be called from any thread. Now it's just a hint to help -block jobs and other operations co-locate themselves in a thread with -the guest I/O requests. Keep going if setting the AioContext fails. - -Suggested-by: Kevin Wolf -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240119135748.270944-6-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit ea0736d7f84ead109a6b701427991828f97724c3) -Signed-off-by: Stefan Hajnoczi ---- - hw/block/virtio-blk.c | 19 +++++-------------- - 1 file changed, 5 insertions(+), 14 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index f48ce5cbb8..81de06c9f6 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -1786,11 +1786,14 @@ static int virtio_blk_start_ioeventfd(VirtIODevice *vdev) - - memory_region_transaction_commit(); - -+ /* -+ * Try to change the AioContext so that block jobs and other operations can -+ * co-locate their activity in the same AioContext. If it fails, nevermind. -+ */ - r = blk_set_aio_context(s->conf.conf.blk, s->vq_aio_context[0], - &local_err); - if (r < 0) { -- error_report_err(local_err); -- goto fail_aio_context; -+ warn_report_err(local_err); - } - - /* -@@ -1819,18 +1822,6 @@ static int virtio_blk_start_ioeventfd(VirtIODevice *vdev) - } - return 0; - -- fail_aio_context: -- memory_region_transaction_begin(); -- -- for (i = 0; i < nvqs; i++) { -- virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false); -- } -- -- memory_region_transaction_commit(); -- -- for (i = 0; i < nvqs; i++) { -- virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i); -- } - fail_host_notifiers: - k->set_guest_notifiers(qbus->parent, nvqs, false); - fail_guest_notifiers: --- -2.39.3 - diff --git a/kvm-virtio-gpu-block-migration-of-VMs-with-blob-true.patch b/kvm-virtio-gpu-block-migration-of-VMs-with-blob-true.patch deleted file mode 100644 index 1f70049..0000000 --- a/kvm-virtio-gpu-block-migration-of-VMs-with-blob-true.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 5db0b4131c56d96760b3300298f4bedab99d35cb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Wed, 6 Sep 2023 17:00:22 +0400 -Subject: [PATCH 100/101] virtio-gpu: block migration of VMs with blob=true -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Marc-André Lureau -RH-MergeRequest: 217: virtio-gpu: block migration of VMs with blob=true -RH-Jira: RHEL-7565 -RH-Commit: [1/1] f978ca697d574b1419eb027a1007c060dfb83298 - -JIRA: https://issues.redhat.com/browse/RHEL-7565 - -commit 9c549ab6895a43ad0cb33e684e11cdb0b5400897 -Author: Marc-André Lureau -Date: Wed Sep 6 17:00:22 2023 +0400 - -virtio-gpu: block migration of VMs with blob=true - -"blob" resources don't have an associated pixman image: - -#0 pixman_image_get_stride (image=0x0) at ../pixman/pixman-image.c:921 -#1 0x0000562327c25236 in virtio_gpu_save (f=0x56232bb13b00, opaque=0x56232b555a60, size=0, field=0x5623289ab6c8 <__compound_literal.3+104>, vmdesc=0x56232ab59fe0) at ../hw/display/virtio-gpu.c:1225 - -Related to: -https://bugzilla.redhat.com/show_bug.cgi?id=2236353 - -Signed-off-by: Marc-André Lureau -Acked-by: Peter Xu - -[ rhel backport - fix Error* vs Error** argument ] -Signed-off-by: Marc-André Lureau ---- - hw/display/virtio-gpu.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c -index b016d3bac8..1702190ead 100644 ---- a/hw/display/virtio-gpu.c -+++ b/hw/display/virtio-gpu.c -@@ -27,6 +27,7 @@ - #include "hw/virtio/virtio-gpu-pixman.h" - #include "hw/virtio/virtio-bus.h" - #include "hw/qdev-properties.h" -+#include "migration/blocker.h" - #include "qemu/log.h" - #include "qemu/module.h" - #include "qapi/error.h" -@@ -41,6 +42,8 @@ virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id, - - static void virtio_gpu_reset_bh(void *opaque); - -+static Error *blob_mig_blocker; -+ - void virtio_gpu_update_cursor_data(VirtIOGPU *g, - struct virtio_gpu_scanout *s, - uint32_t resource_id) -@@ -1452,6 +1455,14 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) - error_setg(errp, "blobs and virgl are not compatible (yet)"); - return; - } -+ -+ if (!blob_mig_blocker) { -+ error_setg(&blob_mig_blocker, -+ "virtio-gpu blob VMs are currently not migratable."); -+ } -+ if (migrate_add_blocker(&blob_mig_blocker, errp)) { -+ return; -+ } - } - - if (!virtio_gpu_base_device_realize(qdev, -@@ -1478,6 +1489,9 @@ static void virtio_gpu_device_unrealize(DeviceState *qdev) - { - VirtIOGPU *g = VIRTIO_GPU(qdev); - -+ if (virtio_gpu_blob_enabled(g->parent_obj.conf)) { -+ migrate_del_blocker(&blob_mig_blocker); -+ } - g_clear_pointer(&g->ctrl_bh, qemu_bh_delete); - g_clear_pointer(&g->cursor_bh, qemu_bh_delete); - g_clear_pointer(&g->reset_bh, qemu_bh_delete); --- -2.39.3 - diff --git a/kvm-virtio-mem-default-enable-dynamic-memslots.patch b/kvm-virtio-mem-default-enable-dynamic-memslots.patch deleted file mode 100644 index 6ad1c98..0000000 --- a/kvm-virtio-mem-default-enable-dynamic-memslots.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 94bccae527f1ab8328cc7692532046d700e2ca71 Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Mon, 5 Feb 2024 19:27:07 +0100 -Subject: [PATCH 22/22] virtio-mem: default-enable "dynamic-memslots" - -RH-Author: David Hildenbrand -RH-MergeRequest: 220: virtio-mem: default-enable "dynamic-memslots" -RH-Jira: RHEL-24045 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] d9a60acd7de1d8703ea3ca938e388e19f31f5347 - -JIRA: https://issues.redhat.com/browse/RHEL-24045 -Upstream: RHEL only - -We only support selected vhost-user devices in combination with -virtio-mem in RHEL. One devices that works well is virtiofsd, devices that -are currently incompatible include DPDK and SPDK. - -The vhost devices we support must be compatible with the dynamic-memslot -feature (i.e., support at least 509 memslots, support dynamically adding/ -removing memslots), such that setting "dynamic-memslots=on" will work a -expected and not make certain QEMU commandlines or hotplug of vhost-user -devices bail out. - -Let's set "dynamic-memslots=on" starting with RHEL 9.4, so we -get the benefits (i.e., reduced metadata consumption in KVM, majority of -unplugged memory being inaccessible) as default. - -When wanting to run virtio-mem with incompatible vhost-user devices, it -might just work (if the vhost-user device is created before the -virtio-mem device), or the feature can be manually disabled by -specifying "dynamic-memslots=off". - -Signed-off-by: David Hildenbrand ---- - hw/core/machine.c | 2 ++ - hw/virtio/virtio-mem.c | 3 ++- - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 446601ee30..309f6ba685 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -78,6 +78,8 @@ GlobalProperty hw_compat_rhel_9_4[] = { - { "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }, - /* hw_compat_rhel_9_4 from hw_compat_8_1 */ - { "igb", "x-pcie-flr-init", "off" }, -+ /* hw_compat_rhel_9_4 jira RHEL-24045 */ -+ { "virtio-mem", "dynamic-memslots", "off" }, - }; - const size_t hw_compat_rhel_9_4_len = G_N_ELEMENTS(hw_compat_rhel_9_4); - -diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c -index 75ee38aa46..00ca91e8fe 100644 ---- a/hw/virtio/virtio-mem.c -+++ b/hw/virtio/virtio-mem.c -@@ -1696,8 +1696,9 @@ static Property virtio_mem_properties[] = { - #endif - DEFINE_PROP_BOOL(VIRTIO_MEM_EARLY_MIGRATION_PROP, VirtIOMEM, - early_migration, true), -+ /* RHEL: default-enable "dynamic-memslots" (jira RHEL-24045) */ - DEFINE_PROP_BOOL(VIRTIO_MEM_DYNAMIC_MEMSLOTS_PROP, VirtIOMEM, -- dynamic_memslots, false), -+ dynamic_memslots, true), - DEFINE_PROP_END_OF_LIST(), - }; - --- -2.39.3 - diff --git a/kvm-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch b/kvm-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch deleted file mode 100644 index b8066b2..0000000 --- a/kvm-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch +++ /dev/null @@ -1,78 +0,0 @@ -From da3a5afa41790ae913d41cfcdc3c6a8731ae3fe8 Mon Sep 17 00:00:00 2001 -From: Hanna Czenczek -Date: Fri, 2 Feb 2024 16:31:56 +0100 -Subject: [PATCH 1/6] virtio-scsi: Attach event vq notifier with no_poll - -RH-Author: Hanna Czenczek -RH-MergeRequest: 223: virtio: Re-enable notifications after drain -RH-Jira: RHEL-3934 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [1/3] d29b461a0a4b584af0ee80fb3f9e45c92ea88eb0 (hreitz/qemu-kvm-c-9-s) - -As of commit 38738f7dbbda90fbc161757b7f4be35b52205552 ("virtio-scsi: -don't waste CPU polling the event virtqueue"), we only attach an io_read -notifier for the virtio-scsi event virtqueue instead, and no polling -notifiers. During operation, the event virtqueue is typically -non-empty, but none of the buffers are intended to be used immediately. -Instead, they only get used when certain events occur. Therefore, it -makes no sense to continuously poll it when non-empty, because it is -supposed to be and stay non-empty. - -We do this by using virtio_queue_aio_attach_host_notifier_no_poll() -instead of virtio_queue_aio_attach_host_notifier() for the event -virtqueue. - -Commit 766aa2de0f29b657148e04599320d771c36fd126 ("virtio-scsi: implement -BlockDevOps->drained_begin()") however has virtio_scsi_drained_end() use -virtio_queue_aio_attach_host_notifier() for all virtqueues, including -the event virtqueue. This can lead to it being polled again, undoing -the benefit of commit 38738f7dbbda90fbc161757b7f4be35b52205552. - -Fix it by using virtio_queue_aio_attach_host_notifier_no_poll() for the -event virtqueue. - -Reported-by: Fiona Ebner -Fixes: 766aa2de0f29b657148e04599320d771c36fd126 - ("virtio-scsi: implement BlockDevOps->drained_begin()") -Reviewed-by: Stefan Hajnoczi -Tested-by: Fiona Ebner -Reviewed-by: Fiona Ebner -Signed-off-by: Hanna Czenczek -Message-ID: <20240202153158.788922-2-hreitz@redhat.com> -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit c42c3833e0cfdf2b80fb3ca410acfd392b6874ab) ---- - hw/scsi/virtio-scsi.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c -index ca365a70e9..9943186917 100644 ---- a/hw/scsi/virtio-scsi.c -+++ b/hw/scsi/virtio-scsi.c -@@ -1149,6 +1149,7 @@ static void virtio_scsi_drained_begin(SCSIBus *bus) - static void virtio_scsi_drained_end(SCSIBus *bus) - { - VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); -+ VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); - VirtIODevice *vdev = VIRTIO_DEVICE(s); - uint32_t total_queues = VIRTIO_SCSI_VQ_NUM_FIXED + - s->parent_obj.conf.num_queues; -@@ -1166,7 +1167,11 @@ static void virtio_scsi_drained_end(SCSIBus *bus) - - for (uint32_t i = 0; i < total_queues; i++) { - VirtQueue *vq = virtio_get_queue(vdev, i); -- virtio_queue_aio_attach_host_notifier(vq, s->ctx); -+ if (vq == vs->event_vq) { -+ virtio_queue_aio_attach_host_notifier_no_poll(vq, s->ctx); -+ } else { -+ virtio_queue_aio_attach_host_notifier(vq, s->ctx); -+ } - } - } - --- -2.39.3 - diff --git a/kvm-virtio-scsi-don-t-lock-AioContext-around-virtio_queu.patch b/kvm-virtio-scsi-don-t-lock-AioContext-around-virtio_queu.patch deleted file mode 100644 index 9ad8fdf..0000000 --- a/kvm-virtio-scsi-don-t-lock-AioContext-around-virtio_queu.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 1ee3f919a51135a0798a14c734ca80d74d30025d Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 4 Dec 2023 11:42:57 -0500 -Subject: [PATCH 078/101] virtio-scsi: don't lock AioContext around - virtio_queue_aio_attach_host_notifier() - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [9/26] 5e1179e617d05bf765b285ba42393ec1ddbeba28 (kmwolf/centos-qemu-kvm) - -virtio_queue_aio_attach_host_notifier() does not require the AioContext -lock. Stop taking the lock and add an explicit smp_wmb() because we were -relying on the implicit barrier in the AioContext lock before. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Reviewed-by: Kevin Wolf -Message-ID: <20231204164259.1515217-3-stefanha@redhat.com> -Signed-off-by: Kevin Wolf ---- - hw/scsi/virtio-scsi-dataplane.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - -diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c -index 1e684beebe..135e23fe54 100644 ---- a/hw/scsi/virtio-scsi-dataplane.c -+++ b/hw/scsi/virtio-scsi-dataplane.c -@@ -149,23 +149,17 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev) - - memory_region_transaction_commit(); - -- /* -- * These fields are visible to the IOThread so we rely on implicit barriers -- * in aio_context_acquire() on the write side and aio_notify_accept() on -- * the read side. -- */ - s->dataplane_starting = false; - s->dataplane_started = true; -+ smp_wmb(); /* paired with aio_notify_accept() */ - - if (s->bus.drain_count == 0) { -- aio_context_acquire(s->ctx); - virtio_queue_aio_attach_host_notifier(vs->ctrl_vq, s->ctx); - virtio_queue_aio_attach_host_notifier_no_poll(vs->event_vq, s->ctx); - - for (i = 0; i < vs->conf.num_queues; i++) { - virtio_queue_aio_attach_host_notifier(vs->cmd_vqs[i], s->ctx); - } -- aio_context_release(s->ctx); - } - return 0; - --- -2.39.3 - diff --git a/kvm-virtio-scsi-replace-AioContext-lock-with-tmf_bh_lock.patch b/kvm-virtio-scsi-replace-AioContext-lock-with-tmf_bh_lock.patch deleted file mode 100644 index 2654cb7..0000000 --- a/kvm-virtio-scsi-replace-AioContext-lock-with-tmf_bh_lock.patch +++ /dev/null @@ -1,173 +0,0 @@ -From c2d7633ead6e19d4b6af5552ca907ae071b8734b Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 5 Dec 2023 13:19:58 -0500 -Subject: [PATCH 081/101] virtio-scsi: replace AioContext lock with tmf_bh_lock - -RH-Author: Kevin Wolf -RH-MergeRequest: 214: Remove AioContext lock -RH-Jira: RHEL-15965 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [12/26] 8fb375bfd72a491d47321c78078577071a4e90fb (kmwolf/centos-qemu-kvm) - -Protect the Task Management Function BH state with a lock. The TMF BH -runs in the main loop thread. An IOThread might process a TMF at the -same time as the TMF BH is running. Therefore tmf_bh_list and tmf_bh -must be protected by a lock. - -Run TMF request completion in the IOThread using aio_wait_bh_oneshot(). -This avoids more locking to protect the virtqueue and SCSI layer state. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Reviewed-by: Kevin Wolf -Message-ID: <20231205182011.1976568-2-stefanha@redhat.com> -Signed-off-by: Kevin Wolf ---- - hw/scsi/virtio-scsi.c | 62 ++++++++++++++++++++++----------- - include/hw/virtio/virtio-scsi.h | 3 +- - 2 files changed, 43 insertions(+), 22 deletions(-) - -diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c -index 9c751bf296..4f8d35facc 100644 ---- a/hw/scsi/virtio-scsi.c -+++ b/hw/scsi/virtio-scsi.c -@@ -123,6 +123,30 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req) - virtio_scsi_free_req(req); - } - -+static void virtio_scsi_complete_req_bh(void *opaque) -+{ -+ VirtIOSCSIReq *req = opaque; -+ -+ virtio_scsi_complete_req(req); -+} -+ -+/* -+ * Called from virtio_scsi_do_one_tmf_bh() in main loop thread. The main loop -+ * thread cannot touch the virtqueue since that could race with an IOThread. -+ */ -+static void virtio_scsi_complete_req_from_main_loop(VirtIOSCSIReq *req) -+{ -+ VirtIOSCSI *s = req->dev; -+ -+ if (!s->ctx || s->ctx == qemu_get_aio_context()) { -+ /* No need to schedule a BH when there is no IOThread */ -+ virtio_scsi_complete_req(req); -+ } else { -+ /* Run request completion in the IOThread */ -+ aio_wait_bh_oneshot(s->ctx, virtio_scsi_complete_req_bh, req); -+ } -+} -+ - static void virtio_scsi_bad_req(VirtIOSCSIReq *req) - { - virtio_error(VIRTIO_DEVICE(req->dev), "wrong size for virtio-scsi headers"); -@@ -338,10 +362,7 @@ static void virtio_scsi_do_one_tmf_bh(VirtIOSCSIReq *req) - - out: - object_unref(OBJECT(d)); -- -- virtio_scsi_acquire(s); -- virtio_scsi_complete_req(req); -- virtio_scsi_release(s); -+ virtio_scsi_complete_req_from_main_loop(req); - } - - /* Some TMFs must be processed from the main loop thread */ -@@ -354,18 +375,16 @@ static void virtio_scsi_do_tmf_bh(void *opaque) - - GLOBAL_STATE_CODE(); - -- virtio_scsi_acquire(s); -+ WITH_QEMU_LOCK_GUARD(&s->tmf_bh_lock) { -+ QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) { -+ QTAILQ_REMOVE(&s->tmf_bh_list, req, next); -+ QTAILQ_INSERT_TAIL(&reqs, req, next); -+ } - -- QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) { -- QTAILQ_REMOVE(&s->tmf_bh_list, req, next); -- QTAILQ_INSERT_TAIL(&reqs, req, next); -+ qemu_bh_delete(s->tmf_bh); -+ s->tmf_bh = NULL; - } - -- qemu_bh_delete(s->tmf_bh); -- s->tmf_bh = NULL; -- -- virtio_scsi_release(s); -- - QTAILQ_FOREACH_SAFE(req, &reqs, next, tmp) { - QTAILQ_REMOVE(&reqs, req, next); - virtio_scsi_do_one_tmf_bh(req); -@@ -379,8 +398,7 @@ static void virtio_scsi_reset_tmf_bh(VirtIOSCSI *s) - - GLOBAL_STATE_CODE(); - -- virtio_scsi_acquire(s); -- -+ /* Called after ioeventfd has been stopped, so tmf_bh_lock is not needed */ - if (s->tmf_bh) { - qemu_bh_delete(s->tmf_bh); - s->tmf_bh = NULL; -@@ -393,19 +411,19 @@ static void virtio_scsi_reset_tmf_bh(VirtIOSCSI *s) - req->resp.tmf.response = VIRTIO_SCSI_S_TARGET_FAILURE; - virtio_scsi_complete_req(req); - } -- -- virtio_scsi_release(s); - } - - static void virtio_scsi_defer_tmf_to_bh(VirtIOSCSIReq *req) - { - VirtIOSCSI *s = req->dev; - -- QTAILQ_INSERT_TAIL(&s->tmf_bh_list, req, next); -+ WITH_QEMU_LOCK_GUARD(&s->tmf_bh_lock) { -+ QTAILQ_INSERT_TAIL(&s->tmf_bh_list, req, next); - -- if (!s->tmf_bh) { -- s->tmf_bh = qemu_bh_new(virtio_scsi_do_tmf_bh, s); -- qemu_bh_schedule(s->tmf_bh); -+ if (!s->tmf_bh) { -+ s->tmf_bh = qemu_bh_new(virtio_scsi_do_tmf_bh, s); -+ qemu_bh_schedule(s->tmf_bh); -+ } - } - } - -@@ -1235,6 +1253,7 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp) - Error *err = NULL; - - QTAILQ_INIT(&s->tmf_bh_list); -+ qemu_mutex_init(&s->tmf_bh_lock); - - virtio_scsi_common_realize(dev, - virtio_scsi_handle_ctrl, -@@ -1277,6 +1296,7 @@ static void virtio_scsi_device_unrealize(DeviceState *dev) - - qbus_set_hotplug_handler(BUS(&s->bus), NULL); - virtio_scsi_common_unrealize(dev); -+ qemu_mutex_destroy(&s->tmf_bh_lock); - } - - static Property virtio_scsi_properties[] = { -diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h -index 779568ab5d..da8cb928d9 100644 ---- a/include/hw/virtio/virtio-scsi.h -+++ b/include/hw/virtio/virtio-scsi.h -@@ -85,8 +85,9 @@ struct VirtIOSCSI { - - /* - * TMFs deferred to main loop BH. These fields are protected by -- * virtio_scsi_acquire(). -+ * tmf_bh_lock. - */ -+ QemuMutex tmf_bh_lock; - QEMUBH *tmf_bh; - QTAILQ_HEAD(, VirtIOSCSIReq) tmf_bh_list; - --- -2.39.3 - diff --git a/kvm-x86-rhel-9.2.0-machine-type-compat-fix.patch b/kvm-x86-rhel-9.2.0-machine-type-compat-fix.patch deleted file mode 100644 index a8bf6ac..0000000 --- a/kvm-x86-rhel-9.2.0-machine-type-compat-fix.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 2932c8de175fadeed4bb7c1024724cbabc53f6d5 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Mon, 19 Feb 2024 02:37:27 -0500 -Subject: [PATCH 6/6] x86: rhel 9.2.0 machine type compat fix - -RH-Author: Sebastian Ott -RH-MergeRequest: 342: Draft: x86: rhel 9.2.0 machine type compat fix (RHEL) -RH-Jira: RHEL-17068 -RH-Acked-by: Thomas Huth -RH-Commit: [23/23] 658dda965f34119de300eef26155f47b1b3fa7f1 - -Fix up the compatibility for 9.2.0 and older. - -Signed-off-by: Sebastian Ott's avatarSebastian Ott ---- - hw/i386/pc_piix.c | 2 ++ - hw/i386/pc_q35.c | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 44038391fb..09d02cc91f 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -1023,6 +1023,8 @@ static void pc_machine_rhel760_options(MachineClass *m) - pcmc->enforce_amd_1tb_hole = false; - /* From pc_i440fx_8_0_machine_options() */ - pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32; -+ /* From pc_i440fx_8_1_machine_options() */ -+ pcmc->broken_32bit_mem_addr_check = true; - /* Introduced in QEMU 8.2 */ - pcmc->default_south_bridge = TYPE_PIIX3_DEVICE; - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 6387df97c8..c6967e1846 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -759,6 +759,8 @@ static void pc_q35_machine_rhel920_options(MachineClass *m) - - /* From pc_q35_8_0_machine_options() */ - pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32; -+ /* From pc_q35_8_1_machine_options() */ -+ pcmc->broken_32bit_mem_addr_check = true; - - compat_props_add(m->compat_props, hw_compat_rhel_9_4, - hw_compat_rhel_9_4_len); --- -2.39.3 - diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 973e9a2..aee8f37 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -148,8 +148,8 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm -Version: 8.2.0 -Release: 11%{?rcrel}%{?dist}%{?cc_suffix} +Version: 9.0.0 +Release: 1%{?rcrel}%{?dist}%{?cc_suffix} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -186,430 +186,8 @@ Patch0012: 0012-vfio-cap-number-of-devices-that-can-be-assigned.patch Patch0013: 0013-Add-support-statement-to-help-output.patch Patch0014: 0014-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch Patch0015: 0015-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch -Patch0016: 0016-Introduce-RHEL-9.4.0-qemu-kvm-machine-type-for-aarch.patch -# For RHEL-17168 - Introduce virt-rhel9.4.0 arm-virt machine type [aarch64] -Patch17: kvm-hw-arm-virt-Fix-compats.patch -# For RHEL-19738 - Enable properties allowing to disable high memory regions -Patch18: kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch19: kvm-vfio-Introduce-base-object-for-VFIOContainer-and-tar.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch20: kvm-vfio-container-Introduce-a-empty-VFIOIOMMUOps.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch21: kvm-vfio-container-Switch-to-dma_map-unmap-API.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch22: kvm-vfio-common-Introduce-vfio_container_init-destroy-he.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch23: kvm-vfio-common-Move-giommu_list-in-base-container.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch24: kvm-vfio-container-Move-space-field-to-base-container.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch25: kvm-vfio-container-Switch-to-IOMMU-BE-set_dirty_page_tra.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch26: kvm-vfio-container-Move-per-container-device-list-in-bas.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch27: kvm-vfio-container-Convert-functions-to-base-container.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch28: kvm-vfio-container-Move-pgsizes-and-dma_max_mappings-to-.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch29: kvm-vfio-container-Move-vrdl_list-to-base-container.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch30: kvm-vfio-container-Move-listener-to-base-container.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch31: kvm-vfio-container-Move-dirty_pgsizes-and-max_dirty_bitm.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch32: kvm-vfio-container-Move-iova_ranges-to-base-container.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch33: kvm-vfio-container-Implement-attach-detach_device.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch34: kvm-vfio-spapr-Introduce-spapr-backend-and-target-interf.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch35: kvm-vfio-spapr-switch-to-spapr-IOMMU-BE-add-del_section_.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch36: kvm-vfio-spapr-Move-prereg_listener-into-spapr-container.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch37: kvm-vfio-spapr-Move-hostwin_list-into-spapr-container.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch38: kvm-backends-iommufd-Introduce-the-iommufd-object.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch39: kvm-util-char_dev-Add-open_cdev.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch40: kvm-vfio-common-return-early-if-space-isn-t-empty.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch41: kvm-vfio-iommufd-Implement-the-iommufd-backend.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch42: kvm-vfio-iommufd-Relax-assert-check-for-iommufd-backend.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch43: kvm-vfio-iommufd-Add-support-for-iova_ranges-and-pgsizes.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch44: kvm-vfio-pci-Extract-out-a-helper-vfio_pci_get_pci_hot_r.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch45: kvm-vfio-pci-Introduce-a-vfio-pci-hot-reset-interface.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch46: kvm-vfio-iommufd-Enable-pci-hot-reset-through-iommufd-cd.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch47: kvm-vfio-pci-Allow-the-selection-of-a-given-iommu-backen.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch48: kvm-vfio-pci-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch49: kvm-vfio-platform-Allow-the-selection-of-a-given-iommu-b.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch50: kvm-vfio-platform-Make-vfio-cdev-pre-openable-by-passing.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch51: kvm-vfio-ap-Allow-the-selection-of-a-given-iommu-backend.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch52: kvm-vfio-ap-Make-vfio-cdev-pre-openable-by-passing-a-fil.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch53: kvm-vfio-ccw-Allow-the-selection-of-a-given-iommu-backen.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch54: kvm-vfio-ccw-Make-vfio-cdev-pre-openable-by-passing-a-fi.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch55: kvm-vfio-Make-VFIOContainerBase-poiner-parameter-const-i.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch56: kvm-hw-arm-Activate-IOMMUFD-for-virt-machines.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch57: kvm-kconfig-Activate-IOMMUFD-for-s390x-machines.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch58: kvm-hw-i386-Activate-IOMMUFD-for-q35-machines.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch59: kvm-vfio-pci-Move-VFIODevice-initializations-in-vfio_ins.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch60: kvm-vfio-platform-Move-VFIODevice-initializations-in-vfi.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch61: kvm-vfio-ap-Move-VFIODevice-initializations-in-vfio_ap_i.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch62: kvm-vfio-ccw-Move-VFIODevice-initializations-in-vfio_ccw.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch63: kvm-vfio-Introduce-a-helper-function-to-initialize-VFIOD.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch64: kvm-docs-devel-Add-VFIO-iommufd-backend-documentation.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch65: kvm-hw-ppc-Kconfig-Imply-VFIO_PCI.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch66: kvm-vfio-spapr-Extend-VFIOIOMMUOps-with-a-release-handle.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch67: kvm-vfio-container-Introduce-vfio_legacy_setup-for-furth.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch68: kvm-vfio-container-Initialize-VFIOIOMMUOps-under-vfio_in.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch69: kvm-vfio-container-Introduce-a-VFIOIOMMU-QOM-interface.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch70: kvm-vfio-container-Introduce-a-VFIOIOMMU-legacy-QOM-inte.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch71: kvm-vfio-container-Intoduce-a-new-VFIOIOMMUClass-setup-h.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch72: kvm-vfio-spapr-Introduce-a-sPAPR-VFIOIOMMU-QOM-interface.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch73: kvm-vfio-iommufd-Introduce-a-VFIOIOMMU-iommufd-QOM-inter.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch74: kvm-vfio-spapr-Only-compile-sPAPR-IOMMU-support-when-nee.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch75: kvm-vfio-iommufd-Remove-CONFIG_IOMMUFD-usage.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch76: kvm-vfio-container-Replace-basename-with-g_path_get_base.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch77: kvm-hw-vfio-fix-iteration-over-global-VFIODevice-list.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch78: kvm-vfio-iommufd-Remove-the-use-of-stat-to-check-file-ex.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch79: kvm-vfio-container-Rename-vfio_init_container-to-vfio_se.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch80: kvm-vfio-migration-Add-helper-function-to-set-state-or-r.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch81: kvm-backends-iommufd-Remove-check-on-number-of-backend-u.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch82: kvm-backends-iommufd-Remove-mutex.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch83: kvm-Compile-IOMMUFD-object-on-aarch64.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch84: kvm-Compile-IOMMUFD-on-s390x.patch -# For RHEL-19302 - NVIDIA:Grace-Hopper Backport QEMU IOMMUFD Backend -# For RHEL-21057 - Request backport of 9353b6da430f90e47f352dbf6dc31120c8914da6 -Patch85: kvm-Compile-IOMMUFD-on-x86_64.patch -# For RHEL-18212 - [RHEL9][Secure-execution][s390x] The error message is not clear when boot up a SE guest with wrong encryption -Patch86: kvm-target-s390x-kvm-pv-Provide-some-more-useful-informa.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch87: kvm-nbd-server-avoid-per-NBDRequest-nbd_client_get-put.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch88: kvm-nbd-server-only-traverse-NBDExport-clients-from-main.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch89: kvm-nbd-server-introduce-NBDClient-lock-to-protect-field.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch90: kvm-block-file-posix-set-up-Linux-AIO-and-io_uring-in-th.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch91: kvm-virtio-blk-add-lock-to-protect-s-rq.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch92: kvm-virtio-blk-don-t-lock-AioContext-in-the-completion-c.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch93: kvm-virtio-blk-don-t-lock-AioContext-in-the-submission-c.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch94: kvm-scsi-only-access-SCSIDevice-requests-from-one-thread.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch95: kvm-virtio-scsi-don-t-lock-AioContext-around-virtio_queu.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch96: kvm-scsi-don-t-lock-AioContext-in-I-O-code-path.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch97: kvm-dma-helpers-don-t-lock-AioContext-in-dma_blk_cb.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch98: kvm-virtio-scsi-replace-AioContext-lock-with-tmf_bh_lock.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch99: kvm-scsi-assert-that-callbacks-run-in-the-correct-AioCon.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch100: kvm-tests-remove-aio_context_acquire-tests.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch101: kvm-aio-make-aio_context_acquire-aio_context_release-a-n.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch102: kvm-graph-lock-remove-AioContext-locking.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch103: kvm-block-remove-AioContext-locking.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch104: kvm-block-remove-bdrv_co_lock.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch105: kvm-scsi-remove-AioContext-locking.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch106: kvm-aio-wait-draw-equivalence-between-AIO_WAIT_WHILE-and.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch107: kvm-aio-remove-aio_context_acquire-aio_context_release-A.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch108: kvm-docs-remove-AioContext-lock-from-IOThread-docs.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch109: kvm-scsi-remove-outdated-AioContext-lock-comment.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch110: kvm-job-remove-outdated-AioContext-locking-comments.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch111: kvm-block-remove-outdated-AioContext-locking-comments.patch -# For RHEL-15965 - [qemu-kvm] Remove AioContext lock (no response with QMP command block_resize) -Patch112: kvm-block-coroutine-wrapper-use-qemu_get_current_aio_con.patch -# For RHEL-21169 - [s390x] VM fails to start with ISM passed through QEMU 8.2 -Patch113: kvm-s390x-pci-avoid-double-enable-disable-of-aif.patch -# For RHEL-21169 - [s390x] VM fails to start with ISM passed through QEMU 8.2 -Patch114: kvm-s390x-pci-refresh-fh-before-disabling-aif.patch -# For RHEL-21169 - [s390x] VM fails to start with ISM passed through QEMU 8.2 -Patch115: kvm-s390x-pci-drive-ISM-reset-from-subsystem-reset.patch -# For RHEL-21570 - Critical performance degradation for input devices in virtio vnc session -Patch116: kvm-include-ui-rect.h-fix-qemu_rect_init-mis-assignment.patch -# For RHEL-7565 - qemu crashed when migrate guest with blob resources enabled -Patch117: kvm-virtio-gpu-block-migration-of-VMs-with-blob-true.patch -# For RHEL-21293 - [emulated igb] Failed to set up TRIGGER eventfd signaling for interrupt INTX-0: VFIO_DEVICE_SET_IRQS failure: Invalid argument -Patch118: kvm-vfio-pci-Clear-MSI-X-IRQ-index-always.patch -# For RHEL-20341 - memory-device size alignment check invalid in QEMU 8.2 -Patch119: kvm-hv-balloon-use-get_min_alignment-to-express-32-GiB-a.patch -# For RHEL-20341 - memory-device size alignment check invalid in QEMU 8.2 -Patch120: kvm-memory-device-reintroduce-memory-region-size-check.patch -# For RHEL-24593 - qemu crash blk_get_aio_context(BlockBackend *): Assertion `ctx == blk->ctx' when repeatedly hotplug/unplug disk -Patch121: kvm-block-backend-Allow-concurrent-context-changes.patch -# For RHEL-24593 - qemu crash blk_get_aio_context(BlockBackend *): Assertion `ctx == blk->ctx' when repeatedly hotplug/unplug disk -Patch122: kvm-scsi-Await-request-purging.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch123: kvm-string-output-visitor-show-structs-as-omitted.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch124: kvm-string-output-visitor-Fix-pseudo-struct-handling.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch125: kvm-qdev-properties-alias-all-object-class-properties.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch126: kvm-qdev-add-IOThreadVirtQueueMappingList-property-type.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch127: kvm-virtio-blk-add-iothread-vq-mapping-parameter.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch128: kvm-virtio-blk-Fix-potential-nullpointer-read-access-in-.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch129: kvm-iotests-add-filter_qmp_generated_node_ids.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch130: kvm-iotests-port-141-to-Python-for-reliable-QMP-testing.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch131: kvm-monitor-only-run-coroutine-commands-in-qemu_aio_cont.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch132: kvm-virtio-blk-move-dataplane-code-into-virtio-blk.c.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch133: kvm-virtio-blk-rename-dataplane-create-destroy-functions.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch134: kvm-virtio-blk-rename-dataplane-to-ioeventfd.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch135: kvm-virtio-blk-restart-s-rq-reqs-in-vq-AioContexts.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch136: kvm-virtio-blk-tolerate-failure-to-set-BlockBackend-AioC.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch137: kvm-virtio-blk-always-set-ioeventfd-during-startup.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch138: kvm-tests-unit-Bump-test-replication-timeout-to-60-secon.patch -# For RHEL-17369 - [nfv virt][rt][post-copy migration] qemu-kvm: ../block/qcow2.c:5263: ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *, Error **): Assertion `false' failed. -# For RHEL-20764 - [qemu-kvm] Enable qemu multiqueue block layer support -# For RHEL-7356 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-9] -Patch139: kvm-iotests-iothreads-stream-Use-the-right-TimeoutError.patch -# For RHEL-24045 - QEMU: default-enable dynamically using multiple memslots for virtio-mem -Patch140: kvm-virtio-mem-default-enable-dynamic-memslots.patch -# For RHEL-3934 - [qemu-kvm] Failed on repeatedly hotplug/unplug disk iothread enabled -Patch141: kvm-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch -# For RHEL-3934 - [qemu-kvm] Failed on repeatedly hotplug/unplug disk iothread enabled -Patch142: kvm-virtio-Re-enable-notifications-after-drain.patch -# For RHEL-3934 - [qemu-kvm] Failed on repeatedly hotplug/unplug disk iothread enabled -Patch143: kvm-virtio-blk-Use-ioeventfd_attach-in-start_ioeventfd.patch -# For RHEL-15394 - virtio-blk: qemu hang on "no response on QMP query-status" when write data to disk without enough space -Patch144: kvm-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch -# For RHEL-24988 - Mark virt-rhel9.{0,2}.0 machine types as deprecated -Patch145: kvm-hw-arm-virt-deprecate-virt-rhel9.-0-2-.0-machine-typ.patch -# For RHEL-17068 - Check/fix machine type compatibility for qemu-kvm 8.2.0 [x86_64] -Patch146: kvm-x86-rhel-9.2.0-machine-type-compat-fix.patch -# For RHEL-26049 - When max vcpu is greater than or equal to 246, qemu unable to init event notifier -Patch147: kvm-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch -# For RHEL-24614 - [RHEL9][chardev][s390x] qemu hit core dump while using TLS server from host to guest -Patch148: kvm-chardev-char-socket-Fix-TLS-io-channels-sending-too-.patch -# For RHEL-19629 - CVE-2023-6683 qemu-kvm: QEMU: VNC: NULL pointer dereference in qemu_clipboard_request() [rhel-9] -Patch149: kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch -# For RHEL-19629 - CVE-2023-6683 qemu-kvm: QEMU: VNC: NULL pointer dereference in qemu_clipboard_request() [rhel-9] -Patch150: kvm-ui-clipboard-add-asserts-for-update-and-request.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch151: kvm-hw-i386-pc-Defer-smbios_set_defaults-to-machine_done.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch152: kvm-Implement-base-of-SMBIOS-type-9-descriptor.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch153: kvm-Implement-SMBIOS-type-9-v2.6.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch154: kvm-smbios-cleanup-smbios_get_tables-from-legacy-handlin.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch155: kvm-smbios-get-rid-of-smbios_smp_sockets-global.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch156: kvm-smbios-get-rid-of-smbios_legacy-global.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch157: kvm-smbios-avoid-mangling-user-provided-tables.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch158: kvm-smbios-don-t-check-type4-structures-in-legacy-mode.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch159: kvm-smbios-add-smbios_add_usr_blob_size-helper.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch160: kvm-smbios-rename-expose-structures-bitmaps-used-by-both.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch161: kvm-smbios-build-legacy-mode-code-only-for-pc-machine.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch162: kvm-smbios-handle-errors-consistently.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch163: kvm-smbios-get-rid-of-global-smbios_ep_type.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch164: kvm-smbios-clear-smbios_type4_count-before-building-tabl.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch165: kvm-smbios-extend-smbios-entry-point-type-with-auto-valu.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch166: kvm-smbios-in-case-of-entry-point-is-auto-try-to-build-v.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch167: kvm-smbios-error-out-when-building-type-4-table-is-not-p.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch168: kvm-pc-q35-set-SMBIOS-entry-point-type-to-auto-by-defaul.patch -# For RHEL-28125 - RHEL9.4 - KVM : Live migration of guest with multiple qcow devices remains incomplete. -Patch169: kvm-mirror-Don-t-call-job_pause_point-under-graph-lock.patch -# For RHEL-28125 - RHEL9.4 - KVM : Live migration of guest with multiple qcow devices remains incomplete. -Patch170: kvm-nbd-server-Fix-race-in-draining-the-export.patch -# For RHEL-28125 - RHEL9.4 - KVM : Live migration of guest with multiple qcow devices remains incomplete. -Patch171: kvm-iotests-Add-test-for-reset-AioContext-switches-with-.patch -# For RHEL-21705 - pc-q35-rhel9.4.0 does not provide proper computer information -Patch172: kvm-pc-smbios-fixup-manufacturer-product-version-to-matc.patch -# For RHEL-24614 - [RHEL9][chardev] qemu hit core dump while using TLS server from host to guest -Patch173: kvm-chardev-lower-priority-of-the-HUP-GSource-in-socket-.patch -# For RHEL-24614 - [RHEL9][chardev] qemu hit core dump while using TLS server from host to guest -Patch174: kvm-Revert-chardev-char-socket-Fix-TLS-io-channels-sendi.patch -# For RHEL-24614 - [RHEL9][chardev] qemu hit core dump while using TLS server from host to guest -Patch175: kvm-Revert-chardev-use-a-child-source-for-qio-input-sour.patch -# For RHEL-28947 - Qemu crashing with "failed to set up stack guard page: Cannot allocate memory" -Patch176: kvm-coroutine-cap-per-thread-local-pool-size.patch -# For RHEL-28947 - Qemu crashing with "failed to set up stack guard page: Cannot allocate memory" -Patch177: kvm-coroutine-reserve-5-000-mappings.patch +Patch0016: 0016-Add-upstream-compatibility-bits.patch +Patch0017: 0017-x86-rhel-9.4.0-machine-type-compat-fix.patch %if %{have_clang} BuildRequires: clang @@ -1234,7 +812,7 @@ run_configure \ --group=all --binary %{_libexecdir}/qemu-kvm --probe-prefix qemu.kvm \ trace/trace-events-all qemu-kvm-simpletrace.stp -cp -a %{kvm_target}-softmmu/qemu-system-%{kvm_target} qemu-kvm +cp -a qemu-system-%{kvm_target} qemu-kvm %ifarch s390x # Copy the built new images into place for "make check": @@ -1320,7 +898,7 @@ popd mkdir -p %{buildroot}%{_datadir}/systemtap/tapset -install -m 0755 %{qemu_kvm_build}/%{kvm_target}-softmmu/qemu-system-%{kvm_target} %{buildroot}%{_libexecdir}/qemu-kvm +install -m 0755 %{qemu_kvm_build}/qemu-system-%{kvm_target} %{buildroot}%{_libexecdir}/qemu-kvm install -m 0644 %{qemu_kvm_build}/qemu-kvm.stp %{buildroot}%{_datadir}/systemtap/tapset/ install -m 0644 %{qemu_kvm_build}/qemu-kvm-log.stp %{buildroot}%{_datadir}/systemtap/tapset/ install -m 0644 %{qemu_kvm_build}/qemu-kvm-simpletrace.stp %{buildroot}%{_datadir}/systemtap/tapset/ @@ -1379,6 +957,7 @@ rm -rf %{buildroot}%{_datadir}/%{name}/qboot.rom rm -rf %{buildroot}%{_datadir}/%{name}/s390-ccw.img rm -rf %{buildroot}%{_datadir}/%{name}/s390-netboot.img rm -rf %{buildroot}%{_datadir}/%{name}/hppa-firmware.img +rm -rf %{buildroot}%{_datadir}/%{name}/hppa-firmware64.img rm -rf %{buildroot}%{_datadir}/%{name}/canyonlands.dtb rm -rf %{buildroot}%{_datadir}/%{name}/u-boot-sam460-20100605.bin @@ -1609,6 +1188,10 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %{_datadir}/systemtap/tapset/qemu-kvm-simpletrace.stp %{_datadir}/%{name}/systemtap/script.d/qemu_kvm.stp %{_datadir}/%{name}/systemtap/conf.d/qemu_kvm.conf +%{_datadir}/systemtap/tapset/qemu-img*.stp +%{_datadir}/systemtap/tapset/qemu-io*.stp +%{_datadir}/systemtap/tapset/qemu-nbd*.stp +%{_datadir}/systemtap/tapset/qemu-storage-daemon*.stp %ifarch x86_64 %{_libdir}/%{name}/accel-tcg-%{kvm_target}.so @@ -1671,6 +1254,11 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Wed Apr 24 2024 Miroslav Rezanina - 9.0.0-1 +- Rebase to QEMU 9.0.0 [RHEL-28073] +- Resolves: RHEL-28073 + (Rebase qemu-kvm to QEMU 9.0.0 for RHEL 9.5) + * Tue Mar 26 2024 Miroslav Rezanina - 8.2.0-11 - kvm-coroutine-cap-per-thread-local-pool-size.patch [RHEL-28947] - kvm-coroutine-reserve-5-000-mappings.patch [RHEL-28947] diff --git a/sources b/sources index a38f0b3..a4e2afa 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (qemu-8.2.0.tar.xz) = 92ec41196ff145cdbb98948f6b6e43214fa4b4419554a8a1927fb4527080c8212ccb703e184baf8ee0bdfa50ad7a84689e8f5a69eba1bd7bbbdfd69e3b91256c +SHA512 (qemu-9.0.0.tar.xz) = 1603517cd4c93632ba60ad7261eb67374f12a744bf58f10b0e8686e46d3a02d8b6bf58a0c617f23a1868084aaba6386c24341894f75539e0b816091718721427