lkml.org 
[lkml]   [2019]   [Nov]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 4/9] drivers/iommu: Take a ref to the IOMMU driver prior to ->add_device()
    Date
    To avoid accidental removal of an active IOMMU driver module, take a
    reference to the driver module in 'iommu_probe_device()' immediately
    prior to invoking the '->add_device()' callback and hold it until the
    after the device has been removed by '->remove_device()'.

    Suggested-by: Joerg Roedel <joro@8bytes.org>
    Signed-off-by: Will Deacon <will@kernel.org>
    ---
    drivers/iommu/iommu.c | 19 +++++++++++++++++--
    include/linux/iommu.h | 2 ++
    2 files changed, 19 insertions(+), 2 deletions(-)

    diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
    index c1aadb570145..4bfecfbbe2cf 100644
    --- a/drivers/iommu/iommu.c
    +++ b/drivers/iommu/iommu.c
    @@ -22,6 +22,7 @@
    #include <linux/bitops.h>
    #include <linux/property.h>
    #include <linux/fsl/mc.h>
    +#include <linux/module.h>
    #include <trace/events/iommu.h>

    static struct kset *iommu_group_kset;
    @@ -185,10 +186,21 @@ int iommu_probe_device(struct device *dev)
    if (!iommu_get_dev_param(dev))
    return -ENOMEM;

    + if (!try_module_get(ops->owner)) {
    + ret = -EINVAL;
    + goto err_free_dev_param;
    + }
    +
    ret = ops->add_device(dev);
    if (ret)
    - iommu_free_dev_param(dev);
    + goto err_module_put;
    +
    + return 0;

    +err_module_put:
    + module_put(ops->owner);
    +err_free_dev_param:
    + iommu_free_dev_param(dev);
    return ret;
    }

    @@ -199,7 +211,10 @@ void iommu_release_device(struct device *dev)
    if (dev->iommu_group)
    ops->remove_device(dev);

    - iommu_free_dev_param(dev);
    + if (dev->iommu_param) {
    + module_put(ops->owner);
    + iommu_free_dev_param(dev);
    + }
    }

    static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
    diff --git a/include/linux/iommu.h b/include/linux/iommu.h
    index 29bac5345563..d9dab5a3e912 100644
    --- a/include/linux/iommu.h
    +++ b/include/linux/iommu.h
    @@ -245,6 +245,7 @@ struct iommu_iotlb_gather {
    * @sva_get_pasid: Get PASID associated to a SVA handle
    * @page_response: handle page request response
    * @pgsize_bitmap: bitmap of all possible supported page sizes
    + * @owner: Driver module providing these ops
    */
    struct iommu_ops {
    bool (*capable)(enum iommu_cap);
    @@ -308,6 +309,7 @@ struct iommu_ops {
    struct iommu_page_response *msg);

    unsigned long pgsize_bitmap;
    + struct module *owner;
    };

    /**
    --
    2.24.0.rc1.363.gb1bccd3e3d-goog
    \
     
     \ /
      Last update: 2019-11-08 16:17    [W:3.293 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site