From: Nicolin Chen <[email protected]> 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 <[email protected]> Tested-by: Nicolin Chen <[email protected]> Co-developed-by: Shameer Kolothum <[email protected]> Signed-off-by: Shameer Kolothum <[email protected]> --- hw/arm/tegra241-cmdqv.h | 3 +++ hw/arm/tegra241-cmdqv.c | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) 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); 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; -- 2.43.0
