Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+35 -17
+3 -1
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
··· 3858 3858 3859 3859 static void arm_smmu_device_shutdown(struct platform_device *pdev) 3860 3860 { 3861 - arm_smmu_device_remove(pdev); 3861 + struct arm_smmu_device *smmu = platform_get_drvdata(pdev); 3862 + 3863 + arm_smmu_device_disable(smmu); 3862 3864 } 3863 3865 3864 3866 static const struct of_device_id arm_smmu_of_match[] = {
+22 -10
drivers/iommu/arm/arm-smmu/arm-smmu.c
··· 1316 1316 1317 1317 switch (cap) { 1318 1318 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; 1321 1327 case IOMMU_CAP_NOEXEC: 1322 1328 return true; 1323 1329 default: ··· 2191 2185 return 0; 2192 2186 } 2193 2187 2194 - static int arm_smmu_device_remove(struct platform_device *pdev) 2188 + static void arm_smmu_device_shutdown(struct platform_device *pdev) 2195 2189 { 2196 2190 struct arm_smmu_device *smmu = platform_get_drvdata(pdev); 2197 2191 2198 2192 if (!smmu) 2199 - return -ENODEV; 2193 + return; 2200 2194 2201 2195 if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS)) 2202 2196 dev_notice(&pdev->dev, "disabling translation\n"); 2203 - 2204 - iommu_device_unregister(&smmu->iommu); 2205 - iommu_device_sysfs_remove(&smmu->iommu); 2206 2197 2207 2198 arm_smmu_rpm_get(smmu); 2208 2199 /* Turn the thing off */ ··· 2212 2209 clk_bulk_disable(smmu->num_clks, smmu->clks); 2213 2210 2214 2211 clk_bulk_unprepare(smmu->num_clks, smmu->clks); 2215 - return 0; 2216 2212 } 2217 2213 2218 - static void arm_smmu_device_shutdown(struct platform_device *pdev) 2214 + static int arm_smmu_device_remove(struct platform_device *pdev) 2219 2215 { 2220 - arm_smmu_device_remove(pdev); 2216 + struct arm_smmu_device *smmu = platform_get_drvdata(pdev); 2217 + 2218 + if (!smmu) 2219 + return -ENODEV; 2220 + 2221 + iommu_device_unregister(&smmu->iommu); 2222 + iommu_device_sysfs_remove(&smmu->iommu); 2223 + 2224 + arm_smmu_device_shutdown(pdev); 2225 + 2226 + return 0; 2221 2227 } 2222 2228 2223 2229 static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
+5 -3
drivers/iommu/iommu.c
··· 3185 3185 */ 3186 3186 int iommu_device_claim_dma_owner(struct device *dev, void *owner) 3187 3187 { 3188 - struct iommu_group *group = iommu_group_get(dev); 3188 + struct iommu_group *group; 3189 3189 int ret = 0; 3190 3190 3191 - if (!group) 3192 - return -ENODEV; 3193 3191 if (WARN_ON(!owner)) 3194 3192 return -EINVAL; 3193 + 3194 + group = iommu_group_get(dev); 3195 + if (!group) 3196 + return -ENODEV; 3195 3197 3196 3198 mutex_lock(&group->mutex); 3197 3199 if (group->owner_cnt) {
+2 -2
drivers/iommu/iova.c
··· 197 197 198 198 curr = __get_cached_rbnode(iovad, limit_pfn); 199 199 curr_iova = to_iova(curr); 200 - retry_pfn = curr_iova->pfn_hi + 1; 200 + retry_pfn = curr_iova->pfn_hi; 201 201 202 202 retry: 203 203 do { ··· 211 211 if (high_pfn < size || new_pfn < low_pfn) { 212 212 if (low_pfn == iovad->start_pfn && retry_pfn < limit_pfn) { 213 213 high_pfn = limit_pfn; 214 - low_pfn = retry_pfn; 214 + low_pfn = retry_pfn + 1; 215 215 curr = iova_find_limit(iovad, limit_pfn); 216 216 curr_iova = to_iova(curr); 217 217 goto retry;
+3 -1
drivers/iommu/mtk_iommu_v1.c
··· 683 683 ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, 684 684 dev_name(&pdev->dev)); 685 685 if (ret) 686 - return ret; 686 + goto out_clk_unprepare; 687 687 688 688 ret = iommu_device_register(&data->iommu, &mtk_iommu_v1_ops, dev); 689 689 if (ret) ··· 698 698 iommu_device_unregister(&data->iommu); 699 699 out_sysfs_remove: 700 700 iommu_device_sysfs_remove(&data->iommu); 701 + out_clk_unprepare: 702 + clk_disable_unprepare(data->bclk); 701 703 return ret; 702 704 } 703 705