* [PATCH v2 1/2] drm/nouveau/instmem/gk20a: fix overflow in IOVA calculation for iommu_map/unmap
@ 2025-06-05 20:19 Alexey Nepomnyashih
2025-06-05 20:19 ` [PATCH v2 2/2] drm/nouveau/instmem/gk20a: fix incorrect argument in iommu_unmap Alexey Nepomnyashih
0 siblings, 1 reply; 2+ messages in thread
From: Alexey Nepomnyashih @ 2025-06-05 20:19 UTC (permalink / raw)
To: Lyude Paul
Cc: Alexey Nepomnyashih, Danilo Krummrich, David Airlie,
Simona Vetter, Maxime Coquelin, Alexandre Torgue, dri-devel,
nouveau, linux-stm32, linux-arm-kernel, linux-kernel,
lvc-project, stable
Fix possible overflow in the address expression used as the second
argument to iommu_map() and iommu_unmap(). Without an explicit cast,
this expression may overflow when 'r->offset' or 'i' are large. Cast
the result to unsigned long before shifting to ensure correct IOVA
computation and prevent unintended wraparound.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Cc: stable@vger.kernel.org # v4.4+
Signed-off-by: Alexey Nepomnyashih <sdl@nppct.ru>
---
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index 201022ae9214..17a0e1a46211 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -334,7 +334,7 @@ gk20a_instobj_dtor_iommu(struct nvkm_memory *memory)
/* Unmap pages from GPU address space and free them */
for (i = 0; i < node->base.mn->length; i++) {
iommu_unmap(imem->domain,
- (r->offset + i) << imem->iommu_pgshift, PAGE_SIZE);
+ ((unsigned long)r->offset + i) << imem->iommu_pgshift, PAGE_SIZE);
dma_unmap_page(dev, node->dma_addrs[i], PAGE_SIZE,
DMA_BIDIRECTIONAL);
__free_page(node->pages[i]);
@@ -472,7 +472,7 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align,
/* Map into GPU address space */
for (i = 0; i < npages; i++) {
- u32 offset = (r->offset + i) << imem->iommu_pgshift;
+ unsigned long offset = ((unsigned long)r->offset + i) << imem->iommu_pgshift;
ret = iommu_map(imem->domain, offset, node->dma_addrs[i],
PAGE_SIZE, IOMMU_READ | IOMMU_WRITE,
--
2.43.0
^ permalink raw reply [flat|nested] 2+ messages in thread* [PATCH v2 2/2] drm/nouveau/instmem/gk20a: fix incorrect argument in iommu_unmap
2025-06-05 20:19 [PATCH v2 1/2] drm/nouveau/instmem/gk20a: fix overflow in IOVA calculation for iommu_map/unmap Alexey Nepomnyashih
@ 2025-06-05 20:19 ` Alexey Nepomnyashih
0 siblings, 0 replies; 2+ messages in thread
From: Alexey Nepomnyashih @ 2025-06-05 20:19 UTC (permalink / raw)
To: Lyude Paul
Cc: Alexey Nepomnyashih, Danilo Krummrich, David Airlie,
Simona Vetter, Maxime Coquelin, Alexandre Torgue, dri-devel,
nouveau, linux-stm32, linux-arm-kernel, linux-kernel,
lvc-project, stable
The unmap logic assumes a fixed step size of PAGE_SIZE, but the
actual IOVA step depends on iommu_pgshift, not PAGE_SHIFT. If
iommu_pgshift > PAGE_SHIFT, this results in mismatched offsets and
causes iommu_unmap() to target incorrect addresses, potentially
leaving mappings intact or corrupting IOMMU state.
Fix this by recomputing the offset per index using the same logic as
in the map loop, ensuring symmetry and correctness.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Cc: stable@vger.kernel.org # v4.3+
Fixes: a7f6da6e758c ("drm/nouveau/instmem/gk20a: add IOMMU support")
Signed-off-by: Alexey Nepomnyashih <sdl@nppct.ru>
---
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index 17a0e1a46211..f58e0d4fb2b1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -481,8 +481,9 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align,
nvkm_error(subdev, "IOMMU mapping failure: %d\n", ret);
while (i-- > 0) {
- offset -= PAGE_SIZE;
- iommu_unmap(imem->domain, offset, PAGE_SIZE);
+ iommu_unmap(imem->domain,
+ ((unsigned long)r->offset + i) << imem->iommu_pgshift,
+ PAGE_SIZE);
}
goto release_area;
}
--
2.43.0
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-06-05 20:19 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-05 20:19 [PATCH v2 1/2] drm/nouveau/instmem/gk20a: fix overflow in IOVA calculation for iommu_map/unmap Alexey Nepomnyashih
2025-06-05 20:19 ` [PATCH v2 2/2] drm/nouveau/instmem/gk20a: fix incorrect argument in iommu_unmap Alexey Nepomnyashih
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®