On Wed Sep 25 19, Joerg Roedel wrote:
From: Joerg Roedel <jroe...@suse.de>

Make sure that attaching a detaching a device can't race against each
other and protect the iommu_dev_data with a spin_lock in these code
paths.

Fixes: 92d420ec028d ("iommu/amd: Relax locking in dma_ops path")
Signed-off-by: Joerg Roedel <jroe...@suse.de>
---
drivers/iommu/amd_iommu.c       | 9 +++++++++
drivers/iommu/amd_iommu_types.h | 3 +++
2 files changed, 12 insertions(+)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 459247c32dc0..bac4e20a5919 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -201,6 +201,7 @@ static struct iommu_dev_data *alloc_dev_data(u16 devid)
        if (!dev_data)
                return NULL;

+       spin_lock_init(&dev_data->lock);
        dev_data->devid = devid;
        ratelimit_default_init(&dev_data->rs);

@@ -2157,6 +2158,8 @@ static int attach_device(struct device *dev,

        dev_data = get_dev_data(dev);

+       spin_lock(&dev_data->lock);
+
        ret = -EBUSY;
        if (dev_data->domain != NULL)
                goto out;
@@ -2199,6 +2202,8 @@ static int attach_device(struct device *dev,
        domain_flush_complete(domain);

out:
+       spin_unlock(&dev_data->lock);
+
        spin_unlock_irqrestore(&domain->lock, flags);

        return ret;
@@ -2218,6 +2223,8 @@ static void detach_device(struct device *dev)

        spin_lock_irqsave(&domain->lock, flags);

+       spin_lock(&dev_data->lock);
+
        /*
         * First check if the device is still attached. It might already
         * be detached from its domain because the generic
@@ -2240,6 +2247,8 @@ static void detach_device(struct device *dev)
        dev_data->ats.enabled = false;

out:
+       spin_unlock(&dev_data->lock);
+
        spin_unlock_irqrestore(&domain->lock, flags);
}

diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 0186501ab971..c9c1612d52e0 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -633,6 +633,9 @@ struct devid_map {
 * This struct contains device specific data for the IOMMU
 */
struct iommu_dev_data {
+       /*Protect against attach/detach races */
+       spinlock_t lock;
+
        struct list_head list;            /* For domain->dev_list */
        struct llist_node dev_data_list;  /* For global dev_data_list */
        struct protection_domain *domain; /* Domain the device is bound to */
--
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reviewed-by: Jerry Snitselaar <jsnit...@redhat.com>

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to