On 5/19/26 12:37 PM, Shameer Kolothum wrote:
> From: Nicolin Chen <[email protected]>
>
> Once a VCMDQ is allocated, map the mmap'd vintf_page0 region directly
> into the guest-visible MMIO space at offset 0x30000 as a RAM-backed
> MemoryRegion. This eliminates QEMU trapping for hot-path CONS/PROD
> index updates.
>
> After this patch, the two VCMDQ apertures use different access paths:
> the direct aperture (0x10000) remains QEMU-trapped and writes via
> vintf_ptr, while the VI aperture (0x30000) is a direct guest RAM
> mapping. Both paths write to the same underlying vintf_page0 memory,
> so no synchronisation between the apertures is needed.
Please further explain the rationale of having 2 separate paths
Eric
>
> The mapping is installed lazily on first successful VCMDQ hardware
> queue allocation and removed when CMDQV or VINTF is disabled.
>
> Signed-off-by: Nicolin Chen <[email protected]>
> Co-developed-by: Shameer Kolothum <[email protected]>
> Signed-off-by: Shameer Kolothum <[email protected]>
> ---
> hw/arm/tegra241-cmdqv.h | 1 +
> hw/arm/tegra241-cmdqv.c | 39 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 40 insertions(+)
>
> diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
> index 7a8cb2ebc7..e9e1933a19 100644
> --- a/hw/arm/tegra241-cmdqv.h
> +++ b/hw/arm/tegra241-cmdqv.h
> @@ -47,6 +47,7 @@ typedef struct Tegra241CMDQV {
> IOMMUFDVeventq *veventq;
> IOMMUFDHWqueue *vcmdq[TEGRA241_CMDQV_MAX_CMDQ];
> void *vintf_page0;
> + MemoryRegion *mr_vintf_page0;
>
> /* CMDQ-V Config page register cache */
> uint32_t config;
> diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c
> index a7e89905df..853c548e58 100644
> --- a/hw/arm/tegra241-cmdqv.c
> +++ b/hw/arm/tegra241-cmdqv.c
> @@ -18,6 +18,40 @@
> #include "tegra241-cmdqv.h"
> #include "trace.h"
>
> +static void tegra241_cmdqv_guest_unmap_vintf_page0(Tegra241CMDQV *cmdqv)
> +{
> + if (!cmdqv->mr_vintf_page0) {
> + return;
> + }
> +
> + memory_region_del_subregion(&cmdqv->mmio_cmdqv, cmdqv->mr_vintf_page0);
> + object_unparent(OBJECT(cmdqv->mr_vintf_page0));
> + g_free(cmdqv->mr_vintf_page0);
> + cmdqv->mr_vintf_page0 = NULL;
> +}
> +
> +static void tegra241_cmdqv_guest_map_vintf_page0(Tegra241CMDQV *cmdqv)
> +{
> + char *name;
> +
> + if (cmdqv->mr_vintf_page0) {
> + return;
> + }
> +
> + name = g_strdup_printf("%s vintf-page0",
> + memory_region_name(&cmdqv->mmio_cmdqv));
> + cmdqv->mr_vintf_page0 = g_malloc0(sizeof(*cmdqv->mr_vintf_page0));
> + memory_region_init_ram_device_ptr(cmdqv->mr_vintf_page0,
> +
> memory_region_owner(&cmdqv->mmio_cmdqv),
> + name, VINTF_PAGE_SIZE,
> + cmdqv->vintf_page0);
> + memory_region_set_skip_iommu_map(cmdqv->mr_vintf_page0, true);
> + memory_region_add_subregion_overlap(&cmdqv->mmio_cmdqv,
> + CMDQV_VINTF_PAGE0_BASE,
> + cmdqv->mr_vintf_page0, 1);
> + g_free(name);
> +}
> +
> static void tegra241_cmdqv_free_vcmdq(Tegra241CMDQV *cmdqv, int index)
> {
> IOMMUFDViommu *viommu = cmdqv->s_accel->viommu;
> @@ -130,6 +164,9 @@ static bool tegra241_cmdqv_setup_vcmdq(Tegra241CMDQV
> *cmdqv, int index,
> /* Pre-alloc cached writes survive the cache-to-hardware transition. */
> tegra241_cmdqv_sync_vcmdq(cmdqv, index);
>
> + /* Map the mmap'd VINTF page0 into guest MMIO space. */
> + tegra241_cmdqv_guest_map_vintf_page0(cmdqv);
> +
> return true;
> }
>
> @@ -449,6 +486,7 @@ static void
> tegra241_cmdqv_config_vintf_write(Tegra241CMDQV *cmdqv,
> tegra241_cmdqv_setup_all_vcmdq(cmdqv, errp);
I would rather put the tegra241_cmdqv_guest_map_vintf_page0(cmdqv) here
to have symetric map/unmap
> }
> } else {
> + tegra241_cmdqv_guest_unmap_vintf_page0(cmdqv);
> tegra241_cmdqv_free_all_vcmdq(cmdqv);
> tegra241_cmdqv_munmap_vintf_page0(cmdqv, errp);
> cmdqv->vintf_status &= ~R_VINTF0_STATUS_ENABLE_OK_MASK;
> @@ -566,6 +604,7 @@ static void tegra241_cmdqv_writel_mmio(Tegra241CMDQV
> *cmdqv, hwaddr offset,
> */
> tegra241_cmdqv_setup_all_vcmdq(cmdqv, &local_err);
same
> } else {
> + tegra241_cmdqv_guest_unmap_vintf_page0(cmdqv);
> tegra241_cmdqv_free_all_vcmdq(cmdqv);
> cmdqv->status &= ~R_STATUS_CMDQV_ENABLED_MASK;
> }
Thanks
Eric