From 5b788c0cab956d0c14176e4f7e5f9a021eee82a1 Mon Sep 17 00:00:00 2001 From: Ketan Kishore Date: Fri, 17 Jul 2026 14:55:47 +0530 Subject: [PATCH] FROMLIST: amba: bus: Fix race condition during DMA configure at IOMMU probe time amba_dma_configure() can be invoked from the IOMMU probe path while a device's driver is still being bound asynchronously by really_probe() on another thread. Call trace: amba_dma_configure __iommu_probe_device probe_iommu_group bus_for_each_dev iommu_device_register arm_smmu_device_probe platform_probe really_probe __driver_probe_device driver_probe_device __device_attach_driver bus_for_each_drv __device_attach device_initial_probe bus_probe_device deferred_probe_work_func process_scheduled_works worker_thread kthread ret_from_fork dev->driver is read and converted to a struct amba_driver before it is known whether dev->driver is actually set. If a driver bind completes concurrently with the IOMMU probe path, the driver_managed_dma could end up being dereferenced through an invalid pointer derived from NULL. Update amba_dma_configure() to read dev->driver once and test if it's NULL before using it. This ensures that we don't dereference an invalid amba driver pointer if the device driver is asynchronously bound while configuring the DMA. This is the same TOCTOU race already fixed for the platform bus in commit 95deee37a123 ("platform: Fix race condition during DMA configure at IOMMU probe time") and for fsl-mc in commit 152f33ee30ee ("bus: fsl_mc: Fix driver_managed_dma check"). amba_dma_configure() has the identical pattern, so apply the same fix here. Fixes: bcb81ac6ae3c ("iommu: Get DT/ACPI parsing into the proper probe path") Link: https://lore.kernel.org/all/20260717-iommu_races-v2-1-d0b7789275af@oss.qualcomm.com/ Cc: stable@vger.kernel.org # 6.1+ Signed-off-by: Ketan Kishore Reviewed-by: Will McVicker --- drivers/amba/bus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 74e34a07ef72f..a04fceb39b3c7 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -353,7 +353,7 @@ static void amba_shutdown(struct device *dev) static int amba_dma_configure(struct device *dev) { - struct amba_driver *drv = to_amba_driver(dev->driver); + const struct device_driver *drv = READ_ONCE(dev->driver); enum dev_dma_attr attr; int ret = 0; @@ -365,7 +365,7 @@ static int amba_dma_configure(struct device *dev) } /* @drv may not be valid when we're called from the IOMMU layer */ - if (!ret && dev->driver && !drv->driver_managed_dma) { + if (!ret && drv && !to_amba_driver(drv)->driver_managed_dma) { ret = iommu_device_use_default_domain(dev); if (ret) arch_teardown_dma_ops(dev);