On 25/06/2026 2:43 pm, Krzysztof Karas wrote:
Currently, if iommu maps fewer bytes than requested (iova_len),
it proceeds to free the iova, but never tries to unmap already
touched bytes. This behavior may cause memory hogging down the
line.
Huh? iommu_map_sg() has always unmapped internally upon any error - can
you clarify how you've seen it returning a short mapping in a non-error
case?
Thanks,
Robin.
Correct that by unmapping before exiting.
Signed-off-by: Krzysztof Karas <[email protected]>
---
drivers/iommu/dma-iommu.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 381b60d9e7ce..c4c058ba07ef 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -1515,8 +1515,14 @@ int iommu_dma_map_sg(struct device *dev, struct
scatterlist *sg, int nents,
* implementation - it knows better than we do.
*/
ret = iommu_map_sg(domain, iova, sg, nents, prot, GFP_ATOMIC);
- if (ret < 0 || ret < iova_len)
+ if (ret < 0 || ret < iova_len) {
+ if (ret > 0) {
+ /* Unmap partially mapped bytes before freeing IOVA */
+ if (iommu_unmap(domain, iova, ret) != ret)
+ ret = -EIO;
+ }
goto out_free_iova;
+ }
return __finalise_sg(dev, sg, nents, iova);
@@ -1525,7 +1531,7 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
out_restore_sg:
__invalidate_sg(sg, nents);
out:
- if (ret != -ENOMEM && ret != -EREMOTEIO)
+ if (ret != -ENOMEM && ret != -EREMOTEIO && ret != -EIO)
return -EINVAL;
return ret;
}