On Sun, Oct 04, 2026 at 05:22:39PM -0400, Yuho Choi wrote:
> intel_gvt_dma_map_guest_page() unmaps and frees the cache entry of a
> gfn when it is requested with a different size, and maps the page again.
> The entry is still referenced: shadow GTT entries and dma-bufs keep
> using its DMA address after the page is unpinned and the DMA mapping is
> torn down.

I don't think this is *real*, as code would simply destroy entry in
that case, and there won't be on-the-fly dma operation on that, as
guest mem setup is totally before execlist submission, if guest driver
changed mapping by ignoring gvt emulated execlist status, that's just bad...

> When the new mapping gets the same DMA address, their later
> intel_gvt_dma_unmap_guest_page() calls also drop the references of the
> new entry.
> 
> Keep the existing entry instead. A 2M mapping covers a 4K request for
> its first page, so take a reference on it. If the entry is smaller than
> the request, fail and let the caller split the 2M entry into 4K pages,
> as it already does when a 2M mapping cannot be set up.
>

So this change would always force 2M to split into 4K? why?

> Fixes: 7366aeb77cd8 ("drm/i915/gvt: fix incorrect cache entry for guest page 
> mapping")
> Cc: [email protected]
> Signed-off-by: Yuho Choi <[email protected]>
> ---
> Compile-tested only (x86_64 defconfig + DRM_I915_GVT_KVMGT, W=1, sparse).
> 
>  drivers/gpu/drm/i915/gvt/kvmgt.c | 20 ++++++++------------
>  1 file changed, 8 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c 
> b/drivers/gpu/drm/i915/gvt/kvmgt.c
> index ec62db5cc3675..9a3e305253469 100644
> --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
> @@ -1626,19 +1626,15 @@ int intel_gvt_dma_map_guest_page(struct intel_vgpu 
> *vgpu, unsigned long gfn,
>               ret = __gvt_cache_add(vgpu, gfn, *dma_addr, size);
>               if (ret)
>                       goto err_unmap;
> -     } else if (entry->size != size) {
> -             /* the same gfn with different size: unmap and re-map */
> -             gvt_dma_unmap_page(vgpu, gfn, entry->dma_addr, entry->size);
> -             __gvt_cache_remove_entry(vgpu, entry);
> -
> -             ret = gvt_dma_map_page(vgpu, gfn, dma_addr, size);
> -             if (ret)
> -                     goto err_unlock;
> -
> -             ret = __gvt_cache_add(vgpu, gfn, *dma_addr, size);
> -             if (ret)
> -                     goto err_unmap;
> +     } else if (entry->size < size) {
> +             /*
> +              * The smaller mapping may still be in use, so don't replace
> +              * it. Fail and let the caller map the range in smaller pages.
> +              */
> +             ret = -EBUSY;
> +             goto err_unlock;
>       } else {
> +             /* A mapping of the same or a larger size covers the request */
>               kref_get(&entry->ref);
>               *dma_addr = entry->dma_addr;
>       }
> 
> base-commit: 7704c4c5bb127673b4f0ead839919db573559e38
> -- 
> 2.43.0

Reply via email to