Commit 92c1d360 authored by Will Deacon's avatar Will Deacon
Browse files

iommu/arm-smmu-v3: Return -EBUSY when trying to re-add a device



Although we WARN in arm_smmu_add_device() if the device being added has
been added already without a subsequent call to arm_smmu_remove_device(),
we still continue half-heartedly, initialising the stream-table for any
new StreamIDs that may have magically appeared and re-establishing device
links that should still be there from last time.

Given that calling ->add_device() twice without removing the device in the
meantime is indicative of an error in the caller, just return -EBUSY after
warning.

Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean Philippe-Brucker <jean-philippe@linaro.org>
Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent a2be6218
Loading
Loading
Loading
Loading
+16 −21
Original line number Diff line number Diff line
@@ -2794,18 +2794,14 @@ static int arm_smmu_add_device(struct device *dev)

	if (!fwspec || fwspec->ops != &arm_smmu_ops)
		return -ENODEV;
	/*
	 * We _can_ actually withstand dodgy bus code re-calling add_device()
	 * without an intervening remove_device()/of_xlate() sequence, but
	 * we're not going to do so quietly...
	 */
	if (WARN_ON_ONCE(fwspec->iommu_priv)) {
		master = fwspec->iommu_priv;
		smmu = master->smmu;
	} else {

	if (WARN_ON_ONCE(fwspec->iommu_priv))
		return -EBUSY;

	smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
	if (!smmu)
		return -ENODEV;

	master = kzalloc(sizeof(*master), GFP_KERNEL);
	if (!master)
		return -ENOMEM;
@@ -2815,7 +2811,6 @@ static int arm_smmu_add_device(struct device *dev)
	master->sids = fwspec->ids;
	master->num_sids = fwspec->num_ids;
	fwspec->iommu_priv = master;
	}

	/* Check the SIDs are in range of the SMMU and our stream table */
	for (i = 0; i < master->num_sids; i++) {