Allocate a Tegra241 CMDQV type vEVENTQ object so that any host side errors
related to the CMDQV can be received and propagated back to the guest.
Event read and propagation will be added in a later patch.
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
---
hw/arm/tegra241-cmdqv.c | 51 +++++++++++++++++++++++++++++++++++++++++
hw/arm/tegra241-cmdqv.h | 1 +
2 files changed, 52 insertions(+)
diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
index 5e9a980d27..812b027923 100644
--- a/hw/arm/tegra241-cmdqv.c
+++ b/hw/arm/tegra241-cmdqv.c
@@ -136,6 +136,52 @@ static uint64_t tegra241_cmdqv_read_vcmdq(Tegra241CMDQV *cmdqv, hwaddr offset,
return 0;
}
}
+
+static void tegra241_cmdqv_free_veventq(Tegra241CMDQV *cmdqv)
+{
+ SMMUv3State *smmu = cmdqv->smmu;
+ SMMUv3AccelState *s_accel = smmu->s_accel;
+ IOMMUFDViommu *viommu = &s_accel->viommu;
+ IOMMUFDVeventq *veventq = cmdqv->veventq;
+
+ if (!veventq) {
+ return;
+ }
+
+ iommufd_backend_free_id(viommu->iommufd, veventq->veventq_id);
+ g_free(veventq);
+ cmdqv->veventq = NULL;
+}
+
+static bool tegra241_cmdqv_alloc_veventq(Tegra241CMDQV *cmdqv, Error **errp)
+{
+ SMMUv3State *smmu = cmdqv->smmu;
+ SMMUv3AccelState *s_accel = smmu->s_accel;
+ IOMMUFDViommu *viommu = &s_accel->viommu;
+ IOMMUFDVeventq *veventq;
+ uint32_t veventq_id;
+ uint32_t veventq_fd;
+
+ if (cmdqv->veventq) {
+ return true;
+ }
+
+ if (!iommufd_backend_alloc_veventq(viommu->iommufd, viommu->viommu_id,
+ IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV,
+ 1 << 16, &veventq_id, &veventq_fd,
+ errp)) {
+ error_append_hint(errp, "Tegra241 CMDQV: failed to alloc veventq");
+ return false;
+ }
+
+ veventq = g_new(IOMMUFDVeventq, 1);
+ veventq->veventq_id = veventq_id;
+ veventq->veventq_fd = veventq_fd;
+ veventq->viommu = viommu;
+ cmdqv->veventq = veventq;
+ return true;
+}
+
static uint64_t tegra241_cmdqv_read(void *opaque, hwaddr offset, unsigned size)
{
Tegra241CMDQV *cmdqv = (Tegra241CMDQV *)opaque;
@@ -259,11 +305,16 @@ static bool tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
g_free(vcmdq);
}
+ if (!tegra241_cmdqv_alloc_veventq(cmdqv, errp)) {
+ return false;
+ }
+
viommu = &s_accel->viommu;
if (!iommufd_backend_alloc_hw_queue(viommu->iommufd, viommu->viommu_id,
IOMMU_HW_QUEUE_TYPE_TEGRA241_CMDQV,
index, addr, size, &hw_queue_id,
errp)) {
+ tegra241_cmdqv_free_veventq(cmdqv);
return false;
}
hw_queue = g_new(IOMMUFDHWqueue, 1);
diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
index 4972e367f6..ba7f2a0b1b 100644
--- a/hw/arm/tegra241-cmdqv.h
+++ b/hw/arm/tegra241-cmdqv.h
@@ -24,6 +24,7 @@ typedef struct Tegra241CMDQV {
MemoryRegion mmio_vintf_page;
void *vcmdq_page0;
IOMMUFDHWqueue *vcmdq[128];
+ IOMMUFDVeventq *veventq;
/* Register Cache */
uint32_t config;
--
2.43.0
On Wed, Dec 10, 2025 at 01:37:31PM +0000, Shameer Kolothum wrote:
> @@ -259,11 +305,16 @@ static bool tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
> g_free(vcmdq);
> }
>
> + if (!tegra241_cmdqv_alloc_veventq(cmdqv, errp)) {
> + return false;
> + }
> +
I think this should be called in tegra241_cmdqv_alloc_viommu().
FWIW, vEVENTQ is crucial for CMDQV, because VINTF/VCMDQ will not
work if guest OS doesn't recover the HW error correctly.
Nicolin
> -----Original Message-----
> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: 29 December 2025 19:50
> To: Shameer Kolothum <skolothumtho@nvidia.com>
> Cc: qemu-arm@nongnu.org; qemu-devel@nongnu.org;
> eric.auger@redhat.com; peter.maydell@linaro.org; Nathan Chen
> <nathanc@nvidia.com>; Matt Ochs <mochs@nvidia.com>; Jason Gunthorpe
> <jgg@nvidia.com>; jonathan.cameron@huawei.com;
> zhangfei.gao@linaro.org; zhenzhong.duan@intel.com; Krishnakant Jaju
> <kjaju@nvidia.com>
> Subject: Re: [RFC PATCH 10/16] hw/arm/tegra241-cmdqv: Allocate vEVENTQ
> object
>
> On Wed, Dec 10, 2025 at 01:37:31PM +0000, Shameer Kolothum wrote:
> > @@ -259,11 +305,16 @@ static bool
> tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
> > g_free(vcmdq);
> > }
> >
> > + if (!tegra241_cmdqv_alloc_veventq(cmdqv, errp)) {
> > + return false;
> > + }
> > +
>
> I think this should be called in tegra241_cmdqv_alloc_viommu().
Should/Can we? _alloc_viommu() will happen before the Guest boot.
Unlike the SMMUv3 vEVENTQ for accel case, we restrict the hotplug
use case when the tegra214-cmdqv is set. And as soon as Guest setup vCMDQ
the vEVENTQ is enabled here. Do you see any issues with this approach?
Thanks,
Shameer
Thanks,
Shameer
On Tue, Dec 30, 2025 at 01:47:08AM -0800, Shameer Kolothum wrote:
> > From: Nicolin Chen <nicolinc@nvidia.com>
> > Sent: 29 December 2025 19:50
> > To: Shameer Kolothum <skolothumtho@nvidia.com>
> > Cc: qemu-arm@nongnu.org; qemu-devel@nongnu.org;
> > eric.auger@redhat.com; peter.maydell@linaro.org; Nathan Chen
> > <nathanc@nvidia.com>; Matt Ochs <mochs@nvidia.com>; Jason Gunthorpe
> > <jgg@nvidia.com>; jonathan.cameron@huawei.com;
> > zhangfei.gao@linaro.org; zhenzhong.duan@intel.com; Krishnakant Jaju
> > <kjaju@nvidia.com>
> > Subject: Re: [RFC PATCH 10/16] hw/arm/tegra241-cmdqv: Allocate vEVENTQ
> > object
> >
> > On Wed, Dec 10, 2025 at 01:37:31PM +0000, Shameer Kolothum wrote:
> > > @@ -259,11 +305,16 @@ static bool
> > tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
> > > g_free(vcmdq);
> > > }
> > >
> > > + if (!tegra241_cmdqv_alloc_veventq(cmdqv, errp)) {
> > > + return false;
> > > + }
> > > +
> >
> > I think this should be called in tegra241_cmdqv_alloc_viommu().
>
> Should/Can we? _alloc_viommu() will happen before the Guest boot.
I think we can. vEVENTQ only needs vIOMMU ID. It's per VINTF v.s.
per VCMDQ (HW_QUEUE). So, it should follow vIOMMU.
Basically, we can allocate vIOMMU (VINTF) and its vEVENTQ even if
the VINTF doesn't contain any LVCMDQs, which are allocated/mapped
to the VINTF later via HW_QUEUE allocations.
> Unlike the SMMUv3 vEVENTQ for accel case, we restrict the hotplug
> use case when the tegra214-cmdqv is set. And as soon as Guest setup vCMDQ
> the vEVENTQ is enabled here. Do you see any issues with this approach?
Once guest OS is booting, !tegra241_cmdqv_alloc_veventq will fail
tegra241_cmdqv_setup_vcmdq while it cannot break the guest OS any
more. Then, the whole thing wouldn't work although guest OS runs?
Nicolin
> -----Original Message-----
> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: 30 December 2025 17:54
> To: Shameer Kolothum <skolothumtho@nvidia.com>
> Cc: qemu-arm@nongnu.org; qemu-devel@nongnu.org;
> eric.auger@redhat.com; peter.maydell@linaro.org; Nathan Chen
> <nathanc@nvidia.com>; Matt Ochs <mochs@nvidia.com>; Jason Gunthorpe
> <jgg@nvidia.com>; jonathan.cameron@huawei.com;
> zhangfei.gao@linaro.org; zhenzhong.duan@intel.com; Krishnakant Jaju
> <kjaju@nvidia.com>
> Subject: Re: [RFC PATCH 10/16] hw/arm/tegra241-cmdqv: Allocate vEVENTQ
> object
>
> On Tue, Dec 30, 2025 at 01:47:08AM -0800, Shameer Kolothum wrote:
> > > From: Nicolin Chen <nicolinc@nvidia.com>
> > > Sent: 29 December 2025 19:50
> > > To: Shameer Kolothum <skolothumtho@nvidia.com>
> > > Cc: qemu-arm@nongnu.org; qemu-devel@nongnu.org;
> > > eric.auger@redhat.com; peter.maydell@linaro.org; Nathan Chen
> > > <nathanc@nvidia.com>; Matt Ochs <mochs@nvidia.com>; Jason
> Gunthorpe
> > > <jgg@nvidia.com>; jonathan.cameron@huawei.com;
> > > zhangfei.gao@linaro.org; zhenzhong.duan@intel.com; Krishnakant Jaju
> > > <kjaju@nvidia.com>
> > > Subject: Re: [RFC PATCH 10/16] hw/arm/tegra241-cmdqv: Allocate
> vEVENTQ
> > > object
> > >
> > > On Wed, Dec 10, 2025 at 01:37:31PM +0000, Shameer Kolothum wrote:
> > > > @@ -259,11 +305,16 @@ static bool
> > > tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
> > > > g_free(vcmdq);
> > > > }
> > > >
> > > > + if (!tegra241_cmdqv_alloc_veventq(cmdqv, errp)) {
> > > > + return false;
> > > > + }
> > > > +
> > >
> > > I think this should be called in tegra241_cmdqv_alloc_viommu().
> >
> > Should/Can we? _alloc_viommu() will happen before the Guest boot.
>
> I think we can. vEVENTQ only needs vIOMMU ID. It's per VINTF v.s.
> per VCMDQ (HW_QUEUE). So, it should follow vIOMMU.
>
> Basically, we can allocate vIOMMU (VINTF) and its vEVENTQ even if
> the VINTF doesn't contain any LVCMDQs, which are allocated/mapped
> to the VINTF later via HW_QUEUE allocations.
But what happens when you receive an event from host during that time?
Should we just ignore it? Or is that not possible at all from a hoist driver
perspective? To me, it looks like the natural flow is setup vEVENTQ when
Guest is ready to receive the events.
> > Unlike the SMMUv3 vEVENTQ for accel case, we restrict the hotplug
> > use case when the tegra214-cmdqv is set. And as soon as Guest setup
> vCMDQ
> > the vEVENTQ is enabled here. Do you see any issues with this approach?
>
> Once guest OS is booting, !tegra241_cmdqv_alloc_veventq will fail
> tegra241_cmdqv_setup_vcmdq while it cannot break the guest OS any
> more. Then, the whole thing wouldn't work although guest OS runs?
If vEVENTQ is mandatory we could exit the Guest with a proper msg in
case tegra241_cmdqv_alloc_veventq() fails, right?
Thanks,
Shameer
>
On Tue, Dec 30, 2025 at 10:10:48AM -0800, Shameer Kolothum wrote:
> > > > On Wed, Dec 10, 2025 at 01:37:31PM +0000, Shameer Kolothum wrote:
> > > > > @@ -259,11 +305,16 @@ static bool
> > > > tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
> > > > > g_free(vcmdq);
> > > > > }
> > > > >
> > > > > + if (!tegra241_cmdqv_alloc_veventq(cmdqv, errp)) {
> > > > > + return false;
> > > > > + }
> > > > > +
> > > >
> > > > I think this should be called in tegra241_cmdqv_alloc_viommu().
> > >
> > > Should/Can we? _alloc_viommu() will happen before the Guest boot.
> >
> > I think we can. vEVENTQ only needs vIOMMU ID. It's per VINTF v.s.
> > per VCMDQ (HW_QUEUE). So, it should follow vIOMMU.
> >
> > Basically, we can allocate vIOMMU (VINTF) and its vEVENTQ even if
> > the VINTF doesn't contain any LVCMDQs, which are allocated/mapped
> > to the VINTF later via HW_QUEUE allocations.
>
> But what happens when you receive an event from host during that time?
> Should we just ignore it? Or is that not possible at all from a hoist driver
> perspective? To me, it looks like the natural flow is setup vEVENTQ when
> Guest is ready to receive the events.
I don't think that will happen. The IRQ register for VINTF/vIOMMU
is LVCMDQ_ERR_MAP. If there is no HW_QUEUE allocated to the VINTF,
there shouldn't be a vEVENT. Otherwise, it would be a kernel bug,
IMHO.
> > > Unlike the SMMUv3 vEVENTQ for accel case, we restrict the hotplug
> > > use case when the tegra214-cmdqv is set. And as soon as Guest setup
> > vCMDQ
> > > the vEVENTQ is enabled here. Do you see any issues with this approach?
> >
> > Once guest OS is booting, !tegra241_cmdqv_alloc_veventq will fail
> > tegra241_cmdqv_setup_vcmdq while it cannot break the guest OS any
> > more. Then, the whole thing wouldn't work although guest OS runs?
>
> If vEVENTQ is mandatory we could exit the Guest with a proper msg in
> case tegra241_cmdqv_alloc_veventq() fails, right?
I don't know. But that doesn't sound right to me. In my mind, once
the guest OS is booting, it could only stop with something like a
blue screen..
Maybe QEMU experts can shed some light here.
Nicolin
> -----Original Message-----
> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: 30 December 2025 18:22
> To: Shameer Kolothum <skolothumtho@nvidia.com>
> Cc: qemu-arm@nongnu.org; qemu-devel@nongnu.org;
> eric.auger@redhat.com; peter.maydell@linaro.org; Nathan Chen
> <nathanc@nvidia.com>; Matt Ochs <mochs@nvidia.com>; Jason Gunthorpe
> <jgg@nvidia.com>; jonathan.cameron@huawei.com;
> zhangfei.gao@linaro.org; zhenzhong.duan@intel.com; Krishnakant Jaju
> <kjaju@nvidia.com>
> Subject: Re: [RFC PATCH 10/16] hw/arm/tegra241-cmdqv: Allocate vEVENTQ
> object
>
> On Tue, Dec 30, 2025 at 10:10:48AM -0800, Shameer Kolothum wrote:
> > > > > On Wed, Dec 10, 2025 at 01:37:31PM +0000, Shameer Kolothum
> wrote:
> > > > > > @@ -259,11 +305,16 @@ static bool
> > > > > tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV *cmdqv, int index,
> > > > > > g_free(vcmdq);
> > > > > > }
> > > > > >
> > > > > > + if (!tegra241_cmdqv_alloc_veventq(cmdqv, errp)) {
> > > > > > + return false;
> > > > > > + }
> > > > > > +
> > > > >
> > > > > I think this should be called in tegra241_cmdqv_alloc_viommu().
> > > >
> > > > Should/Can we? _alloc_viommu() will happen before the Guest boot.
> > >
> > > I think we can. vEVENTQ only needs vIOMMU ID. It's per VINTF v.s.
> > > per VCMDQ (HW_QUEUE). So, it should follow vIOMMU.
> > >
> > > Basically, we can allocate vIOMMU (VINTF) and its vEVENTQ even if
> > > the VINTF doesn't contain any LVCMDQs, which are allocated/mapped
> > > to the VINTF later via HW_QUEUE allocations.
> >
> > But what happens when you receive an event from host during that time?
> > Should we just ignore it? Or is that not possible at all from a hoist driver
> > perspective? To me, it looks like the natural flow is setup vEVENTQ when
> > Guest is ready to receive the events.
>
> I don't think that will happen. The IRQ register for VINTF/vIOMMU
> is LVCMDQ_ERR_MAP. If there is no HW_QUEUE allocated to the VINTF,
> there shouldn't be a vEVENT. Otherwise, it would be a kernel bug,
> IMHO.
Ok. That is reassuring then. I will add that as a comment and move it.
> > > > Unlike the SMMUv3 vEVENTQ for accel case, we restrict the hotplug
> > > > use case when the tegra214-cmdqv is set. And as soon as Guest setup
> > > vCMDQ
> > > > the vEVENTQ is enabled here. Do you see any issues with this approach?
> > >
> > > Once guest OS is booting, !tegra241_cmdqv_alloc_veventq will fail
> > > tegra241_cmdqv_setup_vcmdq while it cannot break the guest OS any
> > > more. Then, the whole thing wouldn't work although guest OS runs?
> >
> > If vEVENTQ is mandatory we could exit the Guest with a proper msg in
> > case tegra241_cmdqv_alloc_veventq() fails, right?
>
> I don't know. But that doesn't sound right to me. In my mind, once
> the guest OS is booting, it could only stop with something like a
> blue screen..
>
> Maybe QEMU experts can shed some light here.
I think, generally it is a last resort option and should be avoided.
Thanks,
Shameer
© 2016 - 2026 Red Hat, Inc.