@samitouri / QOSamiQemu / commits / ab15bda3ac

hw/arm/tegra241-cmdqv: mmap host VINTF Page0 for CMDQV

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>

Nicolin Chen committed Jun 9, 2026 at 12:25 UTC ab15bda3ac1380f63c6e7ae1e80f799cff2a262b
2 files changed +18 -1
hw/arm/tegra241-cmdqv.c
+15 -1
@@ -41,6 +41,10 @@ static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
41 g_free(veventq);
42 cmdqv->veventq = NULL;
43 }
44 + if (cmdqv->vintf_page0) {
45 + munmap(cmdqv->vintf_page0, VINTF_PAGE_SIZE);
46 + cmdqv->vintf_page0 = NULL;
47 + }
48 iommufd_backend_free_id(viommu->iommufd, viommu->viommu_id);
49 }
50
@@ -60,13 +64,20 @@ tegra241_cmdqv_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
64 return false;
65 }
66
67 + if (!iommufd_backend_viommu_mmap(idev->iommufd, viommu_id, VINTF_PAGE_SIZE,
68 + cmdqv->cmdqv_data->out_vintf_mmap_offset,
69 + &cmdqv->vintf_page0, errp)) {
70 + error_append_hint(errp, "Tegra241 CMDQV: failed to mmap VINTF page0");
71 + goto free_viommu;
72 + }
73 +
74 if (!iommufd_backend_alloc_veventq(idev->iommufd, viommu_id,
75 IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV,
76 1 << SMMU_EVENTQS, &veventq_id,
77 &veventq_fd,
78 errp)) {
79 error_append_hint(errp, "Tegra241 CMDQV: failed to alloc veventq");
69 - goto free_viommu;
80 + goto munmap_page0;
81 }
82
83 veventq = g_new(IOMMUFDVeventq, 1);
@@ -77,6 +88,9 @@ tegra241_cmdqv_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
88 *out_viommu_id = viommu_id;
89 return true;
90
91 +munmap_page0:
92 + munmap(cmdqv->vintf_page0, VINTF_PAGE_SIZE);
93 + cmdqv->vintf_page0 = NULL;
94 free_viommu:
95 iommufd_backend_free_id(idev->iommufd, viommu_id);
96 return false;
hw/arm/tegra241-cmdqv.h
+3
@@ -25,6 +25,8 @@
25 */
26 #define TEGRA241_CMDQV_IO_LEN 0x50000
27
28 +#define VINTF_PAGE_SIZE 0x10000
29 +
30 struct iommu_viommu_tegra241_cmdqv;
31
32 typedef struct Tegra241CMDQV {
@@ -33,6 +35,7 @@ typedef struct Tegra241CMDQV {
35 MemoryRegion mmio_cmdqv;
36 qemu_irq irq;
37 IOMMUFDVeventq *veventq;
38 + void *vintf_page0;
39 } Tegra241CMDQV;
40
41 const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);