On Fri, May 15, 2020 at 04:42:23PM +0100, Robin Murphy wrote:
struct iommu_domain *iommu_get_dma_domain(struct device *dev)
{
- return dev->iommu_group->default_domain;
+ struct iommu_domain *domain = dev->iommu_group->default_domain;
+
+ if (__iommu_is_attach_deferred(domain, dev))
+ __iommu_attach_device_no_defer(domain, dev);
This raises a red flag, since iommu-dma already has explicit deferred attach
handling where it should need it, immediately after this is called to
retrieve the domain. The whole thing smells to me like we should have an
explicit special-case in iommu_probe_device() rather than hooking
__iommu_attach_device() in general then having to bodge around the fallout
elsewhere.
Good point, I missed that. But it didn't work for its only user, the
AMD IOMMU driver, the reason is that it calls iommu_attach_device(),
which in its code-path checks for deferred attaching again and bails
out, without do the real attachment.
But below updated fix should work. Jerry, could you please test it
again?
From 4e262dedcd36c7572312c65e66416da74fc78047 Mon Sep 17 00:00:00 2001
From: Joerg Roedel <jroedel@xxxxxxx>
Date: Fri, 15 May 2020 11:25:03 +0200
Subject: [PATCH] iommu: Fix deferred domain attachment
The IOMMU core code has support for deferring the attachment of a domain
to a device. This is needed in kdump kernels where the new domain must
not be attached to a device before the device driver takes it over.
When the AMD IOMMU driver got converted to use the dma-iommu
implementation, the deferred attaching got lost. The code in
dma-iommu.c has support for deferred attaching, but it calls into
iommu_attach_device() to actually do it. But iommu_attach_device()
will check if the device should be deferred in it code-path and do
nothing, breaking deferred attachment.
Provide a function in IOMMU core code to reliably attach a device to a
domain without any deferred checks and also without other safe-guards.
Cc: Jerry Snitselaar <jsnitsel@xxxxxxxxxx>
Cc: Tom Murphy <murphyt7@xxxxxx>
Reported-by: Jerry Snitselaar <jsnitsel@xxxxxxxxxx>
Fixes: 795bbbb9b6f8 ("iommu/dma-iommu: Handle deferred devices")
Signed-off-by: Joerg Roedel <jroedel@xxxxxxx>
---
drivers/iommu/dma-iommu.c | 4 ++--
drivers/iommu/iommu.c | 37 ++++++++++++++++++++++++++++++++-----
include/linux/iommu.h | 2 ++
3 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index ba128d1cdaee..403fda04ea98 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -362,8 +362,8 @@ static int iommu_dma_deferred_attach(struct device *dev,
return 0;
if (unlikely(ops->is_attach_deferred &&
- ops->is_attach_deferred(domain, dev)))
- return iommu_attach_device(domain, dev);
+ ops->is_attach_deferred(domain, dev)))
+ return iommu_attach_device_no_defer(domain, dev);