All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Fix GPU and display on ARM32 platforms using the MSM IOMMU
@ 2026-07-30 13:29 ` Dmitry Baryshkov
  0 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:29 UTC (permalink / raw)
  To: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On apq8064 (tested on the IFC6410 board) neither the GPU nor the display
controller comes up in mainline: with CONFIG_ARM_DMA_USE_IOMMU enabled
both devices either fail to probe with -EBUSY or take the kernel down
during the ensuing unwind. Three independent problems stack up on that
path, one in each of three subsystems, and only fixing all of them makes
the board usable.

First, the MSM IOMMU driver does not handle a device that is attached to
several IOMMU instances, which is exactly how apq8064 describes both the
GPU (&gfx3d and &gfx3d1) and the display controller (&mdp_port0 and
&mdp_port1). It keyed the per-device bookkeeping off two mismatched
things, a per-IOMMU list and a per-device pointer, so only one of the
instances ever got programmed with the stream IDs. That had been merely
wrong for years, but it turned into a NULL dereference once the IOMMU
core started deferring probe per instance, so today the board does not
even reach a shell with the display enabled.

Second, on ARM32 the arch code gives every IOMMU-backed device a
dma_iommu_mapping of its own and attaches it. drm/msm manages its address
spaces itself and cannot take over a device whose group already has that
foreign domain attached. The other ARM32 DRM drivers that are in the same
position (tegra, rockchip, exynos) drop the arch mapping first; drm/msm
has to do the same.

Third, arm_iommu_detach_device() undoes things in the opposite order from
the one arm_iommu_attach_device() set them up in. An IOMMU driver that
allocates its page tables during attach therefore frees them with the
IOMMU DMA ops installed rather than the direct ops that mapped them,
which ends in a NULL pointer dereference. This is trivially reachable as
soon as any of the probe failures above unwinds, and it is what turns the
GPU probe failure into a crash rather than an error message.

The three patches are independent and are expected to be picked up by
three different maintainers.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Dmitry Baryshkov (3):
      iommu/msm: track a context master per device and IOMMU
      ARM: dma-mapping: reset DMA ops before detaching from the IOMMU
      drm/msm: detach the ARM DMA mapping before attaching our own domain

 arch/arm/mm/dma-mapping.c       |  5 ++++-
 drivers/gpu/drm/msm/msm_iommu.c | 22 ++++++++++++++++++++++
 drivers/iommu/msm_iommu.c       | 27 +++++++++++++++------------
 3 files changed, 41 insertions(+), 13 deletions(-)
---
base-commit: 3652b49adac266a3d27cb41cdfdb7d8790fc3633
change-id: 20260723-fix-qcom-smmu-b5798c65d689
prerequisite-change-id: 20260723-msm-fix-crash-8c13220d9465:v1
prerequisite-patch-id: 3556d41e924ad64e8e9c06cc5bd1972c66957f42

Best regards,
--  
With best wishes
Dmitry


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

* [PATCH 0/3] Fix GPU and display on ARM32 platforms using the MSM IOMMU
@ 2026-07-30 13:29 ` Dmitry Baryshkov
  0 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:29 UTC (permalink / raw)
  To: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On apq8064 (tested on the IFC6410 board) neither the GPU nor the display
controller comes up in mainline: with CONFIG_ARM_DMA_USE_IOMMU enabled
both devices either fail to probe with -EBUSY or take the kernel down
during the ensuing unwind. Three independent problems stack up on that
path, one in each of three subsystems, and only fixing all of them makes
the board usable.

First, the MSM IOMMU driver does not handle a device that is attached to
several IOMMU instances, which is exactly how apq8064 describes both the
GPU (&gfx3d and &gfx3d1) and the display controller (&mdp_port0 and
&mdp_port1). It keyed the per-device bookkeeping off two mismatched
things, a per-IOMMU list and a per-device pointer, so only one of the
instances ever got programmed with the stream IDs. That had been merely
wrong for years, but it turned into a NULL dereference once the IOMMU
core started deferring probe per instance, so today the board does not
even reach a shell with the display enabled.

Second, on ARM32 the arch code gives every IOMMU-backed device a
dma_iommu_mapping of its own and attaches it. drm/msm manages its address
spaces itself and cannot take over a device whose group already has that
foreign domain attached. The other ARM32 DRM drivers that are in the same
position (tegra, rockchip, exynos) drop the arch mapping first; drm/msm
has to do the same.

Third, arm_iommu_detach_device() undoes things in the opposite order from
the one arm_iommu_attach_device() set them up in. An IOMMU driver that
allocates its page tables during attach therefore frees them with the
IOMMU DMA ops installed rather than the direct ops that mapped them,
which ends in a NULL pointer dereference. This is trivially reachable as
soon as any of the probe failures above unwinds, and it is what turns the
GPU probe failure into a crash rather than an error message.

The three patches are independent and are expected to be picked up by
three different maintainers.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Dmitry Baryshkov (3):
      iommu/msm: track a context master per device and IOMMU
      ARM: dma-mapping: reset DMA ops before detaching from the IOMMU
      drm/msm: detach the ARM DMA mapping before attaching our own domain

 arch/arm/mm/dma-mapping.c       |  5 ++++-
 drivers/gpu/drm/msm/msm_iommu.c | 22 ++++++++++++++++++++++
 drivers/iommu/msm_iommu.c       | 27 +++++++++++++++------------
 3 files changed, 41 insertions(+), 13 deletions(-)
---
base-commit: 3652b49adac266a3d27cb41cdfdb7d8790fc3633
change-id: 20260723-fix-qcom-smmu-b5798c65d689
prerequisite-change-id: 20260723-msm-fix-crash-8c13220d9465:v1
prerequisite-patch-id: 3556d41e924ad64e8e9c06cc5bd1972c66957f42

Best regards,
--  
With best wishes
Dmitry


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH 1/3] iommu/msm: track a context master per device and IOMMU
  2026-07-30 13:29 ` Dmitry Baryshkov
@ 2026-07-30 13:29   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:29 UTC (permalink / raw)
  To: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

insert_iommu_master() decided whether to allocate a struct
msm_iommu_ctx_dev by testing whether the IOMMU's ctx_list was empty,
caching the result in dev_iommu_priv, then unconditionally dereferenced
the master:

	master = dev_iommu_priv_get(dev);
	if (list_empty(&(*iommu)->ctx_list)) {
		master = kzalloc_obj(...);
		...
	}
	for (sid = 0; sid < master->num_mids; sid++)

Neither key is right. A master describes one device on one IOMMU
instance: the attach and lookup paths find a device on an IOMMU by
walking that IOMMU's ctx_list for a master whose of_node matches. The
ctx_list emptiness test is per-IOMMU, and the dev_iommu_priv cache is
per-device, so the two disagree as soon as one device spans several
IOMMUs. On apq8064 the GPU uses &gfx3d and &gfx3d1 and the display
controller uses &mdp_port0 and &mdp_port1, each instance carrying the
same stream IDs.

The per-device cache also turns into a NULL dereference. When the first
of a device's IOMMUs registers, iommu_device_register() walks the bus and
drives ->of_xlate(), which links a master onto that IOMMU's ctx_list. The
device cannot finish probing because its second IOMMU is not registered
yet (-EPROBE_DEFER); that tears down dev->iommu and drops the cached
master, but the master stays linked on the first IOMMU's ctx_list. Once
the second IOMMU registers, its bus walk replays of_iommu_configure() for
all of the device's entries, so ->of_xlate() runs again for the first
IOMMU: dev_iommu_priv is NULL while ctx_list is not empty, allocation is
skipped and master->num_mids dereferences NULL:

  qcom_iommu_of_xlate from of_iommu_xlate
  of_iommu_xlate from of_iommu_configure
  of_iommu_configure from platform_dma_configure
  platform_dma_configure from __iommu_probe_device
  __iommu_probe_device from probe_iommu_group
  probe_iommu_group from bus_for_each_dev
  bus_for_each_dev from iommu_device_register
  iommu_device_register from msm_iommu_probe

The faulty guard has been there since the driver gained generic master
bindings, but it stayed dormant for years because a device's ->of_xlate()
only ran once all of its IOMMUs were present. It became reachable when
iommu_fwspec_init() started deferring per instance on the ->ready flag,
which is what lets a master be stranded on the first IOMMU and then have
->of_xlate() replayed with dev_iommu_priv already reset. Hence the two
Fixes below: the first introduced the guard, the second made it fatal.

Look the master up in the target IOMMU's ctx_list instead, allocating one
only when that IOMMU has none for the device yet. Each instance now keeps
its own master and gets programmed with the full set of stream IDs. A
stream ID seen twice is an expected consequence of the replay described
above and is already ignored, so demote that message to dev_dbg().

Fixes: f78ebca8ff3d ("iommu/msm: Add support for generic master bindings")
Fixes: da33e87bd2bf ("iommu: Handle yet another race around registration")
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Assisted-by: Claude:claude-opus-5
---
 drivers/iommu/msm_iommu.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 0ad5ff431d5b..3847f5f0059f 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -601,24 +601,27 @@ static int insert_iommu_master(struct device *dev,
 				struct msm_iommu_dev **iommu,
 				const struct of_phandle_args *spec)
 {
-	struct msm_iommu_ctx_dev *master = dev_iommu_priv_get(dev);
+	struct msm_iommu_ctx_dev *master;
 	int sid;
 
-	if (list_empty(&(*iommu)->ctx_list)) {
-		master = kzalloc_obj(*master, GFP_ATOMIC);
-		if (!master) {
-			dev_err(dev, "Failed to allocate iommu_master\n");
-			return -ENOMEM;
-		}
-		master->of_node = dev->of_node;
-		list_add(&master->list, &(*iommu)->ctx_list);
-		dev_iommu_priv_set(dev, master);
+	/* A master describes one device on one IOMMU instance. */
+	list_for_each_entry(master, &(*iommu)->ctx_list, list)
+		if (master->of_node == dev->of_node)
+			goto add_sid;
+
+	master = kzalloc_obj(*master, GFP_ATOMIC);
+	if (!master) {
+		dev_err(dev, "Failed to allocate iommu_master\n");
+		return -ENOMEM;
 	}
+	master->of_node = dev->of_node;
+	list_add(&master->list, &(*iommu)->ctx_list);
 
+add_sid:
 	for (sid = 0; sid < master->num_mids; sid++)
 		if (master->mids[sid] == spec->args[0]) {
-			dev_warn(dev, "Stream ID 0x%x repeated; ignoring\n",
-				 sid);
+			dev_dbg(dev, "Stream ID 0x%x repeated; ignoring\n",
+				sid);
 			return 0;
 		}
 

-- 
2.47.3


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

* [PATCH 1/3] iommu/msm: track a context master per device and IOMMU
@ 2026-07-30 13:29   ` Dmitry Baryshkov
  0 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:29 UTC (permalink / raw)
  To: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

insert_iommu_master() decided whether to allocate a struct
msm_iommu_ctx_dev by testing whether the IOMMU's ctx_list was empty,
caching the result in dev_iommu_priv, then unconditionally dereferenced
the master:

	master = dev_iommu_priv_get(dev);
	if (list_empty(&(*iommu)->ctx_list)) {
		master = kzalloc_obj(...);
		...
	}
	for (sid = 0; sid < master->num_mids; sid++)

Neither key is right. A master describes one device on one IOMMU
instance: the attach and lookup paths find a device on an IOMMU by
walking that IOMMU's ctx_list for a master whose of_node matches. The
ctx_list emptiness test is per-IOMMU, and the dev_iommu_priv cache is
per-device, so the two disagree as soon as one device spans several
IOMMUs. On apq8064 the GPU uses &gfx3d and &gfx3d1 and the display
controller uses &mdp_port0 and &mdp_port1, each instance carrying the
same stream IDs.

The per-device cache also turns into a NULL dereference. When the first
of a device's IOMMUs registers, iommu_device_register() walks the bus and
drives ->of_xlate(), which links a master onto that IOMMU's ctx_list. The
device cannot finish probing because its second IOMMU is not registered
yet (-EPROBE_DEFER); that tears down dev->iommu and drops the cached
master, but the master stays linked on the first IOMMU's ctx_list. Once
the second IOMMU registers, its bus walk replays of_iommu_configure() for
all of the device's entries, so ->of_xlate() runs again for the first
IOMMU: dev_iommu_priv is NULL while ctx_list is not empty, allocation is
skipped and master->num_mids dereferences NULL:

  qcom_iommu_of_xlate from of_iommu_xlate
  of_iommu_xlate from of_iommu_configure
  of_iommu_configure from platform_dma_configure
  platform_dma_configure from __iommu_probe_device
  __iommu_probe_device from probe_iommu_group
  probe_iommu_group from bus_for_each_dev
  bus_for_each_dev from iommu_device_register
  iommu_device_register from msm_iommu_probe

The faulty guard has been there since the driver gained generic master
bindings, but it stayed dormant for years because a device's ->of_xlate()
only ran once all of its IOMMUs were present. It became reachable when
iommu_fwspec_init() started deferring per instance on the ->ready flag,
which is what lets a master be stranded on the first IOMMU and then have
->of_xlate() replayed with dev_iommu_priv already reset. Hence the two
Fixes below: the first introduced the guard, the second made it fatal.

Look the master up in the target IOMMU's ctx_list instead, allocating one
only when that IOMMU has none for the device yet. Each instance now keeps
its own master and gets programmed with the full set of stream IDs. A
stream ID seen twice is an expected consequence of the replay described
above and is already ignored, so demote that message to dev_dbg().

Fixes: f78ebca8ff3d ("iommu/msm: Add support for generic master bindings")
Fixes: da33e87bd2bf ("iommu: Handle yet another race around registration")
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Assisted-by: Claude:claude-opus-5
---
 drivers/iommu/msm_iommu.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 0ad5ff431d5b..3847f5f0059f 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -601,24 +601,27 @@ static int insert_iommu_master(struct device *dev,
 				struct msm_iommu_dev **iommu,
 				const struct of_phandle_args *spec)
 {
-	struct msm_iommu_ctx_dev *master = dev_iommu_priv_get(dev);
+	struct msm_iommu_ctx_dev *master;
 	int sid;
 
-	if (list_empty(&(*iommu)->ctx_list)) {
-		master = kzalloc_obj(*master, GFP_ATOMIC);
-		if (!master) {
-			dev_err(dev, "Failed to allocate iommu_master\n");
-			return -ENOMEM;
-		}
-		master->of_node = dev->of_node;
-		list_add(&master->list, &(*iommu)->ctx_list);
-		dev_iommu_priv_set(dev, master);
+	/* A master describes one device on one IOMMU instance. */
+	list_for_each_entry(master, &(*iommu)->ctx_list, list)
+		if (master->of_node == dev->of_node)
+			goto add_sid;
+
+	master = kzalloc_obj(*master, GFP_ATOMIC);
+	if (!master) {
+		dev_err(dev, "Failed to allocate iommu_master\n");
+		return -ENOMEM;
 	}
+	master->of_node = dev->of_node;
+	list_add(&master->list, &(*iommu)->ctx_list);
 
+add_sid:
 	for (sid = 0; sid < master->num_mids; sid++)
 		if (master->mids[sid] == spec->args[0]) {
-			dev_warn(dev, "Stream ID 0x%x repeated; ignoring\n",
-				 sid);
+			dev_dbg(dev, "Stream ID 0x%x repeated; ignoring\n",
+				sid);
 			return 0;
 		}
 

-- 
2.47.3


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH 2/3] ARM: dma-mapping: reset DMA ops before detaching from the IOMMU
  2026-07-30 13:29 ` Dmitry Baryshkov
@ 2026-07-30 13:29   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:29 UTC (permalink / raw)
  To: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

arm_iommu_attach_device() installs the IOMMU-aware dma_map_ops only
after iommu_attach_device() has run, so a driver that builds its page
tables during attach (msm_iommu via io-pgtable) maps them while the
device still has the direct DMA ops: the resulting dma_handle equals the
physical address.

arm_iommu_detach_device() does the reverse in the wrong order. It calls
iommu_detach_device() first and clears the DMA ops afterwards. When
detaching frees those page tables (msm_iommu_identity_attach() ->
free_io_pgtable_ops()), the freeing dma_unmap now goes through the still
installed IOMMU ops, which treat the stored physical address as an IOVA.
iommu_unmap() warns "region not mapped" and __free_iova() indexes an
unallocated bitmap extension, dereferencing NULL:

  __bitmap_clear from arm_iommu_unmap_phys
  arm_iommu_unmap_phys from dma_unmap_phys
  dma_unmap_phys from __arm_v7s_free_table
  __arm_v7s_free_table from arm_v7s_free_pgtable
  arm_v7s_free_pgtable from msm_iommu_identity_attach
  msm_iommu_identity_attach from __iommu_attach_device
  __iommu_attach_device from iommu_detach_device
  iommu_detach_device from arm_iommu_detach_device
  arm_iommu_detach_device from arch_teardown_dma_ops
  arch_teardown_dma_ops from device_unbind_cleanup

This is reached on apq8064 (ifc6410) when the adreno GPU probe fails and
its DMA ops are torn down.

Reset the DMA ops before iommu_detach_device() so page-table teardown
runs with the same direct ops that mapped them at attach time.

Fixes: 78fc30b4bb35 ("iommu/msm: Implement an IDENTITY domain")
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Assisted-by: Claude:claude-opus-5
---
 arch/arm/mm/dma-mapping.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f9bc53b60f99..a467e0d01a5b 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1642,10 +1642,13 @@ void arm_iommu_detach_device(struct device *dev)
 		return;
 	}
 
+	/* Reset DMA ops before detach so page-table teardown uses the same
+	 * direct ops that mapped them at attach time.
+	 */
+	set_dma_ops(dev, NULL);
 	iommu_detach_device(mapping->domain, dev);
 	kref_put(&mapping->kref, release_iommu_mapping);
 	to_dma_iommu_mapping(dev) = NULL;
-	set_dma_ops(dev, NULL);
 
 	pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
 }

-- 
2.47.3


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

* [PATCH 2/3] ARM: dma-mapping: reset DMA ops before detaching from the IOMMU
@ 2026-07-30 13:29   ` Dmitry Baryshkov
  0 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:29 UTC (permalink / raw)
  To: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

arm_iommu_attach_device() installs the IOMMU-aware dma_map_ops only
after iommu_attach_device() has run, so a driver that builds its page
tables during attach (msm_iommu via io-pgtable) maps them while the
device still has the direct DMA ops: the resulting dma_handle equals the
physical address.

arm_iommu_detach_device() does the reverse in the wrong order. It calls
iommu_detach_device() first and clears the DMA ops afterwards. When
detaching frees those page tables (msm_iommu_identity_attach() ->
free_io_pgtable_ops()), the freeing dma_unmap now goes through the still
installed IOMMU ops, which treat the stored physical address as an IOVA.
iommu_unmap() warns "region not mapped" and __free_iova() indexes an
unallocated bitmap extension, dereferencing NULL:

  __bitmap_clear from arm_iommu_unmap_phys
  arm_iommu_unmap_phys from dma_unmap_phys
  dma_unmap_phys from __arm_v7s_free_table
  __arm_v7s_free_table from arm_v7s_free_pgtable
  arm_v7s_free_pgtable from msm_iommu_identity_attach
  msm_iommu_identity_attach from __iommu_attach_device
  __iommu_attach_device from iommu_detach_device
  iommu_detach_device from arm_iommu_detach_device
  arm_iommu_detach_device from arch_teardown_dma_ops
  arch_teardown_dma_ops from device_unbind_cleanup

This is reached on apq8064 (ifc6410) when the adreno GPU probe fails and
its DMA ops are torn down.

Reset the DMA ops before iommu_detach_device() so page-table teardown
runs with the same direct ops that mapped them at attach time.

Fixes: 78fc30b4bb35 ("iommu/msm: Implement an IDENTITY domain")
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Assisted-by: Claude:claude-opus-5
---
 arch/arm/mm/dma-mapping.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f9bc53b60f99..a467e0d01a5b 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1642,10 +1642,13 @@ void arm_iommu_detach_device(struct device *dev)
 		return;
 	}
 
+	/* Reset DMA ops before detach so page-table teardown uses the same
+	 * direct ops that mapped them at attach time.
+	 */
+	set_dma_ops(dev, NULL);
 	iommu_detach_device(mapping->domain, dev);
 	kref_put(&mapping->kref, release_iommu_mapping);
 	to_dma_iommu_mapping(dev) = NULL;
-	set_dma_ops(dev, NULL);
 
 	pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
 }

-- 
2.47.3


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH 3/3] drm/msm: detach the ARM DMA mapping before attaching our own domain
  2026-07-30 13:29 ` Dmitry Baryshkov
@ 2026-07-30 13:29   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:29 UTC (permalink / raw)
  To: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On ARM32 with CONFIG_ARM_DMA_USE_IOMMU, arch_setup_dma_ops() creates a
dma_iommu_mapping for every IOMMU-backed device and attaches its domain
to the device's IOMMU group. That domain is neither the group's default
nor its blocking domain, so when msm_iommu_new() later attaches the
domain the driver manages itself, __iommu_attach_group() refuses it:

	if (group->domain && group->domain != group->default_domain &&
	    group->domain != group->blocking_domain)
		return -EBUSY;

Both the GPU and the display controller are hit by this on apq8064
(IFC6410), leaving the board with no GPU and no display:

  adreno 4300000.gpu: failed to load adreno gpu
  adreno 4300000.gpu: probe with driver adreno failed with error -16
  mdp4 5100000.display-controller: [drm:msm_drm_kms_init] *ERROR* failed to load kms
  mdp4 5100000.display-controller: adev bind failed: -16

Other ARM32 DRM drivers that manage their own domains (tegra, rockchip,
exynos) drop the arch mapping first. Do the same in msm_iommu_new(),
which both the display and the GPU paths go through.

With this the GPU and the KMS device both initialise:

  [drm] Initialized msm 1.13.0 for 4300000.gpu on minor 0
  [drm] Initialized msm-kms 1.13.0 for 5100000.display-controller on minor 1

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Assisted-by: Claude:claude-opus-5
---
 drivers/gpu/drm/msm/msm_iommu.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 897e42c8d5c8..da6782fca6bd 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -7,6 +7,15 @@
 #include <linux/adreno-smmu-priv.h>
 #include <linux/io-pgtable.h>
 #include <linux/kmemleak.h>
+
+#if defined(CONFIG_ARM_DMA_USE_IOMMU)
+#include <asm/dma-iommu.h>
+#else
+#define arm_iommu_detach_device(...)	({ })
+#define arm_iommu_release_mapping(...)	({ })
+#define to_dma_iommu_mapping(dev)	NULL
+#endif
+
 #include "msm_drv.h"
 #include "msm_gpu_trace.h"
 #include "msm_mmu.h"
@@ -749,6 +758,19 @@ struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks)
 
 	mutex_init(&iommu->init_lock);
 
+	/*
+	 * ARM32 attaches a DMA mapping domain to every IOMMU-backed device,
+	 * which would make attaching our own domain fail with -EBUSY.
+	 */
+	if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
+		struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+
+		if (mapping) {
+			arm_iommu_detach_device(dev);
+			arm_iommu_release_mapping(mapping);
+		}
+	}
+
 	ret = iommu_attach_device(iommu->domain, dev);
 	if (ret) {
 		iommu_domain_free(domain);

-- 
2.47.3


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

* [PATCH 3/3] drm/msm: detach the ARM DMA mapping before attaching our own domain
@ 2026-07-30 13:29   ` Dmitry Baryshkov
  0 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:29 UTC (permalink / raw)
  To: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On ARM32 with CONFIG_ARM_DMA_USE_IOMMU, arch_setup_dma_ops() creates a
dma_iommu_mapping for every IOMMU-backed device and attaches its domain
to the device's IOMMU group. That domain is neither the group's default
nor its blocking domain, so when msm_iommu_new() later attaches the
domain the driver manages itself, __iommu_attach_group() refuses it:

	if (group->domain && group->domain != group->default_domain &&
	    group->domain != group->blocking_domain)
		return -EBUSY;

Both the GPU and the display controller are hit by this on apq8064
(IFC6410), leaving the board with no GPU and no display:

  adreno 4300000.gpu: failed to load adreno gpu
  adreno 4300000.gpu: probe with driver adreno failed with error -16
  mdp4 5100000.display-controller: [drm:msm_drm_kms_init] *ERROR* failed to load kms
  mdp4 5100000.display-controller: adev bind failed: -16

Other ARM32 DRM drivers that manage their own domains (tegra, rockchip,
exynos) drop the arch mapping first. Do the same in msm_iommu_new(),
which both the display and the GPU paths go through.

With this the GPU and the KMS device both initialise:

  [drm] Initialized msm 1.13.0 for 4300000.gpu on minor 0
  [drm] Initialized msm-kms 1.13.0 for 5100000.display-controller on minor 1

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Assisted-by: Claude:claude-opus-5
---
 drivers/gpu/drm/msm/msm_iommu.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 897e42c8d5c8..da6782fca6bd 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -7,6 +7,15 @@
 #include <linux/adreno-smmu-priv.h>
 #include <linux/io-pgtable.h>
 #include <linux/kmemleak.h>
+
+#if defined(CONFIG_ARM_DMA_USE_IOMMU)
+#include <asm/dma-iommu.h>
+#else
+#define arm_iommu_detach_device(...)	({ })
+#define arm_iommu_release_mapping(...)	({ })
+#define to_dma_iommu_mapping(dev)	NULL
+#endif
+
 #include "msm_drv.h"
 #include "msm_gpu_trace.h"
 #include "msm_mmu.h"
@@ -749,6 +758,19 @@ struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks)
 
 	mutex_init(&iommu->init_lock);
 
+	/*
+	 * ARM32 attaches a DMA mapping domain to every IOMMU-backed device,
+	 * which would make attaching our own domain fail with -EBUSY.
+	 */
+	if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
+		struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+
+		if (mapping) {
+			arm_iommu_detach_device(dev);
+			arm_iommu_release_mapping(mapping);
+		}
+	}
+
 	ret = iommu_attach_device(iommu->domain, dev);
 	if (ret) {
 		iommu_domain_free(domain);

-- 
2.47.3


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH 3/3] drm/msm: detach the ARM DMA mapping before attaching our own domain
  2026-07-30 13:29   ` Dmitry Baryshkov
@ 2026-07-30 13:42     ` Konrad Dybcio
  -1 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-30 13:42 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Joerg Roedel (AMD), Will Deacon,
	Robin Murphy, Sricharan Ramabadhran, Joerg Roedel, Russell King,
	Lu Baolu, Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
> On ARM32 with CONFIG_ARM_DMA_USE_IOMMU, arch_setup_dma_ops() creates a
> dma_iommu_mapping for every IOMMU-backed device and attaches its domain
> to the device's IOMMU group. That domain is neither the group's default
> nor its blocking domain, so when msm_iommu_new() later attaches the
> domain the driver manages itself, __iommu_attach_group() refuses it:

[...]

> +#if defined(CONFIG_ARM_DMA_USE_IOMMU)
> +#include <asm/dma-iommu.h>
> +#else
> +#define arm_iommu_detach_device(...)	({ })
> +#define arm_iommu_release_mapping(...)	({ })
> +#define to_dma_iommu_mapping(dev)	NULL
> +#endif

I see this is prior art, but should we support this config being off?

Konrad

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

* Re: [PATCH 3/3] drm/msm: detach the ARM DMA mapping before attaching our own domain
@ 2026-07-30 13:42     ` Konrad Dybcio
  0 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-30 13:42 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Joerg Roedel (AMD), Will Deacon,
	Robin Murphy, Sricharan Ramabadhran, Joerg Roedel, Russell King,
	Lu Baolu, Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
> On ARM32 with CONFIG_ARM_DMA_USE_IOMMU, arch_setup_dma_ops() creates a
> dma_iommu_mapping for every IOMMU-backed device and attaches its domain
> to the device's IOMMU group. That domain is neither the group's default
> nor its blocking domain, so when msm_iommu_new() later attaches the
> domain the driver manages itself, __iommu_attach_group() refuses it:

[...]

> +#if defined(CONFIG_ARM_DMA_USE_IOMMU)
> +#include <asm/dma-iommu.h>
> +#else
> +#define arm_iommu_detach_device(...)	({ })
> +#define arm_iommu_release_mapping(...)	({ })
> +#define to_dma_iommu_mapping(dev)	NULL
> +#endif

I see this is prior art, but should we support this config being off?

Konrad

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH 1/3] iommu/msm: track a context master per device and IOMMU
  2026-07-30 13:29   ` Dmitry Baryshkov
  (?)
@ 2026-07-30 13:52   ` sashiko-bot
  -1 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-07-30 13:52 UTC (permalink / raw)
  To: Dmitry Baryshkov; +Cc: dri-devel

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Incomplete Refactoring breaking Device Attachment for Shared IOMMUs.

Pre-existing issues:
- [High] Out-of-bounds Read / Undefined Behavior due to `list_first_entry()` on potentially empty `ctx_list`.
- [High] Lockless Access / Race Condition during TLB flushes iterating over `ctx_list`.
--

--- Patch [1]: [PATCH 1/3] iommu/msm: track a context master per device and IOMMU ---
commit c8d40e4c746f720804d5ad115bf7e9dd560b624f
Author: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

iommu/msm: track a context master per device and IOMMU

insert_iommu_master() decided whether to allocate a struct
msm_iommu_ctx_dev by testing whether the IOMMU's ctx_list was empty,
caching the result in dev_iommu_priv, then unconditionally dereferenced
the master.

> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index 4ef1e8c8244b0..aab87ccbcada9 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -601,24 +601,27 @@ static int insert_iommu_master(struct device *dev,
>  				struct msm_iommu_dev **iommu,
>  				const struct of_phandle_args *spec)
>  {
[ ... ]
> -	if (list_empty(&(*iommu)->ctx_list)) {
> -		master = kzalloc_obj(*master, GFP_ATOMIC);
> -		if (!master) {
> -			dev_err(dev, "Failed to allocate iommu_master\n");
> -			return -ENOMEM;
> -		}
> -		master->of_node = dev->of_node;
> -		list_add(&master->list, &(*iommu)->ctx_list);
> -		dev_iommu_priv_set(dev, master);
> +	/* A master describes one device on one IOMMU instance. */
> +	list_for_each_entry(master, &(*iommu)->ctx_list, list)
> +		if (master->of_node == dev->of_node)
> +			goto add_sid;
> +
> +	master = kzalloc_obj(*master, GFP_ATOMIC);
> +	if (!master) {
> +		dev_err(dev, "Failed to allocate iommu_master\n");
> +		return -ENOMEM;
>  	}
> +	master->of_node = dev->of_node;
> +	list_add(&master->list, &(*iommu)->ctx_list);

[Severity: High]
Is it possible this change breaks device attachment for shared IOMMUs?

By allowing multiple masters to be added to ctx_list, find_iommu_for_dev()
and msm_iommu_attach_dev() might fail because they still only check the
first entry:

drivers/iommu/msm_iommu.c:find_iommu_for_dev() {
    master = list_first_entry(&iommu->ctx_list,
                              struct msm_iommu_ctx_dev,
                              list);
    if (master->of_node == dev->of_node) {
    ...
}

When a second device probes, it is added to the head of the list. When the
first device subsequently tries to attach, it would compare its of_node
against the new head (the second device), fail the match, and return -ENODEV.

Furthermore, when a match is found in msm_iommu_attach_dev(), it iterates
over all masters in ctx_list (even those belonging to other devices):

drivers/iommu/msm_iommu.c:msm_iommu_attach_dev() {
    ...
    list_for_each_entry(master, &iommu->ctx_list, list) {
        if (master->num) {
            dev_err(dev, "domain already attached");
    ...
}

Will this improperly attach all devices sharing the IOMMU to the same domain,
breaking domain isolation?

[Severity: High]
This isn't a bug introduced by this patch, but could calling
list_first_entry() on a potentially empty ctx_list cause an out-of-bounds
read?

During device probe, find_iommu_for_dev() and msm_iommu_attach_dev() iterate
over all registered IOMMUs in qcom_iommu_devices and unconditionally call
list_first_entry():

drivers/iommu/msm_iommu.c:find_iommu_for_dev() {
    master = list_first_entry(&iommu->ctx_list,
                              struct msm_iommu_ctx_dev,
                              list);
    if (master->of_node == dev->of_node) {
    ...
}

If an IOMMU has been registered but no devices have been attached to it yet
(such as during early bus probing), its ctx_list is empty. list_first_entry
on an empty list yields an invalid pointer.

Could this lead to a panic via page fault when master->of_node is
dereferenced?

[Severity: High]
This is a pre-existing issue, but does using list_add() here introduce a race
condition with concurrent lockless readers?

The TLB flush functions (__flush_iotlb and __flush_iotlb_range) iterate over
iommu->ctx_list without holding msm_iommu_lock or using RCU primitives:

drivers/iommu/msm_iommu.c:__flush_iotlb() {
    ...
    list_for_each_entry(master, &iommu->ctx_list, list)
        SET_CTX_TLBIALL(iommu->base, master->num, 0);
    ...
}

At the same time, insert_iommu_master() modifies this same ctx_list using
list_add() (a non-RCU primitive) while holding msm_iommu_lock.

Since this patch allows multiple masters per IOMMU, can a concurrent TLB
flush observe torn pointers or partially initialized nodes if a second device
is probed while the first device is actively performing DMA/unmap operations?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-fix-qcom-smmu-v1-0-b12fa067804e@oss.qualcomm.com?part=1

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

* Re: [PATCH 1/3] iommu/msm: track a context master per device and IOMMU
  2026-07-30 13:29   ` Dmitry Baryshkov
@ 2026-07-30 13:57     ` Konrad Dybcio
  -1 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-30 13:57 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Joerg Roedel (AMD), Will Deacon,
	Robin Murphy, Sricharan Ramabadhran, Joerg Roedel, Russell King,
	Lu Baolu, Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
> insert_iommu_master() decided whether to allocate a struct
> msm_iommu_ctx_dev by testing whether the IOMMU's ctx_list was empty,
> caching the result in dev_iommu_priv, then unconditionally dereferenced
> the master:

[...]

> -			dev_warn(dev, "Stream ID 0x%x repeated; ignoring\n",
> -				 sid);
> +			dev_dbg(dev, "Stream ID 0x%x repeated; ignoring\n",
> +				sid);

Is this intentionally part of the patch?

Konrad

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH 1/3] iommu/msm: track a context master per device and IOMMU
@ 2026-07-30 13:57     ` Konrad Dybcio
  0 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-30 13:57 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Joerg Roedel (AMD), Will Deacon,
	Robin Murphy, Sricharan Ramabadhran, Joerg Roedel, Russell King,
	Lu Baolu, Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
> insert_iommu_master() decided whether to allocate a struct
> msm_iommu_ctx_dev by testing whether the IOMMU's ctx_list was empty,
> caching the result in dev_iommu_priv, then unconditionally dereferenced
> the master:

[...]

> -			dev_warn(dev, "Stream ID 0x%x repeated; ignoring\n",
> -				 sid);
> +			dev_dbg(dev, "Stream ID 0x%x repeated; ignoring\n",
> +				sid);

Is this intentionally part of the patch?

Konrad

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

* Re: [PATCH 3/3] drm/msm: detach the ARM DMA mapping before attaching our own domain
  2026-07-30 13:42     ` Konrad Dybcio
@ 2026-07-30 13:58       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:58 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner, linux-arm-msm, iommu,
	linux-kernel, linux-arm-kernel, dri-devel, freedreno,
	linux-rockchip

On Thu, Jul 30, 2026 at 03:42:58PM +0200, Konrad Dybcio wrote:
> On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
> > On ARM32 with CONFIG_ARM_DMA_USE_IOMMU, arch_setup_dma_ops() creates a
> > dma_iommu_mapping for every IOMMU-backed device and attaches its domain
> > to the device's IOMMU group. That domain is neither the group's default
> > nor its blocking domain, so when msm_iommu_new() later attaches the
> > domain the driver manages itself, __iommu_attach_group() refuses it:
> 
> [...]
> 
> > +#if defined(CONFIG_ARM_DMA_USE_IOMMU)
> > +#include <asm/dma-iommu.h>
> > +#else
> > +#define arm_iommu_detach_device(...)	({ })
> > +#define arm_iommu_release_mapping(...)	({ })
> > +#define to_dma_iommu_mapping(dev)	NULL
> > +#endif
> 
> I see this is prior art, but should we support this config being off?

Yes. For example, on arm64.

-- 
With best wishes
Dmitry

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

* Re: [PATCH 3/3] drm/msm: detach the ARM DMA mapping before attaching our own domain
@ 2026-07-30 13:58       ` Dmitry Baryshkov
  0 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 13:58 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner, linux-arm-msm, iommu,
	linux-kernel, linux-arm-kernel, dri-devel, freedreno,
	linux-rockchip

On Thu, Jul 30, 2026 at 03:42:58PM +0200, Konrad Dybcio wrote:
> On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
> > On ARM32 with CONFIG_ARM_DMA_USE_IOMMU, arch_setup_dma_ops() creates a
> > dma_iommu_mapping for every IOMMU-backed device and attaches its domain
> > to the device's IOMMU group. That domain is neither the group's default
> > nor its blocking domain, so when msm_iommu_new() later attaches the
> > domain the driver manages itself, __iommu_attach_group() refuses it:
> 
> [...]
> 
> > +#if defined(CONFIG_ARM_DMA_USE_IOMMU)
> > +#include <asm/dma-iommu.h>
> > +#else
> > +#define arm_iommu_detach_device(...)	({ })
> > +#define arm_iommu_release_mapping(...)	({ })
> > +#define to_dma_iommu_mapping(dev)	NULL
> > +#endif
> 
> I see this is prior art, but should we support this config being off?

Yes. For example, on arm64.

-- 
With best wishes
Dmitry

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH 3/3] drm/msm: detach the ARM DMA mapping before attaching our own domain
  2026-07-30 13:58       ` Dmitry Baryshkov
@ 2026-07-30 13:59         ` Konrad Dybcio
  -1 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-30 13:59 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner, linux-arm-msm, iommu,
	linux-kernel, linux-arm-kernel, dri-devel, freedreno,
	linux-rockchip

On 7/30/26 3:58 PM, Dmitry Baryshkov wrote:
> On Thu, Jul 30, 2026 at 03:42:58PM +0200, Konrad Dybcio wrote:
>> On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
>>> On ARM32 with CONFIG_ARM_DMA_USE_IOMMU, arch_setup_dma_ops() creates a
>>> dma_iommu_mapping for every IOMMU-backed device and attaches its domain
>>> to the device's IOMMU group. That domain is neither the group's default
>>> nor its blocking domain, so when msm_iommu_new() later attaches the
>>> domain the driver manages itself, __iommu_attach_group() refuses it:
>>
>> [...]
>>
>>> +#if defined(CONFIG_ARM_DMA_USE_IOMMU)
>>> +#include <asm/dma-iommu.h>
>>> +#else
>>> +#define arm_iommu_detach_device(...)	({ })
>>> +#define arm_iommu_release_mapping(...)	({ })
>>> +#define to_dma_iommu_mapping(dev)	NULL
>>> +#endif
>>
>> I see this is prior art, but should we support this config being off?
> 
> Yes. For example, on arm64.

Right

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

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

* Re: [PATCH 3/3] drm/msm: detach the ARM DMA mapping before attaching our own domain
@ 2026-07-30 13:59         ` Konrad Dybcio
  0 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-30 13:59 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner, linux-arm-msm, iommu,
	linux-kernel, linux-arm-kernel, dri-devel, freedreno,
	linux-rockchip

On 7/30/26 3:58 PM, Dmitry Baryshkov wrote:
> On Thu, Jul 30, 2026 at 03:42:58PM +0200, Konrad Dybcio wrote:
>> On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
>>> On ARM32 with CONFIG_ARM_DMA_USE_IOMMU, arch_setup_dma_ops() creates a
>>> dma_iommu_mapping for every IOMMU-backed device and attaches its domain
>>> to the device's IOMMU group. That domain is neither the group's default
>>> nor its blocking domain, so when msm_iommu_new() later attaches the
>>> domain the driver manages itself, __iommu_attach_group() refuses it:
>>
>> [...]
>>
>>> +#if defined(CONFIG_ARM_DMA_USE_IOMMU)
>>> +#include <asm/dma-iommu.h>
>>> +#else
>>> +#define arm_iommu_detach_device(...)	({ })
>>> +#define arm_iommu_release_mapping(...)	({ })
>>> +#define to_dma_iommu_mapping(dev)	NULL
>>> +#endif
>>
>> I see this is prior art, but should we support this config being off?
> 
> Yes. For example, on arm64.

Right

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH 2/3] ARM: dma-mapping: reset DMA ops before detaching from the IOMMU
  2026-07-30 13:29   ` Dmitry Baryshkov
@ 2026-07-30 14:04     ` Robin Murphy
  -1 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2026-07-30 14:04 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Joerg Roedel (AMD), Will Deacon,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On 30/07/2026 2:29 pm, Dmitry Baryshkov wrote:
> arm_iommu_attach_device() installs the IOMMU-aware dma_map_ops only
> after iommu_attach_device() has run, so a driver that builds its page
> tables during attach (msm_iommu via io-pgtable) maps them while the
> device still has the direct DMA ops: the resulting dma_handle equals the
> physical address.
> 
> arm_iommu_detach_device() does the reverse in the wrong order. It calls
> iommu_detach_device() first and clears the DMA ops afterwards. When
> detaching frees those page tables (msm_iommu_identity_attach() ->
> free_io_pgtable_ops()), the freeing dma_unmap now goes through the still
> installed IOMMU ops,

Hang on, that sounds majorly wrong...

> which treat the stored physical address as an IOVA.
> iommu_unmap() warns "region not mapped" and __free_iova() indexes an
> unallocated bitmap extension, dereferencing NULL:
> 
>    __bitmap_clear from arm_iommu_unmap_phys
>    arm_iommu_unmap_phys from dma_unmap_phys

*this* dma_unmap is for the IOMMU device itself - the client device's 
ops should be irrelevant, and the IOMMU device should never be trying to 
translate itself through its own ops either.

 From a quick look, the real issue appears to be that the assignment of 
priv->dev in msm_iommu_attach_dev() and subsequent use in 
msm_iommu_domain_config() is completely bogus.

Thanks,
Robin.

>    dma_unmap_phys from __arm_v7s_free_table
>    __arm_v7s_free_table from arm_v7s_free_pgtable
>    arm_v7s_free_pgtable from msm_iommu_identity_attach
>    msm_iommu_identity_attach from __iommu_attach_device
>    __iommu_attach_device from iommu_detach_device
>    iommu_detach_device from arm_iommu_detach_device
>    arm_iommu_detach_device from arch_teardown_dma_ops
>    arch_teardown_dma_ops from device_unbind_cleanup
> 
> This is reached on apq8064 (ifc6410) when the adreno GPU probe fails and
> its DMA ops are torn down.
> 
> Reset the DMA ops before iommu_detach_device() so page-table teardown
> runs with the same direct ops that mapped them at attach time.
> 
> Fixes: 78fc30b4bb35 ("iommu/msm: Implement an IDENTITY domain")
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Assisted-by: Claude:claude-opus-5
> ---
>   arch/arm/mm/dma-mapping.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index f9bc53b60f99..a467e0d01a5b 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1642,10 +1642,13 @@ void arm_iommu_detach_device(struct device *dev)
>   		return;
>   	}
>   
> +	/* Reset DMA ops before detach so page-table teardown uses the same
> +	 * direct ops that mapped them at attach time.
> +	 */
> +	set_dma_ops(dev, NULL);
>   	iommu_detach_device(mapping->domain, dev);
>   	kref_put(&mapping->kref, release_iommu_mapping);
>   	to_dma_iommu_mapping(dev) = NULL;
> -	set_dma_ops(dev, NULL);
>   
>   	pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
>   }
> 


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH 2/3] ARM: dma-mapping: reset DMA ops before detaching from the IOMMU
@ 2026-07-30 14:04     ` Robin Murphy
  0 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2026-07-30 14:04 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Joerg Roedel (AMD), Will Deacon,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner
  Cc: linux-arm-msm, iommu, linux-kernel, linux-arm-kernel, dri-devel,
	freedreno, linux-rockchip

On 30/07/2026 2:29 pm, Dmitry Baryshkov wrote:
> arm_iommu_attach_device() installs the IOMMU-aware dma_map_ops only
> after iommu_attach_device() has run, so a driver that builds its page
> tables during attach (msm_iommu via io-pgtable) maps them while the
> device still has the direct DMA ops: the resulting dma_handle equals the
> physical address.
> 
> arm_iommu_detach_device() does the reverse in the wrong order. It calls
> iommu_detach_device() first and clears the DMA ops afterwards. When
> detaching frees those page tables (msm_iommu_identity_attach() ->
> free_io_pgtable_ops()), the freeing dma_unmap now goes through the still
> installed IOMMU ops,

Hang on, that sounds majorly wrong...

> which treat the stored physical address as an IOVA.
> iommu_unmap() warns "region not mapped" and __free_iova() indexes an
> unallocated bitmap extension, dereferencing NULL:
> 
>    __bitmap_clear from arm_iommu_unmap_phys
>    arm_iommu_unmap_phys from dma_unmap_phys

*this* dma_unmap is for the IOMMU device itself - the client device's 
ops should be irrelevant, and the IOMMU device should never be trying to 
translate itself through its own ops either.

 From a quick look, the real issue appears to be that the assignment of 
priv->dev in msm_iommu_attach_dev() and subsequent use in 
msm_iommu_domain_config() is completely bogus.

Thanks,
Robin.

>    dma_unmap_phys from __arm_v7s_free_table
>    __arm_v7s_free_table from arm_v7s_free_pgtable
>    arm_v7s_free_pgtable from msm_iommu_identity_attach
>    msm_iommu_identity_attach from __iommu_attach_device
>    __iommu_attach_device from iommu_detach_device
>    iommu_detach_device from arm_iommu_detach_device
>    arm_iommu_detach_device from arch_teardown_dma_ops
>    arch_teardown_dma_ops from device_unbind_cleanup
> 
> This is reached on apq8064 (ifc6410) when the adreno GPU probe fails and
> its DMA ops are torn down.
> 
> Reset the DMA ops before iommu_detach_device() so page-table teardown
> runs with the same direct ops that mapped them at attach time.
> 
> Fixes: 78fc30b4bb35 ("iommu/msm: Implement an IDENTITY domain")
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Assisted-by: Claude:claude-opus-5
> ---
>   arch/arm/mm/dma-mapping.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index f9bc53b60f99..a467e0d01a5b 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1642,10 +1642,13 @@ void arm_iommu_detach_device(struct device *dev)
>   		return;
>   	}
>   
> +	/* Reset DMA ops before detach so page-table teardown uses the same
> +	 * direct ops that mapped them at attach time.
> +	 */
> +	set_dma_ops(dev, NULL);
>   	iommu_detach_device(mapping->domain, dev);
>   	kref_put(&mapping->kref, release_iommu_mapping);
>   	to_dma_iommu_mapping(dev) = NULL;
> -	set_dma_ops(dev, NULL);
>   
>   	pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
>   }
> 


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

* Re: [PATCH 1/3] iommu/msm: track a context master per device and IOMMU
  2026-07-30 13:57     ` Konrad Dybcio
@ 2026-07-30 14:30       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 14:30 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner, linux-arm-msm, iommu,
	linux-kernel, linux-arm-kernel, dri-devel, freedreno,
	linux-rockchip

On Thu, Jul 30, 2026 at 03:57:42PM +0200, Konrad Dybcio wrote:
> On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
> > insert_iommu_master() decided whether to allocate a struct
> > msm_iommu_ctx_dev by testing whether the IOMMU's ctx_list was empty,
> > caching the result in dev_iommu_priv, then unconditionally dereferenced
> > the master:
> 
> [...]
> 
> > -			dev_warn(dev, "Stream ID 0x%x repeated; ignoring\n",
> > -				 sid);
> > +			dev_dbg(dev, "Stream ID 0x%x repeated; ignoring\n",
> > +				sid);
> 
> Is this intentionally part of the patch?

It can be dropped, yes.

-- 
With best wishes
Dmitry

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

* Re: [PATCH 1/3] iommu/msm: track a context master per device and IOMMU
@ 2026-07-30 14:30       ` Dmitry Baryshkov
  0 siblings, 0 replies; 21+ messages in thread
From: Dmitry Baryshkov @ 2026-07-30 14:30 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Rob Clark, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Sricharan Ramabadhran, Joerg Roedel, Russell King, Lu Baolu,
	Jerry Snitselaar, Jason Gunthorpe, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Heiko Stuebner, linux-arm-msm, iommu,
	linux-kernel, linux-arm-kernel, dri-devel, freedreno,
	linux-rockchip

On Thu, Jul 30, 2026 at 03:57:42PM +0200, Konrad Dybcio wrote:
> On 7/30/26 3:29 PM, Dmitry Baryshkov wrote:
> > insert_iommu_master() decided whether to allocate a struct
> > msm_iommu_ctx_dev by testing whether the IOMMU's ctx_list was empty,
> > caching the result in dev_iommu_priv, then unconditionally dereferenced
> > the master:
> 
> [...]
> 
> > -			dev_warn(dev, "Stream ID 0x%x repeated; ignoring\n",
> > -				 sid);
> > +			dev_dbg(dev, "Stream ID 0x%x repeated; ignoring\n",
> > +				sid);
> 
> Is this intentionally part of the patch?

It can be dropped, yes.

-- 
With best wishes
Dmitry

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

end of thread, other threads:[~2026-07-30 14:31 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 13:29 [PATCH 0/3] Fix GPU and display on ARM32 platforms using the MSM IOMMU Dmitry Baryshkov
2026-07-30 13:29 ` Dmitry Baryshkov
2026-07-30 13:29 ` [PATCH 1/3] iommu/msm: track a context master per device and IOMMU Dmitry Baryshkov
2026-07-30 13:29   ` Dmitry Baryshkov
2026-07-30 13:52   ` sashiko-bot
2026-07-30 13:57   ` Konrad Dybcio
2026-07-30 13:57     ` Konrad Dybcio
2026-07-30 14:30     ` Dmitry Baryshkov
2026-07-30 14:30       ` Dmitry Baryshkov
2026-07-30 13:29 ` [PATCH 2/3] ARM: dma-mapping: reset DMA ops before detaching from the IOMMU Dmitry Baryshkov
2026-07-30 13:29   ` Dmitry Baryshkov
2026-07-30 14:04   ` Robin Murphy
2026-07-30 14:04     ` Robin Murphy
2026-07-30 13:29 ` [PATCH 3/3] drm/msm: detach the ARM DMA mapping before attaching our own domain Dmitry Baryshkov
2026-07-30 13:29   ` Dmitry Baryshkov
2026-07-30 13:42   ` Konrad Dybcio
2026-07-30 13:42     ` Konrad Dybcio
2026-07-30 13:58     ` Dmitry Baryshkov
2026-07-30 13:58       ` Dmitry Baryshkov
2026-07-30 13:59       ` Konrad Dybcio
2026-07-30 13:59         ` Konrad Dybcio

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.