Messages in this thread | | | Subject | Re: [PATCH] iommu: Implement deferred domain attachment | From | Lu Baolu <> | Date | Fri, 15 May 2020 21:51:03 +0800 |
| |
Hi Joerg,
On 2020/5/15 17:45, Joerg Roedel wrote: > From: Joerg Roedel <jroedel@suse.de> > > 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. > > But this needs support from the dma-ops code too, to actually do the > late attachment when there are DMA-API calls for the device. This got > lost in the AMD IOMMU driver after converting it to the dma-iommu code. > > Do the late attachment in the dma-iommu code-path to fix the issue. > > Cc: Jerry Snitselaar <jsnitsel@redhat.com> > Cc: Tom Murphy <murphyt7@tcd.ie> > Reported-by: Jerry Snitselaar <jsnitsel@redhat.com> > Tested-by: Jerry Snitselaar <jsnitsel@redhat.com> > Fixes: be62dbf554c5 ("iommu/amd: Convert AMD iommu driver to the dma-iommu api") > Signed-off-by: Joerg Roedel <jroedel@suse.de> > --- > drivers/iommu/iommu.c | 33 +++++++++++++++++++++++++++------ > 1 file changed, 27 insertions(+), 6 deletions(-) > > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c > index 4050569188be..f54ebb964271 100644 > --- a/drivers/iommu/iommu.c > +++ b/drivers/iommu/iommu.c > @@ -1889,13 +1889,19 @@ void iommu_domain_free(struct iommu_domain *domain) > } > EXPORT_SYMBOL_GPL(iommu_domain_free); > > -static int __iommu_attach_device(struct iommu_domain *domain, > - struct device *dev) > +static bool __iommu_is_attach_deferred(struct iommu_domain *domain, > + struct device *dev) > +{ > + if (!domain->ops->is_attach_deferred) > + return false; > + > + return domain->ops->is_attach_deferred(domain, dev); > +} > + > +static int __iommu_attach_device_no_defer(struct iommu_domain *domain, > + struct device *dev) > { > int ret; > - if ((domain->ops->is_attach_deferred != NULL) && > - domain->ops->is_attach_deferred(domain, dev)) > - return 0; > > if (unlikely(domain->ops->attach_dev == NULL)) > return -ENODEV; > @@ -1903,9 +1909,19 @@ static int __iommu_attach_device(struct iommu_domain *domain, > ret = domain->ops->attach_dev(domain, dev); > if (!ret) > trace_attach_device_to_domain(dev); > + > return ret; > } > > +static int __iommu_attach_device(struct iommu_domain *domain, > + struct device *dev) > +{ > + if (__iommu_is_attach_deferred(domain, dev)) > + return 0; > + > + return __iommu_attach_device_no_defer(domain, dev); > +} > + > int iommu_attach_device(struct iommu_domain *domain, struct device *dev) > { > struct iommu_group *group; > @@ -2023,7 +2039,12 @@ EXPORT_SYMBOL_GPL(iommu_get_domain_for_dev); > */ > 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);
It seems that the return value needs to be checked. The default domain is invalid if attach() failed.
Best regards, baolu
| |