Skip to content

Commit fcbd621

Browse files
rmurphy-armwilldeacon
authored andcommitted
iommu/arm-smmu-v3: Clean up more on probe failure
kmemleak noticed that the iopf queue allocated deep down within arm_smmu_init_structures() can be leaked by a subsequent error return from arm_smmu_device_probe(). Furthermore, after arm_smmu_device_reset() we will also leave the SMMU enabled with an empty Stream Table, silently blocking all DMA. This proves rather annoying for debugging said probe failure, so let's handle it a bit better by putting the SMMU back into (more or less) the same state as if it hadn't probed at all. Signed-off-by: Robin Murphy <[email protected]> Link: https://lore.kernel.org/r/5137901958471cf67f2fad5c2229f8a8f1ae901a.1733406914.git.robin.murphy@arm.com Signed-off-by: Will Deacon <[email protected]>
1 parent 97cb1fa commit fcbd621

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4777,7 +4777,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
47774777
/* Initialise in-memory data structures */
47784778
ret = arm_smmu_init_structures(smmu);
47794779
if (ret)
4780-
return ret;
4780+
goto err_free_iopf;
47814781

47824782
/* Record our private device structure */
47834783
platform_set_drvdata(pdev, smmu);
@@ -4788,22 +4788,29 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
47884788
/* Reset the device */
47894789
ret = arm_smmu_device_reset(smmu);
47904790
if (ret)
4791-
return ret;
4791+
goto err_disable;
47924792

47934793
/* And we're up. Go go go! */
47944794
ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
47954795
"smmu3.%pa", &ioaddr);
47964796
if (ret)
4797-
return ret;
4797+
goto err_disable;
47984798

47994799
ret = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev);
48004800
if (ret) {
48014801
dev_err(dev, "Failed to register iommu\n");
4802-
iommu_device_sysfs_remove(&smmu->iommu);
4803-
return ret;
4802+
goto err_free_sysfs;
48044803
}
48054804

48064805
return 0;
4806+
4807+
err_free_sysfs:
4808+
iommu_device_sysfs_remove(&smmu->iommu);
4809+
err_disable:
4810+
arm_smmu_device_disable(smmu);
4811+
err_free_iopf:
4812+
iopf_queue_free(smmu->evtq.iopf);
4813+
return ret;
48074814
}
48084815

48094816
static void arm_smmu_device_remove(struct platform_device *pdev)

0 commit comments

Comments
 (0)