summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhenhao Wan <whi4ed0g@gmail.com>2026-08-11 22:28:50 +0800
committerDanilo Krummrich <dakr@kernel.org>2026-09-01 11:09:24 +0200
commitcaa1bc2a0a6ca19dcb90bbf88208b0fe2decd66f (patch)
treeb658009cab89d1535641f1f9377a12ff38de33c5
parentdeced5fa01c5e9813384b6c176379e5baaf5ec10 (diff)
downloadlinux-next-caa1bc2a0a6ca19dcb90bbf88208b0fe2decd66f.tar.gz
linux-next-caa1bc2a0a6ca19dcb90bbf88208b0fe2decd66f.zip
drm/nouveau/dmem: fix mismatched DMA unmap size for large folios
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 <danisjiang@gmail.com> Assisted-by: Claude:claude-opus-5 Cc: stable@vger.kernel.org Signed-off-by: Zhenhao Wan <whi4ed0g@gmail.com> Link: https://patch.msgid.link/20260811-b4-nouveau-dmem-thp-fixes-v1-1-2cdf9860af2a@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dmem.c4
1 files 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: