Hi Shameer, On 5/19/26 12:37 PM, Shameer Kolothum wrote: > From: Nicolin Chen <[email protected]> > > CMDQV HW reads guest queue memory by its host physical address set > up via IOMMUFD. This requires the guest queue to be contiguous in > both guest PA and host PA space. With Tegra241 CMDQV enabled, we > must only advertise a command queue size (CMDQS) that the host can > safely back with physically contiguous memory. Allowing a queue size > larger than the host page size could cause the hardware to DMA across > page boundaries, leading to faults. > > Use qemu_ram_backend_pagesize_min() to find the smallest memory- > backend page size in use, then cap IDR1.CMDQS so the guest cannot > configure a command queue that exceeds that contiguous backing. > > Signed-off-by: Nicolin Chen <[email protected]> > Signed-off-by: Shameer Kolothum <[email protected]> > --- > hw/arm/tegra241-cmdqv.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c > index ad64f06260..7f617bcc97 100644 > --- a/hw/arm/tegra241-cmdqv.c > +++ b/hw/arm/tegra241-cmdqv.c > @@ -16,6 +16,8 @@ > #include "hw/arm/smmuv3-common.h" > #include "hw/core/irq.h" > #include "smmuv3-accel.h" > +#include "smmuv3-internal.h" > +#include "system/ramblock.h" > #include "tegra241-cmdqv.h" > #include "trace.h" > > @@ -856,6 +858,8 @@ free_viommu: > static void tegra241_cmdqv_init_regs(SMMUv3State *s, Tegra241CMDQV *cmdqv) > { > int i; > + size_t pgsize; > + uint32_t val; > > cmdqv->config = V_CONFIG_RESET; > cmdqv->param = FIELD_DP32(0, PARAM, CMDQV_VER, CMDQV_VER); > @@ -887,6 +891,19 @@ static void tegra241_cmdqv_init_regs(SMMUv3State *s, > Tegra241CMDQV *cmdqv) > cmdqv->vcmdq_base[i] = 0; > cmdqv->vcmdq_cons_indx_base[i] = 0; > } > + > + /* > + * CMDQ must not cross a physical RAM backend page. Adjust CMDQS so the > + * queue fits entirely within the smallest backend page size, ensuring > + * the command queue is physically contiguous in host memory. > + * > + * IDR1.CMDQS = log2(max_qsz) - entry_shift > + * > + * where entry_shift = 4 (each CMDQ entry is 16 bytes = 2^4). > + */ > + pgsize = qemu_ram_backend_pagesize_min(); OK I see this is done at init size before we know the GPA. But I meant you may end up with a page size that is suboptimal, no?
Could you elaborate on the actual requirements with regards to huge page usage in this patch and in the cover letter? Thanks Eric > + val = FIELD_EX32(s->idr[1], IDR1, CMDQS); > + s->idr[1] = FIELD_DP32(s->idr[1], IDR1, CMDQS, MIN(ctz64(pgsize) - 4, > val)); > } > > static void tegra241_cmdqv_reset(SMMUv3State *s)
