iommu/mediatek: Add mutex for data in the mtk_iommu_domain
authorYong Wu <yong.wu@mediatek.com>
Tue, 3 May 2022 07:13:59 +0000 (15:13 +0800)
committerJoerg Roedel <jroedel@suse.de>
Wed, 4 May 2022 08:39:38 +0000 (10:39 +0200)
Same with the previous patch, add a mutex for the "data" in the
mtk_iommu_domain. Just improve the safety for multi devices
enter attach_device at the same time. We don't get the real issue
for this.

Signed-off-by: Yong Wu <yong.wu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Link: https://lore.kernel.org/r/20220503071427.2285-9-yong.wu@mediatek.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/mtk_iommu.c

index 3413cc98e57e40a1d7cdf7ac11cdfea7c96fbdfb..ecdce5d3e8cf6a6f73f912d8e42f0d74829d969a 100644 (file)
@@ -128,6 +128,8 @@ struct mtk_iommu_domain {
 
        struct mtk_iommu_data           *data;
        struct iommu_domain             domain;
+
+       struct mutex                    mutex; /* Protect "data" in this structure */
 };
 
 static const struct iommu_ops mtk_iommu_ops;
@@ -434,6 +436,7 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
        dom = kzalloc(sizeof(*dom), GFP_KERNEL);
        if (!dom)
                return NULL;
+       mutex_init(&dom->mutex);
 
        return &dom->domain;
 }
@@ -455,14 +458,19 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
        if (domid < 0)
                return domid;
 
+       mutex_lock(&dom->mutex);
        if (!dom->data) {
                /* Data is in the frstdata in sharing pgtable case. */
                frstdata = mtk_iommu_get_m4u_data();
 
-               if (mtk_iommu_domain_finalise(dom, frstdata, domid))
+               ret = mtk_iommu_domain_finalise(dom, frstdata, domid);
+               if (ret) {
+                       mutex_unlock(&dom->mutex);
                        return -ENODEV;
+               }
                dom->data = data;
        }
+       mutex_unlock(&dom->mutex);
 
        mutex_lock(&data->mutex);
        if (!data->m4u_dom) { /* Initialize the M4U HW */