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)


Reply via email to