lkml.org 
[lkml]   [2020]   [Jun]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.6 100/606] iommu: Fix deferred domain attachment
    Date
    From: Joerg Roedel <jroedel@suse.de>

    [ Upstream commit bd421264ed307dd296eab036851221b225071a32 ]

    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.

    Move the is_deferred_attach() check out of the attach_device path and
    into iommu_group_add_device() to make deferred attaching work from the
    dma-iommu code.

    Fixes: 795bbbb9b6f8 ("iommu/dma-iommu: Handle deferred devices")
    Reported-by: Jerry Snitselaar <jsnitsel@redhat.com>
    Suggested-by: Robin Murphy <robin.murphy@arm.com>
    Signed-off-by: Joerg Roedel <jroedel@suse.de>
    Tested-by: Jerry Snitselaar <jsnitsel@redhat.com>
    Cc: Jerry Snitselaar <jsnitsel@redhat.com>
    Cc: Tom Murphy <murphyt7@tcd.ie>
    Cc: Robin Murphy <robin.murphy@arm.com>
    Link: https://lore.kernel.org/r/20200519130340.14564-1-joro@8bytes.org
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/iommu/iommu.c | 17 +++++++++++------
    1 file changed, 11 insertions(+), 6 deletions(-)

    diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
    index 8d2477941fd9..22b28076d48e 100644
    --- a/drivers/iommu/iommu.c
    +++ b/drivers/iommu/iommu.c
    @@ -692,6 +692,15 @@ static int iommu_group_create_direct_mappings(struct iommu_group *group,
    return ret;
    }

    +static bool iommu_is_attach_deferred(struct iommu_domain *domain,
    + struct device *dev)
    +{
    + if (domain->ops->is_attach_deferred)
    + return domain->ops->is_attach_deferred(domain, dev);
    +
    + return false;
    +}
    +
    /**
    * iommu_group_add_device - add a device to an iommu group
    * @group: the group into which to add the device (reference should be held)
    @@ -746,7 +755,7 @@ int iommu_group_add_device(struct iommu_group *group, struct device *dev)

    mutex_lock(&group->mutex);
    list_add_tail(&device->list, &group->devices);
    - if (group->domain)
    + if (group->domain && !iommu_is_attach_deferred(group->domain, dev))
    ret = __iommu_attach_device(group->domain, dev);
    mutex_unlock(&group->mutex);
    if (ret)
    @@ -1652,9 +1661,6 @@ static int __iommu_attach_device(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;
    @@ -1726,8 +1732,7 @@ EXPORT_SYMBOL_GPL(iommu_sva_unbind_gpasid);
    static void __iommu_detach_device(struct iommu_domain *domain,
    struct device *dev)
    {
    - if ((domain->ops->is_attach_deferred != NULL) &&
    - domain->ops->is_attach_deferred(domain, dev))
    + if (iommu_is_attach_deferred(domain, dev))
    return;

    if (unlikely(domain->ops->detach_dev == NULL))
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-06-09 01:18    [W:4.051 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site