All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shameer Kolothum <skolothumtho@nvidia.com>
To: <qemu-arm@nongnu.org>, <qemu-devel@nongnu.org>
Cc: <eric.auger@redhat.com>, <peter.maydell@linaro.org>,
	<clg@redhat.com>, <alex@shazbot.org>, <nicolinc@nvidia.com>,
	<nathanc@nvidia.com>, <mochs@nvidia.com>, <jan@nvidia.com>,
	<jgg@nvidia.com>, <jonathan.cameron@huawei.com>,
	<zhangfei.gao@linaro.org>, <zhenzhong.duan@intel.com>,
	<kjaju@nvidia.com>, <phrdina@redhat.com>,
	<skolothumtho@nvidia.com>
Subject: [PATCH v3 19/32] hw/arm/tegra241-cmdqv: Allocate HW VCMDQs on base register programming
Date: Thu, 26 Feb 2026 10:50:43 +0000	[thread overview]
Message-ID: <20260226105056.897-20-skolothumtho@nvidia.com> (raw)
In-Reply-To: <20260226105056.897-1-skolothumtho@nvidia.com>

From: Nicolin Chen <nicolinc@nvidia.com>

Add support for allocating IOMMUFD hardware queues when the guest
programs the VCMDQ BASE registers.

VCMDQ_EN is part of the VCMDQ_CONFIG register, which is accessed
through the VINTF Page0 region. This region is mapped directly into
the guest address space (introduced in a subsequent patch), so QEMU
does not trap writes to VCMDQ_CONFIG.

Since VCMDQ_EN writes are not trapped, QEMU cannot allocate the
hardware queue based on that bit. Instead, allocate the IOMMUFD
hardware queue when the guest writes a VCMDQ BASE register with a
valid RAM-backed address and when CMDQV and VINTF are enabled.

If a hardware queue was previously allocated for the same VCMDQ,
free it before reallocation.

Writes with invalid addresses are ignored.

All allocated VCMDQs are freed when CMDQV or VINTF is disabled.

Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
---
 hw/arm/tegra241-cmdqv.h | 11 +++++++
 hw/arm/tegra241-cmdqv.c | 71 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
index 3ce9f539ae..139e14b61b 100644
--- a/hw/arm/tegra241-cmdqv.h
+++ b/hw/arm/tegra241-cmdqv.h
@@ -36,6 +36,7 @@ typedef struct Tegra241CMDQV {
     SMMUv3AccelState *s_accel;
     MemoryRegion mmio_cmdqv;
     qemu_irq irq;
+    IOMMUFDHWqueue *vcmdq[TEGRA241_CMDQV_MAX_CMDQ];
     void *vintf_page0;
 
     /* Register Cache */
@@ -322,6 +323,16 @@ A_VI_VCMDQi_CONS_INDX_BASE_DRAM_L(1)
 A_VI_VCMDQi_CONS_INDX_BASE_DRAM_H(0)
 A_VI_VCMDQi_CONS_INDX_BASE_DRAM_H(1)
 
+static inline bool tegra241_cmdq_enabled(Tegra241CMDQV *cmdq)
+{
+    return cmdq->status & R_STATUS_CMDQV_ENABLED_MASK;
+}
+
+static inline bool tegra241_vintf_enabled(Tegra241CMDQV *cmdq)
+{
+    return cmdq->vintf_status & R_VINTF0_STATUS_ENABLE_OK_MASK;
+}
+
 const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
 
 #endif /* HW_ARM_TEGRA241_CMDQV_H */
diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
index a3767a85a3..002dde50fc 100644
--- a/hw/arm/tegra241-cmdqv.c
+++ b/hw/arm/tegra241-cmdqv.c
@@ -151,6 +151,67 @@ static uint64_t tegra241_cmdqv_read(void *opaque, hwaddr offset, unsigned size)
     }
 }
 
+static void tegra241_cmdqv_free_vcmdq(Tegra241CMDQV *cmdqv, int index)
+{
+    SMMUv3AccelState *accel = cmdqv->s_accel;
+    IOMMUFDViommu *viommu = accel->viommu;
+    IOMMUFDHWqueue *vcmdq = cmdqv->vcmdq[index];
+
+    if (!vcmdq) {
+        return;
+    }
+    iommufd_backend_free_id(viommu->iommufd, vcmdq->hw_queue_id);
+    g_free(vcmdq);
+    cmdqv->vcmdq[index] = NULL;
+}
+
+static void tegra241_cmdqv_free_all_vcmdq(Tegra241CMDQV *cmdqv)
+{
+    /* Free in the reverse order to avoid "resource busy" error */
+    for (int i = (TEGRA241_CMDQV_MAX_CMDQ - 1); i >= 0; i--) {
+        tegra241_cmdqv_free_vcmdq(cmdqv, i);
+    }
+}
+
+static bool tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
+                                       Error **errp)
+{
+    SMMUv3AccelState *accel = cmdqv->s_accel;
+    uint64_t base_mask = (uint64_t)R_VCMDQ0_BASE_L_ADDR_MASK |
+                         (uint64_t)R_VCMDQ0_BASE_H_ADDR_MASK << 32;
+    uint64_t addr = cmdqv->vcmdq_base[index] & base_mask;
+    uint64_t log2 = cmdqv->vcmdq_base[index] & R_VCMDQ0_BASE_L_LOG2SIZE_MASK;
+    uint64_t size = 1ULL << (log2 + 4);
+    IOMMUFDViommu *viommu = accel->viommu;
+    IOMMUFDHWqueue *hw_queue;
+    uint32_t hw_queue_id;
+
+    /* Ignore any invalid address. This may come as part of reset etc */
+    if (!address_space_is_ram(&address_space_memory, addr) ||
+        !address_space_is_ram(&address_space_memory, addr + size - 1)) {
+        return true;
+    }
+
+    if (!tegra241_cmdq_enabled(cmdqv) || !tegra241_vintf_enabled(cmdqv)) {
+        return true;
+    }
+
+    tegra241_cmdqv_free_vcmdq(cmdqv, index);
+
+    if (!iommufd_backend_alloc_hw_queue(viommu->iommufd, viommu->viommu_id,
+                                        IOMMU_HW_QUEUE_TYPE_TEGRA241_CMDQV,
+                                        index, addr, size, &hw_queue_id,
+                                        errp)) {
+        return false;
+    }
+    hw_queue = g_new(IOMMUFDHWqueue, 1);
+    hw_queue->hw_queue_id = hw_queue_id;
+    hw_queue->viommu = viommu;
+    cmdqv->vcmdq[index] = hw_queue;
+
+    return true;
+}
+
 static bool
 tegra241_cmdqv_munmap_vintf_page0(Tegra241CMDQV *cmdqv, Error **errp)
 {
@@ -192,7 +253,7 @@ static bool tegra241_cmdqv_mmap_vintf_page0(Tegra241CMDQV *cmdqv, Error **errp)
  */
 static void
 tegra241_cmdqv_write_vcmdq(Tegra241CMDQV *cmdqv, hwaddr offset0, int index,
-                           uint64_t value, unsigned size)
+                           uint64_t value, unsigned size, Error **errp)
 {
     switch (offset0) {
     case A_VCMDQ0_CONS_INDX:
@@ -220,11 +281,13 @@ tegra241_cmdqv_write_vcmdq(Tegra241CMDQV *cmdqv, hwaddr offset0, int index,
                 (cmdqv->vcmdq_base[index] & 0xffffffff00000000ULL) |
                 (value & 0xffffffffULL);
         }
+        tegra241_cmdqv_setup_vcmdq(cmdqv, index, errp);
         return;
     case A_VCMDQ0_BASE_H:
         cmdqv->vcmdq_base[index] =
             (cmdqv->vcmdq_base[index] & 0xffffffffULL) |
             ((uint64_t)value << 32);
+        tegra241_cmdqv_setup_vcmdq(cmdqv, index, errp);
         return;
     case A_VCMDQ0_CONS_INDX_BASE_DRAM_L:
         if (size == 8) {
@@ -263,6 +326,7 @@ static void tegra241_cmdqv_write_vintf(Tegra241CMDQV *cmdqv, hwaddr offset,
             tegra241_cmdqv_mmap_vintf_page0(cmdqv, errp);
             cmdqv->vintf_status |= R_VINTF0_STATUS_ENABLE_OK_MASK;
         } else {
+            tegra241_cmdqv_free_all_vcmdq(cmdqv);
             tegra241_cmdqv_munmap_vintf_page0(cmdqv, errp);
             cmdqv->vintf_status &= ~R_VINTF0_STATUS_ENABLE_OK_MASK;
         }
@@ -302,6 +366,7 @@ static void tegra241_cmdqv_write(void *opaque, hwaddr offset, uint64_t value,
         if (value & R_CONFIG_CMDQV_EN_MASK) {
             cmdqv->status |= R_STATUS_CMDQV_ENABLED_MASK;
         } else {
+            tegra241_cmdqv_free_all_vcmdq(cmdqv);
             cmdqv->status &= ~R_STATUS_CMDQV_ENABLED_MASK;
         }
         break;
@@ -321,7 +386,7 @@ static void tegra241_cmdqv_write(void *opaque, hwaddr offset, uint64_t value,
     case A_VCMDQ0_CONS_INDX ... A_VCMDQ1_GERRORN:
         index = (offset - 0x10000) / 0x80;
         tegra241_cmdqv_write_vcmdq(cmdqv, offset - 0x80 * index, index, value,
-                                   size);
+                                   size, &local_err);
         break;
     case A_VI_VCMDQ0_BASE_L ... A_VI_VCMDQ1_CONS_INDX_BASE_DRAM_H:
         /* Same decoding as read() case: See comments above */
@@ -330,7 +395,7 @@ static void tegra241_cmdqv_write(void *opaque, hwaddr offset, uint64_t value,
     case A_VCMDQ0_BASE_L ... A_VCMDQ1_CONS_INDX_BASE_DRAM_H:
         index = (offset - 0x20000) / 0x80;
         tegra241_cmdqv_write_vcmdq(cmdqv, offset - 0x80 * index, index, value,
-                                   size);
+                                   size, &local_err);
         break;
     default:
         qemu_log_mask(LOG_UNIMP, "%s unhandled write access at 0x%" PRIx64 "\n",
-- 
2.43.0



  parent reply	other threads:[~2026-02-26 10:56 UTC|newest]

Thread overview: 93+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-26 10:50 [PATCH v3 00/32] hw/arm/virt: Introduce Tegra241 CMDQV support for accelerated SMMUv3 Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 01/32] backends/iommufd: Update iommufd_backend_get_device_info Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 02/32] backends/iommufd: Update iommufd_backend_alloc_viommu to allow user ptr Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 03/32] backends/iommufd: Introduce iommufd_backend_alloc_hw_queue Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 04/32] backends/iommufd: Introduce iommufd_backend_viommu_mmap Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 05/32] hw/arm/smmuv3-accel: Introduce CMDQV ops interface Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 06/32] hw/arm/tegra241-cmdqv: Add Tegra241 CMDQV ops backend stub Shameer Kolothum
2026-03-09  9:18   ` Eric Auger
2026-03-09 10:48     ` Shameer Kolothum Thodi
2026-03-09 12:52       ` Eric Auger
2026-03-09 12:59   ` Eric Auger
2026-02-26 10:50 ` [PATCH v3 07/32] hw/arm/smmuv3-accel: Wire CMDQV ops into accel lifecycle Shameer Kolothum
2026-03-09 11:05   ` Eric Auger
2026-02-26 10:50 ` [PATCH v3 08/32] hw/arm/virt: Store SMMUv3 device objects in VirtMachineState Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 09/32] hw/arm/virt-acpi-build: Use stored SMMUv3 devices for IORT build Shameer Kolothum
2026-03-09 10:18   ` Eric Auger
2026-02-26 10:50 ` [PATCH v3 10/32] hw/arm/tegra241-cmdqv: Probe host Tegra241 CMDQV support Shameer Kolothum
2026-03-09 10:31   ` Eric Auger
2026-03-09 10:54     ` Shameer Kolothum Thodi
2026-02-26 10:50 ` [PATCH v3 11/32] hw/arm/tegra241-cmdqv: Implement CMDQV init Shameer Kolothum
2026-03-09 10:44   ` Eric Auger
2026-02-26 10:50 ` [PATCH v3 12/32] hw/arm/virt: Link SMMUv3 CMDQV resources to platform bus Shameer Kolothum
2026-03-09 10:57   ` Eric Auger
2026-02-26 10:50 ` [PATCH v3 13/32] hw/arm/tegra241-cmdqv: Implement CMDQV vIOMMU alloc/free Shameer Kolothum
2026-03-09 11:09   ` Eric Auger
2026-03-09 11:31     ` Shameer Kolothum Thodi
2026-03-09 12:46       ` Eric Auger
2026-03-09 18:09       ` Nicolin Chen
2026-03-09 18:25         ` Shameer Kolothum Thodi
2026-03-09 19:05           ` Nicolin Chen
2026-02-26 10:50 ` [PATCH v3 14/32] hw/arm/tegra241-cmdqv: Emulate global CMDQV registers Shameer Kolothum
2026-03-09 16:33   ` Eric Auger
2026-03-10 11:37     ` Shameer Kolothum Thodi
2026-03-11 10:34       ` Eric Auger
2026-03-09 17:15   ` Eric Auger
2026-03-09 17:56   ` Eric Auger
2026-03-11  7:47   ` Eric Auger
2026-02-26 10:50 ` [PATCH v3 15/32] hw/arm/tegra241-cmdqv: Emulate global and VINTF VCMDQ register reads Shameer Kolothum
2026-02-27 15:58   ` Jonathan Cameron via
2026-02-27 15:58     ` Jonathan Cameron via qemu development
2026-03-09 17:44   ` Eric Auger
2026-03-09 18:04     ` Shameer Kolothum Thodi
2026-03-09 18:40       ` Nicolin Chen
2026-03-09 18:53         ` Shameer Kolothum Thodi
2026-03-09 19:14           ` Nicolin Chen
2026-03-11  9:26   ` Eric Auger
2026-02-26 10:50 ` [PATCH v3 16/32] hw/arm/tegra241-cmdqv: Emulate global and VINTF VCMDQ register writes Shameer Kolothum
2026-03-11 13:32   ` Eric Auger
2026-04-15 13:17     ` Shameer Kolothum Thodi
2026-02-26 10:50 ` [PATCH v3 17/32] hw/arm/tegra241-cmdqv: mmap VINTF Page0 for CMDQV Shameer Kolothum
2026-03-09 17:52   ` Eric Auger
2026-03-11  7:55   ` Eric Auger
2026-03-11  9:26     ` Shameer Kolothum Thodi
2026-03-11 10:05       ` Eric Auger
2026-03-11 12:34         ` Shameer Kolothum Thodi
2026-03-11 13:19           ` Eric Auger
2026-03-11 13:59             ` Shameer Kolothum Thodi
     [not found]               ` <70cab06d-2114-46b6-ab56-403cbd0003e0@redhat.com>
2026-03-12 18:05                 ` Shameer Kolothum Thodi
2026-03-12 21:11                   ` Nicolin Chen
2026-03-11 13:43   ` Eric Auger
2026-03-11 13:59   ` Eric Auger
2026-04-13  6:52     ` Shameer Kolothum Thodi
2026-02-26 10:50 ` [PATCH v3 18/32] system/physmem: Add address_space_is_ram() helper Shameer Kolothum
2026-02-26 10:50 ` Shameer Kolothum [this message]
2026-03-11 14:33   ` [PATCH v3 19/32] hw/arm/tegra241-cmdqv: Allocate HW VCMDQs on base register programming Eric Auger
2026-04-13  7:40     ` Shameer Kolothum Thodi
2026-02-26 10:50 ` [PATCH v3 20/32] hw/arm/tegra241-cmdqv: Use mmap'ed VINTF page0 as VCMDQ backing Shameer Kolothum
2026-03-11 14:52   ` Eric Auger
2026-03-11 15:43     ` Shameer Kolothum Thodi
2026-02-26 10:50 ` [PATCH v3 21/32] hw/arm/tegra241-cmdqv: Map VINTF page0 into guest MMIO space Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 22/32] hw/arm/tegra241-cmdqv: Add vEVENTQ allocation and free Shameer Kolothum
2026-03-09 17:24   ` Nicolin Chen
2026-03-09 17:41     ` Shameer Kolothum Thodi
2026-03-09 19:37       ` Nicolin Chen
2026-02-26 10:50 ` [PATCH v3 23/32] hw/arm/smmuv3-accel: Introduce common helper for veventq read Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 24/32] hw/arm/tegra241-cmdqv: Read and propagate Tegra241 CMDQV errors Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 25/32] hw/arm/tegra241-cmdqv: Add reset handler Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 26/32] hw/arm/tegra241-cmdqv: Limit queue size based on backend page size Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 27/32] tests/qtest/bios-tables-test: Prepare for IORT SMMUv3 node identifier change Shameer Kolothum
2026-03-09 18:06   ` Eric Auger
2026-02-26 10:50 ` [PATCH v3 28/32] hw/arm/smmuv3: Add per-device identifier property Shameer Kolothum
2026-03-09 18:11   ` Eric Auger
2026-03-09 18:22   ` Eric Auger
2026-03-09 18:33     ` Shameer Kolothum Thodi
2026-02-26 10:50 ` [PATCH v3 29/32] tests/qtest/bios-tables-test: Update IORT blobs for SMMUv3 identifier change Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 30/32] hw/arm/smmuv3-accel: Introduce helper to query CMDQV type Shameer Kolothum
2026-03-09 18:05   ` Eric Auger
2026-02-26 10:50 ` [PATCH v3 31/32] hw/arm/virt-acpi: Advertise Tegra241 CMDQV nodes in DSDT Shameer Kolothum
2026-02-26 10:50 ` [PATCH v3 32/32] hw/arm/smmuv3: Add cmdqv property for SMMUv3 device Shameer Kolothum
2026-03-11 18:24 ` [PATCH v3 00/32] hw/arm/virt: Introduce Tegra241 CMDQV support for accelerated SMMUv3 Eric Auger
2026-03-11 18:34   ` Shameer Kolothum Thodi
2026-03-11 20:00     ` Jason Gunthorpe
2026-03-13 11:06       ` Shameer Kolothum Thodi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260226105056.897-20-skolothumtho@nvidia.com \
    --to=skolothumtho@nvidia.com \
    --cc=alex@shazbot.org \
    --cc=clg@redhat.com \
    --cc=eric.auger@redhat.com \
    --cc=jan@nvidia.com \
    --cc=jgg@nvidia.com \
    --cc=jonathan.cameron@huawei.com \
    --cc=kjaju@nvidia.com \
    --cc=mochs@nvidia.com \
    --cc=nathanc@nvidia.com \
    --cc=nicolinc@nvidia.com \
    --cc=peter.maydell@linaro.org \
    --cc=phrdina@redhat.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=zhangfei.gao@linaro.org \
    --cc=zhenzhong.duan@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.