linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
@ 2024-02-02 14:28 Jason Gunthorpe
  2024-02-03  8:02 ` Michael Shavit
  2024-02-08 12:58 ` Will Deacon
  0 siblings, 2 replies; 13+ messages in thread
From: Jason Gunthorpe @ 2024-02-02 14:28 UTC (permalink / raw)
  To: iommu, Joerg Roedel, linux-arm-kernel, Robin Murphy
  Cc: Dan Carpenter, Michael Shavit, Nicolin Chen, patches, Will Deacon

If the SMMU is configured to use a two level CD table then
arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
GFP_KERNEL. Due to recent changes this is being done under a spinlock to
iterate over the device list - thus it will trigger a sleeping while
atomic warning:

  arm_smmu_sva_set_dev_pasid()
    mutex_lock(&sva_lock);
    __arm_smmu_sva_bind()
     arm_smmu_mmu_notifier_get()
      spin_lock_irqsave()
      arm_smmu_write_ctx_desc()
	arm_smmu_get_cd_ptr()
         arm_smmu_alloc_cd_leaf_table()
	  dmam_alloc_coherent(GFP_KERNEL)

This is a 64K high order allocation and really should not be done
atomically.

The proper answer is to sequence CD programming in a way that does not
require the device list or a spinlock. Part two of my lager series does
this and already solves this bug.

In the mean time we can solve the functional issue by preallocating the CD
entry outside any locking. CD leafs are effectively never freed so this
guarantees the arm_smmu_write_ctx_desc() inside the lock will not take the
allocation path.

Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56@moroto.mountain/
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 5 +++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c     | 2 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h     | 2 ++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index 05722121f00e70..068d60732e6481 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -588,6 +588,11 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
 {
 	int ret = 0;
 	struct mm_struct *mm = domain->mm;
+	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+
+	/* Preallocate the required leafs outside locks */
+	if (!arm_smmu_get_cd_ptr(master, id))
+		return -ENOMEM;
 
 	mutex_lock(&sva_lock);
 	ret = __arm_smmu_sva_bind(dev, mm);
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 0ffb1cf17e0b2e..ec2bb8685bb50e 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1019,7 +1019,7 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst,
 	WRITE_ONCE(*dst, cpu_to_le64(val));
 }
 
-static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
+__le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
 {
 	__le64 *l1ptr;
 	unsigned int idx;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 65fb388d51734d..fa0eeb3519ef28 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -748,6 +748,8 @@ extern struct xarray arm_smmu_asid_xa;
 extern struct mutex arm_smmu_asid_lock;
 extern struct arm_smmu_ctx_desc quiet_cd;
 
+__le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid);
+
 int arm_smmu_write_ctx_desc(struct arm_smmu_master *smmu_master, int ssid,
 			    struct arm_smmu_ctx_desc *cd);
 void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);

base-commit: c76c50cd425e574df5a071cd7e1805d0764aabff
-- 
2.43.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2024-02-15 11:38 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-02 14:28 [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock Jason Gunthorpe
2024-02-03  8:02 ` Michael Shavit
2024-02-08 12:58 ` Will Deacon
2024-02-08 14:27   ` Jason Gunthorpe
2024-02-13 11:20     ` Will Deacon
2024-02-13 12:18       ` Jason Gunthorpe
2024-02-13 12:54         ` Will Deacon
2024-02-13 13:30           ` Jason Gunthorpe
2024-02-13 13:56             ` Will Deacon
2024-02-13 14:00               ` Jason Gunthorpe
2024-02-14 17:00                 ` Will Deacon
2024-02-14 19:09                   ` Jason Gunthorpe
2024-02-15 11:38                     ` Will Deacon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).