iommu/arm-smmu: Check the return type of map_sg and take appropriate action
We cannot call unmap directly if the map_sg fails partially as the tlb
invalidate functions need to enable/prepare clocks, which require
non-atomic context. Let map_sg return the failure and handle this when
we are out of the atomic context.
Change-Id: I6401c1e281850aeda27e32524cae34324045f762
Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 2d412c4..597923b 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1606,6 +1606,7 @@
struct scatterlist *sg, unsigned int nents, int prot)
{
int ret;
+ size_t size;
unsigned long flags;
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
@@ -1614,8 +1615,12 @@
return -ENODEV;
spin_lock_irqsave(&smmu_domain->pgtbl_lock, flags);
- ret = ops->map_sg(ops, iova, sg, nents, prot);
+ ret = ops->map_sg(ops, iova, sg, nents, prot, &size);
spin_unlock_irqrestore(&smmu_domain->pgtbl_lock, flags);
+
+ if (!ret)
+ arm_smmu_unmap(domain, iova, size);
+
return ret;
}