From: Nicolin Chen <[email protected]> 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. Reviewed-by: Eric Auger <[email protected]> Co-developed-by: Shameer Kolothum <[email protected]> Signed-off-by: Nicolin Chen <[email protected]> Signed-off-by: Shameer Kolothum <[email protected]> --- hw/arm/tegra241-cmdqv.h | 1 + hw/arm/tegra241-cmdqv.c | 48 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h index 030f5758d5..54854421f2 100644 --- a/hw/arm/tegra241-cmdqv.h +++ b/hw/arm/tegra241-cmdqv.h @@ -30,6 +30,7 @@ typedef struct Tegra241CMDQV { SMMUv3AccelState *s_accel; MemoryRegion mmio_cmdqv; qemu_irq irq; + IOMMUFDVeventq *veventq; } Tegra241CMDQV; const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void); diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c index 298671e0ce..6a6cfc2f71 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" @@ -25,13 +26,58 @@ static void tegra241_cmdqv_write_mmio(void *opaque, hwaddr offset, uint64_t valu 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; } -- 2.43.0
