Hi Shameer,
On 6/9/26 1:25 PM, Shameer Kolothum wrote:
> 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]>
Reviewed-by: Eric Auger <[email protected]>
Thanks
Eric
> ---
> 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;