On Fri, 8 Nov 2019 16:25:07 +0100
Jean-Philippe Brucker <jean-phili...@linaro.org> wrote:

> Let add_device() clean up after itself. The iommu_bus_init() function
> does call remove_device() on error, but other sites (e.g. of_iommu) do
> not.
> 
> Don't free level-2 stream tables because we'd have to track if we
> allocated each of them or if they are used by other endpoints. It's not
> worth the hassle since they are managed resources.
> 
> Reviewed-by: Eric Auger <eric.au...@redhat.com>
> Signed-off-by: Jean-Philippe Brucker <jean-phili...@linaro.org>

Potentially some fun around reordering of last few actions, but
doesn't seem there is any real connection between them so should be
fine.

Reviewed-by: Jonathan Cameron <jonathan.came...@huawei.com>

> ---
>  drivers/iommu/arm-smmu-v3.c | 28 +++++++++++++++++++++-------
>  1 file changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 82eac89ee187..88ec0bf33492 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -2826,14 +2826,16 @@ static int arm_smmu_add_device(struct device *dev)
>       for (i = 0; i < master->num_sids; i++) {
>               u32 sid = master->sids[i];
>  
> -             if (!arm_smmu_sid_in_range(smmu, sid))
> -                     return -ERANGE;
> +             if (!arm_smmu_sid_in_range(smmu, sid)) {
> +                     ret = -ERANGE;
> +                     goto err_free_master;
> +             }
>  
>               /* Ensure l2 strtab is initialised */
>               if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
>                       ret = arm_smmu_init_l2_strtab(smmu, sid);
>                       if (ret)
> -                             return ret;
> +                             goto err_free_master;
>               }
>       }
>  
> @@ -2843,13 +2845,25 @@ static int arm_smmu_add_device(struct device *dev)
>               master->ssid_bits = min_t(u8, master->ssid_bits,
>                                         CTXDESC_LINEAR_CDMAX);
>  
> +     ret = iommu_device_link(&smmu->iommu, dev);
> +     if (ret)
> +             goto err_free_master;
> +
>       group = iommu_group_get_for_dev(dev);
> -     if (!IS_ERR(group)) {
> -             iommu_group_put(group);
> -             iommu_device_link(&smmu->iommu, dev);
> +     if (IS_ERR(group)) {
> +             ret = PTR_ERR(group);
> +             goto err_unlink;
>       }
>  
> -     return PTR_ERR_OR_ZERO(group);
> +     iommu_group_put(group);
> +     return 0;
> +
> +err_unlink:
> +     iommu_device_unlink(&smmu->iommu, dev);
> +err_free_master:
> +     kfree(master);
> +     fwspec->iommu_priv = NULL;
> +     return ret;
>  }
>  
>  static void arm_smmu_remove_device(struct device *dev)


_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to