[PATCH v9 04/12] iommu/arm-smmu-v3: Destroy vmid_map ida via devres
From: Nicolin Chen
Date: Tue Jul 21 2026 - 16:01:18 EST
The vmid_map ida is only destroyed in arm_smmu_device_remove(), which does
not run when the probe fails. This is currently harmless, as the ida stays
empty until the first S2 domain allocation, which can only happen after a
successful probe.
An upcoming change will start reserving the crashed kernel's VMIDs in this
ida, at the probe time of a kdump kernel. A probe failure would then leak
the ida's internal allocations.
Register a devres action right after ida_init(), making devres the single
owner that covers both the unbind and probe failure paths. Also, move the
ida_init() call to the entry of arm_smmu_init_strtab(), as the reservation
will run in the adoption path prior to the regular stream table setup.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Nicolin Chen <nicolinc@xxxxxxxxxx>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 132bee5fbb1d1..0df6c17a53173 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4494,20 +4494,27 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
return 0;
}
+static void arm_smmu_deinit_strtab(void *data)
+{
+ struct arm_smmu_device *smmu = data;
+
+ ida_destroy(&smmu->vmid_map);
+}
+
static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
{
int ret;
+ ida_init(&smmu->vmid_map);
+ ret = devm_add_action_or_reset(smmu->dev, arm_smmu_deinit_strtab, smmu);
+ if (ret)
+ return ret;
+
if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
ret = arm_smmu_init_strtab_2lvl(smmu);
else
ret = arm_smmu_init_strtab_linear(smmu);
- if (ret)
- return ret;
-
- ida_init(&smmu->vmid_map);
-
- return 0;
+ return ret;
}
static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
@@ -5548,7 +5555,6 @@ static void arm_smmu_device_remove(struct platform_device *pdev)
iommu_device_sysfs_remove(&smmu->iommu);
arm_smmu_device_disable(smmu);
iopf_queue_free(smmu->evtq.iopf);
- ida_destroy(&smmu->vmid_map);
}
static void arm_smmu_device_shutdown(struct platform_device *pdev)
--
2.43.0