From 92b97fee789287a62e8a9b20775320283ed03c74 Mon Sep 17 00:00:00 2001 From: Sudarshan Rajagopalan Date: Thu, 19 Dec 2019 18:03:43 -0800 Subject: [PATCH] iommu/arm-smmu: avoid possible deadlock during map_sg A possible deadlock could occur with the following flow: arm_smmu_map_sg() -->arm_smmu_secure_domain_lock() -->ops->map_sg() //this returns an error with ret = 0 -->size_to_unmap = iova + size - __saved_iova_start; -->goto out; -->arm_smmu_assign_table() -->arm_smmu_unmap() ---->arm_smmu_secure_domain_lock() //DEADLOCKed!!!!! -------->mutex_lock() The secure domain lock is needed to protect hyp assign and unassign. Hence, its safe to call arm_smmu_secure_domain_unlock() after the map and assign is done. Do this to avoid any runtime deadlocks. Change-Id: I35effc170d8432d32c0cab3081be4897830d9212 Signed-off-by: Sudarshan Rajagopalan Signed-off-by: Isaac J. Manjarres --- drivers/iommu/arm-smmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index ea445d8fe7f3..08016ea62bee 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -3046,12 +3046,12 @@ static size_t arm_smmu_map_sg(struct iommu_domain *domain, unsigned long iova, out: arm_smmu_assign_table(smmu_domain); + arm_smmu_secure_domain_unlock(smmu_domain); if (size_to_unmap) { arm_smmu_unmap(domain, __saved_iova_start, size_to_unmap, NULL); iova = __saved_iova_start; } - arm_smmu_secure_domain_unlock(smmu_domain); return iova - __saved_iova_start; }