Device-private THP migration maps migration buffers with page_size()
and records that length in dma_info->size.  For a compound folio
page_size() is PAGE_SIZE << order, but two teardown sites still pass a
literal PAGE_SIZE to dma_unmap_page():

  - nouveau_dmem_migrate_to_ram() on the success path, and
  - nouveau_dmem_migrate_copy_one() on the copy-error path.

For an order > 0 folio this unmaps less than was mapped, leaking the
remainder of the IOMMU/IOVA mapping.  The other unmap sites, in
nouveau_dmem_migrate_chunk() and nouveau_dmem_evict_chunk(), already
use the saved size; use it here too.

Fixes: c32287471077 ("gpu/drm/nouveau: enable THP support for GPU memory 
migration")
Reported-by: Yuhao Jiang <[email protected]>
Assisted-by: Claude:claude-opus-5
Cc: [email protected]
Signed-off-by: Zhenhao Wan <[email protected]>
---
 drivers/gpu/drm/nouveau/nouveau_dmem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c 
b/drivers/gpu/drm/nouveau/nouveau_dmem.c
index 9442ec6e1f6c..d2abee3efb9a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
@@ -267,7 +267,7 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct 
vm_fault *vmf)
        nouveau_fence_new(&fence, dmem->migrate.chan);
        migrate_vma_pages(&args);
        nouveau_dmem_fence_done(&fence);
-       dma_unmap_page(drm->dev->dev, dma_info.dma_addr, PAGE_SIZE,
+       dma_unmap_page(drm->dev->dev, dma_info.dma_addr, dma_info.size,
                                DMA_BIDIRECTIONAL);
 done:
        migrate_vma_finalize(&args);
@@ -772,7 +772,7 @@ static unsigned long nouveau_dmem_migrate_copy_one(struct 
nouveau_drm *drm,
        return mpfn;
 
 out_dma_unmap:
-       dma_unmap_page(dev, dma_info->dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
+       dma_unmap_page(dev, dma_info->dma_addr, dma_info->size, 
DMA_BIDIRECTIONAL);
 out_free_page:
        nouveau_dmem_page_free_locked(drm, dpage);
 out:

-- 
2.34.1

Reply via email to