@samitouri / QOSamiQemu / commits / 43763a1ab7

hw/arm/tegra241-cmdqv: Implement CMDQV vIOMMU alloc/free

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>

Nicolin Chen committed Jun 9, 2026 at 12:25 UTC 43763a1ab76fb618119bb76b0e4a93b599b40f13
2 files changed +48 -1
hw/arm/tegra241-cmdqv.c
+47 -1
@@ -10,6 +10,7 @@
10 #include "qemu/osdep.h"
11
12 #include "hw/arm/smmuv3.h"
13 +#include "hw/arm/smmuv3-common.h"
14 #include "smmuv3-accel.h"
15 #include "tegra241-cmdqv.h"
16
@@ -26,13 +27,58 @@ static void tegra241_cmdqv_write_mmio(void *opaque, hwaddr offset,
27
28 static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
29 {
30 + SMMUv3AccelState *accel = s->s_accel;
31 + IOMMUFDViommu *viommu = accel->viommu;
32 + Tegra241CMDQV *cmdqv = accel->cmdqv;
33 + IOMMUFDVeventq *veventq = cmdqv->veventq;
34 +
35 + if (!viommu) {
36 + return;
37 + }
38 + if (veventq) {
39 + close(veventq->veventq_fd);
40 + iommufd_backend_free_id(viommu->iommufd, veventq->veventq_id);
41 + g_free(veventq);
42 + cmdqv->veventq = NULL;
43 + }
44 + iommufd_backend_free_id(viommu->iommufd, viommu->viommu_id);
45 }
46
47 static bool
48 tegra241_cmdqv_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
49 uint32_t *out_viommu_id, Error **errp)
50 {
35 - error_setg(errp, "NVIDIA Tegra241 CMDQV is unsupported");
51 + Tegra241CMDQV *cmdqv = s->s_accel->cmdqv;
52 + uint32_t viommu_id, veventq_id, veventq_fd;
53 + IOMMUFDVeventq *veventq;
54 +
55 + if (!iommufd_backend_alloc_viommu(idev->iommufd, idev->devid,
56 + IOMMU_VIOMMU_TYPE_TEGRA241_CMDQV,
57 + idev->hwpt_id, cmdqv->cmdqv_data,
58 + sizeof(*cmdqv->cmdqv_data), &viommu_id,
59 + errp)) {
60 + return false;
61 + }
62 +
63 + if (!iommufd_backend_alloc_veventq(idev->iommufd, viommu_id,
64 + IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV,
65 + 1 << SMMU_EVENTQS, &veventq_id,
66 + &veventq_fd,
67 + errp)) {
68 + error_append_hint(errp, "Tegra241 CMDQV: failed to alloc veventq");
69 + goto free_viommu;
70 + }
71 +
72 + veventq = g_new(IOMMUFDVeventq, 1);
73 + veventq->veventq_id = veventq_id;
74 + veventq->veventq_fd = veventq_fd;
75 + cmdqv->veventq = veventq;
76 +
77 + *out_viommu_id = viommu_id;
78 + return true;
79 +
80 +free_viommu:
81 + iommufd_backend_free_id(idev->iommufd, viommu_id);
82 return false;
83 }
84
hw/arm/tegra241-cmdqv.h
+1
@@ -32,6 +32,7 @@ typedef struct Tegra241CMDQV {
32 SMMUv3AccelState *s_accel;
33 MemoryRegion mmio_cmdqv;
34 qemu_irq irq;
35 + IOMMUFDVeventq *veventq;
36 } Tegra241CMDQV;
37
38 const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);