--- /dev/null
+From b46064a18810bad3aea089a79993ca5ea7a3d2b2 Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Fri, 28 Feb 2025 15:46:30 +0000
+Subject: iommu: Handle race with default domain setup
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+commit b46064a18810bad3aea089a79993ca5ea7a3d2b2 upstream.
+
+It turns out that deferred default domain creation leaves a subtle
+race window during iommu_device_register() wherein a client driver may
+asynchronously probe in parallel and get as far as performing DMA API
+operations with dma-direct, only to be switched to iommu-dma underfoot
+once the default domain attachment finally happens, with obviously
+disastrous consequences. Even the wonky of_iommu_configure() path is at
+risk, since iommu_fwspec_init() will no longer defer client probe as the
+instance ops are (necessarily) already registered, and the "replay"
+iommu_probe_device() call can see dev->iommu_group already set and so
+think there's nothing to do either.
+
+Fortunately we already have the right tool in the right place in the
+form of iommu_device_use_default_domain(), which just needs to ensure
+that said default domain is actually ready to *be* used. Deferring the
+client probe shouldn't have too much impact, given that this only
+happens while the IOMMU driver is probing, and thus due to kick the
+deferred probe list again once it finishes.
+
+Reported-by: Charan Teja Kalla <quic_charante@quicinc.com>
+Fixes: 98ac73f99bc4 ("iommu: Require a default_domain for all iommu drivers")
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/e88b94c9b575034a2c98a48b3d383654cbda7902.1740753261.git.robin.murphy@arm.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/iommu.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -3115,6 +3115,11 @@ int iommu_device_use_default_domain(stru
+ return 0;
+
+ mutex_lock(&group->mutex);
++ /* We may race against bus_iommu_probe() finalising groups here */
++ if (!group->default_domain) {
++ ret = -EPROBE_DEFER;
++ goto unlock_out;
++ }
+ if (group->owner_cnt) {
+ if (group->domain != group->default_domain || group->owner ||
+ !xa_empty(&group->pasid_array)) {