Skip to content

Commit 7c69844

Browse files
committed
Merge tag 'iommu-fixes-v6.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel: - Core: Fix an iommu-group refcount leak - Fix overflow issue in IOVA alloc path - ARM-SMMU fixes from Will: - Fix VFIO regression on NXP SoCs by reporting IOMMU_CAP_CACHE_COHERENCY - Fix SMMU shutdown paths to avoid device unregistration race - Error handling fix for Mediatek IOMMU driver * tag 'iommu-fixes-v6.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/mediatek-v1: Fix an error handling path in mtk_iommu_v1_probe() iommu/iova: Fix alloc iova overflows issue iommu: Fix refcount leak in iommu_device_claim_dma_owner iommu/arm-smmu-v3: Don't unregister on shutdown iommu/arm-smmu: Don't unregister on shutdown iommu/arm-smmu: Report IOMMU_CAP_CACHE_COHERENCY even betterer
2 parents 4f43ade + 142e821 commit 7c69844

File tree

5 files changed

+35
-17
lines changed

5 files changed

+35
-17
lines changed

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3858,7 +3858,9 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
38583858

38593859
static void arm_smmu_device_shutdown(struct platform_device *pdev)
38603860
{
3861-
arm_smmu_device_remove(pdev);
3861+
struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
3862+
3863+
arm_smmu_device_disable(smmu);
38623864
}
38633865

38643866
static const struct of_device_id arm_smmu_of_match[] = {

drivers/iommu/arm/arm-smmu/arm-smmu.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,8 +1316,14 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
13161316

13171317
switch (cap) {
13181318
case IOMMU_CAP_CACHE_COHERENCY:
1319-
/* Assume that a coherent TCU implies coherent TBUs */
1320-
return cfg->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK;
1319+
/*
1320+
* It's overwhelmingly the case in practice that when the pagetable
1321+
* walk interface is connected to a coherent interconnect, all the
1322+
* translation interfaces are too. Furthermore if the device is
1323+
* natively coherent, then its translation interface must also be.
1324+
*/
1325+
return cfg->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK ||
1326+
device_get_dma_attr(dev) == DEV_DMA_COHERENT;
13211327
case IOMMU_CAP_NOEXEC:
13221328
return true;
13231329
default:
@@ -2185,19 +2191,16 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
21852191
return 0;
21862192
}
21872193

2188-
static int arm_smmu_device_remove(struct platform_device *pdev)
2194+
static void arm_smmu_device_shutdown(struct platform_device *pdev)
21892195
{
21902196
struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
21912197

21922198
if (!smmu)
2193-
return -ENODEV;
2199+
return;
21942200

21952201
if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS))
21962202
dev_notice(&pdev->dev, "disabling translation\n");
21972203

2198-
iommu_device_unregister(&smmu->iommu);
2199-
iommu_device_sysfs_remove(&smmu->iommu);
2200-
22012204
arm_smmu_rpm_get(smmu);
22022205
/* Turn the thing off */
22032206
arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sCR0, ARM_SMMU_sCR0_CLIENTPD);
@@ -2209,12 +2212,21 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
22092212
clk_bulk_disable(smmu->num_clks, smmu->clks);
22102213

22112214
clk_bulk_unprepare(smmu->num_clks, smmu->clks);
2212-
return 0;
22132215
}
22142216

2215-
static void arm_smmu_device_shutdown(struct platform_device *pdev)
2217+
static int arm_smmu_device_remove(struct platform_device *pdev)
22162218
{
2217-
arm_smmu_device_remove(pdev);
2219+
struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
2220+
2221+
if (!smmu)
2222+
return -ENODEV;
2223+
2224+
iommu_device_unregister(&smmu->iommu);
2225+
iommu_device_sysfs_remove(&smmu->iommu);
2226+
2227+
arm_smmu_device_shutdown(pdev);
2228+
2229+
return 0;
22182230
}
22192231

22202232
static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)

drivers/iommu/iommu.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,14 +3185,16 @@ EXPORT_SYMBOL_GPL(iommu_group_claim_dma_owner);
31853185
*/
31863186
int iommu_device_claim_dma_owner(struct device *dev, void *owner)
31873187
{
3188-
struct iommu_group *group = iommu_group_get(dev);
3188+
struct iommu_group *group;
31893189
int ret = 0;
31903190

3191-
if (!group)
3192-
return -ENODEV;
31933191
if (WARN_ON(!owner))
31943192
return -EINVAL;
31953193

3194+
group = iommu_group_get(dev);
3195+
if (!group)
3196+
return -ENODEV;
3197+
31963198
mutex_lock(&group->mutex);
31973199
if (group->owner_cnt) {
31983200
if (group->owner != owner) {

drivers/iommu/iova.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad,
197197

198198
curr = __get_cached_rbnode(iovad, limit_pfn);
199199
curr_iova = to_iova(curr);
200-
retry_pfn = curr_iova->pfn_hi + 1;
200+
retry_pfn = curr_iova->pfn_hi;
201201

202202
retry:
203203
do {
@@ -211,7 +211,7 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad,
211211
if (high_pfn < size || new_pfn < low_pfn) {
212212
if (low_pfn == iovad->start_pfn && retry_pfn < limit_pfn) {
213213
high_pfn = limit_pfn;
214-
low_pfn = retry_pfn;
214+
low_pfn = retry_pfn + 1;
215215
curr = iova_find_limit(iovad, limit_pfn);
216216
curr_iova = to_iova(curr);
217217
goto retry;

drivers/iommu/mtk_iommu_v1.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
683683
ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
684684
dev_name(&pdev->dev));
685685
if (ret)
686-
return ret;
686+
goto out_clk_unprepare;
687687

688688
ret = iommu_device_register(&data->iommu, &mtk_iommu_v1_ops, dev);
689689
if (ret)
@@ -698,6 +698,8 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
698698
iommu_device_unregister(&data->iommu);
699699
out_sysfs_remove:
700700
iommu_device_sysfs_remove(&data->iommu);
701+
out_clk_unprepare:
702+
clk_disable_unprepare(data->bclk);
701703
return ret;
702704
}
703705

0 commit comments

Comments
 (0)