public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Miroslav Rezanina <mrezanin@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/qemu] eln: * Mon Jun 29 2026 Miroslav Rezanina <mrezanin@redhat.com> - 10.1.0-23
Date: Tue, 30 Jun 2026 15:09:04 GMT [thread overview]
Message-ID: <178283214486.1.12847396152023937975.rpms-qemu-3177ce9841a3@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/qemu
Branch : eln
Commit : 3177ce9841a33c732090ed8033497ae846e96ed0
Author : Miroslav Rezanina <mrezanin@redhat.com>
Date : 2026-06-30T17:07:57+02:00
Stats : +17694/-1 in 114 file(s)
URL : https://src.fedoraproject.org/rpms/qemu/c/3177ce9841a33c732090ed8033497ae846e96ed0?branch=eln
Log:
* Mon Jun 29 2026 Miroslav Rezanina <mrezanin@redhat.com> - 10.1.0-23
- kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vio.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vde.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmu-common-Factor-out-common-helper-function.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmu-add-memory-regions-as-property-for-an-SM.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Extract-common-definitions-to-smmuv3-c.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmu-common-Make-iommu-ops-part-of-SMMUState.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Introduce-smmuv3-accel-device.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Initialize-shared-system-address.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-pci-Move-pci_init_bus_master-after-adding-dev.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-Export-pci_device_get_iommu_bus_devfn-and-ret.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-pci-Add-optional-supports_address_space-callb.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-bridge-pci_expander_bridge-Move-TYPE_PXB_PCIE.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Restrict-accelerated-SMMUv3-to-v.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Implement-get_viommu_cap-callback.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-Introduce-pci_device_get_viommu_flags.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-Introduce-pci_device_get_host_iommu_quirks.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-common-Define-STE-CD-fields-via-regist.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-common-Add-NSCFG-bit-definition-for-CD.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-common-Add-STE-CD-set-helpers-for-repe.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Add-set-unset_iommu_device-callb.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-propagate-smmuv3_cmdq_consume-errors-t.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Add-nested-vSTE-install-uninstal.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Install-SMMUv3-GBPA-based-hwpt.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-pci-Introduce-a-callback-to-retrieve-the-MSI-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Implement-get_msi_direct_gpa-cal.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-virt-Set-msi-gpa-property.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Add-support-to-issue-invalidatio.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Initialize-ID-registers-early-during-r.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Get-host-SMMUv3-hw-info-and-vali.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-host-gpex-Allow-to-generate-preserve-boot-con.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-virt-Set-PCI-preserve_config-for-accel-SMMUv3.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-tests-qtest-bios-tables-test-Prepare-for-IORT-reviso.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-virt-acpi-build-Add-IORT-RMR-regions-to-handl.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-tests-qtest-bios-tables-test-Update-IORT-blobs-after.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Block-migration-when-accel-is-enabled.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Add-accel-property-for-SMMUv3-device.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Add-a-property-to-specify-RIL-su.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Add-support-for-ATS.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Add-property-to-specify-OAS-bits.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-backends-iommufd-Retrieve-PASID-width-from-iommufd_b.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-backends-iommufd-Add-get_pasid_info-callback.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-Add-helper-to-insert-PCIe-extended-capability.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-Factor-out-common-PASID-capability-initializa.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-vfio-pci-Synthesize-PASID-capability-for-vfio-pci.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Make-SubstreamID-support-configu.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-system-memory-Factor-address_space_is_io-out.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-target-i386-arch_memory_mapping-Use-address_space_me.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-s390x-sclp-Use-address_space_memory_is_io-in-sclp.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-system-physmem-Remove-cpu_physical_memory_is_io.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vev.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Add-viommu-free-helper.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Allocate-vEVENTQ-for-accelerated.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Introduce-a-helper-function-for-event-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Read-and-propagate-host-vIOMMU-e.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Correct-SMMUEN-field-name-in-CR0.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Fix-CFGI_CD-handling-when-stage-1-is-u.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Check-ATS-compatibility-between-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Change-ats-property-type-to-OnOf.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Change-ril-property-type-to-OnOf.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-qdev-Add-a-SsidSizeMode-property-type.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Change-ssidsize-property-type-to.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-qdev-Add-an-OasMode-property-type.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Change-oas-property-type-to-OasM.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-qemu-options.hx-Document-arm-smmuv3-device-s-accel-p.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Have-smmuv3_accel_init-take-an-Error-p.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Update-ATC-invalidation-check.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Improve-accel-SMMUv3-usage-documentati.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Add-helper-for-resolving-auto-pa.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ats.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ril.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ssidsiz.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-oas.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Set-default-ats-ril-ssidsize-oas-to-au.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-qemu-options.hx-Support-auto-for-accel-SMMUv3-proper.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-pci-pci-Enforce-pci_setup_iommu_per_bus-is-called.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-vfio-iommufd-Force-creating-nesting-parent-HWPT.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-vfio-iommufd-Control-dirty-tracking-for-nesting-p.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-backends-iommufd-Update-iommufd_backend_get_device_i.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-iommufd-Rename-all-the-idev-and-idevc-variables-to-h.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-backends-iommufd-Update-iommufd_backend_alloc_viommu.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-backends-iommufd-Introduce-iommufd_backend_alloc_hw_.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-backends-iommufd-Introduce-iommufd_backend_viommu_mm.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-system-iommufd-Remove-unused-viommu-pointer-from-IOM.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Introduce-CMDQV-ops-interface.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Avoid-including-CONFIG_DEVICES-in-hw-h.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Add-Tegra241-CMDQV-ops-backend.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Wire-CMDQV-ops-into-accel-lifecy.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-virt-Use-stored-SMMUv3-device-list-for-IORT-b.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Probe-host-Tegra241-CMDQV-supp.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-init.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-virt-Link-SMMUv3-CMDQV-resources-to-platform-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-vIOMMU-alloc-f.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-mmap-host-VINTF-Page0-for-CMDQ.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Emulate-CMDQ-V-Config-region.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-reads.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-writes.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Allocate-HW-VCMDQs-once-config.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Route-allocated-VCMDQ-Page0-ac.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-memory-Allow-RAM-device-regions-to-skip-IOMMU-mappin.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Use-mmap-d-host-VINTF-page0-fo.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Introduce-common-helper-for-veve.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Read-and-propagate-Tegra241-CM.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Initialize-register-state-on-r.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Limit-queue-size-based-on-back.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Add-per-device-identifier-property.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Introduce-helper-to-query-CMDQV-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-virt-acpi-Advertise-Tegra241-CMDQV-nodes-in-D.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-accel-Enforce-viommu-association-when-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-tegra241-cmdqv-Document-the-CMDQV-design-and-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-hw-arm-smmuv3-Add-cmdqv-property-for-SMMUv3-device.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- kvm-rh-aarch64-rh-devices.mak-Add-CONFIG_TEGRA241_CMDQV.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
- Resolves: RHEL-142465
([RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus)
- Resolves: RHEL-160190
(NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3)
- Resolves: RHEL-163596
(NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3)
- Resolves: RHEL-73794
(NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1)
- Resolves: RHEL-73796
(NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1)
- Resolves: RHEL-73798
(NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1)
---
diff --git a/.gitignore b/.gitignore
index 855cccf..b212237 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,7 @@
/qemu-9.1.0.tar.xz
/qemu-10.0.0.tar.xz
/qemu-10.1.0.tar.xz
+/IORT
+/IORT.its_off
+/IORT.smmuv3-dev
+/IORT.smmuv3-legacy
diff --git a/kvm-backends-iommufd-Add-get_pasid_info-callback.patch b/kvm-backends-iommufd-Add-get_pasid_info-callback.patch
new file mode 100644
index 0000000..c53a898
--- /dev/null
+++ b/kvm-backends-iommufd-Add-get_pasid_info-callback.patch
@@ -0,0 +1,111 @@
+From e614aef2ad181cc80c1688ebbf568d5eed193e37 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 041/111] backends/iommufd: Add get_pasid_info() callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [41/111] 3c436702f4ac6d8819ba999b7503a98efb770fec (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+The get_pasid_info callback retrieves PASID capability information
+when the HostIOMMUDevice backend supports it. Currently, only the
+Linux IOMMUFD backend provides this information.
+
+This will be used by a subsequent patch to synthesize a PASID
+capability for vfio-pci devices behind a vIOMMU that supports PASID.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-34-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 22afd9d865cb05d93c92c8fca7a23e1eb879e889)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 17 +++++++++++++++++
+ include/system/host_iommu_device.h | 17 +++++++++++++++++
+ 2 files changed, 34 insertions(+)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index 6381f9664b..f1707eadc6 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -538,11 +538,28 @@ static int hiod_iommufd_get_cap(HostIOMMUDevice *hiod, int cap, Error **errp)
+ }
+ }
+
++static bool hiod_iommufd_get_pasid_info(HostIOMMUDevice *hiod,
++ PasidInfo *pasid_info)
++{
++ HostIOMMUDeviceCaps *caps = &hiod->caps;
++
++ if (!caps->max_pasid_log2) {
++ return false;
++ }
++
++ g_assert(pasid_info);
++ pasid_info->exec_perm = (caps->hw_caps & IOMMU_HW_CAP_PCI_PASID_EXEC);
++ pasid_info->priv_mod = (caps->hw_caps & IOMMU_HW_CAP_PCI_PASID_PRIV);
++ pasid_info->max_pasid_log2 = caps->max_pasid_log2;
++ return true;
++}
++
+ static void hiod_iommufd_class_init(ObjectClass *oc, const void *data)
+ {
+ HostIOMMUDeviceClass *hioc = HOST_IOMMU_DEVICE_CLASS(oc);
+
+ hioc->get_cap = hiod_iommufd_get_cap;
++ hioc->get_pasid_info = hiod_iommufd_get_pasid_info;
+ };
+
+ static const TypeInfo types[] = {
+diff --git a/include/system/host_iommu_device.h b/include/system/host_iommu_device.h
+index bfb2b60478..f000301583 100644
+--- a/include/system/host_iommu_device.h
++++ b/include/system/host_iommu_device.h
+@@ -59,6 +59,12 @@ struct HostIOMMUDevice {
+ #endif
+ };
+
++typedef struct PasidInfo {
++ bool exec_perm;
++ bool priv_mod;
++ uint8_t max_pasid_log2;
++} PasidInfo;
++
+ /**
+ * struct HostIOMMUDeviceClass - The base class for all host IOMMU devices.
+ *
+@@ -116,6 +122,17 @@ struct HostIOMMUDeviceClass {
+ * @hiod: handle to the host IOMMU device
+ */
+ uint64_t (*get_page_size_mask)(HostIOMMUDevice *hiod);
++ /**
++ * @get_pasid_info: Return the PASID information associated with the
++ * @hiod Host IOMMU device.
++ *
++ * @hiod: handle to the host IOMMU device
++ *
++ * @pasid_info: If success, returns the PASID related information.
++ *
++ * Returns: true on success, false on failure.
++ */
++ bool (*get_pasid_info)(HostIOMMUDevice *hiod, PasidInfo *pasid_info);
+ };
+
+ /*
+--
+2.52.0
+
diff --git a/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_hw_.patch b/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_hw_.patch
new file mode 100644
index 0000000..6eee724
--- /dev/null
+++ b/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_hw_.patch
@@ -0,0 +1,124 @@
+From b024184da63ed552873ceb7f5aebfffe11d4cf52 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:24 +0100
+Subject: [PATCH 081/111] backends/iommufd: Introduce
+ iommufd_backend_alloc_hw_queue
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [81/111] 3db17914eedcce25ddbd6f008e73fc3c0270e450 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Conflicts: contextual conflict in backends/trace-events since
+we don't have igvm trace points
+
+Add a helper to allocate an iommufd backed HW queue for a vIOMMU.
+
+While at it, define a struct IOMMUFDHWqueue for use by vendor
+implementations.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-4-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 41dae463f487a5d94822a069043b7675405d0365)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 31 +++++++++++++++++++++++++++++++
+ backends/trace-events | 1 +
+ include/system/iommufd.h | 11 +++++++++++
+ 3 files changed, 43 insertions(+)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index 621b6115cb..0e11d2722a 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -545,6 +545,37 @@ bool iommufd_backend_alloc_veventq(IOMMUFDBackend *be, uint32_t viommu_id,
+ return true;
+ }
+
++bool iommufd_backend_alloc_hw_queue(IOMMUFDBackend *be, uint32_t viommu_id,
++ uint32_t queue_type, uint32_t index,
++ uint64_t addr, uint64_t length,
++ uint32_t *out_hw_queue_id, Error **errp)
++{
++ int ret;
++ struct iommu_hw_queue_alloc alloc_hw_queue = {
++ .size = sizeof(alloc_hw_queue),
++ .flags = 0,
++ .viommu_id = viommu_id,
++ .type = queue_type,
++ .index = index,
++ .nesting_parent_iova = addr,
++ .length = length,
++ };
++
++ ret = ioctl(be->fd, IOMMU_HW_QUEUE_ALLOC, &alloc_hw_queue);
++
++ trace_iommufd_backend_alloc_hw_queue(be->fd, viommu_id, queue_type,
++ index, addr, length,
++ alloc_hw_queue.out_hw_queue_id, ret);
++ if (ret) {
++ error_setg_errno(errp, errno, "IOMMU_HW_QUEUE_ALLOC failed");
++ return false;
++ }
++
++ g_assert(out_hw_queue_id);
++ *out_hw_queue_id = alloc_hw_queue.out_hw_queue_id;
++ return true;
++}
++
+ bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
+ uint32_t hwpt_id, Error **errp)
+ {
+diff --git a/backends/trace-events b/backends/trace-events
+index 934cdd8107..a88996488d 100644
+--- a/backends/trace-events
++++ b/backends/trace-events
+@@ -24,3 +24,4 @@ iommufd_backend_invalidate_cache(int iommufd, uint32_t id, uint32_t data_type, u
+ iommufd_backend_alloc_viommu(int iommufd, uint32_t dev_id, uint32_t type, uint32_t hwpt_id, uint64_t data_ptr, uint32_t data_len, uint32_t viommu_id, int ret) " iommufd=%d type=%u dev_id=%u hwpt_id=%u data_ptr=0x%"PRIx64" data_len=0x%x viommu_id=%u (%d)"
+ iommufd_backend_alloc_vdev(int iommufd, uint32_t dev_id, uint32_t viommu_id, uint64_t virt_id, uint32_t vdev_id, int ret) " iommufd=%d dev_id=%u viommu_id=%u virt_id=0x%"PRIx64" vdev_id=%u (%d)"
+ iommufd_viommu_alloc_eventq(int iommufd, uint32_t viommu_id, uint32_t type, uint32_t veventq_id, uint32_t veventq_fd, int ret) " iommufd=%d viommu_id=%u type=%u veventq_id=%u veventq_fd=%u (%d)"
++iommufd_backend_alloc_hw_queue(int iommufd, uint32_t viommu_id, uint32_t queue_type, uint32_t index, uint64_t addr, uint64_t size, uint32_t queue_id, int ret) " iommufd=%d viommu_id=%u queue_type=%u index=%u addr=0x%"PRIx64" size=0x%"PRIx64" queue_id=%u (%d)"
+diff --git a/include/system/iommufd.h b/include/system/iommufd.h
+index 783d125ee4..a538a13b80 100644
+--- a/include/system/iommufd.h
++++ b/include/system/iommufd.h
+@@ -65,6 +65,12 @@ typedef struct IOMMUFDVeventq {
+ bool event_start; /* True after first valid event; cleared on overflow */
+ } IOMMUFDVeventq;
+
++/* HW queue object for a vIOMMU-specific HW-accelerated queue */
++typedef struct IOMMUFDHWqueue {
++ IOMMUFDViommu *viommu;
++ uint32_t hw_queue_id;
++} IOMMUFDHWqueue;
++
+ bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
+ void iommufd_backend_disconnect(IOMMUFDBackend *be);
+
+@@ -101,6 +107,11 @@ bool iommufd_backend_alloc_veventq(IOMMUFDBackend *be, uint32_t viommu_id,
+ uint32_t *out_veventq_id,
+ uint32_t *out_veventq_fd, Error **errp);
+
++bool iommufd_backend_alloc_hw_queue(IOMMUFDBackend *be, uint32_t viommu_id,
++ uint32_t queue_type, uint32_t index,
++ uint64_t addr, uint64_t length,
++ uint32_t *out_hw_queue_id, Error **errp);
++
+ bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
+ bool start, Error **errp);
+ bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
+--
+2.52.0
+
diff --git a/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vde.patch b/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vde.patch
new file mode 100644
index 0000000..931d93d
--- /dev/null
+++ b/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vde.patch
@@ -0,0 +1,122 @@
+From 1ef487fbeab465ec6ed4d4f4286b465e7e797c24 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 002/111] backends/iommufd: Introduce
+ iommufd_backend_alloc_vdev
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [2/111] b063cc8959bb43f4c3112b4ec19329c5dcb1e556 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Add a helper to allocate an iommufd device's virtual device (in the user
+space) per a viommu instance.
+
+While at it, introduce a struct IOMMUFDVdev for later use by vendor
+IOMMU implementations.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-3-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit cd438bf9bdf75cc7251ffb968ea59e640fe096e6)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 27 +++++++++++++++++++++++++++
+ backends/trace-events | 1 +
+ include/system/iommufd.h | 12 ++++++++++++
+ 3 files changed, 40 insertions(+)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index 3d4a4ae736..e68a2c934f 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -472,6 +472,33 @@ bool iommufd_backend_alloc_viommu(IOMMUFDBackend *be, uint32_t dev_id,
+ return true;
+ }
+
++bool iommufd_backend_alloc_vdev(IOMMUFDBackend *be, uint32_t dev_id,
++ uint32_t viommu_id, uint64_t virt_id,
++ uint32_t *out_vdev_id, Error **errp)
++{
++ int ret;
++ struct iommu_vdevice_alloc alloc_vdev = {
++ .size = sizeof(alloc_vdev),
++ .viommu_id = viommu_id,
++ .dev_id = dev_id,
++ .virt_id = virt_id,
++ };
++
++ ret = ioctl(be->fd, IOMMU_VDEVICE_ALLOC, &alloc_vdev);
++
++ trace_iommufd_backend_alloc_vdev(be->fd, dev_id, viommu_id, virt_id,
++ alloc_vdev.out_vdevice_id, ret);
++
++ if (ret) {
++ error_setg_errno(errp, errno, "IOMMU_VDEVICE_ALLOC failed");
++ return false;
++ }
++
++ g_assert(out_vdev_id);
++ *out_vdev_id = alloc_vdev.out_vdevice_id;
++ return true;
++}
++
+ bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
+ uint32_t hwpt_id, Error **errp)
+ {
+diff --git a/backends/trace-events b/backends/trace-events
+index 01c2d9bde9..8408dc8701 100644
+--- a/backends/trace-events
++++ b/backends/trace-events
+@@ -22,3 +22,4 @@ iommufd_backend_set_dirty(int iommufd, uint32_t hwpt_id, bool start, int ret) "
+ iommufd_backend_get_dirty_bitmap(int iommufd, uint32_t hwpt_id, uint64_t iova, uint64_t size, uint64_t page_size, int ret) " iommufd=%d hwpt=%u iova=0x%"PRIx64" size=0x%"PRIx64" page_size=0x%"PRIx64" (%d)"
+ iommufd_backend_invalidate_cache(int iommufd, uint32_t id, uint32_t data_type, uint32_t entry_len, uint32_t entry_num, uint32_t done_num, uint64_t data_ptr, int ret) " iommufd=%d id=%u data_type=%u entry_len=%u entry_num=%u done_num=%u data_ptr=0x%"PRIx64" (%d)"
+ iommufd_backend_alloc_viommu(int iommufd, uint32_t dev_id, uint32_t type, uint32_t hwpt_id, uint32_t viommu_id, int ret) " iommufd=%d type=%u dev_id=%u hwpt_id=%u viommu_id=%u (%d)"
++iommufd_backend_alloc_vdev(int iommufd, uint32_t dev_id, uint32_t viommu_id, uint64_t virt_id, uint32_t vdev_id, int ret) " iommufd=%d dev_id=%u viommu_id=%u virt_id=0x%"PRIx64" vdev_id=%u (%d)"
+diff --git a/include/system/iommufd.h b/include/system/iommufd.h
+index 11b8413c3f..41e216c677 100644
+--- a/include/system/iommufd.h
++++ b/include/system/iommufd.h
+@@ -48,6 +48,14 @@ typedef struct IOMMUFDViommu {
+ uint32_t viommu_id; /* virtual IOMMU ID of allocated object */
+ } IOMMUFDViommu;
+
++/*
++ * Virtual device object for a physical device bind to a vIOMMU.
++ */
++typedef struct IOMMUFDVdev {
++ uint32_t vdevice_id; /* object handle for vDevice */
++ uint32_t virt_id; /* virtual device ID */
++} IOMMUFDVdev;
++
+ bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
+ void iommufd_backend_disconnect(IOMMUFDBackend *be);
+
+@@ -73,6 +81,10 @@ bool iommufd_backend_alloc_viommu(IOMMUFDBackend *be, uint32_t dev_id,
+ uint32_t viommu_type, uint32_t hwpt_id,
+ uint32_t *out_hwpt, Error **errp);
+
++bool iommufd_backend_alloc_vdev(IOMMUFDBackend *be, uint32_t dev_id,
++ uint32_t viommu_id, uint64_t virt_id,
++ uint32_t *out_vdev_id, Error **errp);
++
+ bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
+ bool start, Error **errp);
+ bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
+--
+2.52.0
+
diff --git a/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vev.patch b/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vev.patch
new file mode 100644
index 0000000..efff3d1
--- /dev/null
+++ b/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vev.patch
@@ -0,0 +1,127 @@
+From 30da7f8af7c6d1e240cab27117e4b06143bab4c4 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Fri, 6 Mar 2026 09:01:11 +0000
+Subject: [PATCH 050/111] backends/iommufd: Introduce
+ iommufd_backend_alloc_veventq
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [50/111] ed7d1d76b95dcbd4df9bab81ed7c660b2eda094c (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73796
+
+Conflicts: contextual in backends/trace-events because we don't
+ have IGM trace points downstream
+
+Add a new helper for IOMMU_VEVENTQ_ALLOC ioctl to allocate a virtual event
+queue (vEVENTQ) for a vIOMMU object.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260226084456.112142-2-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 0885cd5504dfdbd531a1fc0e3e421d3c9934b03a)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 31 +++++++++++++++++++++++++++++++
+ backends/trace-events | 1 +
+ include/system/iommufd.h | 14 ++++++++++++++
+ 3 files changed, 46 insertions(+)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index f1707eadc6..5b919e4be9 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -503,6 +503,37 @@ bool iommufd_backend_alloc_vdev(IOMMUFDBackend *be, uint32_t dev_id,
+ return true;
+ }
+
++bool iommufd_backend_alloc_veventq(IOMMUFDBackend *be, uint32_t viommu_id,
++ uint32_t type, uint32_t depth,
++ uint32_t *out_veventq_id,
++ uint32_t *out_veventq_fd, Error **errp)
++{
++ int ret;
++ struct iommu_veventq_alloc alloc_veventq = {
++ .size = sizeof(alloc_veventq),
++ .flags = 0,
++ .type = type,
++ .veventq_depth = depth,
++ .viommu_id = viommu_id,
++ };
++
++ ret = ioctl(be->fd, IOMMU_VEVENTQ_ALLOC, &alloc_veventq);
++
++ trace_iommufd_viommu_alloc_eventq(be->fd, viommu_id, type,
++ alloc_veventq.out_veventq_id,
++ alloc_veventq.out_veventq_fd, ret);
++ if (ret) {
++ error_setg_errno(errp, errno, "IOMMU_VEVENTQ_ALLOC failed");
++ return false;
++ }
++
++ g_assert(out_veventq_id);
++ g_assert(out_veventq_fd);
++ *out_veventq_id = alloc_veventq.out_veventq_id;
++ *out_veventq_fd = alloc_veventq.out_veventq_fd;
++ return true;
++}
++
+ bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
+ uint32_t hwpt_id, Error **errp)
+ {
+diff --git a/backends/trace-events b/backends/trace-events
+index 8408dc8701..5afa7a40be 100644
+--- a/backends/trace-events
++++ b/backends/trace-events
+@@ -23,3 +23,4 @@ iommufd_backend_get_dirty_bitmap(int iommufd, uint32_t hwpt_id, uint64_t iova, u
+ iommufd_backend_invalidate_cache(int iommufd, uint32_t id, uint32_t data_type, uint32_t entry_len, uint32_t entry_num, uint32_t done_num, uint64_t data_ptr, int ret) " iommufd=%d id=%u data_type=%u entry_len=%u entry_num=%u done_num=%u data_ptr=0x%"PRIx64" (%d)"
+ iommufd_backend_alloc_viommu(int iommufd, uint32_t dev_id, uint32_t type, uint32_t hwpt_id, uint32_t viommu_id, int ret) " iommufd=%d type=%u dev_id=%u hwpt_id=%u viommu_id=%u (%d)"
+ iommufd_backend_alloc_vdev(int iommufd, uint32_t dev_id, uint32_t viommu_id, uint64_t virt_id, uint32_t vdev_id, int ret) " iommufd=%d dev_id=%u viommu_id=%u virt_id=0x%"PRIx64" vdev_id=%u (%d)"
++iommufd_viommu_alloc_eventq(int iommufd, uint32_t viommu_id, uint32_t type, uint32_t veventq_id, uint32_t veventq_fd, int ret) " iommufd=%d viommu_id=%u type=%u veventq_id=%u veventq_fd=%u (%d)"
+diff --git a/include/system/iommufd.h b/include/system/iommufd.h
+index aa78bf1e1d..25da754434 100644
+--- a/include/system/iommufd.h
++++ b/include/system/iommufd.h
+@@ -56,6 +56,15 @@ typedef struct IOMMUFDVdev {
+ uint32_t virt_id; /* virtual device ID */
+ } IOMMUFDVdev;
+
++/* Virtual event queue interface for a vIOMMU */
++typedef struct IOMMUFDVeventq {
++ IOMMUFDViommu *viommu;
++ uint32_t veventq_id;
++ uint32_t veventq_fd;
++ uint32_t last_event_seq; /* Sequence number of last processed event */
++ bool event_start; /* True after first valid event; cleared on overflow */
++} IOMMUFDVeventq;
++
+ bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
+ void iommufd_backend_disconnect(IOMMUFDBackend *be);
+
+@@ -86,6 +95,11 @@ bool iommufd_backend_alloc_vdev(IOMMUFDBackend *be, uint32_t dev_id,
+ uint32_t viommu_id, uint64_t virt_id,
+ uint32_t *out_vdev_id, Error **errp);
+
++bool iommufd_backend_alloc_veventq(IOMMUFDBackend *be, uint32_t viommu_id,
++ uint32_t type, uint32_t depth,
++ uint32_t *out_veventq_id,
++ uint32_t *out_veventq_fd, Error **errp);
++
+ bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
+ bool start, Error **errp);
+ bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
+--
+2.52.0
+
diff --git a/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vio.patch b/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vio.patch
new file mode 100644
index 0000000..f941198
--- /dev/null
+++ b/kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vio.patch
@@ -0,0 +1,122 @@
+From ce364f92071b60f7cb4a04b69f6f6a9c7c0257fa Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 001/111] backends/iommufd: Introduce
+ iommufd_backend_alloc_viommu
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [1/111] a18282a27ab9339bc218c7c776ac0524f9573669 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Add a helper to allocate a viommu object.
+
+Also introduce a struct IOMMUFDViommu that can be used later by vendor
+IOMMU implementations.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-2-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit f2d31df0d92546a86e8cdbf51436db6aae8c167a)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 26 ++++++++++++++++++++++++++
+ backends/trace-events | 1 +
+ include/system/iommufd.h | 14 ++++++++++++++
+ 3 files changed, 41 insertions(+)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index fdfb7c9d67..3d4a4ae736 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -446,6 +446,32 @@ bool iommufd_backend_invalidate_cache(IOMMUFDBackend *be, uint32_t id,
+ return !ret;
+ }
+
++bool iommufd_backend_alloc_viommu(IOMMUFDBackend *be, uint32_t dev_id,
++ uint32_t viommu_type, uint32_t hwpt_id,
++ uint32_t *out_viommu_id, Error **errp)
++{
++ int ret;
++ struct iommu_viommu_alloc alloc_viommu = {
++ .size = sizeof(alloc_viommu),
++ .type = viommu_type,
++ .dev_id = dev_id,
++ .hwpt_id = hwpt_id,
++ };
++
++ ret = ioctl(be->fd, IOMMU_VIOMMU_ALLOC, &alloc_viommu);
++
++ trace_iommufd_backend_alloc_viommu(be->fd, dev_id, viommu_type, hwpt_id,
++ alloc_viommu.out_viommu_id, ret);
++ if (ret) {
++ error_setg_errno(errp, errno, "IOMMU_VIOMMU_ALLOC failed");
++ return false;
++ }
++
++ g_assert(out_viommu_id);
++ *out_viommu_id = alloc_viommu.out_viommu_id;
++ return true;
++}
++
+ bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
+ uint32_t hwpt_id, Error **errp)
+ {
+diff --git a/backends/trace-events b/backends/trace-events
+index 56132d3fd2..01c2d9bde9 100644
+--- a/backends/trace-events
++++ b/backends/trace-events
+@@ -21,3 +21,4 @@ iommufd_backend_free_id(int iommufd, uint32_t id, int ret) " iommufd=%d id=%d (%
+ iommufd_backend_set_dirty(int iommufd, uint32_t hwpt_id, bool start, int ret) " iommufd=%d hwpt=%u enable=%d (%d)"
+ iommufd_backend_get_dirty_bitmap(int iommufd, uint32_t hwpt_id, uint64_t iova, uint64_t size, uint64_t page_size, int ret) " iommufd=%d hwpt=%u iova=0x%"PRIx64" size=0x%"PRIx64" page_size=0x%"PRIx64" (%d)"
+ iommufd_backend_invalidate_cache(int iommufd, uint32_t id, uint32_t data_type, uint32_t entry_len, uint32_t entry_num, uint32_t done_num, uint64_t data_ptr, int ret) " iommufd=%d id=%u data_type=%u entry_len=%u entry_num=%u done_num=%u data_ptr=0x%"PRIx64" (%d)"
++iommufd_backend_alloc_viommu(int iommufd, uint32_t dev_id, uint32_t type, uint32_t hwpt_id, uint32_t viommu_id, int ret) " iommufd=%d type=%u dev_id=%u hwpt_id=%u viommu_id=%u (%d)"
+diff --git a/include/system/iommufd.h b/include/system/iommufd.h
+index a659f36a20..11b8413c3f 100644
+--- a/include/system/iommufd.h
++++ b/include/system/iommufd.h
+@@ -38,6 +38,16 @@ struct IOMMUFDBackend {
+ /*< public >*/
+ };
+
++/*
++ * Virtual IOMMU object that represents physical IOMMU's virtualization
++ * support
++ */
++typedef struct IOMMUFDViommu {
++ IOMMUFDBackend *iommufd;
++ uint32_t s2_hwpt_id; /* ID of stage 2 HWPT */
++ uint32_t viommu_id; /* virtual IOMMU ID of allocated object */
++} IOMMUFDViommu;
++
+ bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
+ void iommufd_backend_disconnect(IOMMUFDBackend *be);
+
+@@ -59,6 +69,10 @@ bool iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t dev_id,
+ uint32_t data_type, uint32_t data_len,
+ void *data_ptr, uint32_t *out_hwpt,
+ Error **errp);
++bool iommufd_backend_alloc_viommu(IOMMUFDBackend *be, uint32_t dev_id,
++ uint32_t viommu_type, uint32_t hwpt_id,
++ uint32_t *out_hwpt, Error **errp);
++
+ bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
+ bool start, Error **errp);
+ bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
+--
+2.52.0
+
diff --git a/kvm-backends-iommufd-Introduce-iommufd_backend_viommu_mm.patch b/kvm-backends-iommufd-Introduce-iommufd_backend_viommu_mm.patch
new file mode 100644
index 0000000..0420ed5
--- /dev/null
+++ b/kvm-backends-iommufd-Introduce-iommufd_backend_viommu_mm.patch
@@ -0,0 +1,102 @@
+From 53ba4b1a6de094a4881eba56b55c34055330a04d Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:25 +0100
+Subject: [PATCH 082/111] backends/iommufd: Introduce
+ iommufd_backend_viommu_mmap
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [82/111] 699aec712a9be27abecdb2a37f14b7b8968bae49 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Conflicts: contextual conflict in backends/trace-events since
+we don't have igvm trace points
+
+Add a backend helper to mmap hardware MMIO regions exposed via iommufd for
+a vIOMMU instance. This allows user space to access HW-accelerated MMIO
+pages provided by the vIOMMU.
+
+The caller is responsible for unmapping the returned region.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-5-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit b391e41e53b5268d0943c4f2276749a9448496b3)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 22 ++++++++++++++++++++++
+ backends/trace-events | 1 +
+ include/system/iommufd.h | 4 ++++
+ 3 files changed, 27 insertions(+)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index 0e11d2722a..e457173da5 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -576,6 +576,28 @@ bool iommufd_backend_alloc_hw_queue(IOMMUFDBackend *be, uint32_t viommu_id,
+ return true;
+ }
+
++/*
++ * Helper to mmap HW MMIO regions exposed via iommufd for a vIOMMU instance.
++ * The caller is responsible for unmapping the mapped region.
++ */
++bool iommufd_backend_viommu_mmap(IOMMUFDBackend *be, uint32_t viommu_id,
++ uint64_t size, off_t offset, void **out_ptr,
++ Error **errp)
++{
++ g_assert(viommu_id);
++ g_assert(out_ptr);
++
++ *out_ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, be->fd,
++ offset);
++ trace_iommufd_backend_viommu_mmap(be->fd, viommu_id, size, offset);
++ if (*out_ptr == MAP_FAILED) {
++ error_setg_errno(errp, errno, "IOMMUFD vIOMMU mmap failed");
++ return false;
++ }
++
++ return true;
++}
++
+ bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
+ uint32_t hwpt_id, Error **errp)
+ {
+diff --git a/backends/trace-events b/backends/trace-events
+index a88996488d..eae799c882 100644
+--- a/backends/trace-events
++++ b/backends/trace-events
+@@ -25,3 +25,4 @@ iommufd_backend_alloc_viommu(int iommufd, uint32_t dev_id, uint32_t type, uint32
+ iommufd_backend_alloc_vdev(int iommufd, uint32_t dev_id, uint32_t viommu_id, uint64_t virt_id, uint32_t vdev_id, int ret) " iommufd=%d dev_id=%u viommu_id=%u virt_id=0x%"PRIx64" vdev_id=%u (%d)"
+ iommufd_viommu_alloc_eventq(int iommufd, uint32_t viommu_id, uint32_t type, uint32_t veventq_id, uint32_t veventq_fd, int ret) " iommufd=%d viommu_id=%u type=%u veventq_id=%u veventq_fd=%u (%d)"
+ iommufd_backend_alloc_hw_queue(int iommufd, uint32_t viommu_id, uint32_t queue_type, uint32_t index, uint64_t addr, uint64_t size, uint32_t queue_id, int ret) " iommufd=%d viommu_id=%u queue_type=%u index=%u addr=0x%"PRIx64" size=0x%"PRIx64" queue_id=%u (%d)"
++iommufd_backend_viommu_mmap(int iommufd, uint32_t viommu_id, uint64_t size, uint64_t offset) " iommufd=%d viommu_id=%u size=0x%"PRIx64" offset=0x%"PRIx64
+diff --git a/include/system/iommufd.h b/include/system/iommufd.h
+index a538a13b80..2abb7c9605 100644
+--- a/include/system/iommufd.h
++++ b/include/system/iommufd.h
+@@ -112,6 +112,10 @@ bool iommufd_backend_alloc_hw_queue(IOMMUFDBackend *be, uint32_t viommu_id,
+ uint64_t addr, uint64_t length,
+ uint32_t *out_hw_queue_id, Error **errp);
+
++bool iommufd_backend_viommu_mmap(IOMMUFDBackend *be, uint32_t viommu_id,
++ uint64_t size, off_t offset, void **out_ptr,
++ Error **errp);
++
+ bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
+ bool start, Error **errp);
+ bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
+--
+2.52.0
+
diff --git a/kvm-backends-iommufd-Retrieve-PASID-width-from-iommufd_b.patch b/kvm-backends-iommufd-Retrieve-PASID-width-from-iommufd_b.patch
new file mode 100644
index 0000000..80f815c
--- /dev/null
+++ b/kvm-backends-iommufd-Retrieve-PASID-width-from-iommufd_b.patch
@@ -0,0 +1,167 @@
+From 3a3d4951c65f26ec8215ea06a5283673bef8e499 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 040/111] backends/iommufd: Retrieve PASID width from
+ iommufd_backend_get_device_info()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [40/111] e6c94449414ec82230d03c39d255e1ceff69bbea (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Conflicts: contextual conflict in hw/vfio/iommufd.c
+Add caps local variable and pass it in iommufd_backend_get_device_info()
+This is due to the fact we don't have
+68d3a2a24d7c ("Workaround for ERRATA_772415_SPR17")
+
+Retrieve PASID width from iommufd_backend_get_device_info() and store it
+in HostIOMMUDeviceCaps for later use.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Cédric Le Goater <clg@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-33-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 550beca3d7b0159681a09d63dfce19ac31509f9f)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 6 +++++-
+ hw/arm/smmuv3-accel.c | 3 ++-
+ hw/vfio/iommufd.c | 8 ++++++--
+ include/system/host_iommu_device.h | 3 +++
+ include/system/iommufd.h | 3 ++-
+ 5 files changed, 18 insertions(+), 5 deletions(-)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index e68a2c934f..6381f9664b 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -388,7 +388,8 @@ bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be,
+
+ bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
+ uint32_t *type, void *data, uint32_t len,
+- uint64_t *caps, Error **errp)
++ uint64_t *caps, uint8_t *max_pasid_log2,
++ Error **errp)
+ {
+ struct iommu_hw_info info = {
+ .size = sizeof(info),
+@@ -407,6 +408,9 @@ bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
+ g_assert(caps);
+ *caps = info.out_capabilities;
+
++ if (max_pasid_log2) {
++ *max_pasid_log2 = info.out_max_pasid_log2;
++ }
+ return true;
+ }
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index ea420afeb7..342944da23 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -121,7 +121,8 @@ smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ uint64_t caps;
+
+ if (!iommufd_backend_get_device_info(idev->iommufd, idev->devid, &data_type,
+- &info, sizeof(info), &caps, errp)) {
++ &info, sizeof(info), &caps, NULL,
++ errp)) {
+ return false;
+ }
+
+diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
+index bb5775aa71..67acdfa183 100644
+--- a/hw/vfio/iommufd.c
++++ b/hw/vfio/iommufd.c
+@@ -308,6 +308,7 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
+ VFIOContainer *bcontainer = VFIO_IOMMU(container);
+ uint32_t type, flags = 0;
+ uint64_t hw_caps;
++ VendorCaps caps;
+ VFIOIOASHwpt *hwpt;
+ uint32_t hwpt_id;
+ int ret;
+@@ -353,7 +354,8 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
+ * instead.
+ */
+ if (!iommufd_backend_get_device_info(vbasedev->iommufd, vbasedev->devid,
+- &type, NULL, 0, &hw_caps, errp)) {
++ &type, &caps, sizeof(caps), &hw_caps,
++ NULL, errp)) {
+ return false;
+ }
+
+@@ -880,19 +882,21 @@ static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
+ HostIOMMUDeviceCaps *caps = &hiod->caps;
+ VendorCaps *vendor_caps = &caps->vendor_caps;
+ enum iommu_hw_info_type type;
++ uint8_t max_pasid_log2;
+ uint64_t hw_caps;
+
+ hiod->agent = opaque;
+
+ if (!iommufd_backend_get_device_info(vdev->iommufd, vdev->devid, &type,
+ vendor_caps, sizeof(*vendor_caps),
+- &hw_caps, errp)) {
++ &hw_caps, &max_pasid_log2, errp)) {
+ return false;
+ }
+
+ hiod->name = g_strdup(vdev->name);
+ caps->type = type;
+ caps->hw_caps = hw_caps;
++ caps->max_pasid_log2 = max_pasid_log2;
+
+ idev = HOST_IOMMU_DEVICE_IOMMUFD(hiod);
+ idev->iommufd = vdev->iommufd;
+diff --git a/include/system/host_iommu_device.h b/include/system/host_iommu_device.h
+index ab849a4a82..bfb2b60478 100644
+--- a/include/system/host_iommu_device.h
++++ b/include/system/host_iommu_device.h
+@@ -30,6 +30,8 @@ typedef union VendorCaps {
+ * @hw_caps: host platform IOMMU capabilities (e.g. on IOMMUFD this represents
+ * the @out_capabilities value returned from IOMMU_GET_HW_INFO ioctl)
+ *
++ * @max_pasid_log2: width of PASIDs supported by host IOMMU device
++ *
+ * @vendor_caps: host platform IOMMU vendor specific capabilities (e.g. on
+ * IOMMUFD this represents a user-space buffer filled by kernel
+ * with host IOMMU @type specific hardware information data)
+@@ -37,6 +39,7 @@ typedef union VendorCaps {
+ typedef struct HostIOMMUDeviceCaps {
+ uint32_t type;
+ uint64_t hw_caps;
++ uint8_t max_pasid_log2;
+ VendorCaps vendor_caps;
+ } HostIOMMUDeviceCaps;
+ #endif
+diff --git a/include/system/iommufd.h b/include/system/iommufd.h
+index 41e216c677..aa78bf1e1d 100644
+--- a/include/system/iommufd.h
++++ b/include/system/iommufd.h
+@@ -71,7 +71,8 @@ int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id,
+ hwaddr iova, uint64_t size);
+ bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
+ uint32_t *type, void *data, uint32_t len,
+- uint64_t *caps, Error **errp);
++ uint64_t *caps, uint8_t *max_pasid_log2,
++ Error **errp);
+ bool iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t dev_id,
+ uint32_t pt_id, uint32_t flags,
+ uint32_t data_type, uint32_t data_len,
+--
+2.52.0
+
diff --git a/kvm-backends-iommufd-Update-iommufd_backend_alloc_viommu.patch b/kvm-backends-iommufd-Update-iommufd_backend_alloc_viommu.patch
new file mode 100644
index 0000000..bef4305
--- /dev/null
+++ b/kvm-backends-iommufd-Update-iommufd_backend_alloc_viommu.patch
@@ -0,0 +1,110 @@
+From 7916e88667364d8845de78f481c2f611e5cc0eb0 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:23 +0100
+Subject: [PATCH 080/111] backends/iommufd: Update iommufd_backend_alloc_viommu
+ to allow user ptr
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [80/111] 6068eed2afc6aa74d12fec8e2bf154f86dfd8671 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+The updated IOMMUFD VIOMMU_ALLOC uAPI allows userspace to provide a data
+buffer when creating a vIOMMU (e.g. for Tegra241 CMDQV). Extend
+iommufd_backend_alloc_viommu() to pass a user pointer and size to the
+kernel.
+
+Update the caller accordingly.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-3-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit d2f3b3156dbdcdf3b2136e3450014317bdd9f864)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 4 ++++
+ backends/trace-events | 2 +-
+ hw/arm/smmuv3-accel.c | 4 ++--
+ include/system/iommufd.h | 1 +
+ 4 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index b328f89699..621b6115cb 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -459,6 +459,7 @@ bool iommufd_backend_invalidate_cache(IOMMUFDBackend *be, uint32_t id,
+
+ bool iommufd_backend_alloc_viommu(IOMMUFDBackend *be, uint32_t dev_id,
+ uint32_t viommu_type, uint32_t hwpt_id,
++ void *data_ptr, uint32_t data_len,
+ uint32_t *out_viommu_id, Error **errp)
+ {
+ int ret;
+@@ -467,11 +468,14 @@ bool iommufd_backend_alloc_viommu(IOMMUFDBackend *be, uint32_t dev_id,
+ .type = viommu_type,
+ .dev_id = dev_id,
+ .hwpt_id = hwpt_id,
++ .data_len = data_len,
++ .data_uptr = (uintptr_t)data_ptr,
+ };
+
+ ret = ioctl(be->fd, IOMMU_VIOMMU_ALLOC, &alloc_viommu);
+
+ trace_iommufd_backend_alloc_viommu(be->fd, dev_id, viommu_type, hwpt_id,
++ (uintptr_t)data_ptr, data_len,
+ alloc_viommu.out_viommu_id, ret);
+ if (ret) {
+ error_setg_errno(errp, errno, "IOMMU_VIOMMU_ALLOC failed");
+diff --git a/backends/trace-events b/backends/trace-events
+index 5afa7a40be..934cdd8107 100644
+--- a/backends/trace-events
++++ b/backends/trace-events
+@@ -21,6 +21,6 @@ iommufd_backend_free_id(int iommufd, uint32_t id, int ret) " iommufd=%d id=%d (%
+ iommufd_backend_set_dirty(int iommufd, uint32_t hwpt_id, bool start, int ret) " iommufd=%d hwpt=%u enable=%d (%d)"
+ iommufd_backend_get_dirty_bitmap(int iommufd, uint32_t hwpt_id, uint64_t iova, uint64_t size, uint64_t page_size, int ret) " iommufd=%d hwpt=%u iova=0x%"PRIx64" size=0x%"PRIx64" page_size=0x%"PRIx64" (%d)"
+ iommufd_backend_invalidate_cache(int iommufd, uint32_t id, uint32_t data_type, uint32_t entry_len, uint32_t entry_num, uint32_t done_num, uint64_t data_ptr, int ret) " iommufd=%d id=%u data_type=%u entry_len=%u entry_num=%u done_num=%u data_ptr=0x%"PRIx64" (%d)"
+-iommufd_backend_alloc_viommu(int iommufd, uint32_t dev_id, uint32_t type, uint32_t hwpt_id, uint32_t viommu_id, int ret) " iommufd=%d type=%u dev_id=%u hwpt_id=%u viommu_id=%u (%d)"
++iommufd_backend_alloc_viommu(int iommufd, uint32_t dev_id, uint32_t type, uint32_t hwpt_id, uint64_t data_ptr, uint32_t data_len, uint32_t viommu_id, int ret) " iommufd=%d type=%u dev_id=%u hwpt_id=%u data_ptr=0x%"PRIx64" data_len=0x%x viommu_id=%u (%d)"
+ iommufd_backend_alloc_vdev(int iommufd, uint32_t dev_id, uint32_t viommu_id, uint64_t virt_id, uint32_t vdev_id, int ret) " iommufd=%d dev_id=%u viommu_id=%u virt_id=0x%"PRIx64" vdev_id=%u (%d)"
+ iommufd_viommu_alloc_eventq(int iommufd, uint32_t viommu_id, uint32_t type, uint32_t veventq_id, uint32_t veventq_fd, int ret) " iommufd=%d viommu_id=%u type=%u veventq_id=%u veventq_fd=%u (%d)"
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 163d3e7279..4cef487679 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -582,8 +582,8 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *hiodi,
+ IOMMUFDViommu *viommu;
+
+ if (!iommufd_backend_alloc_viommu(hiodi->iommufd, hiodi->devid,
+- IOMMU_VIOMMU_TYPE_ARM_SMMUV3,
+- s2_hwpt_id, &viommu_id, errp)) {
++ IOMMU_VIOMMU_TYPE_ARM_SMMUV3, s2_hwpt_id,
++ NULL, 0, &viommu_id, errp)) {
+ return false;
+ }
+
+diff --git a/include/system/iommufd.h b/include/system/iommufd.h
+index e45f4a5e87..783d125ee4 100644
+--- a/include/system/iommufd.h
++++ b/include/system/iommufd.h
+@@ -89,6 +89,7 @@ bool iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t dev_id,
+ Error **errp);
+ bool iommufd_backend_alloc_viommu(IOMMUFDBackend *be, uint32_t dev_id,
+ uint32_t viommu_type, uint32_t hwpt_id,
++ void *data_ptr, uint32_t data_len,
+ uint32_t *out_hwpt, Error **errp);
+
+ bool iommufd_backend_alloc_vdev(IOMMUFDBackend *be, uint32_t dev_id,
+--
+2.52.0
+
diff --git a/kvm-backends-iommufd-Update-iommufd_backend_get_device_i.patch b/kvm-backends-iommufd-Update-iommufd_backend_get_device_i.patch
new file mode 100644
index 0000000..3333b16
--- /dev/null
+++ b/kvm-backends-iommufd-Update-iommufd_backend_get_device_i.patch
@@ -0,0 +1,106 @@
+From 22efc23db4a5d1773170bc1f898a55d979bd0b00 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:22 +0100
+Subject: [PATCH 078/111] backends/iommufd: Update
+ iommufd_backend_get_device_info
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [78/111] 3ca7bb7a3544994a178876f3b15738112945a525 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+The updated IOMMUFD uAPI introduces the ability for userspace to request
+a specific hardware info data type via IOMMU_GET_HW_INFO. Update
+iommufd_backend_get_device_info() to set IOMMU_HW_INFO_FLAG_INPUT_TYPE
+when a non-zero type is supplied, and adjust all callers to pass a type
+value explicitly initialised to zero (IOMMU_HW_INFO_TYPE_DEFAULT) when
+no specific type is requested.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-2-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 3e79b45e0478de367745aa1f5d3b0a4573c69ab0)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 7 +++++++
+ hw/arm/smmuv3-accel.c | 2 +-
+ hw/vfio/iommufd.c | 4 ++--
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index 5b919e4be9..416e193751 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -386,16 +386,23 @@ bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be,
+ return true;
+ }
+
++/*
++ * @type can carry a desired HW info type defined in the uapi headers. If caller
++ * doesn't have one, indicating it wants the default type, then @type should be
++ * zeroed (i.e. IOMMU_HW_INFO_TYPE_DEFAULT).
++ */
+ bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
+ uint32_t *type, void *data, uint32_t len,
+ uint64_t *caps, uint8_t *max_pasid_log2,
+ Error **errp)
+ {
+ struct iommu_hw_info info = {
++ .flags = (*type) ? IOMMU_HW_INFO_FLAG_INPUT_TYPE : 0,
+ .size = sizeof(info),
+ .dev_id = devid,
+ .data_len = len,
+ .data_uptr = (uintptr_t)data,
++ .in_data_type = *type,
+ };
+
+ if (ioctl(be->fd, IOMMU_GET_HW_INFO, &info)) {
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 0b01848292..f97129388f 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -176,7 +176,7 @@ smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ Error **errp)
+ {
+ struct iommu_hw_info_arm_smmuv3 info;
+- uint32_t data_type;
++ uint32_t data_type = IOMMU_HW_INFO_TYPE_DEFAULT;
+ uint64_t caps;
+
+ if (!iommufd_backend_get_device_info(idev->iommufd, idev->devid, &data_type,
+diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
+index 7e0287f814..93703a0036 100644
+--- a/hw/vfio/iommufd.c
++++ b/hw/vfio/iommufd.c
+@@ -307,7 +307,7 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
+ IOMMUFDBackend *iommufd = vbasedev->iommufd;
+ VFIOContainer *bcontainer = VFIO_IOMMU(container);
+ bool viommu_nesting, viommu_nesting_dirty;
+- uint32_t type, flags = 0;
++ uint32_t type = IOMMU_HW_INFO_TYPE_DEFAULT, flags = 0;
+ uint64_t hw_caps;
+ VendorCaps caps;
+ VFIOIOASHwpt *hwpt;
+@@ -897,7 +897,7 @@ static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
+ HostIOMMUDeviceIOMMUFD *idev;
+ HostIOMMUDeviceCaps *caps = &hiod->caps;
+ VendorCaps *vendor_caps = &caps->vendor_caps;
+- enum iommu_hw_info_type type;
++ uint32_t type = IOMMU_HW_INFO_TYPE_DEFAULT;
+ uint8_t max_pasid_log2;
+ uint64_t hw_caps;
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmu-add-memory-regions-as-property-for-an-SM.patch b/kvm-hw-arm-smmu-add-memory-regions-as-property-for-an-SM.patch
new file mode 100644
index 0000000..0b058c0
--- /dev/null
+++ b/kvm-hw-arm-smmu-add-memory-regions-as-property-for-an-SM.patch
@@ -0,0 +1,210 @@
+From 938b9e6cc71799999c3d2911c3281de87a32ae5a Mon Sep 17 00:00:00 2001
+From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Date: Thu, 15 Jan 2026 15:26:30 +0000
+Subject: [PATCH 004/111] hw/arm/smmu: add memory regions as property for an
+ SMMU instance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [4/111] de140c2d7250de6154e18e036a7a114502a43867 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+This will be used to access non-secure and secure memory. Secure support
+and Granule Protection Check (for RME) for SMMU need to access secure
+memory.
+
+As well, it allows to remove usage of global address_space_memory,
+allowing different SMMU instances to have a specific view of memory.
+
+User creatable SMMU are handled as well for virt machine,
+by setting the memory properties when device is plugged in.
+
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260108210453.2280733-1-pierrick.bouvier@linaro.org
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 53b54a82520f23da2be49cc0d69210a086fc7072)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/sbsa-ref.c | 16 ++++++++++++----
+ hw/arm/smmu-common.c | 11 +++++++++++
+ hw/arm/virt.c | 13 +++++++++++--
+ include/hw/arm/smmu-common.h | 4 ++++
+ include/hw/arm/virt.h | 2 ++
+ 5 files changed, 40 insertions(+), 6 deletions(-)
+
+diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
+index 15c1ff4b14..48c2054be0 100644
+--- a/hw/arm/sbsa-ref.c
++++ b/hw/arm/sbsa-ref.c
+@@ -611,7 +611,9 @@ static void create_xhci(const SBSAMachineState *sms)
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
+ }
+
+-static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
++static void create_smmu(const SBSAMachineState *sms, PCIBus *bus,
++ MemoryRegion *sysmem,
++ MemoryRegion *secure_sysmem)
+ {
+ hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
+ int irq = sbsa_ref_irqmap[SBSA_SMMU];
+@@ -623,6 +625,10 @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
+ object_property_set_str(OBJECT(dev), "stage", "nested", &error_abort);
+ object_property_set_link(OBJECT(dev), "primary-bus", OBJECT(bus),
+ &error_abort);
++ object_property_set_link(OBJECT(dev), "memory", OBJECT(sysmem),
++ &error_abort);
++ object_property_set_link(OBJECT(dev), "secure-memory", OBJECT(secure_sysmem),
++ &error_abort);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
+ for (i = 0; i < NUM_SMMU_IRQS; i++) {
+@@ -631,7 +637,9 @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
+ }
+ }
+
+-static void create_pcie(SBSAMachineState *sms)
++static void create_pcie(SBSAMachineState *sms,
++ MemoryRegion *sysmem,
++ MemoryRegion *secure_sysmem)
+ {
+ hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
+ hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
+@@ -687,7 +695,7 @@ static void create_pcie(SBSAMachineState *sms)
+
+ pci_create_simple(pci->bus, -1, "bochs-display");
+
+- create_smmu(sms, pci->bus);
++ create_smmu(sms, pci->bus, sysmem, secure_sysmem);
+ }
+
+ static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
+@@ -823,7 +831,7 @@ static void sbsa_ref_init(MachineState *machine)
+
+ create_xhci(sms);
+
+- create_pcie(sms);
++ create_pcie(sms, sysmem, secure_sysmem);
+
+ create_secure_ec(secure_sysmem);
+
+diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
+index 59d6147ec9..75d840e389 100644
+--- a/hw/arm/smmu-common.c
++++ b/hw/arm/smmu-common.c
+@@ -952,6 +952,13 @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
+ return;
+ }
+
++ g_assert(s->memory);
++ address_space_init(&s->memory_as, s->memory, "smmu-memory-view");
++ if (s->secure_memory) {
++ address_space_init(&s->secure_memory_as, s->secure_memory,
++ "smmu-secure-memory-view");
++ }
++
+ /*
+ * We only allow default PCIe Root Complex(pcie.0) or pxb-pcie based extra
+ * root complexes to be associated with SMMU.
+@@ -1002,6 +1009,10 @@ static const Property smmu_dev_properties[] = {
+ DEFINE_PROP_BOOL("smmu_per_bus", SMMUState, smmu_per_bus, false),
+ DEFINE_PROP_LINK("primary-bus", SMMUState, primary_bus,
+ TYPE_PCI_BUS, PCIBus *),
++ DEFINE_PROP_LINK("memory", SMMUState, memory,
++ TYPE_MEMORY_REGION, MemoryRegion *),
++ DEFINE_PROP_LINK("secure-memory", SMMUState, secure_memory,
++ TYPE_MEMORY_REGION, MemoryRegion *),
+ };
+
+ static void smmu_base_class_init(ObjectClass *klass, const void *data)
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index 5bb6ba7de7..e3e0233474 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -1526,8 +1526,7 @@ static void create_smmuv3_dev_dtb(VirtMachineState *vms,
+ 0x0, vms->iommu_phandle, 0x0, 0x10000);
+ }
+
+-static void create_smmu(const VirtMachineState *vms,
+- PCIBus *bus)
++static void create_smmu(const VirtMachineState *vms, PCIBus *bus)
+ {
+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
+ int irq = vms->irqmap[VIRT_SMMU];
+@@ -1547,6 +1546,10 @@ static void create_smmu(const VirtMachineState *vms,
+ }
+ object_property_set_link(OBJECT(dev), "primary-bus", OBJECT(bus),
+ &error_abort);
++ object_property_set_link(OBJECT(dev), "memory", OBJECT(vms->sysmem),
++ &error_abort);
++ object_property_set_link(OBJECT(dev), "secure-memory", OBJECT(vms->secure_sysmem),
++ &error_abort);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
+ for (i = 0; i < NUM_SMMU_IRQS; i++) {
+@@ -1621,6 +1624,7 @@ static void create_pcie(VirtMachineState *vms)
+ memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
+ ecam_reg, 0, size_ecam);
+ memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias);
++ vms->sysmem = get_system_memory();
+
+ /* Map the MMIO window into system address space so as to expose
+ * the section of PCI MMIO space which starts at the same base address
+@@ -2279,6 +2283,7 @@ static void machvirt_init(MachineState *machine)
+ * devices go in at higher priority and take precedence.
+ */
+ secure_sysmem = g_new(MemoryRegion, 1);
++ vms->secure_sysmem = secure_sysmem;
+ memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
+ UINT64_MAX);
+ memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
+@@ -3082,6 +3087,10 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+ } else if (vms->iommu == VIRT_IOMMU_NONE) {
+ /* The new SMMUv3 device is specific to the PCI bus */
+ object_property_set_bool(OBJECT(dev), "smmu_per_bus", true, NULL);
++ object_property_set_link(OBJECT(dev), "memory",
++ OBJECT(vms->sysmem), NULL);
++ object_property_set_link(OBJECT(dev), "secure-memory",
++ OBJECT(vms->secure_sysmem), NULL);
+ }
+ }
+ }
+diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
+index d307ddd952..e626c6c567 100644
+--- a/include/hw/arm/smmu-common.h
++++ b/include/hw/arm/smmu-common.h
+@@ -162,6 +162,10 @@ struct SMMUState {
+ uint8_t bus_num;
+ PCIBus *primary_bus;
+ bool smmu_per_bus; /* SMMU is specific to the primary_bus */
++ MemoryRegion *memory;
++ AddressSpace memory_as;
++ MemoryRegion *secure_memory;
++ AddressSpace secure_memory_as;
+ };
+
+ struct SMMUBaseClass {
+diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
+index 98b877c8b9..8d90b66b87 100644
+--- a/include/hw/arm/virt.h
++++ b/include/hw/arm/virt.h
+@@ -181,6 +181,8 @@ struct VirtMachineState {
+ bool ns_el2_virt_timer_irq;
+ CXLState cxl_devices_state;
+ bool legacy_smmuv3_present;
++ MemoryRegion *sysmem;
++ MemoryRegion *secure_sysmem;
+ };
+
+ #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmu-common-Factor-out-common-helper-function.patch b/kvm-hw-arm-smmu-common-Factor-out-common-helper-function.patch
new file mode 100644
index 0000000..72cf640
--- /dev/null
+++ b/kvm-hw-arm-smmu-common-Factor-out-common-helper-function.patch
@@ -0,0 +1,124 @@
+From 918055b41105a10c2378ffd6d6c24543a66a11e4 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 003/111] hw/arm/smmu-common: Factor out common helper
+ functions and export
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [3/111] 24724b112687ea545700cdf9580220b83c302707 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Factor out common helper functions and export. Subsequent patches for
+smmuv3 accel support will make use of this.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-4-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 8d9633f1edbbdf693f39106a23dc020476cc2ebc)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmu-common.c | 44 +++++++++++++++++++++---------------
+ include/hw/arm/smmu-common.h | 6 +++++
+ 2 files changed, 32 insertions(+), 18 deletions(-)
+
+diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
+index 62a7612184..59d6147ec9 100644
+--- a/hw/arm/smmu-common.c
++++ b/hw/arm/smmu-common.c
+@@ -847,12 +847,24 @@ SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num)
+ return NULL;
+ }
+
+-static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
++void smmu_init_sdev(SMMUState *s, SMMUDevice *sdev, PCIBus *bus, int devfn)
+ {
+- SMMUState *s = opaque;
+- SMMUPciBus *sbus = g_hash_table_lookup(s->smmu_pcibus_by_busptr, bus);
+- SMMUDevice *sdev;
+ static unsigned int index;
++ g_autofree char *name = g_strdup_printf("%s-%d-%d", s->mrtypename, devfn,
++ index++);
++ sdev->smmu = s;
++ sdev->bus = bus;
++ sdev->devfn = devfn;
++
++ memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu),
++ s->mrtypename, OBJECT(s), name, UINT64_MAX);
++ address_space_init(&sdev->as, MEMORY_REGION(&sdev->iommu), name);
++ trace_smmu_add_mr(name);
++}
++
++SMMUPciBus *smmu_get_sbus(SMMUState *s, PCIBus *bus)
++{
++ SMMUPciBus *sbus = g_hash_table_lookup(s->smmu_pcibus_by_busptr, bus);
+
+ if (!sbus) {
+ sbus = g_malloc0(sizeof(SMMUPciBus) +
+@@ -861,23 +873,19 @@ static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
+ g_hash_table_insert(s->smmu_pcibus_by_busptr, bus, sbus);
+ }
+
++ return sbus;
++}
++
++static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
++{
++ SMMUState *s = opaque;
++ SMMUPciBus *sbus = smmu_get_sbus(s, bus);
++ SMMUDevice *sdev;
++
+ sdev = sbus->pbdev[devfn];
+ if (!sdev) {
+- char *name = g_strdup_printf("%s-%d-%d", s->mrtypename, devfn, index++);
+-
+ sdev = sbus->pbdev[devfn] = g_new0(SMMUDevice, 1);
+-
+- sdev->smmu = s;
+- sdev->bus = bus;
+- sdev->devfn = devfn;
+-
+- memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu),
+- s->mrtypename,
+- OBJECT(s), name, UINT64_MAX);
+- address_space_init(&sdev->as,
+- MEMORY_REGION(&sdev->iommu), name);
+- trace_smmu_add_mr(name);
+- g_free(name);
++ smmu_init_sdev(s, sdev, bus, devfn);
+ }
+
+ return &sdev->as;
+diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
+index 80d0fecfde..d307ddd952 100644
+--- a/include/hw/arm/smmu-common.h
++++ b/include/hw/arm/smmu-common.h
+@@ -180,6 +180,12 @@ OBJECT_DECLARE_TYPE(SMMUState, SMMUBaseClass, ARM_SMMU)
+ /* Return the SMMUPciBus handle associated to a PCI bus number */
+ SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num);
+
++/* Return the SMMUPciBus handle associated to a PCI bus */
++SMMUPciBus *smmu_get_sbus(SMMUState *s, PCIBus *bus);
++
++/* Initialize SMMUDevice handle associated to a SMMUPciBus */
++void smmu_init_sdev(SMMUState *s, SMMUDevice *sdev, PCIBus *bus, int devfn);
++
+ /* Return the stream ID of an SMMU device */
+ static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
+ {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmu-common-Make-iommu-ops-part-of-SMMUState.patch b/kvm-hw-arm-smmu-common-Make-iommu-ops-part-of-SMMUState.patch
new file mode 100644
index 0000000..fe1a00c
--- /dev/null
+++ b/kvm-hw-arm-smmu-common-Make-iommu-ops-part-of-SMMUState.patch
@@ -0,0 +1,77 @@
+From 060b817ebbd77d3ec0a7a9d7bdfce8df4ce3e7e6 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 006/111] hw/arm/smmu-common: Make iommu ops part of SMMUState
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [6/111] 1a120125bce9df1d6897d71d66ed94f72c3a615d (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Make iommu ops part of SMMUState and set to the current default smmu_ops.
+No functional change intended. This will allow SMMUv3 accel implementation
+to set a different iommu ops later.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-5-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 797fffedac9355495c010a12d4766517db2aa911)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmu-common.c | 7 +++++--
+ include/hw/arm/smmu-common.h | 1 +
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
+index 75d840e389..d70ca81775 100644
+--- a/hw/arm/smmu-common.c
++++ b/hw/arm/smmu-common.c
+@@ -959,6 +959,9 @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
+ "smmu-secure-memory-view");
+ }
+
++ if (!s->iommu_ops) {
++ s->iommu_ops = &smmu_ops;
++ }
+ /*
+ * We only allow default PCIe Root Complex(pcie.0) or pxb-pcie based extra
+ * root complexes to be associated with SMMU.
+@@ -978,9 +981,9 @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
+ }
+
+ if (s->smmu_per_bus) {
+- pci_setup_iommu_per_bus(pci_bus, &smmu_ops, s);
++ pci_setup_iommu_per_bus(pci_bus, s->iommu_ops, s);
+ } else {
+- pci_setup_iommu(pci_bus, &smmu_ops, s);
++ pci_setup_iommu(pci_bus, s->iommu_ops, s);
+ }
+ return;
+ }
+diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
+index e626c6c567..ffcac991de 100644
+--- a/include/hw/arm/smmu-common.h
++++ b/include/hw/arm/smmu-common.h
+@@ -166,6 +166,7 @@ struct SMMUState {
+ AddressSpace memory_as;
+ MemoryRegion *secure_memory;
+ AddressSpace secure_memory_as;
++ const PCIIOMMUOps *iommu_ops;
+ };
+
+ struct SMMUBaseClass {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Add-accel-property-for-SMMUv3-device.patch b/kvm-hw-arm-smmuv3-Add-accel-property-for-SMMUv3-device.patch
new file mode 100644
index 0000000..354f63b
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Add-accel-property-for-SMMUv3-device.patch
@@ -0,0 +1,179 @@
+From 3f2d3f5c1d9a64009abfa03f01ddd2411449ff5f Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 036/111] hw/arm/smmuv3: Add accel property for SMMUv3 device
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [36/111] baba44ac01f76bcea04c4366994441a55cb7cb5e (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Add an "accel" property to enable SMMUv3 accelerator mode.
+
+Accelerator mode relies on IORT RMR entries for MSI support and is
+therefore not supported when booting with a device tree.
+
+In this mode, the host SMMUv3 operates in nested translation
+(Stage-1 + Stage-2), with the guest owning the Stage-1 page tables.
+Expose only Stage-1 to the guest to ensure it uses the correct page
+table format
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-29-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 6cc3a621c6f184ffa04bf68f7a57323c63f6ef56)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 32 ++++++++++++++++++++++++++++++++
+ hw/arm/virt-acpi-build.c | 4 +---
+ hw/arm/virt.c | 22 +++++++++++++---------
+ 3 files changed, 46 insertions(+), 12 deletions(-)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 6faa660bab..0d2f5a9b0c 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1916,6 +1916,29 @@ static void smmu_reset_exit(Object *obj, ResetType type)
+ smmuv3_accel_reset(s);
+ }
+
++static bool smmu_validate_property(SMMUv3State *s, Error **errp)
++{
++#ifndef CONFIG_ARM_SMMUV3_ACCEL
++ if (s->accel) {
++ error_setg(errp, "accel=on support not compiled in");
++ return false;
++ }
++#endif
++
++ if (!s->accel) {
++ return true;
++ }
++
++ /* If no stage specified, SMMUv3 defaults to stage 1 */
++ if (s->stage && strcmp(s->stage, "1")) {
++ error_setg(errp,
++ "Only stage1 is supported for SMMUv3 with accel=on");
++ return false;
++ }
++
++ return true;
++}
++
+ static void smmu_realize(DeviceState *d, Error **errp)
+ {
+ SMMUState *sys = ARM_SMMU(d);
+@@ -1924,6 +1947,10 @@ static void smmu_realize(DeviceState *d, Error **errp)
+ SysBusDevice *dev = SYS_BUS_DEVICE(d);
+ Error *local_err = NULL;
+
++ if (!smmu_validate_property(s, errp)) {
++ return;
++ }
++
+ if (s->accel) {
+ smmuv3_accel_init(s);
+ error_setg(&s->migration_blocker, "Migration not supported with SMMUv3 "
+@@ -2029,6 +2056,7 @@ static const Property smmuv3_properties[] = {
+ * Defaults to stage 1
+ */
+ DEFINE_PROP_STRING("stage", SMMUv3State, stage),
++ DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false),
+ /* GPA of MSI doorbell, for SMMUv3 accel use. */
+ DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
+ };
+@@ -2052,6 +2080,10 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ device_class_set_props(dc, smmuv3_properties);
+ dc->hotpluggable = false;
+ dc->user_creatable = true;
++
++ object_class_property_set_description(klass, "accel",
++ "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
++ "configured in nested mode for vfio-pci dev assignment");
+ }
+
+ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
+index 1323d1a0da..33c6519f0a 100644
+--- a/hw/arm/virt-acpi-build.c
++++ b/hw/arm/virt-acpi-build.c
+@@ -406,9 +406,7 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
+ }
+
+ bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
+- if (object_property_find(obj, "accel")) {
+- sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
+- }
++ sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
+ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+ sbdev = SYS_BUS_DEVICE(obj);
+ sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index 672b8d912c..5486af4456 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -1503,8 +1503,8 @@ static void create_smmuv3_dt_bindings(const VirtMachineState *vms, hwaddr base,
+ g_free(node);
+ }
+
+-static void create_smmuv3_dev_dtb(VirtMachineState *vms,
+- DeviceState *dev, PCIBus *bus)
++static void create_smmuv3_dev_dtb(VirtMachineState *vms, DeviceState *dev,
++ PCIBus *bus, Error **errp)
+ {
+ PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+ SysBusDevice *sbdev = SYS_BUS_DEVICE(dev);
+@@ -1512,10 +1512,15 @@ static void create_smmuv3_dev_dtb(VirtMachineState *vms,
+ hwaddr base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+ MachineState *ms = MACHINE(vms);
+
+- if (!(vms->bootinfo.firmware_loaded && virt_is_acpi_enabled(vms)) &&
+- strcmp("pcie.0", bus->qbus.name)) {
+- warn_report("SMMUv3 device only supported with pcie.0 for DT");
+- return;
++ if (!(vms->bootinfo.firmware_loaded && virt_is_acpi_enabled(vms))) {
++ if (object_property_get_bool(OBJECT(dev), "accel", &error_abort)) {
++ error_setg(errp, "SMMUv3 with accel=on not supported for DT");
++ return;
++ }
++ if (strcmp("pcie.0", bus->qbus.name)) {
++ warn_report("SMMUv3 device only supported with pcie.0 for DT");
++ return;
++ }
+ }
+ base += vms->memmap[VIRT_PLATFORM_BUS].base;
+ irq += vms->irqmap[VIRT_PLATFORM_BUS];
+@@ -3092,8 +3097,7 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+ object_property_set_link(OBJECT(dev), "secure-memory",
+ OBJECT(vms->secure_sysmem), NULL);
+ }
+- if (object_property_find(OBJECT(dev), "accel") &&
+- object_property_get_bool(OBJECT(dev), "accel", &error_abort)) {
++ if (object_property_get_bool(OBJECT(dev), "accel", &error_abort)) {
+ hwaddr db_start = 0;
+
+ if (!kvm_enabled() || !kvm_irqchip_in_kernel()) {
+@@ -3148,7 +3152,7 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
+ return;
+ }
+
+- create_smmuv3_dev_dtb(vms, dev, bus);
++ create_smmuv3_dev_dtb(vms, dev, bus, errp);
+ }
+ }
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Add-cmdqv-property-for-SMMUv3-device.patch b/kvm-hw-arm-smmuv3-Add-cmdqv-property-for-SMMUv3-device.patch
new file mode 100644
index 0000000..b449b91
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Add-cmdqv-property-for-SMMUv3-device.patch
@@ -0,0 +1,92 @@
+From 00aaa67fff49aa2dabd33cc51975e2d09287af60 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:52 +0100
+Subject: [PATCH 110/111] hw/arm/smmuv3: Add cmdqv property for SMMUv3 device
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [110/111] afd980dfcdcf4d602312a4c65fedf19f08fc6c3b (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Conflicts: contextual conflict in qemu-options.hx as we don't
+have amd-iommu device documentation downstream
+
+Introduce a "cmdqv" property to enable Tegra241 CMDQV support.
+This is only enabled for accelerated SMMUv3 devices.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-32-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit fced8da695f9f40842aa87d0dfde365c8ef65a36)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 8 ++++++++
+ qemu-options.hx | 8 ++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 9e252bca66..931c2fe710 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1994,6 +1994,10 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ "bits if accel=on");
+ return false;
+ }
++ if (s->cmdqv == ON_OFF_AUTO_ON) {
++ error_setg(errp, "cmdqv can only be enabled if accel=on");
++ return false;
++ }
+ return true;
+ }
+
+@@ -2144,6 +2148,7 @@ static const Property smmuv3_properties[] = {
+ DEFINE_PROP_OAS_MODE("oas", SMMUv3State, oas, OAS_MODE_AUTO),
+ DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
+ SSID_SIZE_MODE_AUTO),
++ DEFINE_PROP_ON_OFF_AUTO("cmdqv", SMMUv3State, cmdqv, ON_OFF_AUTO_AUTO),
+ };
+
+ static void smmuv3_instance_init(Object *obj)
+@@ -2194,6 +2199,9 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "than 0 is required to enable PASID support."
+ "Please ensure the value does not exceed the maximum "
+ "SubstreamID size supported by the host platform.");
++ object_class_property_set_description(klass, "cmdqv",
++ "Enable/disable CMDQV support (for accel=on). "
++ "Valid values are on, off, and auto. Defaults to auto.");
+ }
+
+ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 3fe2171e70..c0e863bb00 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -1281,6 +1281,14 @@ SRST
+
+ - With accel=off, auto is resolved to 0.
+
++ ``cmdqv=on|off|auto`` (default: auto)
++ Enable hardware Command Queue Virtualization (CMDQV) for the
++ SMMUv3 command queue. Currently only the NVIDIA Tegra241 CMDQV
++ implementation is supported.
++
++ - With accel=on, auto means the value is automatically derived from the host SMMU.
++ - With accel=off, auto is resolved to 'off'.
++
+ ERST
+
+ DEF("name", HAS_ARG, QEMU_OPTION_name,
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Add-per-device-identifier-property.patch b/kvm-hw-arm-smmuv3-Add-per-device-identifier-property.patch
new file mode 100644
index 0000000..d0b2bf5
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Add-per-device-identifier-property.patch
@@ -0,0 +1,136 @@
+From 370cea17a431430e0a69d659b75c9ef9295191e4 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:47 +0100
+Subject: [PATCH 105/111] hw/arm/smmuv3: Add per-device identifier property
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [105/111] 96bf9c1f23c27769323425ffd01bf0baf4809454 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Add an "identifier" property to the SMMUv3 device and use it when
+building the ACPI IORT SMMUv3 node Identifier field.
+
+This avoids relying on device enumeration order and provides a stable
+per-device identifier. A subsequent patch will use the same identifier
+when generating the DSDT description for Tegra241 CMDQV, ensuring that
+the IORT and DSDT entries refer to the same SMMUv3 instance.
+
+The identifier is assigned at pre-plug time, accounting for the ITS Group
+node that build_iort() places before SMMUv3 nodes in the IORT table, so
+that identifiers are globally unique across all IORT nodes.
+
+No functional change: IORT blob content for bios-tables qtest is identical
+to before.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-27-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit eb7a06e842409f41cbd85b01086d8e6a2b9c4774)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 2 ++
+ hw/arm/virt-acpi-build.c | 5 ++++-
+ hw/arm/virt.c | 12 ++++++++++++
+ include/hw/arm/smmuv3.h | 1 +
+ 4 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 1e98ee0e76..9e252bca66 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -2126,6 +2126,8 @@ static const Property smmuv3_properties[] = {
+ * Defaults to stage 1
+ */
+ DEFINE_PROP_STRING("stage", SMMUv3State, stage),
++ /* Identifier used for ACPI IORT SMMUv3 (and DSDT for CMDQV) generation */
++ DEFINE_PROP_UINT8("identifier", SMMUv3State, identifier, 0),
+ DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false),
+ /* GPA of MSI doorbell, for SMMUv3 accel use. */
+ DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
+diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
+index 597d51199c..20dfe9e4d8 100644
+--- a/hw/arm/virt-acpi-build.c
++++ b/hw/arm/virt-acpi-build.c
+@@ -348,6 +348,7 @@ static int iort_idmap_compare(gconstpointer a, gconstpointer b)
+ typedef struct AcpiIortSMMUv3Dev {
+ int irq;
+ hwaddr base;
++ uint8_t id;
+ GArray *rc_smmu_idmaps;
+ /* Offset of the SMMUv3 IORT Node relative to the start of the IORT */
+ size_t offset;
+@@ -410,6 +411,7 @@ static int populate_smmuv3_dev(VirtMachineState *vms, GArray *sdev_blob)
+ &error_abort));
+ sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
+ sdev.ats = smmuv3_ats_enabled(ARM_SMMUV3(obj));
++ sdev.id = object_property_get_uint(obj, "identifier", &error_abort);
+ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+ sbdev = SYS_BUS_DEVICE(obj);
+ sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+@@ -636,7 +638,8 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ (ID_MAPPING_ENTRY_SIZE * smmu_mapping_count);
+ build_append_int_noprefix(table_data, node_size, 2); /* Length */
+ build_append_int_noprefix(table_data, 4, 1); /* Revision */
+- build_append_int_noprefix(table_data, id++, 4); /* Identifier */
++ build_append_int_noprefix(table_data, sdev->id, 4); /* Identifier */
++ id++; /* advance shared counter for RC/RMR node uniqueness */
+ /* Number of ID mappings */
+ build_append_int_noprefix(table_data, smmu_mapping_count, 4);
+ /* Reference to ID Array */
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index ca150d455c..dc993cbaa1 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -264,6 +264,9 @@ static MemMapEntry extended_memmap[] = {
+ /* Any CXL Fixed memory windows come here */
+ };
+
++/* Counts SMMUv3 devices plugged; used to assign stable IORT identifiers */
++static uint8_t smmuv3_dev_id;
++
+ static const int a15irqmap[] = {
+ [VIRT_UART0] = 1,
+ [VIRT_RTC] = 2,
+@@ -3118,6 +3121,15 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+ OBJECT(vms->sysmem), NULL);
+ object_property_set_link(OBJECT(dev), "secure-memory",
+ OBJECT(vms->secure_sysmem), NULL);
++ /*
++ * In build_iort(), the ITS node(id=0) precedes SMMUv3 nodes
++ * when present. Account for it so this SMMUv3's identifier
++ * is globally unique across all IORT nodes.
++ */
++ uint8_t its_offset = (vms->msi_controller == VIRT_MSI_CTRL_ITS)
++ ? 1 : 0;
++ object_property_set_uint(OBJECT(dev), "identifier",
++ its_offset + smmuv3_dev_id++, NULL);
+ }
+ if (object_property_get_bool(OBJECT(dev), "accel", &error_abort)) {
+ hwaddr db_start = 0;
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index 34d0f65eaa..d39fe8850b 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -65,6 +65,7 @@ struct SMMUv3State {
+ qemu_irq irq[4];
+ QemuMutex mutex;
+ char *stage;
++ uint8_t identifier;
+
+ /* SMMU has HW accelerator support for nested S1 + s2 */
+ bool accel;
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Avoid-including-CONFIG_DEVICES-in-hw-h.patch b/kvm-hw-arm-smmuv3-Avoid-including-CONFIG_DEVICES-in-hw-h.patch
new file mode 100644
index 0000000..ad2d9b6
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Avoid-including-CONFIG_DEVICES-in-hw-h.patch
@@ -0,0 +1,178 @@
+From b1520bc26a36eca3f4ea73606dcec1081918e323 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
+Date: Tue, 10 Mar 2026 12:06:19 +0100
+Subject: [PATCH 085/111] hw/arm/smmuv3: Avoid including CONFIG_DEVICES in hw/
+ header
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [85/111] 9e4fac5674fbf767b565deab18de671a3cdecdbd (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+By turning the inline functions into stubs we can avoid the
+use of target-specific CONFIG_DEVICES include in a hw/ header,
+allowing to build the source files including it as common objects.
+
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-Id: <20260410200031.18572-3-philmd@linaro.org>
+(cherry picked from commit 12ce4d9630ae09edec706f6254417e3ec96e08e5)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/meson.build | 5 ++--
+ hw/arm/smmuv3-accel-stubs.c | 52 +++++++++++++++++++++++++++++++++++++
+ hw/arm/smmuv3-accel.h | 42 ------------------------------
+ 3 files changed, 55 insertions(+), 44 deletions(-)
+ create mode 100644 hw/arm/smmuv3-accel-stubs.c
+
+diff --git a/hw/arm/meson.build b/hw/arm/meson.build
+index bcb27c0bf6..b3f2e4d5dd 100644
+--- a/hw/arm/meson.build
++++ b/hw/arm/meson.build
+@@ -61,8 +61,9 @@ arm_common_ss.add(when: 'CONFIG_ARMSSE', if_true: files('armsse.c'))
+ arm_common_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.c'))
+ arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP', if_true: files('fsl-imx8mp.c'))
+ arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP_EVK', if_true: files('imx8mp-evk.c'))
+-arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
+-arm_ss.add(when: 'CONFIG_ARM_SMMUV3_ACCEL', if_true: files('smmuv3-accel.c'))
++arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
++arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3_ACCEL', if_true: files('smmuv3-accel.c'))
++stub_ss.add(files('smmuv3-accel-stubs.c'))
+ arm_common_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
+ arm_common_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
+ arm_ss.add(when: 'CONFIG_XEN', if_true: files(
+diff --git a/hw/arm/smmuv3-accel-stubs.c b/hw/arm/smmuv3-accel-stubs.c
+new file mode 100644
+index 0000000000..70cef66966
+--- /dev/null
++++ b/hw/arm/smmuv3-accel-stubs.c
+@@ -0,0 +1,52 @@
++/*
++ * Stubs for accelerated SMMU instance backed by an iommufd vIOMMU object.
++ *
++ * SPDX-License-Identifier: GPL-2.0-or-later
++ */
++
++#include "qemu/osdep.h"
++#include "qapi/error.h"
++#include "hw/arm/smmuv3.h"
++#include "hw/arm/smmuv3-accel.h"
++
++bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
++{
++ error_setg(errp, "accel=on support not compiled in");
++ return false;
++}
++
++bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
++ Error **errp)
++{
++ return true;
++}
++
++bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
++ Error **errp)
++{
++ return true;
++}
++
++bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
++{
++ return true;
++}
++
++bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
++ Error **errp)
++{
++ return true;
++}
++
++void smmuv3_accel_idr_override(SMMUv3State *s)
++{
++}
++
++bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp)
++{
++ return true;
++}
++
++void smmuv3_accel_reset(SMMUv3State *s)
++{
++}
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index 849015f98e..b45f25ad03 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -15,7 +15,6 @@
+ #ifdef CONFIG_LINUX
+ #include <linux/iommufd.h>
+ #endif
+-#include CONFIG_DEVICES
+
+ /*
+ * CMDQ-Virtualization (CMDQV) hardware support, extends the SMMUv3 to
+@@ -77,7 +76,6 @@ typedef struct SMMUv3AccelDevice {
+ SMMUv3AccelState *s_accel;
+ } SMMUv3AccelDevice;
+
+-#ifdef CONFIG_ARM_SMMUV3_ACCEL
+ bool smmuv3_accel_init(SMMUv3State *s, Error **errp);
+ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+ Error **errp);
+@@ -89,45 +87,5 @@ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
+ void smmuv3_accel_idr_override(SMMUv3State *s);
+ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp);
+ void smmuv3_accel_reset(SMMUv3State *s);
+-#else
+-#include "qapi/error.h"
+-static inline bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+-{
+- error_setg(errp, "accel=on support not compiled in");
+- return false;
+-}
+-static inline bool
+-smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+- Error **errp)
+-{
+- return true;
+-}
+-static inline bool
+-smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
+- Error **errp)
+-{
+- return true;
+-}
+-static inline bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
+-{
+- return true;
+-}
+-static inline bool
+-smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
+- Error **errp)
+-{
+- return true;
+-}
+-static inline void smmuv3_accel_idr_override(SMMUv3State *s)
+-{
+-}
+-static inline bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp)
+-{
+- return true;
+-}
+-static inline void smmuv3_accel_reset(SMMUv3State *s)
+-{
+-}
+-#endif
+
+ #endif /* HW_ARM_SMMUV3_ACCEL_H */
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Block-migration-when-accel-is-enabled.patch b/kvm-hw-arm-smmuv3-Block-migration-when-accel-is-enabled.patch
new file mode 100644
index 0000000..b9de00f
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Block-migration-when-accel-is-enabled.patch
@@ -0,0 +1,80 @@
+From 81b2907455241359747060e7ccd97f7cdfeaefe0 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 035/111] hw/arm/smmuv3: Block migration when accel is enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [35/111] 8765c2972ab5482b548e8799ed48e3a15505f74c (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Live migration is not supported when the SMMUv3 accelerator mode is
+enabled. Add a migration blocker to prevent migration in this
+configuration.
+
+Conflicts: use hw/irq.h and hw/sysbus.h instead of hw/core/*
+because we don't have
+32222dc3bbd1 include: move hw/irq.h to hw/core/ nor
+c755f3b95964 include: move hw/sysbus.h to hw/core
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-28-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit be0cf3c8f121f5c0ec398429666d2ef0e88aa37a)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 6 ++++++
+ include/hw/arm/smmuv3.h | 1 +
+ 2 files changed, 7 insertions(+)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index dba5abc8d3..6faa660bab 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -20,6 +20,7 @@
+ #include "qemu/bitops.h"
+ #include "hw/irq.h"
+ #include "hw/sysbus.h"
++#include "migration/blocker.h"
+ #include "migration/vmstate.h"
+ #include "hw/qdev-properties.h"
+ #include "hw/qdev-core.h"
+@@ -1925,6 +1926,11 @@ static void smmu_realize(DeviceState *d, Error **errp)
+
+ if (s->accel) {
+ smmuv3_accel_init(s);
++ error_setg(&s->migration_blocker, "Migration not supported with SMMUv3 "
++ "accelerator mode enabled");
++ if (migrate_add_blocker(&s->migration_blocker, errp) < 0) {
++ return;
++ }
+ }
+
+ c->parent_realize(d, &local_err);
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index 5616a8a2be..9c39acd5ca 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -68,6 +68,7 @@ struct SMMUv3State {
+ bool accel;
+ struct SMMUv3AccelState *s_accel;
+ uint64_t msi_gpa;
++ Error *migration_blocker;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Correct-SMMUEN-field-name-in-CR0.patch b/kvm-hw-arm-smmuv3-Correct-SMMUEN-field-name-in-CR0.patch
new file mode 100644
index 0000000..e66e2de
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Correct-SMMUEN-field-name-in-CR0.patch
@@ -0,0 +1,69 @@
+From f34e634b62b520727c41a992cc22891b6d3e7ac2 Mon Sep 17 00:00:00 2001
+From: Tao Tang <tangtao1634@phytium.com.cn>
+Date: Wed, 4 Mar 2026 22:23:43 +0800
+Subject: [PATCH 055/111] hw/arm/smmuv3: Correct SMMUEN field name in CR0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [55/111] 33926f3b19af938bd90f11d1c0aa920655940111 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+The FIELD macro for the SMMU enable bit in the CR0 register was
+incorrectly named SMMU_ENABLE.
+
+The ARM SMMUv3 Architecture Specification (both older IHI 0070.E.a and
+newer IHI 0070.G.b) consistently refers to the SMMU enable bit as SMMUEN.
+
+This change makes our implementation consistent with the manual.
+
+Signed-off-by: Tao Tang <tangtao1634@phytium.com.cn>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Reviewed-by: Mostafa Saleh <smostafa@google.com>
+Message-id: 20260304142344.3341444-3-tangtao1634@phytium.com.cn
+Fixes: 10a83cb9887 ("hw/arm/smmuv3: Skeleton")
+Link: https://lists.nongnu.org/archive/html/qemu-arm/2025-09/msg01270.html
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit af15801a61d66510434131ae50c2ad2135fa3de1)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-internal.h | 2 +-
+ include/hw/arm/smmuv3-common.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
+index 466bfd390e..0bfb02a054 100644
+--- a/hw/arm/smmuv3-internal.h
++++ b/hw/arm/smmuv3-internal.h
+@@ -41,7 +41,7 @@ typedef enum SMMUTranslationClass {
+
+ static inline int smmu_enabled(SMMUv3State *s)
+ {
+- return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE);
++ return FIELD_EX32(s->cr[0], CR0, SMMUEN);
+ }
+
+ /* Command Queue Entry */
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index 4b764ed125..f1d74d6832 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -351,7 +351,7 @@ REG32(IDR5, 0x14)
+ REG32(IIDR, 0x18)
+ REG32(AIDR, 0x1c)
+ REG32(CR0, 0x20)
+- FIELD(CR0, SMMU_ENABLE, 0, 1)
++ FIELD(CR0, SMMUEN, 0, 1)
+ FIELD(CR0, EVENTQEN, 2, 1)
+ FIELD(CR0, CMDQEN, 3, 1)
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Extract-common-definitions-to-smmuv3-c.patch b/kvm-hw-arm-smmuv3-Extract-common-definitions-to-smmuv3-c.patch
new file mode 100644
index 0000000..13638f5
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Extract-common-definitions-to-smmuv3-c.patch
@@ -0,0 +1,611 @@
+From 89c1b05e005bb0bdbcd9439c08738a13d8e94564 Mon Sep 17 00:00:00 2001
+From: Tao Tang <tangtao1634@phytium.com.cn>
+Date: Sun, 21 Dec 2025 11:25:01 +0800
+Subject: [PATCH 005/111] hw/arm/smmuv3: Extract common definitions to
+ smmuv3-common.h
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [5/111] b556c954826de35f2ae70d8b5e7ef936eaa7a2f7 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Move register definitions, command enums, and Stream Table Entry (STE) /
+Context Descriptor (CD) structure definitions from the internal header
+hw/arm/smmuv3-internal.h to a new common header
+include/hw/arm/smmuv3-common.h.
+
+This allows other components, such as generic SMMUv3 tests or test devices,
+to utilize these definitions without including the specific SMMUv3 device
+internal state.
+
+Signed-off-by: Tao Tang <tangtao1634@phytium.com.cn>
+Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-ID: <20260119161112.3841386-2-tangtao1634@phytium.com.cn>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+(cherry picked from commit 81ee3206f05797aeeae4baa0cecae44e5fad5d64)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-internal.h | 255 +------------------------------
+ include/hw/arm/smmuv3-common.h | 268 +++++++++++++++++++++++++++++++++
+ 2 files changed, 269 insertions(+), 254 deletions(-)
+ create mode 100644 include/hw/arm/smmuv3-common.h
+
+diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
+index b6b7399347..8679ab6d09 100644
+--- a/hw/arm/smmuv3-internal.h
++++ b/hw/arm/smmuv3-internal.h
+@@ -23,6 +23,7 @@
+
+ #include "hw/registerfields.h"
+ #include "hw/arm/smmu-common.h"
++#include "hw/arm/smmuv3-common.h"
+
+ typedef enum SMMUTranslationStatus {
+ SMMU_TRANS_DISABLE,
+@@ -38,147 +39,6 @@ typedef enum SMMUTranslationClass {
+ SMMU_CLASS_IN,
+ } SMMUTranslationClass;
+
+-/* MMIO Registers */
+-
+-REG32(IDR0, 0x0)
+- FIELD(IDR0, S2P, 0 , 1)
+- FIELD(IDR0, S1P, 1 , 1)
+- FIELD(IDR0, TTF, 2 , 2)
+- FIELD(IDR0, COHACC, 4 , 1)
+- FIELD(IDR0, BTM, 5 , 1)
+- FIELD(IDR0, HTTU, 6 , 2)
+- FIELD(IDR0, DORMHINT, 8 , 1)
+- FIELD(IDR0, HYP, 9 , 1)
+- FIELD(IDR0, ATS, 10, 1)
+- FIELD(IDR0, NS1ATS, 11, 1)
+- FIELD(IDR0, ASID16, 12, 1)
+- FIELD(IDR0, MSI, 13, 1)
+- FIELD(IDR0, SEV, 14, 1)
+- FIELD(IDR0, ATOS, 15, 1)
+- FIELD(IDR0, PRI, 16, 1)
+- FIELD(IDR0, VMW, 17, 1)
+- FIELD(IDR0, VMID16, 18, 1)
+- FIELD(IDR0, CD2L, 19, 1)
+- FIELD(IDR0, VATOS, 20, 1)
+- FIELD(IDR0, TTENDIAN, 21, 2)
+- FIELD(IDR0, ATSRECERR, 23, 1)
+- FIELD(IDR0, STALL_MODEL, 24, 2)
+- FIELD(IDR0, TERM_MODEL, 26, 1)
+- FIELD(IDR0, STLEVEL, 27, 2)
+- FIELD(IDR0, RME_IMPL, 30, 1)
+-
+-REG32(IDR1, 0x4)
+- FIELD(IDR1, SIDSIZE, 0 , 6)
+- FIELD(IDR1, SSIDSIZE, 6 , 5)
+- FIELD(IDR1, PRIQS, 11, 5)
+- FIELD(IDR1, EVENTQS, 16, 5)
+- FIELD(IDR1, CMDQS, 21, 5)
+- FIELD(IDR1, ATTR_PERMS_OVR, 26, 1)
+- FIELD(IDR1, ATTR_TYPES_OVR, 27, 1)
+- FIELD(IDR1, REL, 28, 1)
+- FIELD(IDR1, QUEUES_PRESET, 29, 1)
+- FIELD(IDR1, TABLES_PRESET, 30, 1)
+- FIELD(IDR1, ECMDQ, 31, 1)
+-
+-#define SMMU_IDR1_SIDSIZE 16
+-#define SMMU_CMDQS 19
+-#define SMMU_EVENTQS 19
+-
+-REG32(IDR2, 0x8)
+- FIELD(IDR2, BA_VATOS, 0, 10)
+-
+-REG32(IDR3, 0xc)
+- FIELD(IDR3, HAD, 2, 1);
+- FIELD(IDR3, PBHA, 3, 1);
+- FIELD(IDR3, XNX, 4, 1);
+- FIELD(IDR3, PPS, 5, 1);
+- FIELD(IDR3, MPAM, 7, 1);
+- FIELD(IDR3, FWB, 8, 1);
+- FIELD(IDR3, STT, 9, 1);
+- FIELD(IDR3, RIL, 10, 1);
+- FIELD(IDR3, BBML, 11, 2);
+- FIELD(IDR3, E0PD, 13, 1);
+- FIELD(IDR3, PTWNNC, 14, 1);
+- FIELD(IDR3, DPT, 15, 1);
+-
+-REG32(IDR4, 0x10)
+-
+-REG32(IDR5, 0x14)
+- FIELD(IDR5, OAS, 0, 3);
+- FIELD(IDR5, GRAN4K, 4, 1);
+- FIELD(IDR5, GRAN16K, 5, 1);
+- FIELD(IDR5, GRAN64K, 6, 1);
+- FIELD(IDR5, VAX, 10, 2);
+- FIELD(IDR5, STALL_MAX, 16, 16);
+-
+-#define SMMU_IDR5_OAS 4
+-
+-REG32(IIDR, 0x18)
+-REG32(AIDR, 0x1c)
+-REG32(CR0, 0x20)
+- FIELD(CR0, SMMU_ENABLE, 0, 1)
+- FIELD(CR0, EVENTQEN, 2, 1)
+- FIELD(CR0, CMDQEN, 3, 1)
+-
+-#define SMMU_CR0_RESERVED 0xFFFFFC20
+-
+-REG32(CR0ACK, 0x24)
+-REG32(CR1, 0x28)
+-REG32(CR2, 0x2c)
+-REG32(STATUSR, 0x40)
+-REG32(GBPA, 0x44)
+- FIELD(GBPA, ABORT, 20, 1)
+- FIELD(GBPA, UPDATE, 31, 1)
+-
+-/* Use incoming. */
+-#define SMMU_GBPA_RESET_VAL 0x1000
+-
+-REG32(IRQ_CTRL, 0x50)
+- FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1)
+- FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1)
+- FIELD(IRQ_CTRL, EVENTQ_IRQEN, 2, 1)
+-
+-REG32(IRQ_CTRL_ACK, 0x54)
+-REG32(GERROR, 0x60)
+- FIELD(GERROR, CMDQ_ERR, 0, 1)
+- FIELD(GERROR, EVENTQ_ABT_ERR, 2, 1)
+- FIELD(GERROR, PRIQ_ABT_ERR, 3, 1)
+- FIELD(GERROR, MSI_CMDQ_ABT_ERR, 4, 1)
+- FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
+- FIELD(GERROR, MSI_PRIQ_ABT_ERR, 6, 1)
+- FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
+- FIELD(GERROR, MSI_SFM_ERR, 8, 1)
+-
+-REG32(GERRORN, 0x64)
+-
+-#define A_GERROR_IRQ_CFG0 0x68 /* 64b */
+-REG32(GERROR_IRQ_CFG1, 0x70)
+-REG32(GERROR_IRQ_CFG2, 0x74)
+-
+-#define A_STRTAB_BASE 0x80 /* 64b */
+-
+-#define SMMU_BASE_ADDR_MASK 0xfffffffffffc0
+-
+-REG32(STRTAB_BASE_CFG, 0x88)
+- FIELD(STRTAB_BASE_CFG, FMT, 16, 2)
+- FIELD(STRTAB_BASE_CFG, SPLIT, 6 , 5)
+- FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
+-
+-#define A_CMDQ_BASE 0x90 /* 64b */
+-REG32(CMDQ_PROD, 0x98)
+-REG32(CMDQ_CONS, 0x9c)
+- FIELD(CMDQ_CONS, ERR, 24, 7)
+-
+-#define A_EVENTQ_BASE 0xa0 /* 64b */
+-REG32(EVENTQ_PROD, 0xa8)
+-REG32(EVENTQ_CONS, 0xac)
+-
+-#define A_EVENTQ_IRQ_CFG0 0xb0 /* 64b */
+-REG32(EVENTQ_IRQ_CFG1, 0xb8)
+-REG32(EVENTQ_IRQ_CFG2, 0xbc)
+-
+-#define A_IDREGS 0xfd0
+-
+ static inline int smmu_enabled(SMMUv3State *s)
+ {
+ return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE);
+@@ -272,37 +132,6 @@ static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
+ s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
+ }
+
+-/* Commands */
+-
+-typedef enum SMMUCommandType {
+- SMMU_CMD_NONE = 0x00,
+- SMMU_CMD_PREFETCH_CONFIG ,
+- SMMU_CMD_PREFETCH_ADDR,
+- SMMU_CMD_CFGI_STE,
+- SMMU_CMD_CFGI_STE_RANGE,
+- SMMU_CMD_CFGI_CD,
+- SMMU_CMD_CFGI_CD_ALL,
+- SMMU_CMD_CFGI_ALL,
+- SMMU_CMD_TLBI_NH_ALL = 0x10,
+- SMMU_CMD_TLBI_NH_ASID,
+- SMMU_CMD_TLBI_NH_VA,
+- SMMU_CMD_TLBI_NH_VAA,
+- SMMU_CMD_TLBI_EL3_ALL = 0x18,
+- SMMU_CMD_TLBI_EL3_VA = 0x1a,
+- SMMU_CMD_TLBI_EL2_ALL = 0x20,
+- SMMU_CMD_TLBI_EL2_ASID,
+- SMMU_CMD_TLBI_EL2_VA,
+- SMMU_CMD_TLBI_EL2_VAA,
+- SMMU_CMD_TLBI_S12_VMALL = 0x28,
+- SMMU_CMD_TLBI_S2_IPA = 0x2a,
+- SMMU_CMD_TLBI_NSNH_ALL = 0x30,
+- SMMU_CMD_ATC_INV = 0x40,
+- SMMU_CMD_PRI_RESP,
+- SMMU_CMD_RESUME = 0x44,
+- SMMU_CMD_STALL_TERM,
+- SMMU_CMD_SYNC,
+-} SMMUCommandType;
+-
+ static const char *cmd_stringify[] = {
+ [SMMU_CMD_PREFETCH_CONFIG] = "SMMU_CMD_PREFETCH_CONFIG",
+ [SMMU_CMD_PREFETCH_ADDR] = "SMMU_CMD_PREFETCH_ADDR",
+@@ -525,64 +354,6 @@ typedef struct SMMUEventInfo {
+
+ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
+
+-/* Configuration Data */
+-
+-/* STE Level 1 Descriptor */
+-typedef struct STEDesc {
+- uint32_t word[2];
+-} STEDesc;
+-
+-/* CD Level 1 Descriptor */
+-typedef struct CDDesc {
+- uint32_t word[2];
+-} CDDesc;
+-
+-/* Stream Table Entry(STE) */
+-typedef struct STE {
+- uint32_t word[16];
+-} STE;
+-
+-/* Context Descriptor(CD) */
+-typedef struct CD {
+- uint32_t word[16];
+-} CD;
+-
+-/* STE fields */
+-
+-#define STE_VALID(x) extract32((x)->word[0], 0, 1)
+-
+-#define STE_CONFIG(x) extract32((x)->word[0], 1, 3)
+-#define STE_CFG_S1_ENABLED(config) (config & 0x1)
+-#define STE_CFG_S2_ENABLED(config) (config & 0x2)
+-#define STE_CFG_ABORT(config) (!(config & 0x4))
+-#define STE_CFG_BYPASS(config) (config == 0x4)
+-
+-#define STE_S1FMT(x) extract32((x)->word[0], 4 , 2)
+-#define STE_S1CDMAX(x) extract32((x)->word[1], 27, 5)
+-#define STE_S1STALLD(x) extract32((x)->word[2], 27, 1)
+-#define STE_EATS(x) extract32((x)->word[2], 28, 2)
+-#define STE_STRW(x) extract32((x)->word[2], 30, 2)
+-#define STE_S2VMID(x) extract32((x)->word[4], 0 , 16)
+-#define STE_S2T0SZ(x) extract32((x)->word[5], 0 , 6)
+-#define STE_S2SL0(x) extract32((x)->word[5], 6 , 2)
+-#define STE_S2TG(x) extract32((x)->word[5], 14, 2)
+-#define STE_S2PS(x) extract32((x)->word[5], 16, 3)
+-#define STE_S2AA64(x) extract32((x)->word[5], 19, 1)
+-#define STE_S2ENDI(x) extract32((x)->word[5], 20, 1)
+-#define STE_S2AFFD(x) extract32((x)->word[5], 21, 1)
+-#define STE_S2HD(x) extract32((x)->word[5], 23, 1)
+-#define STE_S2HA(x) extract32((x)->word[5], 24, 1)
+-#define STE_S2S(x) extract32((x)->word[5], 25, 1)
+-#define STE_S2R(x) extract32((x)->word[5], 26, 1)
+-
+-#define STE_CTXPTR(x) \
+- ((extract64((x)->word[1], 0, 16) << 32) | \
+- ((x)->word[0] & 0xffffffc0))
+-
+-#define STE_S2TTB(x) \
+- ((extract64((x)->word[7], 0, 16) << 32) | \
+- ((x)->word[6] & 0xfffffff0))
+-
+ static inline int oas2bits(int oas_field)
+ {
+ switch (oas_field) {
+@@ -603,30 +374,6 @@ static inline int oas2bits(int oas_field)
+ g_assert_not_reached();
+ }
+
+-/* CD fields */
+-
+-#define CD_VALID(x) extract32((x)->word[0], 31, 1)
+-#define CD_ASID(x) extract32((x)->word[1], 16, 16)
+-#define CD_TTB(x, sel) \
+- ((extract64((x)->word[(sel) * 2 + 3], 0, 19) << 32) | \
+- ((x)->word[(sel) * 2 + 2] & ~0xfULL))
+-
+-#define CD_HAD(x, sel) extract32((x)->word[(sel) * 2 + 2], 1, 1)
+-
+-#define CD_TSZ(x, sel) extract32((x)->word[0], (16 * (sel)) + 0, 6)
+-#define CD_TG(x, sel) extract32((x)->word[0], (16 * (sel)) + 6, 2)
+-#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
+-#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
+-#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
+-#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
+-#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
+-#define CD_HD(x) extract32((x)->word[1], 10 , 1)
+-#define CD_HA(x) extract32((x)->word[1], 11 , 1)
+-#define CD_S(x) extract32((x)->word[1], 12, 1)
+-#define CD_R(x) extract32((x)->word[1], 13, 1)
+-#define CD_A(x) extract32((x)->word[1], 14, 1)
+-#define CD_AARCH64(x) extract32((x)->word[1], 9 , 1)
+-
+ /**
+ * tg2granule - Decodes the CD translation granule size field according
+ * to the ttbr in use
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+new file mode 100644
+index 0000000000..9da817f41a
+--- /dev/null
++++ b/include/hw/arm/smmuv3-common.h
+@@ -0,0 +1,268 @@
++/*
++ * ARM SMMUv3 support - Common API
++ *
++ * Copyright (C) 2014-2016 Broadcom Corporation
++ * Copyright (c) 2017 Red Hat, Inc.
++ * Written by Prem Mallappa, Eric Auger
++ *
++ * SPDX-License-Identifier: GPL-2.0-or-later
++ */
++
++#ifndef HW_ARM_SMMUV3_COMMON_H
++#define HW_ARM_SMMUV3_COMMON_H
++
++/* Configuration Data */
++
++/* STE Level 1 Descriptor */
++typedef struct STEDesc {
++ uint32_t word[2];
++} STEDesc;
++
++/* CD Level 1 Descriptor */
++typedef struct CDDesc {
++ uint32_t word[2];
++} CDDesc;
++
++/* Stream Table Entry(STE) */
++typedef struct STE {
++ uint32_t word[16];
++} STE;
++
++/* Context Descriptor(CD) */
++typedef struct CD {
++ uint32_t word[16];
++} CD;
++
++/* STE fields */
++
++#define STE_VALID(x) extract32((x)->word[0], 0, 1)
++
++#define STE_CONFIG(x) extract32((x)->word[0], 1, 3)
++#define STE_CFG_S1_ENABLED(config) (config & 0x1)
++#define STE_CFG_S2_ENABLED(config) (config & 0x2)
++#define STE_CFG_ABORT(config) (!(config & 0x4))
++#define STE_CFG_BYPASS(config) (config == 0x4)
++
++#define STE_S1FMT(x) extract32((x)->word[0], 4 , 2)
++#define STE_S1CDMAX(x) extract32((x)->word[1], 27, 5)
++#define STE_S1STALLD(x) extract32((x)->word[2], 27, 1)
++#define STE_EATS(x) extract32((x)->word[2], 28, 2)
++#define STE_STRW(x) extract32((x)->word[2], 30, 2)
++#define STE_S2VMID(x) extract32((x)->word[4], 0 , 16)
++#define STE_S2T0SZ(x) extract32((x)->word[5], 0 , 6)
++#define STE_S2SL0(x) extract32((x)->word[5], 6 , 2)
++#define STE_S2TG(x) extract32((x)->word[5], 14, 2)
++#define STE_S2PS(x) extract32((x)->word[5], 16, 3)
++#define STE_S2AA64(x) extract32((x)->word[5], 19, 1)
++#define STE_S2ENDI(x) extract32((x)->word[5], 20, 1)
++#define STE_S2AFFD(x) extract32((x)->word[5], 21, 1)
++#define STE_S2HD(x) extract32((x)->word[5], 23, 1)
++#define STE_S2HA(x) extract32((x)->word[5], 24, 1)
++#define STE_S2S(x) extract32((x)->word[5], 25, 1)
++#define STE_S2R(x) extract32((x)->word[5], 26, 1)
++
++#define STE_CTXPTR(x) \
++ ((extract64((x)->word[1], 0, 16) << 32) | \
++ ((x)->word[0] & 0xffffffc0))
++
++#define STE_S2TTB(x) \
++ ((extract64((x)->word[7], 0, 16) << 32) | \
++ ((x)->word[6] & 0xfffffff0))
++
++/* CD fields */
++
++#define CD_VALID(x) extract32((x)->word[0], 31, 1)
++#define CD_ASID(x) extract32((x)->word[1], 16, 16)
++#define CD_TTB(x, sel) \
++ ((extract64((x)->word[(sel) * 2 + 3], 0, 19) << 32) | \
++ ((x)->word[(sel) * 2 + 2] & ~0xfULL))
++
++#define CD_HAD(x, sel) extract32((x)->word[(sel) * 2 + 2], 1, 1)
++
++#define CD_TSZ(x, sel) extract32((x)->word[0], (16 * (sel)) + 0, 6)
++#define CD_TG(x, sel) extract32((x)->word[0], (16 * (sel)) + 6, 2)
++#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
++#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
++#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
++#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
++#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
++#define CD_HD(x) extract32((x)->word[1], 10 , 1)
++#define CD_HA(x) extract32((x)->word[1], 11 , 1)
++#define CD_S(x) extract32((x)->word[1], 12, 1)
++#define CD_R(x) extract32((x)->word[1], 13, 1)
++#define CD_A(x) extract32((x)->word[1], 14, 1)
++#define CD_AARCH64(x) extract32((x)->word[1], 9 , 1)
++
++/* MMIO Registers */
++
++REG32(IDR0, 0x0)
++ FIELD(IDR0, S2P, 0 , 1)
++ FIELD(IDR0, S1P, 1 , 1)
++ FIELD(IDR0, TTF, 2 , 2)
++ FIELD(IDR0, COHACC, 4 , 1)
++ FIELD(IDR0, BTM, 5 , 1)
++ FIELD(IDR0, HTTU, 6 , 2)
++ FIELD(IDR0, DORMHINT, 8 , 1)
++ FIELD(IDR0, HYP, 9 , 1)
++ FIELD(IDR0, ATS, 10, 1)
++ FIELD(IDR0, NS1ATS, 11, 1)
++ FIELD(IDR0, ASID16, 12, 1)
++ FIELD(IDR0, MSI, 13, 1)
++ FIELD(IDR0, SEV, 14, 1)
++ FIELD(IDR0, ATOS, 15, 1)
++ FIELD(IDR0, PRI, 16, 1)
++ FIELD(IDR0, VMW, 17, 1)
++ FIELD(IDR0, VMID16, 18, 1)
++ FIELD(IDR0, CD2L, 19, 1)
++ FIELD(IDR0, VATOS, 20, 1)
++ FIELD(IDR0, TTENDIAN, 21, 2)
++ FIELD(IDR0, ATSRECERR, 23, 1)
++ FIELD(IDR0, STALL_MODEL, 24, 2)
++ FIELD(IDR0, TERM_MODEL, 26, 1)
++ FIELD(IDR0, STLEVEL, 27, 2)
++ FIELD(IDR0, RME_IMPL, 30, 1)
++
++REG32(IDR1, 0x4)
++ FIELD(IDR1, SIDSIZE, 0 , 6)
++ FIELD(IDR1, SSIDSIZE, 6 , 5)
++ FIELD(IDR1, PRIQS, 11, 5)
++ FIELD(IDR1, EVENTQS, 16, 5)
++ FIELD(IDR1, CMDQS, 21, 5)
++ FIELD(IDR1, ATTR_PERMS_OVR, 26, 1)
++ FIELD(IDR1, ATTR_TYPES_OVR, 27, 1)
++ FIELD(IDR1, REL, 28, 1)
++ FIELD(IDR1, QUEUES_PRESET, 29, 1)
++ FIELD(IDR1, TABLES_PRESET, 30, 1)
++ FIELD(IDR1, ECMDQ, 31, 1)
++
++#define SMMU_IDR1_SIDSIZE 16
++#define SMMU_CMDQS 19
++#define SMMU_EVENTQS 19
++
++REG32(IDR2, 0x8)
++ FIELD(IDR2, BA_VATOS, 0, 10)
++
++REG32(IDR3, 0xc)
++ FIELD(IDR3, HAD, 2, 1);
++ FIELD(IDR3, PBHA, 3, 1);
++ FIELD(IDR3, XNX, 4, 1);
++ FIELD(IDR3, PPS, 5, 1);
++ FIELD(IDR3, MPAM, 7, 1);
++ FIELD(IDR3, FWB, 8, 1);
++ FIELD(IDR3, STT, 9, 1);
++ FIELD(IDR3, RIL, 10, 1);
++ FIELD(IDR3, BBML, 11, 2);
++ FIELD(IDR3, E0PD, 13, 1);
++ FIELD(IDR3, PTWNNC, 14, 1);
++ FIELD(IDR3, DPT, 15, 1);
++
++REG32(IDR4, 0x10)
++
++REG32(IDR5, 0x14)
++ FIELD(IDR5, OAS, 0, 3);
++ FIELD(IDR5, GRAN4K, 4, 1);
++ FIELD(IDR5, GRAN16K, 5, 1);
++ FIELD(IDR5, GRAN64K, 6, 1);
++ FIELD(IDR5, VAX, 10, 2);
++ FIELD(IDR5, STALL_MAX, 16, 16);
++
++#define SMMU_IDR5_OAS 4
++
++REG32(IIDR, 0x18)
++REG32(AIDR, 0x1c)
++REG32(CR0, 0x20)
++ FIELD(CR0, SMMU_ENABLE, 0, 1)
++ FIELD(CR0, EVENTQEN, 2, 1)
++ FIELD(CR0, CMDQEN, 3, 1)
++
++#define SMMU_CR0_RESERVED 0xFFFFFC20
++
++REG32(CR0ACK, 0x24)
++REG32(CR1, 0x28)
++REG32(CR2, 0x2c)
++REG32(STATUSR, 0x40)
++REG32(GBPA, 0x44)
++ FIELD(GBPA, ABORT, 20, 1)
++ FIELD(GBPA, UPDATE, 31, 1)
++
++/* Use incoming. */
++#define SMMU_GBPA_RESET_VAL 0x1000
++
++REG32(IRQ_CTRL, 0x50)
++ FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1)
++ FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1)
++ FIELD(IRQ_CTRL, EVENTQ_IRQEN, 2, 1)
++
++REG32(IRQ_CTRL_ACK, 0x54)
++REG32(GERROR, 0x60)
++ FIELD(GERROR, CMDQ_ERR, 0, 1)
++ FIELD(GERROR, EVENTQ_ABT_ERR, 2, 1)
++ FIELD(GERROR, PRIQ_ABT_ERR, 3, 1)
++ FIELD(GERROR, MSI_CMDQ_ABT_ERR, 4, 1)
++ FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
++ FIELD(GERROR, MSI_PRIQ_ABT_ERR, 6, 1)
++ FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
++ FIELD(GERROR, MSI_SFM_ERR, 8, 1)
++
++REG32(GERRORN, 0x64)
++
++#define A_GERROR_IRQ_CFG0 0x68 /* 64b */
++REG32(GERROR_IRQ_CFG1, 0x70)
++REG32(GERROR_IRQ_CFG2, 0x74)
++
++#define A_STRTAB_BASE 0x80 /* 64b */
++
++#define SMMU_BASE_ADDR_MASK 0xfffffffffffc0
++
++REG32(STRTAB_BASE_CFG, 0x88)
++ FIELD(STRTAB_BASE_CFG, FMT, 16, 2)
++ FIELD(STRTAB_BASE_CFG, SPLIT, 6 , 5)
++ FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
++
++#define A_CMDQ_BASE 0x90 /* 64b */
++REG32(CMDQ_PROD, 0x98)
++REG32(CMDQ_CONS, 0x9c)
++ FIELD(CMDQ_CONS, ERR, 24, 7)
++
++#define A_EVENTQ_BASE 0xa0 /* 64b */
++REG32(EVENTQ_PROD, 0xa8)
++REG32(EVENTQ_CONS, 0xac)
++
++#define A_EVENTQ_IRQ_CFG0 0xb0 /* 64b */
++REG32(EVENTQ_IRQ_CFG1, 0xb8)
++REG32(EVENTQ_IRQ_CFG2, 0xbc)
++
++#define A_IDREGS 0xfd0
++
++/* Commands */
++
++typedef enum SMMUCommandType {
++ SMMU_CMD_NONE = 0x00,
++ SMMU_CMD_PREFETCH_CONFIG ,
++ SMMU_CMD_PREFETCH_ADDR,
++ SMMU_CMD_CFGI_STE,
++ SMMU_CMD_CFGI_STE_RANGE,
++ SMMU_CMD_CFGI_CD,
++ SMMU_CMD_CFGI_CD_ALL,
++ SMMU_CMD_CFGI_ALL,
++ SMMU_CMD_TLBI_NH_ALL = 0x10,
++ SMMU_CMD_TLBI_NH_ASID,
++ SMMU_CMD_TLBI_NH_VA,
++ SMMU_CMD_TLBI_NH_VAA,
++ SMMU_CMD_TLBI_EL3_ALL = 0x18,
++ SMMU_CMD_TLBI_EL3_VA = 0x1a,
++ SMMU_CMD_TLBI_EL2_ALL = 0x20,
++ SMMU_CMD_TLBI_EL2_ASID,
++ SMMU_CMD_TLBI_EL2_VA,
++ SMMU_CMD_TLBI_EL2_VAA,
++ SMMU_CMD_TLBI_S12_VMALL = 0x28,
++ SMMU_CMD_TLBI_S2_IPA = 0x2a,
++ SMMU_CMD_TLBI_NSNH_ALL = 0x30,
++ SMMU_CMD_ATC_INV = 0x40,
++ SMMU_CMD_PRI_RESP,
++ SMMU_CMD_RESUME = 0x44,
++ SMMU_CMD_STALL_TERM,
++ SMMU_CMD_SYNC,
++} SMMUCommandType;
++
++#endif /* HW_ARM_SMMUV3_COMMON_H */
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Fix-CFGI_CD-handling-when-stage-1-is-u.patch b/kvm-hw-arm-smmuv3-Fix-CFGI_CD-handling-when-stage-1-is-u.patch
new file mode 100644
index 0000000..4ba5d73
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Fix-CFGI_CD-handling-when-stage-1-is-u.patch
@@ -0,0 +1,59 @@
+From f5ccf1f80d37ce44ce10d8c12f4f8233deb03066 Mon Sep 17 00:00:00 2001
+From: Tao Tang <tangtao1634@phytium.com.cn>
+Date: Wed, 4 Mar 2026 22:23:44 +0800
+Subject: [PATCH 056/111] hw/arm/smmuv3: Fix CFGI_CD handling when stage-1 is
+ unsupported
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [56/111] ba0c09d31ebe3ea81c3ea2d716c22268ffe9f122 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+Add a STAGE1_SUPPORTED check in the CMD_CFGI_CD and CMD_CFGI_CD_ALL path
+and return CERROR_ILL when stage-1 translation is not implemented,
+matching the architecture requirement (IHI 0070G.b, page 176).
+
+Fixes: 32cfd7f39e08 ("hw/arm/smmuv3: Cache/invalidate config data")
+Signed-off-by: Tao Tang <tangtao1634@phytium.com.cn>
+Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Reviewed-by: Mostafa Saleh <smostafa@google.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260304142344.3341444-4-tangtao1634@phytium.com.cn
+Links: https://lore.kernel.org/qemu-devel/20260221101733.2995020-1-tangtao1634@phytium.com.cn/
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit fb147007d145866775b0cd5a794c9fa8efdb8c3d)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 8b51554620..d937f4add5 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1407,6 +1407,15 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+ break;
+ }
+
++ /*
++ * This command raises CERROR_ILL when stage 1 is not implemented
++ * according to (IHI 0070G.b) Page 176.
++ */
++ if (!STAGE1_SUPPORTED(s)) {
++ cmd_error = SMMU_CERROR_ILL;
++ break;
++ }
++
+ trace_smmuv3_cmdq_cfgi_cd(sid);
+ smmuv3_flush_config(sdev);
+ if (!smmuv3_accel_issue_inv_cmd(s, &cmd, sdev, errp)) {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Have-smmuv3_accel_init-take-an-Error-p.patch b/kvm-hw-arm-smmuv3-Have-smmuv3_accel_init-take-an-Error-p.patch
new file mode 100644
index 0000000..8c46cd0
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Have-smmuv3_accel_init-take-an-Error-p.patch
@@ -0,0 +1,111 @@
+From 3bc8b97e9b2ba8b67a2fca2313832d565d2303df Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
+Date: Thu, 9 Apr 2026 13:35:56 +0200
+Subject: [PATCH 065/111] hw/arm/smmuv3: Have smmuv3_accel_init() take an
+ Error* parameter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [65/111] ff4ac1030fe29a13b111252411a1e15038f7cca7 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+By giving smmuv3_accel_init() the ability to populate an error,
+we can fail early in smmu_realize() when CONFIG_ARM_SMMUV3_ACCEL
+is not available, simplifying smmu_validate_property().
+
+Suggested-by: Shameer Kolothum Thodi <skolothumtho@nvidia.com>
+Co-developed-by: Shameer Kolothum Thodi <skolothumtho@nvidia.com>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-Id: <20260410200031.18572-2-philmd@linaro.org>
+(cherry picked from commit 4c7fefc2d043a66f799cf2c2e34ed680b1b44b5c)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 3 ++-
+ hw/arm/smmuv3-accel.h | 7 +++++--
+ hw/arm/smmuv3.c | 11 +++--------
+ 3 files changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 65c2f44880..ae031f1ecc 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -917,11 +917,12 @@ static void smmuv3_accel_as_init(SMMUv3State *s)
+ address_space_init(shared_as_sysmem, &root, "smmuv3-accel-as-sysmem");
+ }
+
+-void smmuv3_accel_init(SMMUv3State *s)
++bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+ {
+ SMMUState *bs = ARM_SMMU(s);
+
+ s->s_accel = g_new0(SMMUv3AccelState, 1);
+ bs->iommu_ops = &smmuv3_accel_ops;
+ smmuv3_accel_as_init(s);
++ return true;
+ }
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index dba6c71de5..1ca2c80a93 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -42,7 +42,7 @@ typedef struct SMMUv3AccelDevice {
+ } SMMUv3AccelDevice;
+
+ #ifdef CONFIG_ARM_SMMUV3_ACCEL
+-void smmuv3_accel_init(SMMUv3State *s);
++bool smmuv3_accel_init(SMMUv3State *s, Error **errp);
+ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+ Error **errp);
+ bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
+@@ -54,8 +54,11 @@ void smmuv3_accel_idr_override(SMMUv3State *s);
+ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp);
+ void smmuv3_accel_reset(SMMUv3State *s);
+ #else
+-static inline void smmuv3_accel_init(SMMUv3State *s)
++#include "qapi/error.h"
++static inline bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+ {
++ error_setg(errp, "accel=on support not compiled in");
++ return false;
+ }
+ static inline bool
+ smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 7951d85ec9..5fc55aa30a 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1965,13 +1965,6 @@ static void smmu_reset_exit(Object *obj, ResetType type)
+
+ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ {
+-#ifndef CONFIG_ARM_SMMUV3_ACCEL
+- if (s->accel) {
+- error_setg(errp, "accel=on support not compiled in");
+- return false;
+- }
+-#endif
+-
+ if (s->ats == ON_OFF_AUTO_AUTO) {
+ error_setg(errp, "ats auto mode is not supported");
+ return false;
+@@ -2033,7 +2026,9 @@ static void smmu_realize(DeviceState *d, Error **errp)
+ }
+
+ if (s->accel) {
+- smmuv3_accel_init(s);
++ if (!smmuv3_accel_init(s, errp)) {
++ return;
++ }
+ error_setg(&s->migration_blocker, "Migration not supported with SMMUv3 "
+ "accelerator mode enabled");
+ if (migrate_add_blocker(&s->migration_blocker, errp) < 0) {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Implement-get_viommu_cap-callback.patch b/kvm-hw-arm-smmuv3-Implement-get_viommu_cap-callback.patch
new file mode 100644
index 0000000..cbbf741
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Implement-get_viommu_cap-callback.patch
@@ -0,0 +1,72 @@
+From c4cf09178e90bd22d7815c4fc16f1a6c5b99f46f Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 014/111] hw/arm/smmuv3: Implement get_viommu_cap() callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [14/111] 254bfc96a6ae9a8a909be4f4df74cc31b05ec205 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+For accelerated SMMUv3, we need nested parent domain creation. Add the
+callback support so that VFIO can create a nested parent.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-12-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit fc6dafb98cec0905fca61c15eb8287de75af2230)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 2fcd301322..be09cf8b73 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -10,6 +10,7 @@
+ #include "qemu/error-report.h"
+
+ #include "hw/arm/smmuv3.h"
++#include "hw/core/iommu.h"
+ #include "hw/pci/pci_bridge.h"
+ #include "hw/pci-host/gpex.h"
+ #include "hw/vfio/pci.h"
+@@ -129,9 +130,21 @@ static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque,
+ }
+ }
+
++static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
++{
++ /*
++ * We return VIOMMU_FLAG_WANT_NESTING_PARENT to inform VFIO core to create a
++ * nesting parent which is required for accelerated SMMUv3 support.
++ * The real HW nested support should be reported from host SMMUv3 and if
++ * it doesn't, the nesting parent allocation will fail anyway in VFIO core.
++ */
++ return VIOMMU_FLAG_WANT_NESTING_PARENT;
++}
++
+ static const PCIIOMMUOps smmuv3_accel_ops = {
+ .supports_address_space = smmuv3_accel_supports_as,
+ .get_address_space = smmuv3_accel_find_add_as,
++ .get_viommu_flags = smmuv3_accel_get_viommu_flags,
+ };
+
+ static void smmuv3_accel_as_init(SMMUv3State *s)
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Improve-accel-SMMUv3-usage-documentati.patch b/kvm-hw-arm-smmuv3-Improve-accel-SMMUv3-usage-documentati.patch
new file mode 100644
index 0000000..6da21cf
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Improve-accel-SMMUv3-usage-documentati.patch
@@ -0,0 +1,52 @@
+From c153b0934b729a36c377366769822a4ac87099ac Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Mon, 8 Jun 2026 10:48:53 -0700
+Subject: [PATCH 067/111] hw/arm/smmuv3: Improve accel SMMUv3 usage
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [67/111] 1b682f65ef48f1736b6179c5e0520b4f17ba75e6 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+Add a statement to clarify that the host SMMUv3 must support HW-accelerated
+vfio-pci device assignment when setting accel=on.
+
+Reported-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260608174900.2227340-3-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 6328edbe5d72fd9f636b0e9785e72efe883d557e)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index c724c6b819..f76a527182 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -2165,7 +2165,9 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+
+ object_class_property_set_description(klass, "accel",
+ "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
+- "configured in nested mode for vfio-pci dev assignment");
++ "configured in nested mode for vfio-pci dev assignment. Please "
++ "ensure the host SMMUv3 supports nested translation before "
++ "enabling.");
+ object_class_property_set_description(klass, "ril",
+ "Disable range invalidation support (for accel=on). ril=auto "
+ "is not supported.");
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Initialize-ID-registers-early-during-r.patch b/kvm-hw-arm-smmuv3-Initialize-ID-registers-early-during-r.patch
new file mode 100644
index 0000000..3cafe62
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Initialize-ID-registers-early-during-r.patch
@@ -0,0 +1,96 @@
+From 27993494929455703de48a0fdd98c78af882dada Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 028/111] hw/arm/smmuv3: Initialize ID registers early during
+ realize()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [28/111] c31ff8cc5b1eda787830e66138080dbf11f6906e (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Factor out ID register init into smmuv3_init_id_regs() and call it from
+realize(). This ensures ID registers are initialized early for use in the
+accelerated SMMUv3 path and will be utilized in subsequent patch.
+
+Other registers remain initialized in smmuv3_reset().
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-21-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit f577dcdb5c1ca7d458d2cb365e884813c1505f9b)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 513da966a4..dba5abc8d3 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -258,7 +258,12 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
+ info->recorded = true;
+ }
+
+-static void smmuv3_init_regs(SMMUv3State *s)
++/*
++ * Called during realize(), as the ID registers will be accessed early in the
++ * SMMUv3 accel path for feature compatibility checks. The remaining registers
++ * are initialized later in smmuv3_reset().
++ */
++static void smmuv3_init_id_regs(SMMUv3State *s)
+ {
+ /* Based on sys property, the stages supported in smmu will be advertised.*/
+ if (s->stage && !strcmp("2", s->stage)) {
+@@ -298,7 +303,11 @@ static void smmuv3_init_regs(SMMUv3State *s)
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1);
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
++ s->aidr = 0x1;
++}
+
++static void smmuv3_reset(SMMUv3State *s)
++{
+ s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
+ s->cmdq.prod = 0;
+ s->cmdq.cons = 0;
+@@ -310,7 +319,6 @@ static void smmuv3_init_regs(SMMUv3State *s)
+
+ s->features = 0;
+ s->sid_split = 0;
+- s->aidr = 0x1;
+ s->cr[0] = 0;
+ s->cr0ack = 0;
+ s->irq_ctrl = 0;
+@@ -1903,7 +1911,7 @@ static void smmu_reset_exit(Object *obj, ResetType type)
+ c->parent_phases.exit(obj, type);
+ }
+
+- smmuv3_init_regs(s);
++ smmuv3_reset(s);
+ smmuv3_accel_reset(s);
+ }
+
+@@ -1935,6 +1943,7 @@ static void smmu_realize(DeviceState *d, Error **errp)
+ sysbus_init_mmio(dev, &sys->iomem);
+
+ smmu_init_irq(s, dev);
++ smmuv3_init_id_regs(s);
+ }
+
+ static const VMStateDescription vmstate_smmuv3_queue = {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Introduce-a-helper-function-for-event-.patch b/kvm-hw-arm-smmuv3-Introduce-a-helper-function-for-event-.patch
new file mode 100644
index 0000000..3dc99c9
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Introduce-a-helper-function-for-event-.patch
@@ -0,0 +1,119 @@
+From efca87fb97687307cc608b0beec14873d31014fa Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Fri, 6 Mar 2026 09:01:11 +0000
+Subject: [PATCH 053/111] hw/arm/smmuv3: Introduce a helper function for event
+ propagation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [53/111] 8ce584d593ad657ef9ea7fcd337ef53e13f1d2b2 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73796
+
+Factor out the code that propagates event records to the guest into a
+helper function. The accelerated SMMUv3 path can use this to propagate
+host events in a subsequent patch.
+
+Take the mutex inside the helper before accessing the Event Queue.
+Today event propagation occurs only in the core SMMUv3 path and is
+effectively serialized. A subsequent patch will also invoke this helper
+from the accelerated event read path, which may run concurrently.
+Therefore serialization is required here.
+
+No functional change intended.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260226084456.112142-5-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 43585524a7c628c0ebace5c33ba865c4e2c55177)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-internal.h | 4 ++++
+ hw/arm/smmuv3.c | 20 ++++++++++++++------
+ hw/arm/trace-events | 2 +-
+ 3 files changed, 19 insertions(+), 7 deletions(-)
+
+diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
+index 998d30473d..466bfd390e 100644
+--- a/hw/arm/smmuv3-internal.h
++++ b/hw/arm/smmuv3-internal.h
+@@ -352,7 +352,11 @@ typedef struct SMMUEventInfo {
+ (x)->word[6] = (uint32_t)(addr & 0xffffffff); \
+ } while (0)
+
++#define EVT_GET_TYPE(x) extract32((x)->word[0], 0, 8)
++#define EVT_GET_SID(x) ((x)->word[1])
++
+ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
++void smmuv3_propagate_event(SMMUv3State *s, Evt *evt);
+ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, SMMUEventInfo *event);
+
+ static inline int oas2bits(int oas_field)
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 1a218f749d..8b51554620 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -168,10 +168,22 @@ static MemTxResult smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
+ return MEMTX_OK;
+ }
+
++void smmuv3_propagate_event(SMMUv3State *s, Evt *evt)
++{
++ MemTxResult r;
++
++ trace_smmuv3_propagate_event(smmu_event_string(EVT_GET_TYPE(evt)),
++ EVT_GET_SID(evt));
++ QEMU_LOCK_GUARD(&s->mutex);
++ r = smmuv3_write_eventq(s, evt);
++ if (r != MEMTX_OK) {
++ smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_EVENTQ_ABT_ERR_MASK);
++ }
++}
++
+ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
+ {
+ Evt evt = {};
+- MemTxResult r;
+
+ if (!smmuv3_eventq_enabled(s)) {
+ return;
+@@ -251,11 +263,7 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
+ g_assert_not_reached();
+ }
+
+- trace_smmuv3_record_event(smmu_event_string(info->type), info->sid);
+- r = smmuv3_write_eventq(s, &evt);
+- if (r != MEMTX_OK) {
+- smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_EVENTQ_ABT_ERR_MASK);
+- }
++ smmuv3_propagate_event(s, &evt);
+ info->recorded = true;
+ }
+
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index 8135c0c734..3457536fb0 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -40,7 +40,7 @@ smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
+ smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
+ smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
+ smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
+-smmuv3_record_event(const char *type, uint32_t sid) "%s sid=0x%x"
++smmuv3_propagate_event(const char *type, uint32_t sid) "%s sid=0x%x"
+ smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "sid=0x%x features:0x%x, sid_split:0x%x"
+ smmuv3_find_ste_2lvl(uint64_t strtab_base, uint64_t l1ptr, int l1_ste_offset, uint64_t l2ptr, int l2_ste_offset, int max_l2_ste) "strtab_base:0x%"PRIx64" l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_ste:%d"
+ smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Set-default-ats-ril-ssidsize-oas-to-au.patch b/kvm-hw-arm-smmuv3-Set-default-ats-ril-ssidsize-oas-to-au.patch
new file mode 100644
index 0000000..270e6de
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Set-default-ats-ril-ssidsize-oas-to-au.patch
@@ -0,0 +1,146 @@
+From 404ac4a7236dc28940c7185b2e8a4fadbbe6f06c Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Mon, 8 Jun 2026 10:48:59 -0700
+Subject: [PATCH 073/111] hw/arm/smmuv3: Set default ats, ril, ssidsize, oas to
+ auto
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [73/111] ad6ebf8a64277a364ee604cf9c13b8dced85b7f1 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+Conflicts: contextual conflict in machine.c as we don't have
+hw_compat_10_1, hw_compat_10_2, hw_compat_11_0 in RHEL. So add
+the compats in last hw_compat_10_0 which then are propagated to
+hw_compat_rhel_10_2. Note as we don't have a new machine type in
+10.3 the new defaults don't apply and it will be needed to set auto
+value explicitly. Also fix the setting of hw_compat_rhel_10_2_len.
+
+Set the default value of ATS, RIL, SSIDSIZE, and OAS to auto, in order
+to match the host IOMMU properties when accel=on.
+
+If accel=off and these property values are set to auto, the default
+property values defined in smmuv3_init_id_regs() for OAS and RIL will
+remain unchanged, while SSIDSIZE and ATS values will remain initialized
+at 0.
+
+Introduce a new compat for the changed defaults.
+
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260608174900.2227340-9-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit e61f8d1138aa0f702632723f14161da8288936d4)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 23 +++++++++++++++--------
+ hw/core/machine.c | 15 ++++++++++++++-
+ 2 files changed, 29 insertions(+), 9 deletions(-)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 89d34c9923..1e98ee0e76 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -2129,12 +2129,19 @@ static const Property smmuv3_properties[] = {
+ DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false),
+ /* GPA of MSI doorbell, for SMMUv3 accel use. */
+ DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
++ /*
++ * AUTO values for accel=off will resolve to:
++ * ril: on
++ * ats: off
++ * oas: 44
++ * ssidsize: 0
++ */
+ /* RIL can be turned off for accel cases */
+- DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_ON),
+- DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_OFF),
+- DEFINE_PROP_OAS_MODE("oas", SMMUv3State, oas, OAS_MODE_44),
++ DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_AUTO),
++ DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
++ DEFINE_PROP_OAS_MODE("oas", SMMUv3State, oas, OAS_MODE_AUTO),
+ DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
+- SSID_SIZE_MODE_0),
++ SSID_SIZE_MODE_AUTO),
+ };
+
+ static void smmuv3_instance_init(Object *obj)
+@@ -2164,22 +2171,22 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "enabling.");
+ object_class_property_set_description(klass, "ril",
+ "Enable/disable range invalidation support (for accel=on). "
+- "Valid values are on, off, and auto. Defaults to on. "
++ "Valid values are on, off, and auto. Defaults to auto. "
+ "Any attempt to turn it 'on' while the host does not support "
+ "it would fail.");
+ object_class_property_set_description(klass, "ats",
+ "Enable/disable ATS support (for accel=on). "
+- "Valid values are on, off, and auto. Defaults to off. "
++ "Valid values are on, off, and auto. Defaults to auto. "
+ "Please ensure host platform supports ATS before setting it "
+ "to on.");
+ object_class_property_set_description(klass, "oas",
+ "Set Output Address Size in bits (for accel=on). "
+- "Valid values are 44, 48, and auto. Defaults to 44 bits."
++ "Valid values are 44, 48, and auto. Defaults to auto."
+ "Please ensure the value does not exceed the maximum "
+ "Output Address Size supported by the host platform.");
+ object_class_property_set_description(klass, "ssidsize",
+ "Set number of bits used to represent SubstreamIDs (SSIDs). "
+- "Valid values are 0-20 and auto. Defaults to 0. "
++ "Valid values are 0-20 and auto. Defaults to auto. "
+ "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
+ "A value of 0 disables SubstreamID support. A value greater "
+ "than 0 is required to enable PASID support."
+diff --git a/hw/core/machine.c b/hw/core/machine.c
+index 2b339f6a13..601d8c6a1f 100644
+--- a/hw/core/machine.c
++++ b/hw/core/machine.c
+@@ -36,12 +36,17 @@
+ #include "hw/virtio/virtio-net.h"
+ #include "hw/virtio/virtio-iommu.h"
+ #include "audio/audio.h"
++#include "hw/arm/smmuv3.h"
+
+ GlobalProperty hw_compat_10_0[] = {
+ { "scsi-hd", "dpofua", "off" },
+ { "vfio-pci", "x-migration-load-config-after-iter", "off" },
+ { "ramfb", "use-legacy-x86-rom", "true"},
+ { "vfio-pci-nohotplug", "use-legacy-x86-rom", "true" },
++ { TYPE_ARM_SMMUV3, "ats", "off" },
++ { TYPE_ARM_SMMUV3, "ril", "on" },
++ { TYPE_ARM_SMMUV3, "ssidsize", "0" },
++ { TYPE_ARM_SMMUV3, "oas", "44" },
+ };
+ const size_t hw_compat_10_0_len = G_N_ELEMENTS(hw_compat_10_0);
+
+@@ -304,8 +309,16 @@ GlobalProperty hw_compat_rhel_10_2[] = {
+ { "ramfb", "use-legacy-x86-rom", "true"},
+ /* hw_compat_rhel_10_2 from hw_compat_10_0 */
+ { "vfio-pci-nohotplug", "use-legacy-x86-rom", "true" },
++ /* hw_compat_rhel_10_2 from hw_compat_10_0 */
++ { TYPE_ARM_SMMUV3, "ats", "off" },
++ /* hw_compat_rhel_10_2 from hw_compat_10_0 */
++ { TYPE_ARM_SMMUV3, "ril", "on" },
++ /* hw_compat_rhel_10_2 from hw_compat_10_0 */
++ { TYPE_ARM_SMMUV3, "ssidsize", "0" },
++ /* hw_compat_rhel_10_2 from hw_compat_10_0 */
++ { TYPE_ARM_SMMUV3, "oas", "44" },
+ };
+-const size_t hw_compat_rhel_10_2_len = G_N_ELEMENTS(hw_compat_10_0);
++const size_t hw_compat_rhel_10_2_len = G_N_ELEMENTS(hw_compat_rhel_10_2);
+
+ GlobalProperty hw_compat_rhel_10_1[] = {
+ /* hw_compat_rhel_10_1 from hw_compat_9_1 */
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-Update-ATC-invalidation-check.patch b/kvm-hw-arm-smmuv3-Update-ATC-invalidation-check.patch
new file mode 100644
index 0000000..2ec47e1
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-Update-ATC-invalidation-check.patch
@@ -0,0 +1,52 @@
+From ef1caeab79fd5be8bd3e46170af2c6c630dc3958 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Mon, 8 Jun 2026 10:48:52 -0700
+Subject: [PATCH 066/111] hw/arm/smmuv3: Update ATC invalidation check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [66/111] 3c32cca7cc7c03287d85f5aaae983149d19a5cad (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+Use smmuv3_ats_enabled() to determine whether ATS is enabled for the
+guest when handling an ATC invalidation command, as setting the ATS
+property value to 'auto' will resolve to ATS being detected as
+enabled in the ATC invalidation check otherwise.
+
+Fixes: f7f5013a55a3 ("hw/arm/smmuv3-accel: Add support for ATS")
+Reported-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260608174900.2227340-2-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 8addbdb793b783228ab22867ac5e2d59ea6662a7)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 5fc55aa30a..c724c6b819 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1528,7 +1528,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+ {
+ SMMUDevice *sdev = smmu_find_sdev(bs, CMD_SID(&cmd));
+
+- if (!sdev || !s->ats) {
++ if (!sdev || !smmuv3_ats_enabled(s)) {
+ trace_smmuv3_unhandled_cmd(type);
+ break;
+ }
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Add-a-property-to-specify-RIL-su.patch b/kvm-hw-arm-smmuv3-accel-Add-a-property-to-specify-RIL-su.patch
new file mode 100644
index 0000000..2225cbe
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Add-a-property-to-specify-RIL-su.patch
@@ -0,0 +1,150 @@
+From 173447f0eb8f5d9486e21e6290c7059cdba4df46 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 037/111] hw/arm/smmuv3-accel: Add a property to specify RIL
+ support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [37/111] ce485009c27e5fc84da112baab386d28c178e4c7 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Currently QEMU SMMUv3 has RIL support by default. But if accelerated mode
+is enabled, RIL has to be compatible with host SMMUv3 support.
+
+Add a property so that the user can specify this.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-30-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit bd715ff5bda973c85caa16f1cabf1e9aef30dc70)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 14 ++++++++++++--
+ hw/arm/smmuv3-accel.h | 4 ++++
+ hw/arm/smmuv3.c | 9 +++++++++
+ include/hw/arm/smmuv3.h | 1 +
+ 4 files changed, 26 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 33011962e3..df82f1e32a 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -68,8 +68,8 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
+ return false;
+ }
+
+- /* QEMU SMMUv3 supports Range Invalidation by default */
+- if (FIELD_EX32(info->idr[3], IDR3, RIL) !=
++ /* User can disable QEMU SMMUv3 Range Invalidation support */
++ if (FIELD_EX32(info->idr[3], IDR3, RIL) <
+ FIELD_EX32(s->idr[3], IDR3, RIL)) {
+ error_setg(errp, "Host SMMUv3 doesn't support Range Invalidation");
+ return false;
+@@ -646,6 +646,16 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
+ .get_msi_direct_gpa = smmuv3_accel_get_msi_gpa,
+ };
+
++void smmuv3_accel_idr_override(SMMUv3State *s)
++{
++ if (!s->accel) {
++ return;
++ }
++
++ /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
++ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
++}
++
+ /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
+ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
+ {
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index 41b37e3122..a8a64802ec 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -49,6 +49,7 @@ bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
+ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp);
+ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
+ Error **errp);
++void smmuv3_accel_idr_override(SMMUv3State *s);
+ void smmuv3_accel_reset(SMMUv3State *s);
+ #else
+ static inline void smmuv3_accel_init(SMMUv3State *s)
+@@ -76,6 +77,9 @@ smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
+ {
+ return true;
+ }
++static inline void smmuv3_accel_idr_override(SMMUv3State *s)
++{
++}
+ static inline void smmuv3_accel_reset(SMMUv3State *s)
+ {
+ }
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 0d2f5a9b0c..643706b29c 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -305,6 +305,7 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1);
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
+ s->aidr = 0x1;
++ smmuv3_accel_idr_override(s);
+ }
+
+ static void smmuv3_reset(SMMUv3State *s)
+@@ -1926,6 +1927,10 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ #endif
+
+ if (!s->accel) {
++ if (!s->ril) {
++ error_setg(errp, "ril can only be disabled if accel=on");
++ return false;
++ }
+ return true;
+ }
+
+@@ -2059,6 +2064,8 @@ static const Property smmuv3_properties[] = {
+ DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false),
+ /* GPA of MSI doorbell, for SMMUv3 accel use. */
+ DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
++ /* RIL can be turned off for accel cases */
++ DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
+ };
+
+ static void smmuv3_instance_init(Object *obj)
+@@ -2084,6 +2091,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ object_class_property_set_description(klass, "accel",
+ "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
+ "configured in nested mode for vfio-pci dev assignment");
++ object_class_property_set_description(klass, "ril",
++ "Disable range invalidation support (for accel=on)");
+ }
+
+ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index 9c39acd5ca..533a2182e8 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -69,6 +69,7 @@ struct SMMUv3State {
+ struct SMMUv3AccelState *s_accel;
+ uint64_t msi_gpa;
+ Error *migration_blocker;
++ bool ril;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Add-helper-for-resolving-auto-pa.patch b/kvm-hw-arm-smmuv3-accel-Add-helper-for-resolving-auto-pa.patch
new file mode 100644
index 0000000..15420b7
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Add-helper-for-resolving-auto-pa.patch
@@ -0,0 +1,167 @@
+From c7ecd05ab988cc750b7367ea6cebae674cb3e31c Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Mon, 8 Jun 2026 10:48:54 -0700
+Subject: [PATCH 068/111] hw/arm/smmuv3-accel: Add helper for resolving auto
+ parameters
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [68/111] cb386d939db43c67b117bfe51e31407c02e8c616 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+Introduce smmuv3_accel_auto_finalise() to resolve properties that are
+set to 'auto' for accelerated SMMUv3. This helper function allows
+properties such as ats, ril, ssidsize, and oas support to be resolved
+from host IOMMU capabilities via IOMMU_GET_HW_INFO.
+
+The later commits in this series set the auto_mode flag to true when
+an accel SMMUv3 property value is explicitly set to 'auto', or if the
+property value is not set and defaults to auto mode.
+
+Setting these property values to 'auto' requires at least one
+cold-plugged device to retrieve and finalise these properties. If the
+auto_mode flag is true, register a machine_init_done notifier to
+verify this requirement and fail boot if it is not met.
+
+Hot-plugged devices into an accel SMMUv3-associated bus will re-use
+the resolved host values from the initial cold-plug.
+
+Subsequent patches will make use of this helper to resolve 'auto' to
+what is reported by host IOMMU capabilities.
+
+Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260608174900.2227340-4-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 16c547e9cb911d751d35fbe181a5cea8f9d52fbc)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 41 +++++++++++++++++++++++++++++++++++++++++
+ hw/arm/smmuv3-accel.h | 2 ++
+ include/hw/arm/smmuv3.h | 3 +++
+ 3 files changed, 46 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index ae031f1ecc..e625f145c4 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -18,6 +18,7 @@
+
+ #include "smmuv3-internal.h"
+ #include "smmuv3-accel.h"
++#include "system/system.h"
+
+ /*
+ * The root region aliases the global system memory, and shared_as_sysmem
+@@ -35,11 +36,33 @@ static int smmuv3_oas_bits(uint32_t oas)
+ return map[oas];
+ }
+
++static void smmuv3_accel_auto_finalise(SMMUv3State *s,
++ struct iommu_hw_info_arm_smmuv3 *info)
++{
++ SMMUv3AccelState *accel = s->s_accel;
++
++ /*
++ * Return if 'auto' was not set for any accel SMMUv3 property, or
++ * if property values were already resolved from a previous call
++ * to this function (e.g. if this function was called again after
++ * VM boot during device hot plug). We do not accept new property
++ * values in this case where auto_finalised == true, and we re-use
++ * the values determined from the initial cold plug.
++ */
++ if (!accel->auto_mode || accel->auto_finalised) {
++ return;
++ }
++
++ accel->auto_finalised = true;
++}
++
+ static bool
+ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
+ struct iommu_hw_info_arm_smmuv3 *info,
+ Error **errp)
+ {
++ smmuv3_accel_auto_finalise(s, info);
++
+ /* QEMU SMMUv3 supports both linear and 2-level stream tables */
+ if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=
+ FIELD_EX32(s->idr[0], IDR0, STLEVEL)) {
+@@ -917,6 +940,18 @@ static void smmuv3_accel_as_init(SMMUv3State *s)
+ address_space_init(shared_as_sysmem, &root, "smmuv3-accel-as-sysmem");
+ }
+
++static void smmuv3_accel_machine_done(Notifier *notifier, void *data)
++{
++ SMMUv3State *s = container_of(notifier, SMMUv3State, machine_done);
++ SMMUv3AccelState *accel = s->s_accel;
++
++ if (accel->auto_mode && !accel->auto_finalised) {
++ error_report("arm-smmuv3 accel=on with 'auto' properties requires "
++ "at least one cold-plugged VFIO device");
++ exit(1);
++ }
++}
++
+ bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+ {
+ SMMUState *bs = ARM_SMMU(s);
+@@ -924,5 +959,11 @@ bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+ s->s_accel = g_new0(SMMUv3AccelState, 1);
+ bs->iommu_ops = &smmuv3_accel_ops;
+ smmuv3_accel_as_init(s);
++
++ if (s->s_accel->auto_mode) {
++ s->machine_done.notify = smmuv3_accel_machine_done;
++ qemu_add_machine_init_done_notifier(&s->machine_done);
++ }
++
+ return true;
+ }
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index 1ca2c80a93..d7b9f8a8e6 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -26,6 +26,8 @@ typedef struct SMMUv3AccelState {
+ uint32_t bypass_hwpt_id;
+ uint32_t abort_hwpt_id;
+ QLIST_HEAD(, SMMUv3AccelDevice) device_list;
++ bool auto_mode;
++ bool auto_finalised;
+ } SMMUv3AccelState;
+
+ typedef struct SMMUS1Hwpt {
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index 82f18eb090..85be3d7467 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -22,6 +22,7 @@
+ #include "hw/arm/smmu-common.h"
+ #include "qom/object.h"
+ #include "qapi/qapi-types-misc-arm.h"
++#include "qemu/notify.h"
+
+ #define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
+
+@@ -74,6 +75,8 @@ struct SMMUv3State {
+ OnOffAuto ats;
+ OasMode oas;
+ SsidSizeMode ssidsize;
++
++ Notifier machine_done;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Add-nested-vSTE-install-uninstal.patch b/kvm-hw-arm-smmuv3-accel-Add-nested-vSTE-install-uninstal.patch
new file mode 100644
index 0000000..83e1377
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Add-nested-vSTE-install-uninstal.patch
@@ -0,0 +1,421 @@
+From 9ea3b4bff367d92ec736e800eca1858b599a419a Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 022/111] hw/arm/smmuv3-accel: Add nested vSTE
+ install/uninstall support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [22/111] 82797493d2a4627bc07d4faaba7d4405d1ecda90 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+A device placed behind a vSMMU instance must have corresponding vSTEs
+(bypass, abort, or translate) installed. The bypass and abort proxy nested
+HWPTs are pre-allocated.
+
+For translat HWPT, a vDEVICE object is allocated and associated with the
+vIOMMU for each guest device. This allows the host kernel to establish a
+virtual SID to physical SID mapping, which is required for handling
+invalidations and event reporting.
+
+An translate HWPT is allocated based on the guest STE configuration and
+attached to the device when the guest issues SMMU_CMD_CFGI_STE or
+SMMU_CMD_CFGI_STE_RANGE, provided the STE enables S1 translation.
+
+If the guest STE is invalid or S1 translation is disabled, the device is
+attached to one of the pre-allocated ABORT or BYPASS HWPTs instead.
+
+While at it, export smmu_find_ste() for use here.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-15-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 2da17a988c2d387b8fde04fdaddf03afa73085f5)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 197 +++++++++++++++++++++++++++++++++
+ hw/arm/smmuv3-accel.h | 22 ++++
+ hw/arm/smmuv3-internal.h | 1 +
+ hw/arm/smmuv3.c | 11 +-
+ hw/arm/trace-events | 2 +
+ include/hw/arm/smmuv3-common.h | 18 +++
+ 6 files changed, 249 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 9c2b917a11..877b7e0e17 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -51,6 +51,188 @@ static uint32_t smmuv3_accel_gbpa_hwpt(SMMUv3State *s, SMMUv3AccelState *accel)
+ accel->abort_hwpt_id : accel->bypass_hwpt_id;
+ }
+
++static bool
++smmuv3_accel_alloc_vdev(SMMUv3AccelDevice *accel_dev, int sid, Error **errp)
++{
++ SMMUv3AccelState *accel = accel_dev->s_accel;
++ HostIOMMUDeviceIOMMUFD *idev = accel_dev->idev;
++ IOMMUFDVdev *vdev = accel_dev->vdev;
++ uint32_t vdevice_id;
++
++ if (!idev || vdev) {
++ return true;
++ }
++
++ if (!iommufd_backend_alloc_vdev(idev->iommufd, idev->devid,
++ accel->viommu->viommu_id, sid,
++ &vdevice_id, errp)) {
++ return false;
++ }
++
++ vdev = g_new(IOMMUFDVdev, 1);
++ vdev->vdevice_id = vdevice_id;
++ vdev->virt_id = sid;
++ accel_dev->vdev = vdev;
++ return true;
++}
++
++static SMMUS1Hwpt *
++smmuv3_accel_dev_alloc_translate(SMMUv3AccelDevice *accel_dev, STE *ste,
++ Error **errp)
++{
++ uint64_t ste_0 = (uint64_t)ste->word[0] | (uint64_t)ste->word[1] << 32;
++ uint64_t ste_1 = (uint64_t)ste->word[2] | (uint64_t)ste->word[3] << 32;
++ HostIOMMUDeviceIOMMUFD *idev = accel_dev->idev;
++ SMMUv3AccelState *accel = accel_dev->s_accel;
++ struct iommu_hwpt_arm_smmuv3 nested_data = {
++ .ste = {
++ cpu_to_le64(ste_0 & STE0_MASK),
++ cpu_to_le64(ste_1 & STE1_MASK),
++ },
++ };
++ uint32_t hwpt_id = 0, flags = 0;
++ SMMUS1Hwpt *s1_hwpt;
++
++ if (!iommufd_backend_alloc_hwpt(idev->iommufd, idev->devid,
++ accel->viommu->viommu_id, flags,
++ IOMMU_HWPT_DATA_ARM_SMMUV3,
++ sizeof(nested_data), &nested_data,
++ &hwpt_id, errp)) {
++ return NULL;
++ }
++
++ s1_hwpt = g_new0(SMMUS1Hwpt, 1);
++ s1_hwpt->hwpt_id = hwpt_id;
++ trace_smmuv3_accel_translate_ste(accel_dev->vdev->virt_id, hwpt_id,
++ nested_data.ste[1], nested_data.ste[0]);
++ return s1_hwpt;
++}
++
++bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
++ Error **errp)
++{
++ SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid,
++ .inval_ste_allowed = true};
++ SMMUv3AccelState *accel = s->s_accel;
++ SMMUv3AccelDevice *accel_dev;
++ HostIOMMUDeviceIOMMUFD *idev;
++ uint32_t config, hwpt_id = 0;
++ SMMUS1Hwpt *s1_hwpt = NULL;
++ const char *type;
++ STE ste;
++
++ if (!accel || !accel->viommu) {
++ return true;
++ }
++
++ accel_dev = container_of(sdev, SMMUv3AccelDevice, sdev);
++ if (!accel_dev->s_accel) {
++ return true;
++ }
++
++ idev = accel_dev->idev;
++ if (!smmuv3_accel_alloc_vdev(accel_dev, sid, errp)) {
++ return false;
++ }
++
++ if (smmu_find_ste(sdev->smmu, sid, &ste, &event)) {
++ /* No STE found, nothing to install */
++ return true;
++ }
++
++ /*
++ * Install the STE based on SMMU enabled/config:
++ * - attach a pre-allocated HWPT for abort/bypass
++ * - or a new HWPT for translate STE
++ *
++ * Note: The vdev remains associated with accel_dev even if HWPT
++ * attach/alloc fails, since the Guest–Host SID mapping stays
++ * valid as long as the device is behind the accelerated SMMUv3.
++ */
++ if (!smmu_enabled(s)) {
++ hwpt_id = smmuv3_accel_gbpa_hwpt(s, accel);
++ } else {
++ config = STE_CONFIG(&ste);
++
++ if (!STE_VALID(&ste) || STE_CFG_ABORT(config)) {
++ hwpt_id = accel->abort_hwpt_id;
++ } else if (STE_CFG_BYPASS(config)) {
++ hwpt_id = accel->bypass_hwpt_id;
++ } else if (STE_CFG_S1_TRANSLATE(config)) {
++ s1_hwpt = smmuv3_accel_dev_alloc_translate(accel_dev, &ste, errp);
++ if (!s1_hwpt) {
++ return false;
++ }
++ hwpt_id = s1_hwpt->hwpt_id;
++ }
++ }
++
++ if (!hwpt_id) {
++ error_setg(errp, "Invalid STE config for sid 0x%x",
++ smmu_get_sid(&accel_dev->sdev));
++ return false;
++ }
++
++ if (!host_iommu_device_iommufd_attach_hwpt(idev, hwpt_id, errp)) {
++ if (s1_hwpt) {
++ iommufd_backend_free_id(idev->iommufd, s1_hwpt->hwpt_id);
++ g_free(s1_hwpt);
++ }
++ return false;
++ }
++
++ /* Free the previous s1_hwpt */
++ if (accel_dev->s1_hwpt) {
++ iommufd_backend_free_id(idev->iommufd, accel_dev->s1_hwpt->hwpt_id);
++ g_free(accel_dev->s1_hwpt);
++ }
++
++ accel_dev->s1_hwpt = s1_hwpt;
++ if (hwpt_id == accel->abort_hwpt_id) {
++ type = "abort";
++ } else if (hwpt_id == accel->bypass_hwpt_id) {
++ type = "bypass";
++ } else {
++ type = "translate";
++ }
++
++ trace_smmuv3_accel_install_ste(sid, type, hwpt_id);
++ return true;
++}
++
++bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
++ Error **errp)
++{
++ SMMUv3AccelState *accel = s->s_accel;
++ SMMUv3AccelDevice *accel_dev;
++ Error *local_err = NULL;
++ bool all_ok = true;
++
++ if (!accel || !accel->viommu) {
++ return true;
++ }
++
++ QLIST_FOREACH(accel_dev, &accel->device_list, next) {
++ uint32_t sid = smmu_get_sid(&accel_dev->sdev);
++
++ if (sid >= range->start && sid <= range->end) {
++ if (!smmuv3_accel_install_ste(s, &accel_dev->sdev,
++ sid, &local_err)) {
++ error_append_hint(&local_err, "Device 0x%x: Failed to install "
++ "STE\n", sid);
++ error_report_err(local_err);
++ local_err = NULL;
++ all_ok = false;
++ }
++ }
++ }
++
++ if (!all_ok) {
++ error_setg(errp, "Failed to install all STEs properly");
++ }
++ return all_ok;
++}
++
+ static bool
+ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ Error **errp)
+@@ -161,6 +343,7 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
+ HostIOMMUDeviceIOMMUFD *idev;
+ SMMUv3AccelDevice *accel_dev;
+ SMMUv3AccelState *accel;
++ IOMMUFDVdev *vdev;
+ SMMUDevice *sdev;
+
+ if (!sbus) {
+@@ -181,6 +364,20 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
+ "0x%x", idev->devid);
+ }
+
++ if (accel_dev->s1_hwpt) {
++ iommufd_backend_free_id(accel_dev->idev->iommufd,
++ accel_dev->s1_hwpt->hwpt_id);
++ g_free(accel_dev->s1_hwpt);
++ accel_dev->s1_hwpt = NULL;
++ }
++
++ vdev = accel_dev->vdev;
++ if (vdev) {
++ iommufd_backend_free_id(accel->viommu->iommufd, vdev->vdevice_id);
++ g_free(vdev);
++ accel_dev->vdev = NULL;
++ }
++
+ accel_dev->idev = NULL;
+ accel_dev->s_accel = NULL;
+ QLIST_REMOVE(accel_dev, next);
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index efb631db4f..4e20b646dc 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -27,19 +27,41 @@ typedef struct SMMUv3AccelState {
+ QLIST_HEAD(, SMMUv3AccelDevice) device_list;
+ } SMMUv3AccelState;
+
++typedef struct SMMUS1Hwpt {
++ uint32_t hwpt_id;
++} SMMUS1Hwpt;
++
+ typedef struct SMMUv3AccelDevice {
+ SMMUDevice sdev;
+ HostIOMMUDeviceIOMMUFD *idev;
++ SMMUS1Hwpt *s1_hwpt;
++ IOMMUFDVdev *vdev;
+ QLIST_ENTRY(SMMUv3AccelDevice) next;
+ SMMUv3AccelState *s_accel;
+ } SMMUv3AccelDevice;
+
+ #ifdef CONFIG_ARM_SMMUV3_ACCEL
+ void smmuv3_accel_init(SMMUv3State *s);
++bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
++ Error **errp);
++bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
++ Error **errp);
+ #else
+ static inline void smmuv3_accel_init(SMMUv3State *s)
+ {
+ }
++static inline bool
++smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
++ Error **errp)
++{
++ return true;
++}
++static inline bool
++smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
++ Error **errp)
++{
++ return true;
++}
+ #endif
+
+ #endif /* HW_ARM_SMMUV3_ACCEL_H */
+diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
+index 8679ab6d09..998d30473d 100644
+--- a/hw/arm/smmuv3-internal.h
++++ b/hw/arm/smmuv3-internal.h
+@@ -353,6 +353,7 @@ typedef struct SMMUEventInfo {
+ } while (0)
+
+ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
++int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, SMMUEventInfo *event);
+
+ static inline int oas2bits(int oas_field)
+ {
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 374ae08baa..bfb41b8866 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -630,8 +630,7 @@ bad_ste:
+ * Supports linear and 2-level stream table
+ * Return 0 on success, -EINVAL otherwise
+ */
+-static int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste,
+- SMMUEventInfo *event)
++int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, SMMUEventInfo *event)
+ {
+ dma_addr_t addr, strtab_base;
+ uint32_t log2size;
+@@ -1341,6 +1340,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+ }
+
+ trace_smmuv3_cmdq_cfgi_ste(sid);
++ if (!smmuv3_accel_install_ste(s, sdev, sid, errp)) {
++ cmd_error = SMMU_CERROR_ILL;
++ break;
++ }
+ smmuv3_flush_config(sdev);
+
+ break;
+@@ -1361,6 +1364,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+ sid_range.end = sid_range.start + mask;
+
+ trace_smmuv3_cmdq_cfgi_ste_range(sid_range.start, sid_range.end);
++ if (!smmuv3_accel_install_ste_range(s, &sid_range, errp)) {
++ cmd_error = SMMU_CERROR_ILL;
++ break;
++ }
+ smmu_configs_inv_sid_range(bs, sid_range);
+ break;
+ }
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index 2aaa0c40c7..8135c0c734 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -69,6 +69,8 @@ smmu_reset_exit(void) ""
+ #smmuv3-accel.c
+ smmuv3_accel_set_iommu_device(int devfn, uint32_t devid) "devfn=0x%x (idev devid=0x%x)"
+ smmuv3_accel_unset_iommu_device(int devfn, uint32_t devid) "devfn=0x%x (idev devid=0x%x)"
++smmuv3_accel_translate_ste(uint32_t vsid, uint32_t hwpt_id, uint64_t ste_1, uint64_t ste_0) "vSID=0x%x hwpt_id=0x%x ste=%"PRIx64":%"PRIx64
++smmuv3_accel_install_ste(uint32_t vsid, const char * type, uint32_t hwpt_id) "vSID=0x%x ste type=%s hwpt_id=0x%x"
+
+ # strongarm.c
+ strongarm_uart_update_parameters(const char *label, int speed, char parity, int data_bits, int stop_bits) "%s speed=%d parity=%c data=%d stop=%d"
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index 905e6ca67f..4d8af5736a 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -99,10 +99,28 @@ REG32(STE_7, 28)
+ #define STE_CFG_S2_ENABLED(config) (config & 0x2)
+ #define STE_CFG_ABORT(config) (!(config & 0x4))
+ #define STE_CFG_BYPASS(config) (config == 0x4)
++#define STE_CFG_S1_TRANSLATE(config) (config == 0x5)
+
+ #define SMMU_STE_VALID (1ULL << 0)
+ #define SMMU_STE_CFG_BYPASS (1ULL << 3)
+
++#define STE0_V MAKE_64BIT_MASK(0, 1)
++#define STE0_CONFIG MAKE_64BIT_MASK(1, 3)
++#define STE0_S1FMT MAKE_64BIT_MASK(4, 2)
++#define STE0_CTXPTR MAKE_64BIT_MASK(6, 50)
++#define STE0_S1CDMAX MAKE_64BIT_MASK(59, 5)
++#define STE0_MASK (STE0_S1CDMAX | STE0_CTXPTR | STE0_S1FMT | STE0_CONFIG | \
++ STE0_V)
++
++#define STE1_S1DSS MAKE_64BIT_MASK(0, 2)
++#define STE1_S1CIR MAKE_64BIT_MASK(2, 2)
++#define STE1_S1COR MAKE_64BIT_MASK(4, 2)
++#define STE1_S1CSH MAKE_64BIT_MASK(6, 2)
++#define STE1_S1STALLD MAKE_64BIT_MASK(27, 1)
++#define STE1_EATS MAKE_64BIT_MASK(28, 2)
++#define STE1_MASK (STE1_EATS | STE1_S1STALLD | STE1_S1CSH | STE1_S1COR | \
++ STE1_S1CIR | STE1_S1DSS)
++
+ /* Update STE fields */
+ #define STE_SET_VALID(ste, v) \
+ ((ste)->word[0] = FIELD_DP32((ste)->word[0], STE_0, VALID, (v)))
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Add-property-to-specify-OAS-bits.patch b/kvm-hw-arm-smmuv3-accel-Add-property-to-specify-OAS-bits.patch
new file mode 100644
index 0000000..5291a7c
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Add-property-to-specify-OAS-bits.patch
@@ -0,0 +1,183 @@
+From 49c01e7b1f196b1251bbf6e3a993d662bd60b2a3 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 039/111] hw/arm/smmuv3-accel: Add property to specify OAS bits
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [39/111] db95cb3ea63f5ab2bdf80fccdf7f8baa4c81cc17 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+QEMU SMMUv3 currently sets the output address size (OAS) to 44 bits.
+With accelerator mode enabled, a device may use SVA, where CPU page tables
+are shared with the SMMU, requiring an OAS at least as large as the
+CPU’s output address size. A user option is added to configure this.
+
+However, the OAS value advertised by the virtual SMMU must remain
+compatible with the capabilities of the host SMMUv3. In accelerated
+mode, the host SMMU performs stage-2 translation and must be able to
+consume the intermediate physical addresses (IPA) produced by stage-1.
+
+The OAS exposed by the virtual SMMU defines the maximum IPA width that
+stage-1 translations may generate. For AArch64 implementations, the
+maximum usable IPA size on the host SMMU is determined by its own OAS.
+Check that the configured OAS does not exceed what the host SMMU
+can safely support.
+
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-32-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit a015ac990fd31bd4c93ce430aa4fce19dbfa49f8)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 22 ++++++++++++++++++++++
+ hw/arm/smmuv3.c | 16 +++++++++++++++-
+ include/hw/arm/smmuv3-common.h | 5 ++++-
+ include/hw/arm/smmuv3.h | 1 +
+ 4 files changed, 42 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index a97abc1f79..ea420afeb7 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -27,6 +27,14 @@
+ static MemoryRegion root, sysmem;
+ static AddressSpace *shared_as_sysmem;
+
++static int smmuv3_oas_bits(uint32_t oas)
++{
++ static const int map[] = { 32, 36, 40, 42, 44, 48, 52, 56 };
++
++ g_assert(oas < ARRAY_SIZE(map));
++ return map[oas];
++}
++
+ static bool
+ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
+ struct iommu_hw_info_arm_smmuv3 *info,
+@@ -74,6 +82,15 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
+ error_setg(errp, "Host SMMUv3 doesn't support Range Invalidation");
+ return false;
+ }
++ /* Check OAS value opted is compatible with Host SMMUv3 IPA */
++ if (FIELD_EX32(info->idr[5], IDR5, OAS) <
++ FIELD_EX32(s->idr[5], IDR5, OAS)) {
++ error_setg(errp, "Host SMMUv3 supports only %d-bit IPA, but the vSMMU "
++ "OAS implies %d-bit IPA",
++ smmuv3_oas_bits(FIELD_EX32(info->idr[5], IDR5, OAS)),
++ smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
++ return false;
++ }
+
+ /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
+ if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
+@@ -657,6 +674,11 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
+
+ /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
++
++ /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
++ if (s->oas == SMMU_OAS_48BIT) {
++ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS_48);
++ }
+ }
+
+ /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index ead0785b2b..ef75a9bec0 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -299,7 +299,8 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
+ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
+ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, BBML, 2);
+
+- s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
++ /* OAS: 44 bits */
++ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS_44);
+ /* 4K, 16K and 64K granule support */
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1);
+@@ -1949,6 +1950,10 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "ats can only be enabled if accel=on");
+ return false;
+ }
++ if (s->oas != SMMU_OAS_44BIT) {
++ error_setg(errp, "OAS must be 44 bits when accel=off");
++ return false;
++ }
+ return true;
+ }
+
+@@ -1959,6 +1964,11 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ return false;
+ }
+
++ if (s->oas != SMMU_OAS_44BIT && s->oas != SMMU_OAS_48BIT) {
++ error_setg(errp, "OAS can only be set to 44 or 48 bits");
++ return false;
++ }
++
+ return true;
+ }
+
+@@ -2085,6 +2095,7 @@ static const Property smmuv3_properties[] = {
+ /* RIL can be turned off for accel cases */
+ DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
+ DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
++ DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
+ };
+
+ static void smmuv3_instance_init(Object *obj)
+@@ -2115,6 +2126,9 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ object_class_property_set_description(klass, "ats",
+ "Enable/disable ATS support (for accel=on). Please ensure host "
+ "platform has ATS support before enabling this");
++ object_class_property_set_description(klass, "oas",
++ "Specify Output Address Size (for accel=on). Supported values "
++ "are 44 or 48 bits. Defaults to 44 bits");
+ }
+
+ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index 4d8af5736a..bc2d49ef4e 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -342,7 +342,10 @@ REG32(IDR5, 0x14)
+ FIELD(IDR5, VAX, 10, 2);
+ FIELD(IDR5, STALL_MAX, 16, 16);
+
+-#define SMMU_IDR5_OAS 4
++#define SMMU_OAS_44BIT 44
++#define SMMU_OAS_48BIT 48
++#define SMMU_IDR5_OAS_44 4
++#define SMMU_IDR5_OAS_48 5
+
+ REG32(IIDR, 0x18)
+ REG32(AIDR, 0x1c)
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index 242d6429ed..d488a39cd0 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -71,6 +71,7 @@ struct SMMUv3State {
+ Error *migration_blocker;
+ bool ril;
+ bool ats;
++ uint8_t oas;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Add-set-unset_iommu_device-callb.patch b/kvm-hw-arm-smmuv3-accel-Add-set-unset_iommu_device-callb.patch
new file mode 100644
index 0000000..e5cd7c3
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Add-set-unset_iommu_device-callb.patch
@@ -0,0 +1,365 @@
+From 3ffeaf008bfcd0e3517239322b1469074cb474bf Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 020/111] hw/arm/smmuv3-accel: Add set/unset_iommu_device
+ callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [20/111] ed11473feafc3c55d8fef15e1837baa55ae48974 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Implement the VFIO/PCI callbacks to attach and detach a HostIOMMUDevice
+to a vSMMUv3 when accel=on,
+
+ - set_iommu_device(): attach a HostIOMMUDevice to a vIOMMU
+ - unset_iommu_device(): detach and release associated resources
+
+In SMMUv3 accel=on mode, the guest SMMUv3 is backed by the host SMMUv3 via
+IOMMUFD. A vIOMMU object (created via IOMMU_VIOMMU_ALLOC) provides a per-VM,
+security-isolated handle to the physical SMMUv3. Without a vIOMMU, the
+vSMMUv3 cannot relay guest operations to the host hardware nor maintain
+isolation across VMs or devices. Therefore, set_iommu_device() allocates
+a vIOMMU object if one does not already exist.
+
+There are two main points to consider in this implementation:
+
+1) VFIO core allocates and attaches a S2 HWPT that acts as the nesting
+ parent for nested HWPTs(IOMMU_DOMAIN_NESTED). This parent HWPT will
+ be shared across multiple vSMMU instances within a VM.
+
+2) A device cannot attach directly to a vIOMMU. Instead, it attaches
+ through a proxy nested HWPT (IOMMU_DOMAIN_NESTED). Based on the STE
+ configuration,there are three types of nested HWPTs: bypass, abort,
+ and translate.
+ -The bypass and abort proxy HWPTs are pre-allocated. When SMMUv3
+ operates in global abort or bypass modes, as controlled by the GBPA
+ register, or issues a vSTE for bypass or abort we attach these
+ pre-allocated nested HWPTs.
+ -The translate HWPT requires a vDEVICE to be allocated first, since
+ invalidations and events depend on a valid vSID.
+ -The vDEVICE allocation and attach operations for vSTE based HWPTs
+ are implemented in subsequent patches.
+
+In summary, a device placed behind a vSMMU instance must have a vSID for
+translate vSTE. The bypass and abort vSTEs are pre-allocated as proxy
+nested HWPTs and is attached based on GBPA register. The core-managed
+nesting parent S2 HWPT is used as parent S2 HWPT for all the nested
+HWPTs and is intended to be shared across vSMMU instances within the
+same VM.
+
+set_iommu_device():
+ - Reuse an existing vIOMMU for the same physical SMMU if available.
+ If not, allocate a new one using the nesting parent S2 HWPT.
+ - Pre-allocate two proxy nested HWPTs (bypass and abort) under the
+ vIOMMU and install one based on GBPA.ABORT value.
+ - Add the device to the vIOMMU’s device list.
+
+unset_iommu_device():
+ - Re-attach device to the nesting parent S2 HWPT.
+ - Remove the device from the vIOMMU’s device list.
+ - If the list is empty, free the proxy HWPTs (bypass and abort)
+ and release the vIOMMU object.
+
+Introduce struct SMMUv3AccelState, representing an accelerated SMMUv3
+instance backed by an iommufd vIOMMU object, and storing the bypass and
+abort proxy HWPT IDs.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-13-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 703b7b91db064b94bb67bc49eaf503b2d6a8d333)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 156 +++++++++++++++++++++++++++++++++
+ hw/arm/smmuv3-accel.h | 18 ++++
+ hw/arm/trace-events | 4 +
+ include/hw/arm/smmuv3-common.h | 3 +
+ include/hw/arm/smmuv3.h | 1 +
+ 5 files changed, 182 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index be09cf8b73..9c2b917a11 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -8,6 +8,7 @@
+
+ #include "qemu/osdep.h"
+ #include "qemu/error-report.h"
++#include "trace.h"
+
+ #include "hw/arm/smmuv3.h"
+ #include "hw/core/iommu.h"
+@@ -15,6 +16,7 @@
+ #include "hw/pci-host/gpex.h"
+ #include "hw/vfio/pci.h"
+
++#include "smmuv3-internal.h"
+ #include "smmuv3-accel.h"
+
+ /*
+@@ -43,6 +45,157 @@ static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus,
+ return accel_dev;
+ }
+
++static uint32_t smmuv3_accel_gbpa_hwpt(SMMUv3State *s, SMMUv3AccelState *accel)
++{
++ return FIELD_EX32(s->gbpa, GBPA, ABORT) ?
++ accel->abort_hwpt_id : accel->bypass_hwpt_id;
++}
++
++static bool
++smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
++ Error **errp)
++{
++ SMMUv3AccelState *accel = s->s_accel;
++ struct iommu_hwpt_arm_smmuv3 bypass_data = {
++ .ste = { SMMU_STE_CFG_BYPASS | SMMU_STE_VALID, 0x0ULL },
++ };
++ struct iommu_hwpt_arm_smmuv3 abort_data = {
++ .ste = { SMMU_STE_VALID, 0x0ULL },
++ };
++ uint32_t s2_hwpt_id = idev->hwpt_id;
++ uint32_t viommu_id, hwpt_id;
++ IOMMUFDViommu *viommu;
++
++ if (!iommufd_backend_alloc_viommu(idev->iommufd, idev->devid,
++ IOMMU_VIOMMU_TYPE_ARM_SMMUV3,
++ s2_hwpt_id, &viommu_id, errp)) {
++ return false;
++ }
++
++ viommu = g_new0(IOMMUFDViommu, 1);
++ viommu->viommu_id = viommu_id;
++ viommu->s2_hwpt_id = s2_hwpt_id;
++ viommu->iommufd = idev->iommufd;
++
++ /*
++ * Pre-allocate HWPTs for S1 bypass and abort cases. These will be attached
++ * later for guest STEs or GBPAs that require bypass or abort configuration.
++ */
++ if (!iommufd_backend_alloc_hwpt(idev->iommufd, idev->devid, viommu_id,
++ 0, IOMMU_HWPT_DATA_ARM_SMMUV3,
++ sizeof(abort_data), &abort_data,
++ &accel->abort_hwpt_id, errp)) {
++ goto free_viommu;
++ }
++
++ if (!iommufd_backend_alloc_hwpt(idev->iommufd, idev->devid, viommu_id,
++ 0, IOMMU_HWPT_DATA_ARM_SMMUV3,
++ sizeof(bypass_data), &bypass_data,
++ &accel->bypass_hwpt_id, errp)) {
++ goto free_abort_hwpt;
++ }
++
++ /* Attach a HWPT based on SMMUv3 GBPA.ABORT value */
++ hwpt_id = smmuv3_accel_gbpa_hwpt(s, accel);
++ if (!host_iommu_device_iommufd_attach_hwpt(idev, hwpt_id, errp)) {
++ goto free_bypass_hwpt;
++ }
++ accel->viommu = viommu;
++ return true;
++
++free_bypass_hwpt:
++ iommufd_backend_free_id(idev->iommufd, accel->bypass_hwpt_id);
++free_abort_hwpt:
++ iommufd_backend_free_id(idev->iommufd, accel->abort_hwpt_id);
++free_viommu:
++ iommufd_backend_free_id(idev->iommufd, viommu->viommu_id);
++ g_free(viommu);
++ return false;
++}
++
++static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
++ HostIOMMUDevice *hiod, Error **errp)
++{
++ HostIOMMUDeviceIOMMUFD *idev = HOST_IOMMU_DEVICE_IOMMUFD(hiod);
++ SMMUState *bs = opaque;
++ SMMUv3State *s = ARM_SMMUV3(bs);
++ SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
++ SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus, bus, devfn);
++
++ if (!idev) {
++ return true;
++ }
++
++ if (accel_dev->idev) {
++ if (accel_dev->idev != idev) {
++ error_setg(errp, "Device already has an associated idev 0x%x",
++ idev->devid);
++ return false;
++ }
++ return true;
++ }
++
++ if (s->s_accel->viommu) {
++ goto done;
++ }
++
++ if (!smmuv3_accel_alloc_viommu(s, idev, errp)) {
++ error_append_hint(errp, "Unable to alloc vIOMMU: idev devid 0x%x: ",
++ idev->devid);
++ return false;
++ }
++
++done:
++ accel_dev->idev = idev;
++ accel_dev->s_accel = s->s_accel;
++ QLIST_INSERT_HEAD(&s->s_accel->device_list, accel_dev, next);
++ trace_smmuv3_accel_set_iommu_device(devfn, idev->devid);
++ return true;
++}
++
++static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
++ int devfn)
++{
++ SMMUState *bs = opaque;
++ SMMUPciBus *sbus = g_hash_table_lookup(bs->smmu_pcibus_by_busptr, bus);
++ HostIOMMUDeviceIOMMUFD *idev;
++ SMMUv3AccelDevice *accel_dev;
++ SMMUv3AccelState *accel;
++ SMMUDevice *sdev;
++
++ if (!sbus) {
++ return;
++ }
++
++ sdev = sbus->pbdev[devfn];
++ if (!sdev) {
++ return;
++ }
++
++ accel_dev = container_of(sdev, SMMUv3AccelDevice, sdev);
++ idev = accel_dev->idev;
++ accel = accel_dev->s_accel;
++ /* Re-attach the default s2 hwpt id */
++ if (!host_iommu_device_iommufd_attach_hwpt(idev, idev->hwpt_id, NULL)) {
++ error_report("Unable to attach the default HW pagetable: idev devid "
++ "0x%x", idev->devid);
++ }
++
++ accel_dev->idev = NULL;
++ accel_dev->s_accel = NULL;
++ QLIST_REMOVE(accel_dev, next);
++ trace_smmuv3_accel_unset_iommu_device(devfn, idev->devid);
++
++ if (QLIST_EMPTY(&accel->device_list)) {
++ iommufd_backend_free_id(accel->viommu->iommufd, accel->bypass_hwpt_id);
++ iommufd_backend_free_id(accel->viommu->iommufd, accel->abort_hwpt_id);
++ iommufd_backend_free_id(accel->viommu->iommufd,
++ accel->viommu->viommu_id);
++ g_free(accel->viommu);
++ accel->viommu = NULL;
++ }
++}
++
+ /*
+ * Only allow PCIe bridges, pxb-pcie roots, and GPEX roots so vfio-pci
+ * endpoints can sit downstream. Accelerated SMMUv3 requires a vfio-pci
+@@ -145,6 +298,8 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
+ .supports_address_space = smmuv3_accel_supports_as,
+ .get_address_space = smmuv3_accel_find_add_as,
+ .get_viommu_flags = smmuv3_accel_get_viommu_flags,
++ .set_iommu_device = smmuv3_accel_set_iommu_device,
++ .unset_iommu_device = smmuv3_accel_unset_iommu_device,
+ };
+
+ static void smmuv3_accel_as_init(SMMUv3State *s)
+@@ -168,6 +323,7 @@ void smmuv3_accel_init(SMMUv3State *s)
+ {
+ SMMUState *bs = ARM_SMMU(s);
+
++ s->s_accel = g_new0(SMMUv3AccelState, 1);
+ bs->iommu_ops = &smmuv3_accel_ops;
+ smmuv3_accel_as_init(s);
+ }
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index 0dc6b00d35..efb631db4f 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -10,10 +10,28 @@
+ #define HW_ARM_SMMUV3_ACCEL_H
+
+ #include "hw/arm/smmu-common.h"
++#include "system/iommufd.h"
++#ifdef CONFIG_LINUX
++#include <linux/iommufd.h>
++#endif
+ #include CONFIG_DEVICES
+
++/*
++ * Represents an accelerated SMMU instance backed by an iommufd vIOMMU object.
++ * Holds bypass and abort proxy HWPT IDs used for device attachment.
++ */
++typedef struct SMMUv3AccelState {
++ IOMMUFDViommu *viommu;
++ uint32_t bypass_hwpt_id;
++ uint32_t abort_hwpt_id;
++ QLIST_HEAD(, SMMUv3AccelDevice) device_list;
++} SMMUv3AccelState;
++
+ typedef struct SMMUv3AccelDevice {
+ SMMUDevice sdev;
++ HostIOMMUDeviceIOMMUFD *idev;
++ QLIST_ENTRY(SMMUv3AccelDevice) next;
++ SMMUv3AccelState *s_accel;
+ } SMMUv3AccelDevice;
+
+ #ifdef CONFIG_ARM_SMMUV3_ACCEL
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index f3386bd7ae..2aaa0c40c7 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -66,6 +66,10 @@ smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s
+ smmuv3_inv_notifiers_iova(const char *name, int asid, int vmid, uint64_t iova, uint8_t tg, uint64_t num_pages, int stage) "iommu mr=%s asid=%d vmid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" stage=%d"
+ smmu_reset_exit(void) ""
+
++#smmuv3-accel.c
++smmuv3_accel_set_iommu_device(int devfn, uint32_t devid) "devfn=0x%x (idev devid=0x%x)"
++smmuv3_accel_unset_iommu_device(int devfn, uint32_t devid) "devfn=0x%x (idev devid=0x%x)"
++
+ # strongarm.c
+ strongarm_uart_update_parameters(const char *label, int speed, char parity, int data_bits, int stop_bits) "%s speed=%d parity=%c data=%d stop=%d"
+ strongarm_ssp_read_underrun(void) "SSP rx underrun"
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index 30101915e2..905e6ca67f 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -100,6 +100,9 @@ REG32(STE_7, 28)
+ #define STE_CFG_ABORT(config) (!(config & 0x4))
+ #define STE_CFG_BYPASS(config) (config == 0x4)
+
++#define SMMU_STE_VALID (1ULL << 0)
++#define SMMU_STE_CFG_BYPASS (1ULL << 3)
++
+ /* Update STE fields */
+ #define STE_SET_VALID(ste, v) \
+ ((ste)->word[0] = FIELD_DP32((ste)->word[0], STE_0, VALID, (v)))
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index bb7076286b..e54ece2d38 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -66,6 +66,7 @@ struct SMMUv3State {
+
+ /* SMMU has HW accelerator support for nested S1 + s2 */
+ bool accel;
++ struct SMMUv3AccelState *s_accel;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Add-support-for-ATS.patch b/kvm-hw-arm-smmuv3-accel-Add-support-for-ATS.patch
new file mode 100644
index 0000000..a6513bb
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Add-support-for-ATS.patch
@@ -0,0 +1,188 @@
+From edf2b5c6f9319e6516568a31d19c46eac686303f Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 038/111] hw/arm/smmuv3-accel: Add support for ATS
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [38/111] 55e6f061ef300a52b72b8268437085e344a6f818 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+QEMU SMMUv3 does not enable ATS (Address Translation Services) by default.
+When accelerated mode is enabled and the host SMMUv3 supports ATS, it can
+be useful to report ATS capability to the guest so it can take advantage
+of it if the device also supports ATS.
+
+Note: ATS support cannot be reliably detected from the host SMMUv3 IDR
+registers alone, as firmware ACPI IORT tables may override them. The
+user must therefore ensure the support before enabling it.
+
+The ATS support enabled here is only relevant for vfio-pci endpoints,
+as SMMUv3 accelerated mode does not support emulated endpoint devices.
+QEMU’s SMMUv3 implementation still lacks support for handling ATS
+translation requests, which would be required for emulated endpoints.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-31-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit f7f5013a55a3447ca81383d8969626e092feb0c9)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 3 +++
+ hw/arm/smmuv3.c | 24 +++++++++++++++++++++++-
+ hw/arm/virt-acpi-build.c | 10 ++++++++--
+ include/hw/arm/smmuv3.h | 1 +
+ 4 files changed, 35 insertions(+), 3 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index df82f1e32a..a97abc1f79 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -654,6 +654,9 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
+
+ /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
+ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
++
++ /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
++ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
+ }
+
+ /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 643706b29c..ead0785b2b 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1498,13 +1498,27 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+ */
+ smmuv3_range_inval(bs, &cmd, SMMU_STAGE_2);
+ break;
++ case SMMU_CMD_ATC_INV:
++ {
++ SMMUDevice *sdev = smmu_find_sdev(bs, CMD_SID(&cmd));
++
++ if (!sdev || !s->ats) {
++ trace_smmuv3_unhandled_cmd(type);
++ break;
++ }
++
++ if (!smmuv3_accel_issue_inv_cmd(s, &cmd, sdev, errp)) {
++ cmd_error = SMMU_CERROR_ILL;
++ break;
++ }
++ break;
++ }
+ case SMMU_CMD_TLBI_EL3_ALL:
+ case SMMU_CMD_TLBI_EL3_VA:
+ case SMMU_CMD_TLBI_EL2_ALL:
+ case SMMU_CMD_TLBI_EL2_ASID:
+ case SMMU_CMD_TLBI_EL2_VA:
+ case SMMU_CMD_TLBI_EL2_VAA:
+- case SMMU_CMD_ATC_INV:
+ case SMMU_CMD_PRI_RESP:
+ case SMMU_CMD_RESUME:
+ case SMMU_CMD_STALL_TERM:
+@@ -1931,6 +1945,10 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "ril can only be disabled if accel=on");
+ return false;
+ }
++ if (s->ats) {
++ error_setg(errp, "ats can only be enabled if accel=on");
++ return false;
++ }
+ return true;
+ }
+
+@@ -2066,6 +2084,7 @@ static const Property smmuv3_properties[] = {
+ DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
+ /* RIL can be turned off for accel cases */
+ DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
++ DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
+ };
+
+ static void smmuv3_instance_init(Object *obj)
+@@ -2093,6 +2112,9 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "configured in nested mode for vfio-pci dev assignment");
+ object_class_property_set_description(klass, "ril",
+ "Disable range invalidation support (for accel=on)");
++ object_class_property_set_description(klass, "ats",
++ "Enable/disable ATS support (for accel=on). Please ensure host "
++ "platform has ATS support before enabling this");
+ }
+
+ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
+index 33c6519f0a..160f1d10e5 100644
+--- a/hw/arm/virt-acpi-build.c
++++ b/hw/arm/virt-acpi-build.c
+@@ -352,6 +352,7 @@ typedef struct AcpiIortSMMUv3Dev {
+ /* Offset of the SMMUv3 IORT Node relative to the start of the IORT */
+ size_t offset;
+ bool accel;
++ bool ats;
+ } AcpiIortSMMUv3Dev;
+
+ /*
+@@ -407,6 +408,7 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
+
+ bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
+ sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
++ sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
+ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+ sbdev = SYS_BUS_DEVICE(obj);
+ sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+@@ -550,6 +552,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ int i, nb_nodes, rc_mapping_count;
+ AcpiIortSMMUv3Dev *sdev;
+ size_t node_size;
++ bool ats_needed = false;
+ int num_smmus = 0;
+ uint32_t id = 0;
+ int rc_smmu_idmaps_len = 0;
+@@ -585,6 +588,9 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ /* Calculate RMR nodes required. One per SMMUv3 with accelerated mode */
+ for (i = 0; i < num_smmus; i++) {
+ sdev = &g_array_index(smmuv3_devs, AcpiIortSMMUv3Dev, i);
++ if (sdev->ats) {
++ ats_needed = true;
++ }
+ if (sdev->accel) {
+ nb_nodes++;
+ }
+@@ -684,8 +690,8 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ build_append_int_noprefix(table_data, 0, 2); /* Reserved */
+ /* Table 15 Memory Access Flags */
+ build_append_int_noprefix(table_data, 0x3 /* CCA = CPM = DACS = 1 */, 1);
+-
+- build_append_int_noprefix(table_data, 0, 4); /* ATS Attribute */
++ /* ATS Attribute */
++ build_append_int_noprefix(table_data, ats_needed, 4);
+ /* MCFG pci_segment */
+ build_append_int_noprefix(table_data, 0, 4); /* PCI Segment number */
+
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index 533a2182e8..242d6429ed 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -70,6 +70,7 @@ struct SMMUv3State {
+ uint64_t msi_gpa;
+ Error *migration_blocker;
+ bool ril;
++ bool ats;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Add-support-to-issue-invalidatio.patch b/kvm-hw-arm-smmuv3-accel-Add-support-to-issue-invalidatio.patch
new file mode 100644
index 0000000..737310c
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Add-support-to-issue-invalidatio.patch
@@ -0,0 +1,164 @@
+From e63deec0748ea8d907098217a1692d442ba0d6a2 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 027/111] hw/arm/smmuv3-accel: Add support to issue
+ invalidation cmd to host
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [27/111] 5f28f189e1947bf85860a98e0952b5384d73db00 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Provide a helper and use that to issue the invalidation cmd to host SMMUv3.
+We only issue one cmd at a time for now.
+
+Support for batching of commands will be added later after analysing the
+impact.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-20-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 58a789c389cb691c8b25c1a673cfffe49fe93554)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 36 ++++++++++++++++++++++++++++++++++++
+ hw/arm/smmuv3-accel.h | 8 ++++++++
+ hw/arm/smmuv3.c | 16 ++++++++++++++++
+ 3 files changed, 60 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index c6ee123cdf..89dc6f991c 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -233,6 +233,42 @@ bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
+ return all_ok;
+ }
+
++/*
++ * This issues the invalidation cmd to the host SMMUv3.
++ *
++ * sdev is non-NULL for SID based invalidations (e.g. CFGI_CD), and NULL for
++ * non SID invalidations such as SMMU_CMD_TLBI_NH_ASID and SMMU_CMD_TLBI_NH_VA.
++ */
++bool smmuv3_accel_issue_inv_cmd(SMMUv3State *bs, void *cmd, SMMUDevice *sdev,
++ Error **errp)
++{
++ SMMUv3State *s = ARM_SMMUV3(bs);
++ SMMUv3AccelState *accel = s->s_accel;
++ uint32_t entry_num = 1;
++
++ /*
++ * No accel or viommu means no VFIO/IOMMUFD devices, nothing to
++ * invalidate.
++ */
++ if (!accel || !accel->viommu) {
++ return true;
++ }
++
++ /*
++ * SID based invalidations (e.g. CFGI_CD) apply only to vfio-pci endpoints
++ * with a valid vIOMMU vdev.
++ */
++ if (sdev && !container_of(sdev, SMMUv3AccelDevice, sdev)->vdev) {
++ return true;
++ }
++
++ /* Single command (entry_num = 1); no need to check returned entry_num */
++ return iommufd_backend_invalidate_cache(
++ accel->viommu->iommufd, accel->viommu->viommu_id,
++ IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3,
++ sizeof(Cmd), &entry_num, cmd, errp);
++}
++
+ static bool
+ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ Error **errp)
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index c7ed4dce3a..41b37e3122 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -47,6 +47,8 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+ bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
+ Error **errp);
+ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp);
++bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
++ Error **errp);
+ void smmuv3_accel_reset(SMMUv3State *s);
+ #else
+ static inline void smmuv3_accel_init(SMMUv3State *s)
+@@ -68,6 +70,12 @@ static inline bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
+ {
+ return true;
+ }
++static inline bool
++smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
++ Error **errp)
++{
++ return true;
++}
+ static inline void smmuv3_accel_reset(SMMUv3State *s)
+ {
+ }
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index f02e3ee46c..513da966a4 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1388,6 +1388,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+
+ trace_smmuv3_cmdq_cfgi_cd(sid);
+ smmuv3_flush_config(sdev);
++ if (!smmuv3_accel_issue_inv_cmd(s, &cmd, sdev, errp)) {
++ cmd_error = SMMU_CERROR_ILL;
++ break;
++ }
+ break;
+ }
+ case SMMU_CMD_TLBI_NH_ASID:
+@@ -1411,6 +1415,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+ trace_smmuv3_cmdq_tlbi_nh_asid(asid);
+ smmu_inv_notifiers_all(&s->smmu_state);
+ smmu_iotlb_inv_asid_vmid(bs, asid, vmid);
++ if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) {
++ cmd_error = SMMU_CERROR_ILL;
++ break;
++ }
+ break;
+ }
+ case SMMU_CMD_TLBI_NH_ALL:
+@@ -1438,6 +1446,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+ trace_smmuv3_cmdq_tlbi_nsnh();
+ smmu_inv_notifiers_all(&s->smmu_state);
+ smmu_iotlb_inv_all(bs);
++ if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) {
++ cmd_error = SMMU_CERROR_ILL;
++ break;
++ }
+ break;
+ case SMMU_CMD_TLBI_NH_VAA:
+ case SMMU_CMD_TLBI_NH_VA:
+@@ -1446,6 +1458,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+ break;
+ }
+ smmuv3_range_inval(bs, &cmd, SMMU_STAGE_1);
++ if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) {
++ cmd_error = SMMU_CERROR_ILL;
++ break;
++ }
+ break;
+ case SMMU_CMD_TLBI_S12_VMALL:
+ {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Add-viommu-free-helper.patch b/kvm-hw-arm-smmuv3-accel-Add-viommu-free-helper.patch
new file mode 100644
index 0000000..2c6b3a8
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Add-viommu-free-helper.patch
@@ -0,0 +1,81 @@
+From bb6023507aee06a4e9c7436425b863fe1088e515 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Fri, 6 Mar 2026 09:01:11 +0000
+Subject: [PATCH 051/111] hw/arm/smmuv3-accel: Add viommu free helper
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [51/111] ac43708d52e6d4d84e4d54b0cb955f8518fe35d6 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73796
+
+Move viommu teardown into a helper function and use it from the
+last device removal path.
+
+This groups related cleanup logic in one place and improves readability.
+It also makes it easier to extend the teardown in future, for example
+when freeing related objects such as vEVENTQ.
+
+No functional change.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260226084456.112142-3-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 674d57bf6e26a3ae7076a7ee56e6be90580d5208)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index f5cd4df336..c19c526fca 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -390,6 +390,20 @@ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *bs, void *cmd, SMMUDevice *sdev,
+ sizeof(Cmd), &entry_num, cmd, errp);
+ }
+
++static void smmuv3_accel_free_viommu(SMMUv3AccelState *accel)
++{
++ IOMMUFDViommu *viommu = accel->viommu;
++
++ if (!viommu) {
++ return;
++ }
++ iommufd_backend_free_id(viommu->iommufd, accel->bypass_hwpt_id);
++ iommufd_backend_free_id(viommu->iommufd, accel->abort_hwpt_id);
++ iommufd_backend_free_id(viommu->iommufd, accel->viommu->viommu_id);
++ g_free(viommu);
++ accel->viommu = NULL;
++}
++
+ static bool
+ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ Error **errp)
+@@ -549,12 +563,7 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
+ trace_smmuv3_accel_unset_iommu_device(devfn, idev->devid);
+
+ if (QLIST_EMPTY(&accel->device_list)) {
+- iommufd_backend_free_id(accel->viommu->iommufd, accel->bypass_hwpt_id);
+- iommufd_backend_free_id(accel->viommu->iommufd, accel->abort_hwpt_id);
+- iommufd_backend_free_id(accel->viommu->iommufd,
+- accel->viommu->viommu_id);
+- g_free(accel->viommu);
+- accel->viommu = NULL;
++ smmuv3_accel_free_viommu(accel);
+ }
+ }
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Allocate-vEVENTQ-for-accelerated.patch b/kvm-hw-arm-smmuv3-accel-Allocate-vEVENTQ-for-accelerated.patch
new file mode 100644
index 0000000..60718fc
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Allocate-vEVENTQ-for-accelerated.patch
@@ -0,0 +1,225 @@
+From ad0ae224f8e30f6504181cc9d580422ce204b03a Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Fri, 6 Mar 2026 09:01:11 +0000
+Subject: [PATCH 052/111] hw/arm/smmuv3-accel: Allocate vEVENTQ for accelerated
+ SMMUv3 devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [52/111] 91c7085fb8f11c45dfde43b0b5aaaac772571282 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73796
+
+When the guest enables the Event Queue and a vIOMMU is present, allocate a
+vEVENTQ object so that host-side events related to the vIOMMU can be
+received and propagated back to the guest.
+
+Allocate a vEVENTQ only when both of the following conditions are met:
+
+ 1) The guest SMMUv3 driver has set EVENTQEN = 1 in SMMU_CR0.
+ 2) A vIOMMU exists (created when the first VFIO device is attached).
+
+These two conditions may occur in any order.
+
+In the cold-plug case, the vIOMMU already exists before the guest
+driver probes. When the guest sets EVENTQEN = 1 during driver probe,
+the vEVENTQ is allocated at that point.
+
+With hot-plug, the VFIO device may be attached either before or after
+the guest sets EVENTQEN. If the vIOMMU is created first, allocation is
+deferred until EVENTQEN = 1. If EVENTQEN is already set, allocation
+happens when the vIOMMU is created.
+
+In all cases, allocation is triggered when the second required
+condition becomes true.
+
+Errors from command queue consumption and vEVENTQ allocation are reported
+independently as the two operations are unrelated.
+
+Event read and propagation will be added in a later patch.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260226084456.112142-4-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 46f0d48393529cfa3659012971c20f6808eb3b78)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 61 +++++++++++++++++++++++++++++++++++++++++--
+ hw/arm/smmuv3-accel.h | 6 +++++
+ hw/arm/smmuv3.c | 6 +++++
+ 3 files changed, 71 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index c19c526fca..f703ea1aac 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -390,6 +390,19 @@ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *bs, void *cmd, SMMUDevice *sdev,
+ sizeof(Cmd), &entry_num, cmd, errp);
+ }
+
++static void smmuv3_accel_free_veventq(SMMUv3AccelState *accel)
++{
++ IOMMUFDVeventq *veventq = accel->veventq;
++
++ if (!veventq) {
++ return;
++ }
++ close(veventq->veventq_fd);
++ iommufd_backend_free_id(accel->viommu->iommufd, veventq->veventq_id);
++ g_free(veventq);
++ accel->veventq = NULL;
++}
++
+ static void smmuv3_accel_free_viommu(SMMUv3AccelState *accel)
+ {
+ IOMMUFDViommu *viommu = accel->viommu;
+@@ -397,6 +410,7 @@ static void smmuv3_accel_free_viommu(SMMUv3AccelState *accel)
+ if (!viommu) {
+ return;
+ }
++ smmuv3_accel_free_veventq(accel);
+ iommufd_backend_free_id(viommu->iommufd, accel->bypass_hwpt_id);
+ iommufd_backend_free_id(viommu->iommufd, accel->abort_hwpt_id);
+ iommufd_backend_free_id(viommu->iommufd, accel->viommu->viommu_id);
+@@ -404,6 +418,41 @@ static void smmuv3_accel_free_viommu(SMMUv3AccelState *accel)
+ accel->viommu = NULL;
+ }
+
++bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp)
++{
++ SMMUv3AccelState *accel = s->s_accel;
++ IOMMUFDVeventq *veventq;
++ uint32_t veventq_id;
++ uint32_t veventq_fd;
++
++ if (!accel || !accel->viommu) {
++ return true;
++ }
++
++ if (accel->veventq) {
++ return true;
++ }
++
++ if (!smmuv3_eventq_enabled(s)) {
++ return true;
++ }
++
++ if (!iommufd_backend_alloc_veventq(accel->viommu->iommufd,
++ accel->viommu->viommu_id,
++ IOMMU_VEVENTQ_TYPE_ARM_SMMUV3,
++ 1 << s->eventq.log2size, &veventq_id,
++ &veventq_fd, errp)) {
++ return false;
++ }
++
++ veventq = g_new0(IOMMUFDVeventq, 1);
++ veventq->veventq_id = veventq_id;
++ veventq->veventq_fd = veventq_fd;
++ veventq->viommu = accel->viommu;
++ accel->veventq = veventq;
++ return true;
++}
++
+ static bool
+ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ Error **errp)
+@@ -429,6 +478,7 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ viommu->viommu_id = viommu_id;
+ viommu->s2_hwpt_id = s2_hwpt_id;
+ viommu->iommufd = idev->iommufd;
++ accel->viommu = viommu;
+
+ /*
+ * Pre-allocate HWPTs for S1 bypass and abort cases. These will be attached
+@@ -448,14 +498,20 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ goto free_abort_hwpt;
+ }
+
++ /* Allocate a vEVENTQ if guest has enabled event queue */
++ if (!smmuv3_accel_alloc_veventq(s, errp)) {
++ goto free_bypass_hwpt;
++ }
++
+ /* Attach a HWPT based on SMMUv3 GBPA.ABORT value */
+ hwpt_id = smmuv3_accel_gbpa_hwpt(s, accel);
+ if (!host_iommu_device_iommufd_attach_hwpt(idev, hwpt_id, errp)) {
+- goto free_bypass_hwpt;
++ goto free_veventq;
+ }
+- accel->viommu = viommu;
+ return true;
+
++free_veventq:
++ smmuv3_accel_free_veventq(accel);
+ free_bypass_hwpt:
+ iommufd_backend_free_id(idev->iommufd, accel->bypass_hwpt_id);
+ free_abort_hwpt:
+@@ -463,6 +519,7 @@ free_abort_hwpt:
+ free_viommu:
+ iommufd_backend_free_id(idev->iommufd, viommu->viommu_id);
+ g_free(viommu);
++ accel->viommu = NULL;
+ return false;
+ }
+
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index a8a64802ec..dba6c71de5 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -22,6 +22,7 @@
+ */
+ typedef struct SMMUv3AccelState {
+ IOMMUFDViommu *viommu;
++ IOMMUFDVeventq *veventq;
+ uint32_t bypass_hwpt_id;
+ uint32_t abort_hwpt_id;
+ QLIST_HEAD(, SMMUv3AccelDevice) device_list;
+@@ -50,6 +51,7 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp);
+ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
+ Error **errp);
+ void smmuv3_accel_idr_override(SMMUv3State *s);
++bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp);
+ void smmuv3_accel_reset(SMMUv3State *s);
+ #else
+ static inline void smmuv3_accel_init(SMMUv3State *s)
+@@ -80,6 +82,10 @@ smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
+ static inline void smmuv3_accel_idr_override(SMMUv3State *s)
+ {
+ }
++static inline bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp)
++{
++ return true;
++}
+ static inline void smmuv3_accel_reset(SMMUv3State *s)
+ {
+ }
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 49311f5bbf..1a218f749d 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1605,6 +1605,12 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
+ s->cr0ack = data & ~SMMU_CR0_RESERVED;
+ /* in case the command queue has been enabled */
+ smmuv3_cmdq_consume(s, &local_err);
++ if (local_err) {
++ error_report_err(local_err);
++ local_err = NULL;
++ }
++ /* Allocate vEVENTQ if EVENTQ is enabled and a vIOMMU is available */
++ smmuv3_accel_alloc_veventq(s, &local_err);
+ break;
+ case A_CR1:
+ s->cr[1] = data;
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Change-ats-property-type-to-OnOf.patch b/kvm-hw-arm-smmuv3-accel-Change-ats-property-type-to-OnOf.patch
new file mode 100644
index 0000000..c234126
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Change-ats-property-type-to-OnOf.patch
@@ -0,0 +1,154 @@
+From 90c17ee6172d145d3d79e5ffed4f58d6a4747728 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Tue, 24 Mar 2026 14:02:29 +0000
+Subject: [PATCH 058/111] hw/arm/smmuv3-accel: Change "ats" property type to
+ OnOffAuto
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [58/111] 0ddc3fd7fce821a980fc30482c6316191d49d300 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+Change accel SMMUv3 ATS property from bool to OnOffAuto. The 'auto'
+value is not implemented, as this commit is meant to set the property
+to the correct type and avoid breaking JSON/QMP when the auto mode is
+introduced. A future patch will implement resolution of the 'auto'
+value to match the host SMMUv3 ATS support.
+
+The conversion of the ATS property type to OnOffAuto is an
+incompatible change for JSON/QMP when a bool value is expected for
+"ats", but the "ats" property is new in 11.0 and this patch is
+submitted as a fix to the property type.
+
+Fixes: f7f5013a55a3 ("hw/arm/smmuv3-accel: Add support for ATS")
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Message-id: 20260323182454.1416110-3-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 9f8a8e0f2c6fd48b4f3759a02b5210cba6a978e3)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 4 +++-
+ hw/arm/smmuv3.c | 17 ++++++++++++++---
+ hw/arm/virt-acpi-build.c | 2 +-
+ include/hw/arm/smmuv3.h | 4 +++-
+ 4 files changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 2bb142c47f..f21a6a9997 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -827,7 +827,9 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
+ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
+
+ /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
+- s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
++ if (s->ats == ON_OFF_AUTO_ON) {
++ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
++ }
+
+ /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
+ if (s->oas == SMMU_OAS_48BIT) {
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index d937f4add5..6f8d093f51 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -317,6 +317,11 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
+ smmuv3_accel_idr_override(s);
+ }
+
++bool smmuv3_ats_enabled(SMMUv3State *s)
++{
++ return FIELD_EX32(s->idr[0], IDR0, ATS);
++}
++
+ static void smmuv3_reset(SMMUv3State *s)
+ {
+ s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
+@@ -1966,12 +1971,17 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ }
+ #endif
+
++ if (s->ats == ON_OFF_AUTO_AUTO) {
++ error_setg(errp, "ats auto mode is not supported");
++ return false;
++ }
++
+ if (!s->accel) {
+ if (!s->ril) {
+ error_setg(errp, "ril can only be disabled if accel=on");
+ return false;
+ }
+- if (s->ats) {
++ if (s->ats == ON_OFF_AUTO_ON) {
+ error_setg(errp, "ats can only be enabled if accel=on");
+ return false;
+ }
+@@ -2128,7 +2138,7 @@ static const Property smmuv3_properties[] = {
+ DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
+ /* RIL can be turned off for accel cases */
+ DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
+- DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
++ DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_OFF),
+ DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
+ DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
+ };
+@@ -2160,7 +2170,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "Disable range invalidation support (for accel=on)");
+ object_class_property_set_description(klass, "ats",
+ "Enable/disable ATS support (for accel=on). Please ensure host "
+- "platform has ATS support before enabling this");
++ "platform has ATS support before enabling this. ats=auto is not "
++ "supported.");
+ object_class_property_set_description(klass, "oas",
+ "Specify Output Address Size (for accel=on). Supported values "
+ "are 44 or 48 bits. Defaults to 44 bits");
+diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
+index 160f1d10e5..b923e965da 100644
+--- a/hw/arm/virt-acpi-build.c
++++ b/hw/arm/virt-acpi-build.c
+@@ -408,7 +408,7 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
+
+ bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
+ sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
+- sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
++ sdev.ats = smmuv3_ats_enabled(ARM_SMMUV3(obj));
+ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+ sbdev = SYS_BUS_DEVICE(obj);
+ sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index 26b2fc42fd..ce51a5b9b4 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -70,7 +70,7 @@ struct SMMUv3State {
+ uint64_t msi_gpa;
+ Error *migration_blocker;
+ bool ril;
+- bool ats;
++ OnOffAuto ats;
+ uint8_t oas;
+ uint8_t ssidsize;
+ };
+@@ -91,6 +91,8 @@ struct SMMUv3Class {
+ ResettablePhases parent_phases;
+ };
+
++bool smmuv3_ats_enabled(struct SMMUv3State *s);
++
+ #define TYPE_ARM_SMMUV3 "arm-smmuv3"
+ OBJECT_DECLARE_TYPE(SMMUv3State, SMMUv3Class, ARM_SMMUV3)
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Change-oas-property-type-to-OasM.patch b/kvm-hw-arm-smmuv3-accel-Change-oas-property-type-to-OasM.patch
new file mode 100644
index 0000000..90e823f
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Change-oas-property-type-to-OasM.patch
@@ -0,0 +1,145 @@
+From 9756413223d749c334e823d885e7a88c6781f2c6 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Tue, 24 Mar 2026 14:02:30 +0000
+Subject: [PATCH 063/111] hw/arm/smmuv3-accel: Change "oas" property type to
+ OasMode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [63/111] d86f2fd1e98a85b59690c130b71eb79cedd1686a (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+Change accel SMMUv3 OAS property from uint8_t to OasMode. The
+'auto' value is not implemented, as this commit is meant to
+set the property to the correct type and avoid breaking JSON/QMP
+when the auto mode is introduced. A future patch will implement
+resolution of 'auto' value to match the host SMMUv3 OAS value.
+
+The conversion of the "oas" property type to OnOffAuto is an
+incompatible change for JSON/QMP when a uint8_t value is expected for
+"oas", but this property is new in 11.0 and this patch is
+submitted as a fix to the property type.
+
+Fixes: a015ac990fd3 ("hw/arm/smmuv3-accel: Add property to specify OAS bits")
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Message-id: 20260323182454.1416110-8-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit c2ff1305cc7da7cd4596f4409936f25489ea0397)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 2 +-
+ hw/arm/smmuv3.c | 17 +++++++++--------
+ include/hw/arm/smmuv3-common.h | 2 --
+ include/hw/arm/smmuv3.h | 2 +-
+ 4 files changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index bc6cbfebc2..65c2f44880 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -850,7 +850,7 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
+ }
+
+ /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
+- if (s->oas == SMMU_OAS_48BIT) {
++ if (s->oas == OAS_MODE_48) {
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS_48);
+ }
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 66546dbf9e..7951d85ec9 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1984,6 +1984,11 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "ssidsize auto mode is not supported");
+ return false;
+ }
++ if (s->oas != OAS_MODE_44 && s->oas != OAS_MODE_48) {
++ error_setg(errp, "QEMU SMMUv3 model only implements 44 and 48 bit"
++ "OAS; other OasMode values are not supported");
++ return false;
++ }
+
+ if (!s->accel) {
+ if (s->ril == ON_OFF_AUTO_OFF) {
+@@ -1994,7 +1999,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "ats can only be enabled if accel=on");
+ return false;
+ }
+- if (s->oas != SMMU_OAS_44BIT) {
++ if (s->oas > OAS_MODE_44) {
+ error_setg(errp, "OAS must be 44 bits when accel=off");
+ return false;
+ }
+@@ -2012,11 +2017,6 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ return false;
+ }
+
+- if (s->oas != SMMU_OAS_44BIT && s->oas != SMMU_OAS_48BIT) {
+- error_setg(errp, "OAS can only be set to 44 or 48 bits");
+- return false;
+- }
+-
+ return true;
+ }
+
+@@ -2143,7 +2143,7 @@ static const Property smmuv3_properties[] = {
+ /* RIL can be turned off for accel cases */
+ DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_ON),
+ DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_OFF),
+- DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
++ DEFINE_PROP_OAS_MODE("oas", SMMUv3State, oas, OAS_MODE_44),
+ DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
+ SSID_SIZE_MODE_0),
+ };
+@@ -2180,7 +2180,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "supported.");
+ object_class_property_set_description(klass, "oas",
+ "Specify Output Address Size (for accel=on). Supported values "
+- "are 44 or 48 bits. Defaults to 44 bits");
++ "are 44 or 48 bits. Defaults to 44 bits. oas=auto is not "
++ "supported.");
+ object_class_property_set_description(klass, "ssidsize",
+ "Number of bits used to represent SubstreamIDs (SSIDs). "
+ "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index 75464b2f91..b4557d117f 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -342,8 +342,6 @@ REG32(IDR5, 0x14)
+ FIELD(IDR5, VAX, 10, 2);
+ FIELD(IDR5, STALL_MAX, 16, 16);
+
+-#define SMMU_OAS_44BIT 44
+-#define SMMU_OAS_48BIT 48
+ #define SMMU_IDR5_OAS_44 4
+ #define SMMU_IDR5_OAS_48 5
+
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index ddf472493d..82f18eb090 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -72,7 +72,7 @@ struct SMMUv3State {
+ Error *migration_blocker;
+ OnOffAuto ril;
+ OnOffAuto ats;
+- uint8_t oas;
++ OasMode oas;
+ SsidSizeMode ssidsize;
+ };
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Change-ril-property-type-to-OnOf.patch b/kvm-hw-arm-smmuv3-accel-Change-ril-property-type-to-OnOf.patch
new file mode 100644
index 0000000..4cbf3bb
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Change-ril-property-type-to-OnOf.patch
@@ -0,0 +1,117 @@
+From f48e038a50505883038433a91158ae70f4ddaf49 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Tue, 24 Mar 2026 14:02:29 +0000
+Subject: [PATCH 059/111] hw/arm/smmuv3-accel: Change "ril" property type to
+ OnOffAuto
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [59/111] 91f6258e9a17ae761f0eb9444ce3caa65e9d2e0f (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+Change accel SMMUv3 RIL property from bool to OnOffAuto. The 'auto'
+value is not implemented, as this commit is meant to set the property
+to the correct type and avoid breaking JSON/QMP when the auto mode is
+introduced. A future patch will implement resolution of the 'auto'
+value to match the host SMMUv3 RIL support.
+
+The conversion of the RIL property type to OnOffAuto is an
+incompatible change for JSON/QMP when a bool value is expected for
+"ril", but the "ril" property is new in 11.0 and this patch is
+submitted as a fix to the property type.
+
+Fixes: bd715ff5bda9 ("hw/arm/smmuv3-accel: Add a property to specify RIL support")
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Message-id: 20260323182454.1416110-4-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 1a76cc39333c7870ee34075c2295a28e53d1b1ba)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 6 ++++--
+ hw/arm/smmuv3.c | 11 ++++++++---
+ include/hw/arm/smmuv3.h | 2 +-
+ 3 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index f21a6a9997..c31b64295e 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -823,8 +823,10 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
+ return;
+ }
+
+- /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
+- s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
++ /* Only override RIL if user explicitly set OFF */
++ if (s->ril == ON_OFF_AUTO_OFF) {
++ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 0);
++ }
+
+ /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
+ if (s->ats == ON_OFF_AUTO_ON) {
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 6f8d093f51..a7e606c966 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1975,9 +1975,13 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "ats auto mode is not supported");
+ return false;
+ }
++ if (s->ril == ON_OFF_AUTO_AUTO) {
++ error_setg(errp, "ril auto mode is not supported");
++ return false;
++ }
+
+ if (!s->accel) {
+- if (!s->ril) {
++ if (s->ril == ON_OFF_AUTO_OFF) {
+ error_setg(errp, "ril can only be disabled if accel=on");
+ return false;
+ }
+@@ -2137,7 +2141,7 @@ static const Property smmuv3_properties[] = {
+ /* GPA of MSI doorbell, for SMMUv3 accel use. */
+ DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
+ /* RIL can be turned off for accel cases */
+- DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
++ DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_ON),
+ DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_OFF),
+ DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
+ DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
+@@ -2167,7 +2171,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
+ "configured in nested mode for vfio-pci dev assignment");
+ object_class_property_set_description(klass, "ril",
+- "Disable range invalidation support (for accel=on)");
++ "Disable range invalidation support (for accel=on). ril=auto "
++ "is not supported.");
+ object_class_property_set_description(klass, "ats",
+ "Enable/disable ATS support (for accel=on). Please ensure host "
+ "platform has ATS support before enabling this. ats=auto is not "
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index ce51a5b9b4..c35e599bbc 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -69,7 +69,7 @@ struct SMMUv3State {
+ struct SMMUv3AccelState *s_accel;
+ uint64_t msi_gpa;
+ Error *migration_blocker;
+- bool ril;
++ OnOffAuto ril;
+ OnOffAuto ats;
+ uint8_t oas;
+ uint8_t ssidsize;
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Change-ssidsize-property-type-to.patch b/kvm-hw-arm-smmuv3-accel-Change-ssidsize-property-type-to.patch
new file mode 100644
index 0000000..8d960a8
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Change-ssidsize-property-type-to.patch
@@ -0,0 +1,206 @@
+From 034bb0700695cd0f3dac66a04549cf149b1bb923 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Tue, 24 Mar 2026 14:02:29 +0000
+Subject: [PATCH 061/111] hw/arm/smmuv3-accel: Change "ssidsize" property type
+ to SsidSizeMode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [61/111] ba4a1f1758a7a13d36cac6881fa52d97a5fdef09 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+Conflicts: contextual conflict in hw/arm/smmuv3.c because we keep on
+using headers in hw directory and not in hw/core
+
+Change accel SMMUv3 SSIDSIZE property from uint8_t to SsidSizeMode.
+The 'auto' value is not implemented, as this commit is meant to set the
+property to the correct type and avoid breaking JSON/QMP when the auto
+mode is introduced. A future patch will implement resolution of 'auto'
+value to match the host SMMUv3 SSIDSIZE value.
+
+The conversion of the "ssidsize" property type to OnOffAuto is an
+incompatible change for JSON/QMP when a uint8_t value is expected for
+"ssidsize", but this property is new in 11.0 and this patch is
+submitted as a fix to the property type.
+
+Fixes: b8c6f8a69d27 ("hw/arm/smmuv3-accel: Make SubstreamID support configurable")
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Message-id: 20260323182454.1416110-6-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit ffded86bdda6171fea1771199f3f0c9e0601029f)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 23 +++++++++++++++++++++--
+ hw/arm/smmuv3.c | 19 ++++++++++---------
+ include/hw/arm/smmuv3-common.h | 1 -
+ include/hw/arm/smmuv3.h | 3 ++-
+ 4 files changed, 33 insertions(+), 13 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index c31b64295e..bc6cbfebc2 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -802,7 +802,7 @@ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
+ SMMUState *bs = opaque;
+ SMMUv3State *s = ARM_SMMUV3(bs);
+
+- if (s->ssidsize) {
++ if (s->ssidsize > SSID_SIZE_MODE_0) {
+ flags |= VIOMMU_FLAG_PASID_SUPPORTED;
+ }
+ return flags;
+@@ -817,6 +817,22 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
+ .get_msi_direct_gpa = smmuv3_accel_get_msi_gpa,
+ };
+
++/*
++ * This returns the value of a SsidSizeMode value offset by 1 to
++ * account for the enum values offset by 1 from actual values.
++ *
++ * SSID_SIZE_MODE_0 = 1, SSID_SIZE_MODE_1 = 2, etc. so return 0
++ * if SSID_SIZE_MODE_0 is passed as input, return 1 if
++ * SSID_SIZE_MODE_1 is passed as input, etc.
++ */
++static uint8_t ssidsize_mode_to_value(SsidSizeMode mode)
++{
++ if (mode == SSID_SIZE_MODE_AUTO) {
++ return 0;
++ }
++ return mode - 1;
++}
++
+ void smmuv3_accel_idr_override(SMMUv3State *s)
+ {
+ if (!s->accel) {
+@@ -842,7 +858,10 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
+ * By default QEMU SMMUv3 has no SubstreamID support. Update IDR1 if user
+ * has enabled it.
+ */
+- s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, s->ssidsize);
++ if (s->ssidsize > SSID_SIZE_MODE_0) {
++ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
++ ssidsize_mode_to_value(s->ssidsize));
++ }
+ }
+
+ /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index a7e606c966..66546dbf9e 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -20,6 +20,7 @@
+ #include "qemu/bitops.h"
+ #include "hw/irq.h"
+ #include "hw/sysbus.h"
++#include "hw/qdev-properties-system.h"
+ #include "migration/blocker.h"
+ #include "migration/vmstate.h"
+ #include "hw/qdev-properties.h"
+@@ -625,7 +626,7 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
+ }
+
+ /* Multiple context descriptors require SubstreamID support */
+- if (!s->ssidsize && STE_S1CDMAX(ste) != 0) {
++ if (s->ssidsize == SSID_SIZE_MODE_0 && STE_S1CDMAX(ste) != 0) {
+ qemu_log_mask(LOG_UNIMP,
+ "SMMUv3: multiple S1 context descriptors require SubstreamID support. "
+ "Configure ssidsize > 0 (requires accel=on)\n");
+@@ -1979,6 +1980,10 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "ril auto mode is not supported");
+ return false;
+ }
++ if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
++ error_setg(errp, "ssidsize auto mode is not supported");
++ return false;
++ }
+
+ if (!s->accel) {
+ if (s->ril == ON_OFF_AUTO_OFF) {
+@@ -1993,7 +1998,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "OAS must be 44 bits when accel=off");
+ return false;
+ }
+- if (s->ssidsize) {
++ if (s->ssidsize > SSID_SIZE_MODE_0) {
+ error_setg(errp, "ssidsize can only be set if accel=on");
+ return false;
+ }
+@@ -2011,11 +2016,6 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "OAS can only be set to 44 or 48 bits");
+ return false;
+ }
+- if (s->ssidsize > SMMU_SSID_MAX_BITS) {
+- error_setg(errp, "ssidsize must be in the range 0 to %d",
+- SMMU_SSID_MAX_BITS);
+- return false;
+- }
+
+ return true;
+ }
+@@ -2144,7 +2144,8 @@ static const Property smmuv3_properties[] = {
+ DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_ON),
+ DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_OFF),
+ DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
+- DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
++ DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
++ SSID_SIZE_MODE_0),
+ };
+
+ static void smmuv3_instance_init(Object *obj)
+@@ -2185,7 +2186,7 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
+ "Valid range is 0-20, where 0 disables SubstreamID support. "
+ "Defaults to 0. A value greater than 0 is required to enable "
+- "PASID support.");
++ "PASID support. ssidsize=auto is not supported.");
+ }
+
+ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index f1d74d6832..75464b2f91 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -311,7 +311,6 @@ REG32(IDR1, 0x4)
+ FIELD(IDR1, TABLES_PRESET, 30, 1)
+ FIELD(IDR1, ECMDQ, 31, 1)
+
+-#define SMMU_SSID_MAX_BITS 20
+ #define SMMU_IDR1_SIDSIZE 16
+ #define SMMU_CMDQS 19
+ #define SMMU_EVENTQS 19
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index c35e599bbc..ddf472493d 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -21,6 +21,7 @@
+
+ #include "hw/arm/smmu-common.h"
+ #include "qom/object.h"
++#include "qapi/qapi-types-misc-arm.h"
+
+ #define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
+
+@@ -72,7 +73,7 @@ struct SMMUv3State {
+ OnOffAuto ril;
+ OnOffAuto ats;
+ uint8_t oas;
+- uint8_t ssidsize;
++ SsidSizeMode ssidsize;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Check-ATS-compatibility-between-.patch b/kvm-hw-arm-smmuv3-accel-Check-ATS-compatibility-between-.patch
new file mode 100644
index 0000000..768cce9
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Check-ATS-compatibility-between-.patch
@@ -0,0 +1,56 @@
+From 376ff3d65cb420c0629ecead6acefa3c17d127b5 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Tue, 24 Mar 2026 14:02:29 +0000
+Subject: [PATCH 057/111] hw/arm/smmuv3-accel: Check ATS compatibility between
+ host and guest
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [57/111] 63d0ca91b471cb66464226e104162e0fc9d2a19c (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+Compare the host SMMUv3 ATS support bit with the guest SMMUv3 ATS support
+bit in IDR0 and fail the compatibility check if ATS support is opted as
+enabled on the guest SMMUv3 when it is not supported on host SMMUv3.
+
+Fixes: f7f5013a55a3 ("hw/arm/smmuv3-accel: Add support for ATS")
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Message-id: 20260323182454.1416110-2-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit dc86d45232444e75f1b4569fada0a73b5dc209b4)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 17306cd04b..2bb142c47f 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -101,6 +101,12 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
+ smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
+ return false;
+ }
++ /* Check ATS value opted is compatible with Host SMMUv3 */
++ if (FIELD_EX32(info->idr[0], IDR0, ATS) <
++ FIELD_EX32(s->idr[0], IDR0, ATS)) {
++ error_setg(errp, "Host SMMUv3 doesn't support Address Translation Services");
++ return false;
++ }
+
+ /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
+ if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Enforce-viommu-association-when-.patch b/kvm-hw-arm-smmuv3-accel-Enforce-viommu-association-when-.patch
new file mode 100644
index 0000000..a4efc9c
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Enforce-viommu-association-when-.patch
@@ -0,0 +1,98 @@
+From e5129f70e077c23e44e1a37c5f99fc8e9fdc6bdb Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:50 +0100
+Subject: [PATCH 108/111] hw/arm/smmuv3-accel: Enforce viommu association when
+ CMDQV is active
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [108/111] 0f6e9ec6a9a3eecfdb80bd6db4c630cccbdb07fd (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+When CMDQV is active, the first cold-plugged VFIO device establishes
+the viommu to host SMMUv3 association, and the guest's boot-time CMDQV
+configuration (VINTFs, VCMDQs) is built on top of that association.
+
+Hot-unplugging that device would release the viommu and tear down all
+CMDQV state. Hot-plugging another device behind a different host
+SMMUv3+CMDQV would then re-bind the same vSMMUv3 to new host hardware,
+while the guest keeps using its boot-time configuration and ends up
+issuing commands to the wrong host. Block hot-unplug of the
+establishing device to avoid this; retaining the binding across unplug
+is non-trivial and not required by any current use case.
+
+Also abort at machine_done if cmdqv=on is requested but no cold-plugged
+VFIO device was present to initialize it.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-30-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 4435853689e245a8bfec9eb92fd84f3904d60d47)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 18 ++++++++++++++++++
+ hw/arm/smmuv3-accel.h | 1 +
+ 2 files changed, 19 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 9c3bd4413d..80900c2521 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -759,6 +759,18 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
+ return false;
+ }
+
++ /*
++ * CMDQV is active: block hot-unplug of the device that established the
++ * viommu association. Removing it would cause the vIOMMU to host SMMUv3
++ * association be changed via device hot-plug.
++ */
++ if (s->s_accel->cmdqv_ops) {
++ PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
++ error_setg(&accel_dev->unplug_blocker,
++ "CMDQV is active: removing the device that established the "
++ "viommu association would break the guest CMDQV");
++ qdev_add_unplug_blocker(DEVICE(pdev), accel_dev->unplug_blocker);
++ }
+ done:
+ accel_dev->hiodi = hiodi;
+ accel_dev->s_accel = s->s_accel;
+@@ -1082,6 +1094,12 @@ static void smmuv3_accel_machine_done(Notifier *notifier, void *data)
+ "at least one cold-plugged VFIO device");
+ exit(1);
+ }
++
++ if (s->cmdqv == ON_OFF_AUTO_ON && !accel->cmdqv) {
++ error_report("arm-smmuv3 cmdqv=on requires at least one cold-plugged "
++ "VFIO device");
++ exit(1);
++ }
+ }
+
+ bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index 5fc85fb89d..dd755c394d 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -84,6 +84,7 @@ typedef struct SMMUv3AccelDevice {
+ IOMMUFDVdev *vdev;
+ QLIST_ENTRY(SMMUv3AccelDevice) next;
+ SMMUv3AccelState *s_accel;
++ Error *unplug_blocker; /* set when CMDQV is active to block hot-unplug */
+ } SMMUv3AccelDevice;
+
+ bool smmuv3_accel_init(SMMUv3State *s, Error **errp);
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Get-host-SMMUv3-hw-info-and-vali.patch b/kvm-hw-arm-smmuv3-accel-Get-host-SMMUv3-hw-info-and-vali.patch
new file mode 100644
index 0000000..ee1a906
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Get-host-SMMUv3-hw-info-and-vali.patch
@@ -0,0 +1,173 @@
+From 074db18ed80a05411b4156620537b1255ecab3a7 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 029/111] hw/arm/smmuv3-accel: Get host SMMUv3 hw info and
+ validate
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [29/111] 154dbf7600fabd9f8b373ffd5443cc9091e1bb95 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Just before the device gets attached to the SMMUv3, make sure QEMU SMMUv3
+features are compatible with the host SMMUv3.
+
+Not all fields in the host SMMUv3 IDR registers are meaningful for userspace.
+Only the following fields can be used:
+
+ - IDR0: ST_LEVEL, TERM_MODEL, STALL_MODEL, TTENDIAN, CD2L, ASID16, TTF
+ - IDR1: SIDSIZE, SSIDSIZE
+ - IDR3: BBML, RIL
+ - IDR5: VAX, GRAN64K, GRAN16K, GRAN4K
+
+For now, the check is to make sure the features are in sync to enable
+basic accelerated SMMUv3 support. AIDR is not checked, as hardware
+implementations often provide a mix of architecture features regardless
+of the revision reported in AIDR.
+
+Note that SSIDSIZE check will be added later when support for PASID is
+introduced.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-22-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit ad32238ad26bcaa6293742dd712782425253b6fe)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 101 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 101 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 89dc6f991c..33011962e3 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -27,6 +27,99 @@
+ static MemoryRegion root, sysmem;
+ static AddressSpace *shared_as_sysmem;
+
++static bool
++smmuv3_accel_check_hw_compatible(SMMUv3State *s,
++ struct iommu_hw_info_arm_smmuv3 *info,
++ Error **errp)
++{
++ /* QEMU SMMUv3 supports both linear and 2-level stream tables */
++ if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=
++ FIELD_EX32(s->idr[0], IDR0, STLEVEL)) {
++ error_setg(errp, "Host SMMUv3 Stream Table format mismatch "
++ "(host STLEVEL=%u, QEMU STLEVEL=%u)",
++ FIELD_EX32(info->idr[0], IDR0, STLEVEL),
++ FIELD_EX32(s->idr[0], IDR0, STLEVEL));
++ return false;
++ }
++
++ /* QEMU SMMUv3 supports only little-endian translation table walks */
++ if (FIELD_EX32(info->idr[0], IDR0, TTENDIAN) >
++ FIELD_EX32(s->idr[0], IDR0, TTENDIAN)) {
++ error_setg(errp, "Host SMMUv3 doesn't support Little-endian "
++ "translation table");
++ return false;
++ }
++
++ /* QEMU SMMUv3 supports only AArch64 translation table format */
++ if (FIELD_EX32(info->idr[0], IDR0, TTF) <
++ FIELD_EX32(s->idr[0], IDR0, TTF)) {
++ error_setg(errp, "Host SMMUv3 doesn't support AArch64 translation "
++ "table format");
++ return false;
++ }
++
++ /* QEMU SMMUv3 supports SIDSIZE 16 */
++ if (FIELD_EX32(info->idr[1], IDR1, SIDSIZE) <
++ FIELD_EX32(s->idr[1], IDR1, SIDSIZE)) {
++ error_setg(errp, "Host SMMUv3 SIDSIZE not compatible "
++ "(host=%u, QEMU=%u)",
++ FIELD_EX32(info->idr[1], IDR1, SIDSIZE),
++ FIELD_EX32(s->idr[1], IDR1, SIDSIZE));
++ return false;
++ }
++
++ /* QEMU SMMUv3 supports Range Invalidation by default */
++ if (FIELD_EX32(info->idr[3], IDR3, RIL) !=
++ FIELD_EX32(s->idr[3], IDR3, RIL)) {
++ error_setg(errp, "Host SMMUv3 doesn't support Range Invalidation");
++ return false;
++ }
++
++ /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
++ if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
++ FIELD_EX32(s->idr[5], IDR5, GRAN4K)) {
++ error_setg(errp, "Host SMMUv3 doesn't support 4K translation granule");
++ return false;
++ }
++ if (FIELD_EX32(info->idr[5], IDR5, GRAN16K) !=
++ FIELD_EX32(s->idr[5], IDR5, GRAN16K)) {
++ error_setg(errp, "Host SMMUv3 doesn't support 16K translation granule");
++ return false;
++ }
++ if (FIELD_EX32(info->idr[5], IDR5, GRAN64K) !=
++ FIELD_EX32(s->idr[5], IDR5, GRAN64K)) {
++ error_setg(errp, "Host SMMUv3 doesn't support 64K translation granule");
++ return false;
++ }
++
++ return true;
++}
++
++static bool
++smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
++ Error **errp)
++{
++ struct iommu_hw_info_arm_smmuv3 info;
++ uint32_t data_type;
++ uint64_t caps;
++
++ if (!iommufd_backend_get_device_info(idev->iommufd, idev->devid, &data_type,
++ &info, sizeof(info), &caps, errp)) {
++ return false;
++ }
++
++ if (data_type != IOMMU_HW_INFO_TYPE_ARM_SMMUV3) {
++ error_setg(errp, "Wrong data type (%d) for Host SMMUv3 device info",
++ data_type);
++ return false;
++ }
++
++ if (!smmuv3_accel_check_hw_compatible(s, &info, errp)) {
++ return false;
++ }
++ return true;
++}
++
+ static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus,
+ PCIBus *bus, int devfn)
+ {
+@@ -353,6 +446,14 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
+ return true;
+ }
+
++ /*
++ * Check the host SMMUv3 associated with the dev is compatible with the
++ * QEMU SMMUv3 accel.
++ */
++ if (!smmuv3_accel_hw_compatible(s, idev, errp)) {
++ return false;
++ }
++
+ if (s->s_accel->viommu) {
+ goto done;
+ }
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ats.patch b/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ats.patch
new file mode 100644
index 0000000..a4f84be
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ats.patch
@@ -0,0 +1,93 @@
+From ac95c83d843a5e7d06abbc173fb1b5ebeb938540 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Mon, 8 Jun 2026 10:48:55 -0700
+Subject: [PATCH 069/111] hw/arm/smmuv3-accel: Implement "auto" value for "ats"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [69/111] 101e6549edfef8b539367d77ad887875abdd1b49 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+Allow accelerated SMMUv3 Address Translation Services support property
+to be derived from host IOMMU capabilities. Derive host values using
+IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260608174900.2227340-5-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 7e88c1a9d0f99f42a652e0af856b903e038b38cb)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 9 +++++++++
+ hw/arm/smmuv3.c | 11 ++++-------
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index e625f145c4..e03b0883af 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -53,6 +53,11 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s,
+ return;
+ }
+
++ if (s->ats == ON_OFF_AUTO_AUTO) {
++ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
++ FIELD_EX32(info->idr[0], IDR0, ATS));
++ }
++
+ accel->auto_finalised = true;
+ }
+
+@@ -960,6 +965,10 @@ bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+ bs->iommu_ops = &smmuv3_accel_ops;
+ smmuv3_accel_as_init(s);
+
++ if (s->ats == ON_OFF_AUTO_AUTO) {
++ s->s_accel->auto_mode = true;
++ }
++
+ if (s->s_accel->auto_mode) {
+ s->machine_done.notify = smmuv3_accel_machine_done;
+ qemu_add_machine_init_done_notifier(&s->machine_done);
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index f76a527182..e2071938c0 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1965,10 +1965,6 @@ static void smmu_reset_exit(Object *obj, ResetType type)
+
+ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ {
+- if (s->ats == ON_OFF_AUTO_AUTO) {
+- error_setg(errp, "ats auto mode is not supported");
+- return false;
+- }
+ if (s->ril == ON_OFF_AUTO_AUTO) {
+ error_setg(errp, "ril auto mode is not supported");
+ return false;
+@@ -2172,9 +2168,10 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "Disable range invalidation support (for accel=on). ril=auto "
+ "is not supported.");
+ object_class_property_set_description(klass, "ats",
+- "Enable/disable ATS support (for accel=on). Please ensure host "
+- "platform has ATS support before enabling this. ats=auto is not "
+- "supported.");
++ "Enable/disable ATS support (for accel=on). "
++ "Valid values are on, off, and auto. Defaults to off. "
++ "Please ensure host platform supports ATS before setting it "
++ "to on.");
+ object_class_property_set_description(klass, "oas",
+ "Specify Output Address Size (for accel=on). Supported values "
+ "are 44 or 48 bits. Defaults to 44 bits. oas=auto is not "
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-oas.patch b/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-oas.patch
new file mode 100644
index 0000000..c5d97ea
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-oas.patch
@@ -0,0 +1,110 @@
+From ace86d844117aa4f39ad165b61fc92090c5201f3 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Mon, 8 Jun 2026 10:48:58 -0700
+Subject: [PATCH 072/111] hw/arm/smmuv3-accel: Implement "auto" value for "oas"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [72/111] 20acbc3ce50f8a38e8009254c891b1d80d7a3c8a (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+Allow accelerated SMMUv3 OAS property to be derived from host IOMMU
+capabilities. Derive host values using IOMMU_GET_HW_INFO, retrieving
+OAS from IDR5.
+
+This keeps the OAS value advertised by the virtual SMMU compatible with
+the capabilities of the host SMMUv3, so that the intermediate physical
+addresses (IPA) consumed by host SMMU for stage-2 translation do not
+exceed the host's max supported IPA size.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260608174900.2227340-8-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 86ec6639b18cafab2e23cd10c50f4b27597c4a9b)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 8 +++++++-
+ hw/arm/smmuv3.c | 17 ++++++++++-------
+ 2 files changed, 17 insertions(+), 8 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 182676157d..0b01848292 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -68,6 +68,11 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s,
+ FIELD_EX32(info->idr[1], IDR1, SSIDSIZE));
+ }
+
++ if (s->oas == OAS_MODE_AUTO) {
++ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS,
++ FIELD_EX32(info->idr[5], IDR5, OAS));
++ }
++
+ accel->auto_finalised = true;
+ }
+
+@@ -984,7 +989,8 @@ bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+
+ if (s->ats == ON_OFF_AUTO_AUTO ||
+ s->ril == ON_OFF_AUTO_AUTO ||
+- s->ssidsize == SSID_SIZE_MODE_AUTO) {
++ s->ssidsize == SSID_SIZE_MODE_AUTO ||
++ s->oas == OAS_MODE_AUTO) {
+ s->s_accel->auto_mode = true;
+ }
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index bc734fb477..89d34c9923 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1968,9 +1968,11 @@ static void smmu_reset_exit(Object *obj, ResetType type)
+
+ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ {
+- if (s->oas != OAS_MODE_44 && s->oas != OAS_MODE_48) {
+- error_setg(errp, "QEMU SMMUv3 model only implements 44 and 48 bit"
+- "OAS; other OasMode values are not supported");
++ if (s->oas != OAS_MODE_44 && s->oas != OAS_MODE_48 &&
++ s->oas != OAS_MODE_AUTO) {
++ error_setg(errp, "QEMU SMMUv3 model only implements auto, "
++ "44 bit, or 48 bit OAS. Other OasMode values are "
++ "not supported.");
+ return false;
+ }
+
+@@ -1984,7 +1986,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ return false;
+ }
+ if (s->oas > OAS_MODE_44) {
+- error_setg(errp, "OAS must be 44 bits when accel=off");
++ error_setg(errp, "oas must be 44 bits when accel=off");
+ return false;
+ }
+ if (s->ssidsize > SSID_SIZE_MODE_0) {
+@@ -2171,9 +2173,10 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "Please ensure host platform supports ATS before setting it "
+ "to on.");
+ object_class_property_set_description(klass, "oas",
+- "Specify Output Address Size (for accel=on). Supported values "
+- "are 44 or 48 bits. Defaults to 44 bits. oas=auto is not "
+- "supported.");
++ "Set Output Address Size in bits (for accel=on). "
++ "Valid values are 44, 48, and auto. Defaults to 44 bits."
++ "Please ensure the value does not exceed the maximum "
++ "Output Address Size supported by the host platform.");
+ object_class_property_set_description(klass, "ssidsize",
+ "Set number of bits used to represent SubstreamIDs (SSIDs). "
+ "Valid values are 0-20 and auto. Defaults to 0. "
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ril.patch b/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ril.patch
new file mode 100644
index 0000000..3ce88b8
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ril.patch
@@ -0,0 +1,91 @@
+From db9b51eba6ce584776873db265b3c97e2e5fd406 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Mon, 8 Jun 2026 10:48:56 -0700
+Subject: [PATCH 070/111] hw/arm/smmuv3-accel: Implement "auto" value for "ril"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [70/111] 8e22d10a8838c024247af280928fd7620ecc8453 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+Allow accelerated SMMUv3 Range Invalidation support property to be
+derived from host IOMMU capabilities. Derive host values using
+IOMMU_GET_HW_INFO, retrieving RIL capability from IDR3.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260608174900.2227340-6-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 8e0a2aa777f69def65aa382fc66dabf9cf53b8f0)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 8 +++++++-
+ hw/arm/smmuv3.c | 10 ++++------
+ 2 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index e03b0883af..0243e292d8 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -58,6 +58,11 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s,
+ FIELD_EX32(info->idr[0], IDR0, ATS));
+ }
+
++ if (s->ril == ON_OFF_AUTO_AUTO) {
++ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL,
++ FIELD_EX32(info->idr[3], IDR3, RIL));
++ }
++
+ accel->auto_finalised = true;
+ }
+
+@@ -965,7 +970,8 @@ bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+ bs->iommu_ops = &smmuv3_accel_ops;
+ smmuv3_accel_as_init(s);
+
+- if (s->ats == ON_OFF_AUTO_AUTO) {
++ if (s->ats == ON_OFF_AUTO_AUTO ||
++ s->ril == ON_OFF_AUTO_AUTO) {
+ s->s_accel->auto_mode = true;
+ }
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index e2071938c0..78ed2a9df1 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1965,10 +1965,6 @@ static void smmu_reset_exit(Object *obj, ResetType type)
+
+ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ {
+- if (s->ril == ON_OFF_AUTO_AUTO) {
+- error_setg(errp, "ril auto mode is not supported");
+- return false;
+- }
+ if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
+ error_setg(errp, "ssidsize auto mode is not supported");
+ return false;
+@@ -2165,8 +2161,10 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "ensure the host SMMUv3 supports nested translation before "
+ "enabling.");
+ object_class_property_set_description(klass, "ril",
+- "Disable range invalidation support (for accel=on). ril=auto "
+- "is not supported.");
++ "Enable/disable range invalidation support (for accel=on). "
++ "Valid values are on, off, and auto. Defaults to on. "
++ "Any attempt to turn it 'on' while the host does not support "
++ "it would fail.");
+ object_class_property_set_description(klass, "ats",
+ "Enable/disable ATS support (for accel=on). "
+ "Valid values are on, off, and auto. Defaults to off. "
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ssidsiz.patch b/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ssidsiz.patch
new file mode 100644
index 0000000..dcc385e
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ssidsiz.patch
@@ -0,0 +1,145 @@
+From 753ace52c01dd9da1175e2e18d060dc945cd80af Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Mon, 8 Jun 2026 10:48:57 -0700
+Subject: [PATCH 071/111] hw/arm/smmuv3-accel: Implement "auto" value for
+ "ssidsize"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [71/111] f4c6e14d54eb749fbcc601aaeb2bbac539859690 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+Allow accelerated SMMUv3 SSID size property to be derived from host
+IOMMU capabilities. Derive host values using IOMMU_GET_HW_INFO,
+retrieving SSID size from IDR1. When the auto SSID size is resolved
+to a non-zero value, PASID capability is advertised to the vIOMMU
+and accelerated use cases such as Shared Virtual Addressing (SVA)
+are supported.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260608174900.2227340-7-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 13b941aaff48060ce0b5dca5a2b345a6dc25cb1c)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 17 +++++++++++++++--
+ hw/arm/smmuv3.c | 22 ++++++++++++----------
+ 2 files changed, 27 insertions(+), 12 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 0243e292d8..182676157d 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -63,6 +63,11 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s,
+ FIELD_EX32(info->idr[3], IDR3, RIL));
+ }
+
++ if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
++ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
++ FIELD_EX32(info->idr[1], IDR1, SSIDSIZE));
++ }
++
+ accel->auto_finalised = true;
+ }
+
+@@ -823,6 +828,13 @@ static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque,
+ }
+ }
+
++static inline bool smmuv3_pasid_supported(SMMUv3State *s)
++{
++ return s->ssidsize > SSID_SIZE_MODE_0 ||
++ (s->ssidsize == SSID_SIZE_MODE_AUTO &&
++ FIELD_EX32(s->idr[1], IDR1, SSIDSIZE));
++}
++
+ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
+ {
+ /*
+@@ -835,7 +847,7 @@ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
+ SMMUState *bs = opaque;
+ SMMUv3State *s = ARM_SMMUV3(bs);
+
+- if (s->ssidsize > SSID_SIZE_MODE_0) {
++ if (smmuv3_pasid_supported(s)) {
+ flags |= VIOMMU_FLAG_PASID_SUPPORTED;
+ }
+ return flags;
+@@ -971,7 +983,8 @@ bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
+ smmuv3_accel_as_init(s);
+
+ if (s->ats == ON_OFF_AUTO_AUTO ||
+- s->ril == ON_OFF_AUTO_AUTO) {
++ s->ril == ON_OFF_AUTO_AUTO ||
++ s->ssidsize == SSID_SIZE_MODE_AUTO) {
+ s->s_accel->auto_mode = true;
+ }
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 78ed2a9df1..bc734fb477 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -626,7 +626,10 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
+ }
+
+ /* Multiple context descriptors require SubstreamID support */
+- if (s->ssidsize == SSID_SIZE_MODE_0 && STE_S1CDMAX(ste) != 0) {
++ if ((s->ssidsize == SSID_SIZE_MODE_0 ||
++ (s->ssidsize == SSID_SIZE_MODE_AUTO &&
++ !FIELD_EX32(s->idr[1], IDR1, SSIDSIZE))) &&
++ STE_S1CDMAX(ste) != 0) {
+ qemu_log_mask(LOG_UNIMP,
+ "SMMUv3: multiple S1 context descriptors require SubstreamID support. "
+ "Configure ssidsize > 0 (requires accel=on)\n");
+@@ -1965,10 +1968,6 @@ static void smmu_reset_exit(Object *obj, ResetType type)
+
+ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ {
+- if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
+- error_setg(errp, "ssidsize auto mode is not supported");
+- return false;
+- }
+ if (s->oas != OAS_MODE_44 && s->oas != OAS_MODE_48) {
+ error_setg(errp, "QEMU SMMUv3 model only implements 44 and 48 bit"
+ "OAS; other OasMode values are not supported");
+@@ -1989,7 +1988,8 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ return false;
+ }
+ if (s->ssidsize > SSID_SIZE_MODE_0) {
+- error_setg(errp, "ssidsize can only be set if accel=on");
++ error_setg(errp, "ssidsize can only be greater than 0 "
++ "bits if accel=on");
+ return false;
+ }
+ return true;
+@@ -2175,11 +2175,13 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ "are 44 or 48 bits. Defaults to 44 bits. oas=auto is not "
+ "supported.");
+ object_class_property_set_description(klass, "ssidsize",
+- "Number of bits used to represent SubstreamIDs (SSIDs). "
++ "Set number of bits used to represent SubstreamIDs (SSIDs). "
++ "Valid values are 0-20 and auto. Defaults to 0. "
+ "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
+- "Valid range is 0-20, where 0 disables SubstreamID support. "
+- "Defaults to 0. A value greater than 0 is required to enable "
+- "PASID support. ssidsize=auto is not supported.");
++ "A value of 0 disables SubstreamID support. A value greater "
++ "than 0 is required to enable PASID support."
++ "Please ensure the value does not exceed the maximum "
++ "SubstreamID size supported by the host platform.");
+ }
+
+ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Implement-get_msi_direct_gpa-cal.patch b/kvm-hw-arm-smmuv3-accel-Implement-get_msi_direct_gpa-cal.patch
new file mode 100644
index 0000000..381d516
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Implement-get_msi_direct_gpa-cal.patch
@@ -0,0 +1,104 @@
+From f826cb97e9de8c7bc8fae7b81b380d0e7726fb84 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 025/111] hw/arm/smmuv3-accel: Implement get_msi_direct_gpa
+ callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [25/111] afc6a8d07e2db927aed8443d173b66fc3f8f6459 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Accelerated SMMUv3 instances rely on the physical SMMUv3 for nested
+translation (guest Stage-1, host Stage-2). In this mode, the guest Stage-1
+tables are programmed directly into hardware, and QEMU must not attempt to
+walk them for translation, as doing so is not reliably safe. For vfio-pci
+endpoints behind such a vSMMU, the only translation QEMU needs to perform
+is for the MSI doorbell used during KVM MSI setup.
+
+Implement the callback so that kvm_arch_fixup_msi_route() can retrieve the
+MSI doorbell GPA directly, instead of attempting a software walk of the
+guest translation tables.
+
+Also introduce an SMMUv3 device property to carry the MSI doorbell GPA.
+This property will be set by the virt machine in a subsequent patch.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-18-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 3558c85392a46db064eb983633de998a25ea9705)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 10 ++++++++++
+ hw/arm/smmuv3.c | 2 ++
+ include/hw/arm/smmuv3.h | 1 +
+ 3 files changed, 13 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index c125974d12..c6ee123cdf 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -393,6 +393,15 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
+ }
+ }
+
++static uint64_t smmuv3_accel_get_msi_gpa(PCIBus *bus, void *opaque, int devfn)
++{
++ SMMUState *bs = opaque;
++ SMMUv3State *s = ARM_SMMUV3(bs);
++
++ g_assert(s->msi_gpa);
++ return s->msi_gpa;
++}
++
+ /*
+ * Only allow PCIe bridges, pxb-pcie roots, and GPEX roots so vfio-pci
+ * endpoints can sit downstream. Accelerated SMMUv3 requires a vfio-pci
+@@ -497,6 +506,7 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
+ .get_viommu_flags = smmuv3_accel_get_viommu_flags,
+ .set_iommu_device = smmuv3_accel_set_iommu_device,
+ .unset_iommu_device = smmuv3_accel_unset_iommu_device,
++ .get_msi_direct_gpa = smmuv3_accel_get_msi_gpa,
+ };
+
+ /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index 42c60b1ec8..f02e3ee46c 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1998,6 +1998,8 @@ static const Property smmuv3_properties[] = {
+ * Defaults to stage 1
+ */
+ DEFINE_PROP_STRING("stage", SMMUv3State, stage),
++ /* GPA of MSI doorbell, for SMMUv3 accel use. */
++ DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
+ };
+
+ static void smmuv3_instance_init(Object *obj)
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index e54ece2d38..5616a8a2be 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -67,6 +67,7 @@ struct SMMUv3State {
+ /* SMMU has HW accelerator support for nested S1 + s2 */
+ bool accel;
+ struct SMMUv3AccelState *s_accel;
++ uint64_t msi_gpa;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Initialize-shared-system-address.patch b/kvm-hw-arm-smmuv3-accel-Initialize-shared-system-address.patch
new file mode 100644
index 0000000..1b0d599
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Initialize-shared-system-address.patch
@@ -0,0 +1,93 @@
+From e9fa710039a71015b0dfcff975e5ee16fb1f310f Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 008/111] hw/arm/smmuv3-accel: Initialize shared system address
+ space
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [8/111] 696fdb31b39d27f329d68bc0d8acd4686ef7f596 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+To support accelerated SMMUv3 instances, introduce a shared system-wide
+AddressSpace (shared_as_sysmem) that aliases the global system memory.
+This shared AddressSpace will be used in a subsequent patch for all
+vfio-pci devices behind all accelerated SMMUv3 instances within a VM.
+
+Sharing a single system AddressSpace ensures that all devices behind
+accelerated SMMUv3s use the same system address space pointer. This
+allows VFIO/iommufd to reuse a single IOAS ID in iommufd_cdev_attach(),
+enabling the Stage-2 page tables to be shared within the VM rather than
+duplicated for each SMMUv3 instance.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-7-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 7d7931257d6f748d8f0cd595952425c19670f0b5)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 99ef0db8c4..b2eded743e 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -11,6 +11,14 @@
+ #include "hw/arm/smmuv3.h"
+ #include "smmuv3-accel.h"
+
++/*
++ * The root region aliases the global system memory, and shared_as_sysmem
++ * provides a shared Address Space referencing it. This Address Space is used
++ * by all vfio-pci devices behind all accelerated SMMUv3 instances within a VM.
++ */
++static MemoryRegion root, sysmem;
++static AddressSpace *shared_as_sysmem;
++
+ static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus,
+ PCIBus *bus, int devfn)
+ {
+@@ -51,9 +59,27 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
+ .get_address_space = smmuv3_accel_find_add_as,
+ };
+
++static void smmuv3_accel_as_init(SMMUv3State *s)
++{
++
++ if (shared_as_sysmem) {
++ return;
++ }
++
++ memory_region_init(&root, OBJECT(s), "root", UINT64_MAX);
++ memory_region_init_alias(&sysmem, OBJECT(s), "smmuv3-accel-sysmem",
++ get_system_memory(), 0,
++ memory_region_size(get_system_memory()));
++ memory_region_add_subregion(&root, 0, &sysmem);
++
++ shared_as_sysmem = g_new0(AddressSpace, 1);
++ address_space_init(shared_as_sysmem, &root, "smmuv3-accel-as-sysmem");
++}
++
+ void smmuv3_accel_init(SMMUv3State *s)
+ {
+ SMMUState *bs = ARM_SMMU(s);
+
+ bs->iommu_ops = &smmuv3_accel_ops;
++ smmuv3_accel_as_init(s);
+ }
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Install-SMMUv3-GBPA-based-hwpt.patch b/kvm-hw-arm-smmuv3-accel-Install-SMMUv3-GBPA-based-hwpt.patch
new file mode 100644
index 0000000..874372a
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Install-SMMUv3-GBPA-based-hwpt.patch
@@ -0,0 +1,134 @@
+From b95cb9924294da296caddfcd37ad15ea45f0d86c Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 023/111] hw/arm/smmuv3-accel: Install SMMUv3 GBPA based hwpt
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [23/111] 6efcc61bf304eb1ab554334c20a963121b33108c (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+On guest reboot or on GBPA update, attach a nested HWPT based on the
+GPBA.ABORT bit which either aborts all incoming transactions or bypasses
+them.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-16-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit b6b867b9c16d479af0ba95ac71411a0ff788220a)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 36 ++++++++++++++++++++++++++++++++++++
+ hw/arm/smmuv3-accel.h | 9 +++++++++
+ hw/arm/smmuv3.c | 2 ++
+ 3 files changed, 47 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 877b7e0e17..c125974d12 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -499,6 +499,42 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
+ .unset_iommu_device = smmuv3_accel_unset_iommu_device,
+ };
+
++/* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
++bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
++{
++ SMMUv3AccelState *accel = s->s_accel;
++ SMMUv3AccelDevice *accel_dev;
++ Error *local_err = NULL;
++ bool all_ok = true;
++ uint32_t hwpt_id;
++
++ if (!accel || !accel->viommu) {
++ return true;
++ }
++
++ hwpt_id = smmuv3_accel_gbpa_hwpt(s, accel);
++ QLIST_FOREACH(accel_dev, &accel->device_list, next) {
++ if (!host_iommu_device_iommufd_attach_hwpt(accel_dev->idev, hwpt_id,
++ &local_err)) {
++ error_append_hint(&local_err, "Failed to attach GBPA hwpt %u for "
++ "idev devid %u", hwpt_id, accel_dev->idev->devid);
++ error_report_err(local_err);
++ local_err = NULL;
++ all_ok = false;
++ }
++ }
++ if (!all_ok) {
++ error_setg(errp, "Failed to attach all GBPA based HWPTs properly");
++ }
++ return all_ok;
++}
++
++void smmuv3_accel_reset(SMMUv3State *s)
++{
++ /* Attach a HWPT based on GBPA reset value */
++ smmuv3_accel_attach_gbpa_hwpt(s, NULL);
++}
++
+ static void smmuv3_accel_as_init(SMMUv3State *s)
+ {
+
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index 4e20b646dc..c7ed4dce3a 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -46,6 +46,8 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+ Error **errp);
+ bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
+ Error **errp);
++bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp);
++void smmuv3_accel_reset(SMMUv3State *s);
+ #else
+ static inline void smmuv3_accel_init(SMMUv3State *s)
+ {
+@@ -62,6 +64,13 @@ smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range,
+ {
+ return true;
+ }
++static inline bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
++{
++ return true;
++}
++static inline void smmuv3_accel_reset(SMMUv3State *s)
++{
++}
+ #endif
+
+ #endif /* HW_ARM_SMMUV3_ACCEL_H */
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index bfb41b8866..42c60b1ec8 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1600,6 +1600,7 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
+ if (data & R_GBPA_UPDATE_MASK) {
+ /* Ignore update bit as write is synchronous. */
+ s->gbpa = data & ~R_GBPA_UPDATE_MASK;
++ smmuv3_accel_attach_gbpa_hwpt(s, &local_err);
+ }
+ break;
+ case A_STRTAB_BASE: /* 64b */
+@@ -1887,6 +1888,7 @@ static void smmu_reset_exit(Object *obj, ResetType type)
+ }
+
+ smmuv3_init_regs(s);
++ smmuv3_accel_reset(s);
+ }
+
+ static void smmu_realize(DeviceState *d, Error **errp)
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Introduce-CMDQV-ops-interface.patch b/kvm-hw-arm-smmuv3-accel-Introduce-CMDQV-ops-interface.patch
new file mode 100644
index 0000000..9917c6f
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Introduce-CMDQV-ops-interface.patch
@@ -0,0 +1,112 @@
+From b51c2abea81d87ed70013f9004b716d4264ff839 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:27 +0100
+Subject: [PATCH 084/111] hw/arm/smmuv3-accel: Introduce CMDQV ops interface
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [84/111] d0ebe2694524a5e53e830a9636b25371c09c820a (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Command Queue Virtualization (CMDQV) is a hardware extension available
+on certain platforms that allows the SMMUv3 command queue to be
+virtualized and passed through to a VM, improving performance.
+
+For example, NVIDIA Tegra241 implements CMDQV to support virtualization
+of multiple command queues (VCMDQs).
+
+The term CMDQV is used here generically to refer to any platform that
+provides hardware support to virtualize the SMMUv3 command queue.
+
+CMDQV support is a specialization of the IOMMUFD-backed accelerated
+SMMUv3 path. Introduce an ops interface to factor out CMDQV-specific
+probe, initialization, and vIOMMU allocation logic from the base
+implementation. The ops pointer and associated state are stored in
+the accelerated SMMUv3 state.
+
+This provides an extensible design to support future vendor-specific
+CMDQV implementations.
+
+No functional change.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-7-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 4912111c682f9649176026c5ce0137c25dc91b4a)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.h | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index d89c117fd1..849015f98e 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -10,12 +10,45 @@
+ #define HW_ARM_SMMUV3_ACCEL_H
+
+ #include "hw/arm/smmu-common.h"
++#include "hw/arm/smmuv3.h"
+ #include "system/iommufd.h"
+ #ifdef CONFIG_LINUX
+ #include <linux/iommufd.h>
+ #endif
+ #include CONFIG_DEVICES
+
++/*
++ * CMDQ-Virtualization (CMDQV) hardware support, extends the SMMUv3 to
++ * support multiple VCMDQs with virtualization capabilities.
++ * CMDQV specific behavior is factored behind this ops interface.
++ */
++typedef struct SMMUv3AccelCmdqvOps {
++ /**
++ * @probe: Mandatory. Vendor-specific device probing.
++ */
++ bool (*probe)(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev, Error **errp);
++ /**
++ * @init: Optional callback. Initialize CMDQV hardware.
++ */
++ bool (*init)(SMMUv3State *s, Error **errp);
++ /**
++ * @alloc_viommu: Mandatory. Allocate CMDQV viommu resources.
++ */
++ bool (*alloc_viommu)(SMMUv3State *s,
++ HostIOMMUDeviceIOMMUFD *idev,
++ uint32_t *out_viommu_id,
++ Error **errp);
++ /**
++ * @free_viommu: Optional callback. Free CMDQV viommu resources.
++ * If NULL, the viommu_id is freed directly via iommufd_backend_free_id().
++ */
++ void (*free_viommu)(SMMUv3State *s);
++ /**
++ * @reset: Optional callback. Reset CMDQV state.
++ */
++ void (*reset)(SMMUv3State *s);
++} SMMUv3AccelCmdqvOps;
++
+ /*
+ * Represents an accelerated SMMU instance backed by an iommufd vIOMMU object.
+ * Holds bypass and abort proxy HWPT IDs used for device attachment.
+@@ -28,6 +61,7 @@ typedef struct SMMUv3AccelState {
+ QLIST_HEAD(, SMMUv3AccelDevice) device_list;
+ bool auto_mode;
+ bool auto_finalised;
++ const SMMUv3AccelCmdqvOps *cmdqv_ops;
+ } SMMUv3AccelState;
+
+ typedef struct SMMUS1Hwpt {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Introduce-common-helper-for-veve.patch b/kvm-hw-arm-smmuv3-accel-Introduce-common-helper-for-veve.patch
new file mode 100644
index 0000000..b750fc5
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Introduce-common-helper-for-veve.patch
@@ -0,0 +1,171 @@
+From 797da99309c9e32426b24dd0ccb50b9c184e7ede Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:43 +0100
+Subject: [PATCH 101/111] hw/arm/smmuv3-accel: Introduce common helper for
+ veventq read
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [101/111] dd3f176292b344f27dffcb67334d2b9fdcf92faa (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Move the vEVENTQ read and validation logic into a common helper
+smmuv3_accel_event_read_validate(). The helper performs the read(),
+checks for overflow and short reads, validates the sequence number,
+and updates the sequence state.
+
+This helper can be reused for Tegra241 CMDQV vEVENTQ support in a
+subsequent patch.
+
+Error handling is slightly adjusted: instead of reporting errors
+directly in the read handler, the helper now returns errors via
+Error **. Sequence gaps are reported as warnings.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-23-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit f8015fe988df09448ea67458dd31f04d704388c3)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel-stubs.c | 7 ++++
+ hw/arm/smmuv3-accel.c | 67 ++++++++++++++++++++++---------------
+ hw/arm/smmuv3-accel.h | 2 ++
+ 3 files changed, 49 insertions(+), 27 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel-stubs.c b/hw/arm/smmuv3-accel-stubs.c
+index 70cef66966..9e6c44a282 100644
+--- a/hw/arm/smmuv3-accel-stubs.c
++++ b/hw/arm/smmuv3-accel-stubs.c
+@@ -47,6 +47,13 @@ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp)
+ return true;
+ }
+
++bool smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type,
++ void *buf, size_t size, Error **errp)
++{
++ return true;
++}
++
++
+ void smmuv3_accel_reset(SMMUv3State *s)
+ {
+ }
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 3ceca56a67..c1c2a67c97 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -440,47 +440,60 @@ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *bs, void *cmd, SMMUDevice *sdev,
+ sizeof(Cmd), &entry_num, cmd, errp);
+ }
+
+-static void smmuv3_accel_event_read(void *opaque)
++bool smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type,
++ void *buf, size_t size, Error **errp)
+ {
+- SMMUv3State *s = opaque;
+- IOMMUFDVeventq *veventq = s->s_accel->veventq;
+- struct {
+- struct iommufd_vevent_header hdr;
+- struct iommu_vevent_arm_smmuv3 vevent;
+- } buf;
+- enum iommu_veventq_type type = IOMMU_VEVENTQ_TYPE_ARM_SMMUV3;
+- uint32_t id = veventq->veventq_id;
+ uint32_t last_seq = veventq->last_event_seq;
++ uint32_t id = veventq->veventq_id;
++ struct iommufd_vevent_header *hdr;
+ ssize_t bytes;
+
+- bytes = read(veventq->veventq_fd, &buf, sizeof(buf));
++ bytes = read(veventq->veventq_fd, buf, size);
+ if (bytes <= 0) {
+ if (errno == EAGAIN || errno == EINTR) {
+- return;
++ return true;
+ }
+- error_report_once("vEVENTQ(type %u id %u): read failed (%m)", type, id);
+- return;
++ error_setg(errp, "vEVENTQ(type %u id %u): read failed (%m)", type, id);
++ return false;
+ }
+-
+- if (bytes == sizeof(buf.hdr) &&
+- (buf.hdr.flags & IOMMU_VEVENTQ_FLAG_LOST_EVENTS)) {
+- error_report_once("vEVENTQ(type %u id %u): overflowed", type, id);
++ hdr = (struct iommufd_vevent_header *)buf;
++ if (bytes == sizeof(*hdr) &&
++ (hdr->flags & IOMMU_VEVENTQ_FLAG_LOST_EVENTS)) {
++ error_setg(errp, "vEVENTQ(type %u id %u): overflowed", type, id);
+ veventq->event_start = false;
+- return;
++ return false;
+ }
+- if (bytes < sizeof(buf)) {
+- error_report_once("vEVENTQ(type %u id %u): short read(%zd/%zd bytes)",
+- type, id, bytes, sizeof(buf));
+- return;
++ if (bytes < size) {
++ error_setg(errp, "vEVENTQ(type %u id %u): short read(%zd/%zd bytes)",
++ type, id, bytes, size);
++ return false;
+ }
+-
+ /* Check sequence in hdr for lost events if any */
+- if (veventq->event_start && (buf.hdr.sequence - last_seq != 1)) {
+- error_report_once("vEVENTQ(type %u id %u): lost %u event(s)",
+- type, id, buf.hdr.sequence - last_seq - 1);
++ if (veventq->event_start && (hdr->sequence - last_seq != 1)) {
++ warn_report("vEVENTQ(type %u id %u): lost %u event(s)",
++ type, id, hdr->sequence - last_seq - 1);
+ }
+- veventq->last_event_seq = buf.hdr.sequence;
++ veventq->last_event_seq = hdr->sequence;
+ veventq->event_start = true;
++ return true;
++}
++
++static void smmuv3_accel_event_read(void *opaque)
++{
++ SMMUv3State *s = opaque;
++ IOMMUFDVeventq *veventq = s->s_accel->veventq;
++ struct {
++ struct iommufd_vevent_header hdr;
++ struct iommu_vevent_arm_smmuv3 vevent;
++ } buf;
++ Error *local_err = NULL;
++
++ if (!smmuv3_accel_event_read_validate(veventq,
++ IOMMU_VEVENTQ_TYPE_ARM_SMMUV3, &buf,
++ sizeof(buf), &local_err)) {
++ warn_report_err_once(local_err);
++ return;
++ }
+ smmuv3_propagate_event(s, (Evt *)&buf.vevent);
+ }
+
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index e0bbec8581..8d0f636338 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -87,6 +87,8 @@ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
+ Error **errp);
+ void smmuv3_accel_idr_override(SMMUv3State *s);
+ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp);
++bool smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type,
++ void *buf, size_t size, Error **errp);
+ void smmuv3_accel_reset(SMMUv3State *s);
+
+ #endif /* HW_ARM_SMMUV3_ACCEL_H */
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Introduce-helper-to-query-CMDQV-.patch b/kvm-hw-arm-smmuv3-accel-Introduce-helper-to-query-CMDQV-.patch
new file mode 100644
index 0000000..738e9d0
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Introduce-helper-to-query-CMDQV-.patch
@@ -0,0 +1,138 @@
+From e75168be94bda921feca7955b173de4700dd6b0c Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:48 +0100
+Subject: [PATCH 106/111] hw/arm/smmuv3-accel: Introduce helper to query CMDQV
+ type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [106/111] 363c0461547a4df58e52522d40ca1cb1b7575f60 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Introduce a SMMUv3AccelCmdqvType enum and a helper to query the
+CMDQV implementation type associated with an accelerated SMMUv3
+instance.
+
+A subsequent patch will use this helper when generating the
+Tegra241 CMDQV DSDT.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-28-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit d3e56703bfc58969ac02009bcdbac7f5b25998db)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel-stubs.c | 5 +++++
+ hw/arm/smmuv3-accel.c | 12 ++++++++++++
+ hw/arm/smmuv3-accel.h | 10 ++++++++++
+ hw/arm/tegra241-cmdqv.c | 6 ++++++
+ 4 files changed, 33 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel-stubs.c b/hw/arm/smmuv3-accel-stubs.c
+index 9e6c44a282..147ae06163 100644
+--- a/hw/arm/smmuv3-accel-stubs.c
++++ b/hw/arm/smmuv3-accel-stubs.c
+@@ -57,3 +57,8 @@ bool smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type,
+ void smmuv3_accel_reset(SMMUv3State *s)
+ {
+ }
++
++SMMUv3AccelCmdqvType smmuv3_accel_cmdqv_type(Object *obj)
++{
++ return SMMUV3_CMDQV_NONE;
++}
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index c1c2a67c97..9c3bd4413d 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -1060,6 +1060,18 @@ static void smmuv3_accel_as_init(SMMUv3State *s)
+ address_space_init(shared_as_sysmem, &root, "smmuv3-accel-as-sysmem");
+ }
+
++SMMUv3AccelCmdqvType smmuv3_accel_cmdqv_type(Object *obj)
++{
++ SMMUv3State *s = ARM_SMMUV3(obj);
++ SMMUv3AccelState *accel = s->s_accel;
++
++ if (!accel || !accel->cmdqv_ops || !accel->cmdqv_ops->get_type) {
++ return SMMUV3_CMDQV_NONE;
++ }
++
++ return accel->cmdqv_ops->get_type();
++}
++
+ static void smmuv3_accel_machine_done(Notifier *notifier, void *data)
+ {
+ SMMUv3State *s = container_of(notifier, SMMUv3State, machine_done);
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index 8d0f636338..5fc85fb89d 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -16,6 +16,11 @@
+ #include <linux/iommufd.h>
+ #endif
+
++typedef enum SMMUv3AccelCmdqvType {
++ SMMUV3_CMDQV_NONE = 0,
++ SMMUV3_CMDQV_TEGRA241,
++} SMMUv3AccelCmdqvType;
++
+ /*
+ * CMDQ-Virtualization (CMDQV) hardware support, extends the SMMUv3 to
+ * support multiple VCMDQs with virtualization capabilities.
+@@ -42,6 +47,10 @@ typedef struct SMMUv3AccelCmdqvOps {
+ * If NULL, the viommu_id is freed directly via iommufd_backend_free_id().
+ */
+ void (*free_viommu)(SMMUv3State *s);
++ /**
++ * @get_type: Optional callback. Return the CMDQV implementation type.
++ */
++ SMMUv3AccelCmdqvType (*get_type)(void);
+ /**
+ * @reset: Optional callback. Reset CMDQV state.
+ */
+@@ -90,5 +99,6 @@ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp);
+ bool smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type,
+ void *buf, size_t size, Error **errp);
+ void smmuv3_accel_reset(SMMUv3State *s);
++SMMUv3AccelCmdqvType smmuv3_accel_cmdqv_type(Object *obj);
+
+ #endif /* HW_ARM_SMMUV3_ACCEL_H */
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index a4c140e34c..1bed1374ba 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -964,6 +964,11 @@ static bool tegra241_cmdqv_init(SMMUv3State *s, Error **errp)
+ return true;
+ }
+
++static SMMUv3AccelCmdqvType tegra241_cmdqv_get_type(void)
++{
++ return SMMUV3_CMDQV_TEGRA241;
++}
++
+ static bool tegra241_cmdqv_probe(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ Error **errp)
+ {
+@@ -1004,6 +1009,7 @@ static const SMMUv3AccelCmdqvOps tegra241_cmdqv_ops = {
+ .init = tegra241_cmdqv_init,
+ .alloc_viommu = tegra241_cmdqv_alloc_viommu,
+ .free_viommu = tegra241_cmdqv_free_viommu,
++ .get_type = tegra241_cmdqv_get_type,
+ .reset = tegra241_cmdqv_reset,
+ };
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Introduce-smmuv3-accel-device.patch b/kvm-hw-arm-smmuv3-accel-Introduce-smmuv3-accel-device.patch
new file mode 100644
index 0000000..4a7e746
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Introduce-smmuv3-accel-device.patch
@@ -0,0 +1,219 @@
+From 9fa0e1b82cc1863a481e3700929c40f0160d95cb Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 007/111] hw/arm/smmuv3-accel: Introduce smmuv3 accel device
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [7/111] 1b76cd4032c19e0abebd850ee1e000f5e7768993 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Set up dedicated PCIIOMMUOps for the accel SMMUv3, since it will need
+different callback handling in upcoming patches. This also adds a
+CONFIG_ARM_SMMUV3_ACCEL build option so the feature can be disabled
+at compile time. Because we now include CONFIG_DEVICES in the header to
+check for ARM_SMMUV3_ACCEL, the meson file entry for smmuv3.c needs to
+be changed to arm_ss.add.
+
+The “accel” property isn’t user visible yet and it will be introduced in
+a later patch once all the supporting pieces are ready.
+
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-6-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 79fcbec80a85891b30684703d3ac96a7b992ae49)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/Kconfig | 5 ++++
+ hw/arm/meson.build | 3 ++-
+ hw/arm/smmuv3-accel.c | 59 +++++++++++++++++++++++++++++++++++++++++
+ hw/arm/smmuv3-accel.h | 27 +++++++++++++++++++
+ hw/arm/smmuv3.c | 5 ++++
+ include/hw/arm/smmuv3.h | 3 +++
+ 6 files changed, 101 insertions(+), 1 deletion(-)
+ create mode 100644 hw/arm/smmuv3-accel.c
+ create mode 100644 hw/arm/smmuv3-accel.h
+
+diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
+index 3baa6c6c74..1f49550c61 100644
+--- a/hw/arm/Kconfig
++++ b/hw/arm/Kconfig
+@@ -622,8 +622,13 @@ config FSL_IMX8MP_EVK
+ depends on TCG && AARCH64
+ select FSL_IMX8MP
+
++config ARM_SMMUV3_ACCEL
++ bool
++ depends on ARM_SMMUV3
++
+ config ARM_SMMUV3
+ bool
++ select ARM_SMMUV3_ACCEL if IOMMUFD
+
+ config FSL_IMX6UL
+ bool
+diff --git a/hw/arm/meson.build b/hw/arm/meson.build
+index dc68391305..bcb27c0bf6 100644
+--- a/hw/arm/meson.build
++++ b/hw/arm/meson.build
+@@ -61,7 +61,8 @@ arm_common_ss.add(when: 'CONFIG_ARMSSE', if_true: files('armsse.c'))
+ arm_common_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.c'))
+ arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP', if_true: files('fsl-imx8mp.c'))
+ arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP_EVK', if_true: files('imx8mp-evk.c'))
+-arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
++arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
++arm_ss.add(when: 'CONFIG_ARM_SMMUV3_ACCEL', if_true: files('smmuv3-accel.c'))
+ arm_common_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
+ arm_common_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
+ arm_ss.add(when: 'CONFIG_XEN', if_true: files(
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+new file mode 100644
+index 0000000000..99ef0db8c4
+--- /dev/null
++++ b/hw/arm/smmuv3-accel.c
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2025 Huawei Technologies R & D (UK) Ltd
++ * Copyright (C) 2025 NVIDIA
++ * Written by Nicolin Chen, Shameer Kolothum
++ *
++ * SPDX-License-Identifier: GPL-2.0-or-later
++ */
++
++#include "qemu/osdep.h"
++
++#include "hw/arm/smmuv3.h"
++#include "smmuv3-accel.h"
++
++static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus,
++ PCIBus *bus, int devfn)
++{
++ SMMUDevice *sdev = sbus->pbdev[devfn];
++ SMMUv3AccelDevice *accel_dev;
++
++ if (sdev) {
++ return container_of(sdev, SMMUv3AccelDevice, sdev);
++ }
++
++ accel_dev = g_new0(SMMUv3AccelDevice, 1);
++ sdev = &accel_dev->sdev;
++
++ sbus->pbdev[devfn] = sdev;
++ smmu_init_sdev(bs, sdev, bus, devfn);
++ return accel_dev;
++}
++
++/*
++ * Find or add an address space for the given PCI device.
++ *
++ * If a device matching @bus and @devfn already exists, return its
++ * corresponding address space. Otherwise, create a new device entry
++ * and initialize address space for it.
++ */
++static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque,
++ int devfn)
++{
++ SMMUState *bs = opaque;
++ SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
++ SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus, bus, devfn);
++ SMMUDevice *sdev = &accel_dev->sdev;
++
++ return &sdev->as;
++}
++
++static const PCIIOMMUOps smmuv3_accel_ops = {
++ .get_address_space = smmuv3_accel_find_add_as,
++};
++
++void smmuv3_accel_init(SMMUv3State *s)
++{
++ SMMUState *bs = ARM_SMMU(s);
++
++ bs->iommu_ops = &smmuv3_accel_ops;
++}
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+new file mode 100644
+index 0000000000..0dc6b00d35
+--- /dev/null
++++ b/hw/arm/smmuv3-accel.h
+@@ -0,0 +1,27 @@
++/*
++ * Copyright (c) 2025 Huawei Technologies R & D (UK) Ltd
++ * Copyright (C) 2025 NVIDIA
++ * Written by Nicolin Chen, Shameer Kolothum
++ *
++ * SPDX-License-Identifier: GPL-2.0-or-later
++ */
++
++#ifndef HW_ARM_SMMUV3_ACCEL_H
++#define HW_ARM_SMMUV3_ACCEL_H
++
++#include "hw/arm/smmu-common.h"
++#include CONFIG_DEVICES
++
++typedef struct SMMUv3AccelDevice {
++ SMMUDevice sdev;
++} SMMUv3AccelDevice;
++
++#ifdef CONFIG_ARM_SMMUV3_ACCEL
++void smmuv3_accel_init(SMMUv3State *s);
++#else
++static inline void smmuv3_accel_init(SMMUv3State *s)
++{
++}
++#endif
++
++#endif /* HW_ARM_SMMUV3_ACCEL_H */
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index bcf8af8dc7..ef991cb7d8 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -32,6 +32,7 @@
+ #include "qapi/error.h"
+
+ #include "hw/arm/smmuv3.h"
++#include "smmuv3-accel.h"
+ #include "smmuv3-internal.h"
+ #include "smmu-internal.h"
+
+@@ -1882,6 +1883,10 @@ static void smmu_realize(DeviceState *d, Error **errp)
+ SysBusDevice *dev = SYS_BUS_DEVICE(d);
+ Error *local_err = NULL;
+
++ if (s->accel) {
++ smmuv3_accel_init(s);
++ }
++
+ c->parent_realize(d, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index d183a62766..bb7076286b 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -63,6 +63,9 @@ struct SMMUv3State {
+ qemu_irq irq[4];
+ QemuMutex mutex;
+ char *stage;
++
++ /* SMMU has HW accelerator support for nested S1 + s2 */
++ bool accel;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Make-SubstreamID-support-configu.patch b/kvm-hw-arm-smmuv3-accel-Make-SubstreamID-support-configu.patch
new file mode 100644
index 0000000..1ef4063
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Make-SubstreamID-support-configu.patch
@@ -0,0 +1,186 @@
+From 2e3a09c929d35cc1f5d998801811260e1da24105 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 045/111] hw/arm/smmuv3-accel: Make SubstreamID support
+ configurable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [45/111] 78b8d97d32ebb27be666593bec7ca0cb80007eb7 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+QEMU SMMUv3 currently reports no SubstreamID support, forcing SSID to
+zero. This prevents accelerated use cases such as Shared Virtual
+Addressing (SVA), which require multiple Stage-1 context descriptors
+indexed by SubstreamID.
+
+Add a new "ssidsize" property to explicitly configure the number of bits
+used for SubstreamIDs. A value greater than zero enables SubstreamID
+support and advertises PASID capability to the vIOMMU.
+
+The requested SSIDSIZE is validated against host SMMUv3 capabilities and
+is only supported when accel=on.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-38-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit b8c6f8a69d2734a65a00f11788d6711e5d28a4ec)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 25 ++++++++++++++++++++++++-
+ hw/arm/smmuv3.c | 22 ++++++++++++++++++++--
+ include/hw/arm/smmuv3-common.h | 1 +
+ include/hw/arm/smmuv3.h | 1 +
+ 4 files changed, 46 insertions(+), 3 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 342944da23..f5cd4df336 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -76,6 +76,16 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
+ return false;
+ }
+
++ /* Check SSIDSIZE value opted-in is compatible with Host SMMUv3 SSIDSIZE */
++ if (FIELD_EX32(info->idr[1], IDR1, SSIDSIZE) <
++ FIELD_EX32(s->idr[1], IDR1, SSIDSIZE)) {
++ error_setg(errp, "Host SMMUv3 SSIDSIZE not compatible "
++ "(host=%u, QEMU=%u)",
++ FIELD_EX32(info->idr[1], IDR1, SSIDSIZE),
++ FIELD_EX32(s->idr[1], IDR1, SSIDSIZE));
++ return false;
++ }
++
+ /* User can disable QEMU SMMUv3 Range Invalidation support */
+ if (FIELD_EX32(info->idr[3], IDR3, RIL) <
+ FIELD_EX32(s->idr[3], IDR3, RIL)) {
+@@ -652,7 +662,14 @@ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
+ * The real HW nested support should be reported from host SMMUv3 and if
+ * it doesn't, the nesting parent allocation will fail anyway in VFIO core.
+ */
+- return VIOMMU_FLAG_WANT_NESTING_PARENT;
++ uint64_t flags = VIOMMU_FLAG_WANT_NESTING_PARENT;
++ SMMUState *bs = opaque;
++ SMMUv3State *s = ARM_SMMUV3(bs);
++
++ if (s->ssidsize) {
++ flags |= VIOMMU_FLAG_PASID_SUPPORTED;
++ }
++ return flags;
+ }
+
+ static const PCIIOMMUOps smmuv3_accel_ops = {
+@@ -680,6 +697,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
+ if (s->oas == SMMU_OAS_48BIT) {
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS_48);
+ }
++
++ /*
++ * By default QEMU SMMUv3 has no SubstreamID support. Update IDR1 if user
++ * has enabled it.
++ */
++ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, s->ssidsize);
+ }
+
+ /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index ef75a9bec0..49311f5bbf 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -611,9 +611,11 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
+ }
+ }
+
+- if (STE_S1CDMAX(ste) != 0) {
++ /* Multiple context descriptors require SubstreamID support */
++ if (!s->ssidsize && STE_S1CDMAX(ste) != 0) {
+ qemu_log_mask(LOG_UNIMP,
+- "SMMUv3 does not support multiple context descriptors yet\n");
++ "SMMUv3: multiple S1 context descriptors require SubstreamID support. "
++ "Configure ssidsize > 0 (requires accel=on)\n");
+ goto bad_ste;
+ }
+
+@@ -1954,6 +1956,10 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "OAS must be 44 bits when accel=off");
+ return false;
+ }
++ if (s->ssidsize) {
++ error_setg(errp, "ssidsize can only be set if accel=on");
++ return false;
++ }
+ return true;
+ }
+
+@@ -1968,6 +1974,11 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
+ error_setg(errp, "OAS can only be set to 44 or 48 bits");
+ return false;
+ }
++ if (s->ssidsize > SMMU_SSID_MAX_BITS) {
++ error_setg(errp, "ssidsize must be in the range 0 to %d",
++ SMMU_SSID_MAX_BITS);
++ return false;
++ }
+
+ return true;
+ }
+@@ -2096,6 +2107,7 @@ static const Property smmuv3_properties[] = {
+ DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
+ DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
+ DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
++ DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
+ };
+
+ static void smmuv3_instance_init(Object *obj)
+@@ -2129,6 +2141,12 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
+ object_class_property_set_description(klass, "oas",
+ "Specify Output Address Size (for accel=on). Supported values "
+ "are 44 or 48 bits. Defaults to 44 bits");
++ object_class_property_set_description(klass, "ssidsize",
++ "Number of bits used to represent SubstreamIDs (SSIDs). "
++ "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
++ "Valid range is 0-20, where 0 disables SubstreamID support. "
++ "Defaults to 0. A value greater than 0 is required to enable "
++ "PASID support.");
+ }
+
+ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index bc2d49ef4e..4b764ed125 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -311,6 +311,7 @@ REG32(IDR1, 0x4)
+ FIELD(IDR1, TABLES_PRESET, 30, 1)
+ FIELD(IDR1, ECMDQ, 31, 1)
+
++#define SMMU_SSID_MAX_BITS 20
+ #define SMMU_IDR1_SIDSIZE 16
+ #define SMMU_CMDQS 19
+ #define SMMU_EVENTQS 19
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index d488a39cd0..26b2fc42fd 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -72,6 +72,7 @@ struct SMMUv3State {
+ bool ril;
+ bool ats;
+ uint8_t oas;
++ uint8_t ssidsize;
+ };
+
+ typedef enum {
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Read-and-propagate-host-vIOMMU-e.patch b/kvm-hw-arm-smmuv3-accel-Read-and-propagate-host-vIOMMU-e.patch
new file mode 100644
index 0000000..8730b82
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Read-and-propagate-host-vIOMMU-e.patch
@@ -0,0 +1,143 @@
+From 6560e5f70f3f242b06b3523e1f910e25db719073 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Fri, 6 Mar 2026 09:01:11 +0000
+Subject: [PATCH 054/111] hw/arm/smmuv3-accel: Read and propagate host vIOMMU
+ events
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [54/111] 87b794e5d88a3402c0f8250bd80eb65dd3435b2d (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73796
+
+Install an event handler on the vEVENTQ fd to read and propagate host
+generated vIOMMU events to the guest.
+
+The handler runs in QEMU's main loop, using a non-blocking fd registered
+via qemu_set_fd_handler().
+
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260226084456.112142-6-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit c0c97fbc6cf764f0d66d5122c4117d0770e89902)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 64 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 64 insertions(+)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index f703ea1aac..17306cd04b 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -390,6 +390,50 @@ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *bs, void *cmd, SMMUDevice *sdev,
+ sizeof(Cmd), &entry_num, cmd, errp);
+ }
+
++static void smmuv3_accel_event_read(void *opaque)
++{
++ SMMUv3State *s = opaque;
++ IOMMUFDVeventq *veventq = s->s_accel->veventq;
++ struct {
++ struct iommufd_vevent_header hdr;
++ struct iommu_vevent_arm_smmuv3 vevent;
++ } buf;
++ enum iommu_veventq_type type = IOMMU_VEVENTQ_TYPE_ARM_SMMUV3;
++ uint32_t id = veventq->veventq_id;
++ uint32_t last_seq = veventq->last_event_seq;
++ ssize_t bytes;
++
++ bytes = read(veventq->veventq_fd, &buf, sizeof(buf));
++ if (bytes <= 0) {
++ if (errno == EAGAIN || errno == EINTR) {
++ return;
++ }
++ error_report_once("vEVENTQ(type %u id %u): read failed (%m)", type, id);
++ return;
++ }
++
++ if (bytes == sizeof(buf.hdr) &&
++ (buf.hdr.flags & IOMMU_VEVENTQ_FLAG_LOST_EVENTS)) {
++ error_report_once("vEVENTQ(type %u id %u): overflowed", type, id);
++ veventq->event_start = false;
++ return;
++ }
++ if (bytes < sizeof(buf)) {
++ error_report_once("vEVENTQ(type %u id %u): short read(%zd/%zd bytes)",
++ type, id, bytes, sizeof(buf));
++ return;
++ }
++
++ /* Check sequence in hdr for lost events if any */
++ if (veventq->event_start && (buf.hdr.sequence - last_seq != 1)) {
++ error_report_once("vEVENTQ(type %u id %u): lost %u event(s)",
++ type, id, buf.hdr.sequence - last_seq - 1);
++ }
++ veventq->last_event_seq = buf.hdr.sequence;
++ veventq->event_start = true;
++ smmuv3_propagate_event(s, (Evt *)&buf.vevent);
++}
++
+ static void smmuv3_accel_free_veventq(SMMUv3AccelState *accel)
+ {
+ IOMMUFDVeventq *veventq = accel->veventq;
+@@ -397,6 +441,7 @@ static void smmuv3_accel_free_veventq(SMMUv3AccelState *accel)
+ if (!veventq) {
+ return;
+ }
++ qemu_set_fd_handler(veventq->veventq_fd, NULL, NULL, NULL);
+ close(veventq->veventq_fd);
+ iommufd_backend_free_id(accel->viommu->iommufd, veventq->veventq_id);
+ g_free(veventq);
+@@ -424,6 +469,7 @@ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp)
+ IOMMUFDVeventq *veventq;
+ uint32_t veventq_id;
+ uint32_t veventq_fd;
++ int flags;
+
+ if (!accel || !accel->viommu) {
+ return true;
+@@ -445,12 +491,30 @@ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp)
+ return false;
+ }
+
++ flags = fcntl(veventq_fd, F_GETFL);
++ if (flags < 0) {
++ error_setg_errno(errp, errno, "Failed to get flags for vEVENTQ fd");
++ goto free_veventq;
++ }
++ if (fcntl(veventq_fd, F_SETFL, flags | O_NONBLOCK) < 0) {
++ error_setg_errno(errp, errno, "Failed to set O_NONBLOCK on vEVENTQ fd");
++ goto free_veventq;
++ }
++
+ veventq = g_new0(IOMMUFDVeventq, 1);
+ veventq->veventq_id = veventq_id;
+ veventq->veventq_fd = veventq_fd;
+ veventq->viommu = accel->viommu;
+ accel->veventq = veventq;
++
++ /* Set up event handler for veventq fd */
++ qemu_set_fd_handler(veventq_fd, smmuv3_accel_event_read, NULL, s);
+ return true;
++
++free_veventq:
++ close(veventq_fd);
++ iommufd_backend_free_id(accel->viommu->iommufd, veventq_id);
++ return false;
+ }
+
+ static bool
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Restrict-accelerated-SMMUv3-to-v.patch b/kvm-hw-arm-smmuv3-accel-Restrict-accelerated-SMMUv3-to-v.patch
new file mode 100644
index 0000000..deb3471
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Restrict-accelerated-SMMUv3-to-v.patch
@@ -0,0 +1,198 @@
+From 85d81ec5715c42de0019cbe8260ddbc6662f850b Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 013/111] hw/arm/smmuv3-accel: Restrict accelerated SMMUv3 to
+ vfio-pci endpoints with iommufd
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [13/111] c7a4d250dd7429e1c136ad544552dd499e87af35 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Accelerated SMMUv3 is only meaningful when a device can leverage the host
+SMMUv3 in nested mode (S1+S2 translation). To keep the model consistent
+and correct, this mode is restricted to vfio-pci endpoint devices using
+the iommufd backend.
+
+Non-endpoint emulated devices such as PCIe root ports and bridges are also
+permitted so that vfio-pci devices can be attached downstream. All other
+device types are unsupported in accelerated mode.
+
+Implement supports_address_space() callback to reject all such unsupported
+devices.
+
+This restriction also avoids complications with IOTLB invalidations. Some
+TLBI commands (e.g. CMD_TLBI_NH_ASID) lack an associated SID, making it
+difficult to trace the originating device. Allowing emulated endpoints
+would require invalidating both QEMU’s software IOTLB and the host’s
+hardware IOTLB, which can significantly degrade performance.
+
+A key design choice is the address space returned for accelerated vfio-pci
+endpoints. VFIO core has a container that manages an HWPT. By default, it
+allocates a stage-1 normal HWPT, unless vIOMMU requests for a nesting
+parent HWPT for accelerated cases.
+
+VFIO core adds a listener for that HWPT and sets up a handler
+vfio_container_region_add() where it checks the memory region.
+
+ -If the region is a non-IOMMU translated one (system address space), VFIO
+ treats it as RAM and handles all stage-2 mappings for the core allocated
+ nesting parent HWPT.
+
+ -If the region is an IOMMU address space, VFIO instead enables IOTLB
+ notifier handling and translation replay, skipping the RAM listener and
+ therefore not installing stage-2 mappings.
+
+For accelerated SMMUv3, correct operation requires the S1+S2 nesting
+model, and therefore VFIO must take the "system address space" path so
+that stage-2 mappings are properly built. Returning an alias of the
+system address space ensures this happens. Returning the IOMMU address
+space would omit stage-2 mapping and break nested translation.
+
+Another option considered was forcing a pre-registration path using
+vfio_prereg_listener() to set up stage-2 mappings, but this requires
+changes in VFIO core and was not adopted. Returning an alias of the
+system address space keeps the design aligned with existing VFIO/iommufd
+nesting flows and avoids the need for cross-subsystem changes.
+
+In summary:
+ - vfio-pci devices(with iommufd as backend) return an address space
+ aliased to system address space.
+ - bridges and root ports return the IOMMU address space.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-11-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit c7ecb4cf2e9458678d649ffd3b8aa61a7976552e)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 77 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 76 insertions(+), 1 deletion(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index b2eded743e..2fcd301322 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -7,8 +7,13 @@
+ */
+
+ #include "qemu/osdep.h"
++#include "qemu/error-report.h"
+
+ #include "hw/arm/smmuv3.h"
++#include "hw/pci/pci_bridge.h"
++#include "hw/pci-host/gpex.h"
++#include "hw/vfio/pci.h"
++
+ #include "smmuv3-accel.h"
+
+ /*
+@@ -37,6 +42,48 @@ static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus,
+ return accel_dev;
+ }
+
++/*
++ * Only allow PCIe bridges, pxb-pcie roots, and GPEX roots so vfio-pci
++ * endpoints can sit downstream. Accelerated SMMUv3 requires a vfio-pci
++ * endpoint using the iommufd backend; all other device types are rejected.
++ * This avoids supporting emulated endpoints, which would complicate IOTLB
++ * invalidation and hurt performance.
++ */
++static bool smmuv3_accel_pdev_allowed(PCIDevice *pdev, bool *vfio_pci)
++{
++
++ if (object_dynamic_cast(OBJECT(pdev), TYPE_PCI_BRIDGE) ||
++ object_dynamic_cast(OBJECT(pdev), TYPE_PXB_PCIE_DEV) ||
++ object_dynamic_cast(OBJECT(pdev), TYPE_GPEX_ROOT_DEVICE)) {
++ return true;
++ } else if ((object_dynamic_cast(OBJECT(pdev), TYPE_VFIO_PCI))) {
++ *vfio_pci = true;
++ if (object_property_get_link(OBJECT(pdev), "iommufd", NULL)) {
++ return true;
++ }
++ }
++ return false;
++}
++
++static bool smmuv3_accel_supports_as(PCIBus *bus, void *opaque, int devfn,
++ Error **errp)
++{
++ PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
++ bool vfio_pci = false;
++
++ if (pdev && !smmuv3_accel_pdev_allowed(pdev, &vfio_pci)) {
++ if (vfio_pci) {
++ error_setg(errp, "vfio-pci endpoint devices without an iommufd "
++ "backend not allowed when using arm-smmuv3,accel=on");
++
++ } else {
++ error_setg(errp, "Emulated endpoint devices are not allowed when "
++ "using arm-smmuv3,accel=on");
++ }
++ return false;
++ }
++ return true;
++}
+ /*
+ * Find or add an address space for the given PCI device.
+ *
+@@ -47,15 +94,43 @@ static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus,
+ static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque,
+ int devfn)
+ {
++ PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
+ SMMUState *bs = opaque;
+ SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
+ SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus, bus, devfn);
+ SMMUDevice *sdev = &accel_dev->sdev;
++ bool vfio_pci = false;
+
+- return &sdev->as;
++ if (pdev && !smmuv3_accel_pdev_allowed(pdev, &vfio_pci)) {
++ /* Should never be here: supports_address_space() filters these out */
++ g_assert_not_reached();
++ }
++
++ /*
++ * In the accelerated mode, a vfio-pci device attached via the iommufd
++ * backend must remain in the system address space. Such a device is
++ * always translated by its physical SMMU (using either a stage-2-only
++ * STE or a nested STE), where the parent stage-2 page table is allocated
++ * by the VFIO core to back the system address space.
++ *
++ * Return the shared_as_sysmem aliased to the global system memory in this
++ * case. Sharing address_space_memory also allows devices under different
++ * vSMMU instances in the same VM to reuse a single nesting parent HWPT in
++ * the VFIO core.
++ *
++ * For non-endpoint emulated devices such as PCIe root ports and bridges,
++ * which may use the normal emulated translation path and software IOTLBs,
++ * return the SMMU's IOMMU address space.
++ */
++ if (vfio_pci) {
++ return shared_as_sysmem;
++ } else {
++ return &sdev->as;
++ }
+ }
+
+ static const PCIIOMMUOps smmuv3_accel_ops = {
++ .supports_address_space = smmuv3_accel_supports_as,
+ .get_address_space = smmuv3_accel_find_add_as,
+ };
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-accel-Wire-CMDQV-ops-into-accel-lifecy.patch b/kvm-hw-arm-smmuv3-accel-Wire-CMDQV-ops-into-accel-lifecy.patch
new file mode 100644
index 0000000..fbfa1ad
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-accel-Wire-CMDQV-ops-into-accel-lifecy.patch
@@ -0,0 +1,217 @@
+From e65e13ba52d7bf68a18e0fbebe238e3fe1741008 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:29 +0100
+Subject: [PATCH 087/111] hw/arm/smmuv3-accel: Wire CMDQV ops into accel
+ lifecycle
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [87/111] 478812c8d4b682cb6eb159100712ff6eeec32e16 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Add support for selecting and initializing a CMDQV backend based on the
+cmdqv OnOffAuto property.
+
+If set to OFF, CMDQV is not used and the default IOMMUFD-backed allocation
+path is taken.
+
+If set to AUTO, QEMU attempts to probe a CMDQV backend during device setup.
+If probing succeeds, the selected ops are stored in the accelerated SMMUv3
+state and used. If probing fails, QEMU silently falls back to the default
+path.
+
+If set to ON, QEMU requires CMDQV support. Probing is performed during
+setup and failure results in an error.
+
+When a CMDQV backend is active, its callbacks are used for vIOMMU
+allocation, free, and reset handling. Otherwise, the base implementation
+is used.
+
+The current implementation wires up the Tegra241 CMDQV backend through the
+generic ops interface. Functional CMDQV behaviour is added in subsequent
+patches.
+
+No functional change.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-9-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit f4ec4767ce0c1fe5b0b1adf5f559ca808c3c2aba)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 94 ++++++++++++++++++++++++++++++++++++++---
+ include/hw/arm/smmuv3.h | 2 +
+ 2 files changed, 89 insertions(+), 7 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 70b2581c17..3ceca56a67 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -19,6 +19,7 @@
+ #include "smmuv3-internal.h"
+ #include "smmuv3-accel.h"
+ #include "system/system.h"
++#include "tegra241-cmdqv.h"
+
+ /*
+ * The root region aliases the global system memory, and shared_as_sysmem
+@@ -570,6 +571,7 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *hiodi,
+ Error **errp)
+ {
+ SMMUv3AccelState *accel = s->s_accel;
++ const SMMUv3AccelCmdqvOps *cmdqv_ops = accel->cmdqv_ops;
+ struct iommu_hwpt_arm_smmuv3 bypass_data = {
+ .ste = { SMMU_STE_CFG_BYPASS | SMMU_STE_VALID, 0x0ULL },
+ };
+@@ -580,10 +582,17 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *hiodi,
+ uint32_t viommu_id, hwpt_id;
+ IOMMUFDViommu *viommu;
+
+- if (!iommufd_backend_alloc_viommu(hiodi->iommufd, hiodi->devid,
+- IOMMU_VIOMMU_TYPE_ARM_SMMUV3, s2_hwpt_id,
+- NULL, 0, &viommu_id, errp)) {
+- return false;
++ if (cmdqv_ops) {
++ if (!cmdqv_ops->alloc_viommu(s, hiodi, &viommu_id, errp)) {
++ return false;
++ }
++ } else {
++ if (!iommufd_backend_alloc_viommu(hiodi->iommufd, hiodi->devid,
++ IOMMU_VIOMMU_TYPE_ARM_SMMUV3,
++ s2_hwpt_id, NULL, 0, &viommu_id,
++ errp)) {
++ return false;
++ }
+ }
+
+ viommu = g_new0(IOMMUFDViommu, 1);
+@@ -629,12 +638,70 @@ free_bypass_hwpt:
+ free_abort_hwpt:
+ iommufd_backend_free_id(hiodi->iommufd, accel->abort_hwpt_id);
+ free_viommu:
+- iommufd_backend_free_id(hiodi->iommufd, viommu->viommu_id);
++ if (cmdqv_ops && cmdqv_ops->free_viommu) {
++ cmdqv_ops->free_viommu(s);
++ } else {
++ iommufd_backend_free_id(hiodi->iommufd, viommu->viommu_id);
++ }
+ g_free(viommu);
+ accel->viommu = NULL;
+ return false;
+ }
+
++static const SMMUv3AccelCmdqvOps *
++smmuv3_accel_probe_cmdqv(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
++ Error **errp)
++{
++ const SMMUv3AccelCmdqvOps *ops = tegra241_cmdqv_get_ops();
++
++ if (!ops) {
++ error_setg(errp, "No CMDQV ops found");
++ return NULL;
++ }
++ g_assert(ops->probe);
++ g_assert(ops->alloc_viommu);
++
++ if (!ops->probe(s, idev, errp)) {
++ return NULL;
++ }
++ return ops;
++}
++
++static bool
++smmuv3_accel_select_cmdqv(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
++ Error **errp)
++{
++ const SMMUv3AccelCmdqvOps *ops = NULL;
++
++ if (s->s_accel->cmdqv_ops) {
++ return true;
++ }
++
++ switch (s->cmdqv) {
++ case ON_OFF_AUTO_OFF:
++ s->s_accel->cmdqv_ops = NULL;
++ return true;
++ case ON_OFF_AUTO_AUTO:
++ ops = smmuv3_accel_probe_cmdqv(s, idev, NULL);
++ break;
++ case ON_OFF_AUTO_ON:
++ ops = smmuv3_accel_probe_cmdqv(s, idev, errp);
++ if (!ops) {
++ error_append_hint(errp, "CMDQV requested but not supported");
++ return false;
++ }
++ break;
++ default:
++ g_assert_not_reached();
++ }
++
++ if (ops && ops->init && !ops->init(s, errp)) {
++ return false;
++ }
++ s->s_accel->cmdqv_ops = ops;
++ return true;
++}
++
+ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
+ HostIOMMUDevice *hiod, Error **errp)
+ {
+@@ -669,6 +736,10 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
+ goto done;
+ }
+
++ if (!smmuv3_accel_select_cmdqv(s, hiodi, errp)) {
++ return false;
++ }
++
+ if (!smmuv3_accel_alloc_viommu(s, hiodi, errp)) {
+ error_append_hint(errp, "Unable to alloc vIOMMU: hiodi devid 0x%x: ",
+ hiodi->devid);
+@@ -946,8 +1017,17 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
+
+ void smmuv3_accel_reset(SMMUv3State *s)
+ {
+- /* Attach a HWPT based on GBPA reset value */
+- smmuv3_accel_attach_gbpa_hwpt(s, NULL);
++ SMMUv3AccelState *accel = s->s_accel;
++
++ if (!accel) {
++ return;
++ }
++ /* Attach a HWPT based on GBPA reset value */
++ smmuv3_accel_attach_gbpa_hwpt(s, NULL);
++
++ if (accel->cmdqv_ops && accel->cmdqv_ops->reset) {
++ accel->cmdqv_ops->reset(s);
++ }
+ }
+
+ static void smmuv3_accel_as_init(SMMUv3State *s)
+diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
+index 85be3d7467..34d0f65eaa 100644
+--- a/include/hw/arm/smmuv3.h
++++ b/include/hw/arm/smmuv3.h
+@@ -75,6 +75,8 @@ struct SMMUv3State {
+ OnOffAuto ats;
+ OasMode oas;
+ SsidSizeMode ssidsize;
++ /* SMMU CMDQV extension */
++ OnOffAuto cmdqv;
+
+ Notifier machine_done;
+ };
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-common-Add-NSCFG-bit-definition-for-CD.patch b/kvm-hw-arm-smmuv3-common-Add-NSCFG-bit-definition-for-CD.patch
new file mode 100644
index 0000000..5b05a89
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-common-Add-NSCFG-bit-definition-for-CD.patch
@@ -0,0 +1,62 @@
+From 65ad5f09c955ddda26e37eab3178be5740f9aa27 Mon Sep 17 00:00:00 2001
+From: Tao Tang <tangtao1634@phytium.com.cn>
+Date: Sun, 21 Dec 2025 16:25:11 +0800
+Subject: [PATCH 018/111] hw/arm/smmuv3-common: Add NSCFG bit definition for CD
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [18/111] 881eb3ccb1c31e2207e8aa8b98d80fde6436cce3 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Add NSCFG bit definition for CD structure. This allows proper
+configuration of non-secure access settings in CD.
+
+Signed-off-by: Tao Tang <tangtao1634@phytium.com.cn>
+Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-ID: <20260119161112.3841386-5-tangtao1634@phytium.com.cn>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+(cherry picked from commit ee1c84ded10cf82674e494df4f6b92aef099e4fb)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ include/hw/arm/smmuv3-common.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index 90300ad61c..06ef6e7720 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -123,11 +123,13 @@ REG32(CD_1, 4)
+ FIELD(CD_1, A, 14, 1)
+ FIELD(CD_1, ASID, 16, 16)
+ REG32(CD_2, 8)
++ FIELD(CD_2, NSCFG0, 0, 1)
+ FIELD(CD_2, HAD0, 1, 1)
+ FIELD(CD_2, TTB0_LO, 4, 28)
+ REG32(CD_3, 12)
+ FIELD(CD_3, TTB0_HI, 0, 20)
+ REG32(CD_4, 16)
++ FIELD(CD_4, NSCFG1, 0, 1)
+ FIELD(CD_4, HAD1, 1, 1)
+ FIELD(CD_4, TTB1_LO, 4, 28)
+ REG32(CD_5, 20)
+@@ -155,6 +157,9 @@ REG32(CD_5, 20)
+ #define CD_R(x) FIELD_EX32((x)->word[1], CD_1, R)
+ #define CD_A(x) FIELD_EX32((x)->word[1], CD_1, A)
+ #define CD_ASID(x) FIELD_EX32((x)->word[1], CD_1, ASID)
++#define CD_NSCFG(x, sel) ((sel) ? \
++ FIELD_EX32((x)->word[4], CD_4, NSCFG1) : \
++ FIELD_EX32((x)->word[2], CD_2, NSCFG0))
+ #define CD_HAD(x, sel) ((sel) ? \
+ FIELD_EX32((x)->word[4], CD_4, HAD1) : \
+ FIELD_EX32((x)->word[2], CD_2, HAD0))
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-common-Add-STE-CD-set-helpers-for-repe.patch b/kvm-hw-arm-smmuv3-common-Add-STE-CD-set-helpers-for-repe.patch
new file mode 100644
index 0000000..23c97d9
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-common-Add-STE-CD-set-helpers-for-repe.patch
@@ -0,0 +1,132 @@
+From feef2df0075cedfa205ddad395c57cc09e928bee Mon Sep 17 00:00:00 2001
+From: Tao Tang <tangtao1634@phytium.com.cn>
+Date: Sun, 21 Dec 2025 16:28:00 +0800
+Subject: [PATCH 019/111] hw/arm/smmuv3-common: Add STE/CD set helpers for
+ repeated field setup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [19/111] d3b17fe755f5a98f7fee1bc231504fb44230d2a2 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+This change introduces STE_SET_* and CD_SET_* helpers to centralize and
+simplify repeated field setting logic.
+
+Signed-off-by: Tao Tang <tangtao1634@phytium.com.cn>
+Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-ID: <20260119161112.3841386-6-tangtao1634@phytium.com.cn>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+(cherry picked from commit 59a6b74aeb34c185e261a0cc8d0beb4591388422)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ include/hw/arm/smmuv3-common.h | 79 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 79 insertions(+)
+
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index 06ef6e7720..30101915e2 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -100,6 +100,37 @@ REG32(STE_7, 28)
+ #define STE_CFG_ABORT(config) (!(config & 0x4))
+ #define STE_CFG_BYPASS(config) (config == 0x4)
+
++/* Update STE fields */
++#define STE_SET_VALID(ste, v) \
++ ((ste)->word[0] = FIELD_DP32((ste)->word[0], STE_0, VALID, (v)))
++#define STE_SET_CONFIG(ste, v) \
++ ((ste)->word[0] = FIELD_DP32((ste)->word[0], STE_0, CONFIG, (v)))
++
++#define STE_SET_CTXPTR(ste, v) do { \
++ (ste)->word[0] = FIELD_DP32((ste)->word[0], STE_0, CTXPTR_LO, (v) >> 6); \
++ (ste)->word[1] = FIELD_DP32((ste)->word[1], STE_1, CTXPTR_HI, (v) >> 32); \
++} while (0)
++#define STE_SET_S2T0SZ(ste, v) \
++ ((ste)->word[5] = FIELD_DP32((ste)->word[5], STE_5, S2T0SZ, (v)))
++#define STE_SET_S2SL0(ste, v) \
++ ((ste)->word[5] = FIELD_DP32((ste)->word[5], STE_5, S2SL0, (v)))
++#define STE_SET_S2TG(ste, v) \
++ ((ste)->word[5] = FIELD_DP32((ste)->word[5], STE_5, S2TG, (v)))
++#define STE_SET_S2PS(ste, v) \
++ ((ste)->word[5] = FIELD_DP32((ste)->word[5], STE_5, S2PS, (v)))
++#define STE_SET_S2AA64(ste, v) \
++ ((ste)->word[5] = FIELD_DP32((ste)->word[5], STE_5, S2AA64, (v)))
++#define STE_SET_S2ENDI(ste, v) \
++ ((ste)->word[5] = FIELD_DP32((ste)->word[5], STE_5, S2ENDI, (v)))
++#define STE_SET_S2AFFD(ste, v) \
++ ((ste)->word[5] = FIELD_DP32((ste)->word[5], STE_5, S2AFFD, (v)))
++#define STE_SET_S2S(ste, v) \
++ ((ste)->word[5] = FIELD_DP32((ste)->word[5], STE_5, S2S, (v)))
++#define STE_SET_S2TTB(ste, v) do { \
++ (ste)->word[6] = FIELD_DP32((ste)->word[6], STE_6, S2TTB_LO, (v) >> 4); \
++ (ste)->word[7] = FIELD_DP32((ste)->word[7], STE_7, S2TTB_HI, (v) >> 32); \
++} while (0)
++
+ /* CD fields */
+
+ REG32(CD_0, 0)
+@@ -169,6 +200,54 @@ REG32(CD_5, 20)
+ (((uint64_t)FIELD_EX32((x)->word[3], CD_3, TTB0_HI) << 32) | \
+ ((uint64_t)FIELD_EX32((x)->word[2], CD_2, TTB0_LO) << 4)))
+
++/* Update CD fields */
++#define CD_SET_VALID(cd, v) \
++ ((cd)->word[0] = FIELD_DP32((cd)->word[0], CD_0, VALID, (v)))
++#define CD_SET_ASID(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, ASID, (v)))
++#define CD_SET_TTB(cd, sel, v) do { \
++ if (sel) { \
++ (cd)->word[4] = FIELD_DP32((cd)->word[4], CD_4, TTB1_LO, (v) >> 4); \
++ (cd)->word[5] = FIELD_DP32((cd)->word[5], CD_5, TTB1_HI, (v) >> 32); \
++ } else { \
++ (cd)->word[2] = FIELD_DP32((cd)->word[2], CD_2, TTB0_LO, (v) >> 4); \
++ (cd)->word[3] = FIELD_DP32((cd)->word[3], CD_3, TTB0_HI, (v) >> 32); \
++ } \
++} while (0)
++
++#define CD_SET_TSZ(cd, sel, v) \
++ ((cd)->word[0] = (sel) ? FIELD_DP32((cd)->word[0], CD_0, TSZ1, (v)) : \
++ FIELD_DP32((cd)->word[0], CD_0, TSZ0, (v)))
++#define CD_SET_TG(cd, sel, v) \
++ ((cd)->word[0] = (sel) ? FIELD_DP32((cd)->word[0], CD_0, TG1, (v)) : \
++ FIELD_DP32((cd)->word[0], CD_0, TG0, (v)))
++#define CD_SET_EPD(cd, sel, v) \
++ ((cd)->word[0] = (sel) ? FIELD_DP32((cd)->word[0], CD_0, EPD1, (v)) : \
++ FIELD_DP32((cd)->word[0], CD_0, EPD0, (v)))
++#define CD_SET_ENDI(cd, v) \
++ ((cd)->word[0] = FIELD_DP32((cd)->word[0], CD_0, ENDI, (v)))
++#define CD_SET_IPS(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, IPS, (v)))
++#define CD_SET_AFFD(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, AFFD, (v)))
++#define CD_SET_TBI(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, TBI, (v)))
++#define CD_SET_HD(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, HD, (v)))
++#define CD_SET_HA(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, HA, (v)))
++#define CD_SET_S(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, S, (v)))
++#define CD_SET_R(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, R, (v)))
++#define CD_SET_A(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, A, (v)))
++#define CD_SET_AARCH64(cd, v) \
++ ((cd)->word[1] = FIELD_DP32((cd)->word[1], CD_1, AARCH64, (v)))
++#define CD_SET_NSCFG(cd, sel, v) \
++ ((sel) ? ((cd)->word[4] = FIELD_DP32((cd)->word[4], CD_4, NSCFG1, (v))) : \
++ ((cd)->word[2] = FIELD_DP32((cd)->word[2], CD_2, NSCFG0, (v))))
++
+ /* MMIO Registers */
+
+ REG32(IDR0, 0x0)
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-common-Define-STE-CD-fields-via-regist.patch b/kvm-hw-arm-smmuv3-common-Define-STE-CD-fields-via-regist.patch
new file mode 100644
index 0000000..48cd5d9
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-common-Define-STE-CD-fields-via-regist.patch
@@ -0,0 +1,235 @@
+From dade45312b53d2bf2bb29337eaff362816c7e119 Mon Sep 17 00:00:00 2001
+From: Tao Tang <tangtao1634@phytium.com.cn>
+Date: Sun, 21 Dec 2025 12:46:12 +0800
+Subject: [PATCH 017/111] hw/arm/smmuv3-common: Define STE/CD fields via
+ registerfields
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [17/111] c466c568db1c9242dd6eecd772c6aeb69277bd5e (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Conflicts: replace hw/core/registerfields.h by former
+ hw/registerfields.h because we don't have
+3e7316044d9c include: move hw/registerfields.h to hw/core/
+
+Switch STE/CD bitfield definitions and accessors to the
+'registerfields.h' REG/FIELD API.
+
+Signed-off-by: Tao Tang <tangtao1634@phytium.com.cn>
+Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-ID: <20260119161112.3841386-3-tangtao1634@phytium.com.cn>
+[PMD: Updated STE::CTXPTR_HI, STE::S2TTB_HI and CD:TTBx_HI lengths]
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+(cherry picked from commit 0a50d06fa1dd5425077c71f223ef29be9b36fe45)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ include/hw/arm/smmuv3-common.h | 169 +++++++++++++++++++++++----------
+ 1 file changed, 120 insertions(+), 49 deletions(-)
+
+diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h
+index 9da817f41a..90300ad61c 100644
+--- a/include/hw/arm/smmuv3-common.h
++++ b/include/hw/arm/smmuv3-common.h
+@@ -11,6 +11,8 @@
+ #ifndef HW_ARM_SMMUV3_COMMON_H
+ #define HW_ARM_SMMUV3_COMMON_H
+
++#include "hw/registerfields.h"
++
+ /* Configuration Data */
+
+ /* STE Level 1 Descriptor */
+@@ -35,63 +37,132 @@ typedef struct CD {
+
+ /* STE fields */
+
+-#define STE_VALID(x) extract32((x)->word[0], 0, 1)
++REG32(STE_0, 0)
++ FIELD(STE_0, VALID, 0, 1)
++ FIELD(STE_0, CONFIG, 1, 3)
++ FIELD(STE_0, S1FMT, 4, 2)
++ FIELD(STE_0, CTXPTR_LO, 6, 26)
++REG32(STE_1, 4)
++ FIELD(STE_1, CTXPTR_HI, 0, 24)
++ FIELD(STE_1, S1CDMAX, 27, 5)
++REG32(STE_2, 8)
++ FIELD(STE_2, S1STALLD, 27, 1)
++ FIELD(STE_2, EATS, 28, 2)
++ FIELD(STE_2, STRW, 30, 2)
++REG32(STE_4, 16)
++ FIELD(STE_4, S2VMID, 0, 16)
++REG32(STE_5, 20)
++ FIELD(STE_5, S2T0SZ, 0, 6)
++ FIELD(STE_5, S2SL0, 6, 2)
++ FIELD(STE_5, S2TG, 14, 2)
++ FIELD(STE_5, S2PS, 16, 3)
++ FIELD(STE_5, S2AA64, 19, 1)
++ FIELD(STE_5, S2ENDI, 20, 1)
++ FIELD(STE_5, S2AFFD, 21, 1)
++ FIELD(STE_5, S2HD, 23, 1)
++ FIELD(STE_5, S2HA, 24, 1)
++ FIELD(STE_5, S2S, 25, 1)
++ FIELD(STE_5, S2R, 26, 1)
++REG32(STE_6, 24)
++ FIELD(STE_6, S2TTB_LO, 4, 28)
++REG32(STE_7, 28)
++ FIELD(STE_7, S2TTB_HI, 0, 20)
++
++/* Get STE fields */
++#define STE_VALID(x) FIELD_EX32((x)->word[0], STE_0, VALID)
++#define STE_CONFIG(x) FIELD_EX32((x)->word[0], STE_0, CONFIG)
++#define STE_S1FMT(x) FIELD_EX32((x)->word[0], STE_0, S1FMT)
++#define STE_CTXPTR(x) \
++ (((uint64_t)FIELD_EX32((x)->word[0], STE_0, CTXPTR_LO) << 6) | \
++ ((uint64_t)FIELD_EX32((x)->word[1], STE_1, CTXPTR_HI) << 32))
++#define STE_S1CDMAX(x) FIELD_EX32((x)->word[1], STE_1, S1CDMAX)
++#define STE_S1STALLD(x) FIELD_EX32((x)->word[2], STE_2, S1STALLD)
++#define STE_EATS(x) FIELD_EX32((x)->word[2], STE_2, EATS)
++#define STE_STRW(x) FIELD_EX32((x)->word[2], STE_2, STRW)
++#define STE_S2VMID(x) FIELD_EX32((x)->word[4], STE_4, S2VMID)
++#define STE_S2T0SZ(x) FIELD_EX32((x)->word[5], STE_5, S2T0SZ)
++#define STE_S2SL0(x) FIELD_EX32((x)->word[5], STE_5, S2SL0)
++#define STE_S2TG(x) FIELD_EX32((x)->word[5], STE_5, S2TG)
++#define STE_S2PS(x) FIELD_EX32((x)->word[5], STE_5, S2PS)
++#define STE_S2AA64(x) FIELD_EX32((x)->word[5], STE_5, S2AA64)
++#define STE_S2ENDI(x) FIELD_EX32((x)->word[5], STE_5, S2ENDI)
++#define STE_S2AFFD(x) FIELD_EX32((x)->word[5], STE_5, S2AFFD)
++#define STE_S2HD(x) FIELD_EX32((x)->word[5], STE_5, S2HD)
++#define STE_S2HA(x) FIELD_EX32((x)->word[5], STE_5, S2HA)
++#define STE_S2S(x) FIELD_EX32((x)->word[5], STE_5, S2S)
++#define STE_S2R(x) FIELD_EX32((x)->word[5], STE_5, S2R)
++#define STE_S2TTB(x) \
++ (((uint64_t)FIELD_EX32((x)->word[6], STE_6, S2TTB_LO) << 4) | \
++ ((uint64_t)FIELD_EX32((x)->word[7], STE_7, S2TTB_HI) << 32))
+
+-#define STE_CONFIG(x) extract32((x)->word[0], 1, 3)
+ #define STE_CFG_S1_ENABLED(config) (config & 0x1)
+ #define STE_CFG_S2_ENABLED(config) (config & 0x2)
+ #define STE_CFG_ABORT(config) (!(config & 0x4))
+ #define STE_CFG_BYPASS(config) (config == 0x4)
+
+-#define STE_S1FMT(x) extract32((x)->word[0], 4 , 2)
+-#define STE_S1CDMAX(x) extract32((x)->word[1], 27, 5)
+-#define STE_S1STALLD(x) extract32((x)->word[2], 27, 1)
+-#define STE_EATS(x) extract32((x)->word[2], 28, 2)
+-#define STE_STRW(x) extract32((x)->word[2], 30, 2)
+-#define STE_S2VMID(x) extract32((x)->word[4], 0 , 16)
+-#define STE_S2T0SZ(x) extract32((x)->word[5], 0 , 6)
+-#define STE_S2SL0(x) extract32((x)->word[5], 6 , 2)
+-#define STE_S2TG(x) extract32((x)->word[5], 14, 2)
+-#define STE_S2PS(x) extract32((x)->word[5], 16, 3)
+-#define STE_S2AA64(x) extract32((x)->word[5], 19, 1)
+-#define STE_S2ENDI(x) extract32((x)->word[5], 20, 1)
+-#define STE_S2AFFD(x) extract32((x)->word[5], 21, 1)
+-#define STE_S2HD(x) extract32((x)->word[5], 23, 1)
+-#define STE_S2HA(x) extract32((x)->word[5], 24, 1)
+-#define STE_S2S(x) extract32((x)->word[5], 25, 1)
+-#define STE_S2R(x) extract32((x)->word[5], 26, 1)
+-
+-#define STE_CTXPTR(x) \
+- ((extract64((x)->word[1], 0, 16) << 32) | \
+- ((x)->word[0] & 0xffffffc0))
+-
+-#define STE_S2TTB(x) \
+- ((extract64((x)->word[7], 0, 16) << 32) | \
+- ((x)->word[6] & 0xfffffff0))
+-
+ /* CD fields */
+
+-#define CD_VALID(x) extract32((x)->word[0], 31, 1)
+-#define CD_ASID(x) extract32((x)->word[1], 16, 16)
+-#define CD_TTB(x, sel) \
+- ((extract64((x)->word[(sel) * 2 + 3], 0, 19) << 32) | \
+- ((x)->word[(sel) * 2 + 2] & ~0xfULL))
+-
+-#define CD_HAD(x, sel) extract32((x)->word[(sel) * 2 + 2], 1, 1)
+-
+-#define CD_TSZ(x, sel) extract32((x)->word[0], (16 * (sel)) + 0, 6)
+-#define CD_TG(x, sel) extract32((x)->word[0], (16 * (sel)) + 6, 2)
+-#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
+-#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
+-#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
+-#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
+-#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
+-#define CD_HD(x) extract32((x)->word[1], 10 , 1)
+-#define CD_HA(x) extract32((x)->word[1], 11 , 1)
+-#define CD_S(x) extract32((x)->word[1], 12, 1)
+-#define CD_R(x) extract32((x)->word[1], 13, 1)
+-#define CD_A(x) extract32((x)->word[1], 14, 1)
+-#define CD_AARCH64(x) extract32((x)->word[1], 9 , 1)
++REG32(CD_0, 0)
++ FIELD(CD_0, TSZ0, 0, 6)
++ FIELD(CD_0, TG0, 6, 2)
++ FIELD(CD_0, EPD0, 14, 1)
++ FIELD(CD_0, ENDI, 15, 1)
++ FIELD(CD_0, TSZ1, 16, 6)
++ FIELD(CD_0, TG1, 22, 2)
++ FIELD(CD_0, EPD1, 30, 1)
++ FIELD(CD_0, VALID, 31, 1)
++REG32(CD_1, 4)
++ FIELD(CD_1, IPS, 0, 3)
++ FIELD(CD_1, AFFD, 3, 1)
++ FIELD(CD_1, TBI, 6, 2)
++ FIELD(CD_1, AARCH64, 9, 1)
++ FIELD(CD_1, HD, 10, 1)
++ FIELD(CD_1, HA, 11, 1)
++ FIELD(CD_1, S, 12, 1)
++ FIELD(CD_1, R, 13, 1)
++ FIELD(CD_1, A, 14, 1)
++ FIELD(CD_1, ASID, 16, 16)
++REG32(CD_2, 8)
++ FIELD(CD_2, HAD0, 1, 1)
++ FIELD(CD_2, TTB0_LO, 4, 28)
++REG32(CD_3, 12)
++ FIELD(CD_3, TTB0_HI, 0, 20)
++REG32(CD_4, 16)
++ FIELD(CD_4, HAD1, 1, 1)
++ FIELD(CD_4, TTB1_LO, 4, 28)
++REG32(CD_5, 20)
++ FIELD(CD_5, TTB1_HI, 0, 20)
++
++/* Get CD fields */
++#define CD_TSZ(x, sel) ((sel) ? \
++ FIELD_EX32((x)->word[0], CD_0, TSZ1) : \
++ FIELD_EX32((x)->word[0], CD_0, TSZ0))
++#define CD_TG(x, sel) ((sel) ? \
++ FIELD_EX32((x)->word[0], CD_0, TG1) : \
++ FIELD_EX32((x)->word[0], CD_0, TG0))
++#define CD_EPD(x, sel) ((sel) ? \
++ FIELD_EX32((x)->word[0], CD_0, EPD1) : \
++ FIELD_EX32((x)->word[0], CD_0, EPD0))
++#define CD_ENDI(x) FIELD_EX32((x)->word[0], CD_0, ENDI)
++#define CD_VALID(x) FIELD_EX32((x)->word[0], CD_0, VALID)
++#define CD_IPS(x) FIELD_EX32((x)->word[1], CD_1, IPS)
++#define CD_AFFD(x) FIELD_EX32((x)->word[1], CD_1, AFFD)
++#define CD_TBI(x) FIELD_EX32((x)->word[1], CD_1, TBI)
++#define CD_AARCH64(x) FIELD_EX32((x)->word[1], CD_1, AARCH64)
++#define CD_HD(x) FIELD_EX32((x)->word[1], CD_1, HD)
++#define CD_HA(x) FIELD_EX32((x)->word[1], CD_1, HA)
++#define CD_S(x) FIELD_EX32((x)->word[1], CD_1, S)
++#define CD_R(x) FIELD_EX32((x)->word[1], CD_1, R)
++#define CD_A(x) FIELD_EX32((x)->word[1], CD_1, A)
++#define CD_ASID(x) FIELD_EX32((x)->word[1], CD_1, ASID)
++#define CD_HAD(x, sel) ((sel) ? \
++ FIELD_EX32((x)->word[4], CD_4, HAD1) : \
++ FIELD_EX32((x)->word[2], CD_2, HAD0))
++#define CD_TTB(x, sel) \
++ ((sel) ? (((uint64_t)FIELD_EX32((x)->word[5], CD_5, TTB1_HI) << 32) | \
++ ((uint64_t)FIELD_EX32((x)->word[4], CD_4, TTB1_LO) << 4)) : \
++ (((uint64_t)FIELD_EX32((x)->word[3], CD_3, TTB0_HI) << 32) | \
++ ((uint64_t)FIELD_EX32((x)->word[2], CD_2, TTB0_LO) << 4)))
+
+ /* MMIO Registers */
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-smmuv3-propagate-smmuv3_cmdq_consume-errors-t.patch b/kvm-hw-arm-smmuv3-propagate-smmuv3_cmdq_consume-errors-t.patch
new file mode 100644
index 0000000..a9453ce
--- /dev/null
+++ b/kvm-hw-arm-smmuv3-propagate-smmuv3_cmdq_consume-errors-t.patch
@@ -0,0 +1,205 @@
+From c57870a0ab4ec54fd7d5e9527a72e709d7416589 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 021/111] hw/arm/smmuv3: propagate smmuv3_cmdq_consume() errors
+ to caller
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [21/111] d548a7201d043a4e0e8ade5c10a3f19ca03357cc (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+smmuv3_cmdq_consume() is updated to return detailed errors via errp.
+
+Although this is currently a no-op, it prepares the ground for accel
+SMMUv3 specific command handling where proper error reporting will be
+useful.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-14-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 95d855167af43e958903f29430f563205b8b2afd)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3.c | 67 +++++++++++++++++++++++++++----------------------
+ 1 file changed, 37 insertions(+), 30 deletions(-)
+
+diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
+index ef991cb7d8..374ae08baa 100644
+--- a/hw/arm/smmuv3.c
++++ b/hw/arm/smmuv3.c
+@@ -1279,7 +1279,7 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cmd, SMMUStage stage)
+ }
+ }
+
+-static int smmuv3_cmdq_consume(SMMUv3State *s)
++static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp)
+ {
+ SMMUState *bs = ARM_SMMU(s);
+ SMMUCmdError cmd_error = SMMU_CERROR_NONE;
+@@ -1547,42 +1547,44 @@ static MemTxResult smmu_writell(SMMUv3State *s, hwaddr offset,
+ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
+ uint64_t data, MemTxAttrs attrs)
+ {
++ Error *local_err = NULL;
++
+ switch (offset) {
+ case A_CR0:
+ s->cr[0] = data;
+ s->cr0ack = data & ~SMMU_CR0_RESERVED;
+ /* in case the command queue has been enabled */
+- smmuv3_cmdq_consume(s);
+- return MEMTX_OK;
++ smmuv3_cmdq_consume(s, &local_err);
++ break;
+ case A_CR1:
+ s->cr[1] = data;
+- return MEMTX_OK;
++ break;
+ case A_CR2:
+ s->cr[2] = data;
+- return MEMTX_OK;
++ break;
+ case A_IRQ_CTRL:
+ s->irq_ctrl = data;
+- return MEMTX_OK;
++ break;
+ case A_GERRORN:
+ smmuv3_write_gerrorn(s, data);
+ /*
+ * By acknowledging the CMDQ_ERR, SW may notify cmds can
+ * be processed again
+ */
+- smmuv3_cmdq_consume(s);
+- return MEMTX_OK;
++ smmuv3_cmdq_consume(s, &local_err);
++ break;
+ case A_GERROR_IRQ_CFG0: /* 64b */
+ s->gerror_irq_cfg0 = deposit64(s->gerror_irq_cfg0, 0, 32, data);
+- return MEMTX_OK;
++ break;
+ case A_GERROR_IRQ_CFG0 + 4:
+ s->gerror_irq_cfg0 = deposit64(s->gerror_irq_cfg0, 32, 32, data);
+- return MEMTX_OK;
++ break;
+ case A_GERROR_IRQ_CFG1:
+ s->gerror_irq_cfg1 = data;
+- return MEMTX_OK;
++ break;
+ case A_GERROR_IRQ_CFG2:
+ s->gerror_irq_cfg2 = data;
+- return MEMTX_OK;
++ break;
+ case A_GBPA:
+ /*
+ * If UPDATE is not set, the write is ignored. This is the only
+@@ -1592,71 +1594,76 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
+ /* Ignore update bit as write is synchronous. */
+ s->gbpa = data & ~R_GBPA_UPDATE_MASK;
+ }
+- return MEMTX_OK;
++ break;
+ case A_STRTAB_BASE: /* 64b */
+ s->strtab_base = deposit64(s->strtab_base, 0, 32, data);
+- return MEMTX_OK;
++ break;
+ case A_STRTAB_BASE + 4:
+ s->strtab_base = deposit64(s->strtab_base, 32, 32, data);
+- return MEMTX_OK;
++ break;
+ case A_STRTAB_BASE_CFG:
+ s->strtab_base_cfg = data;
+ if (FIELD_EX32(data, STRTAB_BASE_CFG, FMT) == 1) {
+ s->sid_split = FIELD_EX32(data, STRTAB_BASE_CFG, SPLIT);
+ s->features |= SMMU_FEATURE_2LVL_STE;
+ }
+- return MEMTX_OK;
++ break;
+ case A_CMDQ_BASE: /* 64b */
+ s->cmdq.base = deposit64(s->cmdq.base, 0, 32, data);
+ s->cmdq.log2size = extract64(s->cmdq.base, 0, 5);
+ if (s->cmdq.log2size > SMMU_CMDQS) {
+ s->cmdq.log2size = SMMU_CMDQS;
+ }
+- return MEMTX_OK;
++ break;
+ case A_CMDQ_BASE + 4: /* 64b */
+ s->cmdq.base = deposit64(s->cmdq.base, 32, 32, data);
+- return MEMTX_OK;
++ break;
+ case A_CMDQ_PROD:
+ s->cmdq.prod = data;
+- smmuv3_cmdq_consume(s);
+- return MEMTX_OK;
++ smmuv3_cmdq_consume(s, &local_err);
++ break;
+ case A_CMDQ_CONS:
+ s->cmdq.cons = data;
+- return MEMTX_OK;
++ break;
+ case A_EVENTQ_BASE: /* 64b */
+ s->eventq.base = deposit64(s->eventq.base, 0, 32, data);
+ s->eventq.log2size = extract64(s->eventq.base, 0, 5);
+ if (s->eventq.log2size > SMMU_EVENTQS) {
+ s->eventq.log2size = SMMU_EVENTQS;
+ }
+- return MEMTX_OK;
++ break;
+ case A_EVENTQ_BASE + 4:
+ s->eventq.base = deposit64(s->eventq.base, 32, 32, data);
+- return MEMTX_OK;
++ break;
+ case A_EVENTQ_PROD:
+ s->eventq.prod = data;
+- return MEMTX_OK;
++ break;
+ case A_EVENTQ_CONS:
+ s->eventq.cons = data;
+- return MEMTX_OK;
++ break;
+ case A_EVENTQ_IRQ_CFG0: /* 64b */
+ s->eventq_irq_cfg0 = deposit64(s->eventq_irq_cfg0, 0, 32, data);
+- return MEMTX_OK;
++ break;
+ case A_EVENTQ_IRQ_CFG0 + 4:
+ s->eventq_irq_cfg0 = deposit64(s->eventq_irq_cfg0, 32, 32, data);
+- return MEMTX_OK;
++ break;
+ case A_EVENTQ_IRQ_CFG1:
+ s->eventq_irq_cfg1 = data;
+- return MEMTX_OK;
++ break;
+ case A_EVENTQ_IRQ_CFG2:
+ s->eventq_irq_cfg2 = data;
+- return MEMTX_OK;
++ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s Unexpected 32-bit access to 0x%"PRIx64" (WI)\n",
+ __func__, offset);
+- return MEMTX_OK;
++ break;
+ }
++
++ if (local_err) {
++ error_report_err(local_err);
++ }
++ return MEMTX_OK;
+ }
+
+ static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Add-Tegra241-CMDQV-ops-backend.patch b/kvm-hw-arm-tegra241-cmdqv-Add-Tegra241-CMDQV-ops-backend.patch
new file mode 100644
index 0000000..60b784d
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Add-Tegra241-CMDQV-ops-backend.patch
@@ -0,0 +1,194 @@
+From 47e539f1cfed8264f2fb82a169598e2dc7d73e61 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:28 +0100
+Subject: [PATCH 086/111] hw/arm/tegra241-cmdqv: Add Tegra241 CMDQV ops backend
+ stub
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [86/111] 516b341a36eced6dbaab054d06afb4c57f78eda4 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Conflicts: contextual conflict in hw/arm/Kconfig as we don't have
+FSL_IMX8MM FSL_IMX8MM_EVK configs
+
+Introduce a Tegra241 CMDQV backend that plugs into the SMMUv3 accelerated
+CMDQV ops interface.
+
+This patch wires up the Tegra241 CMDQV backend and provides a stub
+implementation for CMDQV probe, initialization, vIOMMU allocation
+and reset handling.
+
+Functional CMDQV support is added in follow-up patches.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-8-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit bc2fd5ce6ca0f06559c5f9c4f682642ec9d20b25)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/Kconfig | 5 ++++
+ hw/arm/meson.build | 2 ++
+ hw/arm/tegra241-cmdqv-stubs.c | 16 ++++++++++
+ hw/arm/tegra241-cmdqv.c | 56 +++++++++++++++++++++++++++++++++++
+ hw/arm/tegra241-cmdqv.h | 15 ++++++++++
+ 5 files changed, 94 insertions(+)
+ create mode 100644 hw/arm/tegra241-cmdqv-stubs.c
+ create mode 100644 hw/arm/tegra241-cmdqv.c
+ create mode 100644 hw/arm/tegra241-cmdqv.h
+
+diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
+index 1f49550c61..f7bdcfdc83 100644
+--- a/hw/arm/Kconfig
++++ b/hw/arm/Kconfig
+@@ -622,6 +622,10 @@ config FSL_IMX8MP_EVK
+ depends on TCG && AARCH64
+ select FSL_IMX8MP
+
++config TEGRA241_CMDQV
++ bool
++ depends on ARM_SMMUV3_ACCEL
++
+ config ARM_SMMUV3_ACCEL
+ bool
+ depends on ARM_SMMUV3
+@@ -629,6 +633,7 @@ config ARM_SMMUV3_ACCEL
+ config ARM_SMMUV3
+ bool
+ select ARM_SMMUV3_ACCEL if IOMMUFD
++ imply TEGRA241_CMDQV
+
+ config FSL_IMX6UL
+ bool
+diff --git a/hw/arm/meson.build b/hw/arm/meson.build
+index b3f2e4d5dd..18b96b657c 100644
+--- a/hw/arm/meson.build
++++ b/hw/arm/meson.build
+@@ -64,6 +64,8 @@ arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP_EVK', if_true: files('imx8mp-evk.c'))
+ arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
+ arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3_ACCEL', if_true: files('smmuv3-accel.c'))
+ stub_ss.add(files('smmuv3-accel-stubs.c'))
++arm_common_ss.add(when: 'CONFIG_TEGRA241_CMDQV', if_true: files('tegra241-cmdqv.c'))
++stub_ss.add(files('tegra241-cmdqv-stubs.c'))
+ arm_common_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
+ arm_common_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
+ arm_ss.add(when: 'CONFIG_XEN', if_true: files(
+diff --git a/hw/arm/tegra241-cmdqv-stubs.c b/hw/arm/tegra241-cmdqv-stubs.c
+new file mode 100644
+index 0000000000..4669f5c5f5
+--- /dev/null
++++ b/hw/arm/tegra241-cmdqv-stubs.c
+@@ -0,0 +1,16 @@
++/*
++ * Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved
++ *
++ * Stubs for Tegra241 CMDQ-Virtualization extension for SMMUv3
++ *
++ * SPDX-License-Identifier: GPL-2.0-or-later
++ */
++
++#include "qemu/osdep.h"
++#include "smmuv3-accel.h"
++#include "hw/arm/tegra241-cmdqv.h"
++
++const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void)
++{
++ return NULL;
++}
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+new file mode 100644
+index 0000000000..ad5a0d4611
+--- /dev/null
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved
++ * NVIDIA Tegra241 CMDQ-Virtualization extension for SMMUv3
++ *
++ * Written by Nicolin Chen, Shameer Kolothum
++ *
++ * SPDX-License-Identifier: GPL-2.0-or-later
++ */
++
++#include "qemu/osdep.h"
++
++#include "hw/arm/smmuv3.h"
++#include "smmuv3-accel.h"
++#include "tegra241-cmdqv.h"
++
++static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
++{
++}
++
++static bool
++tegra241_cmdqv_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
++ uint32_t *out_viommu_id, Error **errp)
++{
++ error_setg(errp, "NVIDIA Tegra241 CMDQV is unsupported");
++ return false;
++}
++
++static void tegra241_cmdqv_reset(SMMUv3State *s)
++{
++}
++
++static bool tegra241_cmdqv_init(SMMUv3State *s, Error **errp)
++{
++ error_setg(errp, "NVIDIA Tegra241 CMDQV is unsupported");
++ return false;
++}
++
++static bool tegra241_cmdqv_probe(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
++ Error **errp)
++{
++ error_setg(errp, "NVIDIA Tegra241 CMDQV is unsupported");
++ return false;
++}
++
++static const SMMUv3AccelCmdqvOps tegra241_cmdqv_ops = {
++ .probe = tegra241_cmdqv_probe,
++ .init = tegra241_cmdqv_init,
++ .alloc_viommu = tegra241_cmdqv_alloc_viommu,
++ .free_viommu = tegra241_cmdqv_free_viommu,
++ .reset = tegra241_cmdqv_reset,
++};
++
++const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void)
++{
++ return &tegra241_cmdqv_ops;
++}
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+new file mode 100644
+index 0000000000..74a6954017
+--- /dev/null
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -0,0 +1,15 @@
++/*
++ * Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved
++ * NVIDIA Tegra241 CMDQ-Virtualization extension for SMMUv3
++ *
++ * Written by Nicolin Chen, Shameer Kolothum
++ *
++ * SPDX-License-Identifier: GPL-2.0-or-later
++ */
++
++#ifndef HW_ARM_TEGRA241_CMDQV_H
++#define HW_ARM_TEGRA241_CMDQV_H
++
++const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
++
++#endif /* HW_ARM_TEGRA241_CMDQV_H */
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Allocate-HW-VCMDQs-once-config.patch b/kvm-hw-arm-tegra241-cmdqv-Allocate-HW-VCMDQs-once-config.patch
new file mode 100644
index 0000000..f09c802
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Allocate-HW-VCMDQs-once-config.patch
@@ -0,0 +1,390 @@
+From 829d4bd1b7a39838071d95fb93bb3fc46f09fd8d Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:39 +0100
+Subject: [PATCH 097/111] hw/arm/tegra241-cmdqv: Allocate HW VCMDQs once
+ configured
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [97/111] 8926f87f22c76e5fbeae87f101d325f2b902e245 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Add support for allocating IOMMUFD hardware queues when the guest
+programs the VCMDQ BASE registers.
+
+VCMDQ_EN lives in VCMDQ_CONFIG, which is on the VINTF Page0 region
+that a later patch installs into guest MMIO — so QEMU won't trap its
+writes. Allocate the hardware queue instead once all of these are
+set: BASE programmed, CMDQ_ALLOC_MAP.ALLOC, and CMDQV / VINTF
+enabled. Each precondition write retries the allocation, so the
+guest may program them in any order.
+
+iommufd_backend_alloc_hw_queue() needs the guest physical address of
+the VCMDQ ring buffer, so allocation is deferred until the guest has
+populated BASE.
+
+If a hardware queue was previously allocated for the same VCMDQ,
+free it before reallocation. All allocated VCMDQs are freed when
+CMDQV or VINTF is disabled, when the ALLOC bit is cleared, or on reset.
+
+On allocation failure, set CMDQ_INIT_ERR and clear CMDQ_EN_OK in the
+cache so trapped guest reads see the failure rather than a queue
+that looks live. Clear them on a later successful allocation. A guest
+CMDQ_EN write then sets CMDQ_EN_OK only if CMDQ_INIT_ERR is clear.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-19-skolothumtho@nvidia.com
+Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 68336529877af422c0d7c087432998d69af5384f)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 171 +++++++++++++++++++++++++++++++++++++---
+ hw/arm/tegra241-cmdqv.h | 11 +++
+ 2 files changed, 171 insertions(+), 11 deletions(-)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 1f3d883cfe..8cb39e87c4 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -16,6 +16,96 @@
+ #include "tegra241-cmdqv.h"
+ #include "trace.h"
+
++static void tegra241_cmdqv_free_vcmdq(Tegra241CMDQV *cmdqv, int index)
++{
++ IOMMUFDViommu *viommu = cmdqv->s_accel->viommu;
++ IOMMUFDHWqueue *vcmdq = cmdqv->vcmdq[index];
++
++ if (!vcmdq) {
++ return;
++ }
++ iommufd_backend_free_id(viommu->iommufd, vcmdq->hw_queue_id);
++ g_free(vcmdq);
++ cmdqv->vcmdq[index] = NULL;
++}
++
++/*
++ * A VCMDQ's HW queue can be allocated once the guest has programmed:
++ * - VCMDQ_BASE (ring buffer GPA and size). This only checks that BASE is
++ * non-zero, not that both the _L and _H halves have been written; a
++ * half-written BASE may pass here, but the write of the second half
++ * re-runs setup and reallocates with the complete address.
++ * - the VINTF mapping (CMDQ_ALLOC_MAP.ALLOC).
++ * - both the CMDQV global enable and the VINTF enable.
++ */
++static bool tegra241_cmdqv_vcmdq_ready_to_alloc(Tegra241CMDQV *cmdqv, int index)
++{
++ return cmdqv->vcmdq_base[index] &&
++ (cmdqv->cmdq_alloc_map[index] & R_CMDQ_ALLOC_MAP_0_ALLOC_MASK) &&
++ tegra241_cmdqv_enabled(cmdqv) && tegra241_vintf_enabled(cmdqv);
++}
++
++/*
++ * Allocate a host HW VCMDQ from the current cached BASE / size for @index.
++ * No-op (returns true) until the VCMDQ is ready to be allocated.
++ */
++static bool tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
++ Error **errp)
++{
++ SMMUv3AccelState *accel = cmdqv->s_accel;
++ uint64_t base_mask = (uint64_t)R_VCMDQ0_BASE_L_ADDR_MASK |
++ (uint64_t)R_VCMDQ0_BASE_H_ADDR_MASK << 32;
++ uint64_t addr = cmdqv->vcmdq_base[index] & base_mask;
++ uint64_t log2 = cmdqv->vcmdq_base[index] & R_VCMDQ0_BASE_L_LOG2SIZE_MASK;
++ uint64_t size = 1ULL << (log2 + 4);
++ IOMMUFDViommu *viommu = accel->viommu;
++ IOMMUFDHWqueue *hw_queue;
++ uint32_t hw_queue_id;
++
++ if (!tegra241_cmdqv_vcmdq_ready_to_alloc(cmdqv, index)) {
++ return true;
++ }
++
++ tegra241_cmdqv_free_vcmdq(cmdqv, index);
++
++ if (!iommufd_backend_alloc_hw_queue(viommu->iommufd, viommu->viommu_id,
++ IOMMU_HW_QUEUE_TYPE_TEGRA241_CMDQV,
++ index, addr, size, &hw_queue_id,
++ errp)) {
++ /* Record the failure in the cache. */
++ cmdqv->vcmdq_gerror[index] |= R_VCMDQ0_GERROR_CMDQ_INIT_ERR_MASK;
++ cmdqv->vcmdq_status[index] &= ~R_VCMDQ0_STATUS_CMDQ_EN_OK_MASK;
++ return false;
++ }
++ hw_queue = g_new(IOMMUFDHWqueue, 1);
++ hw_queue->hw_queue_id = hw_queue_id;
++ hw_queue->viommu = viommu;
++ cmdqv->vcmdq[index] = hw_queue;
++
++ cmdqv->vcmdq_gerror[index] &= ~R_VCMDQ0_GERROR_CMDQ_INIT_ERR_MASK;
++ cmdqv->vcmdq_status[index] |= R_VCMDQ0_STATUS_CMDQ_EN_OK_MASK;
++
++ return true;
++}
++
++static void tegra241_cmdqv_free_all_vcmdq(Tegra241CMDQV *cmdqv)
++{
++ /* uapi/linux/iommufd.h: hw_queue destroy must be in descending @index. */
++ for (int i = (TEGRA241_CMDQV_MAX_CMDQ - 1); i >= 0; i--) {
++ tegra241_cmdqv_free_vcmdq(cmdqv, i);
++ }
++}
++
++static void tegra241_cmdqv_setup_all_vcmdq(Tegra241CMDQV *cmdqv,
++ Error **errp)
++{
++ for (int i = 0; i < TEGRA241_CMDQV_MAX_CMDQ; i++) {
++ if (!tegra241_cmdqv_setup_vcmdq(cmdqv, i, errp)) {
++ return;
++ }
++ }
++}
++
+ /*
+ * Read a VCMDQ Page 0 register (control/status) using VCMDQ0_* offsets.
+ *
+@@ -143,7 +233,12 @@ static void tegra241_cmdqv_write_vcmdq_page0(Tegra241CMDQV *cmdqv,
+ break;
+ case A_VCMDQ0_CONFIG:
+ if (value & R_VCMDQ0_CONFIG_CMDQ_EN_MASK) {
+- cmdqv->vcmdq_status[index] |= R_VCMDQ0_STATUS_CMDQ_EN_OK_MASK;
++ /* Report init error if any. */
++ if (!(cmdqv->vcmdq_gerror[index] &
++ R_VCMDQ0_GERROR_CMDQ_INIT_ERR_MASK)) {
++ cmdqv->vcmdq_status[index] |=
++ R_VCMDQ0_STATUS_CMDQ_EN_OK_MASK;
++ }
+ } else {
+ cmdqv->vcmdq_status[index] &= ~R_VCMDQ0_STATUS_CMDQ_EN_OK_MASK;
+ }
+@@ -167,16 +262,19 @@ static void tegra241_cmdqv_write_vcmdq_page0(Tegra241CMDQV *cmdqv,
+ */
+ static void tegra241_cmdqv_write_vcmdq_page1(Tegra241CMDQV *cmdqv,
+ hwaddr offset0, int index,
+- uint32_t value, bool direct)
++ uint32_t value, bool direct,
++ Error **errp)
+ {
+ switch (offset0) {
+ case A_VCMDQ0_BASE_L:
+ cmdqv->vcmdq_base[index] =
+ deposit64(cmdqv->vcmdq_base[index], 0, 32, value);
++ tegra241_cmdqv_setup_vcmdq(cmdqv, index, errp);
+ break;
+ case A_VCMDQ0_BASE_H:
+ cmdqv->vcmdq_base[index] =
+ deposit64(cmdqv->vcmdq_base[index], 32, 32, value);
++ tegra241_cmdqv_setup_vcmdq(cmdqv, index, errp);
+ break;
+ case A_VCMDQ0_CONS_INDX_BASE_DRAM_L:
+ cmdqv->vcmdq_cons_indx_base[index] =
+@@ -200,11 +298,13 @@ static void tegra241_cmdqv_write_vcmdq_page1(Tegra241CMDQV *cmdqv,
+ */
+ static void tegra241_cmdqv_write_vcmdq_page1_64(Tegra241CMDQV *cmdqv,
+ hwaddr offset0, int index,
+- uint64_t value, bool direct)
++ uint64_t value, bool direct,
++ Error **errp)
+ {
+ switch (offset0) {
+ case A_VCMDQ0_BASE_L:
+ cmdqv->vcmdq_base[index] = value;
++ tegra241_cmdqv_setup_vcmdq(cmdqv, index, errp);
+ break;
+ case A_VCMDQ0_CONS_INDX_BASE_DRAM_L:
+ cmdqv->vcmdq_cons_indx_base[index] = value;
+@@ -219,7 +319,8 @@ static void tegra241_cmdqv_write_vcmdq_page1_64(Tegra241CMDQV *cmdqv,
+ }
+
+ static void tegra241_cmdqv_config_vintf_write(Tegra241CMDQV *cmdqv,
+- hwaddr offset, uint64_t value)
++ hwaddr offset, uint64_t value,
++ Error **errp)
+ {
+ int i;
+
+@@ -235,7 +336,13 @@ static void tegra241_cmdqv_config_vintf_write(Tegra241CMDQV *cmdqv,
+ cmdqv->vintf_config = value;
+ if (value & R_VINTF0_CONFIG_ENABLE_MASK) {
+ cmdqv->vintf_status |= R_VINTF0_STATUS_ENABLE_OK_MASK;
++ /*
++ * VCMDQs whose BASE was programmed before VINTF was
++ * enabled need their hw_queue allocated now.
++ */
++ tegra241_cmdqv_setup_all_vcmdq(cmdqv, errp);
+ } else {
++ tegra241_cmdqv_free_all_vcmdq(cmdqv);
+ cmdqv->vintf_status &= ~R_VINTF0_STATUS_ENABLE_OK_MASK;
+ }
+ break;
+@@ -341,6 +448,7 @@ out:
+ static void tegra241_cmdqv_writel_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ uint32_t value)
+ {
++ Error *local_err = NULL;
+ int index;
+
+ switch (offset) {
+@@ -348,18 +456,39 @@ static void tegra241_cmdqv_writel_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ cmdqv->config = value;
+ if (value & R_CONFIG_CMDQV_EN_MASK) {
+ cmdqv->status |= R_STATUS_CMDQV_ENABLED_MASK;
++ /*
++ * VCMDQs whose BASE was programmed before CMDQV was enabled
++ * need their hw_queue allocated now.
++ */
++ tegra241_cmdqv_setup_all_vcmdq(cmdqv, &local_err);
+ } else {
++ tegra241_cmdqv_free_all_vcmdq(cmdqv);
+ cmdqv->status &= ~R_STATUS_CMDQV_ENABLED_MASK;
+ }
+ break;
+ case A_VI_INT_MASK_0 ... A_VI_INT_MASK_1:
+ cmdqv->vi_int_mask[(offset - A_VI_INT_MASK_0) / 4] = value;
+ break;
+- case A_CMDQ_ALLOC_MAP_0 ... A_CMDQ_ALLOC_MAP_1:
+- cmdqv->cmdq_alloc_map[(offset - A_CMDQ_ALLOC_MAP_0) / 4] = value;
++ case A_CMDQ_ALLOC_MAP_0 ... A_CMDQ_ALLOC_MAP_1: {
++ int idx = (offset - A_CMDQ_ALLOC_MAP_0) / 4;
++ bool was_alloc = cmdqv->cmdq_alloc_map[idx] &
++ R_CMDQ_ALLOC_MAP_0_ALLOC_MASK;
++ bool now_alloc = value & R_CMDQ_ALLOC_MAP_0_ALLOC_MASK;
++
++ cmdqv->cmdq_alloc_map[idx] = value;
++ /*
++ * If the VCMDQ was already programmed (BASE) before mapping, fire
++ * setup on the ALLOC 0->1 transition; tear down on 1->0.
++ */
++ if (!was_alloc && now_alloc) {
++ tegra241_cmdqv_setup_vcmdq(cmdqv, idx, &local_err);
++ } else if (was_alloc && !now_alloc) {
++ tegra241_cmdqv_free_vcmdq(cmdqv, idx);
++ }
+ break;
++ }
+ case A_VINTF0_CONFIG ... A_VINTF0_LVCMDQ_ERR_MAP_3:
+- tegra241_cmdqv_config_vintf_write(cmdqv, offset, value);
++ tegra241_cmdqv_config_vintf_write(cmdqv, offset, value, &local_err);
+ break;
+ case A_VI_VCMDQ0_CONS_INDX ... A_VI_VCMDQ1_GERRORN:
+ /*
+@@ -387,17 +516,23 @@ static void tegra241_cmdqv_writel_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ offset -= CMDQV_VINTF_PAGE1_BASE - CMDQV_VCMDQ_PAGE1_BASE;
+ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
+ tegra241_cmdqv_write_vcmdq_page1(cmdqv,
+- offset - index * CMDQV_VCMDQ_STRIDE, index, value, false);
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, false,
++ &local_err);
+ break;
+ case A_VCMDQ0_BASE_L ... A_VCMDQ1_CONS_INDX_BASE_DRAM_H:
+ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
+ tegra241_cmdqv_write_vcmdq_page1(cmdqv,
+- offset - index * CMDQV_VCMDQ_STRIDE, index, value, true);
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, true,
++ &local_err);
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s unhandled write access at 0x%" PRIx64 "\n",
+ __func__, offset);
+ }
++
++ if (local_err) {
++ error_report_err(local_err);
++ }
+ }
+
+ /*
+@@ -407,6 +542,7 @@ static void tegra241_cmdqv_writel_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ static void tegra241_cmdqv_writell_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ uint64_t value)
+ {
++ Error *local_err = NULL;
+ int index;
+
+ switch (offset) {
+@@ -419,18 +555,24 @@ static void tegra241_cmdqv_writell_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ offset -= CMDQV_VINTF_PAGE1_BASE - CMDQV_VCMDQ_PAGE1_BASE;
+ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
+ tegra241_cmdqv_write_vcmdq_page1_64(cmdqv,
+- offset - index * CMDQV_VCMDQ_STRIDE, index, value, false);
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, false,
++ &local_err);
+ break;
+ case A_VCMDQ0_BASE_L ... A_VCMDQ1_CONS_INDX_BASE_DRAM_H:
+ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
+ tegra241_cmdqv_write_vcmdq_page1_64(cmdqv,
+- offset - index * CMDQV_VCMDQ_STRIDE, index, value, true);
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, true,
++ &local_err);
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s unhandled 64-bit write at 0x%" PRIx64 " (WI)\n",
+ __func__, offset);
+ }
++
++ if (local_err) {
++ error_report_err(local_err);
++ }
+ }
+
+ static void tegra241_cmdqv_write_mmio(void *opaque, hwaddr offset,
+@@ -535,6 +677,13 @@ free_viommu:
+
+ static void tegra241_cmdqv_reset(SMMUv3State *s)
+ {
++ Tegra241CMDQV *cmdqv = s->s_accel->cmdqv;
++
++ if (!cmdqv) {
++ return;
++ }
++
++ tegra241_cmdqv_free_all_vcmdq(cmdqv);
+ }
+
+ static const MemoryRegionOps mmio_cmdqv_ops = {
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+index cc1b55a5e1..c795da0444 100644
+--- a/hw/arm/tegra241-cmdqv.h
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -47,6 +47,7 @@ typedef struct Tegra241CMDQV {
+ MemoryRegion mmio_cmdqv;
+ qemu_irq irq;
+ IOMMUFDVeventq *veventq;
++ IOMMUFDHWqueue *vcmdq[TEGRA241_CMDQV_MAX_CMDQ];
+ void *vintf_page0;
+
+ /* CMDQ-V Config page register cache */
+@@ -364,6 +365,16 @@ SMMU_CMDQV_VI_VCMDQi_BASE_H_(1)
+ SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_L_(1)
+ SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_H_(1)
+
++static inline bool tegra241_cmdqv_enabled(Tegra241CMDQV *cmdqv)
++{
++ return cmdqv->status & R_STATUS_CMDQV_ENABLED_MASK;
++}
++
++static inline bool tegra241_vintf_enabled(Tegra241CMDQV *cmdqv)
++{
++ return cmdqv->vintf_status & R_VINTF0_STATUS_ENABLE_OK_MASK;
++}
++
+ const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
+
+ #endif /* HW_ARM_TEGRA241_CMDQV_H */
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Document-the-CMDQV-design-and-.patch b/kvm-hw-arm-tegra241-cmdqv-Document-the-CMDQV-design-and-.patch
new file mode 100644
index 0000000..7a6e245
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Document-the-CMDQV-design-and-.patch
@@ -0,0 +1,148 @@
+From b87b7e2da3b0255abd7d6ae5321c64b730d421e4 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:51 +0100
+Subject: [PATCH 109/111] hw/arm/tegra241-cmdqv: Document the CMDQV design and
+ lifecycle
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [109/111] 459c891d5e7df2bfbc8b190babbda310eb6fd177 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Add an overview describing the Tegra241 CMDQV passthrough model, MMIO
+layout, guest-driven lifecycle, and per-VM isolation.
+
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Message-id: 20260609112552.378999-31-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 295ca0e14c6169e831c4a277e48df3a4aa0d8606)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 100 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 100 insertions(+)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 1bed1374ba..5e15494a7f 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -7,6 +7,106 @@
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
++/*
++ * Tegra241 CMDQV - overview
++ * =========================
++ *
++ * NVIDIA Tegra241 extends SMMUv3 with a Command Queue Virtualization (CMDQ-V)
++ * block. It lets a guest issue SMMU invalidation commands directly to
++ * dedicated hardware queues (vCMDQs) without trapping into the hypervisor on
++ * the fast path. vCMDQs are exclusively allocated to Virtual Interfaces
++ * (VINTFs); the host kernel allocates one VINTF per emulated SMMUv3 instance
++ * via iommufd. QEMU emulates the CMDQV MMIO region and drives the host kernel
++ * calls (VIOMMU_ALLOC, HW_QUEUE_ALLOC, mmap); the actual command processing
++ * happens on real hardware.
++ *
++ * A vCMDQ becomes functional only once allocated to the host VINTF; until then
++ * no command processing happens, and trapped register accesses fall back to a
++ * QEMU-side cache. After allocation, the cached register state is migrated to
++ * the hardware and command processing runs on the host; guest accesses to the
++ * live control/status registers then bypass QEMU and reach the host directly.
++ *
++ * MMIO layout (64KB pages, total TEGRA241_CMDQV_IO_LEN)
++ * -----------------------------------------------------
++ * 0x00000 CMDQV Config page: QEMU-trapped.
++ * 0x10000 Direct vCMDQ Page 0 (control/status): QEMU-trapped and routed
++ * to either the mmap'd host VINTF Page 0 (if the vCMDQ has been
++ * allocated to a VINTF) or a per-vCMDQ register cache (otherwise).
++ * 0x20000 Direct vCMDQ Page 1 (BASE / DRAM addresses): QEMU-trapped.
++ * 0x30000 VINTF Page 0 (per-VINTF control/status): the guest's virtual
++ * VINTF Page 0 aperture, backed by the host VINTF Page 0 (mmap'd
++ * via iommufd) and installed into guest MMIO as a RAM-device
++ * subregion when VINTF is enabled; subsequent accesses bypass QEMU.
++ * 0x40000 VINTF Page 1 (per-VINTF BASE): QEMU-trapped. Although this is
++ * a HW alias of the direct Page 1, the kernel only exposes mmap
++ * for the host VINTF Page 0; the host VINTF Page 1 is not mmap'd
++ * and stays trapped.
++ *
++ * The direct vCMDQ apertures (0x10000/0x20000) are HW aliases of the VINTF
++ * apertures (0x30000/0x40000); they expose the same per-vCMDQ register slots
++ * under different addressing.
++ *
++ * The direct vCMDQ Page 0 stays trapped rather than aliased to the host VINTF
++ * Page 0 mmap. The CMDQV architecture allows software to program a vCMDQ
++ * through the direct aperture before allocating it to a VINTF; aliasing to
++ * the host VINTF Page 0 mmap would route those accesses into unallocated
++ * logical slots where the hardware silently drops them, so trapping keeps
++ * accesses well-defined for an unallocated vCMDQ.
++ *
++ * Lifecycle (driven by guest events)
++ * ----------------------------------
++ * 1. First vfio-pci device attach (.set_iommu_device) triggers:
++ * - tegra241_cmdqv_probe(): IOMMU_GET_HW_INFO confirms host CMDQV support.
++ * - IOMMU_VIOMMU_ALLOC: the kernel allocates and enables a VINTF for this
++ * VM, configures the VM's VMID (from its stage-2 HWPT) in VINTF_CONFIG,
++ * forces HYP_OWN=0, and returns the mmap offset/length for the host
++ * VINTF Page 0, which QEMU then mmap()s.
++ *
++ * 2. Guest writes VINTF_CONFIG.ENABLE = 1:
++ * QEMU installs the mmap'd host VINTF Page 0 into guest MMIO as the guest's
++ * virtual VINTF Page 0 aperture (a RAM-device subregion) and reports
++ * STATUS.ENABLE_OK = 1. The aperture is now a direct window onto the host
++ * page, so accesses no longer trap into QEMU; a vCMDQ within it operates as
++ * a real command queue only once it has been allocated (step 3).
++ *
++ * 3. Guest completes vCMDQ setup (BASE, CMDQ_ALLOC_MAP.ALLOC, CMDQV_EN,
++ * VINTF.ENABLE, in any order; each precondition write retries the HW queue
++ * allocation):
++ * IOMMU_HW_QUEUE_ALLOC grants the guest a new host vCMDQ in this VM's
++ * VINTF, binding the guest BASE GPA (translated through stage-2 and pinned
++ * by the kernel) to it.
++ *
++ * 4. Guest SMMU driver programs a Stream Table Entry for a passthrough
++ * device: IOMMU_VDEVICE_ALLOC programs SID_MATCH/SID_REPLACE in this VM's
++ * VINTF so that the HW translates the device's guest vSID into its host
++ * pSID. Commands referencing unmapped SIDs are rejected by HW.
++ *
++ * This reflects the current accel SMMUv3 design, which allocates the
++ * vDEVICE when the guest programs the STE.
++ *
++ * Per-VM isolation
++ * ----------------
++ * - Each VM has its own iommufd FD; all iommufd objects (VINTF, vdevices,
++ * hw_queues, mmap regions) belong to that FD. Cross-FD lookups fail, so
++ * one VM cannot reach another VM's IDs.
++ * - IOMMU_VIOMMU_ALLOC configures the VM's VMID in VINTF_CONFIG; the CMDQV
++ * hardware substitutes / checks VMID on every command the guest issues.
++ * - The kernel allocates the VINTF with HYP_OWN = 0, which restricts the
++ * guest to a safe subset of commands.
++ * - IOMMU_VDEVICE_ALLOC populates SID_MATCH/SID_REPLACE so invalidations
++ * only reach the host StreamIDs assigned to this VM (see step 4).
++ * - IOMMU_HW_QUEUE_ALLOC binds each vCMDQ to a single VINTF, so a guest
++ * cannot reach a vCMDQ that belongs to another VM.
++ *
++ * Limits exposed to the guest
++ * ---------------------------
++ * One VINTF per emulated SMMUv3 and two vCMDQs per VINTF. The HW maximum
++ * vCMDQ size is 8MiB, but the size QEMU exposes to the guest may be smaller.
++ * The queue must be physically contiguous in host memory, so QEMU caps the
++ * exposed size to the host memory-backend page size. Use hugepage backing to
++ * reach the 8MiB maximum.
++ */
++
+ #include "qemu/osdep.h"
+ #include "qemu/log.h"
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Emulate-CMDQ-V-Config-region.patch b/kvm-hw-arm-tegra241-cmdqv-Emulate-CMDQ-V-Config-region.patch
new file mode 100644
index 0000000..86b9aff
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Emulate-CMDQ-V-Config-region.patch
@@ -0,0 +1,409 @@
+From 56c1c28fee7f306288a45c2c25b839cc9e467aac Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:36 +0100
+Subject: [PATCH 094/111] hw/arm/tegra241-cmdqv: Emulate CMDQ-V Config region
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [94/111] d7440fe197d4839cf28c6049bf7752f5a3df331b (eauger1/centos-qemu-kvm)
+
+Conflicts: in hw/arm/tegra241-cmdqv.h used hw/registerfields.h
+instead of hw/core/registerfields.h
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Tegra241 CMDQV exposes control and status registers in the CMDQ-V
+Config page (offset [0x0, 0x10000)) used to configure virtual command
+queue allocation and interrupt behavior.
+
+Add read/write emulation for the CMDQ-V Config region
+([CMDQV_BASE, CMDQV_CMDQ_BASE]), backed by a simple register cache.
+This includes CONFIG, PARAM, STATUS, VI error and interrupt maps, CMDQ
+allocation map and the VINTF0 related registers defined in the CMDQ-V
+Config space. Only VINTF0 is supported; VINTF1-63 are not.
+
+Dispatch writes on access size: Introduced writel_mmio for 4-byte and
+writell_mmio for 8-byte. Reads need no split as the MMIO framework masks
+the returned value to the access size.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260609112552.378999-16-skolothumtho@nvidia.com
+Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit ab9ead11f03d8abc0c069309d516a8abb75eebe7)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 181 +++++++++++++++++++++++++++++++++++++++-
+ hw/arm/tegra241-cmdqv.h | 110 ++++++++++++++++++++++++
+ hw/arm/trace-events | 4 +
+ 3 files changed, 294 insertions(+), 1 deletion(-)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 3eec6073a4..8950d5153b 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -8,21 +8,200 @@
+ */
+
+ #include "qemu/osdep.h"
++#include "qemu/log.h"
+
+ #include "hw/arm/smmuv3.h"
+ #include "hw/arm/smmuv3-common.h"
+ #include "smmuv3-accel.h"
+ #include "tegra241-cmdqv.h"
++#include "trace.h"
++
++static uint64_t tegra241_cmdqv_config_vintf_read(Tegra241CMDQV *cmdqv,
++ hwaddr offset)
++{
++ int i;
++
++ switch (offset) {
++ case A_VINTF0_CONFIG:
++ return cmdqv->vintf_config;
++ case A_VINTF0_STATUS:
++ return cmdqv->vintf_status;
++ case A_VINTF0_SID_MATCH_0 ... A_VINTF0_SID_MATCH_15:
++ i = (offset - A_VINTF0_SID_MATCH_0) / 4;
++ return cmdqv->vintf_sid_match[i];
++ case A_VINTF0_SID_REPLACE_0 ... A_VINTF0_SID_REPLACE_15:
++ i = (offset - A_VINTF0_SID_REPLACE_0) / 4;
++ return cmdqv->vintf_sid_replace[i];
++ case A_VINTF0_LVCMDQ_ERR_MAP_0 ... A_VINTF0_LVCMDQ_ERR_MAP_3:
++ i = (offset - A_VINTF0_LVCMDQ_ERR_MAP_0) / 4;
++ return cmdqv->vintf_cmdq_err_map[i];
++ default:
++ /*
++ * GLB_FILT_CFG_0 (offset 0xC) and GLB_FILT_DATA_0 (offset 0x10) are
++ * filter config and filter data registers. They are not required for
++ * normal VINTF operation and are not emulated.
++ */
++ qemu_log_mask(LOG_UNIMP, "%s unhandled read access at 0x%" PRIx64 "\n",
++ __func__, offset);
++ return 0;
++ }
++}
++
++static void tegra241_cmdqv_config_vintf_write(Tegra241CMDQV *cmdqv,
++ hwaddr offset, uint64_t value)
++{
++ int i;
++
++ switch (offset) {
++ case A_VINTF0_CONFIG:
++ /*
++ * Mask out HYP_OWN on guest writes. This bit selects Hypervisor (1) vs
++ * Guest (0) ownership of the CMDQ. Force it to 0 so the VINTF always
++ * remains guest-owned.
++ */
++ value &= ~R_VINTF0_CONFIG_HYP_OWN_MASK;
++
++ cmdqv->vintf_config = value;
++ if (value & R_VINTF0_CONFIG_ENABLE_MASK) {
++ cmdqv->vintf_status |= R_VINTF0_STATUS_ENABLE_OK_MASK;
++ } else {
++ cmdqv->vintf_status &= ~R_VINTF0_STATUS_ENABLE_OK_MASK;
++ }
++ break;
++ case A_VINTF0_SID_MATCH_0 ... A_VINTF0_SID_MATCH_15:
++ i = (offset - A_VINTF0_SID_MATCH_0) / 4;
++ cmdqv->vintf_sid_match[i] = value;
++ break;
++ case A_VINTF0_SID_REPLACE_0 ... A_VINTF0_SID_REPLACE_15:
++ i = (offset - A_VINTF0_SID_REPLACE_0) / 4;
++ cmdqv->vintf_sid_replace[i] = value;
++ break;
++ default:
++ /*
++ * GLB_FILT_CFG_0 (offset 0xC) and GLB_FILT_DATA_0 (offset 0x10) are
++ * filter config and filter data registers. They are not required for
++ * normal VINTF operation and are not emulated.
++ */
++ qemu_log_mask(LOG_UNIMP, "%s unhandled write access at 0x%" PRIx64 "\n",
++ __func__, offset);
++ return;
++ }
++}
+
+ static uint64_t tegra241_cmdqv_read_mmio(void *opaque, hwaddr offset,
+ unsigned size)
+ {
+- return 0;
++ Tegra241CMDQV *cmdqv = (Tegra241CMDQV *)opaque;
++ uint64_t val = 0;
++
++ if (offset >= TEGRA241_CMDQV_IO_LEN) {
++ qemu_log_mask(LOG_UNIMP,
++ "%s offset 0x%" PRIx64 " off limit (0x%x)\n", __func__,
++ offset, TEGRA241_CMDQV_IO_LEN);
++ goto out;
++ }
++
++ switch (offset) {
++ case A_CONFIG:
++ val = cmdqv->config;
++ break;
++ case A_PARAM:
++ val = cmdqv->param;
++ break;
++ case A_STATUS:
++ val = cmdqv->status;
++ break;
++ case A_VI_ERR_MAP_0 ... A_VI_ERR_MAP_1:
++ val = cmdqv->vi_err_map[(offset - A_VI_ERR_MAP_0) / 4];
++ break;
++ case A_VI_INT_MASK_0 ... A_VI_INT_MASK_1:
++ val = cmdqv->vi_int_mask[(offset - A_VI_INT_MASK_0) / 4];
++ break;
++ case A_CMDQ_ERR_MAP_0 ... A_CMDQ_ERR_MAP_3:
++ val = cmdqv->cmdq_err_map[(offset - A_CMDQ_ERR_MAP_0) / 4];
++ break;
++ case A_CMDQ_ALLOC_MAP_0 ... A_CMDQ_ALLOC_MAP_1:
++ val = cmdqv->cmdq_alloc_map[(offset - A_CMDQ_ALLOC_MAP_0) / 4];
++ break;
++ case A_VINTF0_CONFIG ... A_VINTF0_LVCMDQ_ERR_MAP_3:
++ val = tegra241_cmdqv_config_vintf_read(cmdqv, offset);
++ break;
++ default:
++ qemu_log_mask(LOG_UNIMP, "%s unhandled read access at 0x%" PRIx64 "\n",
++ __func__, offset);
++ }
++
++out:
++ trace_tegra241_cmdqv_read_mmio(offset, val, size);
++ return val;
++}
++
++/* 4-byte MMIO write handler. */
++static void tegra241_cmdqv_writel_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
++ uint32_t value)
++{
++ switch (offset) {
++ case A_CONFIG:
++ cmdqv->config = value;
++ if (value & R_CONFIG_CMDQV_EN_MASK) {
++ cmdqv->status |= R_STATUS_CMDQV_ENABLED_MASK;
++ } else {
++ cmdqv->status &= ~R_STATUS_CMDQV_ENABLED_MASK;
++ }
++ break;
++ case A_VI_INT_MASK_0 ... A_VI_INT_MASK_1:
++ cmdqv->vi_int_mask[(offset - A_VI_INT_MASK_0) / 4] = value;
++ break;
++ case A_CMDQ_ALLOC_MAP_0 ... A_CMDQ_ALLOC_MAP_1:
++ cmdqv->cmdq_alloc_map[(offset - A_CMDQ_ALLOC_MAP_0) / 4] = value;
++ break;
++ case A_VINTF0_CONFIG ... A_VINTF0_LVCMDQ_ERR_MAP_3:
++ tegra241_cmdqv_config_vintf_write(cmdqv, offset, value);
++ break;
++ default:
++ qemu_log_mask(LOG_UNIMP, "%s unhandled write access at 0x%" PRIx64 "\n",
++ __func__, offset);
++ }
++}
++
++/*
++ * 8-byte MMIO write handler.
++ */
++static void tegra241_cmdqv_writell_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
++ uint64_t value)
++{
++ qemu_log_mask(LOG_UNIMP,
++ "%s unhandled 64-bit write at 0x%" PRIx64 " (WI)\n",
++ __func__, offset);
+ }
+
+ static void tegra241_cmdqv_write_mmio(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+ {
++ Tegra241CMDQV *cmdqv = (Tegra241CMDQV *)opaque;
++
++ if (offset >= TEGRA241_CMDQV_IO_LEN) {
++ qemu_log_mask(LOG_UNIMP,
++ "%s offset 0x%" PRIx64 " off limit (0x%x)\n", __func__,
++ offset, TEGRA241_CMDQV_IO_LEN);
++ goto out;
++ }
++
++ switch (size) {
++ case 4:
++ tegra241_cmdqv_writel_mmio(cmdqv, offset, value);
++ break;
++ case 8:
++ tegra241_cmdqv_writell_mmio(cmdqv, offset, value);
++ break;
++ default:
++ qemu_log_mask(LOG_GUEST_ERROR,
++ "%s bad write size %u at 0x%" PRIx64 "\n",
++ __func__, size, offset);
++ }
++
++out:
++ trace_tegra241_cmdqv_write_mmio(offset, value, size);
+ }
+
+ static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+index 00c83b6186..4b86aa01d3 100644
+--- a/hw/arm/tegra241-cmdqv.h
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -10,10 +10,15 @@
+ #ifndef HW_ARM_TEGRA241_CMDQV_H
+ #define HW_ARM_TEGRA241_CMDQV_H
+
++#include "hw/registerfields.h"
++
+ #define CMDQV_VER 1
+ #define CMDQV_NUM_CMDQ_LOG2 1
+ #define CMDQV_NUM_SID_PER_VI_LOG2 4
+
++#define TEGRA241_CMDQV_MAX_CMDQ (1U << CMDQV_NUM_CMDQ_LOG2)
++#define TEGRA241_CMDQV_MAX_NUM_SID (1U << CMDQV_NUM_SID_PER_VI_LOG2)
++
+ /*
+ * Tegra241 CMDQV MMIO layout (64KB pages)
+ *
+@@ -36,8 +41,113 @@ typedef struct Tegra241CMDQV {
+ qemu_irq irq;
+ IOMMUFDVeventq *veventq;
+ void *vintf_page0;
++
++ /* CMDQ-V Config page register cache */
++ uint32_t config;
++ uint32_t param;
++ uint32_t status;
++ uint32_t vi_err_map[2];
++ uint32_t vi_int_mask[2];
++ uint32_t cmdq_err_map[4];
++ uint32_t cmdq_alloc_map[TEGRA241_CMDQV_MAX_CMDQ];
++
++ /* VINTF0 register cache (within CMDQ-V Config page) */
++ uint32_t vintf_config;
++ uint32_t vintf_status;
++ uint32_t vintf_sid_match[TEGRA241_CMDQV_MAX_NUM_SID];
++ uint32_t vintf_sid_replace[TEGRA241_CMDQV_MAX_NUM_SID];
++ uint32_t vintf_cmdq_err_map[4];
+ } Tegra241CMDQV;
+
++/* CMDQ-V Config page registers (offset 0x00000) */
++REG32(CONFIG, 0x0)
++FIELD(CONFIG, CMDQV_EN, 0, 1)
++FIELD(CONFIG, CMDQV_PER_CMD_OFFSET, 1, 3)
++FIELD(CONFIG, CMDQ_MAX_CLK_BATCH, 4, 8)
++FIELD(CONFIG, CMDQ_MAX_CMD_BATCH, 12, 8)
++FIELD(CONFIG, CONS_DRAM_EN, 20, 1)
++
++REG32(PARAM, 0x4)
++FIELD(PARAM, CMDQV_VER, 0, 4)
++FIELD(PARAM, CMDQV_NUM_CMDQ_LOG2, 4, 4)
++FIELD(PARAM, CMDQV_NUM_VI_LOG2, 8, 4)
++FIELD(PARAM, CMDQV_NUM_SID_PER_VI_LOG2, 12, 4)
++
++REG32(STATUS, 0x8)
++FIELD(STATUS, CMDQV_ENABLED, 0, 1)
++
++/* SMMU_CMDQV_VI_ERR_MAP_0/1 definitions */
++#define A_VI_ERR_MAP_0 0x14
++#define A_VI_ERR_MAP_1 0x18
++#define V_VI_ERR_MAP_NO_ERROR (0)
++#define V_VI_ERR_MAP_ERROR (1)
++
++/* SMMU_CMDQV_VI_INT_MASK_0/1 definitions */
++#define A_VI_INT_MASK_0 0x1c
++#define A_VI_INT_MASK_1 0x20
++#define V_VI_INT_MASK_NOT_MASKED (0)
++#define V_VI_INT_MASK_MASKED (1)
++
++/* SMMU_CMDQV_CMDQ_ERR_MAP_0-3 definitions */
++#define A_CMDQ_ERR_MAP_0 0x24
++#define A_CMDQ_ERR_MAP_1 0x28
++#define A_CMDQ_ERR_MAP_2 0x2c
++#define A_CMDQ_ERR_MAP_3 0x30
++
++/*
++ * CMDQ_ALLOC_MAP: one entry per physical VCMDQ. Hardware supports up to 128
++ * entries (CMDQV_NUM_CMDQ_LOG2=7), but QEMU only exposes
++ * TEGRA241_CMDQV_MAX_CMDQ (=2) VCMDQs per VM so only entries 0 and 1 are
++ * defined here.
++ */
++/* 2 identical register entries */
++#define SMMU_CMDQV_CMDQ_ALLOC_MAP_(i) \
++ REG32(CMDQ_ALLOC_MAP_##i, 0x200 + i * 4) \
++ FIELD(CMDQ_ALLOC_MAP_##i, ALLOC, 0, 1) \
++ FIELD(CMDQ_ALLOC_MAP_##i, LVCMDQ, 1, 7) \
++ FIELD(CMDQ_ALLOC_MAP_##i, VIRT_INTF_INDX, 15, 6)
++
++SMMU_CMDQV_CMDQ_ALLOC_MAP_(0)
++SMMU_CMDQV_CMDQ_ALLOC_MAP_(1)
++
++/* SMMU_CMDQV_VINTF0 registers (only VINTF0 is exposed to the guest) */
++REG32(VINTF0_CONFIG, 0x1000)
++FIELD(VINTF0_CONFIG, ENABLE, 0, 1)
++FIELD(VINTF0_CONFIG, VMID, 1, 16)
++FIELD(VINTF0_CONFIG, HYP_OWN, 17, 1)
++
++REG32(VINTF0_STATUS, 0x1004)
++FIELD(VINTF0_STATUS, ENABLE_OK, 0, 1)
++FIELD(VINTF0_STATUS, STATUS, 1, 3)
++FIELD(VINTF0_STATUS, VI_NUM_LVCMDQ, 16, 8)
++
++#define V_VINTF_STATUS_NO_ERROR (0 << 1)
++#define V_VINTF_STATUS_VCMDQ_ERROR (1 << 1)
++
++/*
++ * SMMU_CMDQV_VINTF0_SID_MATCH/_REPLACE: 16 entries per VINTF
++ * (CMDQV_NUM_SID_PER_VI_LOG2=4). Only _0 and _15 are defined,
++ * used as switch case range bounds.
++ */
++REG32(VINTF0_SID_MATCH_0, 0x1040)
++FIELD(VINTF0_SID_MATCH_0, ENABLE, 0, 1)
++FIELD(VINTF0_SID_MATCH_0, VIRT_SID, 1, 20)
++#define A_VINTF0_SID_MATCH_15 (A_VINTF0_SID_MATCH_0 + 15 * 4)
++
++REG32(VINTF0_SID_REPLACE_0, 0x1080)
++FIELD(VINTF0_SID_REPLACE_0, PHYS_SID, 0, 20)
++#define A_VINTF0_SID_REPLACE_15 (A_VINTF0_SID_REPLACE_0 + 15 * 4)
++
++/*
++ * SMMU_CMDQV_VINTF0_LVCMDQ_ERR_MAP: 4 registers per VINTF covering 32 logical
++ * VCMDQs each. With TEGRA241_CMDQV_MAX_CMDQ=2, only MAP_0 bits [1:0] carry
++ * error state. MAP_1..MAP_3 always read as 0. Only _0 and _3 are defined,
++ * used as switch case range bounds.
++ */
++REG32(VINTF0_LVCMDQ_ERR_MAP_0, 0x10c0)
++FIELD(VINTF0_LVCMDQ_ERR_MAP_0, LVCMDQ_ERR_MAP, 0, 32)
++#define A_VINTF0_LVCMDQ_ERR_MAP_3 (A_VINTF0_LVCMDQ_ERR_MAP_0 + 3 * 4)
++
+ const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
+
+ #endif /* HW_ARM_TEGRA241_CMDQV_H */
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index 3457536fb0..8c61d66a26 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -72,6 +72,10 @@ smmuv3_accel_unset_iommu_device(int devfn, uint32_t devid) "devfn=0x%x (idev dev
+ smmuv3_accel_translate_ste(uint32_t vsid, uint32_t hwpt_id, uint64_t ste_1, uint64_t ste_0) "vSID=0x%x hwpt_id=0x%x ste=%"PRIx64":%"PRIx64
+ smmuv3_accel_install_ste(uint32_t vsid, const char * type, uint32_t hwpt_id) "vSID=0x%x ste type=%s hwpt_id=0x%x"
+
++# tegra241-cmdqv
++tegra241_cmdqv_read_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
++tegra241_cmdqv_write_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
++
+ # strongarm.c
+ strongarm_uart_update_parameters(const char *label, int speed, char parity, int data_bits, int stop_bits) "%s speed=%d parity=%c data=%d stop=%d"
+ strongarm_ssp_read_underrun(void) "SSP rx underrun"
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-reads.patch b/kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-reads.patch
new file mode 100644
index 0000000..7ddb4ad
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-reads.patch
@@ -0,0 +1,451 @@
+From 41cd0be6ec20382df99d2e13e181603452f7a203 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:37 +0100
+Subject: [PATCH 095/111] hw/arm/tegra241-cmdqv: Emulate VCMDQ register reads
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [95/111] 00a83972276e9eadcc48efa1fe453d197a5ac873 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Tegra241 CMDQV exposes per-VCMDQ register windows through two MMIO
+apertures:
+
+ Direct VCMDQ aperture (0x10000/0x20000): VCMDQ Page0/Page1
+ VINTF logical aperture (0x30000/0x40000): VINTF0 LVCMDQ Page0/Page1
+
+Both apertures are hardware aliases of the same underlying registers:
+
+ Page 0 (control/status): CONS_INDX, PROD_INDX, CONFIG, STATUS,
+ GERROR, GERRORN
+ Page 1 (base/DRAM): BASE_L/H, CONS_INDX_BASE_DRAM_L/H
+
+The direct aperture Page 0 is programmable at any time so long as
+CMDQV_EN is enabled. The VINTF (logical) aperture Page 0 is
+programmable only once SW has mapped a VCMDQ to a VINTF; the
+"logical" view is local to that VINTF.
+
+Add read emulation for both apertures, backed by a single per-VCMDQ
+register cache. VINTF aperture reads are translated to their
+equivalent direct-aperture offset and served from the same cached
+state.
+
+Per the CMDQV architecture, a VCMDQ must be allocated to a Virtual
+Interface before it is used to send commands to the SMMU. Until that
+allocation happens, reads return cached register state with no HW
+interaction. Subsequent patches wire up IOMMU_HW_QUEUE_ALLOC, mmap
+the host VINTF Page 0, and install it into guest MMIO; after that,
+Page 0 reads from either aperture are served from the hardware-backed
+mmap'd page instead of the cache. Page 1 is also a hardware alias,
+but the kernel only exposes mmap for Page 0, so Page 1 reads always
+trap to QEMU and are served from cache.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260609112552.378999-17-skolothumtho@nvidia.com
+Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 0d06b1cc2050fb8efdb9f023344b2e55125003f0)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 103 +++++++++++++++++++
+ hw/arm/tegra241-cmdqv.h | 216 ++++++++++++++++++++++++++++++++++++++++
+ hw/arm/trace-events | 2 +
+ 3 files changed, 321 insertions(+)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 8950d5153b..2dfd377ee9 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -16,6 +16,79 @@
+ #include "tegra241-cmdqv.h"
+ #include "trace.h"
+
++/*
++ * Read a VCMDQ Page 0 register (control/status) using VCMDQ0_* offsets.
++ *
++ * The caller normalizes the MMIO offset such that @offset0 always refers
++ * to a VCMDQ0_* register, while @index selects the VCMDQ instance.
++ */
++static uint64_t tegra241_cmdqv_read_vcmdq_page0(Tegra241CMDQV *cmdqv,
++ hwaddr offset0, int index,
++ bool direct)
++{
++ uint64_t val = 0;
++
++ switch (offset0) {
++ case A_VCMDQ0_CONS_INDX:
++ val = cmdqv->vcmdq_cons_indx[index];
++ break;
++ case A_VCMDQ0_PROD_INDX:
++ val = cmdqv->vcmdq_prod_indx[index];
++ break;
++ case A_VCMDQ0_CONFIG:
++ val = cmdqv->vcmdq_config[index];
++ break;
++ case A_VCMDQ0_STATUS:
++ val = cmdqv->vcmdq_status[index];
++ break;
++ case A_VCMDQ0_GERROR:
++ val = cmdqv->vcmdq_gerror[index];
++ break;
++ case A_VCMDQ0_GERRORN:
++ val = cmdqv->vcmdq_gerrorn[index];
++ break;
++ default:
++ qemu_log_mask(LOG_UNIMP,
++ "%s unhandled read access at 0x%" PRIx64 "\n",
++ __func__, offset0);
++ }
++ trace_tegra241_cmdqv_read_vcmdq_page0(index, direct ? "direct" : "vi",
++ offset0, val);
++ return val;
++}
++
++/*
++ * Read a VCMDQ Page 1 register (base / DRAM address) using VCMDQ0_* offsets.
++ */
++static uint64_t tegra241_cmdqv_read_vcmdq_page1(Tegra241CMDQV *cmdqv,
++ hwaddr offset0, int index,
++ bool direct)
++{
++ uint64_t val = 0;
++
++ switch (offset0) {
++ case A_VCMDQ0_BASE_L:
++ val = cmdqv->vcmdq_base[index];
++ break;
++ case A_VCMDQ0_BASE_H:
++ val = cmdqv->vcmdq_base[index] >> 32;
++ break;
++ case A_VCMDQ0_CONS_INDX_BASE_DRAM_L:
++ val = cmdqv->vcmdq_cons_indx_base[index];
++ break;
++ case A_VCMDQ0_CONS_INDX_BASE_DRAM_H:
++ val = cmdqv->vcmdq_cons_indx_base[index] >> 32;
++ break;
++ default:
++ qemu_log_mask(LOG_UNIMP,
++ "%s unhandled read access at 0x%" PRIx64 "\n",
++ __func__, offset0);
++ }
++ trace_tegra241_cmdqv_read_vcmdq_page1(index, direct ? "direct" : "vi",
++ offset0, val);
++ return val;
++}
++
+ static uint64_t tegra241_cmdqv_config_vintf_read(Tegra241CMDQV *cmdqv,
+ hwaddr offset)
+ {
+@@ -93,6 +166,7 @@ static uint64_t tegra241_cmdqv_read_mmio(void *opaque, hwaddr offset,
+ {
+ Tegra241CMDQV *cmdqv = (Tegra241CMDQV *)opaque;
+ uint64_t val = 0;
++ int index;
+
+ if (offset >= TEGRA241_CMDQV_IO_LEN) {
+ qemu_log_mask(LOG_UNIMP,
+@@ -126,6 +200,35 @@ static uint64_t tegra241_cmdqv_read_mmio(void *opaque, hwaddr offset,
+ case A_VINTF0_CONFIG ... A_VINTF0_LVCMDQ_ERR_MAP_3:
+ val = tegra241_cmdqv_config_vintf_read(cmdqv, offset);
+ break;
++ case A_VI_VCMDQ0_CONS_INDX ... A_VI_VCMDQ1_GERRORN:
++ /*
++ * VINTF Page0 registers are hardware aliases of VCMDQ Page0 registers.
++ * Translate the VINTF aperture offset to its VCMDQ Page0 equivalent
++ * before dispatching to the Page 0 helper.
++ */
++ offset -= CMDQV_VINTF_PAGE0_BASE - CMDQV_VCMDQ_PAGE0_BASE;
++ index = (offset - CMDQV_VCMDQ_PAGE0_BASE) / CMDQV_VCMDQ_STRIDE;
++ return tegra241_cmdqv_read_vcmdq_page0(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, false);
++ case A_VCMDQ0_CONS_INDX ... A_VCMDQ1_GERRORN:
++ /*
++ * Decode a per-VCMDQ Page 0 access. Each VCMDQ occupies a
++ * CMDQV_VCMDQ_STRIDE-byte window; extract the index and normalize
++ * to the VCMDQ0_* offset before calling the Page 0 helper.
++ */
++ index = (offset - CMDQV_VCMDQ_PAGE0_BASE) / CMDQV_VCMDQ_STRIDE;
++ return tegra241_cmdqv_read_vcmdq_page0(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, true);
++ case A_VI_VCMDQ0_BASE_L ... A_VI_VCMDQ1_CONS_INDX_BASE_DRAM_H:
++ /* Same VINTF-to-VCMDQ translation as VINTF Page0 case above. */
++ offset -= CMDQV_VINTF_PAGE1_BASE - CMDQV_VCMDQ_PAGE1_BASE;
++ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
++ return tegra241_cmdqv_read_vcmdq_page1(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, false);
++ case A_VCMDQ0_BASE_L ... A_VCMDQ1_CONS_INDX_BASE_DRAM_H:
++ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
++ return tegra241_cmdqv_read_vcmdq_page1(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, true);
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s unhandled read access at 0x%" PRIx64 "\n",
+ __func__, offset);
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+index 4b86aa01d3..cc1b55a5e1 100644
+--- a/hw/arm/tegra241-cmdqv.h
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -30,6 +30,13 @@
+ */
+ #define TEGRA241_CMDQV_IO_LEN 0x50000
+
++/* CMDQV MMIO aperture bases and VCMDQ stride */
++#define CMDQV_VCMDQ_PAGE0_BASE 0x10000 /* CMDQV_CMDQ_BASE */
++#define CMDQV_VCMDQ_PAGE1_BASE 0x20000
++#define CMDQV_VINTF_PAGE0_BASE 0x30000 /* CMDQV_VI_CMDQ_BASE */
++#define CMDQV_VINTF_PAGE1_BASE 0x40000
++#define CMDQV_VCMDQ_STRIDE 0x80
++
+ #define VINTF_PAGE_SIZE 0x10000
+
+ struct iommu_viommu_tegra241_cmdqv;
+@@ -57,6 +64,19 @@ typedef struct Tegra241CMDQV {
+ uint32_t vintf_sid_match[TEGRA241_CMDQV_MAX_NUM_SID];
+ uint32_t vintf_sid_replace[TEGRA241_CMDQV_MAX_NUM_SID];
+ uint32_t vintf_cmdq_err_map[4];
++ /*
++ * VCMDQ register cache. The direct (VCMDQ aperture) and logical
++ * (VINTF aperture) views are hardware aliases; both are served from
++ * this single cached copy.
++ */
++ uint32_t vcmdq_cons_indx[TEGRA241_CMDQV_MAX_CMDQ];
++ uint32_t vcmdq_prod_indx[TEGRA241_CMDQV_MAX_CMDQ];
++ uint32_t vcmdq_config[TEGRA241_CMDQV_MAX_CMDQ];
++ uint32_t vcmdq_status[TEGRA241_CMDQV_MAX_CMDQ];
++ uint32_t vcmdq_gerror[TEGRA241_CMDQV_MAX_CMDQ];
++ uint32_t vcmdq_gerrorn[TEGRA241_CMDQV_MAX_CMDQ];
++ uint64_t vcmdq_base[TEGRA241_CMDQV_MAX_CMDQ];
++ uint64_t vcmdq_cons_indx_base[TEGRA241_CMDQV_MAX_CMDQ];
+ } Tegra241CMDQV;
+
+ /* CMDQ-V Config page registers (offset 0x00000) */
+@@ -148,6 +168,202 @@ REG32(VINTF0_LVCMDQ_ERR_MAP_0, 0x10c0)
+ FIELD(VINTF0_LVCMDQ_ERR_MAP_0, LVCMDQ_ERR_MAP, 0, 32)
+ #define A_VINTF0_LVCMDQ_ERR_MAP_3 (A_VINTF0_LVCMDQ_ERR_MAP_0 + 3 * 4)
+
++/*
++ * Direct VCMDQ aperture register windows.
++ *
++ * Page 0 @ CMDQV_VCMDQ_PAGE0_BASE: VCMDQ control and status registers.
++ * Page 1 @ CMDQV_VCMDQ_PAGE1_BASE: VCMDQ base and DRAM address registers.
++ *
++ * Each VCMDQ occupies a CMDQV_VCMDQ_STRIDE-byte slot within its page.
++ */
++
++/* --- Page 0 register macros --- */
++#define SMMU_CMDQV_VCMDQi_CONS_INDX_(i) \
++ REG32(VCMDQ##i##_CONS_INDX, \
++ CMDQV_VCMDQ_PAGE0_BASE + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_CONS_INDX, RD, 0, 20) \
++ FIELD(VCMDQ##i##_CONS_INDX, ERR, 24, 7)
++
++#define V_VCMDQ_CONS_INDX_ERR_CERROR_NONE 0
++#define V_VCMDQ_CONS_INDX_ERR_CERROR_ILL_OPCODE 1
++#define V_VCMDQ_CONS_INDX_ERR_CERROR_ABT 2
++#define V_VCMDQ_CONS_INDX_ERR_CERROR_ATC_INV_SYNC 3
++#define V_VCMDQ_CONS_INDX_ERR_CERROR_ILL_ACCESS 4
++
++#define SMMU_CMDQV_VCMDQi_PROD_INDX_(i) \
++ REG32(VCMDQ##i##_PROD_INDX, \
++ CMDQV_VCMDQ_PAGE0_BASE + 0x4 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_PROD_INDX, WR, 0, 20)
++
++#define SMMU_CMDQV_VCMDQi_CONFIG_(i) \
++ REG32(VCMDQ##i##_CONFIG, \
++ CMDQV_VCMDQ_PAGE0_BASE + 0x8 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_CONFIG, CMDQ_EN, 0, 1)
++
++#define SMMU_CMDQV_VCMDQi_STATUS_(i) \
++ REG32(VCMDQ##i##_STATUS, \
++ CMDQV_VCMDQ_PAGE0_BASE + 0xc + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_STATUS, CMDQ_EN_OK, 0, 1)
++
++#define SMMU_CMDQV_VCMDQi_GERROR_(i) \
++ REG32(VCMDQ##i##_GERROR, \
++ CMDQV_VCMDQ_PAGE0_BASE + 0x10 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_GERROR, CMDQ_ERR, 0, 1) \
++ FIELD(VCMDQ##i##_GERROR, CONS_DRAM_WR_ABT_ERR, 1, 1) \
++ FIELD(VCMDQ##i##_GERROR, CMDQ_INIT_ERR, 2, 1)
++
++#define SMMU_CMDQV_VCMDQi_GERRORN_(i) \
++ REG32(VCMDQ##i##_GERRORN, \
++ CMDQV_VCMDQ_PAGE0_BASE + 0x14 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_GERRORN, CMDQ_ERR, 0, 1) \
++ FIELD(VCMDQ##i##_GERRORN, CONS_DRAM_WR_ABT_ERR, 1, 1) \
++ FIELD(VCMDQ##i##_GERRORN, CMDQ_INIT_ERR, 2, 1)
++
++/* Page 0 layout: VCMDQ0 */
++SMMU_CMDQV_VCMDQi_CONS_INDX_(0)
++SMMU_CMDQV_VCMDQi_PROD_INDX_(0)
++SMMU_CMDQV_VCMDQi_CONFIG_(0)
++SMMU_CMDQV_VCMDQi_STATUS_(0)
++SMMU_CMDQV_VCMDQi_GERROR_(0)
++SMMU_CMDQV_VCMDQi_GERRORN_(0)
++
++/* Page 0 layout: VCMDQ1 */
++SMMU_CMDQV_VCMDQi_CONS_INDX_(1)
++SMMU_CMDQV_VCMDQi_PROD_INDX_(1)
++SMMU_CMDQV_VCMDQi_CONFIG_(1)
++SMMU_CMDQV_VCMDQi_STATUS_(1)
++SMMU_CMDQV_VCMDQi_GERROR_(1)
++SMMU_CMDQV_VCMDQi_GERRORN_(1)
++
++/* --- Page 1 register macros --- */
++#define SMMU_CMDQV_VCMDQi_BASE_L_(i) \
++ REG32(VCMDQ##i##_BASE_L, CMDQV_VCMDQ_PAGE1_BASE + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_BASE_L, LOG2SIZE, 0, 5) \
++ FIELD(VCMDQ##i##_BASE_L, ADDR, 5, 27)
++
++#define SMMU_CMDQV_VCMDQi_BASE_H_(i) \
++ REG32(VCMDQ##i##_BASE_H, \
++ CMDQV_VCMDQ_PAGE1_BASE + 0x4 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_BASE_H, ADDR, 0, 16)
++
++#define SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_L_(i) \
++ REG32(VCMDQ##i##_CONS_INDX_BASE_DRAM_L, \
++ CMDQV_VCMDQ_PAGE1_BASE + 0x8 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_CONS_INDX_BASE_DRAM_L, ADDR, 0, 32)
++
++#define SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_H_(i) \
++ REG32(VCMDQ##i##_CONS_INDX_BASE_DRAM_H, \
++ CMDQV_VCMDQ_PAGE1_BASE + 0xc + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VCMDQ##i##_CONS_INDX_BASE_DRAM_H, ADDR, 0, 16)
++
++/* Page 1 layout: VCMDQ0 */
++SMMU_CMDQV_VCMDQi_BASE_L_(0)
++SMMU_CMDQV_VCMDQi_BASE_H_(0)
++SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_L_(0)
++SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_H_(0)
++
++/* Page 1 layout: VCMDQ1 */
++SMMU_CMDQV_VCMDQi_BASE_L_(1)
++SMMU_CMDQV_VCMDQi_BASE_H_(1)
++SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_L_(1)
++SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_H_(1)
++
++/*
++ * VINTF0 logical VCMDQ aperture register windows.
++ *
++ * Page 0 @ CMDQV_VINTF_PAGE0_BASE: VCMDQ control and status registers.
++ * Page 1 @ CMDQV_VINTF_PAGE1_BASE: VCMDQ base and DRAM address registers.
++ *
++ * VCMDQs mapped via VINTF are accessed through this aperture as
++ * hardware aliases of the direct VCMDQ aperture above.
++ */
++
++/* --- Page 0 register macros --- */
++#define SMMU_CMDQV_VI_VCMDQi_CONS_INDX_(i) \
++ REG32(VI_VCMDQ##i##_CONS_INDX, \
++ CMDQV_VINTF_PAGE0_BASE + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_CONS_INDX, RD, 0, 20) \
++ FIELD(VI_VCMDQ##i##_CONS_INDX, ERR, 24, 7)
++
++#define SMMU_CMDQV_VI_VCMDQi_PROD_INDX_(i) \
++ REG32(VI_VCMDQ##i##_PROD_INDX, \
++ CMDQV_VINTF_PAGE0_BASE + 0x4 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_PROD_INDX, WR, 0, 20)
++
++#define SMMU_CMDQV_VI_VCMDQi_CONFIG_(i) \
++ REG32(VI_VCMDQ##i##_CONFIG, \
++ CMDQV_VINTF_PAGE0_BASE + 0x8 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_CONFIG, CMDQ_EN, 0, 1)
++
++#define SMMU_CMDQV_VI_VCMDQi_STATUS_(i) \
++ REG32(VI_VCMDQ##i##_STATUS, \
++ CMDQV_VINTF_PAGE0_BASE + 0xc + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_STATUS, CMDQ_EN_OK, 0, 1)
++
++#define SMMU_CMDQV_VI_VCMDQi_GERROR_(i) \
++ REG32(VI_VCMDQ##i##_GERROR, \
++ CMDQV_VINTF_PAGE0_BASE + 0x10 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_GERROR, CMDQ_ERR, 0, 1) \
++ FIELD(VI_VCMDQ##i##_GERROR, CONS_DRAM_WR_ABT_ERR, 1, 1) \
++ FIELD(VI_VCMDQ##i##_GERROR, CMDQ_INIT_ERR, 2, 1)
++
++#define SMMU_CMDQV_VI_VCMDQi_GERRORN_(i) \
++ REG32(VI_VCMDQ##i##_GERRORN, \
++ CMDQV_VINTF_PAGE0_BASE + 0x14 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_GERRORN, CMDQ_ERR, 0, 1) \
++ FIELD(VI_VCMDQ##i##_GERRORN, CONS_DRAM_WR_ABT_ERR, 1, 1) \
++ FIELD(VI_VCMDQ##i##_GERRORN, CMDQ_INIT_ERR, 2, 1)
++
++/* Page 0 layout: VCMDQ0 */
++SMMU_CMDQV_VI_VCMDQi_CONS_INDX_(0)
++SMMU_CMDQV_VI_VCMDQi_PROD_INDX_(0)
++SMMU_CMDQV_VI_VCMDQi_CONFIG_(0)
++SMMU_CMDQV_VI_VCMDQi_STATUS_(0)
++SMMU_CMDQV_VI_VCMDQi_GERROR_(0)
++SMMU_CMDQV_VI_VCMDQi_GERRORN_(0)
++
++/* Page 0 layout: VCMDQ1 */
++SMMU_CMDQV_VI_VCMDQi_CONS_INDX_(1)
++SMMU_CMDQV_VI_VCMDQi_PROD_INDX_(1)
++SMMU_CMDQV_VI_VCMDQi_CONFIG_(1)
++SMMU_CMDQV_VI_VCMDQi_STATUS_(1)
++SMMU_CMDQV_VI_VCMDQi_GERROR_(1)
++SMMU_CMDQV_VI_VCMDQi_GERRORN_(1)
++
++/* --- Page 1 register macros --- */
++#define SMMU_CMDQV_VI_VCMDQi_BASE_L_(i) \
++ REG32(VI_VCMDQ##i##_BASE_L, \
++ CMDQV_VINTF_PAGE1_BASE + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_BASE_L, LOG2SIZE, 0, 5) \
++ FIELD(VI_VCMDQ##i##_BASE_L, ADDR, 5, 27)
++
++#define SMMU_CMDQV_VI_VCMDQi_BASE_H_(i) \
++ REG32(VI_VCMDQ##i##_BASE_H, \
++ CMDQV_VINTF_PAGE1_BASE + 0x4 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_BASE_H, ADDR, 0, 16)
++
++#define SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_L_(i) \
++ REG32(VI_VCMDQ##i##_CONS_INDX_BASE_DRAM_L, \
++ CMDQV_VINTF_PAGE1_BASE + 0x8 + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_CONS_INDX_BASE_DRAM_L, ADDR, 0, 32)
++
++#define SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_H_(i) \
++ REG32(VI_VCMDQ##i##_CONS_INDX_BASE_DRAM_H, \
++ CMDQV_VINTF_PAGE1_BASE + 0xc + i * CMDQV_VCMDQ_STRIDE) \
++ FIELD(VI_VCMDQ##i##_CONS_INDX_BASE_DRAM_H, ADDR, 0, 16)
++
++/* Page 1 layout: VCMDQ0 */
++SMMU_CMDQV_VI_VCMDQi_BASE_L_(0)
++SMMU_CMDQV_VI_VCMDQi_BASE_H_(0)
++SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_L_(0)
++SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_H_(0)
++
++/* Page 1 layout: VCMDQ1 */
++SMMU_CMDQV_VI_VCMDQi_BASE_L_(1)
++SMMU_CMDQV_VI_VCMDQi_BASE_H_(1)
++SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_L_(1)
++SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_H_(1)
++
+ const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
+
+ #endif /* HW_ARM_TEGRA241_CMDQV_H */
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index 8c61d66a26..5156604228 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -75,6 +75,8 @@ smmuv3_accel_install_ste(uint32_t vsid, const char * type, uint32_t hwpt_id) "vS
+ # tegra241-cmdqv
+ tegra241_cmdqv_read_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
+ tegra241_cmdqv_write_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
++tegra241_cmdqv_read_vcmdq_page0(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
++tegra241_cmdqv_read_vcmdq_page1(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
+
+ # strongarm.c
+ strongarm_uart_update_parameters(const char *label, int speed, char parity, int data_bits, int stop_bits) "%s speed=%d parity=%c data=%d stop=%d"
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-writes.patch b/kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-writes.patch
new file mode 100644
index 0000000..b09a59a
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-writes.patch
@@ -0,0 +1,264 @@
+From 0cd4d9d91be6d973f4dedb5414f6ed9819b4be49 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:38 +0100
+Subject: [PATCH 096/111] hw/arm/tegra241-cmdqv: Emulate VCMDQ register writes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [96/111] f9145dcb13afc681df094d30fecbfc211913410f (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+This is the write side counterpart of the VCMDQ read emulation. Add
+write handling for both the direct VCMDQ aperture and the VINTF
+logical aperture using the same index decoding and VINTF-to-VCMDQ
+translation logic as the read path.
+
+VINTF aperture writes are translated to their direct-aperture
+equivalent and update the same cached state. Page 1 registers
+(BASE, CONS_INDX_BASE) always update the cache.
+
+Per the CMDQV architecture, a VCMDQ must be allocated to a Virtual
+Interface before it is used to send commands to the SMMU. Until
+that allocation happens, MMIO writes only update cached register
+state - no command consumption, error handling, or interrupt
+activity is driven from these writes. Subsequent patches wire up
+IOMMU_HW_QUEUE_ALLOC, mmap the host VINTF Page 0, and install it
+into guest MMIO; after that, Page 0 writes from either aperture
+reach the hardware-backed mmap'd page instead of just the cache.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260609112552.378999-18-skolothumtho@nvidia.com
+Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit bbe6bc469a96c64a66e221d83605fe71d248ff9f)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 159 +++++++++++++++++++++++++++++++++++++++-
+ hw/arm/trace-events | 2 +
+ 2 files changed, 159 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 2dfd377ee9..1f3d883cfe 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -120,6 +120,104 @@ static uint64_t tegra241_cmdqv_config_vintf_read(Tegra241CMDQV *cmdqv,
+ }
+ }
+
++/*
++ * Write a VCMDQ Page 0 register (control/status) using VCMDQ0_* offsets.
++ *
++ * The caller normalizes the MMIO offset such that @offset0 always refers
++ * to a VCMDQ0_* register, while @index selects the VCMDQ instance.
++ *
++ * Page 0 registers are all 32-bit; this helper is only called for 4-byte
++ * writes.
++ */
++static void tegra241_cmdqv_write_vcmdq_page0(Tegra241CMDQV *cmdqv,
++ hwaddr offset0, int index,
++ uint32_t value, bool direct)
++{
++ switch (offset0) {
++ case A_VCMDQ0_CONS_INDX:
++ cmdqv->vcmdq_cons_indx[index] = value;
++ break;
++ case A_VCMDQ0_PROD_INDX:
++ /* VCMDQ is functional only once allocated to a VINTF; cache only. */
++ cmdqv->vcmdq_prod_indx[index] = value;
++ break;
++ case A_VCMDQ0_CONFIG:
++ if (value & R_VCMDQ0_CONFIG_CMDQ_EN_MASK) {
++ cmdqv->vcmdq_status[index] |= R_VCMDQ0_STATUS_CMDQ_EN_OK_MASK;
++ } else {
++ cmdqv->vcmdq_status[index] &= ~R_VCMDQ0_STATUS_CMDQ_EN_OK_MASK;
++ }
++ cmdqv->vcmdq_config[index] = value;
++ break;
++ case A_VCMDQ0_GERRORN:
++ /* VCMDQ is functional only once allocated to a VINTF; cache only. */
++ cmdqv->vcmdq_gerrorn[index] = value;
++ break;
++ default:
++ qemu_log_mask(LOG_UNIMP,
++ "%s unhandled write access at 0x%" PRIx64 "\n",
++ __func__, offset0);
++ }
++ trace_tegra241_cmdqv_write_vcmdq_page0(index, direct ? "direct" : "vi",
++ offset0, value);
++}
++
++/*
++ * Write a VCMDQ Page 1 register (base / DRAM address) - 4-byte access.
++ */
++static void tegra241_cmdqv_write_vcmdq_page1(Tegra241CMDQV *cmdqv,
++ hwaddr offset0, int index,
++ uint32_t value, bool direct)
++{
++ switch (offset0) {
++ case A_VCMDQ0_BASE_L:
++ cmdqv->vcmdq_base[index] =
++ deposit64(cmdqv->vcmdq_base[index], 0, 32, value);
++ break;
++ case A_VCMDQ0_BASE_H:
++ cmdqv->vcmdq_base[index] =
++ deposit64(cmdqv->vcmdq_base[index], 32, 32, value);
++ break;
++ case A_VCMDQ0_CONS_INDX_BASE_DRAM_L:
++ cmdqv->vcmdq_cons_indx_base[index] =
++ deposit64(cmdqv->vcmdq_cons_indx_base[index], 0, 32, value);
++ break;
++ case A_VCMDQ0_CONS_INDX_BASE_DRAM_H:
++ cmdqv->vcmdq_cons_indx_base[index] =
++ deposit64(cmdqv->vcmdq_cons_indx_base[index], 32, 32, value);
++ break;
++ default:
++ qemu_log_mask(LOG_UNIMP,
++ "%s unhandled write access at 0x%" PRIx64 "\n",
++ __func__, offset0);
++ }
++ trace_tegra241_cmdqv_write_vcmdq_page1(index, direct ? "direct" : "vi",
++ offset0, value);
++}
++
++/*
++ * Write a VCMDQ Page 1 register - 8-byte access at BASE_L or DRAM_L.
++ */
++static void tegra241_cmdqv_write_vcmdq_page1_64(Tegra241CMDQV *cmdqv,
++ hwaddr offset0, int index,
++ uint64_t value, bool direct)
++{
++ switch (offset0) {
++ case A_VCMDQ0_BASE_L:
++ cmdqv->vcmdq_base[index] = value;
++ break;
++ case A_VCMDQ0_CONS_INDX_BASE_DRAM_L:
++ cmdqv->vcmdq_cons_indx_base[index] = value;
++ break;
++ default:
++ qemu_log_mask(LOG_UNIMP,
++ "%s unhandled 64-bit write at 0x%" PRIx64 "\n",
++ __func__, offset0);
++ }
++ trace_tegra241_cmdqv_write_vcmdq_page1(index, direct ? "direct" : "vi",
++ offset0, value);
++}
++
+ static void tegra241_cmdqv_config_vintf_write(Tegra241CMDQV *cmdqv,
+ hwaddr offset, uint64_t value)
+ {
+@@ -243,6 +341,8 @@ out:
+ static void tegra241_cmdqv_writel_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ uint32_t value)
+ {
++ int index;
++
+ switch (offset) {
+ case A_CONFIG:
+ cmdqv->config = value;
+@@ -261,6 +361,39 @@ static void tegra241_cmdqv_writel_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ case A_VINTF0_CONFIG ... A_VINTF0_LVCMDQ_ERR_MAP_3:
+ tegra241_cmdqv_config_vintf_write(cmdqv, offset, value);
+ break;
++ case A_VI_VCMDQ0_CONS_INDX ... A_VI_VCMDQ1_GERRORN:
++ /*
++ * VINTF Page0 registers are hardware aliases of VCMDQ Page0 registers.
++ * Translate the VINTF aperture offset to its VCMDQ Page0 equivalent
++ * before dispatching to the Page 0 helper.
++ */
++ offset -= CMDQV_VINTF_PAGE0_BASE - CMDQV_VCMDQ_PAGE0_BASE;
++ index = (offset - CMDQV_VCMDQ_PAGE0_BASE) / CMDQV_VCMDQ_STRIDE;
++ tegra241_cmdqv_write_vcmdq_page0(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, false);
++ break;
++ case A_VCMDQ0_CONS_INDX ... A_VCMDQ1_GERRORN:
++ /*
++ * Decode a per-VCMDQ Page 0 access. Each VCMDQ occupies a
++ * CMDQV_VCMDQ_STRIDE-byte window; extract the index and normalize
++ * to the VCMDQ0_* offset before calling the Page 0 helper.
++ */
++ index = (offset - CMDQV_VCMDQ_PAGE0_BASE) / CMDQV_VCMDQ_STRIDE;
++ tegra241_cmdqv_write_vcmdq_page0(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, true);
++ break;
++ case A_VI_VCMDQ0_BASE_L ... A_VI_VCMDQ1_CONS_INDX_BASE_DRAM_H:
++ /* Same VINTF-to-VCMDQ translation as VINTF Page0 case above. */
++ offset -= CMDQV_VINTF_PAGE1_BASE - CMDQV_VCMDQ_PAGE1_BASE;
++ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
++ tegra241_cmdqv_write_vcmdq_page1(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, false);
++ break;
++ case A_VCMDQ0_BASE_L ... A_VCMDQ1_CONS_INDX_BASE_DRAM_H:
++ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
++ tegra241_cmdqv_write_vcmdq_page1(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, true);
++ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s unhandled write access at 0x%" PRIx64 "\n",
+ __func__, offset);
+@@ -268,14 +401,36 @@ static void tegra241_cmdqv_writel_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ }
+
+ /*
+- * 8-byte MMIO write handler.
++ * 8-byte MMIO write handler. Only Page 1 BASE / CONS_INDX_BASE_DRAM accept
++ * full 64-bit writes; other offsets are write-ignored.
+ */
+ static void tegra241_cmdqv_writell_mmio(Tegra241CMDQV *cmdqv, hwaddr offset,
+ uint64_t value)
+ {
+- qemu_log_mask(LOG_UNIMP,
++ int index;
++
++ switch (offset) {
++ case A_VI_VCMDQ0_BASE_L ... A_VI_VCMDQ1_CONS_INDX_BASE_DRAM_H:
++ /*
++ * VINTF Page1 registers are hardware aliases of VCMDQ Page1 registers.
++ * Translate the VINTF aperture offset to its VCMDQ Page1 equivalent
++ * before dispatching to the Page 1 helper.
++ */
++ offset -= CMDQV_VINTF_PAGE1_BASE - CMDQV_VCMDQ_PAGE1_BASE;
++ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
++ tegra241_cmdqv_write_vcmdq_page1_64(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, false);
++ break;
++ case A_VCMDQ0_BASE_L ... A_VCMDQ1_CONS_INDX_BASE_DRAM_H:
++ index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
++ tegra241_cmdqv_write_vcmdq_page1_64(cmdqv,
++ offset - index * CMDQV_VCMDQ_STRIDE, index, value, true);
++ break;
++ default:
++ qemu_log_mask(LOG_UNIMP,
+ "%s unhandled 64-bit write at 0x%" PRIx64 " (WI)\n",
+ __func__, offset);
++ }
+ }
+
+ static void tegra241_cmdqv_write_mmio(void *opaque, hwaddr offset,
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index 5156604228..666967dc5e 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -77,6 +77,8 @@ tegra241_cmdqv_read_mmio(uint64_t offset, uint64_t val, unsigned size) "offset:
+ tegra241_cmdqv_write_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
+ tegra241_cmdqv_read_vcmdq_page0(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
+ tegra241_cmdqv_read_vcmdq_page1(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
++tegra241_cmdqv_write_vcmdq_page0(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
++tegra241_cmdqv_write_vcmdq_page1(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
+
+ # strongarm.c
+ strongarm_uart_update_parameters(const char *label, int speed, char parity, int data_bits, int stop_bits) "%s speed=%d parity=%c data=%d stop=%d"
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-init.patch b/kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-init.patch
new file mode 100644
index 0000000..7c80ba4
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-init.patch
@@ -0,0 +1,163 @@
+From 45e38151ba9dbaed137e4a8df39e4ab795ac39ab Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:32 +0100
+Subject: [PATCH 090/111] hw/arm/tegra241-cmdqv: Implement CMDQV init
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [90/111] 88aae2a631de96c673ac5615e40b98040a2a4961 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Tegra241 CMDQV extends SMMUv3 with support for virtual command queues
+(VCMDQs) exposed via a CMDQV MMIO region. The CMDQV MMIO space is split
+into 64KB pages:
+
+0x00000 (CMDQ-V Config page)
+0x10000 (CMDQ-V CMDQ Page0)
+0x20000 (CMDQ-V CMDQ Page1)
+0x30000 (Virtual Interface Page0)
+0x40000 (Virtual Interface Page1)
+
+This patch wires up the Tegra241 CMDQV init callback and allocates
+vendor-specific CMDQV state. The state pointer is stored in
+SMMUv3AccelState for use by subsequent CMDQV operations.
+
+The CMDQV MMIO region and a dedicated IRQ line are registered with the
+SMMUv3 device. The MMIO read/write handlers are currently stubs and will
+be implemented in later patches.
+
+The CMDQV interrupt is edge-triggered and indicates VCMDQ or VINTF
+error conditions. This patch only registers the IRQ line. Interrupt
+generation and propagation to the guest will be added in a subsequent
+patch.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260609112552.378999-12-skolothumtho@nvidia.com
+Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit b110918bce7c65bd514c5dfd36e6abc8c21534f5)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.h | 1 +
+ hw/arm/tegra241-cmdqv.c | 40 ++++++++++++++++++++++++++++++++++++++--
+ hw/arm/tegra241-cmdqv.h | 20 ++++++++++++++++++++
+ 3 files changed, 59 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index b45f25ad03..e0bbec8581 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -61,6 +61,7 @@ typedef struct SMMUv3AccelState {
+ bool auto_mode;
+ bool auto_finalised;
+ const SMMUv3AccelCmdqvOps *cmdqv_ops;
++ void *cmdqv; /* vendor specific CMDQV state */
+ } SMMUv3AccelState;
+
+ typedef struct SMMUS1Hwpt {
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 3a19a1af56..2875affc8d 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -13,6 +13,17 @@
+ #include "smmuv3-accel.h"
+ #include "tegra241-cmdqv.h"
+
++static uint64_t tegra241_cmdqv_read_mmio(void *opaque, hwaddr offset,
++ unsigned size)
++{
++ return 0;
++}
++
++static void tegra241_cmdqv_write_mmio(void *opaque, hwaddr offset,
++ uint64_t value, unsigned size)
++{
++}
++
+ static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
+ {
+ }
+@@ -29,10 +40,35 @@ static void tegra241_cmdqv_reset(SMMUv3State *s)
+ {
+ }
+
++static const MemoryRegionOps mmio_cmdqv_ops = {
++ .read = tegra241_cmdqv_read_mmio,
++ .write = tegra241_cmdqv_write_mmio,
++ .endianness = DEVICE_LITTLE_ENDIAN,
++ .valid = {
++ .min_access_size = 4,
++ .max_access_size = 8,
++ },
++ .impl = {
++ .min_access_size = 4,
++ .max_access_size = 8,
++ },
++};
++
+ static bool tegra241_cmdqv_init(SMMUv3State *s, Error **errp)
+ {
+- error_setg(errp, "NVIDIA Tegra241 CMDQV is unsupported");
+- return false;
++ SysBusDevice *sbd = SYS_BUS_DEVICE(OBJECT(s));
++ SMMUv3AccelState *accel = s->s_accel;
++ Tegra241CMDQV *cmdqv;
++
++ cmdqv = g_new0(Tegra241CMDQV, 1);
++ cmdqv->cmdqv_data = g_new0(struct iommu_viommu_tegra241_cmdqv, 1);
++ memory_region_init_io(&cmdqv->mmio_cmdqv, OBJECT(s), &mmio_cmdqv_ops, cmdqv,
++ "tegra241-cmdqv", TEGRA241_CMDQV_IO_LEN);
++ sysbus_init_mmio(sbd, &cmdqv->mmio_cmdqv);
++ sysbus_init_irq(sbd, &cmdqv->irq);
++ cmdqv->s_accel = accel;
++ accel->cmdqv = cmdqv;
++ return true;
+ }
+
+ static bool tegra241_cmdqv_probe(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+index 38c8b27b4d..a5f65a8991 100644
+--- a/hw/arm/tegra241-cmdqv.h
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -14,6 +14,26 @@
+ #define CMDQV_NUM_CMDQ_LOG2 1
+ #define CMDQV_NUM_SID_PER_VI_LOG2 4
+
++/*
++ * Tegra241 CMDQV MMIO layout (64KB pages)
++ *
++ * 0x00000 (CMDQ-V Config page)
++ * 0x10000 (CMDQ-V CMDQ Page0)
++ * 0x20000 (CMDQ-V CMDQ Page1)
++ * 0x30000 (Virtual Interface Page0)
++ * 0x40000 (Virtual Interface Page1)
++ */
++#define TEGRA241_CMDQV_IO_LEN 0x50000
++
++struct iommu_viommu_tegra241_cmdqv;
++
++typedef struct Tegra241CMDQV {
++ struct iommu_viommu_tegra241_cmdqv *cmdqv_data;
++ SMMUv3AccelState *s_accel;
++ MemoryRegion mmio_cmdqv;
++ qemu_irq irq;
++} Tegra241CMDQV;
++
+ const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
+
+ #endif /* HW_ARM_TEGRA241_CMDQV_H */
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-vIOMMU-alloc-f.patch b/kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-vIOMMU-alloc-f.patch
new file mode 100644
index 0000000..8ea5615
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-vIOMMU-alloc-f.patch
@@ -0,0 +1,130 @@
+From ee99c9bf31e30f284e374d8b02c44b8fdaf4139f Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:34 +0100
+Subject: [PATCH 092/111] hw/arm/tegra241-cmdqv: Implement CMDQV vIOMMU
+ alloc/free
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [92/111] f932036d720a12681cb5515842421d3ce56e9e30 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Replace the stub implementation with real vIOMMU allocation for
+Tegra241 CMDQV.
+
+Allocate a matching vEVENTQ together with the vIOMMU, since it is
+specific to the Tegra241 CMDQV vIOMMU and used to receive CMDQV
+events.
+
+Free both objects on teardown.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260609112552.378999-14-skolothumtho@nvidia.com
+Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 43763a1ab76fb618119bb76b0e4a93b599b40f13)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 48 ++++++++++++++++++++++++++++++++++++++++-
+ hw/arm/tegra241-cmdqv.h | 1 +
+ 2 files changed, 48 insertions(+), 1 deletion(-)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 2875affc8d..c1351c8519 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -10,6 +10,7 @@
+ #include "qemu/osdep.h"
+
+ #include "hw/arm/smmuv3.h"
++#include "hw/arm/smmuv3-common.h"
+ #include "smmuv3-accel.h"
+ #include "tegra241-cmdqv.h"
+
+@@ -26,13 +27,58 @@ static void tegra241_cmdqv_write_mmio(void *opaque, hwaddr offset,
+
+ static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
+ {
++ SMMUv3AccelState *accel = s->s_accel;
++ IOMMUFDViommu *viommu = accel->viommu;
++ Tegra241CMDQV *cmdqv = accel->cmdqv;
++ IOMMUFDVeventq *veventq = cmdqv->veventq;
++
++ if (!viommu) {
++ return;
++ }
++ if (veventq) {
++ close(veventq->veventq_fd);
++ iommufd_backend_free_id(viommu->iommufd, veventq->veventq_id);
++ g_free(veventq);
++ cmdqv->veventq = NULL;
++ }
++ iommufd_backend_free_id(viommu->iommufd, viommu->viommu_id);
+ }
+
+ static bool
+ tegra241_cmdqv_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ uint32_t *out_viommu_id, Error **errp)
+ {
+- error_setg(errp, "NVIDIA Tegra241 CMDQV is unsupported");
++ Tegra241CMDQV *cmdqv = s->s_accel->cmdqv;
++ uint32_t viommu_id, veventq_id, veventq_fd;
++ IOMMUFDVeventq *veventq;
++
++ if (!iommufd_backend_alloc_viommu(idev->iommufd, idev->devid,
++ IOMMU_VIOMMU_TYPE_TEGRA241_CMDQV,
++ idev->hwpt_id, cmdqv->cmdqv_data,
++ sizeof(*cmdqv->cmdqv_data), &viommu_id,
++ errp)) {
++ return false;
++ }
++
++ if (!iommufd_backend_alloc_veventq(idev->iommufd, viommu_id,
++ IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV,
++ 1 << SMMU_EVENTQS, &veventq_id,
++ &veventq_fd,
++ errp)) {
++ error_append_hint(errp, "Tegra241 CMDQV: failed to alloc veventq");
++ goto free_viommu;
++ }
++
++ veventq = g_new(IOMMUFDVeventq, 1);
++ veventq->veventq_id = veventq_id;
++ veventq->veventq_fd = veventq_fd;
++ cmdqv->veventq = veventq;
++
++ *out_viommu_id = viommu_id;
++ return true;
++
++free_viommu:
++ iommufd_backend_free_id(idev->iommufd, viommu_id);
+ return false;
+ }
+
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+index a5f65a8991..9fc720e96c 100644
+--- a/hw/arm/tegra241-cmdqv.h
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -32,6 +32,7 @@ typedef struct Tegra241CMDQV {
+ SMMUv3AccelState *s_accel;
+ MemoryRegion mmio_cmdqv;
+ qemu_irq irq;
++ IOMMUFDVeventq *veventq;
+ } Tegra241CMDQV;
+
+ const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Initialize-register-state-on-r.patch b/kvm-hw-arm-tegra241-cmdqv-Initialize-register-state-on-r.patch
new file mode 100644
index 0000000..4e42547
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Initialize-register-state-on-r.patch
@@ -0,0 +1,120 @@
+From 3d0860d341a6cfb580cb1f5369fc42c8e5edf7e5 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:45 +0100
+Subject: [PATCH 103/111] hw/arm/tegra241-cmdqv: Initialize register state on
+ reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [103/111] c7d9172502f2e3ab87e9205b814f5f6e80637eee (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Initialize the Tegra241 CMDQV register state in the reset handler.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-25-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit ae1a6a69c002fc331861be505d641014198bc33e)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 38 ++++++++++++++++++++++++++++++++++++++
+ hw/arm/tegra241-cmdqv.h | 3 +++
+ hw/arm/trace-events | 1 +
+ 3 files changed, 42 insertions(+)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 71d02ae740..6804f0bb7e 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -863,6 +863,42 @@ free_viommu:
+ return false;
+ }
+
++static void tegra241_cmdqv_init_regs(SMMUv3State *s, Tegra241CMDQV *cmdqv)
++{
++ int i;
++
++ cmdqv->config = V_CONFIG_RESET;
++ cmdqv->param = FIELD_DP32(0, PARAM, CMDQV_VER, CMDQV_VER);
++ cmdqv->param = FIELD_DP32(cmdqv->param, PARAM, CMDQV_NUM_CMDQ_LOG2,
++ CMDQV_NUM_CMDQ_LOG2);
++ cmdqv->param = FIELD_DP32(cmdqv->param, PARAM, CMDQV_NUM_SID_PER_VI_LOG2,
++ CMDQV_NUM_SID_PER_VI_LOG2);
++ trace_tegra241_cmdqv_init_regs(cmdqv->param);
++ cmdqv->status = R_STATUS_CMDQV_ENABLED_MASK;
++
++ for (i = 0; i < 2; i++) {
++ cmdqv->vi_err_map[i] = 0;
++ cmdqv->vi_int_mask[i] = 0;
++ }
++ for (i = 0; i < 4; i++) {
++ cmdqv->cmdq_err_map[i] = 0;
++ cmdqv->vintf_cmdq_err_map[i] = 0;
++ }
++ cmdqv->vintf_config = 0;
++ cmdqv->vintf_status = 0;
++ for (i = 0; i < TEGRA241_CMDQV_MAX_CMDQ; i++) {
++ cmdqv->cmdq_alloc_map[i] = 0;
++ cmdqv->vcmdq_cons_indx[i] = 0;
++ cmdqv->vcmdq_prod_indx[i] = 0;
++ cmdqv->vcmdq_config[i] = 0;
++ cmdqv->vcmdq_status[i] = 0;
++ cmdqv->vcmdq_gerror[i] = 0;
++ cmdqv->vcmdq_gerrorn[i] = 0;
++ cmdqv->vcmdq_base[i] = 0;
++ cmdqv->vcmdq_cons_indx_base[i] = 0;
++ }
++}
++
+ static void tegra241_cmdqv_reset(SMMUv3State *s)
+ {
+ Tegra241CMDQV *cmdqv = s->s_accel->cmdqv;
+@@ -873,6 +909,8 @@ static void tegra241_cmdqv_reset(SMMUv3State *s)
+
+ tegra241_cmdqv_guest_unmap_vintf_page0(cmdqv);
+ tegra241_cmdqv_free_all_vcmdq(cmdqv);
++
++ tegra241_cmdqv_init_regs(s, cmdqv);
+ }
+
+ static const MemoryRegionOps mmio_cmdqv_ops = {
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+index 0964f68a20..a924e7e90f 100644
+--- a/hw/arm/tegra241-cmdqv.h
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -89,6 +89,9 @@ FIELD(CONFIG, CMDQ_MAX_CLK_BATCH, 4, 8)
+ FIELD(CONFIG, CMDQ_MAX_CMD_BATCH, 12, 8)
+ FIELD(CONFIG, CONS_DRAM_EN, 20, 1)
+
++/* CMDQV_EN=1, PER_CMD_OFFSET=16B, CLK_BATCH=256, CMD_BATCH=32. */
++#define V_CONFIG_RESET 0x00020083
++
+ REG32(PARAM, 0x4)
+ FIELD(PARAM, CMDQV_VER, 0, 4)
+ FIELD(PARAM, CMDQV_NUM_CMDQ_LOG2, 4, 4)
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index dbed00afbb..0bd718b1ab 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -76,6 +76,7 @@ smmuv3_accel_install_ste(uint32_t vsid, const char * type, uint32_t hwpt_id) "vS
+ tegra241_cmdqv_read_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
+ tegra241_cmdqv_write_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
+ tegra241_cmdqv_err_map(uint32_t map3, uint32_t map2, uint32_t map1, uint32_t map0) "hw irq received. error (hex) maps: %04X:%04X:%04X:%04X"
++tegra241_cmdqv_init_regs(uint32_t param) "register init, param=0x%08X"
+ tegra241_cmdqv_read_vcmdq_page0(int index, const char *aperture, const char *backing, uint64_t offset0, uint64_t val) "vcmdq[%d] %s (%s) offset0: 0x%"PRIx64" val: 0x%"PRIx64
+ tegra241_cmdqv_read_vcmdq_page1(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
+ tegra241_cmdqv_write_vcmdq_page0(int index, const char *aperture, const char *backing, uint64_t offset0, uint64_t val) "vcmdq[%d] %s (%s) offset0: 0x%"PRIx64" val: 0x%"PRIx64
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Limit-queue-size-based-on-back.patch b/kvm-hw-arm-tegra241-cmdqv-Limit-queue-size-based-on-back.patch
new file mode 100644
index 0000000..aaa2e43
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Limit-queue-size-based-on-back.patch
@@ -0,0 +1,97 @@
+From e87230889999d19b5bb045670cca5721e4e92533 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:46 +0100
+Subject: [PATCH 104/111] hw/arm/tegra241-cmdqv: Limit queue size based on
+ backend page size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [104/111] a3c4ec875272161cf41791a9806a4a085a659ffa (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+CMDQV HW performs DMA accesses to guest queue memory by its host
+physical address set up via IOMMUFD. This requires the guest queue
+to be contiguous in both guest PA and host PA space. With Tegra241
+CMDQV enabled, we must only advertise a command queue size (CMDQS)
+that the host can safely back with physically contiguous memory.
+Allowing a queue size larger than the host page size could cause
+the hardware to DMA across page boundaries, leading to faults.
+
+Use qemu_minrampagesize() to find the smallest memory-backend page
+size in use, then cap IDR1.CMDQS so the guest cannot configure a
+command queue that exceeds that contiguous backing.
+
+Note this is done at SMMUv3 init, before any guest queue GPA is
+known, so the cap is conservative. Maximum queue size is 8MiB;
+it is recommended to back the VM with hugepage sizes large enough
+so CMDQS stays at the HW maximum. Smaller backing pages reduce
+CMDQS accordingly.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-26-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 0552f94fbdb6d2a3cee292911353241b1ba534cd)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 6804f0bb7e..a4c140e34c 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -14,6 +14,8 @@
+ #include "hw/arm/smmuv3-common.h"
+ #include "hw/irq.h"
+ #include "smmuv3-accel.h"
++#include "smmuv3-internal.h"
++#include "system/hostmem.h"
+ #include "tegra241-cmdqv.h"
+ #include "trace.h"
+
+@@ -866,6 +868,8 @@ free_viommu:
+ static void tegra241_cmdqv_init_regs(SMMUv3State *s, Tegra241CMDQV *cmdqv)
+ {
+ int i;
++ long pgsize;
++ uint32_t val;
+
+ cmdqv->config = V_CONFIG_RESET;
+ cmdqv->param = FIELD_DP32(0, PARAM, CMDQV_VER, CMDQV_VER);
+@@ -897,6 +901,22 @@ static void tegra241_cmdqv_init_regs(SMMUv3State *s, Tegra241CMDQV *cmdqv)
+ cmdqv->vcmdq_base[i] = 0;
+ cmdqv->vcmdq_cons_indx_base[i] = 0;
+ }
++
++ /*
++ * CMDQ must not cross a physical RAM backend page. Adjust CMDQS so the
++ * queue fits entirely within the smallest backend page size, ensuring
++ * the command queue is physically contiguous in host memory.
++ *
++ * IDR1.CMDQS = log2(max_qsz) - entry_shift
++ *
++ * where entry_shift = 4 (each CMDQ entry is 16 bytes = 2^4).
++ */
++ pgsize = qemu_minrampagesize();
++ if (pgsize == LONG_MAX) {
++ pgsize = qemu_real_host_page_size();
++ }
++ val = FIELD_EX32(s->idr[1], IDR1, CMDQS);
++ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, CMDQS, MIN(ctz64(pgsize) - 4, val));
+ }
+
+ static void tegra241_cmdqv_reset(SMMUv3State *s)
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Probe-host-Tegra241-CMDQV-supp.patch b/kvm-hw-arm-tegra241-cmdqv-Probe-host-Tegra241-CMDQV-supp.patch
new file mode 100644
index 0000000..678b194
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Probe-host-Tegra241-CMDQV-supp.patch
@@ -0,0 +1,103 @@
+From 2886a2c1b009f99327da4b691c30f7d0149f18e6 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:31 +0100
+Subject: [PATCH 089/111] hw/arm/tegra241-cmdqv: Probe host Tegra241 CMDQV
+ support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [89/111] 2dfd7f24b8300f222b3be054996d3bd17aabf9e6 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Use IOMMU_GET_HW_INFO to query host support for Tegra241 CMDQV.
+
+Validate the returned data type, version, and minimum number of vCMDQs and
+SIDs per Tegra241 CMDQ Virtual Interface(VI). Fail the probe if the host
+does not meet these requirements.
+
+The QEMU model supports one Virtual Interface(VI) per VM with 2 vCMDQs and
+16 SIDs per VI, so the probe ensures the host implementation is compatible
+with these limits.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-11-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 61e7de842085f313cab0be4f1b296f3dec52b5a2)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 32 ++++++++++++++++++++++++++++++--
+ hw/arm/tegra241-cmdqv.h | 4 ++++
+ 2 files changed, 34 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index ad5a0d4611..3a19a1af56 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -38,8 +38,36 @@ static bool tegra241_cmdqv_init(SMMUv3State *s, Error **errp)
+ static bool tegra241_cmdqv_probe(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ Error **errp)
+ {
+- error_setg(errp, "NVIDIA Tegra241 CMDQV is unsupported");
+- return false;
++ uint32_t data_type = IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV;
++ struct iommu_hw_info_tegra241_cmdqv cmdqv_info;
++ uint64_t caps;
++
++ if (!iommufd_backend_get_device_info(idev->iommufd, idev->devid, &data_type,
++ &cmdqv_info, sizeof(cmdqv_info), &caps,
++ NULL, errp)) {
++ return false;
++ }
++ if (data_type != IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV) {
++ error_setg(errp, "Host CMDQV: unexpected data type %u (expected %u)",
++ data_type, IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV);
++ return false;
++ }
++ if (cmdqv_info.version != CMDQV_VER) {
++ error_setg(errp, "Host CMDQV: unsupported version %u (expected %u)",
++ cmdqv_info.version, CMDQV_VER);
++ return false;
++ }
++ if (cmdqv_info.log2vcmdqs < CMDQV_NUM_CMDQ_LOG2) {
++ error_setg(errp, "Host CMDQV: insufficient vCMDQs log2=%u (need >= %u)",
++ cmdqv_info.log2vcmdqs, CMDQV_NUM_CMDQ_LOG2);
++ return false;
++ }
++ if (cmdqv_info.log2vsids < CMDQV_NUM_SID_PER_VI_LOG2) {
++ error_setg(errp, "Host CMDQV: insufficient SIDs log2=%u (need >= %u)",
++ cmdqv_info.log2vsids, CMDQV_NUM_SID_PER_VI_LOG2);
++ return false;
++ }
++ return true;
+ }
+
+ static const SMMUv3AccelCmdqvOps tegra241_cmdqv_ops = {
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+index 74a6954017..38c8b27b4d 100644
+--- a/hw/arm/tegra241-cmdqv.h
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -10,6 +10,10 @@
+ #ifndef HW_ARM_TEGRA241_CMDQV_H
+ #define HW_ARM_TEGRA241_CMDQV_H
+
++#define CMDQV_VER 1
++#define CMDQV_NUM_CMDQ_LOG2 1
++#define CMDQV_NUM_SID_PER_VI_LOG2 4
++
+ const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
+
+ #endif /* HW_ARM_TEGRA241_CMDQV_H */
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Read-and-propagate-Tegra241-CM.patch b/kvm-hw-arm-tegra241-cmdqv-Read-and-propagate-Tegra241-CM.patch
new file mode 100644
index 0000000..e1b0377
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Read-and-propagate-Tegra241-CM.patch
@@ -0,0 +1,165 @@
+From 89fb1af579e19967cb0af6e779827a526ca9598a Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:44 +0100
+Subject: [PATCH 102/111] hw/arm/tegra241-cmdqv: Read and propagate Tegra241
+ CMDQV errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [102/111] b4f1bb2a739a357cdf2b145c0be5a93c9b771171 (eauger1/centos-qemu-kvm)
+
+Conflicts: hw/core/irq.h replaced by hw/irq.h in hw/arm/tegra241-cmdqv.c
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Install an event handler on the CMDQV vEVENTQ fd to read and propagate
+host received CMDQV errors to the guest.
+
+The handler runs in QEMU's main loop, using a non-blocking fd registered
+via qemu_set_fd_handler().
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-24-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 1de52612f3ff339598b8c19ee5caa563a371a323)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 63 +++++++++++++++++++++++++++++++++++++++++
+ hw/arm/trace-events | 1 +
+ 2 files changed, 64 insertions(+)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 7264b4bfa9..71d02ae740 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -12,6 +12,7 @@
+
+ #include "hw/arm/smmuv3.h"
+ #include "hw/arm/smmuv3-common.h"
++#include "hw/irq.h"
+ #include "smmuv3-accel.h"
+ #include "tegra241-cmdqv.h"
+ #include "trace.h"
+@@ -729,6 +730,51 @@ out:
+ trace_tegra241_cmdqv_write_mmio(offset, value, size);
+ }
+
++static void tegra241_cmdqv_event_read(void *opaque)
++{
++ Tegra241CMDQV *cmdqv = opaque;
++ IOMMUFDVeventq *veventq = cmdqv->veventq;
++ struct {
++ struct iommufd_vevent_header hdr;
++ struct iommu_vevent_tegra241_cmdqv vevent;
++ } buf;
++ Error *local_err = NULL;
++
++ if (!smmuv3_accel_event_read_validate(veventq,
++ IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV,
++ &buf, sizeof(buf), &local_err)) {
++ warn_report_err_once(local_err);
++ return;
++ }
++
++ if (buf.vevent.lvcmdq_err_map[0] || buf.vevent.lvcmdq_err_map[1]) {
++ cmdqv->vintf_cmdq_err_map[0] =
++ extract64(buf.vevent.lvcmdq_err_map[0], 0, 32);
++ cmdqv->vintf_cmdq_err_map[1] =
++ extract64(buf.vevent.lvcmdq_err_map[0], 32, 32);
++ cmdqv->vintf_cmdq_err_map[2] =
++ extract64(buf.vevent.lvcmdq_err_map[1], 0, 32);
++ cmdqv->vintf_cmdq_err_map[3] =
++ extract64(buf.vevent.lvcmdq_err_map[1], 32, 32);
++ /*
++ * CMDQV_CMDQ_ERR_MAP and VINTF0_LVCMDQ_ERR_MAP are distinct
++ * registers (different MMIO offsets). With only VINTF0 exposed
++ * they carry the same data, so mirror.
++ */
++ for (int i = 0; i < 4; i++) {
++ cmdqv->cmdq_err_map[i] = cmdqv->vintf_cmdq_err_map[i];
++ }
++ /* Set the VINTF0 bit in VI_ERR_MAP_0 (only VINTF0 is exposed). */
++ cmdqv->vi_err_map[0] |= BIT(0);
++ if (!(cmdqv->vi_int_mask[0] & BIT(0))) {
++ qemu_irq_pulse(cmdqv->irq);
++ }
++ trace_tegra241_cmdqv_err_map(
++ cmdqv->vintf_cmdq_err_map[3], cmdqv->vintf_cmdq_err_map[2],
++ cmdqv->vintf_cmdq_err_map[1], cmdqv->vintf_cmdq_err_map[0]);
++ }
++}
++
+ static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
+ {
+ SMMUv3AccelState *accel = s->s_accel;
+@@ -740,6 +786,7 @@ static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
+ return;
+ }
+ if (veventq) {
++ qemu_set_fd_handler(veventq->veventq_fd, NULL, NULL, NULL);
+ close(veventq->veventq_fd);
+ iommufd_backend_free_id(viommu->iommufd, veventq->veventq_id);
+ g_free(veventq);
+@@ -759,6 +806,7 @@ tegra241_cmdqv_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ Tegra241CMDQV *cmdqv = s->s_accel->cmdqv;
+ uint32_t viommu_id, veventq_id, veventq_fd;
+ IOMMUFDVeventq *veventq;
++ int flags;
+
+ if (!iommufd_backend_alloc_viommu(idev->iommufd, idev->devid,
+ IOMMU_VIOMMU_TYPE_TEGRA241_CMDQV,
+@@ -784,14 +832,29 @@ tegra241_cmdqv_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ goto munmap_page0;
+ }
+
++ flags = fcntl(veventq_fd, F_GETFL);
++ if (flags < 0) {
++ error_setg(errp, "Failed to get flags for vEVENTQ fd");
++ goto free_veventq;
++ }
++ if (fcntl(veventq_fd, F_SETFL, O_NONBLOCK | flags) < 0) {
++ error_setg(errp, "Failed to set O_NONBLOCK on vEVENTQ fd");
++ goto free_veventq;
++ }
++
+ veventq = g_new(IOMMUFDVeventq, 1);
+ veventq->veventq_id = veventq_id;
+ veventq->veventq_fd = veventq_fd;
+ cmdqv->veventq = veventq;
+
++ /* Set up event handler for veventq fd */
++ qemu_set_fd_handler(veventq_fd, tegra241_cmdqv_event_read, NULL, cmdqv);
+ *out_viommu_id = viommu_id;
+ return true;
+
++free_veventq:
++ close(veventq_fd);
++ iommufd_backend_free_id(idev->iommufd, veventq_id);
+ munmap_page0:
+ munmap(cmdqv->vintf_page0, VINTF_PAGE_SIZE);
+ cmdqv->vintf_page0 = NULL;
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index a8dcbc82db..dbed00afbb 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -75,6 +75,7 @@ smmuv3_accel_install_ste(uint32_t vsid, const char * type, uint32_t hwpt_id) "vS
+ # tegra241-cmdqv
+ tegra241_cmdqv_read_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
+ tegra241_cmdqv_write_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
++tegra241_cmdqv_err_map(uint32_t map3, uint32_t map2, uint32_t map1, uint32_t map0) "hw irq received. error (hex) maps: %04X:%04X:%04X:%04X"
+ tegra241_cmdqv_read_vcmdq_page0(int index, const char *aperture, const char *backing, uint64_t offset0, uint64_t val) "vcmdq[%d] %s (%s) offset0: 0x%"PRIx64" val: 0x%"PRIx64
+ tegra241_cmdqv_read_vcmdq_page1(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
+ tegra241_cmdqv_write_vcmdq_page0(int index, const char *aperture, const char *backing, uint64_t offset0, uint64_t val) "vcmdq[%d] %s (%s) offset0: 0x%"PRIx64" val: 0x%"PRIx64
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Route-allocated-VCMDQ-Page0-ac.patch b/kvm-hw-arm-tegra241-cmdqv-Route-allocated-VCMDQ-Page0-ac.patch
new file mode 100644
index 0000000..7ac65c3
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Route-allocated-VCMDQ-Page0-ac.patch
@@ -0,0 +1,244 @@
+From 05198739d42d3ad9b57a52075b56dbfa7042de41 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:40 +0100
+Subject: [PATCH 098/111] hw/arm/tegra241-cmdqv: Route allocated VCMDQ Page0
+ accesses to the mmap'd host VINTF page0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [98/111] 06b905fe92b20420565b5730d6ed2d0a843c0eba (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Introduce tegra241_cmdqv_vintf_lvcmdq_ptr() to route VCMDQ Page 0
+register accesses through the mmap'd host VINTF Page 0 backing once a
+hardware queue has been allocated for the VCMDQ.
+
+The two QEMU-trapped Page 0 apertures (direct at 0x10000, VINTF at
+0x30000) are hardware aliases of the same underlying registers. A
+subsequent patch installs the VINTF aperture as a RAM-device into
+guest MMIO; in this patch both remain QEMU-trapped.
+
+The direct VCMDQ aperture stays QEMU-trapped (rather than aliased
+to the VINTF mmap) so that writes to an unallocated VCMDQ remain
+well-defined. The CMDQV architecture allows software to program a
+VCMDQ through the direct aperture without first allocating it to a
+VINTF; aliasing to the VINTF mmap would route those writes into
+unallocated logical slots where the hardware silently drops them.
+
+A VCMDQ Page 0 access is served from one of two sources:
+
+ - Cache-backed: no hw_queue is allocated for the VCMDQ
+ (HW_QUEUE_ALLOC has not yet succeeded). Both apertures use
+ QEMU's register cache.
+
+ - HW-backed: HW_QUEUE_ALLOC has succeeded. Both apertures access
+ the registers directly through the mmap'd host VINTF Page 0.
+
+tegra241_cmdqv_sync_vcmdq() copies any cached writes (CONS_INDX,
+PROD_INDX, CONFIG, GERRORN) into the mmap'd page on the cache-to-HW
+transition so the guest's earlier register state survives. Freeing a
+VCMDQ clears the cached Page0 registers.
+
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Message-id: 20260609112552.378999-20-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 1d0f7753541784cbafb7aee3adc843816bf7c66d)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 89 +++++++++++++++++++++++++++++++++++++++++
+ hw/arm/trace-events | 4 +-
+ 2 files changed, 91 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 8cb39e87c4..63fe0ac681 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -16,6 +16,16 @@
+ #include "tegra241-cmdqv.h"
+ #include "trace.h"
+
++static void tegra241_cmdqv_reset_vcmdq_cache(Tegra241CMDQV *cmdqv, int index)
++{
++ cmdqv->vcmdq_cons_indx[index] = 0;
++ cmdqv->vcmdq_prod_indx[index] = 0;
++ cmdqv->vcmdq_config[index] = 0;
++ cmdqv->vcmdq_status[index] = 0;
++ cmdqv->vcmdq_gerror[index] = 0;
++ cmdqv->vcmdq_gerrorn[index] = 0;
++}
++
+ static void tegra241_cmdqv_free_vcmdq(Tegra241CMDQV *cmdqv, int index)
+ {
+ IOMMUFDViommu *viommu = cmdqv->s_accel->viommu;
+@@ -27,6 +37,7 @@ static void tegra241_cmdqv_free_vcmdq(Tegra241CMDQV *cmdqv, int index)
+ iommufd_backend_free_id(viommu->iommufd, vcmdq->hw_queue_id);
+ g_free(vcmdq);
+ cmdqv->vcmdq[index] = NULL;
++ tegra241_cmdqv_reset_vcmdq_cache(cmdqv, index);
+ }
+
+ /*
+@@ -45,6 +56,47 @@ static bool tegra241_cmdqv_vcmdq_ready_to_alloc(Tegra241CMDQV *cmdqv, int index)
+ tegra241_cmdqv_enabled(cmdqv) && tegra241_vintf_enabled(cmdqv);
+ }
+
++/*
++ * Return a pointer into the mmap'd VINTF page0 for the VCMDQ Page 0
++ * register at @offset0 in VCMDQ slot @index, or NULL when the VCMDQ
++ * has no hw_queue allocated or the host VINTF page0 is not mmap'd.
++ */
++static inline uint32_t *tegra241_cmdqv_vintf_lvcmdq_ptr(Tegra241CMDQV *cmdqv,
++ int index, hwaddr offset0)
++{
++ if (!cmdqv->vcmdq[index] || !cmdqv->vintf_page0) {
++ return NULL;
++ }
++ return (uint32_t *)(cmdqv->vintf_page0 +
++ (index * CMDQV_VCMDQ_STRIDE) +
++ (offset0 - CMDQV_VCMDQ_PAGE0_BASE));
++}
++
++/*
++ * Flush cached register writes into the mmap'd host VINTF page0 after a
++ * successful HW_QUEUE_ALLOC, so the guest's earlier writes survive
++ * the cache-to-hardware transition.
++ */
++static void tegra241_cmdqv_sync_vcmdq(Tegra241CMDQV *cmdqv, int index)
++{
++ uint32_t *ptr;
++
++ ptr = tegra241_cmdqv_vintf_lvcmdq_ptr(cmdqv, index, A_VCMDQ0_CONS_INDX);
++ if (!ptr) {
++ return;
++ }
++ *ptr = cmdqv->vcmdq_cons_indx[index];
++
++ ptr = tegra241_cmdqv_vintf_lvcmdq_ptr(cmdqv, index, A_VCMDQ0_PROD_INDX);
++ *ptr = cmdqv->vcmdq_prod_indx[index];
++
++ ptr = tegra241_cmdqv_vintf_lvcmdq_ptr(cmdqv, index, A_VCMDQ0_CONFIG);
++ *ptr = cmdqv->vcmdq_config[index];
++
++ ptr = tegra241_cmdqv_vintf_lvcmdq_ptr(cmdqv, index, A_VCMDQ0_GERRORN);
++ *ptr = cmdqv->vcmdq_gerrorn[index];
++}
++
+ /*
+ * Allocate a host HW VCMDQ from the current cached BASE / size for @index.
+ * No-op (returns true) until the VCMDQ is ready to be allocated.
+@@ -85,6 +137,9 @@ static bool tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
+ cmdqv->vcmdq_gerror[index] &= ~R_VCMDQ0_GERROR_CMDQ_INIT_ERR_MASK;
+ cmdqv->vcmdq_status[index] |= R_VCMDQ0_STATUS_CMDQ_EN_OK_MASK;
+
++ /* Push cached writes to HW; freeing resets the cache. */
++ tegra241_cmdqv_sync_vcmdq(cmdqv, index);
++
+ return true;
+ }
+
+@@ -111,13 +166,23 @@ static void tegra241_cmdqv_setup_all_vcmdq(Tegra241CMDQV *cmdqv,
+ *
+ * The caller normalizes the MMIO offset such that @offset0 always refers
+ * to a VCMDQ0_* register, while @index selects the VCMDQ instance.
++ *
++ * If the VCMDQ is allocated and the host VINTF page0 is mmap'd, read
++ * directly from the host VINTF page0 backing. Otherwise, fall back to
++ * the cache.
+ */
+ static uint64_t tegra241_cmdqv_read_vcmdq_page0(Tegra241CMDQV *cmdqv,
+ hwaddr offset0, int index,
+ bool direct)
+ {
++ uint32_t *ptr = tegra241_cmdqv_vintf_lvcmdq_ptr(cmdqv, index, offset0);
+ uint64_t val = 0;
+
++ if (ptr) {
++ val = *ptr;
++ goto out;
++ }
++
+ switch (offset0) {
+ case A_VCMDQ0_CONS_INDX:
+ val = cmdqv->vcmdq_cons_indx[index];
+@@ -142,7 +207,9 @@ static uint64_t tegra241_cmdqv_read_vcmdq_page0(Tegra241CMDQV *cmdqv,
+ "%s unhandled read access at 0x%" PRIx64 "\n",
+ __func__, offset0);
+ }
++out:
+ trace_tegra241_cmdqv_read_vcmdq_page0(index, direct ? "direct" : "vi",
++ ptr ? "hw" : "cache",
+ offset0, val);
+ return val;
+ }
+@@ -218,11 +285,31 @@ static uint64_t tegra241_cmdqv_config_vintf_read(Tegra241CMDQV *cmdqv,
+ *
+ * Page 0 registers are all 32-bit; this helper is only called for 4-byte
+ * writes.
++ *
++ * If the VCMDQ is allocated and the host VINTF page0 is mmap'd, write
++ * directly to the VINTF page0 backing. Otherwise, update the cache.
+ */
+ static void tegra241_cmdqv_write_vcmdq_page0(Tegra241CMDQV *cmdqv,
+ hwaddr offset0, int index,
+ uint32_t value, bool direct)
+ {
++ uint32_t *ptr = tegra241_cmdqv_vintf_lvcmdq_ptr(cmdqv, index, offset0);
++ bool hw = false;
++
++ if (ptr) {
++ switch (offset0) {
++ case A_VCMDQ0_CONS_INDX:
++ case A_VCMDQ0_PROD_INDX:
++ case A_VCMDQ0_CONFIG:
++ case A_VCMDQ0_GERRORN:
++ *ptr = value;
++ hw = true;
++ goto out;
++ default:
++ break;
++ }
++ }
++
+ switch (offset0) {
+ case A_VCMDQ0_CONS_INDX:
+ cmdqv->vcmdq_cons_indx[index] = value;
+@@ -253,7 +340,9 @@ static void tegra241_cmdqv_write_vcmdq_page0(Tegra241CMDQV *cmdqv,
+ "%s unhandled write access at 0x%" PRIx64 "\n",
+ __func__, offset0);
+ }
++out:
+ trace_tegra241_cmdqv_write_vcmdq_page0(index, direct ? "direct" : "vi",
++ hw ? "hw" : "cache",
+ offset0, value);
+ }
+
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index 666967dc5e..a8dcbc82db 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -75,9 +75,9 @@ smmuv3_accel_install_ste(uint32_t vsid, const char * type, uint32_t hwpt_id) "vS
+ # tegra241-cmdqv
+ tegra241_cmdqv_read_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
+ tegra241_cmdqv_write_mmio(uint64_t offset, uint64_t val, unsigned size) "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
+-tegra241_cmdqv_read_vcmdq_page0(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
++tegra241_cmdqv_read_vcmdq_page0(int index, const char *aperture, const char *backing, uint64_t offset0, uint64_t val) "vcmdq[%d] %s (%s) offset0: 0x%"PRIx64" val: 0x%"PRIx64
+ tegra241_cmdqv_read_vcmdq_page1(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
+-tegra241_cmdqv_write_vcmdq_page0(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
++tegra241_cmdqv_write_vcmdq_page0(int index, const char *aperture, const char *backing, uint64_t offset0, uint64_t val) "vcmdq[%d] %s (%s) offset0: 0x%"PRIx64" val: 0x%"PRIx64
+ tegra241_cmdqv_write_vcmdq_page1(int index, const char *aperture, uint64_t offset0, uint64_t val) "vcmdq[%d] %s offset0: 0x%"PRIx64" val: 0x%"PRIx64
+
+ # strongarm.c
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-Use-mmap-d-host-VINTF-page0-fo.patch b/kvm-hw-arm-tegra241-cmdqv-Use-mmap-d-host-VINTF-page0-fo.patch
new file mode 100644
index 0000000..7391b86
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-Use-mmap-d-host-VINTF-page0-fo.patch
@@ -0,0 +1,129 @@
+From 9d5701e0445ac377f61fa219ddf59ec7714dc858 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:42 +0100
+Subject: [PATCH 100/111] hw/arm/tegra241-cmdqv: Use mmap'd host VINTF page0
+ for virtual VINTF page0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [100/111] 2417c5223a363995121cd311eb7f714572dc5447 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Install the mmap'd host VINTF page0 as a RAM-device MemoryRegion
+backing the guest's virtual VINTF Page 0 aperture (guest MMIO offset
+0x30000) when VINTF is enabled, and remove it on VINTF disable or
+reset. This eliminates QEMU trapping for hot-path CONS/PROD index
+updates via that aperture.
+
+After this patch, the two VCMDQ Page 0 apertures use different
+access paths: the direct aperture (0x10000) remains QEMU-trapped,
+while the VINTF aperture (0x30000) is a guest-direct RAM mapping.
+
+The direct aperture is intentionally kept trapped (not aliased to
+the host VINTF mmap) so that writes to an unallocated VCMDQ remain
+well-defined. The CMDQV architecture allows software to program a
+VCMDQ through the direct aperture without first allocating it to a
+VINTF; aliasing would route those writes to unallocated logical
+slots in the VINTF page, where the hardware silently drops them.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-22-skolothumtho@nvidia.com
+Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 5965b81ce2835de49ba4eb36c386e72be5ff1ba8)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 37 +++++++++++++++++++++++++++++++++++++
+ hw/arm/tegra241-cmdqv.h | 1 +
+ 2 files changed, 38 insertions(+)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index 63fe0ac681..7264b4bfa9 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -26,6 +26,40 @@ static void tegra241_cmdqv_reset_vcmdq_cache(Tegra241CMDQV *cmdqv, int index)
+ cmdqv->vcmdq_gerrorn[index] = 0;
+ }
+
++static void tegra241_cmdqv_guest_unmap_vintf_page0(Tegra241CMDQV *cmdqv)
++{
++ if (!cmdqv->mr_vintf_page0) {
++ return;
++ }
++
++ memory_region_del_subregion(&cmdqv->mmio_cmdqv, cmdqv->mr_vintf_page0);
++ object_unparent(OBJECT(cmdqv->mr_vintf_page0));
++ g_free(cmdqv->mr_vintf_page0);
++ cmdqv->mr_vintf_page0 = NULL;
++}
++
++static void tegra241_cmdqv_guest_map_vintf_page0(Tegra241CMDQV *cmdqv)
++{
++ char *name;
++
++ if (cmdqv->mr_vintf_page0) {
++ return;
++ }
++
++ name = g_strdup_printf("%s vintf-page0",
++ memory_region_name(&cmdqv->mmio_cmdqv));
++ cmdqv->mr_vintf_page0 = g_malloc0(sizeof(*cmdqv->mr_vintf_page0));
++ memory_region_init_ram_device_ptr(cmdqv->mr_vintf_page0,
++ memory_region_owner(&cmdqv->mmio_cmdqv),
++ name, VINTF_PAGE_SIZE,
++ cmdqv->vintf_page0);
++ memory_region_set_skip_iommu_map(cmdqv->mr_vintf_page0, true);
++ memory_region_add_subregion_overlap(&cmdqv->mmio_cmdqv,
++ CMDQV_VINTF_PAGE0_BASE,
++ cmdqv->mr_vintf_page0, 1);
++ g_free(name);
++}
++
+ static void tegra241_cmdqv_free_vcmdq(Tegra241CMDQV *cmdqv, int index)
+ {
+ IOMMUFDViommu *viommu = cmdqv->s_accel->viommu;
+@@ -430,7 +464,9 @@ static void tegra241_cmdqv_config_vintf_write(Tegra241CMDQV *cmdqv,
+ * enabled need their hw_queue allocated now.
+ */
+ tegra241_cmdqv_setup_all_vcmdq(cmdqv, errp);
++ tegra241_cmdqv_guest_map_vintf_page0(cmdqv);
+ } else {
++ tegra241_cmdqv_guest_unmap_vintf_page0(cmdqv);
+ tegra241_cmdqv_free_all_vcmdq(cmdqv);
+ cmdqv->vintf_status &= ~R_VINTF0_STATUS_ENABLE_OK_MASK;
+ }
+@@ -772,6 +808,7 @@ static void tegra241_cmdqv_reset(SMMUv3State *s)
+ return;
+ }
+
++ tegra241_cmdqv_guest_unmap_vintf_page0(cmdqv);
+ tegra241_cmdqv_free_all_vcmdq(cmdqv);
+ }
+
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+index c795da0444..0964f68a20 100644
+--- a/hw/arm/tegra241-cmdqv.h
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -49,6 +49,7 @@ typedef struct Tegra241CMDQV {
+ IOMMUFDVeventq *veventq;
+ IOMMUFDHWqueue *vcmdq[TEGRA241_CMDQV_MAX_CMDQ];
+ void *vintf_page0;
++ MemoryRegion *mr_vintf_page0;
+
+ /* CMDQ-V Config page register cache */
+ uint32_t config;
+--
+2.52.0
+
diff --git a/kvm-hw-arm-tegra241-cmdqv-mmap-host-VINTF-Page0-for-CMDQ.patch b/kvm-hw-arm-tegra241-cmdqv-mmap-host-VINTF-Page0-for-CMDQ.patch
new file mode 100644
index 0000000..37fd6c4
--- /dev/null
+++ b/kvm-hw-arm-tegra241-cmdqv-mmap-host-VINTF-Page0-for-CMDQ.patch
@@ -0,0 +1,116 @@
+From afe9e82db92db41cb6d87f55410b388667b8e537 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:35 +0100
+Subject: [PATCH 093/111] hw/arm/tegra241-cmdqv: mmap host VINTF Page0 for
+ CMDQV
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [93/111] 049d226826cbec9ff2d6509d46b73b3d70371230 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+The kernel currently exposes a single VINTF per emulated SMMUv3
+instance. IOMMU_VIOMMU_ALLOC returns an mmap offset for the host
+VINTF Page0 allocated for this SMMU. However, VCMDQs only become
+bound to that VINTF after IOMMU_HW_QUEUE_ALLOC, so until then the
+mapped Page0 does not back any real VCMDQ state.
+
+mmap the host VINTF Page0 right after IOMMU_VIOMMU_ALLOC, as the host
+VINTF is already enabled at that point, and unmap it when the vIOMMU is
+freed. The mapping shares the vIOMMU's lifetime. This prepares the VINTF
+mapping in advance of subsequent patches that add VCMDQ allocation.
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-15-skolothumtho@nvidia.com
+Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit ab15bda3ac1380f63c6e7ae1e80f799cff2a262b)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/tegra241-cmdqv.c | 16 +++++++++++++++-
+ hw/arm/tegra241-cmdqv.h | 3 +++
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
+index c1351c8519..3eec6073a4 100644
+--- a/hw/arm/tegra241-cmdqv.c
++++ b/hw/arm/tegra241-cmdqv.c
+@@ -41,6 +41,10 @@ static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
+ g_free(veventq);
+ cmdqv->veventq = NULL;
+ }
++ if (cmdqv->vintf_page0) {
++ munmap(cmdqv->vintf_page0, VINTF_PAGE_SIZE);
++ cmdqv->vintf_page0 = NULL;
++ }
+ iommufd_backend_free_id(viommu->iommufd, viommu->viommu_id);
+ }
+
+@@ -60,13 +64,20 @@ tegra241_cmdqv_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ return false;
+ }
+
++ if (!iommufd_backend_viommu_mmap(idev->iommufd, viommu_id, VINTF_PAGE_SIZE,
++ cmdqv->cmdqv_data->out_vintf_mmap_offset,
++ &cmdqv->vintf_page0, errp)) {
++ error_append_hint(errp, "Tegra241 CMDQV: failed to mmap VINTF page0");
++ goto free_viommu;
++ }
++
+ if (!iommufd_backend_alloc_veventq(idev->iommufd, viommu_id,
+ IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV,
+ 1 << SMMU_EVENTQS, &veventq_id,
+ &veventq_fd,
+ errp)) {
+ error_append_hint(errp, "Tegra241 CMDQV: failed to alloc veventq");
+- goto free_viommu;
++ goto munmap_page0;
+ }
+
+ veventq = g_new(IOMMUFDVeventq, 1);
+@@ -77,6 +88,9 @@ tegra241_cmdqv_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ *out_viommu_id = viommu_id;
+ return true;
+
++munmap_page0:
++ munmap(cmdqv->vintf_page0, VINTF_PAGE_SIZE);
++ cmdqv->vintf_page0 = NULL;
+ free_viommu:
+ iommufd_backend_free_id(idev->iommufd, viommu_id);
+ return false;
+diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
+index 9fc720e96c..00c83b6186 100644
+--- a/hw/arm/tegra241-cmdqv.h
++++ b/hw/arm/tegra241-cmdqv.h
+@@ -25,6 +25,8 @@
+ */
+ #define TEGRA241_CMDQV_IO_LEN 0x50000
+
++#define VINTF_PAGE_SIZE 0x10000
++
+ struct iommu_viommu_tegra241_cmdqv;
+
+ typedef struct Tegra241CMDQV {
+@@ -33,6 +35,7 @@ typedef struct Tegra241CMDQV {
+ MemoryRegion mmio_cmdqv;
+ qemu_irq irq;
+ IOMMUFDVeventq *veventq;
++ void *vintf_page0;
+ } Tegra241CMDQV;
+
+ const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
+--
+2.52.0
+
diff --git a/kvm-hw-arm-virt-Link-SMMUv3-CMDQV-resources-to-platform-.patch b/kvm-hw-arm-virt-Link-SMMUv3-CMDQV-resources-to-platform-.patch
new file mode 100644
index 0000000..f541f39
--- /dev/null
+++ b/kvm-hw-arm-virt-Link-SMMUv3-CMDQV-resources-to-platform-.patch
@@ -0,0 +1,84 @@
+From 9de83551465e408908b9999a70709041c417a120 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:33 +0100
+Subject: [PATCH 091/111] hw/arm/virt: Link SMMUv3 CMDQV resources to platform
+ bus
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [91/111] dad452aedd8dc1227e783e058fd1b58806f5f5e6 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+SMMUv3 devices with acceleration may enable CMDQV extensions
+after device realize. In that case, additional MMIO regions and
+IRQ lines may be registered but not yet mapped to the platform bus.
+
+Ensure SMMUv3 device resources are linked to the platform bus
+during machine_done().
+
+This is safe to do unconditionally since the platform bus helpers
+skip resources that are already mapped.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-13-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit dc5726da05a4595338de0e9c3947beaf2e766552)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/virt.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index 5169b4ba5b..ca150d455c 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -1853,6 +1853,25 @@ static void virt_build_smbios(VirtMachineState *vms)
+ }
+ }
+
++/*
++ * SMMUv3 devices with acceleration may enable CMDQV extensions
++ * after device realize. In that case, additional MMIO regions and
++ * IRQ lines may be registered but not yet mapped to the platform bus.
++ *
++ * Ensure all resources are linked to the platform bus before final
++ * machine setup.
++ */
++
++static void virt_smmuv3_dev_link_cmdqv(VirtMachineState *vms)
++{
++ for (int i = 0; i < vms->smmuv3_devices->len; i++) {
++ DeviceState *dev = g_ptr_array_index(vms->smmuv3_devices, i);
++
++ platform_bus_link_device(PLATFORM_BUS_DEVICE(vms->platform_bus_dev),
++ SYS_BUS_DEVICE(dev));
++ }
++}
++
+ static
+ void virt_machine_done(Notifier *notifier, void *data)
+ {
+@@ -1869,6 +1888,9 @@ void virt_machine_done(Notifier *notifier, void *data)
+ if (vms->cxl_devices_state.is_enabled) {
+ cxl_fmws_link_targets(&error_fatal);
+ }
++
++ virt_smmuv3_dev_link_cmdqv(vms);
++
+ /*
+ * If the user provided a dtb, we assume the dynamic sysbus nodes
+ * already are integrated there. This corresponds to a use case where
+--
+2.52.0
+
diff --git a/kvm-hw-arm-virt-Set-PCI-preserve_config-for-accel-SMMUv3.patch b/kvm-hw-arm-virt-Set-PCI-preserve_config-for-accel-SMMUv3.patch
new file mode 100644
index 0000000..86fd855
--- /dev/null
+++ b/kvm-hw-arm-virt-Set-PCI-preserve_config-for-accel-SMMUv3.patch
@@ -0,0 +1,87 @@
+From d614dc06f252e256ce36a88494a77fc1622ca312 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 031/111] hw/arm/virt: Set PCI preserve_config for accel SMMUv3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [31/111] 02e02c742a5492d4a0e4d0c6e29d94bf39d16210 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Introduce a new pci_preserve_config field in virt machine state which
+allows the generation of DSM #5. This field is only set if accel SMMU
+is instantiated.
+
+In a subsequent patch, SMMUv3 accel mode will make use of IORT RMR nodes
+to enable nested translation of MSI doorbell addresses. IORT RMR requires
+_DSM #5 to be set for the PCI host bridge so that the Guest kernel
+preserves the PCI boot configuration.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-24-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 45c57eaefd4c7a67c93e77d6f4436c8569aefbb9)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/virt-acpi-build.c | 8 ++++++++
+ hw/arm/virt.c | 1 +
+ include/hw/arm/virt.h | 1 +
+ 3 files changed, 10 insertions(+)
+
+diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
+index 5a642abac6..6883147040 100644
+--- a/hw/arm/virt-acpi-build.c
++++ b/hw/arm/virt-acpi-build.c
+@@ -163,6 +163,14 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
+ .pci_native_hotplug = !acpi_pcihp,
+ };
+
++ /*
++ * Accel SMMU requires RMRs for MSI 1-1 mapping, which require _DSM
++ * function 5 (_DSM for Preserving PCI Boot Configurations).
++ */
++ if (vms->pci_preserve_config) {
++ cfg.preserve_config = true;
++ }
++
+ if (vms->highmem_mmio) {
+ cfg.mmio64 = memmap[VIRT_HIGH_PCIE_MMIO];
+ }
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index b9765d4248..672b8d912c 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -3111,6 +3111,7 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+ }
+ object_property_set_uint(OBJECT(dev), "msi-gpa", db_start,
+ &error_abort);
++ vms->pci_preserve_config = true;
+ }
+ }
+ }
+diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
+index 8d90b66b87..b6d696e8ce 100644
+--- a/include/hw/arm/virt.h
++++ b/include/hw/arm/virt.h
+@@ -183,6 +183,7 @@ struct VirtMachineState {
+ bool legacy_smmuv3_present;
+ MemoryRegion *sysmem;
+ MemoryRegion *secure_sysmem;
++ bool pci_preserve_config;
+ };
+
+ #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
+--
+2.52.0
+
diff --git a/kvm-hw-arm-virt-Set-msi-gpa-property.patch b/kvm-hw-arm-virt-Set-msi-gpa-property.patch
new file mode 100644
index 0000000..6561cf5
--- /dev/null
+++ b/kvm-hw-arm-virt-Set-msi-gpa-property.patch
@@ -0,0 +1,69 @@
+From 6eaf5c560a39669ec7f43a3714549b14a164c72b Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 026/111] hw/arm/virt: Set msi-gpa property
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [26/111] 8089fb878db15fbb5929e15fb2210b1ec2ccb9c0 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Set the MSI doorbell GPA property for accelerated SMMUv3 devices for use
+by KVM MSI setup. Also, since any meaningful use of vfio-pci devices with
+an accelerated SMMUv3 requires both KVM and a kernel irqchip, ensure
+those are specified when accel=on is selected.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-19-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 5ec2700dcbf72c6bbeb00322e5258f999071d9d5)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/virt.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index e3e0233474..b9765d4248 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -3092,6 +3092,26 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+ object_property_set_link(OBJECT(dev), "secure-memory",
+ OBJECT(vms->secure_sysmem), NULL);
+ }
++ if (object_property_find(OBJECT(dev), "accel") &&
++ object_property_get_bool(OBJECT(dev), "accel", &error_abort)) {
++ hwaddr db_start = 0;
++
++ if (!kvm_enabled() || !kvm_irqchip_in_kernel()) {
++ error_setg(errp, "SMMUv3 accel=on requires KVM with "
++ "kernel-irqchip=on support");
++ return;
++ }
++
++ if (vms->msi_controller == VIRT_MSI_CTRL_ITS) {
++ /* GITS_TRANSLATER page + offset */
++ db_start = base_memmap[VIRT_GIC_ITS].base + 0x10000 + 0x40;
++ } else if (vms->msi_controller == VIRT_MSI_CTRL_GICV2M) {
++ /* MSI_SETSPI_NS page + offset */
++ db_start = base_memmap[VIRT_GIC_V2M].base + 0x40;
++ }
++ object_property_set_uint(OBJECT(dev), "msi-gpa", db_start,
++ &error_abort);
++ }
+ }
+ }
+
+--
+2.52.0
+
diff --git a/kvm-hw-arm-virt-Use-stored-SMMUv3-device-list-for-IORT-b.patch b/kvm-hw-arm-virt-Use-stored-SMMUv3-device-list-for-IORT-b.patch
new file mode 100644
index 0000000..481fb2c
--- /dev/null
+++ b/kvm-hw-arm-virt-Use-stored-SMMUv3-device-list-for-IORT-b.patch
@@ -0,0 +1,173 @@
+From 20f7137990c3b537c92774b18ebcb98ae497cdf7 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:30 +0100
+Subject: [PATCH 088/111] hw/arm/virt: Use stored SMMUv3 device list for IORT
+ build
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [88/111] 901595fab4bc977b43954b0563e95dc3bf505d6f (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Introduce a GPtrArray in VirtMachineState to track all SMMUv3 devices
+created on the virt machine, and use it when building the IORT table
+instead of relying on object_child_foreach_recursive() walks of the
+object tree.
+
+This avoids recursive object traversal and provides a foundation for
+subsequent patches that need direct access to SMMUv3 instances for
+CMDQV-related handling.
+
+No functional change. No bios-tables qtest failures observed.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-10-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 92e340997f861cc7289da76336d40f65a4a58318)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/virt-acpi-build.c | 70 ++++++++++++++++++----------------------
+ hw/arm/virt.c | 3 ++
+ include/hw/arm/virt.h | 1 +
+ 3 files changed, 35 insertions(+), 39 deletions(-)
+
+diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
+index b923e965da..597d51199c 100644
+--- a/hw/arm/virt-acpi-build.c
++++ b/hw/arm/virt-acpi-build.c
+@@ -391,49 +391,41 @@ static int smmuv3_dev_idmap_compare(gconstpointer a, gconstpointer b)
+ return map_a->input_base - map_b->input_base;
+ }
+
+-static int iort_smmuv3_devices(Object *obj, void *opaque)
+-{
+- VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine());
+- AcpiIortSMMUv3Dev sdev = {0};
+- GArray *sdev_blob = opaque;
+- AcpiIortIdMapping idmap;
+- PlatformBusDevice *pbus;
+- int min_bus, max_bus;
+- SysBusDevice *sbdev;
+- PCIBus *bus;
+-
+- if (!object_dynamic_cast(obj, TYPE_ARM_SMMUV3)) {
+- return 0;
+- }
+-
+- bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
+- sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
+- sdev.ats = smmuv3_ats_enabled(ARM_SMMUV3(obj));
+- pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+- sbdev = SYS_BUS_DEVICE(obj);
+- sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+- sdev.base += vms->memmap[VIRT_PLATFORM_BUS].base;
+- sdev.irq = platform_bus_get_irqn(pbus, sbdev, 0);
+- sdev.irq += vms->irqmap[VIRT_PLATFORM_BUS];
+- sdev.irq += ARM_SPI_BASE;
+-
+- pci_bus_range(bus, &min_bus, &max_bus);
+- sdev.rc_smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
+- idmap.input_base = min_bus << 8,
+- idmap.id_count = (max_bus - min_bus + 1) << 8,
+- g_array_append_val(sdev.rc_smmu_idmaps, idmap);
+- g_array_append_val(sdev_blob, sdev);
+- return 0;
+-}
+-
+ /*
+ * Populate the struct AcpiIortSMMUv3Dev for all SMMUv3 devices and
+ * return the total number of idmaps.
+ */
+-static int populate_smmuv3_dev(GArray *sdev_blob)
++static int populate_smmuv3_dev(VirtMachineState *vms, GArray *sdev_blob)
+ {
+- object_child_foreach_recursive(object_get_root(),
+- iort_smmuv3_devices, sdev_blob);
++ for (int i = 0; i < vms->smmuv3_devices->len; i++) {
++ Object *obj = OBJECT(g_ptr_array_index(vms->smmuv3_devices, i));
++ AcpiIortSMMUv3Dev sdev = {0};
++ AcpiIortIdMapping idmap;
++ PlatformBusDevice *pbus;
++ int min_bus, max_bus;
++ SysBusDevice *sbdev;
++ PCIBus *bus;
++
++ bus = PCI_BUS(object_property_get_link(obj, "primary-bus",
++ &error_abort));
++ sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
++ sdev.ats = smmuv3_ats_enabled(ARM_SMMUV3(obj));
++ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
++ sbdev = SYS_BUS_DEVICE(obj);
++ sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
++ sdev.base += vms->memmap[VIRT_PLATFORM_BUS].base;
++ sdev.irq = platform_bus_get_irqn(pbus, sbdev, 0);
++ sdev.irq += vms->irqmap[VIRT_PLATFORM_BUS];
++ sdev.irq += ARM_SPI_BASE;
++
++ pci_bus_range(bus, &min_bus, &max_bus);
++ sdev.rc_smmu_idmaps = g_array_new(false, true,
++ sizeof(AcpiIortIdMapping));
++ idmap.input_base = min_bus << 8;
++ idmap.id_count = (max_bus - min_bus + 1) << 8;
++ g_array_append_val(sdev.rc_smmu_idmaps, idmap);
++ g_array_append_val(sdev_blob, sdev);
++ }
+ /* Sort the smmuv3 devices(if any) by smmu idmap input_base */
+ g_array_sort(sdev_blob, smmuv3_dev_idmap_compare);
+ /*
+@@ -567,7 +559,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ if (vms->legacy_smmuv3_present) {
+ rc_smmu_idmaps_len = populate_smmuv3_legacy_dev(smmuv3_devs);
+ } else {
+- rc_smmu_idmaps_len = populate_smmuv3_dev(smmuv3_devs);
++ rc_smmu_idmaps_len = populate_smmuv3_dev(vms, smmuv3_devs);
+ }
+
+ num_smmus = smmuv3_devs->len;
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index 5486af4456..5169b4ba5b 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -3153,6 +3153,7 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
+ }
+
+ create_smmuv3_dev_dtb(vms, dev, bus, errp);
++ g_ptr_array_add(vms->smmuv3_devices, dev);
+ }
+ }
+
+@@ -3575,6 +3576,8 @@ static void virt_instance_init(Object *obj)
+ vms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
+ vms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
+ cxl_machine_init(obj, &vms->cxl_devices_state);
++
++ vms->smmuv3_devices = g_ptr_array_new_with_free_func(NULL);
+ }
+
+ static const TypeInfo virt_machine_info = {
+diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
+index b6d696e8ce..58a9db9723 100644
+--- a/include/hw/arm/virt.h
++++ b/include/hw/arm/virt.h
+@@ -184,6 +184,7 @@ struct VirtMachineState {
+ MemoryRegion *sysmem;
+ MemoryRegion *secure_sysmem;
+ bool pci_preserve_config;
++ GPtrArray *smmuv3_devices;
+ };
+
+ #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
+--
+2.52.0
+
diff --git a/kvm-hw-arm-virt-acpi-Advertise-Tegra241-CMDQV-nodes-in-D.patch b/kvm-hw-arm-virt-acpi-Advertise-Tegra241-CMDQV-nodes-in-D.patch
new file mode 100644
index 0000000..2ce01e5
--- /dev/null
+++ b/kvm-hw-arm-virt-acpi-Advertise-Tegra241-CMDQV-nodes-in-D.patch
@@ -0,0 +1,173 @@
+From e20c2fceac0cad9a6f509d9087e2fa965cc1489d Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:49 +0100
+Subject: [PATCH 107/111] hw/arm/virt-acpi: Advertise Tegra241 CMDQV nodes in
+ DSDT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [107/111] bae67aefac140c1e405d35e4b6a02560cc40f671 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Add ACPI DSDT support for Tegra241 CMDQV when the SMMUv3 instance is
+created with tegra241-cmdqv.
+
+For each accelerated SMMUv3 instance, add a Tegra241 CMDQV device
+object under the DSDT \_SB namespace, with HID "NVDA200C" and a UID
+that matches the Identifier of the corresponding SMMUv3 IORT node, so
+the guest OS can associate the DSDT device with the right SMMU. The
+_CRS covers the CMDQV MMIO aperture plus its interrupt, and _CCA
+declares I/O cache coherency.
+
+See ACPI Specification 6.5, Section 6 (Device Configuration) for
+_HID/_UID/_CCA/_CRS.
+
+Generated DSDT entry for a CMDQV instance paired with SMMUv3 Identifier=1:
+ ...
+ Device (CV01)
+ {
+ Name (_HID, "NVDA200C") // _HID: Hardware ID
+ Name (_UID, One) // _UID: Unique ID
+ Name (_CCA, One) // _CCA: Cache Coherency Attribute
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
+ {
+ QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+ 0x0000000000000000, // Granularity
+ 0x000000000C080000, // Range Minimum
+ 0x000000000C0CFFFF, // Range Maximum
+ 0x0000000000000000, // Translation Offset
+ 0x0000000000050000, // Length
+ ,, , AddressRangeMemory, TypeStatic)
+ Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
+ {
+ 0x00000094,
+ }
+ })
+ }
+ ...
+Generated IORT SMMUv3 node (Identifier = 1):
+
+ ...
+ [048h 0072 001h] Type : 04
+ [049h 0073 002h] Length : 0058
+ [04Bh 0075 001h] Revision : 04
+ [04Ch 0076 004h] Identifier : 00000001
+ [050h 0080 004h] Mapping Count : 00000001
+ [054h 0084 004h] Mapping Offset : 00000044
+ ...
+
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260609112552.378999-29-skolothumtho@nvidia.com
+Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 67dc6a4c911b5f3a82766d27f41c5cf60b9c17d4)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/trace-events | 1 +
+ hw/arm/virt-acpi-build.c | 52 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 53 insertions(+)
+
+diff --git a/hw/arm/trace-events b/hw/arm/trace-events
+index 0bd718b1ab..1b16f710fe 100644
+--- a/hw/arm/trace-events
++++ b/hw/arm/trace-events
+@@ -9,6 +9,7 @@ omap1_lpg_led(const char *onoff) "omap1 LPG: LED is %s"
+
+ # virt-acpi-build.c
+ virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
++virt_acpi_dsdt_tegra241_cmdqv(int smmu_id, uint64_t base, uint32_t irq) "DSDT: add cmdqv node for (id=%d), base=0x%" PRIx64 ", irq=%d"
+
+ # smmu-common.c
+ smmu_add_mr(const char *name) "%s"
+diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
+index 20dfe9e4d8..2c77d443fe 100644
+--- a/hw/arm/virt-acpi-build.c
++++ b/hw/arm/virt-acpi-build.c
+@@ -64,6 +64,9 @@
+ #include "hw/virtio/virtio-acpi.h"
+ #include "target/arm/multiprocessing.h"
+
++#include "smmuv3-accel.h"
++#include "tegra241-cmdqv.h"
++
+ #define ARM_SPI_BASE 32
+
+ #define ACPI_BUILD_TABLE_SIZE 0x20000
+@@ -1116,6 +1119,51 @@ static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
+ build_fadt(table_data, linker, &fadt, vms->oem_id, vms->oem_table_id);
+ }
+
++static void acpi_dsdt_add_tegra241_cmdqv(Aml *scope, VirtMachineState *vms)
++{
++ for (int i = 0; i < vms->smmuv3_devices->len; i++) {
++ Object *obj = OBJECT(g_ptr_array_index(vms->smmuv3_devices, i));
++ PlatformBusDevice *pbus;
++ Aml *dev, *crs, *addr;
++ SysBusDevice *sbdev;
++ hwaddr base;
++ uint32_t id;
++ int irq;
++
++ if (smmuv3_accel_cmdqv_type(obj) != SMMUV3_CMDQV_TEGRA241) {
++ continue;
++ }
++ id = object_property_get_uint(obj, "identifier", &error_abort);
++ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
++ sbdev = SYS_BUS_DEVICE(obj);
++ base = platform_bus_get_mmio_addr(pbus, sbdev, 1);
++ base += vms->memmap[VIRT_PLATFORM_BUS].base;
++ irq = platform_bus_get_irqn(pbus, sbdev, NUM_SMMU_IRQS);
++ irq += vms->irqmap[VIRT_PLATFORM_BUS];
++ irq += ARM_SPI_BASE;
++
++ dev = aml_device("CV%.02u", id);
++ aml_append(dev, aml_name_decl("_HID", aml_string("NVDA200C")));
++ aml_append(dev, aml_name_decl("_UID", aml_int(id)));
++ aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
++
++ crs = aml_resource_template();
++ addr = aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
++ AML_CACHEABLE, AML_READ_WRITE, 0x0, base,
++ base + TEGRA241_CMDQV_IO_LEN - 0x1, 0x0,
++ TEGRA241_CMDQV_IO_LEN);
++ aml_append(crs, addr);
++ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE,
++ AML_ACTIVE_HIGH, AML_EXCLUSIVE,
++ (uint32_t *)&irq, 1));
++ aml_append(dev, aml_name_decl("_CRS", crs));
++
++ aml_append(scope, dev);
++
++ trace_virt_acpi_dsdt_tegra241_cmdqv(id, base, irq);
++ }
++}
++
+ /* DSDT */
+ static void
+ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+@@ -1179,6 +1227,10 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ acpi_dsdt_add_tpm(scope, vms);
+ #endif
+
++ if (!vms->legacy_smmuv3_present) {
++ acpi_dsdt_add_tegra241_cmdqv(scope, vms);
++ }
++
+ aml_append(dsdt, scope);
+
+ pci0_scope = aml_scope("\\_SB.PCI0");
+--
+2.52.0
+
diff --git a/kvm-hw-arm-virt-acpi-build-Add-IORT-RMR-regions-to-handl.patch b/kvm-hw-arm-virt-acpi-build-Add-IORT-RMR-regions-to-handl.patch
new file mode 100644
index 0000000..d19328b
--- /dev/null
+++ b/kvm-hw-arm-virt-acpi-build-Add-IORT-RMR-regions-to-handl.patch
@@ -0,0 +1,291 @@
+From 37e10410d051d4e6143e6e9ecda4547f18977a68 Mon Sep 17 00:00:00 2001
+From: Eric Auger <eric.auger@redhat.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 033/111] hw/arm/virt-acpi-build: Add IORT RMR regions to
+ handle MSI nested binding
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [33/111] d727e3f2e2cc2886cf9498b1a5e757017f16ca5e (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+To handle SMMUv3 accel=on mode(which configures the host SMMUv3 in nested
+mode), it is practical to expose the guest with reserved memory regions
+(RMRs) covering the IOVAs used by the host kernel to map physical MSI
+doorbells.
+
+Those IOVAs belong to [0x8000000, 0x8100000] matching MSI_IOVA_BASE and
+MSI_IOVA_LENGTH definitions in kernel arm-smmu-v3 driver. This is the
+window used to allocate IOVAs matching physical MSI doorbells.
+
+With those RMRs, the guest is forced to use a flat mapping for this range.
+Hence the assigned device is programmed with one IOVA from this range.
+Stage 1, owned by the guest has a flat mapping for this IOVA. Stage2,
+owned by the VMM then enforces a mapping from this IOVA to the physical
+MSI doorbell.
+
+The creation of those RMR nodes is only relevant if nested stage SMMU is
+in use, along with VFIO. As VFIO devices can be hotplugged, all RMRs need
+to be created in advance.
+
+Initialise AcpiIortSMMUv3Dev structures to avoid using uninitialised
+state when building the IORT, as legacy and device SMMUv3 paths
+populate different fields now(e.g. accel).
+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Message-id: 20260126104342.253965-26-skolothumtho@nvidia.com
+Suggested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 06c0c8fde7867f634f226cec6a318606885b9bc8)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/virt-acpi-build.c | 115 +++++++++++++++++++++++++++++++++++----
+ 1 file changed, 105 insertions(+), 10 deletions(-)
+
+diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
+index 6883147040..1323d1a0da 100644
+--- a/hw/arm/virt-acpi-build.c
++++ b/hw/arm/virt-acpi-build.c
+@@ -263,6 +263,29 @@ static void acpi_dsdt_add_tpm(Aml *scope, VirtMachineState *vms)
+ #define ROOT_COMPLEX_ENTRY_SIZE 36
+ #define IORT_NODE_OFFSET 48
+
++#define IORT_RMR_NUM_ID_MAPPINGS 1
++#define IORT_RMR_NUM_MEM_RANGE_DESC 1
++#define IORT_RMR_COMMON_HEADER_SIZE 28
++#define IORT_RMR_MEM_RANGE_DESC_SIZE 20
++
++/*
++ * IORT RMR flags:
++ * Bit[0] = 0 Disallow remapping of reserved ranges
++ * Bit[1] = 0 Unprivileged access
++ * Bits[9:2] = 0x00 Device nGnRnE memory
++ */
++#define IORT_RMR_FLAGS 0
++
++/*
++ * MSI doorbell IOVA window used by the host kernel SMMUv3 driver.
++ * Described in IORT RMR nodes to reserve the IOVA range where the host
++ * kernel maps physical MSI doorbells for devices. This ensures guests
++ * preserve a flat mapping for MSI doorbell in nested SMMUv3(accel=on)
++ * configurations.
++ */
++#define MSI_IOVA_BASE 0x8000000
++#define MSI_IOVA_LENGTH 0x100000
++
+ /*
+ * Append an ID mapping entry as described by "Table 4 ID mapping format" in
+ * "IO Remapping Table System Software on ARM Platforms", Chapter 3.
+@@ -271,7 +294,8 @@ static void acpi_dsdt_add_tpm(Aml *scope, VirtMachineState *vms)
+ * Note that @id_count gets internally subtracted by one, following the spec.
+ */
+ static void build_iort_id_mapping(GArray *table_data, uint32_t input_base,
+- uint32_t id_count, uint32_t out_ref)
++ uint32_t id_count, uint32_t out_ref,
++ uint32_t flags)
+ {
+ build_append_int_noprefix(table_data, input_base, 4); /* Input base */
+ /* Number of IDs - The number of IDs in the range minus one */
+@@ -279,7 +303,7 @@ static void build_iort_id_mapping(GArray *table_data, uint32_t input_base,
+ build_append_int_noprefix(table_data, input_base, 4); /* Output base */
+ build_append_int_noprefix(table_data, out_ref, 4); /* Output Reference */
+ /* Flags */
+- build_append_int_noprefix(table_data, 0 /* Single mapping (disabled) */, 4);
++ build_append_int_noprefix(table_data, flags, 4);
+ }
+
+ struct AcpiIortIdMapping {
+@@ -327,6 +351,7 @@ typedef struct AcpiIortSMMUv3Dev {
+ GArray *rc_smmu_idmaps;
+ /* Offset of the SMMUv3 IORT Node relative to the start of the IORT */
+ size_t offset;
++ bool accel;
+ } AcpiIortSMMUv3Dev;
+
+ /*
+@@ -336,7 +361,7 @@ typedef struct AcpiIortSMMUv3Dev {
+ static int populate_smmuv3_legacy_dev(GArray *sdev_blob)
+ {
+ VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine());
+- AcpiIortSMMUv3Dev sdev;
++ AcpiIortSMMUv3Dev sdev = {0};
+
+ sdev.rc_smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
+ object_child_foreach_recursive(object_get_root(), iort_host_bridges,
+@@ -368,10 +393,10 @@ static int smmuv3_dev_idmap_compare(gconstpointer a, gconstpointer b)
+ static int iort_smmuv3_devices(Object *obj, void *opaque)
+ {
+ VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine());
++ AcpiIortSMMUv3Dev sdev = {0};
+ GArray *sdev_blob = opaque;
+ AcpiIortIdMapping idmap;
+ PlatformBusDevice *pbus;
+- AcpiIortSMMUv3Dev sdev;
+ int min_bus, max_bus;
+ SysBusDevice *sbdev;
+ PCIBus *bus;
+@@ -381,6 +406,9 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
+ }
+
+ bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
++ if (object_property_find(obj, "accel")) {
++ sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
++ }
+ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+ sbdev = SYS_BUS_DEVICE(obj);
+ sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+@@ -454,10 +482,69 @@ static void create_rc_its_idmaps(GArray *its_idmaps, GArray *smmuv3_devs)
+ }
+ }
+
++static void
++build_iort_rmr_nodes(GArray *table_data, GArray *smmuv3_devices, uint32_t *id)
++{
++ AcpiIortSMMUv3Dev *sdev;
++ AcpiIortIdMapping *idmap;
++ int i;
++
++ for (i = 0; i < smmuv3_devices->len; i++) {
++ uint16_t rmr_len;
++ int bdf;
++
++ sdev = &g_array_index(smmuv3_devices, AcpiIortSMMUv3Dev, i);
++ if (!sdev->accel) {
++ continue;
++ }
++
++ /*
++ * Spec reference:Arm IO Remapping Table(IORT), ARM DEN 0049E.d,
++ * Section 3.1.1.5 "Reserved Memory Range node"
++ */
++ idmap = &g_array_index(sdev->rc_smmu_idmaps, AcpiIortIdMapping, 0);
++ bdf = idmap->input_base;
++ rmr_len = IORT_RMR_COMMON_HEADER_SIZE
++ + (IORT_RMR_NUM_ID_MAPPINGS * ID_MAPPING_ENTRY_SIZE)
++ + (IORT_RMR_NUM_MEM_RANGE_DESC * IORT_RMR_MEM_RANGE_DESC_SIZE);
++
++ /* Table 18 Reserved Memory Range Node */
++ build_append_int_noprefix(table_data, 6 /* RMR */, 1); /* Type */
++ /* Length */
++ build_append_int_noprefix(table_data, rmr_len, 2);
++ build_append_int_noprefix(table_data, 3, 1); /* Revision */
++ build_append_int_noprefix(table_data, (*id)++, 4); /* Identifier */
++ /* Number of ID mappings */
++ build_append_int_noprefix(table_data, IORT_RMR_NUM_ID_MAPPINGS, 4);
++ /* Reference to ID Array */
++ build_append_int_noprefix(table_data, IORT_RMR_COMMON_HEADER_SIZE, 4);
++
++ /* RMR specific data */
++
++ /* Flags */
++ build_append_int_noprefix(table_data, IORT_RMR_FLAGS, 4);
++ /* Number of Memory Range Descriptors */
++ build_append_int_noprefix(table_data, IORT_RMR_NUM_MEM_RANGE_DESC, 4);
++ /* Reference to Memory Range Descriptors */
++ build_append_int_noprefix(table_data, IORT_RMR_COMMON_HEADER_SIZE +
++ (IORT_RMR_NUM_ID_MAPPINGS * ID_MAPPING_ENTRY_SIZE), 4);
++ build_iort_id_mapping(table_data, bdf, idmap->id_count, sdev->offset,
++ 1);
++
++ /* Table 19 Memory Range Descriptor */
++
++ /* Physical Range offset */
++ build_append_int_noprefix(table_data, MSI_IOVA_BASE, 8);
++ /* Physical Range length */
++ build_append_int_noprefix(table_data, MSI_IOVA_LENGTH, 8);
++ build_append_int_noprefix(table_data, 0, 4); /* Reserved */
++ }
++}
++
+ /*
+ * Input Output Remapping Table (IORT)
+ * Conforms to "IO Remapping Table System Software on ARM Platforms",
+- * Document number: ARM DEN 0049E.b, Feb 2021
++ * Document number: ARM DEN 0049E.d, Feb 2022
+ */
+ static void
+ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+@@ -471,7 +558,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ GArray *smmuv3_devs = g_array_new(false, true, sizeof(AcpiIortSMMUv3Dev));
+ GArray *rc_its_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
+
+- AcpiTable table = { .sig = "IORT", .rev = 3, .oem_id = vms->oem_id,
++ AcpiTable table = { .sig = "IORT", .rev = 5, .oem_id = vms->oem_id,
+ .oem_table_id = vms->oem_table_id };
+ /* Table 2 The IORT */
+ acpi_table_begin(&table, table_data);
+@@ -497,6 +584,13 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ nb_nodes++; /* ITS */
+ rc_mapping_count += rc_its_idmaps->len;
+ }
++ /* Calculate RMR nodes required. One per SMMUv3 with accelerated mode */
++ for (i = 0; i < num_smmus; i++) {
++ sdev = &g_array_index(smmuv3_devs, AcpiIortSMMUv3Dev, i);
++ if (sdev->accel) {
++ nb_nodes++;
++ }
++ }
+ } else {
+ if (vms->its) {
+ nb_nodes = 2; /* RC and ITS */
+@@ -569,7 +663,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ /* Array of ID mappings */
+ if (smmu_mapping_count) {
+ /* Output IORT node is the ITS Group node (the first node). */
+- build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET);
++ build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET, 0);
+ }
+ }
+
+@@ -621,7 +715,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ AcpiIortIdMapping, j);
+ /* Output IORT node is the SMMUv3 node. */
+ build_iort_id_mapping(table_data, range->input_base,
+- range->id_count, sdev->offset);
++ range->id_count, sdev->offset, 0);
+ }
+ }
+
+@@ -634,7 +728,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ range = &g_array_index(rc_its_idmaps, AcpiIortIdMapping, i);
+ /* Output IORT node is the ITS Group node (the first node). */
+ build_iort_id_mapping(table_data, range->input_base,
+- range->id_count, IORT_NODE_OFFSET);
++ range->id_count, IORT_NODE_OFFSET, 0);
+ }
+ }
+ } else {
+@@ -643,9 +737,10 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+ * SMMU: RC -> ITS.
+ * Output IORT node is the ITS Group node (the first node).
+ */
+- build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET);
++ build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET, 0);
+ }
+
++ build_iort_rmr_nodes(table_data, smmuv3_devs, &id);
+ acpi_table_end(linker, &table);
+ g_array_free(rc_its_idmaps, true);
+ for (i = 0; i < num_smmus; i++) {
+--
+2.52.0
+
diff --git a/kvm-hw-pci-Add-helper-to-insert-PCIe-extended-capability.patch b/kvm-hw-pci-Add-helper-to-insert-PCIe-extended-capability.patch
new file mode 100644
index 0000000..9ec6151
--- /dev/null
+++ b/kvm-hw-pci-Add-helper-to-insert-PCIe-extended-capability.patch
@@ -0,0 +1,144 @@
+From 3e612715c478cb8707e854e1c775485598ab1316 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 042/111] hw/pci: Add helper to insert PCIe extended capability
+ at a fixed offset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [42/111] a442c70c88c172c341736a6cab31e11622ff9c75 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Add pcie_insert_capability(), a helper to insert a PCIe extended
+capability into an existing extended capability list at a caller
+specified offset.
+
+Unlike pcie_add_capability(), which always appends a capability to the
+end of the list, this helper preserves the existing list ordering while
+allowing insertion at an arbitrary offset.
+
+The helper only validates that the insertion does not overwrite an
+existing PCIe extended capability header, since corrupting a header
+would break the extended capability linked list. Validation of overlaps
+with other configuration space registers or capability-specific
+register blocks is left to the caller.
+
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-35-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 49a2bed19b0e4e68bdc06e6c37532313193e766c)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/pci/pcie.c | 69 +++++++++++++++++++++++++++++++++++++++++++
+ include/hw/pci/pcie.h | 2 ++
+ 2 files changed, 71 insertions(+)
+
+diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
+index eaeb68894e..348b26e4f1 100644
+--- a/hw/pci/pcie.c
++++ b/hw/pci/pcie.c
+@@ -1050,6 +1050,75 @@ static void pcie_ext_cap_set_next(PCIDevice *dev, uint16_t pos, uint16_t next)
+ pci_set_long(dev->config + pos, header);
+ }
+
++/*
++ * Insert a PCIe extended capability at a given offset.
++ *
++ * This helper only validates that the insertion does not overwrite an
++ * existing PCIe extended capability header, as corrupting a header would
++ * break the extended capability linked list.
++ *
++ * The caller must ensure that (offset, size) does not overlap with other
++ * registers or capability-specific register blocks. Overlaps with
++ * capability-specific registers are not checked and are considered a
++ * user-controlled override.
++ *
++ * Note: Best effort helper. The PCIe spec does not require extended
++ * capabilities to be ordered, but most devices use a forward-linked list.
++ * Devices that do not consistently use a forward-linked list may cause
++ * insertion to fail.
++ */
++bool pcie_insert_capability(PCIDevice *dev, uint16_t cap_id, uint8_t cap_ver,
++ uint16_t offset, uint16_t size)
++{
++ uint16_t pos = PCI_CONFIG_SPACE_SIZE, prev = 0;
++ uint32_t header;
++
++ assert(pci_is_express(dev));
++
++ if (!QEMU_IS_ALIGNED(offset, PCI_EXT_CAP_ALIGN) ||
++ size < 8 ||
++ offset < PCI_CONFIG_SPACE_SIZE ||
++ offset >= PCIE_CONFIG_SPACE_SIZE ||
++ offset + size > PCIE_CONFIG_SPACE_SIZE) {
++ return false;
++ }
++
++ header = pci_get_long(dev->config + pos);
++ if (!header) {
++ /* No extended capability present, insertion must be at the ECAP head */
++ if (offset != pos) {
++ return false;
++ }
++ pci_set_long(dev->config + pos, PCI_EXT_CAP(cap_id, cap_ver, 0));
++ goto out;
++ }
++
++ while (header && pos && offset >= pos) {
++ uint16_t next = PCI_EXT_CAP_NEXT(header);
++
++ /* Reject insertion inside an existing ECAP header (4 bytes) */
++ if (offset < pos + PCI_EXT_CAP_ALIGN) {
++ return false;
++ }
++
++ prev = pos;
++ pos = next;
++ header = pos ? pci_get_long(dev->config + pos) : 0;
++ }
++
++ pci_set_long(dev->config + offset, PCI_EXT_CAP(cap_id, cap_ver, pos));
++ if (prev) {
++ pcie_ext_cap_set_next(dev, prev, offset);
++ }
++
++out:
++ /* Make capability read-only by default */
++ memset(dev->wmask + offset, 0, size);
++ memset(dev->w1cmask + offset, 0, size);
++ /* Check capability by default */
++ memset(dev->cmask + offset, 0xFF, size);
++ return true;
++}
+ /*
+ * Caller must supply valid (offset, size) such that the range wouldn't
+ * overlap with other capability or other registers.
+diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
+index ff6ce08e13..3d01718c96 100644
+--- a/include/hw/pci/pcie.h
++++ b/include/hw/pci/pcie.h
+@@ -133,6 +133,8 @@ uint16_t pcie_find_capability(PCIDevice *dev, uint16_t cap_id);
+ void pcie_add_capability(PCIDevice *dev,
+ uint16_t cap_id, uint8_t cap_ver,
+ uint16_t offset, uint16_t size);
++bool pcie_insert_capability(PCIDevice *dev, uint16_t cap_id, uint8_t cap_ver,
++ uint16_t offset, uint16_t size);
+ void pcie_sync_bridge_lnk(PCIDevice *dev);
+
+ void pcie_acs_init(PCIDevice *dev, uint16_t offset);
+--
+2.52.0
+
diff --git a/kvm-hw-pci-Export-pci_device_get_iommu_bus_devfn-and-ret.patch b/kvm-hw-pci-Export-pci_device_get_iommu_bus_devfn-and-ret.patch
new file mode 100644
index 0000000..796e993
--- /dev/null
+++ b/kvm-hw-pci-Export-pci_device_get_iommu_bus_devfn-and-ret.patch
@@ -0,0 +1,99 @@
+From 557603fab8b9a836d4a00e5c0a169b581b21c526 Mon Sep 17 00:00:00 2001
+From: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Date: Tue, 6 Jan 2026 01:12:46 -0500
+Subject: [PATCH 010/111] hw/pci: Export pci_device_get_iommu_bus_devfn() and
+ return bool
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [10/111] eaed17d04b1a47b5101c99ca8066769b1fcc0ba7 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Returns true if PCI device is aliased or false otherwise. This will be
+used in following patch to determine if a PCI device is under a PCI
+bridge.
+
+Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Link: https://lore.kernel.org/qemu-devel/20260106061304.314546-5-zhenzhong.duan@intel.com
+Signed-off-by: Cédric Le Goater <clg@redhat.com>
+(cherry picked from commit d58230d8754fedf6fc7313e0faa25bb5edc5ba2e)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/pci/pci.c | 12 ++++++++----
+ include/hw/pci/pci.h | 2 ++
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index a8eeafd3b2..15dd232cf8 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -2855,20 +2855,21 @@ static void pci_device_class_base_init(ObjectClass *klass, const void *data)
+ * For call sites which don't need aliased BDF, passing NULL to
+ * aliased_[bus|devfn] is allowed.
+ *
++ * Returns true if PCI device RID is aliased or false otherwise.
++ *
+ * @piommu_bus: return root #PCIBus backed by an IOMMU for the PCI device.
+ *
+ * @aliased_bus: return aliased #PCIBus of the PCI device, optional.
+ *
+ * @aliased_devfn: return aliased devfn of the PCI device, optional.
+ */
+-static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
+- PCIBus **piommu_bus,
+- PCIBus **aliased_bus,
+- int *aliased_devfn)
++bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus,
++ PCIBus **aliased_bus, int *aliased_devfn)
+ {
+ PCIBus *bus = pci_get_bus(dev);
+ PCIBus *iommu_bus = bus;
+ int devfn = dev->devfn;
++ bool aliased = false;
+
+ while (iommu_bus && !iommu_bus->iommu_ops && iommu_bus->parent_dev) {
+ PCIBus *parent_bus = pci_get_bus(iommu_bus->parent_dev);
+@@ -2905,6 +2906,7 @@ static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
+ devfn = parent->devfn;
+ bus = parent_bus;
+ }
++ aliased = true;
+ }
+
+ /*
+@@ -2939,6 +2941,8 @@ static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
+ if (aliased_devfn) {
+ *aliased_devfn = devfn;
+ }
++
++ return aliased;
+ }
+
+ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
+diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
+index 6bccb25ac2..bde9dca8e2 100644
+--- a/include/hw/pci/pci.h
++++ b/include/hw/pci/pci.h
+@@ -637,6 +637,8 @@ typedef struct PCIIOMMUOps {
+ bool is_write);
+ } PCIIOMMUOps;
+
++bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus,
++ PCIBus **aliased_bus, int *aliased_devfn);
+ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
+ bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
+ Error **errp);
+--
+2.52.0
+
diff --git a/kvm-hw-pci-Factor-out-common-PASID-capability-initializa.patch b/kvm-hw-pci-Factor-out-common-PASID-capability-initializa.patch
new file mode 100644
index 0000000..87eac08
--- /dev/null
+++ b/kvm-hw-pci-Factor-out-common-PASID-capability-initializa.patch
@@ -0,0 +1,101 @@
+From 980df3009788a6c4e449c98caecf117f50820753 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 043/111] hw/pci: Factor out common PASID capability
+ initialization
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [43/111] 1016e3b1598c9595a0b7ea324a44d84d53fd807e (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Refactor PCIe PASID capability initialization by moving the common
+register init into a new helper, pcie_pasid_common_init().
+
+Subsequent patch to synthesize a vPASID will make use of this
+helper.
+
+No functional change intended.
+
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-36-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 7d59fa20594ec053861f7c49ac53090a41901209)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/pci/pcie.c | 19 ++++++++++++-------
+ include/hw/pci/pcie.h | 2 ++
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
+index 348b26e4f1..40242fead2 100644
+--- a/hw/pci/pcie.c
++++ b/hw/pci/pcie.c
+@@ -1284,18 +1284,13 @@ void pcie_acs_reset(PCIDevice *dev)
+ }
+ }
+
+-/* PASID */
+-void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
+- bool exec_perm, bool priv_mod)
++void pcie_pasid_common_init(PCIDevice *dev, uint16_t offset,
++ uint8_t pasid_width, bool exec_perm, bool priv_mod)
+ {
+ static const uint16_t control_reg_rw_mask = 0x07;
+ uint16_t capability_reg;
+
+ assert(pasid_width <= PCI_EXT_CAP_PASID_MAX_WIDTH);
+-
+- pcie_add_capability(dev, PCI_EXT_CAP_ID_PASID, PCI_PASID_VER, offset,
+- PCI_EXT_CAP_PASID_SIZEOF);
+-
+ capability_reg = ((uint16_t)pasid_width) << PCI_PASID_CAP_WIDTH_SHIFT;
+ capability_reg |= exec_perm ? PCI_PASID_CAP_EXEC : 0;
+ capability_reg |= priv_mod ? PCI_PASID_CAP_PRIV : 0;
+@@ -1307,6 +1302,16 @@ void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
+ pci_set_word(dev->wmask + offset + PCI_PASID_CTRL, control_reg_rw_mask);
+
+ dev->exp.pasid_cap = offset;
++
++}
++
++/* PASID */
++void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
++ bool exec_perm, bool priv_mod)
++{
++ pcie_add_capability(dev, PCI_EXT_CAP_ID_PASID, PCI_PASID_VER, offset,
++ PCI_EXT_CAP_PASID_SIZEOF);
++ pcie_pasid_common_init(dev, offset, pasid_width, exec_perm, priv_mod);
+ }
+
+ /* PRI */
+diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
+index 3d01718c96..029a809ae2 100644
+--- a/include/hw/pci/pcie.h
++++ b/include/hw/pci/pcie.h
+@@ -155,6 +155,8 @@ void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp);
+
++void pcie_pasid_common_init(PCIDevice *dev, uint16_t offset,
++ uint8_t pasid_width, bool exec_perm, bool priv_mod);
+ void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
+ bool exec_perm, bool priv_mod);
+ void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
+--
+2.52.0
+
diff --git a/kvm-hw-pci-Introduce-pci_device_get_host_iommu_quirks.patch b/kvm-hw-pci-Introduce-pci_device_get_host_iommu_quirks.patch
new file mode 100644
index 0000000..1bd9475
--- /dev/null
+++ b/kvm-hw-pci-Introduce-pci_device_get_host_iommu_quirks.patch
@@ -0,0 +1,130 @@
+From dc2391bb200e6ab3c38d76db46919ff4bd7c3e60 Mon Sep 17 00:00:00 2001
+From: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Date: Tue, 6 Jan 2026 01:28:03 -0500
+Subject: [PATCH 016/111] hw/pci: Introduce pci_device_get_host_iommu_quirks()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [16/111] dd4f09360ae6171c7faf6f18af2f6c66367189f7 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+In VFIO core, we call iommufd_backend_get_device_info() to return vendor
+specific hardware information data, but it's not good to retrieve this raw
+data in VFIO core.
+
+Introduce a new PCIIOMMUOps optional callback, get_host_iommu_quirk() which
+allows to retrieve the vendor specific hardware information data and convert
+it into bitmaps defined with enum host_iommu_quirks.
+
+pci_device_get_host_iommu_quirks() is a wrapper that can be called on a PCI
+device potentially protected by a vIOMMU.
+
+Suggested-by: Eric Auger <eric.auger@redhat.com>
+Suggested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Link: https://lore.kernel.org/qemu-devel/20260106062808.316574-2-zhenzhong.duan@intel.com
+Signed-off-by: Cédric Le Goater <clg@redhat.com>
+(cherry picked from commit cd4d7fb72109043d60b5cf6191a1678e96775b98)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/pci/pci.c | 12 ++++++++++++
+ include/hw/core/iommu.h | 5 +++++
+ include/hw/pci/pci.h | 31 +++++++++++++++++++++++++++++++
+ 3 files changed, 48 insertions(+)
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index 27bb2285d4..1f2d4d76f9 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -3038,6 +3038,18 @@ uint64_t pci_device_get_viommu_flags(PCIDevice *dev)
+ return 0;
+ }
+
++uint64_t pci_device_get_host_iommu_quirks(PCIDevice *dev, uint32_t type,
++ void *caps, uint32_t size)
++{
++ PCIBus *iommu_bus;
++
++ pci_device_get_iommu_bus_devfn(dev, &iommu_bus, NULL, NULL);
++ if (iommu_bus && iommu_bus->iommu_ops->get_host_iommu_quirks) {
++ return iommu_bus->iommu_ops->get_host_iommu_quirks(type, caps, size);
++ }
++ return 0;
++}
++
+ int pci_pri_request_page(PCIDevice *dev, uint32_t pasid, bool priv_req,
+ bool exec_req, hwaddr addr, bool lpig,
+ uint16_t prgi, bool is_read, bool is_write)
+diff --git a/include/hw/core/iommu.h b/include/hw/core/iommu.h
+index fcbbcd1015..d5401a397b 100644
+--- a/include/hw/core/iommu.h
++++ b/include/hw/core/iommu.h
+@@ -22,4 +22,9 @@ enum viommu_flags {
+ VIOMMU_FLAG_WANT_NESTING_PARENT = BIT_ULL(0),
+ };
+
++/* Host IOMMU quirks. Extracted from host IOMMU capabilities */
++enum host_iommu_quirks {
++ HOST_IOMMU_QUIRK_NESTING_PARENT_BYPASS_RO = BIT_ULL(0),
++};
++
+ #endif /* HW_IOMMU_H */
+diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
+index 299e7f94da..528faafad2 100644
+--- a/include/hw/pci/pci.h
++++ b/include/hw/pci/pci.h
+@@ -493,6 +493,23 @@ typedef struct PCIIOMMUOps {
+ * enum viommu_flags.
+ */
+ uint64_t (*get_viommu_flags)(void *opaque);
++ /**
++ * @get_host_iommu_quirks: get host IOMMU quirks
++ *
++ * Optional callback, if not implemented, then vIOMMU doesn't support
++ * converting @type specific hardware information data into a standard
++ * bitmap format.
++ *
++ * @type: IOMMU hardware info type
++ *
++ * @caps: IOMMU @type specific hardware information data
++ *
++ * @size: size of @caps
++ *
++ * Returns: bitmap with each bit representing a host IOMMU quirk defined in
++ * enum host_iommu_quirks
++ */
++ uint64_t (*get_host_iommu_quirks)(uint32_t type, void *caps, uint32_t size);
+ /**
+ * @get_iotlb_info: get properties required to initialize a device IOTLB.
+ *
+@@ -685,6 +702,20 @@ void pci_device_unset_iommu_device(PCIDevice *dev);
+ */
+ uint64_t pci_device_get_viommu_flags(PCIDevice *dev);
+
++/**
++ * pci_device_get_host_iommu_quirks: get host IOMMU quirks.
++ *
++ * Returns: bitmap with each bit representing a host IOMMU quirk defined in
++ * enum host_iommu_quirks. Or 0 if vIOMMU doesn't convert any.
++ *
++ * @dev: PCI device pointer.
++ * @type: IOMMU hardware info type
++ * @caps: IOMMU @type specific hardware information data
++ * @size: size of @caps
++ */
++uint64_t pci_device_get_host_iommu_quirks(PCIDevice *dev, uint32_t type,
++ void *caps, uint32_t size);
++
+ /**
+ * pci_iommu_get_iotlb_info: get properties required to initialize a
+ * device IOTLB.
+--
+2.52.0
+
diff --git a/kvm-hw-pci-Introduce-pci_device_get_viommu_flags.patch b/kvm-hw-pci-Introduce-pci_device_get_viommu_flags.patch
new file mode 100644
index 0000000..5593623
--- /dev/null
+++ b/kvm-hw-pci-Introduce-pci_device_get_viommu_flags.patch
@@ -0,0 +1,177 @@
+From 299e2a06b1166b9d942ccf0e49703916b6a5028d Mon Sep 17 00:00:00 2001
+From: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Date: Tue, 6 Jan 2026 01:12:47 -0500
+Subject: [PATCH 015/111] hw/pci: Introduce pci_device_get_viommu_flags()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [15/111] ccbb01571d6c2e1c9ac51e05098649748bc7a8b6 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Introduce a new PCIIOMMUOps optional callback, get_viommu_flags() which
+allows to retrieve flags exposed by a vIOMMU. The first planned vIOMMU
+device flag is VIOMMU_FLAG_WANT_NESTING_PARENT that advertises the
+support of HW nested stage translation scheme and wants other sub-system
+like VFIO's cooperation to create nesting parent HWPT.
+
+pci_device_get_viommu_flags() is a wrapper that can be called on a PCI
+device potentially protected by a vIOMMU.
+
+get_viommu_flags() is designed to return 64bit bitmap of purely vIOMMU
+flags which are only determined by user's configuration, no host
+capabilities involved. Reasons are:
+
+1. host may has heterogeneous IOMMUs, each with different capabilities
+2. this is migration friendly, return value is consistent between source
+ and target.
+
+Note that this op will be invoked at the attach_device() stage, at which
+point host IOMMU capabilities are not yet forwarded to the vIOMMU through
+the set_iommu_device() callback that will be after the attach_device().
+
+See below sequence:
+
+ vfio_device_attach():
+ iommufd_cdev_attach():
+ pci_device_get_viommu_flags() for HW nesting cap
+ create a nesting parent HWPT
+ attach device to the HWPT
+ vfio_device_hiod_create_and_realize() creating hiod
+ ...
+ pci_device_set_iommu_device(hiod)
+
+Suggested-by: Yi Liu <yi.l.liu@intel.com>
+Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Reviewed-by: Cédric Le Goater <clg@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Link: https://lore.kernel.org/qemu-devel/20260106061304.314546-6-zhenzhong.duan@intel.com
+[ clg: include/hw/core/iommu.h: Changed Copyright date 2025 -> 2026 ]
+Signed-off-by: Cédric Le Goater <clg@redhat.com>
+(cherry picked from commit 844302bd5961d8e7a35b601495b9af8f3d26a4c8)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ MAINTAINERS | 1 +
+ hw/pci/pci.c | 11 +++++++++++
+ include/hw/core/iommu.h | 25 +++++++++++++++++++++++++
+ include/hw/pci/pci.h | 22 ++++++++++++++++++++++
+ 4 files changed, 59 insertions(+)
+ create mode 100644 include/hw/core/iommu.h
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index d4696f00d7..c71f53c480 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -2320,6 +2320,7 @@ F: include/system/iommufd.h
+ F: backends/host_iommu_device.c
+ F: include/system/host_iommu_device.h
+ F: include/qemu/chardev_open.h
++F: include/hw/core/iommu.h
+ F: util/chardev_open.c
+ F: docs/devel/vfio-iommufd.rst
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index 141b7ad1f8..27bb2285d4 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -3027,6 +3027,17 @@ void pci_device_unset_iommu_device(PCIDevice *dev)
+ }
+ }
+
++uint64_t pci_device_get_viommu_flags(PCIDevice *dev)
++{
++ PCIBus *iommu_bus;
++
++ pci_device_get_iommu_bus_devfn(dev, &iommu_bus, NULL, NULL);
++ if (iommu_bus && iommu_bus->iommu_ops->get_viommu_flags) {
++ return iommu_bus->iommu_ops->get_viommu_flags(iommu_bus->iommu_opaque);
++ }
++ return 0;
++}
++
+ int pci_pri_request_page(PCIDevice *dev, uint32_t pasid, bool priv_req,
+ bool exec_req, hwaddr addr, bool lpig,
+ uint16_t prgi, bool is_read, bool is_write)
+diff --git a/include/hw/core/iommu.h b/include/hw/core/iommu.h
+new file mode 100644
+index 0000000000..fcbbcd1015
+--- /dev/null
++++ b/include/hw/core/iommu.h
+@@ -0,0 +1,25 @@
++/*
++ * General vIOMMU flags
++ *
++ * Copyright (C) 2026 Intel Corporation.
++ *
++ * SPDX-License-Identifier: GPL-2.0-or-later
++ */
++
++#ifndef HW_IOMMU_H
++#define HW_IOMMU_H
++
++#include "qemu/bitops.h"
++
++/*
++ * Theoretical vIOMMU flags. Only determined by the vIOMMU device properties and
++ * independent on the actual host IOMMU capabilities they may depend on. Each
++ * flag can be an expectation or request to other sub-system or just a pure
++ * vIOMMU capability. vIOMMU can choose which flags to expose.
++ */
++enum viommu_flags {
++ /* vIOMMU needs nesting parent HWPT to create nested HWPT */
++ VIOMMU_FLAG_WANT_NESTING_PARENT = BIT_ULL(0),
++};
++
++#endif /* HW_IOMMU_H */
+diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
+index a19773d0f9..299e7f94da 100644
+--- a/include/hw/pci/pci.h
++++ b/include/hw/pci/pci.h
+@@ -481,6 +481,18 @@ typedef struct PCIIOMMUOps {
+ * @devfn: device and function number of the PCI device.
+ */
+ void (*unset_iommu_device)(PCIBus *bus, void *opaque, int devfn);
++ /**
++ * @get_viommu_flags: get vIOMMU flags
++ *
++ * Optional callback, if not implemented, then vIOMMU doesn't support
++ * exposing flags to other sub-system, e.g., VFIO.
++ *
++ * @opaque: the data passed to pci_setup_iommu().
++ *
++ * Returns: bitmap with each bit representing a vIOMMU flag defined in
++ * enum viommu_flags.
++ */
++ uint64_t (*get_viommu_flags)(void *opaque);
+ /**
+ * @get_iotlb_info: get properties required to initialize a device IOTLB.
+ *
+@@ -663,6 +675,16 @@ bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
+ Error **errp);
+ void pci_device_unset_iommu_device(PCIDevice *dev);
+
++/**
++ * pci_device_get_viommu_flags: get vIOMMU flags.
++ *
++ * Returns: bitmap with each bit representing a vIOMMU flag defined in
++ * enum viommu_flags. Or 0 if vIOMMU doesn't report any.
++ *
++ * @dev: PCI device pointer.
++ */
++uint64_t pci_device_get_viommu_flags(PCIDevice *dev);
++
+ /**
+ * pci_iommu_get_iotlb_info: get properties required to initialize a
+ * device IOTLB.
+--
+2.52.0
+
diff --git a/kvm-hw-pci-bridge-pci_expander_bridge-Move-TYPE_PXB_PCIE.patch b/kvm-hw-pci-bridge-pci_expander_bridge-Move-TYPE_PXB_PCIE.patch
new file mode 100644
index 0000000..3aed736
--- /dev/null
+++ b/kvm-hw-pci-bridge-pci_expander_bridge-Move-TYPE_PXB_PCIE.patch
@@ -0,0 +1,64 @@
+From 16975cee959e7e130f3caae2e49cfadbded02456 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 012/111] hw/pci-bridge/pci_expander_bridge: Move
+ TYPE_PXB_PCIE_DEV to header
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [12/111] 22baeb4ca100fdc45bfc11e947d95e0737ba152c (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Move the TYPE_PXB_PCIE_DEV definition to header so that it can be
+referenced by other code in subsequent patch.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-10-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit d1c585db8bb0a65107f1e5903133bc56b29c46f2)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/pci-bridge/pci_expander_bridge.c | 1 -
+ include/hw/pci/pci_bridge.h | 1 +
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
+index 1bcceddbc4..a8eb2d2426 100644
+--- a/hw/pci-bridge/pci_expander_bridge.c
++++ b/hw/pci-bridge/pci_expander_bridge.c
+@@ -48,7 +48,6 @@ struct PXBBus {
+ char bus_path[8];
+ };
+
+-#define TYPE_PXB_PCIE_DEV "pxb-pcie"
+ OBJECT_DECLARE_SIMPLE_TYPE(PXBPCIEDev, PXB_PCIE_DEV)
+
+ static GList *pxb_dev_list;
+diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h
+index a055fd8d32..b61360b900 100644
+--- a/include/hw/pci/pci_bridge.h
++++ b/include/hw/pci/pci_bridge.h
+@@ -106,6 +106,7 @@ typedef struct PXBPCIEDev {
+
+ #define TYPE_PXB_PCIE_BUS "pxb-pcie-bus"
+ #define TYPE_PXB_CXL_BUS "pxb-cxl-bus"
++#define TYPE_PXB_PCIE_DEV "pxb-pcie"
+ #define TYPE_PXB_DEV "pxb"
+ OBJECT_DECLARE_SIMPLE_TYPE(PXBDev, PXB_DEV)
+
+--
+2.52.0
+
diff --git a/kvm-hw-pci-host-gpex-Allow-to-generate-preserve-boot-con.patch b/kvm-hw-pci-host-gpex-Allow-to-generate-preserve-boot-con.patch
new file mode 100644
index 0000000..ccf0ef1
--- /dev/null
+++ b/kvm-hw-pci-host-gpex-Allow-to-generate-preserve-boot-con.patch
@@ -0,0 +1,193 @@
+From 65626b163011d8db55a94e31a35ac5cdda951e0d Mon Sep 17 00:00:00 2001
+From: Eric Auger <eric.auger@redhat.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 030/111] hw/pci-host/gpex: Allow to generate preserve boot
+ config DSM #5
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [30/111] b597678920fc66163d769bb6800576ff8da82083 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Add a 'preserve_config' field in struct GPEXConfig and, if set, generate
+the _DSM function #5 for preserving PCI boot configurations.
+
+This will be used for SMMUv3 accel=on support in subsequent patch. When
+SMMUv3 acceleration (accel=on) is enabled, QEMU exposes IORT Reserved
+Memory Region (RMR) nodes to support MSI doorbell translations. As per
+the Arm IORT specification, using IORT RMRs mandates the presence of
+_DSM function #5 so that the OS retains the firmware-assigned PCI
+configuration. Hence, this patch adds conditional support for generating
+_DSM #5.
+
+According to the ACPI Specification, Revision 6.6, Section 9.1.1 -
+“_DSM (Device Specific Method)”,
+
+"
+If Function Index is zero, the return is a buffer containing one bit for
+each function index, starting with zero. Bit 0 indicates whether there
+is support for any functions other than function 0 for the specified
+UUID and Revision ID. If set to zero, no functions are supported (other
+than function zero) for the specified UUID and Revision ID. If set to
+one, at least one additional function is supported. For all other bits
+in the buffer, a bit is set to zero to indicate if that function index
+is not supported for the specific UUID and Revision ID. (For example,
+bit 1 set to 0 indicates that function index 1 is not supported for the
+specific UUID and Revision ID.)
+"
+
+Please refer PCI Firmware Specification, Revision 3.3, Section 4.6.5 —
+"_DSM for Preserving PCI Boot Configurations" for Function 5 of _DSM
+method.
+
+Also, while at it, move the byte_list declaration to the top of the
+function for clarity.
+
+At the moment, DSM generation is not yet enabled.
+
+The resulting AML when preserve_config=true is:
+
+ Method (_DSM, 4, NotSerialized)
+ {
+ If ((Arg0 == ToUUID ("e5c937d0-3553-4d7a-9117-ea4d19c3434d")))
+ {
+ If ((Arg2 == Zero))
+ {
+ Return (Buffer (One)
+ {
+ 0x21
+ })
+ }
+
+ If ((Arg2 == 0x05))
+ {
+ Return (Zero)
+ }
+ }
+ ...
+ }
+
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Message-id: 20260126104342.253965-23-skolothumtho@nvidia.com
+[Shameer: Removed possible duplicate _DSM creations]
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 59a5c80623abbb7f5f52fc227cfe0c142858858c)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/pci-host/gpex-acpi.c | 29 +++++++++++++++++++++++------
+ include/hw/pci-host/gpex.h | 1 +
+ 2 files changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
+index 4587baeb78..d9820f9b41 100644
+--- a/hw/pci-host/gpex-acpi.c
++++ b/hw/pci-host/gpex-acpi.c
+@@ -51,10 +51,11 @@ static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq,
+ }
+ }
+
+-static Aml *build_pci_host_bridge_dsm_method(void)
++static Aml *build_pci_host_bridge_dsm_method(bool preserve_config)
+ {
+ Aml *method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
+ Aml *UUID, *ifctx, *ifctx1, *buf;
++ uint8_t byte_list[1] = {0};
+
+ /* PCI Firmware Specification 3.0
+ * 4.6.1. _DSM for PCI Express Slot Information
+@@ -64,10 +65,23 @@ static Aml *build_pci_host_bridge_dsm_method(void)
+ UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
+ ifctx = aml_if(aml_equal(aml_arg(0), UUID));
+ ifctx1 = aml_if(aml_equal(aml_arg(2), aml_int(0)));
+- uint8_t byte_list[1] = {0};
++ if (preserve_config) {
++ /* support functions other than 0, specifically function 5 */
++ byte_list[0] = 0x21;
++ }
+ buf = aml_buffer(1, byte_list);
+ aml_append(ifctx1, aml_return(buf));
+ aml_append(ifctx, ifctx1);
++ if (preserve_config) {
++ Aml *ifctx2 = aml_if(aml_equal(aml_arg(2), aml_int(5)));
++ /*
++ * 0 - The operating system must not ignore the PCI configuration that
++ * firmware has done at boot time.
++ */
++ aml_append(ifctx2, aml_return(aml_int(0)));
++ aml_append(ifctx, ifctx2);
++ }
++
+ aml_append(method, ifctx);
+
+ byte_list[0] = 0;
+@@ -77,12 +91,13 @@ static Aml *build_pci_host_bridge_dsm_method(void)
+ }
+
+ static void acpi_dsdt_add_host_bridge_methods(Aml *dev,
+- bool enable_native_pcie_hotplug)
++ bool enable_native_pcie_hotplug,
++ bool preserve_config)
+ {
+ /* Declare an _OSC (OS Control Handoff) method */
+ aml_append(dev,
+ build_pci_host_bridge_osc_method(enable_native_pcie_hotplug));
+- aml_append(dev, build_pci_host_bridge_dsm_method());
++ aml_append(dev, build_pci_host_bridge_dsm_method(preserve_config));
+ }
+
+ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
+@@ -152,7 +167,8 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
+ build_cxl_osc_method(dev);
+ } else {
+ /* pxb bridges do not have ACPI PCI Hot-plug enabled */
+- acpi_dsdt_add_host_bridge_methods(dev, true);
++ acpi_dsdt_add_host_bridge_methods(dev, true,
++ cfg->preserve_config);
+ }
+
+ aml_append(scope, dev);
+@@ -227,7 +243,8 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
+ }
+ aml_append(dev, aml_name_decl("_CRS", rbuf));
+
+- acpi_dsdt_add_host_bridge_methods(dev, cfg->pci_native_hotplug);
++ acpi_dsdt_add_host_bridge_methods(dev, cfg->pci_native_hotplug,
++ cfg->preserve_config);
+
+ Aml *dev_res0 = aml_device("%s", "RES0");
+ aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02")));
+diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
+index feaf827474..7eea16e728 100644
+--- a/include/hw/pci-host/gpex.h
++++ b/include/hw/pci-host/gpex.h
+@@ -46,6 +46,7 @@ struct GPEXConfig {
+ int irq;
+ PCIBus *bus;
+ bool pci_native_hotplug;
++ bool preserve_config;
+ };
+
+ typedef struct GPEXIrq GPEXIrq;
+--
+2.52.0
+
diff --git a/kvm-hw-pci-pci-Add-optional-supports_address_space-callb.patch b/kvm-hw-pci-pci-Add-optional-supports_address_space-callb.patch
new file mode 100644
index 0000000..67c5522
--- /dev/null
+++ b/kvm-hw-pci-pci-Add-optional-supports_address_space-callb.patch
@@ -0,0 +1,121 @@
+From 0eeecd2bc75468d6a046ae603b21403ca879e779 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 011/111] hw/pci/pci: Add optional supports_address_space()
+ callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [11/111] 21143011cab792cbd353b19b5ceb25b02f2ec689 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Introduce an optional supports_address_space() callback in PCIIOMMUOps to
+allow a vIOMMU implementation to reject devices that should not be attached
+to it.
+
+Currently, get_address_space() is the first and mandatory callback into the
+vIOMMU layer, which always returns an address space. For certain setups, such
+as hardware accelerated vIOMMUs (e.g. ARM SMMUv3 with accel=on), attaching
+emulated endpoint devices is undesirable as it may impact the behavior or
+performance of VFIO passthrough devices, for example, by triggering
+unnecessary invalidations on the host IOMMU.
+
+The new callback allows a vIOMMU to check and reject unsupported devices
+early during PCI device registration.
+
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-9-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 84ce97290c198a36efc596aefb78f5d3b0e86f6c)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/pci/pci.c | 20 ++++++++++++++++++++
+ include/hw/pci/pci.h | 19 +++++++++++++++++++
+ 2 files changed, 39 insertions(+)
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index 15dd232cf8..141b7ad1f8 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -135,6 +135,21 @@ static void pci_set_master(PCIDevice *d, bool enable)
+ d->is_master = enable; /* cache the status */
+ }
+
++static bool
++pci_device_supports_iommu_address_space(PCIDevice *dev, Error **errp)
++{
++ PCIBus *bus;
++ PCIBus *iommu_bus;
++ int devfn;
++
++ pci_device_get_iommu_bus_devfn(dev, &iommu_bus, &bus, &devfn);
++ if (iommu_bus && iommu_bus->iommu_ops->supports_address_space) {
++ return iommu_bus->iommu_ops->supports_address_space(bus,
++ iommu_bus->iommu_opaque, devfn, errp);
++ }
++ return true;
++}
++
+ static void pci_init_bus_master(PCIDevice *pci_dev)
+ {
+ AddressSpace *dma_as = pci_device_iommu_address_space(pci_dev);
+@@ -1412,6 +1427,11 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
+ pci_dev->config_write = config_write;
+ bus->devices[devfn] = pci_dev;
+ pci_dev->version_id = 2; /* Current pci device vmstate version */
++ if (!pci_device_supports_iommu_address_space(pci_dev, errp)) {
++ do_pci_unregister_device(pci_dev);
++ bus->devices[devfn] = NULL;
++ return NULL;
++ }
+ if (phase_check(PHASE_MACHINE_READY)) {
+ pci_init_bus_master(pci_dev);
+ }
+diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
+index bde9dca8e2..a19773d0f9 100644
+--- a/include/hw/pci/pci.h
++++ b/include/hw/pci/pci.h
+@@ -417,6 +417,25 @@ typedef struct IOMMUPRINotifier {
+ * framework for a set of devices on a PCI bus.
+ */
+ typedef struct PCIIOMMUOps {
++ /**
++ * @supports_address_space: Optional pre-check to determine whether a PCI
++ * device can be associated with an IOMMU. If this callback returns true,
++ * the IOMMU accepts the device association and get_address_space() can be
++ * called to obtain the address_space to be used.
++ *
++ * @bus: the #PCIBus being accessed.
++ *
++ * @opaque: the data passed to pci_setup_iommu().
++ *
++ * @devfn: device and function number.
++ *
++ * @errp: pass an Error out only when return false
++ *
++ * Returns: true if the device can be associated with an IOMMU, false
++ * otherwise with errp set.
++ */
++ bool (*supports_address_space)(PCIBus *bus, void *opaque, int devfn,
++ Error **errp);
+ /**
+ * @get_address_space: get the address space for a set of devices
+ * on a PCI bus.
+--
+2.52.0
+
diff --git a/kvm-hw-pci-pci-Enforce-pci_setup_iommu_per_bus-is-called.patch b/kvm-hw-pci-pci-Enforce-pci_setup_iommu_per_bus-is-called.patch
new file mode 100644
index 0000000..3c8aa7a
--- /dev/null
+++ b/kvm-hw-pci-pci-Enforce-pci_setup_iommu_per_bus-is-called.patch
@@ -0,0 +1,113 @@
+From ad829395fcfb2567599adb5d945698b3f91ae2ab Mon Sep 17 00:00:00 2001
+From: Eric Auger <eric.auger@redhat.com>
+Date: Wed, 3 Jun 2026 14:44:13 +0200
+Subject: [PATCH 075/111] hw/pci/pci: Enforce pci_setup_iommu_per_bus() is
+ called only once per bus
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [75/111] 4ea1111d7a8ba80c4c3f793d8ddef8f26ebd640c (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-142465
+
+Currently it is possible to attach several arm-smmuv3 devices to the
+same bus although it is a wrong setup.
+
+Change the prototype of pci_setup_iommu_per_bus to pass an error
+handle. This latter is set when iommu_per_bus is already set and
+used by the single caller (smmu_base_realize) to report a useful
+error to the end-user.
+
+While at it document pci_setup_iommu_per_bus callback in the header.
+
+Fixes: 66d2f665e163 ("hw/arm/virt: Allow user-creatable SMMUv3 dev instantiation")
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nathan Chen <nathanc@nvidia.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com>
+Message-id: 20260603124415.1120808-1-eric.auger@redhat.com
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 17b9f38982c10cb0696bce73fcedb927aee52de1)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmu-common.c | 4 +++-
+ hw/pci/pci.c | 9 +++++++--
+ include/hw/pci/pci.h | 16 +++++++++++++++-
+ 3 files changed, 25 insertions(+), 4 deletions(-)
+
+diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
+index d70ca81775..d8c16752d5 100644
+--- a/hw/arm/smmu-common.c
++++ b/hw/arm/smmu-common.c
+@@ -981,7 +981,9 @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
+ }
+
+ if (s->smmu_per_bus) {
+- pci_setup_iommu_per_bus(pci_bus, s->iommu_ops, s);
++ if (!pci_setup_iommu_per_bus(pci_bus, s->iommu_ops, s, errp)) {
++ return;
++ }
+ } else {
+ pci_setup_iommu(pci_bus, s->iommu_ops, s);
+ }
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index 344914424c..4fd8afceed 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -3255,11 +3255,16 @@ void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque)
+ * IOMMU ops are returned, avoiding the use of the parent’s IOMMU when
+ * it's not appropriate.
+ */
+-void pci_setup_iommu_per_bus(PCIBus *bus, const PCIIOMMUOps *ops,
+- void *opaque)
++bool pci_setup_iommu_per_bus(PCIBus *bus, const PCIIOMMUOps *ops,
++ void *opaque, Error **errp)
+ {
++ if (bus->iommu_per_bus) {
++ error_setg(errp, "An iommu is already attached to this bus");
++ return false;
++ }
+ pci_setup_iommu(bus, ops, opaque);
+ bus->iommu_per_bus = true;
++ return true;
+ }
+
+ static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
+diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
+index e672c92348..f1ad29f0df 100644
+--- a/include/hw/pci/pci.h
++++ b/include/hw/pci/pci.h
+@@ -864,7 +864,21 @@ int pci_iommu_unregister_iotlb_notifier(PCIDevice *dev, uint32_t pasid,
+ */
+ void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque);
+
+-void pci_setup_iommu_per_bus(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque);
++/**
++ * pci_setup_iommu_per_bus: Initialize specific IOMMU handlers for a PCIBus
++ *
++ * Similar to pci_setup_iommu but enforces that the iommu only protects
++ * @bus downstream end points and no other bus hierarchy
++ *
++ * @bus: the #PCIBus being updated.
++ * @ops: the #PCIIOMMUOps
++ * @opaque: passed to callbacks of the @ops structure.
++ * @errp: error handle
++ *
++ * Returns false on failure with @errp set, true on success
++ */
++bool pci_setup_iommu_per_bus(PCIBus *bus, const PCIIOMMUOps *ops,
++ void *opaque, Error **errp);
+
+ pcibus_t pci_bar_address(PCIDevice *d,
+ int reg, uint8_t type, pcibus_t size);
+--
+2.52.0
+
diff --git a/kvm-hw-pci-pci-Introduce-a-callback-to-retrieve-the-MSI-.patch b/kvm-hw-pci-pci-Introduce-a-callback-to-retrieve-the-MSI-.patch
new file mode 100644
index 0000000..02b21d7
--- /dev/null
+++ b/kvm-hw-pci-pci-Introduce-a-callback-to-retrieve-the-MSI-.patch
@@ -0,0 +1,182 @@
+From 4408abc5514a43de2448a7e649e283d2407a50eb Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 024/111] hw/pci/pci: Introduce a callback to retrieve the MSI
+ doorbell GPA directly
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [24/111] 48db9de84081aaab07118f3b4ba23caa735e5ebd (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+For certain vIOMMU implementations, such as SMMUv3 in accelerated mode,
+the translation tables are programmed directly into the physical SMMUv3
+in a nested configuration. While QEMU knows where the guest tables live,
+safely walking them in software would require trapping and ordering all
+guest invalidations on every command queue. Without this, QEMU could race
+with guest updates and walk stale or freed page tables.
+
+This constraint is fundamental to the design of HW-accelerated vSMMU when
+used with downstream vfio-pci endpoint devices, where QEMU must never walk
+guest translation tables and must rely on the physical SMMU for
+translation. Future accelerated vSMMU features, such as virtual CMDQ, will
+also prevent trapping invalidations, reinforcing this restriction.
+
+For vfio-pci endpoints behind such a vSMMU, the only translation QEMU
+needs is for the MSI doorbell used when setting up KVM MSI route tables.
+Instead of attempting a software walk, introduce an optional vIOMMU
+callback that returns the MSI doorbell GPA directly.
+
+kvm_arch_fixup_msi_route() uses this callback when available and ignores
+the guest provided IOVA in that case.
+
+If the vIOMMU does not implement the callback, we fall back to the
+existing IOMMU based address space translation path.
+
+This ensures correct MSI routing for accelerated SMMUv3 + VFIO passthrough
+while avoiding unsafe software walks of guest translation tables.
+
+As a related change, replace RCU_READ_LOCK_GUARD() with explicit
+rcu_read_lock()/rcu_read_unlock(). The introduction of an early goto
+(set_doorbell) path means the RCU read side critical section can no longer
+be safely scoped using RCU_READ_LOCK_GUARD().
+
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-17-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 5c921b29c9898bc44b86b88127b9e9bef76dc2ef)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/pci/pci.c | 17 +++++++++++++++++
+ include/hw/pci/pci.h | 17 +++++++++++++++++
+ target/arm/kvm.c | 18 +++++++++++++++++-
+ 3 files changed, 51 insertions(+), 1 deletion(-)
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index 1f2d4d76f9..344914424c 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -2965,6 +2965,23 @@ bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus,
+ return aliased;
+ }
+
++bool pci_device_iommu_msi_direct_gpa(PCIDevice *dev, hwaddr *out_doorbell)
++{
++ PCIBus *bus;
++ PCIBus *iommu_bus;
++ int devfn;
++
++ pci_device_get_iommu_bus_devfn(dev, &iommu_bus, &bus, &devfn);
++ if (iommu_bus) {
++ if (iommu_bus->iommu_ops->get_msi_direct_gpa) {
++ *out_doorbell = iommu_bus->iommu_ops->get_msi_direct_gpa(bus,
++ iommu_bus->iommu_opaque, devfn);
++ return true;
++ }
++ }
++ return false;
++}
++
+ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
+ {
+ PCIBus *bus;
+diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
+index 528faafad2..e672c92348 100644
+--- a/include/hw/pci/pci.h
++++ b/include/hw/pci/pci.h
+@@ -683,6 +683,22 @@ typedef struct PCIIOMMUOps {
+ uint32_t pasid, bool priv_req, bool exec_req,
+ hwaddr addr, bool lpig, uint16_t prgi, bool is_read,
+ bool is_write);
++ /**
++ * @get_msi_direct_gpa: get the guest physical address of MSI doorbell
++ * for the device on a PCI bus.
++ *
++ * Optional callback. If implemented, it must return a valid guest
++ * physical address for the MSI doorbell
++ *
++ * @bus: the #PCIBus being accessed.
++ *
++ * @opaque: the data passed to pci_setup_iommu().
++ *
++ * @devfn: device and function number
++ *
++ * Returns: the guest physical address of the MSI doorbell.
++ */
++ uint64_t (*get_msi_direct_gpa)(PCIBus *bus, void *opaque, int devfn);
+ } PCIIOMMUOps;
+
+ bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus,
+@@ -691,6 +707,7 @@ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
+ bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
+ Error **errp);
+ void pci_device_unset_iommu_device(PCIDevice *dev);
++bool pci_device_iommu_msi_direct_gpa(PCIDevice *dev, hwaddr *out_doorbell);
+
+ /**
+ * pci_device_get_viommu_flags: get vIOMMU flags.
+diff --git a/target/arm/kvm.c b/target/arm/kvm.c
+index ccf0fc501a..fe731cc49f 100644
+--- a/target/arm/kvm.c
++++ b/target/arm/kvm.c
+@@ -1614,26 +1614,42 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ return 0;
+ }
+
++ /*
++ * We do have an IOMMU address space, but for some vIOMMU implementations
++ * (e.g. accelerated SMMUv3) the translation tables are programmed into
++ * the physical SMMUv3 in the host (nested S1=guest, S2=host). QEMU cannot
++ * walk these tables in a safe way, so in that case we obtain the MSI
++ * doorbell GPA directly from the vIOMMU backend and ignore the gIOVA
++ * @address.
++ */
++ if (pci_device_iommu_msi_direct_gpa(dev, &doorbell_gpa)) {
++ goto set_doorbell;
++ }
++
+ /* MSI doorbell address is translated by an IOMMU */
+
+- RCU_READ_LOCK_GUARD();
++ rcu_read_lock();
+
+ mr = address_space_translate(as, address, &xlat, &len, true,
+ MEMTXATTRS_UNSPECIFIED);
+
+ if (!mr) {
++ rcu_read_unlock();
+ return 1;
+ }
+
+ mrs = memory_region_find(mr, xlat, 1);
+
+ if (!mrs.mr) {
++ rcu_read_unlock();
+ return 1;
+ }
+
+ doorbell_gpa = mrs.offset_within_address_space;
+ memory_region_unref(mrs.mr);
++ rcu_read_unlock();
+
++set_doorbell:
+ route->u.msi.address_lo = doorbell_gpa;
+ route->u.msi.address_hi = doorbell_gpa >> 32;
+
+--
+2.52.0
+
diff --git a/kvm-hw-pci-pci-Move-pci_init_bus_master-after-adding-dev.patch b/kvm-hw-pci-pci-Move-pci_init_bus_master-after-adding-dev.patch
new file mode 100644
index 0000000..d65dda9
--- /dev/null
+++ b/kvm-hw-pci-pci-Move-pci_init_bus_master-after-adding-dev.patch
@@ -0,0 +1,78 @@
+From 0213083c1d84149b5447d6153aa064cdda39952e Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:04 +0000
+Subject: [PATCH 009/111] hw/pci/pci: Move pci_init_bus_master() after adding
+ device to bus
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [9/111] 0b322e9469e1c9b526028631ba972cdea6c71028 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+During PCI hotplug, in do_pci_register_device(), pci_init_bus_master()
+is called before storing the pci_dev pointer in bus->devices[devfn].
+
+This causes a problem if pci_init_bus_master() (via its
+get_address_space() callback) attempts to retrieve the device using
+pci_find_device(), since the PCI device is not yet visible on the bus.
+
+Fix this by moving the pci_init_bus_master() call to after the device
+has been added to bus->devices[devfn].
+
+This prepares for a subsequent patch where the accel SMMUv3
+get_address_space() callback retrieves the pci_dev to identify the
+attached device type.
+
+No functional change intended.
+
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-8-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit e4eab7d4a1480016876e74081ffef10ab495210b)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/pci/pci.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index d1c22999b9..a8eeafd3b2 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -1369,9 +1369,6 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
+ pci_dev->bus_master_as.max_bounce_buffer_size =
+ pci_dev->max_bounce_buffer_size;
+
+- if (phase_check(PHASE_MACHINE_READY)) {
+- pci_init_bus_master(pci_dev);
+- }
+ pci_dev->irq_state = 0;
+ pci_config_alloc(pci_dev);
+
+@@ -1415,6 +1412,9 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
+ pci_dev->config_write = config_write;
+ bus->devices[devfn] = pci_dev;
+ pci_dev->version_id = 2; /* Current pci device vmstate version */
++ if (phase_check(PHASE_MACHINE_READY)) {
++ pci_init_bus_master(pci_dev);
++ }
+ return pci_dev;
+ }
+
+--
+2.52.0
+
diff --git a/kvm-hw-s390x-sclp-Use-address_space_memory_is_io-in-sclp.patch b/kvm-hw-s390x-sclp-Use-address_space_memory_is_io-in-sclp.patch
new file mode 100644
index 0000000..1a7980b
--- /dev/null
+++ b/kvm-hw-s390x-sclp-Use-address_space_memory_is_io-in-sclp.patch
@@ -0,0 +1,62 @@
+From c4f79c1b51e39dfc06c696507ec6ac8686b454b6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
+Date: Mon, 29 Sep 2025 15:28:06 +0200
+Subject: [PATCH 048/111] hw/s390x/sclp: Use address_space_memory_is_io() in
+ sclp_service_call()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [48/111] 50444ceccb7dc9e66ddd8c103be99adc6b7bb4b2 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73796
+
+When cpu_address_space_init() isn't called during vCPU creation,
+its single address space is the global &address_space_memory.
+
+As s390x boards don't call cpu_address_space_init(), cpu->as
+points to &address_space_memory.
+
+We can then replace cpu_physical_memory_is_io() by the semantically
+equivalent address_space_memory_is_io() call.
+
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Reviewed-by: Eric Farman <farman@linux.ibm.com>
+Message-Id: <20251002084203.63899-5-philmd@linaro.org>
+(cherry picked from commit 1e440937d699514207946c36c353a7a616f8b805)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/s390x/sclp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
+index 9718564fa4..16057356b1 100644
+--- a/hw/s390x/sclp.c
++++ b/hw/s390x/sclp.c
+@@ -16,6 +16,7 @@
+ #include "qemu/units.h"
+ #include "qapi/error.h"
+ #include "hw/boards.h"
++#include "system/memory.h"
+ #include "hw/s390x/sclp.h"
+ #include "hw/s390x/event-facility.h"
+ #include "hw/s390x/s390-pci-bus.h"
+@@ -308,7 +309,7 @@ int sclp_service_call(S390CPU *cpu, uint64_t sccb, uint32_t code)
+ if (env->psw.mask & PSW_MASK_PSTATE) {
+ return -PGM_PRIVILEGED;
+ }
+- if (cpu_physical_memory_is_io(sccb)) {
++ if (address_space_is_io(CPU(cpu)->as, sccb)) {
+ return -PGM_ADDRESSING;
+ }
+ if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
+--
+2.52.0
+
diff --git a/kvm-hw-vfio-iommufd-Control-dirty-tracking-for-nesting-p.patch b/kvm-hw-vfio-iommufd-Control-dirty-tracking-for-nesting-p.patch
new file mode 100644
index 0000000..a269407
--- /dev/null
+++ b/kvm-hw-vfio-iommufd-Control-dirty-tracking-for-nesting-p.patch
@@ -0,0 +1,143 @@
+From 8b71f97dfda4e0df08b3a8b83657b7c6ccfea6e1 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Wed, 1 Apr 2026 09:41:33 +0100
+Subject: [PATCH 077/111] hw/vfio/iommufd: Control dirty tracking for nesting
+ parent HWPT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [77/111] 74b083b2e35b690c32dc01ec37abe76f2f7a63cb (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Conflicts: contextual in all changed files. In hw/i386/intel_iommu.c
+we do not have nested intel iommu downstream, so impacted code does not
+exist. In hw/vfio/device.c and include/hw/vfio/vfio-device.h this is
+due to out of order de36da106dcf hw/vfio: Add helper to retrieve device feature
+backport
+
+QEMU smmuv3 accel does not support live migration yet, so dirty
+tracking for the nesting parent HWPT is not useful.
+
+Also, nested vIOMMU use cases can break on some platforms. For
+example, SMMUv3 with HTTU may advertise dirty tracking capability,
+but the kernel supports it only for stage-1. Requesting dirty
+tracking for a nesting parent HWPT (stage-2) can fail.
+
+Add a vIOMMU flag to explicitly request dirty tracking for the
+nesting parent HWPT. For nested cases, dirty tracking is enabled
+only when requested by the vIOMMU.
+
+Non-nested cases and Intel vIOMMU keep the existing behavior.
+
+Fixes: fc6dafb98cec ("hw/arm/smmuv3: Implement get_viommu_cap() callback")
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Link: https://lore.kernel.org/qemu-devel/20260401084133.56266-1-skolothumtho@nvidia.com
+Signed-off-by: Cédric Le Goater <clg@redhat.com>
+(cherry picked from commit 659275f84694e7b06d67d877137905d371a3fde4)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/vfio/device.c | 11 +++++++++++
+ hw/vfio/iommufd.c | 11 +++++++++--
+ include/hw/core/iommu.h | 2 ++
+ include/hw/vfio/vfio-device.h | 3 ++-
+ 4 files changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/hw/vfio/device.c b/hw/vfio/device.c
+index c01eb72ee7..4bd2476464 100644
+--- a/hw/vfio/device.c
++++ b/hw/vfio/device.c
+@@ -526,6 +526,17 @@ int vfio_device_get_feature(VFIODevice *vbasedev,
+ return vbasedev->io_ops->device_feature(vbasedev, feature);
+ }
+
++bool vfio_device_get_viommu_flags_want_nesting_dirty(VFIODevice *vbasedev)
++{
++ VFIOPCIDevice *vdev = vfio_pci_from_vfio_device(vbasedev);
++
++ if (vdev) {
++ return !!(pci_device_get_viommu_flags(PCI_DEVICE(vdev)) &
++ VIOMMU_FLAG_WANT_NESTING_DIRTY_TRACKING);
++ }
++ return false;
++}
++
+ bool vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev)
+ {
+ VFIOPCIDevice *vdev = vfio_pci_from_vfio_device(vbasedev);
+diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
+index 59dc17b166..7e0287f814 100644
+--- a/hw/vfio/iommufd.c
++++ b/hw/vfio/iommufd.c
+@@ -306,6 +306,7 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
+ ERRP_GUARD();
+ IOMMUFDBackend *iommufd = vbasedev->iommufd;
+ VFIOContainer *bcontainer = VFIO_IOMMU(container);
++ bool viommu_nesting, viommu_nesting_dirty;
+ uint32_t type, flags = 0;
+ uint64_t hw_caps;
+ VendorCaps caps;
+@@ -359,8 +360,14 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
+ return false;
+ }
+
++ viommu_nesting = vfio_device_get_viommu_flags_want_nesting(vbasedev);
++ viommu_nesting_dirty =
++ vfio_device_get_viommu_flags_want_nesting_dirty(vbasedev);
++
+ if (hw_caps & IOMMU_HW_CAP_DIRTY_TRACKING) {
+- flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
++ if (!viommu_nesting || viommu_nesting_dirty) {
++ flags |= IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
++ }
+ }
+
+ /*
+@@ -368,7 +375,7 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
+ * force to create it so that it could be reused by vIOMMU to create
+ * nested HWPT.
+ */
+- if (vfio_device_get_viommu_flags_want_nesting(vbasedev)) {
++ if (viommu_nesting) {
+ flags |= IOMMU_HWPT_ALLOC_NEST_PARENT;
+ }
+
+diff --git a/include/hw/core/iommu.h b/include/hw/core/iommu.h
+index 86af315c15..cd59a367ce 100644
+--- a/include/hw/core/iommu.h
++++ b/include/hw/core/iommu.h
+@@ -21,6 +21,8 @@ enum viommu_flags {
+ /* vIOMMU needs nesting parent HWPT to create nested HWPT */
+ VIOMMU_FLAG_WANT_NESTING_PARENT = BIT_ULL(0),
+ VIOMMU_FLAG_PASID_SUPPORTED = BIT_ULL(1),
++ /* vIOMMU needs dirty tracking on the nesting parent HWPT for nested use */
++ VIOMMU_FLAG_WANT_NESTING_DIRTY_TRACKING = BIT_ULL(2),
+ };
+
+ /* Host IOMMU quirks. Extracted from host IOMMU capabilities */
+diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
+index 27e2976593..82c8fce0ef 100644
+--- a/include/hw/vfio/vfio-device.h
++++ b/include/hw/vfio/vfio-device.h
+@@ -258,9 +258,10 @@ void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainer *bcontainer,
+
+ void vfio_device_unprepare(VFIODevice *vbasedev);
+
++bool vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev);
++bool vfio_device_get_viommu_flags_want_nesting_dirty(VFIODevice *vbasedev);
+ int vfio_device_get_feature(VFIODevice *vbasedev,
+ struct vfio_device_feature *feature);
+-bool vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev);
+
+ int vfio_device_get_region_info(VFIODevice *vbasedev, int index,
+ struct vfio_region_info **info);
+--
+2.52.0
+
diff --git a/kvm-hw-vfio-pci-Synthesize-PASID-capability-for-vfio-pci.patch b/kvm-hw-vfio-pci-Synthesize-PASID-capability-for-vfio-pci.patch
new file mode 100644
index 0000000..0d696d5
--- /dev/null
+++ b/kvm-hw-vfio-pci-Synthesize-PASID-capability-for-vfio-pci.patch
@@ -0,0 +1,214 @@
+From b3bb7119db21bdc9cd2018b9f9518497a8e90715 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 044/111] hw/vfio/pci: Synthesize PASID capability for vfio-pci
+ devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [44/111] ce06dcd543f388a70071785ce3cadd620c900e5b (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Conflicts: hw/vfio/pci.c keep using hw/hw.h instead of hw/core/hw-error.h
+because we don't have 048a23851cd4 ("include: move hw/hw.h to hw/core/,
+rename")
+
+Add support for synthesizing a PCIe PASID extended capability for
+vfio-pci devices when PASID is enabled via a vIOMMU and supported by
+the host IOMMU backend.
+
+PASID capability parameters are retrieved via IOMMUFD APIs and the
+capability is inserted into the PCIe extended capability list using
+the insertion helper. A new x-vpasid-cap-offset property allows
+explicit control over the placement; by default the capability is
+placed at the end of the PCIe extended configuration space.
+
+If the kernel does not expose PASID information or insertion fails,
+the device continues without PASID support.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Reviewed-by: Cédric Le Goater <clg@redhat.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Message-id: 20260126104342.253965-37-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 06b38473cda8cbeb5f4aa0c2480c3b8c06a8d500)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/vfio/pci.c | 75 +++++++++++++++++++++++++++++++++++++++++
+ hw/vfio/pci.h | 1 +
+ hw/vfio/trace-events | 1 +
+ include/hw/core/iommu.h | 1 +
+ 4 files changed, 78 insertions(+)
+
+diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
+index 1ba66699dc..6e0714a630 100644
+--- a/hw/vfio/pci.c
++++ b/hw/vfio/pci.c
+@@ -24,6 +24,7 @@
+ #include <sys/ioctl.h>
+
+ #include "hw/hw.h"
++#include "hw/core/iommu.h"
+ #include "hw/pci/msi.h"
+ #include "hw/pci/msix.h"
+ #include "hw/pci/pci_bridge.h"
+@@ -2501,9 +2502,62 @@ static int vfio_setup_rebar_ecap(VFIOPCIDevice *vdev, uint16_t pos)
+ return 0;
+ }
+
++/*
++ * Try to retrieve PASID capability information via IOMMUFD APIs and,
++ * if supported, synthesize a PASID PCIe extended capability for the
++ * VFIO device.
++ *
++ * Use user-specified PASID capability offset if provided, otherwise
++ * place it at the end of the PCIe extended configuration space.
++ */
++static bool vfio_pci_synthesize_pasid_cap(VFIOPCIDevice *vdev, Error **errp)
++{
++ HostIOMMUDevice *hiod = vdev->vbasedev.hiod;
++ HostIOMMUDeviceClass *hiodc;
++ PasidInfo pasid_info;
++ PCIDevice *pdev = PCI_DEVICE(vdev);
++ uint16_t pasid_offset;
++
++ if (!hiod) {
++ return true;
++ }
++
++ hiodc = HOST_IOMMU_DEVICE_GET_CLASS(hiod);
++ if (!hiodc || !hiodc->get_pasid_info ||
++ !hiodc->get_pasid_info(hiod, &pasid_info) ||
++ !(pci_device_get_viommu_flags(pdev) & VIOMMU_FLAG_PASID_SUPPORTED)) {
++ return true;
++ }
++
++ /* Use user-specified offset if set, otherwise place PASID at the end. */
++ if (vdev->vpasid_cap_offset) {
++ pasid_offset = vdev->vpasid_cap_offset;
++ } else {
++ pasid_offset = PCIE_CONFIG_SPACE_SIZE - PCI_EXT_CAP_PASID_SIZEOF;
++ }
++
++ if (!pcie_insert_capability(pdev, PCI_EXT_CAP_ID_PASID, PCI_PASID_VER,
++ pasid_offset, PCI_EXT_CAP_PASID_SIZEOF)) {
++ error_setg(errp, "vfio: Placing PASID capability at offset 0x%x failed",
++ pasid_offset);
++ return false;
++ }
++ trace_vfio_pci_synthesize_pasid_cap(vdev->vbasedev.name, pasid_offset);
++
++ pcie_pasid_common_init(pdev, pasid_offset, pasid_info.max_pasid_log2,
++ pasid_info.exec_perm, pasid_info.priv_mod);
++
++ /* PASID capability is fully emulated by QEMU */
++ memset(vdev->emulated_config_bits + pdev->exp.pasid_cap, 0xff,
++ PCI_EXT_CAP_PASID_SIZEOF);
++ return true;
++}
++
+ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
+ {
+ PCIDevice *pdev = PCI_DEVICE(vdev);
++ bool pasid_cap_added = false;
++ Error *err = NULL;
+ uint32_t header;
+ uint16_t cap_id, next, size;
+ uint8_t cap_ver;
+@@ -2581,12 +2635,24 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
+ pcie_add_capability(pdev, cap_id, cap_ver, next, size);
+ }
+ break;
++ /*
++ * VFIO kernel does not expose the PASID CAP today. We may synthesize
++ * one later through IOMMUFD APIs. If VFIO ever starts exposing it,
++ * record its presence here so we do not create a duplicate CAP.
++ */
++ case PCI_EXT_CAP_ID_PASID:
++ pasid_cap_added = true;
++ /* fallthrough */
+ default:
+ pcie_add_capability(pdev, cap_id, cap_ver, next, size);
+ }
+
+ }
+
++ if (!pasid_cap_added && !vfio_pci_synthesize_pasid_cap(vdev, &err)) {
++ error_report_err(err);
++ }
++
+ /* Cleanup chain head ID if necessary */
+ if (pci_get_word(pdev->config + PCI_CONFIG_SPACE_SIZE) == 0xFFFF) {
+ pci_set_word(pdev->config + PCI_CONFIG_SPACE_SIZE, 0);
+@@ -3777,6 +3843,8 @@ static const Property vfio_pci_properties[] = {
+ TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
+ #endif
+ DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
++ DEFINE_PROP_UINT16("x-vpasid-cap-offset", VFIOPCIDevice,
++ vpasid_cap_offset, 0),
+ };
+
+ #ifdef CONFIG_IOMMUFD
+@@ -3934,6 +4002,13 @@ static void vfio_pci_class_init(ObjectClass *klass, const void *data)
+ "destination when doing live "
+ "migration of device state via "
+ "multifd channels");
++ object_class_property_set_description(klass, /* 11.0 */
++ "x-vpasid-cap-offset",
++ "PCIe extended configuration space offset at which to place a "
++ "synthetic PASID extended capability when PASID is enabled via "
++ "a vIOMMU. A value of 0 (default) places the capability at the "
++ "end of the extended configuration space. The offset must be "
++ "4-byte aligned and within the PCIe extended configuration space");
+ }
+
+ static const TypeInfo vfio_pci_info = {
+diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
+index 975836945a..c1c59e4092 100644
+--- a/hw/vfio/pci.h
++++ b/hw/vfio/pci.h
+@@ -188,6 +188,7 @@ struct VFIOPCIDevice {
+ bool defer_kvm_irq_routing;
+ bool clear_parent_atomics_on_exit;
+ bool skip_vsc_check;
++ uint16_t vpasid_cap_offset;
+ VFIODisplay *dpy;
+ Notifier irqchip_change_notifier;
+ VFIOPCICPR cpr;
+diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
+index 592a0349d4..82abfc99ae 100644
+--- a/hw/vfio/trace-events
++++ b/hw/vfio/trace-events
+@@ -40,6 +40,7 @@ vfio_pci_hot_reset_result(const char *name, const char *result) "%s hot reset: %
+ vfio_pci_populate_device_config(const char *name, unsigned long size, unsigned long offset, unsigned long flags) "Device '%s' config: size: 0x%lx, offset: 0x%lx, flags: 0x%lx"
+ vfio_pci_populate_device_get_irq_info_failure(const char *errstr) "VFIO_DEVICE_GET_IRQ_INFO failure: %s"
+ vfio_mdev(const char *name, bool is_mdev) " (%s) is_mdev %d"
++vfio_pci_synthesize_pasid_cap(const char *name, uint16_t offset) "%s offset: 0x%x"
+ vfio_add_ext_cap_dropped(const char *name, uint16_t cap, uint16_t offset) "%s 0x%x@0x%x"
+ vfio_pci_reset(const char *name) " (%s)"
+ vfio_pci_reset_flr(const char *name) "%s FLR/VFIO_DEVICE_RESET"
+diff --git a/include/hw/core/iommu.h b/include/hw/core/iommu.h
+index d5401a397b..86af315c15 100644
+--- a/include/hw/core/iommu.h
++++ b/include/hw/core/iommu.h
+@@ -20,6 +20,7 @@
+ enum viommu_flags {
+ /* vIOMMU needs nesting parent HWPT to create nested HWPT */
+ VIOMMU_FLAG_WANT_NESTING_PARENT = BIT_ULL(0),
++ VIOMMU_FLAG_PASID_SUPPORTED = BIT_ULL(1),
+ };
+
+ /* Host IOMMU quirks. Extracted from host IOMMU capabilities */
+--
+2.52.0
+
diff --git a/kvm-iommufd-Rename-all-the-idev-and-idevc-variables-to-h.patch b/kvm-iommufd-Rename-all-the-idev-and-idevc-variables-to-h.patch
new file mode 100644
index 0000000..e59912d
--- /dev/null
+++ b/kvm-iommufd-Rename-all-the-idev-and-idevc-variables-to-h.patch
@@ -0,0 +1,541 @@
+From dfeee0ad5c9325945c72b82155e0cc883c102807 Mon Sep 17 00:00:00 2001
+From: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Date: Wed, 1 Apr 2026 04:03:53 -0400
+Subject: [PATCH 079/111] iommufd: Rename all the idev and idevc variables to
+ hiod and hiodc
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [79/111] 70fe97a5913b2acb2888d3e45ef07226716f37a3 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Conflicts: contextual conflict in hw/i386/intel_iommu_accel.c since
+we do not have accel intel iommu. Ignore changes in this file.
+
+We used idev and idevc naming for HostIOMMUDeviceIOMMUFD and corresponding
+class variables which followed the iommufd_device naming in linux kernel.
+
+This is mixed with the hiod naming for base type HostIOMMUDevice. Rename
+HostIOMMUDeviceIOMMUFD* to hiodi* for consistency in QEMU.
+
+No functional change intended.
+
+Suggested-by: Cédric Le Goater <clg@redhat.com>
+Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Cédric Le Goater <clg@redhat.com>
+Link: https://lore.kernel.org/qemu-devel/20260401080354.1347212-1-zhenzhong.duan@intel.com
+Signed-off-by: Cédric Le Goater <clg@redhat.com>
+(cherry picked from commit e2b7310276087351fadd6afbe9e5a3fff9c25f8d)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ backends/iommufd.c | 26 +++++------
+ hw/arm/smmuv3-accel.c | 93 +++++++++++++++++++-------------------
+ hw/arm/smmuv3-accel.h | 2 +-
+ hw/vfio/container-legacy.c | 10 ++--
+ hw/vfio/iommufd.c | 24 +++++-----
+ include/system/iommufd.h | 12 ++---
+ 6 files changed, 84 insertions(+), 83 deletions(-)
+
+diff --git a/backends/iommufd.c b/backends/iommufd.c
+index 416e193751..b328f89699 100644
+--- a/backends/iommufd.c
++++ b/backends/iommufd.c
+@@ -541,24 +541,24 @@ bool iommufd_backend_alloc_veventq(IOMMUFDBackend *be, uint32_t viommu_id,
+ return true;
+ }
+
+-bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
++bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
+ uint32_t hwpt_id, Error **errp)
+ {
+- HostIOMMUDeviceIOMMUFDClass *idevc =
+- HOST_IOMMU_DEVICE_IOMMUFD_GET_CLASS(idev);
++ HostIOMMUDeviceIOMMUFDClass *hiodic =
++ HOST_IOMMU_DEVICE_IOMMUFD_GET_CLASS(hiodi);
+
+- g_assert(idevc->attach_hwpt);
+- return idevc->attach_hwpt(idev, hwpt_id, errp);
++ g_assert(hiodic->attach_hwpt);
++ return hiodic->attach_hwpt(hiodi, hwpt_id, errp);
+ }
+
+-bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
++bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
+ Error **errp)
+ {
+- HostIOMMUDeviceIOMMUFDClass *idevc =
+- HOST_IOMMU_DEVICE_IOMMUFD_GET_CLASS(idev);
++ HostIOMMUDeviceIOMMUFDClass *hiodic =
++ HOST_IOMMU_DEVICE_IOMMUFD_GET_CLASS(hiodi);
+
+- g_assert(idevc->detach_hwpt);
+- return idevc->detach_hwpt(idev, errp);
++ g_assert(hiodic->detach_hwpt);
++ return hiodic->detach_hwpt(hiodi, errp);
+ }
+
+ static int hiod_iommufd_get_cap(HostIOMMUDevice *hiod, int cap, Error **errp)
+@@ -594,10 +594,10 @@ static bool hiod_iommufd_get_pasid_info(HostIOMMUDevice *hiod,
+
+ static void hiod_iommufd_class_init(ObjectClass *oc, const void *data)
+ {
+- HostIOMMUDeviceClass *hioc = HOST_IOMMU_DEVICE_CLASS(oc);
++ HostIOMMUDeviceClass *hiodc = HOST_IOMMU_DEVICE_CLASS(oc);
+
+- hioc->get_cap = hiod_iommufd_get_cap;
+- hioc->get_pasid_info = hiod_iommufd_get_pasid_info;
++ hiodc->get_cap = hiod_iommufd_get_cap;
++ hiodc->get_pasid_info = hiod_iommufd_get_pasid_info;
+ };
+
+ static const TypeInfo types[] = {
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index f97129388f..163d3e7279 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -172,16 +172,16 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
+ }
+
+ static bool
+-smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
++smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *hiodi,
+ Error **errp)
+ {
+ struct iommu_hw_info_arm_smmuv3 info;
+ uint32_t data_type = IOMMU_HW_INFO_TYPE_DEFAULT;
+ uint64_t caps;
+
+- if (!iommufd_backend_get_device_info(idev->iommufd, idev->devid, &data_type,
+- &info, sizeof(info), &caps, NULL,
+- errp)) {
++ if (!iommufd_backend_get_device_info(hiodi->iommufd, hiodi->devid,
++ &data_type, &info, sizeof(info), &caps,
++ NULL, errp)) {
+ return false;
+ }
+
+@@ -225,15 +225,15 @@ static bool
+ smmuv3_accel_alloc_vdev(SMMUv3AccelDevice *accel_dev, int sid, Error **errp)
+ {
+ SMMUv3AccelState *accel = accel_dev->s_accel;
+- HostIOMMUDeviceIOMMUFD *idev = accel_dev->idev;
++ HostIOMMUDeviceIOMMUFD *hiodi = accel_dev->hiodi;
+ IOMMUFDVdev *vdev = accel_dev->vdev;
+ uint32_t vdevice_id;
+
+- if (!idev || vdev) {
++ if (!hiodi || vdev) {
+ return true;
+ }
+
+- if (!iommufd_backend_alloc_vdev(idev->iommufd, idev->devid,
++ if (!iommufd_backend_alloc_vdev(hiodi->iommufd, hiodi->devid,
+ accel->viommu->viommu_id, sid,
+ &vdevice_id, errp)) {
+ return false;
+@@ -252,7 +252,7 @@ smmuv3_accel_dev_alloc_translate(SMMUv3AccelDevice *accel_dev, STE *ste,
+ {
+ uint64_t ste_0 = (uint64_t)ste->word[0] | (uint64_t)ste->word[1] << 32;
+ uint64_t ste_1 = (uint64_t)ste->word[2] | (uint64_t)ste->word[3] << 32;
+- HostIOMMUDeviceIOMMUFD *idev = accel_dev->idev;
++ HostIOMMUDeviceIOMMUFD *hiodi = accel_dev->hiodi;
+ SMMUv3AccelState *accel = accel_dev->s_accel;
+ struct iommu_hwpt_arm_smmuv3 nested_data = {
+ .ste = {
+@@ -263,7 +263,7 @@ smmuv3_accel_dev_alloc_translate(SMMUv3AccelDevice *accel_dev, STE *ste,
+ uint32_t hwpt_id = 0, flags = 0;
+ SMMUS1Hwpt *s1_hwpt;
+
+- if (!iommufd_backend_alloc_hwpt(idev->iommufd, idev->devid,
++ if (!iommufd_backend_alloc_hwpt(hiodi->iommufd, hiodi->devid,
+ accel->viommu->viommu_id, flags,
+ IOMMU_HWPT_DATA_ARM_SMMUV3,
+ sizeof(nested_data), &nested_data,
+@@ -285,7 +285,7 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+ .inval_ste_allowed = true};
+ SMMUv3AccelState *accel = s->s_accel;
+ SMMUv3AccelDevice *accel_dev;
+- HostIOMMUDeviceIOMMUFD *idev;
++ HostIOMMUDeviceIOMMUFD *hiodi;
+ uint32_t config, hwpt_id = 0;
+ SMMUS1Hwpt *s1_hwpt = NULL;
+ const char *type;
+@@ -300,7 +300,7 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+ return true;
+ }
+
+- idev = accel_dev->idev;
++ hiodi = accel_dev->hiodi;
+ if (!smmuv3_accel_alloc_vdev(accel_dev, sid, errp)) {
+ return false;
+ }
+@@ -343,9 +343,9 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+ return false;
+ }
+
+- if (!host_iommu_device_iommufd_attach_hwpt(idev, hwpt_id, errp)) {
++ if (!host_iommu_device_iommufd_attach_hwpt(hiodi, hwpt_id, errp)) {
+ if (s1_hwpt) {
+- iommufd_backend_free_id(idev->iommufd, s1_hwpt->hwpt_id);
++ iommufd_backend_free_id(hiodi->iommufd, s1_hwpt->hwpt_id);
+ g_free(s1_hwpt);
+ }
+ return false;
+@@ -353,7 +353,7 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
+
+ /* Free the previous s1_hwpt */
+ if (accel_dev->s1_hwpt) {
+- iommufd_backend_free_id(idev->iommufd, accel_dev->s1_hwpt->hwpt_id);
++ iommufd_backend_free_id(hiodi->iommufd, accel_dev->s1_hwpt->hwpt_id);
+ g_free(accel_dev->s1_hwpt);
+ }
+
+@@ -567,7 +567,7 @@ free_veventq:
+ }
+
+ static bool
+-smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
++smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *hiodi,
+ Error **errp)
+ {
+ SMMUv3AccelState *accel = s->s_accel;
+@@ -577,11 +577,11 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ struct iommu_hwpt_arm_smmuv3 abort_data = {
+ .ste = { SMMU_STE_VALID, 0x0ULL },
+ };
+- uint32_t s2_hwpt_id = idev->hwpt_id;
++ uint32_t s2_hwpt_id = hiodi->hwpt_id;
+ uint32_t viommu_id, hwpt_id;
+ IOMMUFDViommu *viommu;
+
+- if (!iommufd_backend_alloc_viommu(idev->iommufd, idev->devid,
++ if (!iommufd_backend_alloc_viommu(hiodi->iommufd, hiodi->devid,
+ IOMMU_VIOMMU_TYPE_ARM_SMMUV3,
+ s2_hwpt_id, &viommu_id, errp)) {
+ return false;
+@@ -590,21 +590,21 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ viommu = g_new0(IOMMUFDViommu, 1);
+ viommu->viommu_id = viommu_id;
+ viommu->s2_hwpt_id = s2_hwpt_id;
+- viommu->iommufd = idev->iommufd;
++ viommu->iommufd = hiodi->iommufd;
+ accel->viommu = viommu;
+
+ /*
+ * Pre-allocate HWPTs for S1 bypass and abort cases. These will be attached
+ * later for guest STEs or GBPAs that require bypass or abort configuration.
+ */
+- if (!iommufd_backend_alloc_hwpt(idev->iommufd, idev->devid, viommu_id,
++ if (!iommufd_backend_alloc_hwpt(hiodi->iommufd, hiodi->devid, viommu_id,
+ 0, IOMMU_HWPT_DATA_ARM_SMMUV3,
+ sizeof(abort_data), &abort_data,
+ &accel->abort_hwpt_id, errp)) {
+ goto free_viommu;
+ }
+
+- if (!iommufd_backend_alloc_hwpt(idev->iommufd, idev->devid, viommu_id,
++ if (!iommufd_backend_alloc_hwpt(hiodi->iommufd, hiodi->devid, viommu_id,
+ 0, IOMMU_HWPT_DATA_ARM_SMMUV3,
+ sizeof(bypass_data), &bypass_data,
+ &accel->bypass_hwpt_id, errp)) {
+@@ -618,7 +618,7 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+
+ /* Attach a HWPT based on SMMUv3 GBPA.ABORT value */
+ hwpt_id = smmuv3_accel_gbpa_hwpt(s, accel);
+- if (!host_iommu_device_iommufd_attach_hwpt(idev, hwpt_id, errp)) {
++ if (!host_iommu_device_iommufd_attach_hwpt(hiodi, hwpt_id, errp)) {
+ goto free_veventq;
+ }
+ return true;
+@@ -626,11 +626,11 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
+ free_veventq:
+ smmuv3_accel_free_veventq(accel);
+ free_bypass_hwpt:
+- iommufd_backend_free_id(idev->iommufd, accel->bypass_hwpt_id);
++ iommufd_backend_free_id(hiodi->iommufd, accel->bypass_hwpt_id);
+ free_abort_hwpt:
+- iommufd_backend_free_id(idev->iommufd, accel->abort_hwpt_id);
++ iommufd_backend_free_id(hiodi->iommufd, accel->abort_hwpt_id);
+ free_viommu:
+- iommufd_backend_free_id(idev->iommufd, viommu->viommu_id);
++ iommufd_backend_free_id(hiodi->iommufd, viommu->viommu_id);
+ g_free(viommu);
+ accel->viommu = NULL;
+ return false;
+@@ -639,20 +639,20 @@ free_viommu:
+ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
+ HostIOMMUDevice *hiod, Error **errp)
+ {
+- HostIOMMUDeviceIOMMUFD *idev = HOST_IOMMU_DEVICE_IOMMUFD(hiod);
++ HostIOMMUDeviceIOMMUFD *hiodi = HOST_IOMMU_DEVICE_IOMMUFD(hiod);
+ SMMUState *bs = opaque;
+ SMMUv3State *s = ARM_SMMUV3(bs);
+ SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
+ SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus, bus, devfn);
+
+- if (!idev) {
++ if (!hiodi) {
+ return true;
+ }
+
+- if (accel_dev->idev) {
+- if (accel_dev->idev != idev) {
+- error_setg(errp, "Device already has an associated idev 0x%x",
+- idev->devid);
++ if (accel_dev->hiodi) {
++ if (accel_dev->hiodi != hiodi) {
++ error_setg(errp, "Device already has an associated hiodi 0x%x",
++ hiodi->devid);
+ return false;
+ }
+ return true;
+@@ -662,7 +662,7 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
+ * Check the host SMMUv3 associated with the dev is compatible with the
+ * QEMU SMMUv3 accel.
+ */
+- if (!smmuv3_accel_hw_compatible(s, idev, errp)) {
++ if (!smmuv3_accel_hw_compatible(s, hiodi, errp)) {
+ return false;
+ }
+
+@@ -670,17 +670,17 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
+ goto done;
+ }
+
+- if (!smmuv3_accel_alloc_viommu(s, idev, errp)) {
+- error_append_hint(errp, "Unable to alloc vIOMMU: idev devid 0x%x: ",
+- idev->devid);
++ if (!smmuv3_accel_alloc_viommu(s, hiodi, errp)) {
++ error_append_hint(errp, "Unable to alloc vIOMMU: hiodi devid 0x%x: ",
++ hiodi->devid);
+ return false;
+ }
+
+ done:
+- accel_dev->idev = idev;
++ accel_dev->hiodi = hiodi;
+ accel_dev->s_accel = s->s_accel;
+ QLIST_INSERT_HEAD(&s->s_accel->device_list, accel_dev, next);
+- trace_smmuv3_accel_set_iommu_device(devfn, idev->devid);
++ trace_smmuv3_accel_set_iommu_device(devfn, hiodi->devid);
+ return true;
+ }
+
+@@ -689,7 +689,7 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
+ {
+ SMMUState *bs = opaque;
+ SMMUPciBus *sbus = g_hash_table_lookup(bs->smmu_pcibus_by_busptr, bus);
+- HostIOMMUDeviceIOMMUFD *idev;
++ HostIOMMUDeviceIOMMUFD *hiodi;
+ SMMUv3AccelDevice *accel_dev;
+ SMMUv3AccelState *accel;
+ IOMMUFDVdev *vdev;
+@@ -705,16 +705,16 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
+ }
+
+ accel_dev = container_of(sdev, SMMUv3AccelDevice, sdev);
+- idev = accel_dev->idev;
++ hiodi = accel_dev->hiodi;
+ accel = accel_dev->s_accel;
+ /* Re-attach the default s2 hwpt id */
+- if (!host_iommu_device_iommufd_attach_hwpt(idev, idev->hwpt_id, NULL)) {
+- error_report("Unable to attach the default HW pagetable: idev devid "
+- "0x%x", idev->devid);
++ if (!host_iommu_device_iommufd_attach_hwpt(hiodi, hiodi->hwpt_id, NULL)) {
++ error_report("Unable to attach the default HW pagetable: hiodi devid "
++ "0x%x", hiodi->devid);
+ }
+
+ if (accel_dev->s1_hwpt) {
+- iommufd_backend_free_id(accel_dev->idev->iommufd,
++ iommufd_backend_free_id(accel_dev->hiodi->iommufd,
+ accel_dev->s1_hwpt->hwpt_id);
+ g_free(accel_dev->s1_hwpt);
+ accel_dev->s1_hwpt = NULL;
+@@ -727,10 +727,10 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
+ accel_dev->vdev = NULL;
+ }
+
+- accel_dev->idev = NULL;
++ accel_dev->hiodi = NULL;
+ accel_dev->s_accel = NULL;
+ QLIST_REMOVE(accel_dev, next);
+- trace_smmuv3_accel_unset_iommu_device(devfn, idev->devid);
++ trace_smmuv3_accel_unset_iommu_device(devfn, hiodi->devid);
+
+ if (QLIST_EMPTY(&accel->device_list)) {
+ smmuv3_accel_free_viommu(accel);
+@@ -929,10 +929,11 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
+
+ hwpt_id = smmuv3_accel_gbpa_hwpt(s, accel);
+ QLIST_FOREACH(accel_dev, &accel->device_list, next) {
+- if (!host_iommu_device_iommufd_attach_hwpt(accel_dev->idev, hwpt_id,
++ if (!host_iommu_device_iommufd_attach_hwpt(accel_dev->hiodi, hwpt_id,
+ &local_err)) {
+ error_append_hint(&local_err, "Failed to attach GBPA hwpt %u for "
+- "idev devid %u", hwpt_id, accel_dev->idev->devid);
++ "hiodi devid %u", hwpt_id,
++ accel_dev->hiodi->devid);
+ error_report_err(local_err);
+ local_err = NULL;
+ all_ok = false;
+diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
+index d7b9f8a8e6..d89c117fd1 100644
+--- a/hw/arm/smmuv3-accel.h
++++ b/hw/arm/smmuv3-accel.h
+@@ -36,7 +36,7 @@ typedef struct SMMUS1Hwpt {
+
+ typedef struct SMMUv3AccelDevice {
+ SMMUDevice sdev;
+- HostIOMMUDeviceIOMMUFD *idev;
++ HostIOMMUDeviceIOMMUFD *hiodi;
+ SMMUS1Hwpt *s1_hwpt;
+ IOMMUFDVdev *vdev;
+ QLIST_ENTRY(SMMUv3AccelDevice) next;
+diff --git a/hw/vfio/container-legacy.c b/hw/vfio/container-legacy.c
+index e639760381..05b8ebef4b 100644
+--- a/hw/vfio/container-legacy.c
++++ b/hw/vfio/container-legacy.c
+@@ -1255,12 +1255,12 @@ static void vfio_iommu_legacy_instance_init(Object *obj)
+
+ static void hiod_legacy_vfio_class_init(ObjectClass *oc, const void *data)
+ {
+- HostIOMMUDeviceClass *hioc = HOST_IOMMU_DEVICE_CLASS(oc);
++ HostIOMMUDeviceClass *hiodc = HOST_IOMMU_DEVICE_CLASS(oc);
+
+- hioc->realize = hiod_legacy_vfio_realize;
+- hioc->get_cap = hiod_legacy_vfio_get_cap;
+- hioc->get_iova_ranges = hiod_legacy_vfio_get_iova_ranges;
+- hioc->get_page_size_mask = hiod_legacy_vfio_get_page_size_mask;
++ hiodc->realize = hiod_legacy_vfio_realize;
++ hiodc->get_cap = hiod_legacy_vfio_get_cap;
++ hiodc->get_iova_ranges = hiod_legacy_vfio_get_iova_ranges;
++ hiodc->get_page_size_mask = hiod_legacy_vfio_get_page_size_mask;
+ };
+
+ static const TypeInfo types[] = {
+diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
+index 93703a0036..191cf80068 100644
+--- a/hw/vfio/iommufd.c
++++ b/hw/vfio/iommufd.c
+@@ -873,19 +873,19 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, const void *data)
+ };
+
+ static bool
+-host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
++host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
+ uint32_t hwpt_id, Error **errp)
+ {
+- VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent;
++ VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->agent;
+
+ return !iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
+ }
+
+ static bool
+-host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
++host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
+ Error **errp)
+ {
+- VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent;
++ VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->agent;
+
+ return iommufd_cdev_detach_ioas_hwpt(vbasedev, errp);
+ }
+@@ -894,7 +894,7 @@ static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
+ Error **errp)
+ {
+ VFIODevice *vdev = opaque;
+- HostIOMMUDeviceIOMMUFD *idev;
++ HostIOMMUDeviceIOMMUFD *hiodi;
+ HostIOMMUDeviceCaps *caps = &hiod->caps;
+ VendorCaps *vendor_caps = &caps->vendor_caps;
+ uint32_t type = IOMMU_HW_INFO_TYPE_DEFAULT;
+@@ -914,10 +914,10 @@ static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
+ caps->hw_caps = hw_caps;
+ caps->max_pasid_log2 = max_pasid_log2;
+
+- idev = HOST_IOMMU_DEVICE_IOMMUFD(hiod);
+- idev->iommufd = vdev->iommufd;
+- idev->devid = vdev->devid;
+- idev->hwpt_id = vdev->hwpt->hwpt_id;
++ hiodi = HOST_IOMMU_DEVICE_IOMMUFD(hiod);
++ hiodi->iommufd = vdev->iommufd;
++ hiodi->devid = vdev->devid;
++ hiodi->hwpt_id = vdev->hwpt->hwpt_id;
+
+ return true;
+ }
+@@ -944,14 +944,14 @@ hiod_iommufd_vfio_get_page_size_mask(HostIOMMUDevice *hiod)
+ static void hiod_iommufd_vfio_class_init(ObjectClass *oc, const void *data)
+ {
+ HostIOMMUDeviceClass *hiodc = HOST_IOMMU_DEVICE_CLASS(oc);
+- HostIOMMUDeviceIOMMUFDClass *idevc = HOST_IOMMU_DEVICE_IOMMUFD_CLASS(oc);
++ HostIOMMUDeviceIOMMUFDClass *hiodic = HOST_IOMMU_DEVICE_IOMMUFD_CLASS(oc);
+
+ hiodc->realize = hiod_iommufd_vfio_realize;
+ hiodc->get_iova_ranges = hiod_iommufd_vfio_get_iova_ranges;
+ hiodc->get_page_size_mask = hiod_iommufd_vfio_get_page_size_mask;
+
+- idevc->attach_hwpt = host_iommu_device_iommufd_vfio_attach_hwpt;
+- idevc->detach_hwpt = host_iommu_device_iommufd_vfio_detach_hwpt;
++ hiodic->attach_hwpt = host_iommu_device_iommufd_vfio_attach_hwpt;
++ hiodic->detach_hwpt = host_iommu_device_iommufd_vfio_detach_hwpt;
+ };
+
+ static const TypeInfo types[] = {
+diff --git a/include/system/iommufd.h b/include/system/iommufd.h
+index 25da754434..e45f4a5e87 100644
+--- a/include/system/iommufd.h
++++ b/include/system/iommufd.h
+@@ -136,7 +136,7 @@ struct HostIOMMUDeviceIOMMUFDClass {
+ *
+ * Mandatory callback.
+ *
+- * @idev: host IOMMU device backed by IOMMUFD backend.
++ * @hiodi: host IOMMU device backed by IOMMUFD backend.
+ *
+ * @hwpt_id: ID of IOMMUFD hardware page table.
+ *
+@@ -144,7 +144,7 @@ struct HostIOMMUDeviceIOMMUFDClass {
+ *
+ * Returns: true on success, false on failure.
+ */
+- bool (*attach_hwpt)(HostIOMMUDeviceIOMMUFD *idev, uint32_t hwpt_id,
++ bool (*attach_hwpt)(HostIOMMUDeviceIOMMUFD *hiodi, uint32_t hwpt_id,
+ Error **errp);
+ /**
+ * @detach_hwpt: detach host IOMMU device from IOMMUFD hardware page table.
+@@ -152,17 +152,17 @@ struct HostIOMMUDeviceIOMMUFDClass {
+ *
+ * Mandatory callback.
+ *
+- * @idev: host IOMMU device backed by IOMMUFD backend.
++ * @hiodi: host IOMMU device backed by IOMMUFD backend.
+ *
+ * @errp: pass an Error out when attachment fails.
+ *
+ * Returns: true on success, false on failure.
+ */
+- bool (*detach_hwpt)(HostIOMMUDeviceIOMMUFD *idev, Error **errp);
++ bool (*detach_hwpt)(HostIOMMUDeviceIOMMUFD *hiodi, Error **errp);
+ };
+
+-bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
++bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
+ uint32_t hwpt_id, Error **errp);
+-bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
++bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
+ Error **errp);
+ #endif
+--
+2.52.0
+
diff --git a/kvm-memory-Allow-RAM-device-regions-to-skip-IOMMU-mappin.patch b/kvm-memory-Allow-RAM-device-regions-to-skip-IOMMU-mappin.patch
new file mode 100644
index 0000000..7b5d902
--- /dev/null
+++ b/kvm-memory-Allow-RAM-device-regions-to-skip-IOMMU-mappin.patch
@@ -0,0 +1,148 @@
+From 38481d1bcb08e5652e949ce60ba5dd46e95dc766 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:41 +0100
+Subject: [PATCH 099/111] memory: Allow RAM device regions to skip IOMMU
+ mapping
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [99/111] 0f2dac574eb1c2042ca4f0c2ea22e5493f6dc174 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Conflicts: system/memory.c. We don't have 5a525dcb4d60
+("system/memory: Constify various MemoryRegion arguments") so
+we get a contextual conflict wrt memory_region_has_guest_memfd
+which does not take a const MemoryRegion * arg downstream. Also
+forced to remove the const for memory_region_skip_iommu_map().
+Also impacts include/system/memory.h declaration.
+5a525dcb4d60 would draw more dependencies so better to skip it.
+
+Some RAM device regions created with memory_region_init_ram_device_ptr()
+are not intended to be P2P DMA targets.
+
+The VFIO listener currently treats all RAM device regions as DMA
+capable and attempts to map them into the IOMMU. For regions without
+dma-buf backing this fails and prints warnings such as:
+
+ IOMMU_IOAS_MAP failed: Bad address, PCI BAR?
+
+Introduce a MemoryRegion flag (ram_device_skip_iommu_map) to mark RAM
+device regions that should not be IOMMU mapped, paired with
+memory_region_skip_iommu_map() / memory_region_set_skip_iommu_map()
+accessors. When the flag is set, the VFIO listener skips DMA mapping
+for that region.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260609112552.378999-21-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 11b9798c7b524762b98ea62b1c3fbc6304699784)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/vfio/listener.c | 6 ++++++
+ hw/vfio/trace-events | 1 +
+ include/system/memory.h | 21 +++++++++++++++++++++
+ system/memory.c | 10 ++++++++++
+ 4 files changed, 38 insertions(+)
+
+diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
+index afcf518f56..60249a7252 100644
+--- a/hw/vfio/listener.c
++++ b/hw/vfio/listener.c
+@@ -609,6 +609,12 @@ void vfio_container_region_add(VFIOContainer *bcontainer,
+ }
+ }
+
++ if (memory_region_skip_iommu_map(section->mr)) {
++ trace_vfio_listener_region_skip_dma_map(memory_region_name(section->mr),
++ iova, int128_get64(llsize));
++ return;
++ }
++
+ ret = vfio_container_dma_map(bcontainer, iova, int128_get64(llsize),
+ vaddr, section->readonly, section->mr);
+ if (ret) {
+diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
+index 82abfc99ae..d98fa5cefb 100644
+--- a/hw/vfio/trace-events
++++ b/hw/vfio/trace-events
+@@ -100,6 +100,7 @@ vfio_listener_region_del_iommu(const char *name) "region_del [iommu] %s"
+ vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]"
+ vfio_known_safe_misalignment(const char *name, uint64_t iova, uint64_t offset_within_region, uintptr_t page_size) "Region \"%s\" iova=0x%"PRIx64" offset_within_region=0x%"PRIx64" qemu_real_host_page_size=0x%"PRIxPTR
+ vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" is not aligned to 0x%"PRIx64" and cannot be mapped for DMA"
++vfio_listener_region_skip_dma_map(const char *name, uint64_t iova, uint64_t size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" marked to skip IOMMU mapping"
+ vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64
+ vfio_device_dirty_tracking_update(uint64_t start, uint64_t end, uint64_t min, uint64_t max) "section 0x%"PRIx64" - 0x%"PRIx64" -> update [0x%"PRIx64" - 0x%"PRIx64"]"
+ vfio_device_dirty_tracking_start(int nr_ranges, uint64_t min32, uint64_t max32, uint64_t min64, uint64_t max64, uint64_t minpci, uint64_t maxpci) "nr_ranges %d 32:[0x%"PRIx64" - 0x%"PRIx64"], 64:[0x%"PRIx64" - 0x%"PRIx64"], pci64:[0x%"PRIx64" - 0x%"PRIx64"]"
+diff --git a/include/system/memory.h b/include/system/memory.h
+index 4913206c8c..8e60f03d44 100644
+--- a/include/system/memory.h
++++ b/include/system/memory.h
+@@ -866,6 +866,8 @@ struct MemoryRegion {
+
+ /* For devices designed to perform re-entrant IO into their own IO MRs */
+ bool disable_reentrancy_guard;
++ /* RAM device region that does not require IOMMU mapping for P2P */
++ bool ram_device_skip_iommu_map;
+ };
+
+ struct IOMMUMemoryRegion {
+@@ -1821,6 +1823,25 @@ static inline bool memory_region_is_romd(MemoryRegion *mr)
+ */
+ bool memory_region_is_protected(MemoryRegion *mr);
+
++/**
++ * memory_region_skip_iommu_map: check whether a memory region is excluded
++ * from IOMMU mapping
++ *
++ * Returns %true if @mr is a RAM device region marked to skip IOMMU mapping.
++ *
++ * @mr: the memory region being queried
++ */
++bool memory_region_skip_iommu_map(MemoryRegion *mr);
++
++/**
++ * memory_region_set_skip_iommu_map: mark a RAM device region to skip IOMMU
++ * mapping
++ *
++ * @mr: the memory region being modified
++ * @skip: %true to skip IOMMU mapping, %false to allow it
++ */
++void memory_region_set_skip_iommu_map(MemoryRegion *mr, bool skip);
++
+ /**
+ * memory_region_has_guest_memfd: check whether a memory region has guest_memfd
+ * associated
+diff --git a/system/memory.c b/system/memory.c
+index 5646547940..bdd53369a9 100644
+--- a/system/memory.c
++++ b/system/memory.c
+@@ -1875,6 +1875,16 @@ bool memory_region_is_protected(MemoryRegion *mr)
+ return mr->ram && (mr->ram_block->flags & RAM_PROTECTED);
+ }
+
++bool memory_region_skip_iommu_map(MemoryRegion *mr)
++{
++ return memory_region_is_ram_device(mr) && mr->ram_device_skip_iommu_map;
++}
++
++void memory_region_set_skip_iommu_map(MemoryRegion *mr, bool skip)
++{
++ mr->ram_device_skip_iommu_map = skip;
++}
++
+ bool memory_region_has_guest_memfd(MemoryRegion *mr)
+ {
+ return mr->ram_block && mr->ram_block->guest_memfd >= 0;
+--
+2.52.0
+
diff --git a/kvm-qdev-Add-a-SsidSizeMode-property-type.patch b/kvm-qdev-Add-a-SsidSizeMode-property-type.patch
new file mode 100644
index 0000000..f2a11f1
--- /dev/null
+++ b/kvm-qdev-Add-a-SsidSizeMode-property-type.patch
@@ -0,0 +1,131 @@
+From 5f0546d421450aede89b929920c3963a83573e13 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Tue, 24 Mar 2026 14:02:29 +0000
+Subject: [PATCH 060/111] qdev: Add a SsidSizeMode property type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [60/111] 907950d10709af8ef5016c7325cdc232b1a39996 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+Introduce a new enum type property allowing to set a Substream ID size
+for HW-accelerated smmuv3. Values are auto and 0..20. The auto value
+allows SSID size property to be derived from host IOMMU capabilities.
+A value of 0 disables SubstreamID, while non-zero values specify the
+SSID size in bits.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Message-id: 20260323182454.1416110-5-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 3a3dd64e63dc772f6067d8215b7add7474e6a3e5)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/core/qdev-properties-system.c | 14 ++++++++++++++
+ include/hw/qdev-properties-system.h | 3 +++
+ qapi/misc-arm.json | 16 ++++++++++++++++
+ qapi/pragma.json | 1 +
+ 4 files changed, 34 insertions(+)
+
+diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
+index 1f810b7ddf..67b3ce3a16 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-types-misc-arm.h"
+ #include "qapi/qapi-visit-virtio.h"
+ #include "qapi/qmp/qerror.h"
+ #include "qemu/ctype.h"
+@@ -723,6 +724,19 @@ const PropertyInfo qdev_prop_zero_page_detection = {
+ .set_default_value = qdev_propinfo_set_default_value_enum,
+ };
+
++/* --- SsidSizeMode --- */
++
++QEMU_BUILD_BUG_ON(sizeof(SsidSizeMode) != sizeof(int));
++
++const PropertyInfo qdev_prop_ssidsize_mode = {
++ .type = "SsidSizeMode",
++ .description = "ssidsize mode: auto, 0-20",
++ .enum_table = &SsidSizeMode_lookup,
++ .get = qdev_propinfo_get_enum,
++ .set = qdev_propinfo_set_enum,
++ .set_default_value = qdev_propinfo_set_default_value_enum,
++};
++
+ /* --- Reserved Region --- */
+
+ /*
+diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
+index 9601a11a09..7f9bcf59f2 100644
+--- a/include/hw/qdev-properties-system.h
++++ b/include/hw/qdev-properties-system.h
+@@ -13,6 +13,7 @@ extern const PropertyInfo qdev_prop_multifd_compression;
+ extern const PropertyInfo qdev_prop_mig_mode;
+ extern const PropertyInfo qdev_prop_granule_mode;
+ extern const PropertyInfo qdev_prop_zero_page_detection;
++extern const PropertyInfo qdev_prop_ssidsize_mode;
+ extern const PropertyInfo qdev_prop_losttickpolicy;
+ extern const PropertyInfo qdev_prop_blockdev_on_error;
+ extern const PropertyInfo qdev_prop_bios_chs_trans;
+@@ -60,6 +61,8 @@ extern const PropertyInfo qdev_prop_virtio_gpu_output_list;
+ #define DEFINE_PROP_ZERO_PAGE_DETECTION(_n, _s, _f, _d) \
+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_zero_page_detection, \
+ ZeroPageDetection)
++#define DEFINE_PROP_SSIDSIZE_MODE(_n, _s, _f, _d) \
++ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_ssidsize_mode, SsidSizeMode)
+ #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
+ LostTickPolicy)
+diff --git a/qapi/misc-arm.json b/qapi/misc-arm.json
+index f921d740f1..416b4240e2 100644
+--- a/qapi/misc-arm.json
++++ b/qapi/misc-arm.json
+@@ -45,3 +45,19 @@
+ # { "version": 3, "emulated": false, "kernel": true } ] }
+ ##
+ { 'command': 'query-gic-capabilities', 'returns': ['GICCapability'] }
++
++##
++# @SsidSizeMode:
++#
++# SMMUv3 SubstreamID size configuration mode.
++#
++# @auto: derive from host IOMMU capabilities
++#
++# Values 0-20: SSIDSIZE value in bits. 0 disables SubstreamID.
++#
++# Since: 11.0
++##
++{ 'enum': 'SsidSizeMode',
++ 'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
++ '10', '11', '12', '13', '14', '15', '16', '17', '18',
++ '19', '20' ] } # order matters, see ssidsize_mode_to_value()
+diff --git a/qapi/pragma.json b/qapi/pragma.json
+index 023a2ef7bc..5ad4487147 100644
+--- a/qapi/pragma.json
++++ b/qapi/pragma.json
+@@ -67,6 +67,7 @@
+ 'S390CpuEntitlement',
+ 'S390CpuPolarization',
+ 'S390CpuState',
++ 'SsidSizeMode',
+ 'String',
+ 'StringWrapper',
+ 'SysEmuTarget',
+--
+2.52.0
+
diff --git a/kvm-qdev-Add-an-OasMode-property-type.patch b/kvm-qdev-Add-an-OasMode-property-type.patch
new file mode 100644
index 0000000..c489bc8
--- /dev/null
+++ b/kvm-qdev-Add-an-OasMode-property-type.patch
@@ -0,0 +1,120 @@
+From e61bd5408af80f3150d8508954a837582a32f3aa Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Tue, 24 Mar 2026 14:02:29 +0000
+Subject: [PATCH 062/111] qdev: Add an OasMode property type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [62/111] c760b42d4840853231ecc1e85f7e0f514a53686d (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+Introduce a new enum type property allowing to set an Output Address
+Size. Values are auto, 32, 36, 40, 42, 44, 48, 52, and 56, where a
+value of N specifies an N-bit OAS.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Message-id: 20260323182454.1416110-7-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit d3d2de3d227b63db5715fcaa89df388c929c7aba)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/core/qdev-properties-system.c | 13 +++++++++++++
+ include/hw/qdev-properties-system.h | 3 +++
+ qapi/misc-arm.json | 28 ++++++++++++++++++++++++++++
+ 3 files changed, 44 insertions(+)
+
+diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
+index 67b3ce3a16..93b2c58ebe 100644
+--- a/hw/core/qdev-properties-system.c
++++ b/hw/core/qdev-properties-system.c
+@@ -737,6 +737,19 @@ const PropertyInfo qdev_prop_ssidsize_mode = {
+ .set_default_value = qdev_propinfo_set_default_value_enum,
+ };
+
++/* --- OasMode --- */
++
++QEMU_BUILD_BUG_ON(sizeof(OasMode) != sizeof(int));
++
++const PropertyInfo qdev_prop_oas_mode = {
++ .type = "OasMode",
++ .description = "oas mode: auto, 32, 36, 40, 42, 44, 48, 52, 56",
++ .enum_table = &OasMode_lookup,
++ .get = qdev_propinfo_get_enum,
++ .set = qdev_propinfo_set_enum,
++ .set_default_value = qdev_propinfo_set_default_value_enum,
++};
++
+ /* --- Reserved Region --- */
+
+ /*
+diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
+index 7f9bcf59f2..153803c34a 100644
+--- a/include/hw/qdev-properties-system.h
++++ b/include/hw/qdev-properties-system.h
+@@ -14,6 +14,7 @@ extern const PropertyInfo qdev_prop_mig_mode;
+ extern const PropertyInfo qdev_prop_granule_mode;
+ extern const PropertyInfo qdev_prop_zero_page_detection;
+ extern const PropertyInfo qdev_prop_ssidsize_mode;
++extern const PropertyInfo qdev_prop_oas_mode;
+ extern const PropertyInfo qdev_prop_losttickpolicy;
+ extern const PropertyInfo qdev_prop_blockdev_on_error;
+ extern const PropertyInfo qdev_prop_bios_chs_trans;
+@@ -63,6 +64,8 @@ extern const PropertyInfo qdev_prop_virtio_gpu_output_list;
+ ZeroPageDetection)
+ #define DEFINE_PROP_SSIDSIZE_MODE(_n, _s, _f, _d) \
+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_ssidsize_mode, SsidSizeMode)
++#define DEFINE_PROP_OAS_MODE(_n, _s, _f, _d) \
++ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_oas_mode, OasMode)
+ #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
+ LostTickPolicy)
+diff --git a/qapi/misc-arm.json b/qapi/misc-arm.json
+index 416b4240e2..4dc66d00e5 100644
+--- a/qapi/misc-arm.json
++++ b/qapi/misc-arm.json
+@@ -61,3 +61,31 @@
+ 'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '10', '11', '12', '13', '14', '15', '16', '17', '18',
+ '19', '20' ] } # order matters, see ssidsize_mode_to_value()
++
++##
++# @OasMode:
++#
++# SMMUv3 Output Address Size configuration mode.
++#
++# @auto: derive from host IOMMU capabilities
++#
++# @32: 32-bit output address size
++#
++# @36: 36-bit output address size
++#
++# @40: 40-bit output address size
++#
++# @42: 42-bit output address size
++#
++# @44: 44-bit output address size
++#
++# @48: 48-bit output address size
++#
++# @52: 52-bit output address size
++#
++# @56: 56-bit output address size
++#
++# Since: 11.0
++##
++{ 'enum': 'OasMode',
++ 'data': [ 'auto', '32', '36', '40', '42', '44', '48', '52', '56' ] }
+--
+2.52.0
+
diff --git a/kvm-qemu-options.hx-Document-arm-smmuv3-device-s-accel-p.patch b/kvm-qemu-options.hx-Document-arm-smmuv3-device-s-accel-p.patch
new file mode 100644
index 0000000..470e28d
--- /dev/null
+++ b/kvm-qemu-options.hx-Document-arm-smmuv3-device-s-accel-p.patch
@@ -0,0 +1,91 @@
+From e622631ba406a9c7864ca7a3fc8104bb07fdecd9 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Tue, 24 Mar 2026 14:02:30 +0000
+Subject: [PATCH 064/111] qemu-options.hx: Document arm-smmuv3 device's accel
+ properties
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [64/111] 310e3a909458ad308f4fbf2dc3296f7b0733c64d (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-160190
+
+Conflicts: contextual conflict in qemu-options.hx because we
+don't have -device amd-iommu documentation introduced by commit
+918973f1d476 ("amd_iommu: Document '-device amd-iommu' common options")
+
+Document arm-smmuv3 properties for setting HW-acceleration,
+Range Invalidation, and Address Translation Services support, as
+well as setting Output Address size and Substream ID size.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Message-id: 20260323182454.1416110-9-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit af35bc0c146ced44f6bfe98587495ae193adcec4)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ qemu-options.hx | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 8eca7faa94..680a903db8 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -1231,13 +1231,43 @@ SRST
+ ``aw-bits=val`` (val between 32 and 64, default depends on machine)
+ This decides the address width of the IOVA address space.
+
+-``-device arm-smmuv3,primary-bus=id``
++``-device arm-smmuv3,primary-bus=id[,option=...]``
+ This is only supported by ``-machine virt`` (ARM).
+
+ ``primary-bus=id``
+ Accepts either the default root complex (pcie.0) or a
+ pxb-pcie based root complex.
+
++ ``accel=on|off`` (default: off)
++ Enables guest to leverage host SMMUv3 features for acceleration.
++ Enabling accel configures the host SMMUv3 in nested mode to support
++ vfio-pci passthrough.
++
++ The following options are available when accel=on.
++ Note: 'auto' mode is not currently supported.
++
++ ``ril=on|off`` (default: on)
++ Support for Range Invalidation, which allows the SMMUv3 driver to
++ invalidate TLB entries for a range of IOVAs at once instead of issuing
++ separate commands to invalidate each page. Must match with host SMMUv3
++ Range Invalidation support.
++
++ ``ats=on|off`` (default: off)
++ Support for Address Translation Services, which enables PCIe devices to
++ cache address translations in their local TLB and reduce latency. Host
++ SMMUv3 must support ATS in order to enable this feature for the vIOMMU.
++
++ ``oas=val`` (supported values are 44 and 48. default: 44)
++ Sets the Output Address Size in bits. The value set here must be less
++ than or equal to the host SMMUv3's supported OAS, so that the
++ intermediate physical addresses (IPA) consumed by host SMMU for stage-2
++ translation do not exceed the host's max supported IPA size.
++
++ ``ssidsize=val`` (val between 0 and 20. default: 0)
++ Sets the Substream ID size in bits. When set to a non-zero value,
++ PASID capability is advertised to the vIOMMU and accelerated use cases
++ such as Shared Virtual Addressing (SVA) are supported.
++
+ ERST
+
+ DEF("name", HAS_ARG, QEMU_OPTION_name,
+--
+2.52.0
+
diff --git a/kvm-qemu-options.hx-Support-auto-for-accel-SMMUv3-proper.patch b/kvm-qemu-options.hx-Support-auto-for-accel-SMMUv3-proper.patch
new file mode 100644
index 0000000..6712619
--- /dev/null
+++ b/kvm-qemu-options.hx-Support-auto-for-accel-SMMUv3-proper.patch
@@ -0,0 +1,94 @@
+From b3e2305a115903a5f7a887ade486f04150f95988 Mon Sep 17 00:00:00 2001
+From: Nathan Chen <nathanc@nvidia.com>
+Date: Mon, 8 Jun 2026 10:49:00 -0700
+Subject: [PATCH 074/111] qemu-options.hx: Support "auto" for accel SMMUv3
+ properties
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [74/111] 0857e99a4635ba07b72c14c47e5a7882140d7400 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-163596
+
+Conflicts: contextual conflict in qemu-options.hx as we don't
+have -device amd-iommu documentation downstream
+
+Update documentation now that "auto" is supported for accelerated SMMUv3
+properties.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Signed-off-by: Nathan Chen <nathanc@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260608174900.2227340-10-nathanc@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 1b8c0edfee08c3d96cf80cab5d851c059fb7c167)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ qemu-options.hx | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 680a903db8..3fe2171e70 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -1243,31 +1243,44 @@ SRST
+ Enabling accel configures the host SMMUv3 in nested mode to support
+ vfio-pci passthrough.
+
+- The following options are available when accel=on.
+- Note: 'auto' mode is not currently supported.
++ The following options will be set to auto by default if not manually
++ set. When accel=on and these properties are set to auto, the value is
++ derived from the host SMMUv3 capabilities via IOMMU_GET_HW_INFO. With
++ accel=on, this requires at least one cold-plugged vfio-pci device; if
++ none is present at machine init, QEMU will abort.
+
+- ``ril=on|off`` (default: on)
++ If accel=off, auto values resolve to the non-accel defaults given below.
++
++ ``ril=on|off|auto`` (default: auto)
+ Support for Range Invalidation, which allows the SMMUv3 driver to
+ invalidate TLB entries for a range of IOVAs at once instead of issuing
+ separate commands to invalidate each page. Must match with host SMMUv3
+ Range Invalidation support.
+
+- ``ats=on|off`` (default: off)
++ - With accel=off, auto is resolved to 'on'.
++
++ ``ats=on|off|auto`` (default: auto)
+ Support for Address Translation Services, which enables PCIe devices to
+ cache address translations in their local TLB and reduce latency. Host
+ SMMUv3 must support ATS in order to enable this feature for the vIOMMU.
+
+- ``oas=val`` (supported values are 44 and 48. default: 44)
++ - With accel=off, auto is resolved to 'off'.
++
++ ``oas=val|auto`` (supported values are 44 and 48. default: auto)
+ Sets the Output Address Size in bits. The value set here must be less
+ than or equal to the host SMMUv3's supported OAS, so that the
+ intermediate physical addresses (IPA) consumed by host SMMU for stage-2
+ translation do not exceed the host's max supported IPA size.
+
+- ``ssidsize=val`` (val between 0 and 20. default: 0)
++ - With accel=off, auto is resolved to 44.
++
++ ``ssidsize=val|auto`` (val between 0 and 20. default: auto)
+ Sets the Substream ID size in bits. When set to a non-zero value,
+ PASID capability is advertised to the vIOMMU and accelerated use cases
+ such as Shared Virtual Addressing (SVA) are supported.
+
++ - With accel=off, auto is resolved to 0.
++
+ ERST
+
+ DEF("name", HAS_ARG, QEMU_OPTION_name,
+--
+2.52.0
+
diff --git a/kvm-rh-aarch64-rh-devices.mak-Add-CONFIG_TEGRA241_CMDQV.patch b/kvm-rh-aarch64-rh-devices.mak-Add-CONFIG_TEGRA241_CMDQV.patch
new file mode 100644
index 0000000..a152704
--- /dev/null
+++ b/kvm-rh-aarch64-rh-devices.mak-Add-CONFIG_TEGRA241_CMDQV.patch
@@ -0,0 +1,38 @@
+From 88c650be0128e88319d63ceed6d9f099a4a25f2e Mon Sep 17 00:00:00 2001
+From: Eric Auger <eric.auger@redhat.com>
+Date: Thu, 7 May 2026 08:59:56 +0200
+Subject: [PATCH 111/111] rh: aarch64-rh-devices.mak: Add CONFIG_TEGRA241_CMDQV
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [111/111] 4c8d5826d2e77ed8437273d91928bd6166236807 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+UPSTREAM: RH Only
+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ 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 92d0b322d0..b0bfc18af3 100644
+--- a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
++++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
+@@ -4,6 +4,7 @@ CONFIG_ARM_GIC_KVM=y
+ CONFIG_ARM_GICV3=y
+ CONFIG_ARM_GIC=y
+ CONFIG_ARM_SMMUV3=y
++CONFIG_TEGRA241_CMDQV=y
+ CONFIG_ARM_VIRT=y
+ CONFIG_CXL=y
+ CONFIG_CXL_MEM_DEVICE=y
+--
+2.52.0
+
diff --git a/kvm-system-iommufd-Remove-unused-viommu-pointer-from-IOM.patch b/kvm-system-iommufd-Remove-unused-viommu-pointer-from-IOM.patch
new file mode 100644
index 0000000..462088d
--- /dev/null
+++ b/kvm-system-iommufd-Remove-unused-viommu-pointer-from-IOM.patch
@@ -0,0 +1,69 @@
+From aaa21147aa0f3cc4be8c9f161c147400f2847888 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Tue, 9 Jun 2026 12:25:26 +0100
+Subject: [PATCH 083/111] system/iommufd: Remove unused viommu pointer from
+ IOMMUFDVeventq
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [83/111] f26bf60ada82caf5d5e8cbdcb643ea9e5995dbcf (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+The viommu field is assigned but never used. Callers freeing the
+veventq already have access to the IOMMUFDViommu object through other
+references, so this field is redundant.
+
+Removing it also simplifies upcoming changes where veventq is
+allocated based on the viommu id before the IOMMUFDViommu object is
+created (e.g. vendor CMDQV-based veventq allocation).
+
+No functional change.
+
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 20260609112552.378999-6-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 9e67a50ea91df52858849d0c36891e7a8931c05f)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/arm/smmuv3-accel.c | 1 -
+ include/system/iommufd.h | 1 -
+ 2 files changed, 2 deletions(-)
+
+diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
+index 4cef487679..70b2581c17 100644
+--- a/hw/arm/smmuv3-accel.c
++++ b/hw/arm/smmuv3-accel.c
+@@ -553,7 +553,6 @@ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp)
+ veventq = g_new0(IOMMUFDVeventq, 1);
+ veventq->veventq_id = veventq_id;
+ veventq->veventq_fd = veventq_fd;
+- veventq->viommu = accel->viommu;
+ accel->veventq = veventq;
+
+ /* Set up event handler for veventq fd */
+diff --git a/include/system/iommufd.h b/include/system/iommufd.h
+index 2abb7c9605..4591096c3e 100644
+--- a/include/system/iommufd.h
++++ b/include/system/iommufd.h
+@@ -58,7 +58,6 @@ typedef struct IOMMUFDVdev {
+
+ /* Virtual event queue interface for a vIOMMU */
+ typedef struct IOMMUFDVeventq {
+- IOMMUFDViommu *viommu;
+ uint32_t veventq_id;
+ uint32_t veventq_fd;
+ uint32_t last_event_seq; /* Sequence number of last processed event */
+--
+2.52.0
+
diff --git a/kvm-system-memory-Factor-address_space_is_io-out.patch b/kvm-system-memory-Factor-address_space_is_io-out.patch
new file mode 100644
index 0000000..013de16
--- /dev/null
+++ b/kvm-system-memory-Factor-address_space_is_io-out.patch
@@ -0,0 +1,92 @@
+From 739a771cce232fe56b29291092dd7c10d1f2b364 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
+Date: Mon, 29 Sep 2025 14:36:19 +0200
+Subject: [PATCH 046/111] system/memory: Factor address_space_is_io() out
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [46/111] 1dcdda9cbb0db9215a654e8e7e6bab6bfb847014 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73796
+
+Factor address_space_is_io() out of cpu_physical_memory_is_io().
+
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Message-Id: <20251002084203.63899-3-philmd@linaro.org>
+(cherry picked from commit 839976e9da4b577aca284847b7e965332f2ca687)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ include/system/memory.h | 9 +++++++++
+ system/physmem.c | 21 ++++++++++++---------
+ 2 files changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/include/system/memory.h b/include/system/memory.h
+index e2cd6ed126..4913206c8c 100644
+--- a/include/system/memory.h
++++ b/include/system/memory.h
+@@ -3017,6 +3017,15 @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
+ bool address_space_access_valid(AddressSpace *as, hwaddr addr, hwaddr len,
+ bool is_write, MemTxAttrs attrs);
+
++/**
++ * address_space_is_io: check whether an guest physical addresses
++ * whithin an address space is I/O memory.
++ *
++ * @as: #AddressSpace to be accessed
++ * @addr: address within that address space
++ */
++bool address_space_is_io(AddressSpace *as, hwaddr addr);
++
+ /* address_space_map: map a physical memory region into a host virtual address
+ *
+ * May map a subset of the requested range, given by and returned in @plen.
+diff --git a/system/physmem.c b/system/physmem.c
+index e5dd760e0b..2e34205ad7 100644
+--- a/system/physmem.c
++++ b/system/physmem.c
+@@ -3376,6 +3376,17 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
+ return flatview_access_valid(fv, addr, len, is_write, attrs);
+ }
+
++bool address_space_is_io(AddressSpace *as, hwaddr addr)
++{
++ MemoryRegion *mr;
++
++ RCU_READ_LOCK_GUARD();
++ mr = address_space_translate(as, addr, &addr, NULL, false,
++ MEMTXATTRS_UNSPECIFIED);
++
++ return !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
++}
++
+ static hwaddr
+ flatview_extend_translation(FlatView *fv, hwaddr addr,
+ hwaddr target_len,
+@@ -3772,15 +3783,7 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
+
+ bool cpu_physical_memory_is_io(hwaddr phys_addr)
+ {
+- MemoryRegion*mr;
+- hwaddr l = 1;
+-
+- RCU_READ_LOCK_GUARD();
+- mr = address_space_translate(&address_space_memory,
+- phys_addr, &phys_addr, &l, false,
+- MEMTXATTRS_UNSPECIFIED);
+-
+- return !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
++ return address_space_is_io(&address_space_memory, phys_addr);
+ }
+
+ int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque)
+--
+2.52.0
+
diff --git a/kvm-system-physmem-Remove-cpu_physical_memory_is_io.patch b/kvm-system-physmem-Remove-cpu_physical_memory_is_io.patch
new file mode 100644
index 0000000..71cdc69
--- /dev/null
+++ b/kvm-system-physmem-Remove-cpu_physical_memory_is_io.patch
@@ -0,0 +1,62 @@
+From 5f3ad40eb9fabb58c7c6986ae42e814d54017db9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
+Date: Mon, 29 Sep 2025 15:36:08 +0200
+Subject: [PATCH 049/111] system/physmem: Remove cpu_physical_memory_is_io()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [49/111] b20b8a1e8804c7105f541ad220967fd205d45322 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73796
+
+There are no more uses of the legacy cpu_physical_memory_is_io()
+method. Remove it.
+
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Message-Id: <20251002084203.63899-6-philmd@linaro.org>
+(cherry picked from commit ec1eb357cb86eee74d63940154db1e1bfa86026a)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ include/exec/cpu-common.h | 2 --
+ system/physmem.c | 5 -----
+ 2 files changed, 7 deletions(-)
+
+diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
+index 9b658a3f48..7ac061bfcb 100644
+--- a/include/exec/cpu-common.h
++++ b/include/exec/cpu-common.h
+@@ -149,8 +149,6 @@ void *cpu_physical_memory_map(hwaddr addr,
+ void cpu_physical_memory_unmap(void *buffer, hwaddr len,
+ bool is_write, hwaddr access_len);
+
+-bool cpu_physical_memory_is_io(hwaddr phys_addr);
+-
+ /* Coalesced MMIO regions are areas where write operations can be reordered.
+ * This usually implies that write operations are side-effect free. This allows
+ * batching which can make a major impact on performance when using
+diff --git a/system/physmem.c b/system/physmem.c
+index 2e34205ad7..4a1294f8a0 100644
+--- a/system/physmem.c
++++ b/system/physmem.c
+@@ -3781,11 +3781,6 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
+ return 0;
+ }
+
+-bool cpu_physical_memory_is_io(hwaddr phys_addr)
+-{
+- return address_space_is_io(&address_space_memory, phys_addr);
+-}
+-
+ int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque)
+ {
+ RAMBlock *block;
+--
+2.52.0
+
diff --git a/kvm-target-i386-arch_memory_mapping-Use-address_space_me.patch b/kvm-target-i386-arch_memory_mapping-Use-address_space_me.patch
new file mode 100644
index 0000000..c9c5422
--- /dev/null
+++ b/kvm-target-i386-arch_memory_mapping-Use-address_space_me.patch
@@ -0,0 +1,83 @@
+From 93d697c70717c2f9a544909774aaa978c0117d65 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
+Date: Mon, 29 Sep 2025 15:35:28 +0200
+Subject: [PATCH 047/111] target/i386/arch_memory_mapping: Use
+ address_space_memory_is_io()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [47/111] 118cf50c385e9d53f0b925de1d4650d28ec36049 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73796
+
+Since all functions have an address space argument, it is
+trivial to replace cpu_physical_memory_is_io() by
+address_space_memory_is_io().
+
+Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Message-Id: <20251002084203.63899-4-philmd@linaro.org>
+(cherry picked from commit 6ffaa9219616d12bc6c3e7cb26a77f7432ac0c70)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ target/i386/arch_memory_mapping.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/target/i386/arch_memory_mapping.c b/target/i386/arch_memory_mapping.c
+index a2398c2173..560f4689ab 100644
+--- a/target/i386/arch_memory_mapping.c
++++ b/target/i386/arch_memory_mapping.c
+@@ -35,7 +35,7 @@ static void walk_pte(MemoryMappingList *list, AddressSpace *as,
+ }
+
+ start_paddr = (pte & ~0xfff) & ~(0x1ULL << 63);
+- if (cpu_physical_memory_is_io(start_paddr)) {
++ if (address_space_is_io(as, start_paddr)) {
+ /* I/O region */
+ continue;
+ }
+@@ -65,7 +65,7 @@ static void walk_pte2(MemoryMappingList *list, AddressSpace *as,
+ }
+
+ start_paddr = pte & ~0xfff;
+- if (cpu_physical_memory_is_io(start_paddr)) {
++ if (address_space_is_io(as, start_paddr)) {
+ /* I/O region */
+ continue;
+ }
+@@ -100,7 +100,7 @@ static void walk_pde(MemoryMappingList *list, AddressSpace *as,
+ if (pde & PG_PSE_MASK) {
+ /* 2 MB page */
+ start_paddr = (pde & ~0x1fffff) & ~(0x1ULL << 63);
+- if (cpu_physical_memory_is_io(start_paddr)) {
++ if (address_space_is_io(as, start_paddr)) {
+ /* I/O region */
+ continue;
+ }
+@@ -142,7 +142,7 @@ static void walk_pde2(MemoryMappingList *list, AddressSpace *as,
+ */
+ high_paddr = ((hwaddr)(pde & 0x1fe000) << 19);
+ start_paddr = (pde & ~0x3fffff) | high_paddr;
+- if (cpu_physical_memory_is_io(start_paddr)) {
++ if (address_space_is_io(as, start_paddr)) {
+ /* I/O region */
+ continue;
+ }
+@@ -203,7 +203,7 @@ static void walk_pdpe(MemoryMappingList *list, AddressSpace *as,
+ if (pdpe & PG_PSE_MASK) {
+ /* 1 GB page */
+ start_paddr = (pdpe & ~0x3fffffff) & ~(0x1ULL << 63);
+- if (cpu_physical_memory_is_io(start_paddr)) {
++ if (address_space_is_io(as, start_paddr)) {
+ /* I/O region */
+ continue;
+ }
+--
+2.52.0
+
diff --git a/kvm-tests-qtest-bios-tables-test-Prepare-for-IORT-reviso.patch b/kvm-tests-qtest-bios-tables-test-Prepare-for-IORT-reviso.patch
new file mode 100644
index 0000000..a83cb95
--- /dev/null
+++ b/kvm-tests-qtest-bios-tables-test-Prepare-for-IORT-reviso.patch
@@ -0,0 +1,50 @@
+From 245045065cd09440ed4909fdab7483a3e785b480 Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 032/111] tests/qtest/bios-tables-test: Prepare for IORT
+ revison upgrade
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [32/111] a7efe2b4794db4049552c7b777d398d495c907b3 (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Subsequent patch will upgrade IORT revision to 5 to add support
+for IORT RMR nodes.
+
+Add the affected IORT blobs to allowed-diff list for bios-table
+tests.
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-25-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit b8e196a746eb279ba5b713de9b236259f944c82d)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ tests/qtest/bios-tables-test-allowed-diff.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
+index dfb8523c8b..3279638ad0 100644
+--- a/tests/qtest/bios-tables-test-allowed-diff.h
++++ b/tests/qtest/bios-tables-test-allowed-diff.h
+@@ -1 +1,5 @@
+ /* List of comma-separated changed AML files to ignore */
++"tests/data/acpi/aarch64/virt/IORT",
++"tests/data/acpi/aarch64/virt/IORT.its_off",
++"tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy",
++"tests/data/acpi/aarch64/virt/IORT.smmuv3-dev",
+--
+2.52.0
+
diff --git a/kvm-tests-qtest-bios-tables-test-Update-IORT-blobs-after.patch b/kvm-tests-qtest-bios-tables-test-Update-IORT-blobs-after.patch
new file mode 100644
index 0000000..c3449da
--- /dev/null
+++ b/kvm-tests-qtest-bios-tables-test-Update-IORT-blobs-after.patch
@@ -0,0 +1,79 @@
+From d7aecf7edeb7efbe4d7110f1251ab347e01c730e Mon Sep 17 00:00:00 2001
+From: Shameer Kolothum <skolothumtho@nvidia.com>
+Date: Thu, 29 Jan 2026 13:32:05 +0000
+Subject: [PATCH 034/111] tests/qtest/bios-tables-test: Update IORT blobs after
+ revision upgrade
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [34/111] 7ece86f5a44f645061770b685d34b4909ff5561a (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73794
+
+Update the reference IORT blobs after revision upgrade for RMR node
+support. This affects the aarch64 'virt' IORT tests.
+
+IORT diff is the same for all the tests:
+
+ /*
+ * Intel ACPI Component Architecture
+ * AML/ASL+ Disassembler version 20230628 (64-bit version)
+ * Copyright (c) 2000 - 2023 Intel Corporation
+ *
+- * Disassembly of tests/data/acpi/aarch64/virt/IORT, Mon Oct 20 14:42:41 2025
++ * Disassembly of /tmp/aml-B4ZRE3, Mon Oct 20 14:42:41 2025
+ *
+ * ACPI Data Table [IORT]
+ *
+ * Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue (in hex)
+ */
+
+ [000h 0000 004h] Signature : "IORT" [IO Remapping Table]
+ [004h 0004 004h] Table Length : 00000080
+-[008h 0008 001h] Revision : 03
+-[009h 0009 001h] Checksum : B3
++[008h 0008 001h] Revision : 05
++[009h 0009 001h] Checksum : B1
+ [00Ah 0010 006h] Oem ID : "BOCHS "
+ [010h 0016 008h] Oem Table ID : "BXPC "
+ [018h 0024 004h] Oem Revision : 00000001
+ [01Ch 0028 004h] Asl Compiler ID : "BXPC"
+ [020h 0032 004h] Asl Compiler Revision : 00000001
+ ...
+
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
+Message-id: 20260126104342.253965-27-skolothumtho@nvidia.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit f48bddafa251503a2aa4a6eb9dd612ec9c0781f7)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ tests/data/acpi/aarch64/virt/IORT | Bin 128 -> 128 bytes
+ tests/data/acpi/aarch64/virt/IORT.its_off | Bin 172 -> 172 bytes
+ tests/data/acpi/aarch64/virt/IORT.smmuv3-dev | Bin 364 -> 364 bytes
+ tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy | Bin 276 -> 276 bytes
+ tests/qtest/bios-tables-test-allowed-diff.h | 4 ----
+ 5 files changed, 4 deletions(-)
+
+diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
+index 3279638ad0..dfb8523c8b 100644
+--- a/tests/qtest/bios-tables-test-allowed-diff.h
++++ b/tests/qtest/bios-tables-test-allowed-diff.h
+@@ -1,5 +1 @@
+ /* List of comma-separated changed AML files to ignore */
+-"tests/data/acpi/aarch64/virt/IORT",
+-"tests/data/acpi/aarch64/virt/IORT.its_off",
+-"tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy",
+-"tests/data/acpi/aarch64/virt/IORT.smmuv3-dev",
+--
+2.52.0
+
diff --git a/kvm-vfio-iommufd-Force-creating-nesting-parent-HWPT.patch b/kvm-vfio-iommufd-Force-creating-nesting-parent-HWPT.patch
new file mode 100644
index 0000000..d883213
--- /dev/null
+++ b/kvm-vfio-iommufd-Force-creating-nesting-parent-HWPT.patch
@@ -0,0 +1,121 @@
+From e860d57ea2f5ed6480d1717226e99626a5f4ba4e Mon Sep 17 00:00:00 2001
+From: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Date: Tue, 6 Jan 2026 01:12:50 -0500
+Subject: [PATCH 076/111] vfio/iommufd: Force creating nesting parent HWPT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Auger <eric.auger@redhat.com>
+RH-MergeRequest: 505: SMMU Rebase for accelerated SMMU and CMDQV support
+RH-Jira: RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798
+RH-Acked-by: Cédric Le Goater <clg@redhat.com>
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Commit: [76/111] 49096907847a865983e879a968586122dccb292e (eauger1/centos-qemu-kvm)
+
+JIRA: https://redhat.atlassian.net/browse/RHEL-73798
+
+Conflicts: contextual conflict in hw/vfio/device.c and
+include/hw/vfio/vfio-device.h due to out of order backport og
+de36da106dcf hw/vfio: Add helper to retrieve device feature
+also change hw/core/hw-error.h into former hw/hw.h since we
+also miss 048a23851cd4 include: move hw/hw.h to hw/core/, rename
+
+Call pci_device_get_viommu_flags() to get if vIOMMU supports
+VIOMMU_FLAG_WANT_NESTING_PARENT.
+
+If yes, create a nesting parent HWPT and add it to the container's hwpt_list,
+letting this parent HWPT cover the entire second stage mappings (GPA=>HPA).
+
+This allows a VFIO passthrough device to directly attach to this default HWPT
+and then to use the system address space and its listener.
+
+Introduce a vfio_device_get_viommu_flags_want_nesting() helper to facilitate
+this implementation.
+
+It is safe to do so because a vIOMMU will be able to fail in set_iommu_device()
+call, if something else related to the VFIO device or vIOMMU isn't compatible.
+
+Suggested-by: Nicolin Chen <nicolinc@nvidia.com>
+Suggested-by: Yi Liu <yi.l.liu@intel.com>
+Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Link: https://lore.kernel.org/qemu-devel/20260106061304.314546-9-zhenzhong.duan@intel.com
+Signed-off-by: Cédric Le Goater <clg@redhat.com>
+(cherry picked from commit c3459c6bfaad6a3d0bef4d3ebc6753bb3e66c1ef)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+---
+ hw/vfio/device.c | 13 +++++++++++++
+ hw/vfio/iommufd.c | 9 +++++++++
+ include/hw/vfio/vfio-device.h | 1 +
+ 3 files changed, 23 insertions(+)
+
+diff --git a/hw/vfio/device.c b/hw/vfio/device.c
+index 330f2598ff..c01eb72ee7 100644
+--- a/hw/vfio/device.c
++++ b/hw/vfio/device.c
+@@ -24,6 +24,8 @@
+ #include "hw/vfio/vfio-device.h"
+ #include "hw/vfio/pci.h"
+ #include "hw/hw.h"
++#include "hw/core/iommu.h"
++#include "hw/hw.h"
+ #include "trace.h"
+ #include "qapi/error.h"
+ #include "qemu/error-report.h"
+@@ -524,6 +526,17 @@ int vfio_device_get_feature(VFIODevice *vbasedev,
+ return vbasedev->io_ops->device_feature(vbasedev, feature);
+ }
+
++bool vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev)
++{
++ VFIOPCIDevice *vdev = vfio_pci_from_vfio_device(vbasedev);
++
++ if (vdev) {
++ return !!(pci_device_get_viommu_flags(PCI_DEVICE(vdev)) &
++ VIOMMU_FLAG_WANT_NESTING_PARENT);
++ }
++ return false;
++}
++
+ /*
+ * Traditional ioctl() based io
+ */
+diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
+index 67acdfa183..59dc17b166 100644
+--- a/hw/vfio/iommufd.c
++++ b/hw/vfio/iommufd.c
+@@ -363,6 +363,15 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
+ flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
+ }
+
++ /*
++ * If vIOMMU requests VFIO's cooperation to create nesting parent HWPT,
++ * force to create it so that it could be reused by vIOMMU to create
++ * nested HWPT.
++ */
++ if (vfio_device_get_viommu_flags_want_nesting(vbasedev)) {
++ flags |= IOMMU_HWPT_ALLOC_NEST_PARENT;
++ }
++
+ if (cpr_is_incoming()) {
+ hwpt_id = vbasedev->cpr.hwpt_id;
+ goto skip_alloc;
+diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
+index fc28f580ba..27e2976593 100644
+--- a/include/hw/vfio/vfio-device.h
++++ b/include/hw/vfio/vfio-device.h
+@@ -260,6 +260,7 @@ void vfio_device_unprepare(VFIODevice *vbasedev);
+
+ int vfio_device_get_feature(VFIODevice *vbasedev,
+ struct vfio_device_feature *feature);
++bool vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev);
+
+ int vfio_device_get_region_info(VFIODevice *vbasedev, int index,
+ struct vfio_region_info **info);
+--
+2.52.0
+
diff --git a/qemu.spec b/qemu.spec
index d5c58a4..5db4f9e 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -143,7 +143,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \
Summary: QEMU is a machine emulator and virtualizer
Name: qemu-kvm
Version: 10.1.0
-Release: 22%{?rcrel}%{?dist}%{?cc_suffix}
+Release: 23%{?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)
@@ -166,6 +166,11 @@ Source28: 95-kvm-memlock.conf
Source30: kvm-s390x.conf
Source31: kvm-x86.conf
Source36: README.tests
+# Handling binary changes for MR 505
+Source40: IORT
+Source41: IORT.its_off
+Source42: IORT.smmuv3-dev
+Source43: IORT.smmuv3-legacy
Patch0001: 0001-python-Replace-asyncio.get_event_loop-for-Python-3.14.patch
@@ -809,6 +814,783 @@ Patch324: kvm-iotests-046-Test-that-discard-write_zeroes-wait-for-.patch
Patch325: kvm-qcow2-Fix-data-loss-on-zero-write-with-detect-zeroes.patch
# For RHEL-186384 - virt-storage: Backport stable branch fixes
Patch326: kvm-block-Fix-crash-after-setting-latency-historygram-wi.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch327: kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vio.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch328: kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vde.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch329: kvm-hw-arm-smmu-common-Factor-out-common-helper-function.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch330: kvm-hw-arm-smmu-add-memory-regions-as-property-for-an-SM.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch331: kvm-hw-arm-smmuv3-Extract-common-definitions-to-smmuv3-c.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch332: kvm-hw-arm-smmu-common-Make-iommu-ops-part-of-SMMUState.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch333: kvm-hw-arm-smmuv3-accel-Introduce-smmuv3-accel-device.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch334: kvm-hw-arm-smmuv3-accel-Initialize-shared-system-address.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch335: kvm-hw-pci-pci-Move-pci_init_bus_master-after-adding-dev.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch336: kvm-hw-pci-Export-pci_device_get_iommu_bus_devfn-and-ret.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch337: kvm-hw-pci-pci-Add-optional-supports_address_space-callb.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch338: kvm-hw-pci-bridge-pci_expander_bridge-Move-TYPE_PXB_PCIE.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch339: kvm-hw-arm-smmuv3-accel-Restrict-accelerated-SMMUv3-to-v.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch340: kvm-hw-arm-smmuv3-Implement-get_viommu_cap-callback.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch341: kvm-hw-pci-Introduce-pci_device_get_viommu_flags.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch342: kvm-hw-pci-Introduce-pci_device_get_host_iommu_quirks.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch343: kvm-hw-arm-smmuv3-common-Define-STE-CD-fields-via-regist.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch344: kvm-hw-arm-smmuv3-common-Add-NSCFG-bit-definition-for-CD.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch345: kvm-hw-arm-smmuv3-common-Add-STE-CD-set-helpers-for-repe.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch346: kvm-hw-arm-smmuv3-accel-Add-set-unset_iommu_device-callb.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch347: kvm-hw-arm-smmuv3-propagate-smmuv3_cmdq_consume-errors-t.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch348: kvm-hw-arm-smmuv3-accel-Add-nested-vSTE-install-uninstal.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch349: kvm-hw-arm-smmuv3-accel-Install-SMMUv3-GBPA-based-hwpt.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch350: kvm-hw-pci-pci-Introduce-a-callback-to-retrieve-the-MSI-.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch351: kvm-hw-arm-smmuv3-accel-Implement-get_msi_direct_gpa-cal.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch352: kvm-hw-arm-virt-Set-msi-gpa-property.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch353: kvm-hw-arm-smmuv3-accel-Add-support-to-issue-invalidatio.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch354: kvm-hw-arm-smmuv3-Initialize-ID-registers-early-during-r.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch355: kvm-hw-arm-smmuv3-accel-Get-host-SMMUv3-hw-info-and-vali.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch356: kvm-hw-pci-host-gpex-Allow-to-generate-preserve-boot-con.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch357: kvm-hw-arm-virt-Set-PCI-preserve_config-for-accel-SMMUv3.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch358: kvm-tests-qtest-bios-tables-test-Prepare-for-IORT-reviso.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch359: kvm-hw-arm-virt-acpi-build-Add-IORT-RMR-regions-to-handl.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch360: kvm-tests-qtest-bios-tables-test-Update-IORT-blobs-after.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch361: kvm-hw-arm-smmuv3-Block-migration-when-accel-is-enabled.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch362: kvm-hw-arm-smmuv3-Add-accel-property-for-SMMUv3-device.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch363: kvm-hw-arm-smmuv3-accel-Add-a-property-to-specify-RIL-su.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch364: kvm-hw-arm-smmuv3-accel-Add-support-for-ATS.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch365: kvm-hw-arm-smmuv3-accel-Add-property-to-specify-OAS-bits.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch366: kvm-backends-iommufd-Retrieve-PASID-width-from-iommufd_b.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch367: kvm-backends-iommufd-Add-get_pasid_info-callback.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch368: kvm-hw-pci-Add-helper-to-insert-PCIe-extended-capability.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch369: kvm-hw-pci-Factor-out-common-PASID-capability-initializa.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch370: kvm-hw-vfio-pci-Synthesize-PASID-capability-for-vfio-pci.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch371: kvm-hw-arm-smmuv3-accel-Make-SubstreamID-support-configu.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch372: kvm-system-memory-Factor-address_space_is_io-out.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch373: kvm-target-i386-arch_memory_mapping-Use-address_space_me.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch374: kvm-hw-s390x-sclp-Use-address_space_memory_is_io-in-sclp.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch375: kvm-system-physmem-Remove-cpu_physical_memory_is_io.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch376: kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vev.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch377: kvm-hw-arm-smmuv3-accel-Add-viommu-free-helper.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch378: kvm-hw-arm-smmuv3-accel-Allocate-vEVENTQ-for-accelerated.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch379: kvm-hw-arm-smmuv3-Introduce-a-helper-function-for-event-.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch380: kvm-hw-arm-smmuv3-accel-Read-and-propagate-host-vIOMMU-e.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch381: kvm-hw-arm-smmuv3-Correct-SMMUEN-field-name-in-CR0.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch382: kvm-hw-arm-smmuv3-Fix-CFGI_CD-handling-when-stage-1-is-u.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch383: kvm-hw-arm-smmuv3-accel-Check-ATS-compatibility-between-.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch384: kvm-hw-arm-smmuv3-accel-Change-ats-property-type-to-OnOf.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch385: kvm-hw-arm-smmuv3-accel-Change-ril-property-type-to-OnOf.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch386: kvm-qdev-Add-a-SsidSizeMode-property-type.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch387: kvm-hw-arm-smmuv3-accel-Change-ssidsize-property-type-to.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch388: kvm-qdev-Add-an-OasMode-property-type.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch389: kvm-hw-arm-smmuv3-accel-Change-oas-property-type-to-OasM.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch390: kvm-qemu-options.hx-Document-arm-smmuv3-device-s-accel-p.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch391: kvm-hw-arm-smmuv3-Have-smmuv3_accel_init-take-an-Error-p.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch392: kvm-hw-arm-smmuv3-Update-ATC-invalidation-check.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch393: kvm-hw-arm-smmuv3-Improve-accel-SMMUv3-usage-documentati.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch394: kvm-hw-arm-smmuv3-accel-Add-helper-for-resolving-auto-pa.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch395: kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ats.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch396: kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ril.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch397: kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ssidsiz.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch398: kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-oas.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch399: kvm-hw-arm-smmuv3-Set-default-ats-ril-ssidsize-oas-to-au.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch400: kvm-qemu-options.hx-Support-auto-for-accel-SMMUv3-proper.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch401: kvm-hw-pci-pci-Enforce-pci_setup_iommu_per_bus-is-called.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch402: kvm-vfio-iommufd-Force-creating-nesting-parent-HWPT.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch403: kvm-hw-vfio-iommufd-Control-dirty-tracking-for-nesting-p.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch404: kvm-backends-iommufd-Update-iommufd_backend_get_device_i.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch405: kvm-iommufd-Rename-all-the-idev-and-idevc-variables-to-h.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch406: kvm-backends-iommufd-Update-iommufd_backend_alloc_viommu.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch407: kvm-backends-iommufd-Introduce-iommufd_backend_alloc_hw_.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch408: kvm-backends-iommufd-Introduce-iommufd_backend_viommu_mm.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch409: kvm-system-iommufd-Remove-unused-viommu-pointer-from-IOM.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch410: kvm-hw-arm-smmuv3-accel-Introduce-CMDQV-ops-interface.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch411: kvm-hw-arm-smmuv3-Avoid-including-CONFIG_DEVICES-in-hw-h.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch412: kvm-hw-arm-tegra241-cmdqv-Add-Tegra241-CMDQV-ops-backend.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch413: kvm-hw-arm-smmuv3-accel-Wire-CMDQV-ops-into-accel-lifecy.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch414: kvm-hw-arm-virt-Use-stored-SMMUv3-device-list-for-IORT-b.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch415: kvm-hw-arm-tegra241-cmdqv-Probe-host-Tegra241-CMDQV-supp.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch416: kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-init.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch417: kvm-hw-arm-virt-Link-SMMUv3-CMDQV-resources-to-platform-.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch418: kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-vIOMMU-alloc-f.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch419: kvm-hw-arm-tegra241-cmdqv-mmap-host-VINTF-Page0-for-CMDQ.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch420: kvm-hw-arm-tegra241-cmdqv-Emulate-CMDQ-V-Config-region.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch421: kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-reads.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch422: kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-writes.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch423: kvm-hw-arm-tegra241-cmdqv-Allocate-HW-VCMDQs-once-config.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch424: kvm-hw-arm-tegra241-cmdqv-Route-allocated-VCMDQ-Page0-ac.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch425: kvm-memory-Allow-RAM-device-regions-to-skip-IOMMU-mappin.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch426: kvm-hw-arm-tegra241-cmdqv-Use-mmap-d-host-VINTF-page0-fo.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch427: kvm-hw-arm-smmuv3-accel-Introduce-common-helper-for-veve.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch428: kvm-hw-arm-tegra241-cmdqv-Read-and-propagate-Tegra241-CM.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch429: kvm-hw-arm-tegra241-cmdqv-Initialize-register-state-on-r.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch430: kvm-hw-arm-tegra241-cmdqv-Limit-queue-size-based-on-back.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch431: kvm-hw-arm-smmuv3-Add-per-device-identifier-property.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch432: kvm-hw-arm-smmuv3-accel-Introduce-helper-to-query-CMDQV-.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch433: kvm-hw-arm-virt-acpi-Advertise-Tegra241-CMDQV-nodes-in-D.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch434: kvm-hw-arm-smmuv3-accel-Enforce-viommu-association-when-.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch435: kvm-hw-arm-tegra241-cmdqv-Document-the-CMDQV-design-and-.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch436: kvm-hw-arm-smmuv3-Add-cmdqv-property-for-SMMUv3-device.patch
+# For RHEL-142465 - [RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus
+# For RHEL-160190 - NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3
+# For RHEL-163596 - NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3
+# For RHEL-73794 - NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1
+# For RHEL-73796 - NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1
+# For RHEL-73798 - NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1
+Patch437: kvm-rh-aarch64-rh-devices.mak-Add-CONFIG_TEGRA241_CMDQV.patch
%if %{have_clang}
BuildRequires: clang
@@ -1148,6 +1930,9 @@ This package provides the additional D-Bus audio driver for QEMU.
%setup -q -n qemu-%{version}%{?rcstr}
%autopatch -p1
+# Handling binary changes for MR 505
+cp %{SOURCE40} %{SOURCE41} %{SOURCE42} %{SOURCE43} tests/data/acpi/aarch64/virt/
+
%global qemu_kvm_build qemu_kvm_build
mkdir -p %{qemu_kvm_build}
@@ -1888,6 +2673,131 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
%endif
%changelog
+* Mon Jun 29 2026 Miroslav Rezanina <mrezanin@redhat.com> - 10.1.0-23
+- kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vio.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vde.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmu-common-Factor-out-common-helper-function.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmu-add-memory-regions-as-property-for-an-SM.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Extract-common-definitions-to-smmuv3-c.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmu-common-Make-iommu-ops-part-of-SMMUState.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Introduce-smmuv3-accel-device.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Initialize-shared-system-address.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-pci-Move-pci_init_bus_master-after-adding-dev.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-Export-pci_device_get_iommu_bus_devfn-and-ret.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-pci-Add-optional-supports_address_space-callb.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-bridge-pci_expander_bridge-Move-TYPE_PXB_PCIE.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Restrict-accelerated-SMMUv3-to-v.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Implement-get_viommu_cap-callback.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-Introduce-pci_device_get_viommu_flags.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-Introduce-pci_device_get_host_iommu_quirks.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-common-Define-STE-CD-fields-via-regist.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-common-Add-NSCFG-bit-definition-for-CD.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-common-Add-STE-CD-set-helpers-for-repe.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Add-set-unset_iommu_device-callb.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-propagate-smmuv3_cmdq_consume-errors-t.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Add-nested-vSTE-install-uninstal.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Install-SMMUv3-GBPA-based-hwpt.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-pci-Introduce-a-callback-to-retrieve-the-MSI-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Implement-get_msi_direct_gpa-cal.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-virt-Set-msi-gpa-property.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Add-support-to-issue-invalidatio.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Initialize-ID-registers-early-during-r.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Get-host-SMMUv3-hw-info-and-vali.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-host-gpex-Allow-to-generate-preserve-boot-con.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-virt-Set-PCI-preserve_config-for-accel-SMMUv3.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-tests-qtest-bios-tables-test-Prepare-for-IORT-reviso.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-virt-acpi-build-Add-IORT-RMR-regions-to-handl.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-tests-qtest-bios-tables-test-Update-IORT-blobs-after.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Block-migration-when-accel-is-enabled.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Add-accel-property-for-SMMUv3-device.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Add-a-property-to-specify-RIL-su.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Add-support-for-ATS.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Add-property-to-specify-OAS-bits.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-backends-iommufd-Retrieve-PASID-width-from-iommufd_b.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-backends-iommufd-Add-get_pasid_info-callback.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-Add-helper-to-insert-PCIe-extended-capability.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-Factor-out-common-PASID-capability-initializa.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-vfio-pci-Synthesize-PASID-capability-for-vfio-pci.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Make-SubstreamID-support-configu.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-system-memory-Factor-address_space_is_io-out.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-target-i386-arch_memory_mapping-Use-address_space_me.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-s390x-sclp-Use-address_space_memory_is_io-in-sclp.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-system-physmem-Remove-cpu_physical_memory_is_io.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-backends-iommufd-Introduce-iommufd_backend_alloc_vev.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Add-viommu-free-helper.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Allocate-vEVENTQ-for-accelerated.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Introduce-a-helper-function-for-event-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Read-and-propagate-host-vIOMMU-e.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Correct-SMMUEN-field-name-in-CR0.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Fix-CFGI_CD-handling-when-stage-1-is-u.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Check-ATS-compatibility-between-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Change-ats-property-type-to-OnOf.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Change-ril-property-type-to-OnOf.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-qdev-Add-a-SsidSizeMode-property-type.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Change-ssidsize-property-type-to.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-qdev-Add-an-OasMode-property-type.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Change-oas-property-type-to-OasM.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-qemu-options.hx-Document-arm-smmuv3-device-s-accel-p.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Have-smmuv3_accel_init-take-an-Error-p.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Update-ATC-invalidation-check.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Improve-accel-SMMUv3-usage-documentati.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Add-helper-for-resolving-auto-pa.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ats.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ril.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-ssidsiz.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Implement-auto-value-for-oas.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Set-default-ats-ril-ssidsize-oas-to-au.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-qemu-options.hx-Support-auto-for-accel-SMMUv3-proper.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-pci-pci-Enforce-pci_setup_iommu_per_bus-is-called.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-vfio-iommufd-Force-creating-nesting-parent-HWPT.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-vfio-iommufd-Control-dirty-tracking-for-nesting-p.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-backends-iommufd-Update-iommufd_backend_get_device_i.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-iommufd-Rename-all-the-idev-and-idevc-variables-to-h.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-backends-iommufd-Update-iommufd_backend_alloc_viommu.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-backends-iommufd-Introduce-iommufd_backend_alloc_hw_.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-backends-iommufd-Introduce-iommufd_backend_viommu_mm.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-system-iommufd-Remove-unused-viommu-pointer-from-IOM.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Introduce-CMDQV-ops-interface.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Avoid-including-CONFIG_DEVICES-in-hw-h.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Add-Tegra241-CMDQV-ops-backend.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Wire-CMDQV-ops-into-accel-lifecy.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-virt-Use-stored-SMMUv3-device-list-for-IORT-b.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Probe-host-Tegra241-CMDQV-supp.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-init.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-virt-Link-SMMUv3-CMDQV-resources-to-platform-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Implement-CMDQV-vIOMMU-alloc-f.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-mmap-host-VINTF-Page0-for-CMDQ.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Emulate-CMDQ-V-Config-region.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-reads.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Emulate-VCMDQ-register-writes.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Allocate-HW-VCMDQs-once-config.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Route-allocated-VCMDQ-Page0-ac.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-memory-Allow-RAM-device-regions-to-skip-IOMMU-mappin.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Use-mmap-d-host-VINTF-page0-fo.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Introduce-common-helper-for-veve.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Read-and-propagate-Tegra241-CM.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Initialize-register-state-on-r.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Limit-queue-size-based-on-back.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Add-per-device-identifier-property.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Introduce-helper-to-query-CMDQV-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-virt-acpi-Advertise-Tegra241-CMDQV-nodes-in-D.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-accel-Enforce-viommu-association-when-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-tegra241-cmdqv-Document-the-CMDQV-design-and-.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-hw-arm-smmuv3-Add-cmdqv-property-for-SMMUv3-device.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- kvm-rh-aarch64-rh-devices.mak-Add-CONFIG_TEGRA241_CMDQV.patch [RHEL-142465 RHEL-160190 RHEL-163596 RHEL-73794 RHEL-73796 RHEL-73798]
+- Resolves: RHEL-142465
+ ([RHEL-10.1][ARM]: Two smmuv3 devices can be attached to the same bus)
+- Resolves: RHEL-160190
+ (NVIDIA:Backport hw/arm/smmuv3-accel: Support AUTO properties - RHEL 10.3)
+- Resolves: RHEL-163596
+ (NVIDIA:Backport hw/arm/smmuv3-accel: Resolve AUTO properties - RHEL 10.3)
+- Resolves: RHEL-73794
+ (NVIDIA:Grace-Hopper:Backport HW accelerated nesting support for arm SMMUv3 - RHEL 10.1)
+- Resolves: RHEL-73796
+ (NVIDIA:Grace-Hopper:Backport vEVENTQ support for smmuv3 - RHEL 10.1)
+- Resolves: RHEL-73798
+ (NVIDIA:Grace-Hopper:Backport CMDQV support - RHEL 10.1)
+
* Tue Jun 23 2026 Miroslav Rezanina <mrezanin@redhat.com> - 10.1.0-22
- kvm-blkdebug-Add-delay-ns-option.patch [RHEL-121686]
- kvm-block-Add-blk_co_start-end_request-and-BDRV_REQ_NO_Q.patch [RHEL-121686]
diff --git a/sources b/sources
index cf81344..5790dab 100644
--- a/sources
+++ b/sources
@@ -1 +1,5 @@
SHA512 (qemu-10.1.0.tar.xz) = 20552a524b6b298181df1af7084b470ded3fe8d1505f05011dda3c33cbc3d91f518ce026b44ba1a8b7f34c64ae81afddceda383066f4772a3a2a6333a2638caf
+SHA512 (IORT) = d07279b02ce160141428bbc256ffe89fa7260cf7fcd8d4111ea59a1ae4e9f7aa6a2a94b6094f4fb26c08ccee3ca8cad467e8bd138bf908207e73af78bfc7e564
+SHA512 (IORT.its_off) = d514bd995e380762c27593e6769a2bf92b0fdbc4a187a134f6f41e2f87a8824a7c6fa993362ab7ec846628dcc0ad5e18000f60f2f5a3e30f1ed1131474e71983
+SHA512 (IORT.smmuv3-dev) = 432480e3992e5e7a2c6258e0ef6fd094eae13e9e76f8cbe4ee93bd10944fb6c07ce94fa25f9704741c9e6ccf6d99a867008453cb0815bb9517680b662f7f1a5e
+SHA512 (IORT.smmuv3-legacy) = 39609d956ae643fe17a4a1a5a0eed11326874982a2646c7337e21e994c8ff6c1ce08bf27396b5db74430a420e6cc628005a75ee7697c3c2dc829882dbe107b95
reply other threads:[~2026-06-30 15:09 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178283214486.1.12847396152023937975.rpms-qemu-3177ce9841a3@fedoraproject.org \
--to=mrezanin@redhat.com \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox