mirror of https://gitee.com/openkylin/linux.git
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: Will Deacon <will@kernel.org>
This commit is contained in:
parent
a2be6218e6
commit
92c1d360dc
|
@ -2794,28 +2794,23 @@ static int arm_smmu_add_device(struct device *dev)
|
||||||
|
|
||||||
if (!fwspec || fwspec->ops != &arm_smmu_ops)
|
if (!fwspec || fwspec->ops != &arm_smmu_ops)
|
||||||
return -ENODEV;
|
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 {
|
|
||||||
smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
|
|
||||||
if (!smmu)
|
|
||||||
return -ENODEV;
|
|
||||||
master = kzalloc(sizeof(*master), GFP_KERNEL);
|
|
||||||
if (!master)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
master->dev = dev;
|
if (WARN_ON_ONCE(fwspec->iommu_priv))
|
||||||
master->smmu = smmu;
|
return -EBUSY;
|
||||||
master->sids = fwspec->ids;
|
|
||||||
master->num_sids = fwspec->num_ids;
|
smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
|
||||||
fwspec->iommu_priv = master;
|
if (!smmu)
|
||||||
}
|
return -ENODEV;
|
||||||
|
|
||||||
|
master = kzalloc(sizeof(*master), GFP_KERNEL);
|
||||||
|
if (!master)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
master->dev = dev;
|
||||||
|
master->smmu = smmu;
|
||||||
|
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 */
|
/* Check the SIDs are in range of the SMMU and our stream table */
|
||||||
for (i = 0; i < master->num_sids; i++) {
|
for (i = 0; i < master->num_sids; i++) {
|
||||||
|
|
Loading…
Reference in New Issue