Re: [PATCH v6 4/6] iommu/arm-smmu: Add the device_link between masters and smmu

2018-02-02 Thread Sricharan R
Hi Robin,

On 2/2/2018 5:01 PM, Robin Murphy wrote:
> On 02/02/18 05:40, Sricharan R wrote:
>> Hi Robin/Vivek,
>>
>> On 2/1/2018 2:23 PM, Vivek Gautam wrote:
>>> Hi,
>>>
>>>
>>> On 1/31/2018 6:39 PM, Robin Murphy wrote:
>>>> On 19/01/18 11:43, Vivek Gautam wrote:
>>>>> From: Sricharan R 
>>>>>
>>>>> Finally add the device link between the master device and
>>>>> smmu, so that the smmu gets runtime enabled/disabled only when the
>>>>> master needs it. This is done from add_device callback which gets
>>>>> called once when the master is added to the smmu.
>>>>
>>>> Don't we need to balance this with a device_link_del() in .remove_device 
>>>> (like exynos-iommu does)?
>>>
>>> Right. Will add device_link_del() call. Thanks for pointing out.
>>
>>   The reason for not adding device_link_del from .remove_device was, the 
>> core device_del
>>   which calls the .remove_device from notifier, calls device_links_purge 
>> before that.
>>   That does the same thing as device_link_del. So by the time .remove_device 
>> is called,
>>   device_links for that device is already cleaned up. Vivek, you may want to 
>> check once that
>>   calling device_link_del from .remove_device has no effect, just to confirm 
>> once more.
> 
> There is at least one path in which .remove_device is not called via the 
> notifier from device_del(), which is in the cleanup path of iommu_bus_init(). 
> AFAICS any links created by .add_device during that process would be left 
> dangling, because the device(s) would be live but otherwise disassociated 
> from the IOMMU afterwards.
> 
> From a maintenance perspective it's easier to have the call in its logical 
> place even if it does nothing 99% of the time; that way we shouldn't have to 
> keep an eye out for subtle changes in the power management code or driver 
> core that might invalidate the device_del() reasoning above, and the power 
> management guys shouldn't have to comprehend the internals of the IOMMU API 
> to make sense of the unbalanced call if they ever want to change their API.

 Ha, for a moment was thinking that with probe deferral add/remove_iommu_group 
in iommu_bus_init is dummy.
 But that may not be true for all Archs.
 Surely agree for the maintainability reason as well. Thanks.

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v6 4/6] iommu/arm-smmu: Add the device_link between masters and smmu

2018-02-01 Thread Sricharan R
Hi Robin/Vivek,

On 2/1/2018 2:23 PM, Vivek Gautam wrote:
> Hi,
> 
> 
> On 1/31/2018 6:39 PM, Robin Murphy wrote:
>> On 19/01/18 11:43, Vivek Gautam wrote:
>>> From: Sricharan R 
>>>
>>> Finally add the device link between the master device and
>>> smmu, so that the smmu gets runtime enabled/disabled only when the
>>> master needs it. This is done from add_device callback which gets
>>> called once when the master is added to the smmu.
>>
>> Don't we need to balance this with a device_link_del() in .remove_device 
>> (like exynos-iommu does)?
> 
> Right. Will add device_link_del() call. Thanks for pointing out.

 The reason for not adding device_link_del from .remove_device was, the core 
device_del 
 which calls the .remove_device from notifier, calls device_links_purge before 
that.
 That does the same thing as device_link_del. So by the time .remove_device is 
called,
 device_links for that device is already cleaned up. Vivek, you may want to 
check once that
 calling device_link_del from .remove_device has no effect, just to confirm 
once more.

Regards,
 Sricharan
 
> 
> regards
> Vivek
> 
>>
>> Robin.
>>
>>> Signed-off-by: Sricharan R 
>>> ---
>>>   drivers/iommu/arm-smmu.c | 11 +++
>>>   1 file changed, 11 insertions(+)
>>>
>>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>>> index 95478bfb182c..33bbcfedb896 100644
>>> --- a/drivers/iommu/arm-smmu.c
>>> +++ b/drivers/iommu/arm-smmu.c
>>> @@ -1367,6 +1367,7 @@ static int arm_smmu_add_device(struct device *dev)
>>>   struct arm_smmu_device *smmu;
>>>   struct arm_smmu_master_cfg *cfg;
>>>   struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>> +    struct device_link *link;
>>>   int i, ret;
>>>     if (using_legacy_binding) {
>>> @@ -1428,6 +1429,16 @@ static int arm_smmu_add_device(struct device *dev)
>>>     pm_runtime_put_sync(smmu->dev);
>>>   +    /*
>>> + * Establish the link between smmu and master, so that the
>>> + * smmu gets runtime enabled/disabled as per the master's
>>> + * needs.
>>> + */
>>> +    link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME);
>>> +    if (!link)
>>> +    dev_warn(smmu->dev, "Unable to create device link between %s and 
>>> %s\n",
>>> + dev_name(smmu->dev), dev_name(dev));
>>> +
>>>   return 0;
>>>     out_cfg_free:
>>>
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v6 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-01 Thread Sricharan R
Hi Robin,

On 1/31/2018 6:36 PM, Robin Murphy wrote:
> On 19/01/18 11:43, Vivek Gautam wrote:
>> From: Sricharan R 
>>
>> The smmu device probe/remove and add/remove master device callbacks
>> gets called when the smmu is not linked to its master, that is without
>> the context of the master device. So calling runtime apis in those places
>> separately.
>>
>> Signed-off-by: Sricharan R 
>> [vivek: Cleanup pm runtime calls]
>> Signed-off-by: Vivek Gautam 
>> ---
>>   drivers/iommu/arm-smmu.c | 45 +
>>   1 file changed, 41 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index 21acffe91a1c..95478bfb182c 100644
>> --- a/drivers/iommu/arm-smmu.c
>> +++ b/drivers/iommu/arm-smmu.c
>> @@ -914,11 +914,15 @@ static void arm_smmu_destroy_domain_context(struct 
>> iommu_domain *domain)
>>   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>>   struct arm_smmu_device *smmu = smmu_domain->smmu;
>>   struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>> -    int irq;
>> +    int ret, irq;
>>     if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
>>   return;
>>   +    ret = pm_runtime_get_sync(smmu->dev);
>> +    if (ret)
>> +    return;
>> +
>>   /*
>>    * Disable the context bank and free the page tables before freeing
>>    * it.
>> @@ -933,6 +937,8 @@ static void arm_smmu_destroy_domain_context(struct 
>> iommu_domain *domain)
>>     free_io_pgtable_ops(smmu_domain->pgtbl_ops);
>>   __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
>> +
>> +    pm_runtime_put_sync(smmu->dev);
>>   }
>>     static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
>> @@ -1408,12 +1414,20 @@ static int arm_smmu_add_device(struct device *dev)
>>   while (i--)
>>   cfg->smendx[i] = INVALID_SMENDX;
>>   -    ret = arm_smmu_master_alloc_smes(dev);
>> +    ret = pm_runtime_get_sync(smmu->dev);
>>   if (ret)
>>   goto out_cfg_free;
>>   +    ret = arm_smmu_master_alloc_smes(dev);
>> +    if (ret) {
>> +    pm_runtime_put_sync(smmu->dev);
>> +    goto out_cfg_free;
> 
> Please keep to the existing pattern and put this on the cleanup path with a 
> new label, rather than inline.

 ok.

> 
>> +    }
>> +
>>   iommu_device_link(&smmu->iommu, dev);
>>   +    pm_runtime_put_sync(smmu->dev);
>> +
>>   return 0;
>>     out_cfg_free:
>> @@ -1428,7 +1442,7 @@ static void arm_smmu_remove_device(struct device *dev)
>>   struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>   struct arm_smmu_master_cfg *cfg;
>>   struct arm_smmu_device *smmu;
>> -
>> +    int ret;
>>     if (!fwspec || fwspec->ops != &arm_smmu_ops)
>>   return;
>> @@ -1436,8 +1450,21 @@ static void arm_smmu_remove_device(struct device *dev)
>>   cfg  = fwspec->iommu_priv;
>>   smmu = cfg->smmu;
>>   +    /*
>> + * The device link between the master device and
>> + * smmu is already purged at this point.
>> + * So enable the power to smmu explicitly.
>> + */
> 
> I don't understand this comment, especially since we don't even introduce 
> device links until the following patch... :/
> 

 This is because the core device_del callback, does a device_links_purge for 
that device,
 before calling the remove_device notifier. As a result, have to explicitly 
turn on the
 power to iommu. Probably the comment should be removed, rest of the places we 
don't
 explain why we are turning on explicitly.

>> +
>> +    ret = pm_runtime_get_sync(smmu->dev);
>> +    if (ret)
>> +    return;
>> +
>>   iommu_device_unlink(&smmu->iommu, dev);
>>   arm_smmu_master_free_smes(fwspec);
>> +
>> +    pm_runtime_put_sync(smmu->dev);
>> +
>>   iommu_group_remove_device(dev);
>>   kfree(fwspec->iommu_priv);
>>   iommu_fwspec_free(dev);
>> @@ -2130,6 +2157,14 @@ static int arm_smmu_device_probe(struct 
>> platform_device *pdev)
>>   if (err)
>>   return err;
>>   +    platform_set_drvdata(pdev, smmu);
>> +
>> +    pm_runtime_enable(dev);
>> +
>> +    err = pm_runtime_get_sync(dev);
>> +    if (err)
>> +    return err;
>> +
>>   err = arm_smmu_device_cfg_probe(smmu);
>>   if (err)
>>   

Re: [PATCH 2/2] iommu: Clean up of_iommu_init_fn

2018-01-08 Thread Sricharan R
_init);
>  module_exit(qcom_iommu_exit);
>  
> -IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1", NULL);
> +IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1");
>  
>  MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations");
>  MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> index 13394ac83c66..0cac59db95bc 100644
> --- a/include/linux/of_iommu.h
> +++ b/include/linux/of_iommu.h
> @@ -33,9 +33,6 @@ static inline const struct iommu_ops 
> *of_iommu_configure(struct device *dev,
>  
>  extern struct of_device_id __iommu_of_table;
>  
> -typedef int (*of_iommu_init_fn)(struct device_node *);
> -
> -#define IOMMU_OF_DECLARE(name, compat, fn) \
> - _OF_DECLARE(iommu, name, compat, fn, of_iommu_init_fn)
> +#define IOMMU_OF_DECLARE(name, compat)   OF_DECLARE_1(iommu, name, 
> compat, NULL)
>  
>  #endif /* __OF_IOMMU_H */
> 


Reviewed-by: Sricharan R 

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/2] iommu/msm: Claim bus ops on probe

2018-01-08 Thread Sricharan R


On 1/9/2018 12:12 AM, Robin Murphy wrote:
> Since the MSM IOMMU driver now probes via DT exclusively rather than
> platform data, dependent masters should be deferred until the IOMMU
> itself is ready. Thus we can do away with the early initialisation
> hook to unconditionally claim the bus ops, and instead do that only
> once an IOMMU is actually probed. Furthermore, this should also make
> the driver safe for multiplatform kernels on non-MSM SoCs.
> 
> Signed-off-by: Robin Murphy 
> ---
>  drivers/iommu/msm_iommu.c | 16 +++-
>  1 file changed, 3 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index 04f4d51ffacb..dda1ce87a070 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -823,6 +823,8 @@ static int msm_iommu_probe(struct platform_device *pdev)
>   goto fail;
>   }
>  
> + bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
> +
>   pr_info("device mapped at %p, irq %d with %d ctx banks\n",
>   iommu->base, iommu->irq, iommu->ncb);
>  
> @@ -875,19 +877,7 @@ static void __exit msm_iommu_driver_exit(void)
>  subsys_initcall(msm_iommu_driver_init);
>  module_exit(msm_iommu_driver_exit);
>  
> -static int __init msm_iommu_init(void)
> -{
> - bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
> - return 0;
> -}
> -
> -static int __init msm_iommu_of_setup(struct device_node *np)
> -{
> - msm_iommu_init();
> - return 0;
> -}
> -
> -IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", msm_iommu_of_setup);
> +IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", NULL);
>  
>  MODULE_LICENSE("GPL v2");
>  MODULE_AUTHOR("Stepan Moskovchenko ");
> 

Reviewed-by: Sricharan R 

Regards,
 Sricharan
-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/4] iommu/msm: Add iommu_group support

2017-07-26 Thread Sricharan R
Hi Robin,

On 7/24/2017 3:25 PM, Robin Murphy wrote:
> On 24/07/17 08:34, Sricharan R wrote:
>> Hi Robin,
>>
>>> As the last step to making groups mandatory, clean up the remaining
>>> drivers by adding basic support. Whilst it may not perfectly reflect the
>>> isolation capabilities of the hardware, using generic_device_group()
>>> should at least maintain existing behaviour with respect to the API.
>>>
>>> Signed-off-by: Robin Murphy 
>>> ---
>>>  drivers/iommu/msm_iommu.c | 15 ++-
>>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
>>> index d0448353d501..04f4d51ffacb 100644
>>> --- a/drivers/iommu/msm_iommu.c
>>> +++ b/drivers/iommu/msm_iommu.c
>>> @@ -393,6 +393,7 @@ static struct msm_iommu_dev *find_iommu_for_dev(struct 
>>> device *dev)
>>>  static int msm_iommu_add_device(struct device *dev)
>>>  {
>>> struct msm_iommu_dev *iommu;
>>> +   struct iommu_group *group;
>>> unsigned long flags;
>>> int ret = 0;
>>>  
>>> @@ -406,7 +407,16 @@ static int msm_iommu_add_device(struct device *dev)
>>>  
>>> spin_unlock_irqrestore(&msm_iommu_lock, flags);
>>>  
>>> -   return ret;
>>> +   if (ret)
>>> +   return ret;
>>> +
>>> +   group = iommu_group_get_for_dev(dev);
>>> +   if (IS_ERR(group))
>>> +   return PTR_ERR(group);
>>> +
>>> +   iommu_group_put(group);
>>> +
>>> +   return 0;
>>>  }
>>>  
>>
>>  While this is correct for completing the group support, this adds the 
>> default domain and
>>  that might break in the driver while attaching a private domain. The 
>> msm_iomm_attach_dev
>>  needs to be fixed by calling msm_iommu_detach_dev while trying to attach a 
>> new domain when
>>  already connected to a default one. But let me test and confirm this.
> 
> The default domain shouldn't matter, since msm_iommu_domain_alloc() will
> refuse to create DMA ops or identity domains in the first place. In the
> absence of a default domain, __iommu_detach_group() will still end up
> calling ops->detach_dev, so I don't think the ultimate behaviour is any
> different with this change. Testing is of course welcome, though ;)

 Ha, you are right. Sorry, overlooked that only DOMAIN_UNMANAGED is supported 
here.
 Meanwhile, lost access to the board. So would give test feedback once i get it.

 Otherwise, Reviewed-by: sricha...@codeaurora.org

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

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


Re: [PATCH 1/4] iommu/msm: Add iommu_group support

2017-07-24 Thread Sricharan R
Hi Robin,

> As the last step to making groups mandatory, clean up the remaining
> drivers by adding basic support. Whilst it may not perfectly reflect the
> isolation capabilities of the hardware, using generic_device_group()
> should at least maintain existing behaviour with respect to the API.
> 
> Signed-off-by: Robin Murphy 
> ---
>  drivers/iommu/msm_iommu.c | 15 ++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index d0448353d501..04f4d51ffacb 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -393,6 +393,7 @@ static struct msm_iommu_dev *find_iommu_for_dev(struct 
> device *dev)
>  static int msm_iommu_add_device(struct device *dev)
>  {
>   struct msm_iommu_dev *iommu;
> + struct iommu_group *group;
>   unsigned long flags;
>   int ret = 0;
>  
> @@ -406,7 +407,16 @@ static int msm_iommu_add_device(struct device *dev)
>  
>   spin_unlock_irqrestore(&msm_iommu_lock, flags);
>  
> - return ret;
> + if (ret)
> + return ret;
> +
> + group = iommu_group_get_for_dev(dev);
> + if (IS_ERR(group))
> + return PTR_ERR(group);
> +
> + iommu_group_put(group);
> +
> + return 0;
>  }
>  

 While this is correct for completing the group support, this adds the default 
domain and
 that might break in the driver while attaching a private domain. The 
msm_iomm_attach_dev
 needs to be fixed by calling msm_iommu_detach_dev while trying to attach a new 
domain when
 already connected to a default one. But let me test and confirm this.

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

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


Re: [PATCH 1/2] iommu/arm-smmu: Track context bank state

2017-07-18 Thread Sricharan R
Hi Robin,

On 7/18/2017 6:14 PM, Robin Murphy wrote:
> Echoing what we do for Stream Map Entries, maintain a software shadow
> state for context bank configuration. With this in place, we are mere
> moments away from blissfully easy suspend/resume support.
> 
> Signed-off-by: Robin Murphy 
> ---
> 
> Since the runtime PM discussion has come back again, I figured it was
> probably about time to finish off my plan for system PM. Lightly tested
> on Juno (MMU-401) with hibernation.
> 
> Robin.
> 
>  drivers/iommu/arm-smmu.c | 159 
> +--
>  1 file changed, 97 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index bc89b4d6c043..86897b7b81d8 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -338,6 +338,13 @@ struct arm_smmu_smr {
>   boolvalid;
>  };
>  
> +struct arm_smmu_cb {
> + u64 ttbr[2];
> + u32 tcr[2];
> + u32 mair[2];
> + struct arm_smmu_cfg *cfg;
> +};
> +

 When i was trying this sometime back [1], was
 saving and using the pgtbl->cfg and domain->cfg for
 restoring the context. But this looks correct to make
 a actual shadow once and use it later all the time.
 Will also try some testing today.

 Reviewed-by: sricha...@codeaurora.org

[1] https://patchwork.kernel.org/patch/9389717/

Regards,
 Sricharan


>  struct arm_smmu_master_cfg {
>   struct arm_smmu_device  *smmu;
>   s16 smendx[];
> @@ -380,6 +387,7 @@ struct arm_smmu_device {
>   u32 num_context_banks;
>   u32 num_s2_context_banks;
>   DECLARE_BITMAP(context_map, ARM_SMMU_MAX_CBS);
> + struct arm_smmu_cb  *cbs;
>   atomic_tirptndx;
>  
>   u32 num_mapping_groups;
> @@ -768,17 +776,69 @@ static irqreturn_t arm_smmu_global_fault(int irq, void 
> *dev)
>  static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
>  struct io_pgtable_cfg *pgtbl_cfg)
>  {
> - u32 reg, reg2;
> - u64 reg64;
> - bool stage1;
>   struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
> - struct arm_smmu_device *smmu = smmu_domain->smmu;
> + struct arm_smmu_cb *cb = &smmu_domain->smmu->cbs[cfg->cbndx];
> + bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
> +
> + cb->cfg = cfg;
> +
> + /* TTBCR */
> + if (stage1) {
> + if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
> + cb->tcr[0] = pgtbl_cfg->arm_v7s_cfg.tcr;
> + } else {
> + cb->tcr[0] = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
> + cb->tcr[1] = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
> + cb->tcr[1] |= TTBCR2_SEP_UPSTREAM;
> + if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
> + cb->tcr[1] |= TTBCR2_AS;
> + }
> + } else {
> + cb->tcr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
> + }
> +
> + /* TTBRs */
> + if (stage1) {
> + if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
> + cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr[0];
> + cb->ttbr[1] = pgtbl_cfg->arm_v7s_cfg.ttbr[1];
> + } else {
> + cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
> + cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
> + }
> + } else {
> + cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
> + }
> +
> + /* MAIRs (stage-1 only) */
> + if (stage1) {
> + if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
> + cb->mair[0] = pgtbl_cfg->arm_v7s_cfg.prrr;
> + cb->mair[1] = pgtbl_cfg->arm_v7s_cfg.nmrr;
> + } else {
> + cb->mair[0] = pgtbl_cfg->arm_lpae_s1_cfg.mair[0];
> + cb->mair[1] = pgtbl_cfg->arm_lpae_s1_cfg.mair[1];
> + }
> + }
> +}
> +
> +static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int 
> idx)
> +{
> + u32 reg;
> + bool stage1;
> + struct arm_smmu_cb *cb = &smmu->cbs[idx];
> + struct arm_smmu_cfg *cfg = cb->cfg;
> + struct arm_smmu_cfg default_cfg = {0};
>   void __iomem *cb_base, *gr1_base;
>  

Re: [PATCH V4 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2017-07-17 Thread Sricharan R
Hi,

On 7/17/2017 5:16 PM, Sricharan R wrote:
> Hi,
> 
> On 7/15/2017 1:09 AM, Rob Clark wrote:
>> On Fri, Jul 14, 2017 at 3:36 PM, Will Deacon  wrote:
>>> On Fri, Jul 14, 2017 at 03:34:42PM -0400, Rob Clark wrote:
>>>> On Fri, Jul 14, 2017 at 3:01 PM, Will Deacon  wrote:
>>>>> On Fri, Jul 14, 2017 at 02:25:45PM -0400, Rob Clark wrote:
>>>>>> On Fri, Jul 14, 2017 at 2:06 PM, Will Deacon  wrote:
>>>>>>> On Fri, Jul 14, 2017 at 01:42:13PM -0400, Rob Clark wrote:
>>>>>>>> On Fri, Jul 14, 2017 at 1:07 PM, Will Deacon  
>>>>>>>> wrote:
>>>>>>>>> On Thu, Jul 13, 2017 at 10:55:10AM -0400, Rob Clark wrote:
>>>>>>>>>> On Thu, Jul 13, 2017 at 9:53 AM, Sricharan R 
>>>>>>>>>>  wrote:
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> On 7/13/2017 5:20 PM, Rob Clark wrote:
>>>>>>>>>>>> On Thu, Jul 13, 2017 at 1:35 AM, Sricharan R 
>>>>>>>>>>>>  wrote:
>>>>>>>>>>>>> Hi Vivek,
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 7/13/2017 10:43 AM, Vivek Gautam wrote:
>>>>>>>>>>>>>> Hi Stephen,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 07/13/2017 04:24 AM, Stephen Boyd wrote:
>>>>>>>>>>>>>>> On 07/06, Vivek Gautam wrote:
>>>>>>>>>>>>>>>> @@ -1231,12 +1237,18 @@ static int arm_smmu_map(struct 
>>>>>>>>>>>>>>>> iommu_domain *domain, unsigned long iova,
>>>>>>>>>>>>>>>>   static size_t arm_smmu_unmap(struct iommu_domain *domain, 
>>>>>>>>>>>>>>>> unsigned long iova,
>>>>>>>>>>>>>>>>size_t size)
>>>>>>>>>>>>>>>>   {
>>>>>>>>>>>>>>>> -struct io_pgtable_ops *ops = 
>>>>>>>>>>>>>>>> to_smmu_domain(domain)->pgtbl_ops;
>>>>>>>>>>>>>>>> +struct arm_smmu_domain *smmu_domain = 
>>>>>>>>>>>>>>>> to_smmu_domain(domain);
>>>>>>>>>>>>>>>> +struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
>>>>>>>>>>>>>>>> +size_t ret;
>>>>>>>>>>>>>>>> if (!ops)
>>>>>>>>>>>>>>>>   return 0;
>>>>>>>>>>>>>>>>   -return ops->unmap(ops, iova, size);
>>>>>>>>>>>>>>>> +pm_runtime_get_sync(smmu_domain->smmu->dev);
>>>>>>>>>>>>>>> Can these map/unmap ops be called from an atomic context? I seem
>>>>>>>>>>>>>>> to recall that being a problem before.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> That's something which was dropped in the following patch merged 
>>>>>>>>>>>>>> in master:
>>>>>>>>>>>>>> 523d7423e21b iommu/arm-smmu: Remove io-pgtable spinlock
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Looks like we don't  need locks here anymore?
>>>>>>>>>>>>>
>>>>>>>>>>>>>  Apart from the locking, wonder why a explicit pm_runtime is 
>>>>>>>>>>>>> needed
>>>>>>>>>>>>>  from unmap. Somehow looks like some path in the master using that
>>>>>>>>>>>>>  should have enabled the pm ?
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Yes, there are a bunch of scenarios where unmap can happen with
>>>>>>>>>>>> disabled master (but not in atomic context).  On the gpu side we
>>>>>>>>>>

Re: [PATCH V4 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2017-07-17 Thread Sricharan R
Hi,

On 7/15/2017 1:09 AM, Rob Clark wrote:
> On Fri, Jul 14, 2017 at 3:36 PM, Will Deacon  wrote:
>> On Fri, Jul 14, 2017 at 03:34:42PM -0400, Rob Clark wrote:
>>> On Fri, Jul 14, 2017 at 3:01 PM, Will Deacon  wrote:
>>>> On Fri, Jul 14, 2017 at 02:25:45PM -0400, Rob Clark wrote:
>>>>> On Fri, Jul 14, 2017 at 2:06 PM, Will Deacon  wrote:
>>>>>> On Fri, Jul 14, 2017 at 01:42:13PM -0400, Rob Clark wrote:
>>>>>>> On Fri, Jul 14, 2017 at 1:07 PM, Will Deacon  
>>>>>>> wrote:
>>>>>>>> On Thu, Jul 13, 2017 at 10:55:10AM -0400, Rob Clark wrote:
>>>>>>>>> On Thu, Jul 13, 2017 at 9:53 AM, Sricharan R 
>>>>>>>>>  wrote:
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> On 7/13/2017 5:20 PM, Rob Clark wrote:
>>>>>>>>>>> On Thu, Jul 13, 2017 at 1:35 AM, Sricharan R 
>>>>>>>>>>>  wrote:
>>>>>>>>>>>> Hi Vivek,
>>>>>>>>>>>>
>>>>>>>>>>>> On 7/13/2017 10:43 AM, Vivek Gautam wrote:
>>>>>>>>>>>>> Hi Stephen,
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 07/13/2017 04:24 AM, Stephen Boyd wrote:
>>>>>>>>>>>>>> On 07/06, Vivek Gautam wrote:
>>>>>>>>>>>>>>> @@ -1231,12 +1237,18 @@ static int arm_smmu_map(struct 
>>>>>>>>>>>>>>> iommu_domain *domain, unsigned long iova,
>>>>>>>>>>>>>>>   static size_t arm_smmu_unmap(struct iommu_domain *domain, 
>>>>>>>>>>>>>>> unsigned long iova,
>>>>>>>>>>>>>>>size_t size)
>>>>>>>>>>>>>>>   {
>>>>>>>>>>>>>>> -struct io_pgtable_ops *ops = 
>>>>>>>>>>>>>>> to_smmu_domain(domain)->pgtbl_ops;
>>>>>>>>>>>>>>> +struct arm_smmu_domain *smmu_domain = 
>>>>>>>>>>>>>>> to_smmu_domain(domain);
>>>>>>>>>>>>>>> +struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
>>>>>>>>>>>>>>> +size_t ret;
>>>>>>>>>>>>>>> if (!ops)
>>>>>>>>>>>>>>>   return 0;
>>>>>>>>>>>>>>>   -return ops->unmap(ops, iova, size);
>>>>>>>>>>>>>>> +pm_runtime_get_sync(smmu_domain->smmu->dev);
>>>>>>>>>>>>>> Can these map/unmap ops be called from an atomic context? I seem
>>>>>>>>>>>>>> to recall that being a problem before.
>>>>>>>>>>>>>
>>>>>>>>>>>>> That's something which was dropped in the following patch merged 
>>>>>>>>>>>>> in master:
>>>>>>>>>>>>> 523d7423e21b iommu/arm-smmu: Remove io-pgtable spinlock
>>>>>>>>>>>>>
>>>>>>>>>>>>> Looks like we don't  need locks here anymore?
>>>>>>>>>>>>
>>>>>>>>>>>>  Apart from the locking, wonder why a explicit pm_runtime is needed
>>>>>>>>>>>>  from unmap. Somehow looks like some path in the master using that
>>>>>>>>>>>>  should have enabled the pm ?
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Yes, there are a bunch of scenarios where unmap can happen with
>>>>>>>>>>> disabled master (but not in atomic context).  On the gpu side we
>>>>>>>>>>> opportunistically keep a buffer mapping until the buffer is freed
>>>>>>>>>>> (which can happen after gpu is disabled).  Likewise, v4l2 won't 
>>>>>>>>>>> unmap
>>>>>>>>>>> an exported dmabuf while some other driver holds a referen

Re: [PATCH V4 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2017-07-13 Thread Sricharan R
Hi,

On 7/13/2017 5:20 PM, Rob Clark wrote:
> On Thu, Jul 13, 2017 at 1:35 AM, Sricharan R  wrote:
>> Hi Vivek,
>>
>> On 7/13/2017 10:43 AM, Vivek Gautam wrote:
>>> Hi Stephen,
>>>
>>>
>>> On 07/13/2017 04:24 AM, Stephen Boyd wrote:
>>>> On 07/06, Vivek Gautam wrote:
>>>>> @@ -1231,12 +1237,18 @@ static int arm_smmu_map(struct iommu_domain 
>>>>> *domain, unsigned long iova,
>>>>>   static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long 
>>>>> iova,
>>>>>size_t size)
>>>>>   {
>>>>> -struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
>>>>> +struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>>>>> +struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
>>>>> +size_t ret;
>>>>> if (!ops)
>>>>>   return 0;
>>>>>   -return ops->unmap(ops, iova, size);
>>>>> +pm_runtime_get_sync(smmu_domain->smmu->dev);
>>>> Can these map/unmap ops be called from an atomic context? I seem
>>>> to recall that being a problem before.
>>>
>>> That's something which was dropped in the following patch merged in master:
>>> 523d7423e21b iommu/arm-smmu: Remove io-pgtable spinlock
>>>
>>> Looks like we don't  need locks here anymore?
>>
>>  Apart from the locking, wonder why a explicit pm_runtime is needed
>>  from unmap. Somehow looks like some path in the master using that
>>  should have enabled the pm ?
>>
> 
> Yes, there are a bunch of scenarios where unmap can happen with
> disabled master (but not in atomic context).  On the gpu side we
> opportunistically keep a buffer mapping until the buffer is freed
> (which can happen after gpu is disabled).  Likewise, v4l2 won't unmap
> an exported dmabuf while some other driver holds a reference to it
> (which can be dropped when the v4l2 device is suspended).
> 
> Since unmap triggers tbl flush which touches iommu regs, the iommu
> driver *definitely* needs a pm_runtime_get_sync().

 Ok, with that being the case, there are two things here,

 1) If the device links are still intact at these places where unmap is called,
then pm_runtime from the master would setup the all the clocks. That would
avoid reintroducing the locking indirectly here.

 2) If not, then doing it here is the only way. But for both cases, since
the unmap can be called from atomic context, resume handler here should
avoid doing clk_prepare_enable , instead move the clk_prepare to the init.

Regards,
 Sricharan


-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

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


Re: [PATCH V4 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2017-07-12 Thread Sricharan R
Hi Vivek,

On 7/13/2017 10:43 AM, Vivek Gautam wrote:
> Hi Stephen,
> 
> 
> On 07/13/2017 04:24 AM, Stephen Boyd wrote:
>> On 07/06, Vivek Gautam wrote:
>>> @@ -1231,12 +1237,18 @@ static int arm_smmu_map(struct iommu_domain 
>>> *domain, unsigned long iova,
>>>   static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long 
>>> iova,
>>>size_t size)
>>>   {
>>> -struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
>>> +struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>>> +struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
>>> +size_t ret;
>>> if (!ops)
>>>   return 0;
>>>   -return ops->unmap(ops, iova, size);
>>> +pm_runtime_get_sync(smmu_domain->smmu->dev);
>> Can these map/unmap ops be called from an atomic context? I seem
>> to recall that being a problem before.
> 
> That's something which was dropped in the following patch merged in master:
> 523d7423e21b iommu/arm-smmu: Remove io-pgtable spinlock
> 
> Looks like we don't  need locks here anymore?

 Apart from the locking, wonder why a explicit pm_runtime is needed
 from unmap. Somehow looks like some path in the master using that
 should have enabled the pm ?

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

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


Re: [PATCH v6 3/6] ACPI/IORT: Ignore all errors except EPROBE_DEFER

2017-05-28 Thread Sricharan R
Hi Rafael,

On 5/28/2017 12:48 AM, Rafael J. Wysocki wrote:
> On Saturday, May 27, 2017 07:17:42 PM Sricharan R wrote:
>> While deferring the probe of IOMMU masters, xlate and
>> add_device callbacks called from iort_iommu_configure
>> can pass back error values like -ENODEV, which means
>> the IOMMU cannot be connected with that master for real
>> reasons. Before the IOMMU probe deferral, all such errors
>> were ignored. Now all those errors are propagated back,
>> killing the master's probe for such errors. Instead ignore
>> all the errors except EPROBE_DEFER, which is the only one
>> of concern and let the master work without IOMMU, thus
>> restoring the old behavior. Also make explicit that
>> acpi_dma_configure handles only -EPROBE_DEFER from
>> iort_iommu_configure.
>>
>> Fixes: 5a1bb638d567 ("drivers: acpi: Handle IOMMU lookup failure with 
>> deferred probing or error")
>> Signed-off-by: Sricharan R 
>> ---
>>  drivers/acpi/arm64/iort.c | 6 ++
>>  drivers/acpi/scan.c   | 4 ++--
>>  2 files changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index c5fecf9..16e101f 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct 
>> device *dev)
>>  if (err)
>>  ops = ERR_PTR(err);
>>  
>> +/* Ignore all other errors apart from EPROBE_DEFER */
>> +if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
>> +dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
>> +ops = NULL;
>> +}
>> +
>>  return ops;
>>  }
>>  
>> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
>> index e39ec7b..3a10d757 100644
>> --- a/drivers/acpi/scan.c
>> +++ b/drivers/acpi/scan.c
>> @@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum 
>> dev_dma_attr attr)
>>  iort_set_dma_mask(dev);
>>  
>>  iommu = iort_iommu_configure(dev);
>> -if (IS_ERR(iommu))
>> -return PTR_ERR(iommu);
>> +if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
>> +return -EPROBE_DEFER;
>>  
>>  size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>>  /*
>>
> 
> ACK for the scan.c change and I'm assuming this to go in via ARM64.
> 

Thanks for the ACK, should go through the IOMMU tree, since this fixes the 
IOMMU probe deferral
that got merged through it.

Regards,
 Sricharan

> Thanks,
> Rafael
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v6 4/6] ARM: dma-mapping: Don't tear down third-party mappings

2017-05-27 Thread Sricharan R
From: Laurent Pinchart 

arch_setup_dma_ops() is used in device probe code paths to create an
IOMMU mapping and attach it to the device. The function assumes that the
device is attached to a device-specific IOMMU instance (or at least a
device-specific TLB in a shared IOMMU instance) and thus creates a
separate mapping for every device.

On several systems (Renesas R-Car Gen2 being one of them), that
assumption is not true, and IOMMU mappings must be shared between
multiple devices. In those cases the IOMMU driver knows better than the
generic ARM dma-mapping layer and attaches mapping to devices manually
with arm_iommu_attach_device(), which sets the DMA ops for the device.

The arch_setup_dma_ops() function takes this into account and bails out
immediately if the device already has DMA ops assigned. However, the
corresponding arch_teardown_dma_ops() function, called from driver
unbind code paths (including probe deferral), will tear the mapping down
regardless of who created it. When the device is reprobed
arch_setup_dma_ops() will be called again but won't perform any
operation as the DMA ops will still be set.

We need to reset the DMA ops in arch_teardown_dma_ops() to fix this.
However, we can't do so unconditionally, as then a new mapping would be
created by arch_setup_dma_ops() when the device is reprobed, regardless
of whether the device needs to share a mapping or not. We must thus keep
track of whether arch_setup_dma_ops() created the mapping, and only in
that case tear it down in arch_teardown_dma_ops().

Keep track of that information in the dev_archdata structure. As the
structure is embedded in all instances of struct device let's not grow
it, but turn the existing dma_coherent bool field into a bitfield that
can be used for other purposes.

Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for 
platform/amba/pci bus devices")
Reviewed-by: Robin Murphy 
Signed-off-by: Laurent Pinchart 
---
 arch/arm/include/asm/device.h | 3 ++-
 arch/arm/mm/dma-mapping.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 36ec9c8..3234fe9 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -19,7 +19,8 @@ struct dev_archdata {
 #ifdef CONFIG_XEN
const struct dma_map_ops *dev_dma_ops;
 #endif
-   bool dma_coherent;
+   unsigned int dma_coherent:1;
+   unsigned int dma_ops_setup:1;
 };
 
 struct omap_device;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c742dfd..b48998f 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2430,9 +2430,13 @@ void arch_setup_dma_ops(struct device *dev, u64 
dma_base, u64 size,
dev->dma_ops = xen_dma_ops;
}
 #endif
+   dev->archdata.dma_ops_setup = true;
 }
 
 void arch_teardown_dma_ops(struct device *dev)
 {
+   if (!dev->archdata.dma_ops_setup)
+   return;
+
arm_teardown_iommu_dma_ops(dev);
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 6/6] arm: dma-mapping: Reset the device's dma_ops

2017-05-27 Thread Sricharan R
arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops()
,dma_ops should be cleared in the teardown path. Currently, only the
device's iommu mapping structures are cleared in arch_teardown_dma_ops,
but not the dma_ops. So on the next reprobe, dma_ops left in place is
stale from the first IOMMU setup, but iommu mappings has been disposed
of. This is a problem when the probe of the device is deferred and
recalled with the IOMMU probe deferral.

So for fixing this, slightly refactor by moving the code from
__arm_iommu_detach_device to arm_iommu_detach_device and cleanup
the former. This takes care of resetting the dma_ops in the teardown
path.

Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for 
platform/amba/pci bus devices")
Reviewed-by: Laurent Pinchart 
Signed-off-by: Sricharan R 
---
 arch/arm/mm/dma-mapping.c | 25 ++---
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index b48998f..bd83c53 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2311,7 +2311,14 @@ int arm_iommu_attach_device(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
 
-static void __arm_iommu_detach_device(struct device *dev)
+/**
+ * arm_iommu_detach_device
+ * @dev: valid struct device pointer
+ *
+ * Detaches the provided device from a previously attached map.
+ * This voids the dma operations (dma_map_ops pointer)
+ */
+void arm_iommu_detach_device(struct device *dev)
 {
struct dma_iommu_mapping *mapping;
 
@@ -2324,22 +2331,10 @@ static void __arm_iommu_detach_device(struct device 
*dev)
iommu_detach_device(mapping->domain, dev);
kref_put(&mapping->kref, release_iommu_mapping);
to_dma_iommu_mapping(dev) = NULL;
+   set_dma_ops(dev, NULL);
 
pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
 }
-
-/**
- * arm_iommu_detach_device
- * @dev: valid struct device pointer
- *
- * Detaches the provided device from a previously attached map.
- * This voids the dma operations (dma_map_ops pointer)
- */
-void arm_iommu_detach_device(struct device *dev)
-{
-   __arm_iommu_detach_device(dev);
-   set_dma_ops(dev, NULL);
-}
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
 static const struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
@@ -2379,7 +2374,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
if (!mapping)
return;
 
-   __arm_iommu_detach_device(dev);
+   arm_iommu_detach_device(dev);
arm_iommu_release_mapping(mapping);
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 3/6] ACPI/IORT: Ignore all errors except EPROBE_DEFER

2017-05-27 Thread Sricharan R
While deferring the probe of IOMMU masters, xlate and
add_device callbacks called from iort_iommu_configure
can pass back error values like -ENODEV, which means
the IOMMU cannot be connected with that master for real
reasons. Before the IOMMU probe deferral, all such errors
were ignored. Now all those errors are propagated back,
killing the master's probe for such errors. Instead ignore
all the errors except EPROBE_DEFER, which is the only one
of concern and let the master work without IOMMU, thus
restoring the old behavior. Also make explicit that
acpi_dma_configure handles only -EPROBE_DEFER from
iort_iommu_configure.

Fixes: 5a1bb638d567 ("drivers: acpi: Handle IOMMU lookup failure with deferred 
probing or error")
Signed-off-by: Sricharan R 
---
 drivers/acpi/arm64/iort.c | 6 ++
 drivers/acpi/scan.c   | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf9..16e101f 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct device 
*dev)
if (err)
ops = ERR_PTR(err);
 
+   /* Ignore all other errors apart from EPROBE_DEFER */
+   if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
+   dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
+   ops = NULL;
+   }
+
return ops;
 }
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e39ec7b..3a10d757 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum 
dev_dma_attr attr)
iort_set_dma_mask(dev);
 
iommu = iort_iommu_configure(dev);
-   if (IS_ERR(iommu))
-   return PTR_ERR(iommu);
+   if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
 
size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
/*
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 5/6] ACPI/IORT: Move the check to get iommu_ops from translated fwspec

2017-05-27 Thread Sricharan R
From: Lorenzo Pieralisi 

With IOMMU probe deferral, iort_iommu_configure can be called
multiple times for the same device. Hence we have a check
to see if the device's fwspec is already translated and return
the iommu_ops from that directly. But the check is wrongly
placed in iort_iommu_xlate, which breaks devices with multiple
sids. Move the check to iort_iommu_configure.

Fixes: 5a1bb638d567 ("drivers: acpi: Handle IOMMU lookup failure with deferred 
probing or error")
Tested-by: Nate Watterson 
Signed-off-by: Lorenzo Pieralisi 
---
 drivers/acpi/arm64/iort.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 16e101f..797b28d 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
device *dev,
int ret = -ENODEV;
struct fwnode_handle *iort_fwnode;
 
-   /*
-* If we already translated the fwspec there
-* is nothing left to do, return the iommu_ops.
-*/
-   ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
-   if (ops)
-   return ops;
-
if (node) {
iort_fwnode = iort_get_fwnode(node);
if (!iort_fwnode)
@@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device 
*dev)
u32 streamid = 0;
int err;
 
+   /*
+* If we already translated the fwspec there
+* is nothing left to do, return the iommu_ops.
+*/
+   ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
+   if (ops)
+   return ops;
+
if (dev_is_pci(dev)) {
struct pci_bus *bus = to_pci_dev(dev)->bus;
u32 rid;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 1/6] iommu: of: Fix check for returning EPROBE_DEFER

2017-05-27 Thread Sricharan R
Now with IOMMU probe deferral, we return -EPROBE_DEFER
for masters that are connected to an IOMMU which is not
probed yet, but going to get probed, so that we can attach
the correct dma_ops. So while trying to defer the probe of
the master, check if the of_iommu node that it is connected
to is marked in DT as 'status=disabled', then the IOMMU is never
is going to get probed. So simply return NULL and let the master
work without an IOMMU.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Reported-by: Geert Uytterhoeven 
Reviewed-by: Laurent Pinchart 
Tested-by: Will Deacon 
Tested-by: Magnus Damn 
Acked-by: Will Deacon 
Signed-off-by: Sricharan R 
---
 drivers/iommu/of_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 9f44ee8..e6e9bec 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node *np)
 
ops = iommu_ops_from_fwnode(fwnode);
if ((ops && !ops->of_xlate) ||
+   !of_device_is_available(iommu_spec->np) ||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 2/6] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-27 Thread Sricharan R
While deferring the probe of IOMMU masters, xlate and
add_device callbacks called from of_iommu_configure
can pass back error values like -ENODEV, which means
the IOMMU cannot be connected with that master for real
reasons. Before the IOMMU probe deferral, all such errors
were ignored. Now all those errors are propagated back,
killing the master's probe for such errors. Instead ignore
all the errors except EPROBE_DEFER, which is the only one
of concern and let the master work without IOMMU, thus
restoring the old behavior. Also make explicit that
of_dma_configure handles only -EPROBE_DEFER from
of_iommu_configure.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Reported-by: Geert Uytterhoeven 
Tested-by: Magnus Damn 
Signed-off-by: Sricharan R 
---
 drivers/iommu/of_iommu.c | 6 ++
 drivers/of/device.c  | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e6e9bec..19779b8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -237,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
ops = ERR_PTR(err);
}
 
+   /* Ignore all other errors apart from EPROBE_DEFER */
+   if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
+   dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
+   ops = NULL;
+   }
+
return ops;
 }
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 9416d05..28c38c7 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -144,8 +144,8 @@ int of_dma_configure(struct device *dev, struct device_node 
*np)
coherent ? " " : " not ");
 
iommu = of_iommu_configure(dev, np);
-   if (IS_ERR(iommu))
-   return PTR_ERR(iommu);
+   if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
 
dev_dbg(dev, "device is%sbehind an iommu\n",
iommu ? " " : " not ");
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH v2] arm: dma-mapping: Reset the device's dma_ops

2017-05-26 Thread Sricharan R
Hi Laurent,

On 5/26/2017 7:44 PM, Laurent Pinchart wrote:
> Hi Sricharan,
> 
> Thank you for the patch.
> 
> On Friday 26 May 2017 16:13:37 Sricharan R wrote:
>> arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops()
>> ,dma_ops should be cleared in the teardown path. Currently, only the
>> device's iommu mapping structures are cleared in arch_teardown_dma_ops,
>> but not the dma_ops. So on the next reprobe, dma_ops left in place is
>> stale from the first IOMMU setup, but iommu mappings has been disposed
>> of. This is a problem when the probe of the device is deferred and
>> recalled with the IOMMU probe deferral.
>>
>> So for fixing this, slightly refactor by moving the code from
>> __arm_iommu_detach_device to arm_iommu_detach_device and cleanup
>> the former. This takes care of resetting the dma_ops in the teardown
>> path.
>>
>> Signed-off-by: Sricharan R 
>> Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for
>> platform/amba/pci bus devices")
> 
> Reviewed-by: Laurent Pinchart 
> 
> Could you please push this upstream along with "[PATCH] ARM: dma-mapping: 
> Don't tear third-party mappings" ?
> 
> (And feel free to s/tear/tear down/ in the subject of that patch, I've only 
> noticed now that I forgot one word)

ok, will change the above and post it with the other patches.

Regards,
 Sricharan

> 
>> ---
>>  arch/arm/mm/dma-mapping.c | 25 ++---
>>  1 file changed, 10 insertions(+), 15 deletions(-)
>>
>> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
>> index c742dfd..6e82e87 100644
>> --- a/arch/arm/mm/dma-mapping.c
>> +++ b/arch/arm/mm/dma-mapping.c
>> @@ -2311,7 +2311,14 @@ int arm_iommu_attach_device(struct device *dev,
>>  }
>>  EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
>>
>> -static void __arm_iommu_detach_device(struct device *dev)
>> +/**
>> + * arm_iommu_detach_device
>> + * @dev: valid struct device pointer
>> + *
>> + * Detaches the provided device from a previously attached map.
>> + * This voids the dma operations (dma_map_ops pointer)
>> + */
>> +void arm_iommu_detach_device(struct device *dev)
>>  {
>>  struct dma_iommu_mapping *mapping;
>>
>> @@ -2324,22 +2331,10 @@ static void __arm_iommu_detach_device(struct device
>> *dev) iommu_detach_device(mapping->domain, dev);
>>  kref_put(&mapping->kref, release_iommu_mapping);
>>  to_dma_iommu_mapping(dev) = NULL;
>> +set_dma_ops(dev, NULL);
>>
>>  pr_debug("Detached IOMMU controller from %s device.\n", 
> dev_name(dev));
>>  }
>> -
>> -/**
>> - * arm_iommu_detach_device
>> - * @dev: valid struct device pointer
>> - *
>> - * Detaches the provided device from a previously attached map.
>> - * This voids the dma operations (dma_map_ops pointer)
>> - */
>> -void arm_iommu_detach_device(struct device *dev)
>> -{
>> -__arm_iommu_detach_device(dev);
>> -set_dma_ops(dev, NULL);
>> -}
>>  EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
>>
>>  static const struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
>> @@ -2379,7 +2374,7 @@ static void arm_teardown_iommu_dma_ops(struct device
>> *dev) if (!mapping)
>>  return;
>>
>> -__arm_iommu_detach_device(dev);
>> +arm_iommu_detach_device(dev);
>>  arm_iommu_release_mapping(mapping);
>>  }
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2] arm: dma-mapping: Reset the device's dma_ops

2017-05-26 Thread Sricharan R
arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops()
,dma_ops should be cleared in the teardown path. Currently, only the
device's iommu mapping structures are cleared in arch_teardown_dma_ops,
but not the dma_ops. So on the next reprobe, dma_ops left in place is
stale from the first IOMMU setup, but iommu mappings has been disposed
of. This is a problem when the probe of the device is deferred and
recalled with the IOMMU probe deferral.

So for fixing this, slightly refactor by moving the code from
__arm_iommu_detach_device to arm_iommu_detach_device and cleanup
the former. This takes care of resetting the dma_ops in the teardown
path.

Signed-off-by: Sricharan R 
Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for 
platform/amba/pci bus devices")
---
 arch/arm/mm/dma-mapping.c | 25 ++---
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c742dfd..6e82e87 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2311,7 +2311,14 @@ int arm_iommu_attach_device(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
 
-static void __arm_iommu_detach_device(struct device *dev)
+/**
+ * arm_iommu_detach_device
+ * @dev: valid struct device pointer
+ *
+ * Detaches the provided device from a previously attached map.
+ * This voids the dma operations (dma_map_ops pointer)
+ */
+void arm_iommu_detach_device(struct device *dev)
 {
struct dma_iommu_mapping *mapping;
 
@@ -2324,22 +2331,10 @@ static void __arm_iommu_detach_device(struct device 
*dev)
iommu_detach_device(mapping->domain, dev);
kref_put(&mapping->kref, release_iommu_mapping);
to_dma_iommu_mapping(dev) = NULL;
+   set_dma_ops(dev, NULL);
 
pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
 }
-
-/**
- * arm_iommu_detach_device
- * @dev: valid struct device pointer
- *
- * Detaches the provided device from a previously attached map.
- * This voids the dma operations (dma_map_ops pointer)
- */
-void arm_iommu_detach_device(struct device *dev)
-{
-   __arm_iommu_detach_device(dev);
-   set_dma_ops(dev, NULL);
-}
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
 static const struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
@@ -2379,7 +2374,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
if (!mapping)
return;
 
-   __arm_iommu_detach_device(dev);
+   arm_iommu_detach_device(dev);
arm_iommu_release_mapping(mapping);
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH V3 6/8] arm: dma-mapping: Reset the device's dma_ops

2017-05-25 Thread Sricharan R
Hi Russell,

On 5/25/2017 8:35 PM, Russell King - ARM Linux wrote:
> On Wed, May 24, 2017 at 02:26:13PM +0300, Laurent Pinchart wrote:
>> Again, the patch I propose is the simplest v4.12-rc fix I can think of, 
>> short 
>> of reverting your complete IOMMU probe deferral patch series. Let's focus on 
>> the v4.12-rc fix, and then discuss how to move forward in v4.13 and beyond.
> 
> Except, I don't think it fixes the problem that Sricharan is trying to
> fix, namely that of DMA ops that have been setup, torn down, and are
> trying to be re-setup again.  The issue here is that results in a stale
> setup, because the dma_ops are left in-place from the first iommu setup,
> but the iommu mapping has been disposed of.
> 
> Your patch only avoids the problem of tearing down someone else's DMA
> ops.  We need a combination of both patches together.
> 
> What needs to happen for Sricharan's problem to be resolved is:
> 
> 1. move all of __arm_iommu_detach_device() into arm_iommu_detach_device().
> 2. replace the __arm_iommu_detach_device() call in 
> arm_teardown_iommu_dma_ops()
>with arm_iommu_detach_device().
> 
> as I don't see any need to have a different order in
> arm_teardown_iommu_dma_ops().
> 

Right, both patches are required and i was also thining the same thing about
using arm_iommu_detach_device from arm_teardown_iommu_dma_ops instead. Will
repost with this.

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V3 6/8] arm: dma-mapping: Reset the device's dma_ops

2017-05-24 Thread Sricharan R
Hi Laurent,

On 5/24/2017 4:56 PM, Laurent Pinchart wrote:
> Hello,
> 
> On Wednesday 24 May 2017 16:01:45 Sricharan R wrote:
>> On 5/24/2017 4:12 AM, Russell King - ARM Linux wrote:
>>> On Wed, May 24, 2017 at 12:46:51AM +0300, Laurent Pinchart wrote:
>>>> On Tuesday 23 May 2017 18:53:19 Russell King - ARM Linux wrote:
>>>>> On Tue, May 23, 2017 at 05:55:57PM +0100, Robin Murphy wrote:
>>>>>> On 23/05/17 17:25, Russell King - ARM Linux wrote:
>>>>>>> So, I've come to apply this patch (since it's finally landed in the
>>>>>>> patch system), and I'm not convinced that the commit message is really
>>>>>>> up to scratch.
>>>>>>>
>>>>>>> The current commit message looks like this:
>>>>>>>
>>>>>>> "   ARM: 8674/1: dma-mapping: Reset the device's dma_ops
>>>>>>>
>>>>>>> arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops(),
>>>>>>> dma_ops should be cleared in the teardown path. Otherwise this
>>>>>>> causes problem when the probe of device is retried after being
>>>>>>> deferred. The device's iommu structures are cleared after
>>>>>>> EPROBEDEFER error, but on the next try dma_ops will still be set
>>>>>>> to old value, which is not right."
>>>>>>>
>>>>>>> It is obviously a fix, but a fix for which patch?  Looking at the
>>>>>>> history, we have "arm: dma-mapping: Don't override dma_ops in
>>>>>>> arch_setup_dma_ops()" which I would have guessed is the appropriate
>>>>>>> one, but this post-dates your patch (it's very recent, v4.12-rc
>>>>>>> recent.)
>>>>>>>
>>>>>>> So, I need more description about the problem you were seeing when
>>>>>>> you first proposed this patch.
>>>>>>>
>>>>>>> How does leaving the dma_ops in place prior to "arm: dma-mapping:
>>>>>>> Don't override dma_ops in arch_setup_dma_ops()" cause problems for
>>>>>>> deferred probing?
>>>>>>>
>>>>>>> What patch is your change trying to fix?  In other words, how far
>>>>>>> back does this patch need to be backported?
>>>>>>
>>>>>> In effect, it's fixing a latent inconsistency that's been present since
>>>>>> its introduction in 4bb25789ed28. However, that has clearly not proven
>>>>>> to be an issue in practice since then. With 09515ef5ddad we start
>>>>>> actually calling arch_teardown_dma_ops() in a manner that might leave
>>>>>> things partially initialised if anyone starts removing and reprobing
>>>>>> drivers, but so far that's still from code inspection[1] rather than
>>>>>> anyone hitting it.
>>>>>>
>>>>>> Given that the changes which tickle it are fresh in -rc1 I'd say
>>>>>> there's no need to backport this, but at the same time it shouldn't do
>>>>>> any damage if you really want to.
>>>>>
>>>>> Well, looking at this, I'm not convinced that much of it is correct.
>>>>>
>>>>> 1) set_dma_ops() is in arch_setup_dma_ops() but this patch adds
>>>>>the unsetting of the DMA ops inside arm_teardown_iommu_dma_ops()
>>>>>rather than arch_teardown_dma_ops().
>>>>>
>>>>>This doesn't strike me as being particularly symmetric.
>>>>>arm_teardown_iommu_dma_ops() is arm_setup_iommu_dma_ops()'s
>>>>>counterpart.
>>>>>
>>>>> 2) arch_setup_dma_ops(), the recent patch to add the existing dma_ops
>>>>>check, and Xen - Xen wants to override the DMA ops if in the
>>>>>initial domain.  It's not clear (at least to me) whether the recent
>>>>>patch adding the dma_ops check took account of this or not.
>>>>>
>>>>> 3) random places seem to fiddle with the dma_ops - notice that
>>>>>arm_iommu_detach_device() sets the dma_ops to NULL.
>>>>>
>>>>>In fact, I think moving __arm_iommu_detach_device() into
>>>>>arm_iommu_detach_device(), calling arm_iommu_det

Re: [PATCH V3 6/8] arm: dma-mapping: Reset the device's dma_ops

2017-05-24 Thread Sricharan R
 Xen (and other 
>> platforms/drivers that set the DMA operations manually) by resetting DMA 
>> operations at device remove() time even if they have been set independently 
>> of 
>> arch_setup_dma_ops().
> 
> That will only occur if the dma ops have been overriden once the DMA
> operations have been setup via arch_setup_dma_ops.  What saves it from
> wholesale NULLing of the DMA operations is the check for a valid
> dma_iommu_mapping structure in arm_teardown_iommu_dma_ops().  This only
> exists when arm_setup_iommu_dma_ops() has attached a mapping to the
> device.
> 

Right, only if the dma ops are set and no dma_iommu_mapping is created for
the device, then arch_teardown_iommu_dma_ops does nothing.

Firstly, this patch for resetting the dma_ops in teardown was required
only when arch_setup_dma_ops has created both the mapping and dma_ops
for the device. Because mappings that were created in arch_setup_dma_ops
are cleared in teardown, so dma ops should also be reset. But this can be 
done by calling arm_iommu_detach_device() from arm_teardown_iommu_dma_ops
to avoid explicitly calling set_dma_ops again, probably this what was
suggested in #3 above ?

Really sorry for the mess, but below cleanups looks required otherwise,

1) set_dma_ops is called for mach-highbank, mach-mevbu during the  
   BUS_NOTIFY_ADD_DEVICE. That should be removed and made to come from
   DT path and arch_setup_dma_ops. dmabounce.c also does set_dma_ops,
   not very sure how to handle that (swiotlb ?), are call
   dmabounce_register_dev during the device's probe instead to have the
   dma_set_ops overriding later in probe ?

2) arm_iommu_attach_device is called from ipmmu-vmsa.c, mtk_iommu_v1.c,
   iommu drivers, from the iommu add_device callback, called
   from BUS_NOTIFY_ADD_DEVICE notifier. This is a problem because,
   with probe-deferral, this can be overridden in arch_setup_dma_ops
   during device probe and cleared in teardown path. But the add_device
   callback notifier is not called again when the device gets reprobed again.
 
   With probe deferral, add_device callback also gets called from
   of_iommu_configure during device probe, so the above drivers should
   be adapted to properly register the iommu_ops to have its add_device
   called from of_iommu_configure path. mtk_iommu_v1.c seems to be fine,
   but ipmmu-vmsa.c should be adapted. otherwise if the devices attached
   to those iommus call arm_iommu_attach_device from its probe path to override
   the default ops set in arch_setup_dma_ops, then all is fine. This seems to
   be the case with exynos_drm_iommu.c, omap3isp/isp.c.

   If the above two are done, the overridding of the default dma_ops and mapping
   should happen after arch_setup_dma_ops is called and also overridden every
   time the device gets reprobed. That should help to get rid of couple of fixes
   that has been added.

3) As Laurent already pointed out earlier, return error codes from some of the
   IOMMU apis needs to standardized.

   Please let me know if its right way of doing it ?

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 5/5] ACPI/IORT: Move the check to get iommu_ops from translated fwspec

2017-05-23 Thread Sricharan R
From: Lorenzo Pieralisi 

With IOMMU probe deferral, iort_iommu_configure can be called
multiple times for the same device. Hence we have a check
to see if the device's fwspec is already translated and return
the iommu_ops from that directly. But the check is wrongly
placed in iort_iommu_xlate, which breaks devices with multiple
sids. Move the check to iort_iommu_configure.

Fixes: 5a1bb638d567 ("drivers: acpi: Handle IOMMU lookup failure with deferred 
probing or error")
Tested-by: Nate Watterson 
Signed-off-by: Lorenzo Pieralisi 
---

[v5] new patch

 drivers/acpi/arm64/iort.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 16e101f..797b28d 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
device *dev,
int ret = -ENODEV;
struct fwnode_handle *iort_fwnode;
 
-   /*
-* If we already translated the fwspec there
-* is nothing left to do, return the iommu_ops.
-*/
-   ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
-   if (ops)
-   return ops;
-
if (node) {
iort_fwnode = iort_get_fwnode(node);
if (!iort_fwnode)
@@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device 
*dev)
u32 streamid = 0;
int err;
 
+   /*
+* If we already translated the fwspec there
+* is nothing left to do, return the iommu_ops.
+*/
+   ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
+   if (ops)
+   return ops;
+
if (dev_is_pci(dev)) {
struct pci_bus *bus = to_pci_dev(dev)->bus;
u32 rid;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 4/5] ARM: dma-mapping: Don't tear third-party mappings

2017-05-23 Thread Sricharan R
From: Laurent Pinchart 

arch_setup_dma_ops() is used in device probe code paths to create an
IOMMU mapping and attach it to the device. The function assumes that the
device is attached to a device-specific IOMMU instance (or at least a
device-specific TLB in a shared IOMMU instance) and thus creates a
separate mapping for every device.

On several systems (Renesas R-Car Gen2 being one of them), that
assumption is not true, and IOMMU mappings must be shared between
multiple devices. In those cases the IOMMU driver knows better than the
generic ARM dma-mapping layer and attaches mapping to devices manually
with arm_iommu_attach_device(), which sets the DMA ops for the device.

The arch_setup_dma_ops() function takes this into account and bails out
immediately if the device already has DMA ops assigned. However, the
corresponding arch_teardown_dma_ops() function, called from driver
unbind code paths (including probe deferral), will tear the mapping down
regardless of who created it. When the device is reprobed
arch_setup_dma_ops() will be called again but won't perform any
operation as the DMA ops will still be set.

We need to reset the DMA ops in arch_teardown_dma_ops() to fix this.
However, we can't do so unconditionally, as then a new mapping would be
created by arch_setup_dma_ops() when the device is reprobed, regardless
of whether the device needs to share a mapping or not. We must thus keep
track of whether arch_setup_dma_ops() created the mapping, and only in
that case tear it down in arch_teardown_dma_ops().

Keep track of that information in the dev_archdata structure. As the
structure is embedded in all instances of struct device let's not grow
it, but turn the existing dma_coherent bool field into a bitfield that
can be used for other purposes.

Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for 
platform/amba/pci bus devices")
Reviewed-by: Robin Murphy 
Signed-off-by: Laurent Pinchart 
---
 arch/arm/include/asm/device.h | 3 ++-
 arch/arm/mm/dma-mapping.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 36ec9c8..3234fe9 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -19,7 +19,8 @@ struct dev_archdata {
 #ifdef CONFIG_XEN
const struct dma_map_ops *dev_dma_ops;
 #endif
-   bool dma_coherent;
+   unsigned int dma_coherent:1;
+   unsigned int dma_ops_setup:1;
 };
 
 struct omap_device;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c742dfd..b48998f 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2430,9 +2430,13 @@ void arch_setup_dma_ops(struct device *dev, u64 
dma_base, u64 size,
dev->dma_ops = xen_dma_ops;
}
 #endif
+   dev->archdata.dma_ops_setup = true;
 }
 
 void arch_teardown_dma_ops(struct device *dev)
 {
+   if (!dev->archdata.dma_ops_setup)
+   return;
+
arm_teardown_iommu_dma_ops(dev);
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 2/5] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-23 Thread Sricharan R
While deferring the probe of IOMMU masters, xlate and
add_device callbacks called from of_iommu_configure
can pass back error values like -ENODEV, which means
the IOMMU cannot be connected with that master for real
reasons. Before the IOMMU probe deferral, all such errors
were ignored. Now all those errors are propagated back,
killing the master's probe for such errors. Instead ignore
all the errors except EPROBE_DEFER, which is the only one
of concern and let the master work without IOMMU, thus
restoring the old behavior. Also make explicit that
of_dma_configure handles only -EPROBE_DEFER from
of_iommu_configure.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Reported-by: Geert Uytterhoeven 
Tested-by: Magnus Damn 
Signed-off-by: Sricharan R 
---
[v5] Added the check in of_dma_configure

 drivers/iommu/of_iommu.c | 6 ++
 drivers/of/device.c  | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e6e9bec..19779b8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -237,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
ops = ERR_PTR(err);
}
 
+   /* Ignore all other errors apart from EPROBE_DEFER */
+   if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
+   dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
+   ops = NULL;
+   }
+
return ops;
 }
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 9416d05..28c38c7 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -144,8 +144,8 @@ int of_dma_configure(struct device *dev, struct device_node 
*np)
coherent ? " " : " not ");
 
iommu = of_iommu_configure(dev, np);
-   if (IS_ERR(iommu))
-   return PTR_ERR(iommu);
+   if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
 
dev_dbg(dev, "device is%sbehind an iommu\n",
iommu ? " " : " not ");
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 1/5] iommu: of: Fix check for returning EPROBE_DEFER

2017-05-23 Thread Sricharan R
Now with IOMMU probe deferral, we return -EPROBE_DEFER
for masters that are connected to an IOMMU which is not
probed yet, but going to get probed, so that we can attach
the correct dma_ops. So while trying to defer the probe of
the master, check if the of_iommu node that it is connected
to is marked in DT as 'status=disabled', then the IOMMU is never
is going to get probed. So simply return NULL and let the master
work without an IOMMU.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Signed-off-by: Sricharan R 
Reported-by: Geert Uytterhoeven 
Reviewed-by: Laurent Pinchart 
Tested-by: Will Deacon 
Tested-by: Magnus Damn 
Acked-by: Will Deacon 
---
 drivers/iommu/of_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 9f44ee8..e6e9bec 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node *np)
 
ops = iommu_ops_from_fwnode(fwnode);
if ((ops && !ops->of_xlate) ||
+   !of_device_is_available(iommu_spec->np) ||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 3/5] ACPI/IORT: Ignore all errors except EPROBE_DEFER

2017-05-23 Thread Sricharan R
While deferring the probe of IOMMU masters, xlate and
add_device callbacks called from iort_iommu_configure
can pass back error values like -ENODEV, which means
the IOMMU cannot be connected with that master for real
reasons. Before the IOMMU probe deferral, all such errors
were ignored. Now all those errors are propagated back,
killing the master's probe for such errors. Instead ignore
all the errors except EPROBE_DEFER, which is the only one
of concern and let the master work without IOMMU, thus
restoring the old behavior. Also make explicit that
acpi_dma_configure handles only -EPROBE_DEFER from
iort_iommu_configure.

Fixes: 5a1bb638d567 ("drivers: acpi: Handle IOMMU lookup failure with deferred 
probing or error")
Signed-off-by: Sricharan R 
---
[v5] Added the check in acpi_dma_configure

 drivers/acpi/arm64/iort.c | 6 ++
 drivers/acpi/scan.c   | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf9..16e101f 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct device 
*dev)
if (err)
ops = ERR_PTR(err);
 
+   /* Ignore all other errors apart from EPROBE_DEFER */
+   if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
+   dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
+   ops = NULL;
+   }
+
return ops;
 }
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e39ec7b..3a10d757 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum 
dev_dma_attr attr)
iort_set_dma_mask(dev);
 
iommu = iort_iommu_configure(dev);
-   if (IS_ERR(iommu))
-   return PTR_ERR(iommu);
+   if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
 
size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
/*
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error

2017-05-23 Thread Sricharan R
Hi Lorenzo,

On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
> On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
>> Hi Sricharan,
>>
>> On 4/10/2017 7:21 AM, Sricharan R wrote:
>>> This is an equivalent to the DT's handling of the iommu master's probe
>>> with deferred probing when the corrsponding iommu is not probed yet.
>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>> been deferred, or having failed.
>>>
>>> The first case occurs when the firmware describes the bus master and
>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>> or the device driver has not been compiled in. Return NULL, the caller
>>> will configure the device without an IOMMU.
>>>
>>> The second and third cases are handled by deferring the probe of the bus
>>> master device which will eventually get reprobed after the IOMMU.
>>>
>>> The last case is currently handled by deferring the probe of the bus
>>> master device as well. A mechanism to either configure the bus master
>>> device without an IOMMU or to fail the bus master device probe depending
>>> on whether the IOMMU is optional or mandatory would be a good
>>> enhancement.
>>>
>>> Tested-by: Hanjun Guo 
>>> Reviewed-by: Robin Murphy 
>>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>>   called multiple times for same device]
>>> Signed-off-by: Lorenzo Pieralisi 
>>> Signed-off-by: Sricharan R 
>>> ---
>>>  drivers/acpi/arm64/iort.c  | 33 -
>>>  drivers/acpi/scan.c| 11 ---
>>>  drivers/base/dma-mapping.c |  2 +-
>>>  include/acpi/acpi_bus.h|  2 +-
>>>  include/linux/acpi.h   |  7 +--
>>>  5 files changed, 47 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>> index 3dd9ec3..e323ece 100644
>>> --- a/drivers/acpi/arm64/iort.c
>>> +++ b/drivers/acpi/arm64/iort.c
>>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
>>> device *dev,
>>> const struct iommu_ops *ops = NULL;
>>> int ret = -ENODEV;
>>> struct fwnode_handle *iort_fwnode;
>>> +   struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>> +
>>> +   /*
>>> +* If we already translated the fwspec there
>>> +* is nothing left to do, return the iommu_ops.
>>> +    */
>>> +   if (fwspec && fwspec->ops)
>>> +   return fwspec->ops;
>>
>> Is this logic strictly required? It breaks masters with multiple SIDs
>> as only the first SID is actually added to the master's fwspec.
> 
> My bad, that's indeed a silly bug I introduced. Please let me know if the
> patch below fixes it, we will send it upstream shortly.
> 

oops, i think emails crossed. Please let me know if you are ok to add this
to the other fixes.

Regards,
 Sricharan

> Lorenzo
> 
> -- >8 --
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index c5fecf9..e326f2a 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
> device *dev,
>   int ret = -ENODEV;
>   struct fwnode_handle *iort_fwnode;
>  
> - /*
> -  * If we already translated the fwspec there
> -  * is nothing left to do, return the iommu_ops.
> -  */
> - ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> - if (ops)
> - return ops;
> -
>   if (node) {
>   iort_fwnode = iort_get_fwnode(node);
>   if (!iort_fwnode)
> @@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct 
> device *dev)
>   u32 streamid = 0;
>   int err;
>  
> + /*
> +  * If we already translated the fwspec there
> +  * is nothing left to do, return the iommu_ops.
> +  */
> + ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> + if (ops)
> + return ops;
> +
>   if (dev_is_pci(dev)) {
>   struct pci_bus *bus = to_pci_dev(dev)->bus;
>   u32 rid;
> 
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error

2017-05-23 Thread Sricharan R
Hi,

On 5/23/2017 11:56 AM, Nate Watterson wrote:
> Hi Sricharan,
> 
> On 4/10/2017 7:21 AM, Sricharan R wrote:
>> This is an equivalent to the DT's handling of the iommu master's probe
>> with deferred probing when the corrsponding iommu is not probed yet.
>> The lack of a registered IOMMU can be caused by the lack of a driver for
>> the IOMMU, the IOMMU device probe not having been performed yet, having
>> been deferred, or having failed.
>>
>> The first case occurs when the firmware describes the bus master and
>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>> or the device driver has not been compiled in. Return NULL, the caller
>> will configure the device without an IOMMU.
>>
>> The second and third cases are handled by deferring the probe of the bus
>> master device which will eventually get reprobed after the IOMMU.
>>
>> The last case is currently handled by deferring the probe of the bus
>> master device as well. A mechanism to either configure the bus master
>> device without an IOMMU or to fail the bus master device probe depending
>> on whether the IOMMU is optional or mandatory would be a good
>> enhancement.
>>
>> Tested-by: Hanjun Guo 
>> Reviewed-by: Robin Murphy 
>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>called multiple times for same device]
>> Signed-off-by: Lorenzo Pieralisi 
>> Signed-off-by: Sricharan R 
>> ---
>>   drivers/acpi/arm64/iort.c  | 33 -
>>   drivers/acpi/scan.c| 11 ---
>>   drivers/base/dma-mapping.c |  2 +-
>>   include/acpi/acpi_bus.h|  2 +-
>>   include/linux/acpi.h   |  7 +--
>>   5 files changed, 47 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 3dd9ec3..e323ece 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
>> device *dev,
>>   const struct iommu_ops *ops = NULL;
>>   int ret = -ENODEV;
>>   struct fwnode_handle *iort_fwnode;
>> +struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>> +
>> +/*
>> + * If we already translated the fwspec there
>> + * is nothing left to do, return the iommu_ops.
>> + */
>> +if (fwspec && fwspec->ops)
>> +return fwspec->ops;
> 
> Is this logic strictly required? It breaks masters with multiple SIDs
> as only the first SID is actually added to the master's fwspec.
> 

The logic here is same as what is done in DT, in of_iommu_configure.
This is to pullback the iommu_ops that was set for the device from the
previous run. (when the device probe is deferred and called again).
Infact this piece of hunk was initially missing in ACPI, later added
since a bug was reported [1] on V9 and then this came in as a fix in V10.
But looks like this check should be in iort_iommu_configure.
Lorenzo, is that correct ?


[1] https://www.spinics.net/lists/arm-kernel/msg572069.html

If yes i will add this in the fixes that i have already posted.

Regards,
 Sricharan


>> if (node) {
>>   iort_fwnode = iort_get_fwnode(node);
>> @@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
>> device *dev,
>>   return NULL;
>> ops = iommu_ops_from_fwnode(iort_fwnode);
>> +/*
>> + * If the ops look-up fails, this means that either
>> + * the SMMU drivers have not been probed yet or that
>> + * the SMMU drivers are not built in the kernel;
>> + * Depending on whether the SMMU drivers are built-in
>> + * in the kernel or not, defer the IOMMU configuration
>> + * or just abort it.
>> + */
>>   if (!ops)
>> -return NULL;
>> +return iort_iommu_driver_enabled(node->type) ?
>> +   ERR_PTR(-EPROBE_DEFER) : NULL;
>> ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
>>   }
>> @@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct 
>> device *dev)
>> while (parent) {
>>   ops = iort_iommu_xlate(dev, parent, streamid);
>> +if (IS_ERR_OR_NULL(ops))
>> +return ops;
>> parent = iort_node_get_id(node, &streamid,
>> IORT_IOMMU_TYPE, i++);
>>   }
>>   }
>>   +/*
>> 

Re: [PATCH V4 3/4] ACPI/IORT: Ignore all errors except EPROBE_DEFER

2017-05-22 Thread Sricharan R
Hi Lorenzo,

On 5/22/2017 5:01 PM, Lorenzo Pieralisi wrote:
> On Mon, May 22, 2017 at 04:35:43PM +0530, Sricharan R wrote:
>> Hi Lorenzo,
>>
>> On 5/22/2017 4:07 PM, Lorenzo Pieralisi wrote:
>>> Hi Sricharan,
>>>
>>> On Thu, May 18, 2017 at 08:24:16PM +0530, Sricharan R wrote:
>>>> While deferring the probe of IOMMU masters, xlate and
>>>> add_device callbacks called from iort_iommu_configure
>>>> can pass back error values like -ENODEV, which means
>>>> the IOMMU cannot be connected with that master for real
>>>> reasons. Before the IOMMU probe deferral, all such errors
>>>> were ignored. Now all those errors are propagated back,
>>>> killing the master's probe for such errors. Instead ignore
>>>> all the errors except EPROBE_DEFER, which is the only one
>>>> of concern and let the master work without IOMMU, thus
>>>> restoring the old behavior.
>>>>
>>>> Fixes: 5a1bb638d567 ("drivers: acpi: Handle IOMMU lookup failure with 
>>>> deferred probing or error")
>>>> Signed-off-by: Sricharan R 
>>>> ---
>>>> [V4] Added this patch newly.
>>>>
>>>>  drivers/acpi/arm64/iort.c | 6 ++
>>>>  1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>>> index c5fecf9..16e101f 100644
>>>> --- a/drivers/acpi/arm64/iort.c
>>>> +++ b/drivers/acpi/arm64/iort.c
>>>> @@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct 
>>>> device *dev)
>>>>if (err)
>>>>ops = ERR_PTR(err);
>>>>  
>>>> +  /* Ignore all other errors apart from EPROBE_DEFER */
>>>> +  if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
>>>> +  dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
>>>> +  ops = NULL;
>>>> +  }
>>>> +
>>>>return ops;
>>>>  }
>>>>  
>>>
>>> It is getting a bit convoluted. Is not it better to propagate the
>>> error back and let acpi_dma_configure() make a decision accordingly ?
>>>
>>
>> ok, I was trying to keep it in same way as DT, where of_dma_configure
>> (here acpi_dma_configure) calls of_iommu_configure(here iort_iommu_configure)
>> which ends up doing the check. So will have to be changed in both places
>> for symmetry.
>>
>>> Something like:
>>>
>>> -- >8 --
>>> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
>>> index e39ec7b..3a10d757 100644
>>> --- a/drivers/acpi/scan.c
>>> +++ b/drivers/acpi/scan.c
>>> @@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum 
>>> dev_dma_attr attr)
>>> iort_set_dma_mask(dev);
>>>  
>>> iommu = iort_iommu_configure(dev);
>>> -   if (IS_ERR(iommu))
>>> -   return PTR_ERR(iommu);
>>> +   if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
>>> +   return -EPROBE_DEFER;
>>
>> In case of other errors apart from EPROBE_DEFER,
>> iommu = NULL should be set, before passing it on to
>> arch_setup_dma_ops.
> 
> Ah yes, sorry, that makes it uglier :(
> 
> Point is, it does not make sense to me to have of/acpi_dma_configure()
> check a return code with (IS_ERR()) whilst we know the only error
> code you are allowed to handle is -EPROBE_DEFER, while at it it is
> better to make the -EPROBE_DEFER check explicit (otherwise it may
> seem that of/acpi_dma_configure() can handle an error code that
> is different from -EPROBE_DEFER - but they don't), no big deal either
> way though.
> 

ok, in which case, the above check that you have shown
to be added additionally to the original patch.

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V4 3/4] ACPI/IORT: Ignore all errors except EPROBE_DEFER

2017-05-22 Thread Sricharan R
Hi Lorenzo,

On 5/22/2017 4:07 PM, Lorenzo Pieralisi wrote:
> Hi Sricharan,
> 
> On Thu, May 18, 2017 at 08:24:16PM +0530, Sricharan R wrote:
>> While deferring the probe of IOMMU masters, xlate and
>> add_device callbacks called from iort_iommu_configure
>> can pass back error values like -ENODEV, which means
>> the IOMMU cannot be connected with that master for real
>> reasons. Before the IOMMU probe deferral, all such errors
>> were ignored. Now all those errors are propagated back,
>> killing the master's probe for such errors. Instead ignore
>> all the errors except EPROBE_DEFER, which is the only one
>> of concern and let the master work without IOMMU, thus
>> restoring the old behavior.
>>
>> Fixes: 5a1bb638d567 ("drivers: acpi: Handle IOMMU lookup failure with 
>> deferred probing or error")
>> Signed-off-by: Sricharan R 
>> ---
>> [V4] Added this patch newly.
>>
>>  drivers/acpi/arm64/iort.c | 6 ++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index c5fecf9..16e101f 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct 
>> device *dev)
>>  if (err)
>>  ops = ERR_PTR(err);
>>  
>> +/* Ignore all other errors apart from EPROBE_DEFER */
>> +if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
>> +dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
>> +ops = NULL;
>> +}
>> +
>>  return ops;
>>  }
>>  
> 
> It is getting a bit convoluted. Is not it better to propagate the
> error back and let acpi_dma_configure() make a decision accordingly ?
> 

ok, I was trying to keep it in same way as DT, where of_dma_configure
(here acpi_dma_configure) calls of_iommu_configure(here iort_iommu_configure)
which ends up doing the check. So will have to be changed in both places
for symmetry.

> Something like:
> 
> -- >8 --
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index e39ec7b..3a10d757 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum 
> dev_dma_attr attr)
>   iort_set_dma_mask(dev);
>  
>   iommu = iort_iommu_configure(dev);
> - if (IS_ERR(iommu))
> - return PTR_ERR(iommu);
> + if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
> + return -EPROBE_DEFER;

In case of other errors apart from EPROBE_DEFER,
iommu = NULL should be set, before passing it on to
arch_setup_dma_ops.

Regards,
 Sricharan

>  
>   size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>   /*
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH V4 3/4] ACPI/IORT: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Sricharan R
While deferring the probe of IOMMU masters, xlate and
add_device callbacks called from iort_iommu_configure
can pass back error values like -ENODEV, which means
the IOMMU cannot be connected with that master for real
reasons. Before the IOMMU probe deferral, all such errors
were ignored. Now all those errors are propagated back,
killing the master's probe for such errors. Instead ignore
all the errors except EPROBE_DEFER, which is the only one
of concern and let the master work without IOMMU, thus
restoring the old behavior.

Fixes: 5a1bb638d567 ("drivers: acpi: Handle IOMMU lookup failure with deferred 
probing or error")
Signed-off-by: Sricharan R 
---
[V4] Added this patch newly.

 drivers/acpi/arm64/iort.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf9..16e101f 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct device 
*dev)
if (err)
ops = ERR_PTR(err);
 
+   /* Ignore all other errors apart from EPROBE_DEFER */
+   if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
+   dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
+   ops = NULL;
+   }
+
return ops;
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V4 4/4] ARM: dma-mapping: Don't tear third-party mappings

2017-05-18 Thread Sricharan R
From: Laurent Pinchart 

arch_setup_dma_ops() is used in device probe code paths to create an
IOMMU mapping and attach it to the device. The function assumes that the
device is attached to a device-specific IOMMU instance (or at least a
device-specific TLB in a shared IOMMU instance) and thus creates a
separate mapping for every device.

On several systems (Renesas R-Car Gen2 being one of them), that
assumption is not true, and IOMMU mappings must be shared between
multiple devices. In those cases the IOMMU driver knows better than the
generic ARM dma-mapping layer and attaches mapping to devices manually
with arm_iommu_attach_device(), which sets the DMA ops for the device.

The arch_setup_dma_ops() function takes this into account and bails out
immediately if the device already has DMA ops assigned. However, the
corresponding arch_teardown_dma_ops() function, called from driver
unbind code paths (including probe deferral), will tear the mapping down
regardless of who created it. When the device is reprobed
arch_setup_dma_ops() will be called again but won't perform any
operation as the DMA ops will still be set.

We need to reset the DMA ops in arch_teardown_dma_ops() to fix this.
However, we can't do so unconditionally, as then a new mapping would be
created by arch_setup_dma_ops() when the device is reprobed, regardless
of whether the device needs to share a mapping or not. We must thus keep
track of whether arch_setup_dma_ops() created the mapping, and only in
that case tear it down in arch_teardown_dma_ops().

Keep track of that information in the dev_archdata structure. As the
structure is embedded in all instances of struct device let's not grow
it, but turn the existing dma_coherent bool field into a bitfield that
can be used for other purposes.

Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for 
platform/amba/pci bus devices")
Reviewed-by: Robin Murphy 
Signed-off-by: Laurent Pinchart 
---
 arch/arm/include/asm/device.h | 3 ++-
 arch/arm/mm/dma-mapping.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 36ec9c8..3234fe9 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -19,7 +19,8 @@ struct dev_archdata {
 #ifdef CONFIG_XEN
const struct dma_map_ops *dev_dma_ops;
 #endif
-   bool dma_coherent;
+   unsigned int dma_coherent:1;
+   unsigned int dma_ops_setup:1;
 };
 
 struct omap_device;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c742dfd..b48998f 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2430,9 +2430,13 @@ void arch_setup_dma_ops(struct device *dev, u64 
dma_base, u64 size,
dev->dma_ops = xen_dma_ops;
}
 #endif
+   dev->archdata.dma_ops_setup = true;
 }
 
 void arch_teardown_dma_ops(struct device *dev)
 {
+   if (!dev->archdata.dma_ops_setup)
+   return;
+
arm_teardown_iommu_dma_ops(dev);
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V4 2/4] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Sricharan R
While deferring the probe of IOMMU masters, xlate and
add_device callbacks called from of_iommu_configure
can pass back error values like -ENODEV, which means
the IOMMU cannot be connected with that master for real
reasons. Before the IOMMU probe deferral, all such errors
were ignored. Now all those errors are propagated back,
killing the master's probe for such errors. Instead ignore
all the errors except EPROBE_DEFER, which is the only one
of concern and let the master work without IOMMU, thus
restoring the old behavior.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Reported-by: Geert Uytterhoeven 
Tested-by: Magnus Damn 
Signed-off-by: Sricharan R 
---
[V4] Reworded commit log and changed dev_info to dev_dbg

 drivers/iommu/of_iommu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e6e9bec..19779b8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -237,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
ops = ERR_PTR(err);
}
 
+   /* Ignore all other errors apart from EPROBE_DEFER */
+   if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
+   dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
+   ops = NULL;
+   }
+
return ops;
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V4 1/4] iommu: of: Fix check for returning EPROBE_DEFER

2017-05-18 Thread Sricharan R
Now with IOMMU probe deferral, we return -EPROBE_DEFER
for masters that are connected to an IOMMU which is not
probed yet, but going to get probed, so that we can attach
the correct dma_ops. So while trying to defer the probe of
the master, check if the of_iommu node that it is connected
to is marked in DT as 'status=disabled', then the IOMMU is never
is going to get probed. So simply return NULL and let the master
work without an IOMMU.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Signed-off-by: Sricharan R 
Reported-by: Geert Uytterhoeven 
Reviewed-by: Laurent Pinchart 
Tested-by: Will Deacon 
Tested-by: Magnus Damn 
Acked-by: Will Deacon 
---
 drivers/iommu/of_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 9f44ee8..e6e9bec 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node *np)
 
ops = iommu_ops_from_fwnode(fwnode);
if ((ops && !ops->of_xlate) ||
+   !of_device_is_available(iommu_spec->np) ||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH V2 2/3] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Sricharan R
Hi Laurent,

On 5/18/2017 7:13 PM, Laurent Pinchart wrote:
> Hi Sricharan
> 
> On Thursday 18 May 2017 19:08:12 Sricharan R wrote:
>> On 5/18/2017 6:00 PM, Laurent Pinchart wrote:
>>> On Thursday 18 May 2017 17:26:14 Sricharan R wrote:
>>>> On 5/18/2017 4:09 PM, Laurent Pinchart wrote:
>>>>> On Thursday 18 May 2017 15:37:09 Sricharan R wrote:
>>>>>> While deferring the probe of IOMMU masters,
>>>>>> xlate and add_device callback can pass back error values
>>>>>> like -ENODEV, which means IOMMU cannot be connected
>>>>>> with that master for real reasons. So rather than
>>>>>> killing the master's probe for such errors, just
>>>>>> ignore the errors and let the master work without
>>>>>> an IOMMU.
>>>>>
>>>>> I don't think this is a good idea. Why should we allow IOMMU drivers to
>>>>> return an error if we're always going to ignore the error value ? That
>>>>> will lead to drivers implementing slightly different behaviours, which
>>>>> will be painful the day we'll need to start acting based on the error
>>>>> value.
>>>>
>>>> The of_iommu_configure interface, before this series, was returning
>>>> either correct 'iommu_ops' or NULL. Also there was no return value from
>>>> of_dma_configure which calls of_iommu_configure. This means that if we
>>>> block only -ENODEV now and let the other errors, the probe of the master
>>>> devices can be killed for reasons apart from deferring. This would be a
>>>> change in behavior introduced. All of xlate, add_device, of_pci_map_rid
>>>> and others can return values apart from -ENODEV. So was thinking that
>>>> restoring the old behavior, except for returning EPROBE_DEFER was the
>>>> better thing to do ?
>>>
>>> We went from a situation where of_iommu_configure() could return either
>>> valid operations in the case the device was to be handled by the IOMMU or
>>> NULL otherwise, to a situation where we needed a third option for probe
>>> deferral. The way we've done this, through error pointers, allows lots of
>>> other errors to be returned as well from the of_xlate and add_device
>>> operations.
>>
>> right, this was difference in the behavior now.
>>
>>> There is currently no use for returning error codes other than
>>> -EPROBE_DEFFER from of_iommu_configure(), so your proposal is to block
>>> errors returned from the of_xlate and add_device operations inside
>>> of_iommu_configure(). My point is that, by doing so, we allow IOMMU
>>> drivers to return random error codes that are then ignored. I believe
>>> this can cause problems in the future when we will need to extend the API
>>> and standardize more error codes, as by then IOMMU drivers will return
>>> random errors (they actually do so already to some extent).
>>>
>>> For of_xlate I agree with you to some extent. v4.11 just checked whether
>>> of_xlate succeeded or not, and just didn't use the IOMMU in case it
>>> failed. The exact error value was ignored, and drivers already return
>>> random errors. Going back to the v4.11 behaviour is what we need to do in
>>> the short-term, even if I believe we should standardize the error values
>>> returned from of_xlate after v4.12.
>>>
>>> For add_device, however, the situation is a bit different. The add_device
>>> operation is called from the IOMMU bus notifier, and the -ENODEV error is
>>> ignored by add_iommu_group(). Any other error will cause bus_set_iommu()
>>> to fail, which makes IOMMU probing fail for the drivers that check the
>>> return value of bus_set_iommu() (some of them don't :-/).
>>>
>>> Fixing all this properly requires standardizing the error codes, and going
>>> through the existing IOMMU drivers to comply with the standardized
>>> behaviour.
>>
>> I understand your concern on standardizing the error codes from xlate,
>> add_device, others and handling them properly. As you said there are quite
>> some errors returned from them today. Also another thing is standardizing
>> the behavior of of_iommu_configure itself. So that API serves to connect a
>> device to its correct iommu_ops. When that's not possible, what should be
>> the output and how should that be handled by the caller. The current
>> behavior is to either 1) connect to correct ops or 2) wait for it or 

Re: [PATCH V2 2/3] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Sricharan R
Hi Laurent,

On 5/18/2017 6:00 PM, Laurent Pinchart wrote:
> Hi Sricharan,
> 
> On Thursday 18 May 2017 17:26:14 Sricharan R wrote:
>> On 5/18/2017 4:09 PM, Laurent Pinchart wrote:
>>> On Thursday 18 May 2017 15:37:09 Sricharan R wrote:
>>>> While deferring the probe of IOMMU masters,
>>>> xlate and add_device callback can pass back error values
>>>> like -ENODEV, which means IOMMU cannot be connected
>>>> with that master for real reasons. So rather than
>>>> killing the master's probe for such errors, just
>>>> ignore the errors and let the master work without
>>>> an IOMMU.
>>>
>>> I don't think this is a good idea. Why should we allow IOMMU drivers to
>>> return an error if we're always going to ignore the error value ? That
>>> will lead to drivers implementing slightly different behaviours, which
>>> will be painful the day we'll need to start acting based on the error
>>> value.
>>
>> The of_iommu_configure interface, before this series, was returning either
>> correct 'iommu_ops' or NULL. Also there was no return value from
>> of_dma_configure which calls of_iommu_configure. This means that if we block
>> only -ENODEV now and let the other errors, the probe of the master devices
>> can be killed for reasons apart from deferring. This would be a change in
>> behavior introduced. All of xlate, add_device, of_pci_map_rid and others
>> can return values apart from -ENODEV. So was thinking that restoring the
>> old behavior, except for returning EPROBE_DEFER was the better thing to do
>> ?
> 
> We went from a situation where of_iommu_configure() could return either valid 
> operations in the case the device was to be handled by the IOMMU or NULL 
> otherwise, to a situation where we needed a third option for probe deferral. 
> The way we've done this, through error pointers, allows lots of other errors 
> to be returned as well from the of_xlate and add_device operations.
> 

right, this was difference in the behavior now.

> There is currently no use for returning error codes other than -EPROBE_DEFFER 
> from of_iommu_configure(), so your proposal is to block errors returned from 
> the of_xlate and add_device operations inside of_iommu_configure(). My point 
> is that, by doing so, we allow IOMMU drivers to return random error codes 
> that 
> are then ignored. I believe this can cause problems in the future when we 
> will 
> need to extend the API and standardize more error codes, as by then IOMMU 
> drivers will return random errors (they actually do so already to some 
> extent).
> 
> For of_xlate I agree with you to some extent. v4.11 just checked whether 
> of_xlate succeeded or not, and just didn't use the IOMMU in case it failed. 
> The exact error value was ignored, and drivers already return random errors. 
> Going back to the v4.11 behaviour is what we need to do in the short-term, 
> even if I believe we should standardize the error values returned from 
> of_xlate after v4.12.
> 
> For add_device, however, the situation is a bit different. The add_device  
> operation is called from the IOMMU bus notifier, and the -ENODEV error is 
> ignored by add_iommu_group(). Any other error will cause bus_set_iommu() to 
> fail, which makes IOMMU probing fail for the drivers that check the return 
> value of bus_set_iommu() (some of them don't :-/).
> 
> Fixing all this properly requires standardizing the error codes, and going 
> through the existing IOMMU drivers to comply with the standardized behaviour. 

I understand your concern on standardizing the error codes from xlate,
add_device, others and handling them properly. As you said there are quite some
errors returned from them today. Also another thing is standardizing the
behavior of of_iommu_configure itself. So that API serves to connect a device
to its correct iommu_ops. When that's not possible, what should be the output
and how should that be handled by the caller. The current behavior is to
either 1) connect to correct ops or 2) wait for it or 3) progress further
with plain/default dma_ops. Anyways as you said standardizing the iommu api
ops, would make the of_iommu_configure handling more specific. Having said that
i think similar fix needs to be done for acpi's iort_iommu_configure as
well.

> While this shouldn't be very difficult, it's likely not material for a v4.12-
> rc fix. We will thus likely need to merge this patch (or something very 
> similar to it), but I'd really like to see this fixed properly for v4.13.
> 

When you say "merge this patch (or something similar)", is that about
documenting the error values for of_xl

Re: [PATCH V2 2/3] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Sricharan R
Hi Laurent,

On 5/18/2017 4:09 PM, Laurent Pinchart wrote:
> Hi Sricharan,
> 
> Thank you for the patch.
> 
> On Thursday 18 May 2017 15:37:09 Sricharan R wrote:
>> While deferring the probe of IOMMU masters,
>> xlate and add_device callback can pass back error values
>> like -ENODEV, which means IOMMU cannot be connected
>> with that master for real reasons. So rather than
>> killing the master's probe for such errors, just
>> ignore the errors and let the master work without
>> an IOMMU.
> 
> I don't think this is a good idea. Why should we allow IOMMU drivers to 
> return 
> an error if we're always going to ignore the error value ? That will lead to 
> drivers implementing slightly different behaviours, which will be painful the 
> day we'll need to start acting based on the error value.
> 

The of_iommu_configure interface, before this series, was returning either
correct 'iommu_ops' or NULL. Also there was no return value from
of_dma_configure which calls of_iommu_configure. This means that if we block
only -ENODEV now and let the other errors, the probe of the master devices
can be killed for reasons apart from deferring. This would be a change in
behavior introduced. All of xlate, add_device, of_pci_map_rid and others
can return values apart from -ENODEV. So was thinking that restoring the
old behavior, except for returning EPROBE_DEFER was the better thing to do ? 

Regards,
 Sricharan

> At the very least, if you want to give a specific meaning to -ENODEV, you 
> should check for that value specifically and not ignore all errors other than 
> -EPROBE_DEFER. You also need to document the meaning of the error value. This 
> can be done in the documentation of the of_xlate operation in 
> include/linux/iommu.h:
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 2cb54adc4a33..6ba553e7384a 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -181,7 +181,6 @@ struct iommu_resv_region {
>   * @domain_window_disable: Disable a particular window for a domain
>   * @domain_set_windows: Set the number of windows for a domain
>   * @domain_get_windows: Return the number of windows for a domain
> - * @of_xlate: add OF master IDs to iommu grouping
>   * @pgsize_bitmap: bitmap of all possible supported page sizes
>   */
>  struct iommu_ops {
> @@ -224,6 +223,11 @@ struct iommu_ops {
>   /* Get the number of windows per domain */
>   u32 (*domain_get_windows)(struct iommu_domain *domain);
>  
> + /**
> +  * @of_xlate:
> +  *
> +  * Add OF master IDs to iommu grouping.
> +  */
>   int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
>  
>   unsigned long pgsize_bitmap;
> 
> 
> And add documentation for the error codes there.
> 
> If you want to ignore some errors returned from the add_device operation you 
> should document it similarly, and in particular document which error check(s) 
> need to be performed by of_xlate and which are the responsibility of 
> add_device.
> 
>> Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred
>> probing or error")
>> Reported-by: Geert Uytterhoeven 
>> Tested-by: Magnus Damn 
>> Signed-off-by: Sricharan R 
>> ---
>> [V2] Corrected spelling/case in commit log
>>
>>  drivers/iommu/of_iommu.c | 6 ++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
>> index e6e9bec..f0d22c0 100644
>> --- a/drivers/iommu/of_iommu.c
>> +++ b/drivers/iommu/of_iommu.c
>> @@ -237,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct
>> device *dev, ops = ERR_PTR(err);
>>  }
>>
>> +/* Ignore all other errors apart from EPROBE_DEFER */
>> +if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
>> +dev_info(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
>> +ops = NULL;
>> +}
>> +
>>  return ops;
>>  }
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH V2 2/3] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-18 Thread Sricharan R
While deferring the probe of IOMMU masters,
xlate and add_device callback can pass back error values
like -ENODEV, which means IOMMU cannot be connected
with that master for real reasons. So rather than
killing the master's probe for such errors, just
ignore the errors and let the master work without
an IOMMU.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Reported-by: Geert Uytterhoeven 
Tested-by: Magnus Damn 
Signed-off-by: Sricharan R 
---
[V2] Corrected spelling/case in commit log

 drivers/iommu/of_iommu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e6e9bec..f0d22c0 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -237,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
ops = ERR_PTR(err);
}
 
+   /* Ignore all other errors apart from EPROBE_DEFER */
+   if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
+   dev_info(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
+   ops = NULL;
+   }
+
return ops;
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V2 1/3] iommu: of: Fix check for returning EPROBE_DEFER

2017-05-18 Thread Sricharan R
Now with IOMMU probe deferral, we return -EPROBE_DEFER
for masters that are connected to an IOMMU which is not
probed yet, but going to get probed, so that we can attach
the correct dma_ops. So while trying to defer the probe of
the master, check if the of_iommu node that it is connected
to is marked in DT as 'status=disabled', then the IOMMU is never
is going to get probed. So simply return NULL and let the master
work without an IOMMU.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Signed-off-by: Sricharan R 
Reported-by: Geert Uytterhoeven 
Tested-by: Will Deacon 
Tested-by: Magnus Damn 
Acked-by: Will Deacon 
---
[V2] Corrected spelling/case in commit log

 drivers/iommu/of_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 9f44ee8..e6e9bec 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node *np)
 
ops = iommu_ops_from_fwnode(fwnode);
if ((ops && !ops->of_xlate) ||
+   !of_device_is_available(iommu_spec->np) ||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V2 3/3] ARM: dma-mapping: Don't tear third-party mappings

2017-05-18 Thread Sricharan R
From: Laurent Pinchart 

arch_setup_dma_ops() is used in device probe code paths to create an
IOMMU mapping and attach it to the device. The function assumes that the
device is attached to a device-specific IOMMU instance (or at least a
device-specific TLB in a shared IOMMU instance) and thus creates a
separate mapping for every device.

On several systems (Renesas R-Car Gen2 being one of them), that
assumption is not true, and IOMMU mappings must be shared between
multiple devices. In those cases the IOMMU driver knows better than the
generic ARM dma-mapping layer and attaches mapping to devices manually
with arm_iommu_attach_device(), which sets the DMA ops for the device.

The arch_setup_dma_ops() function takes this into account and bails out
immediately if the device already has DMA ops assigned. However, the
corresponding arch_teardown_dma_ops() function, called from driver
unbind code paths (including probe deferral), will tear the mapping down
regardless of who created it. When the device is reprobed
arch_setup_dma_ops() will be called again but won't perform any
operation as the DMA ops will still be set.

We need to reset the DMA ops in arch_teardown_dma_ops() to fix this.
However, we can't do so unconditionally, as then a new mapping would be
created by arch_setup_dma_ops() when the device is reprobed, regardless
of whether the device needs to share a mapping or not. We must thus keep
track of whether arch_setup_dma_ops() created the mapping, and only in
that case tear it down in arch_teardown_dma_ops().

Keep track of that information in the dev_archdata structure. As the
structure is embedded in all instances of struct device let's not grow
it, but turn the existing dma_coherent bool field into a bitfield that
can be used for other purposes.

Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for 
platform/amba/pci bus devices")
Reviewed-by: Robin Murphy 
Signed-off-by: Laurent Pinchart 
---
 arch/arm/include/asm/device.h | 3 ++-
 arch/arm/mm/dma-mapping.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 36ec9c8..3234fe9 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -19,7 +19,8 @@ struct dev_archdata {
 #ifdef CONFIG_XEN
const struct dma_map_ops *dev_dma_ops;
 #endif
-   bool dma_coherent;
+   unsigned int dma_coherent:1;
+   unsigned int dma_ops_setup:1;
 };
 
 struct omap_device;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c742dfd..b48998f 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2430,9 +2430,13 @@ void arch_setup_dma_ops(struct device *dev, u64 
dma_base, u64 size,
dev->dma_ops = xen_dma_ops;
}
 #endif
+   dev->archdata.dma_ops_setup = true;
 }
 
 void arch_teardown_dma_ops(struct device *dev)
 {
+   if (!dev->archdata.dma_ops_setup)
+   return;
+
arm_teardown_iommu_dma_ops(dev);
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH 1/3] iommu: of: Fix check for returning EPROBE_DEFER

2017-05-18 Thread Sricharan R
Hi Bjorn,

On 5/17/2017 10:34 PM, Bjorn Helgaas wrote:
> On Wed, May 17, 2017 at 05:00:07PM +0530, Sricharan R wrote:
>> Now with iommu probe deferral, we return -EPROBE_DEFER
>> for master's that are connected to an iommu which is not
> 
> s/master's/masters/
> 
> s/iommu/IOMMU/ in your English text (changelogs and comments).  That seems
> to be the convention, based on "git log drivers/iommu/of_iommu.c"
> 

ok, will correct those.

Regards,
 Sricharan


>> probed yet, but going to get probed, so that we can attach
>> the correct dma_ops. So while trying to defer the probe of
>> the master, check if the of_iommu node that it is connected
>> to is marked in DT as 'status=disabled', then the iommu is never
>> is going to get probed. So simply return NULL and let the master
>> work without an iommu.
>>
>> Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
>> probing or error")
>> Signed-off-by: Sricharan R 
>> Reported-by: Geert Uytterhoeven 
>> Tested-by: Will Deacon 
>> Tested-by: Magnus Damn 
>> Acked-by: Will Deacon 
>> ---
>>  drivers/iommu/of_iommu.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
>> index 9f44ee8..e6e9bec 100644
>> --- a/drivers/iommu/of_iommu.c
>> +++ b/drivers/iommu/of_iommu.c
>> @@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node 
>> *np)
>>  
>>  ops = iommu_ops_from_fwnode(fwnode);
>>  if ((ops && !ops->of_xlate) ||
>> +!of_device_is_available(iommu_spec->np) ||
>>  (!ops && !of_iommu_driver_present(iommu_spec->np)))
>>  return NULL;
>>  
>> -- 
>> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
>> Code Aurora Forum, hosted by The Linux Foundation
>>
>>
>> ___
>> linux-arm-kernel mailing list
>> linux-arm-ker...@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] ARM: dma-mapping: Don't tear third-party mappings

2017-05-17 Thread sricharan

On 2017-05-17 10:45, Sricharan R wrote:

Hi Laurent/Robin,

On 5/16/2017 10:14 PM, Laurent Pinchart wrote:

Hi Robin,

On Tuesday 16 May 2017 16:47:36 Robin Murphy wrote:

On 16/05/17 16:14, Laurent Pinchart wrote:

arch_setup_dma_ops() is used in device probe code paths to create an
IOMMU mapping and attach it to the device. The function assumes that 
the
device is attached to a device-specific IOMMU instance (or at least 
a

device-specific TLB in a shared IOMMU instance) and thus creates a
separate mapping for every device.

On several systems (Renesas R-Car Gen2 being one of them), that
assumption is not true, and IOMMU mappings must be shared between
multiple devices. In those cases the IOMMU driver knows better than 
the
generic ARM dma-mapping layer and attaches mapping to devices 
manually
with arm_iommu_attach_device(), which sets the DMA ops for the 
device.


The arch_setup_dma_ops() function takes this into account and bails 
out

immediately if the device already has DMA ops assigned. However, the
corresponding arch_teardown_dma_ops() function, called from driver
unbind code paths (including probe deferral), will tear the mapping 
down

regardless of who created it. When the device is reprobed
arch_setup_dma_ops() will be called again but won't perform any
operation as the DMA ops will still be set.

We need to reset the DMA ops in arch_teardown_dma_ops() to fix this.
However, we can't do so unconditionally, as then a new mapping would 
be
created by arch_setup_dma_ops() when the device is reprobed, 
regardless
of whether the device needs to share a mapping or not. We must thus 
keep
track of whether arch_setup_dma_ops() created the mapping, and only 
in

that case tear it down in arch_teardown_dma_ops().

Keep track of that information in the dev_archdata structure. As the
structure is embedded in all instances of struct device let's not 
grow
it, but turn the existing dma_coherent bool field into a bitfield 
that

can be used for other purposes.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with 
deferred

probing or error") Signed-off-by: Laurent Pinchart
 ---

 arch/arm/include/asm/device.h | 3 ++-
 arch/arm/mm/dma-mapping.c | 5 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/device.h 
b/arch/arm/include/asm/device.h

index 36ec9c8f6e16..3234fe9bba6e 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -19,7 +19,8 @@ struct dev_archdata {
 #ifdef CONFIG_XEN
const struct dma_map_ops *dev_dma_ops;
 #endif
-   bool dma_coherent;
+   unsigned int dma_coherent:1;


This should only ever be accessed by the Xen DMA code via the
is_device_dma_coherent() helper, so I can't see the change of storage
type causing any problems.


Thank you for double-checking. I agree with your analysis.


+   unsigned int dma_ops_setup:1;
 };

 struct omap_device;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c742dfd2967b..e0272f9140e2 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2430,9 +2430,14 @@ void arch_setup_dma_ops(struct device *dev, 
u64

dma_base, u64 size,
dev->dma_ops = xen_dma_ops;
}
 #endif
+   dev->archdata.dma_ops_setup = true;
 }

 void arch_teardown_dma_ops(struct device *dev)
 {
+   if (!dev->archdata.dma_ops_setup)
+   return;
+
arm_teardown_iommu_dma_ops(dev);
+   set_dma_ops(dev, NULL);


Should we clear dma_ops_setup here for symmetry? I guess in practice
it's down to the IOMMU driver so will never change after the first
probe, but it still feels like a bit of a nagging loose end.


To make a difference, we would need an IOMMU driver that creates a 
mapping
after a first round of arch_setup_dma_ops() / arch_teardown_dma_ops() 
calls,
follow by a second round. I don't think this could happen, but if it 
did, I
believe we'd be screwed already, as there would be a time were an 
incorrect
mapping (created by arch_setup_dma_ops() while the IOMMU driver needs 
to take

care of mapping creation) exists.



Feels correct not to reset this, the iommu drivers in question, seems 
to
creating mapping/attaching in add_device path (which gets called before 
the
clients gets probed) and when the iommu client gets deferred/reprobed 
that

does not happen again even after the first round.


Please ignore the above comment. I said that because I was doing the
dma_ops_setup in arm_iommu_attach_device. I posted the three fixes now 
[1].

Accidentally removed you from CC, sorry for that.
Applied those patches on top of 8674/1 that Robin mentioned
below. So removed setting set_dma_ops(dev, NULL) from your patch.

Also please note that, I changed the Fixes: commit msg in your patch to
("of/acpi: Configure dma operations at probe time for platform/amba/pci 
bus devices")

because that was one which started to invoke the teardown on t

[PATCH 3/3] ARM: dma-mapping: Don't tear third-party mappings

2017-05-17 Thread Sricharan R
From: Laurent Pinchart 

arch_setup_dma_ops() is used in device probe code paths to create an
IOMMU mapping and attach it to the device. The function assumes that the
device is attached to a device-specific IOMMU instance (or at least a
device-specific TLB in a shared IOMMU instance) and thus creates a
separate mapping for every device.

On several systems (Renesas R-Car Gen2 being one of them), that
assumption is not true, and IOMMU mappings must be shared between
multiple devices. In those cases the IOMMU driver knows better than the
generic ARM dma-mapping layer and attaches mapping to devices manually
with arm_iommu_attach_device(), which sets the DMA ops for the device.

The arch_setup_dma_ops() function takes this into account and bails out
immediately if the device already has DMA ops assigned. However, the
corresponding arch_teardown_dma_ops() function, called from driver
unbind code paths (including probe deferral), will tear the mapping down
regardless of who created it. When the device is reprobed
arch_setup_dma_ops() will be called again but won't perform any
operation as the DMA ops will still be set.

We need to reset the DMA ops in arch_teardown_dma_ops() to fix this.
However, we can't do so unconditionally, as then a new mapping would be
created by arch_setup_dma_ops() when the device is reprobed, regardless
of whether the device needs to share a mapping or not. We must thus keep
track of whether arch_setup_dma_ops() created the mapping, and only in
that case tear it down in arch_teardown_dma_ops().

Keep track of that information in the dev_archdata structure. As the
structure is embedded in all instances of struct device let's not grow
it, but turn the existing dma_coherent bool field into a bitfield that
can be used for other purposes.

Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for 
platform/amba/pci bus devices")
Reviewed-by: Robin Murphy 
Signed-off-by: Laurent Pinchart 
---
 arch/arm/include/asm/device.h | 3 ++-
 arch/arm/mm/dma-mapping.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 36ec9c8..3234fe9 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -19,7 +19,8 @@ struct dev_archdata {
 #ifdef CONFIG_XEN
const struct dma_map_ops *dev_dma_ops;
 #endif
-   bool dma_coherent;
+   unsigned int dma_coherent:1;
+   unsigned int dma_ops_setup:1;
 };
 
 struct omap_device;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index cb57f59..b5099d0 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2431,9 +2431,13 @@ void arch_setup_dma_ops(struct device *dev, u64 
dma_base, u64 size,
dev->dma_ops = xen_dma_ops;
}
 #endif
+   dev->archdata.dma_ops_setup = true;
 }
 
 void arch_teardown_dma_ops(struct device *dev)
 {
+   if (!dev->archdata.dma_ops_setup)
+   return;
+
arm_teardown_iommu_dma_ops(dev);
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH 2/3] iommu: of: Ignore all errors except EPROBE_DEFER

2017-05-17 Thread Sricharan R
While deferring the probe of iommu masters,
xlate and add_device callback can pass back error values
like -ENODEV, which means iommu cannot be connected
with that master for real reasons. So rather than
killing the master's probe for such errors, just
ignore the errors and let the master work without
an iommu.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Reported-by: Geert Uytterhoeven 
Tested-by: Magnus Damn 
Signed-off-by: Sricharan R 
---
 drivers/iommu/of_iommu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e6e9bec..2ec2f0b 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -237,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
ops = ERR_PTR(err);
}
 
+   /* Ignore all other errors apart from EPROBE_DEFER */
+   if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
+   dev_info(dev, "Adding to iommu failed: %ld\n", PTR_ERR(ops));
+   ops = NULL;
+   }
+
return ops;
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH 1/3] iommu: of: Fix check for returning EPROBE_DEFER

2017-05-17 Thread Sricharan R
Now with iommu probe deferral, we return -EPROBE_DEFER
for master's that are connected to an iommu which is not
probed yet, but going to get probed, so that we can attach
the correct dma_ops. So while trying to defer the probe of
the master, check if the of_iommu node that it is connected
to is marked in DT as 'status=disabled', then the iommu is never
is going to get probed. So simply return NULL and let the master
work without an iommu.

Fixes: 7b07cbefb68d ("iommu: of: Handle IOMMU lookup failure with deferred 
probing or error")
Signed-off-by: Sricharan R 
Reported-by: Geert Uytterhoeven 
Tested-by: Will Deacon 
Tested-by: Magnus Damn 
Acked-by: Will Deacon 
---
 drivers/iommu/of_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 9f44ee8..e6e9bec 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node *np)
 
ops = iommu_ops_from_fwnode(fwnode);
if ((ops && !ops->of_xlate) ||
+   !of_device_is_available(iommu_spec->np) ||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-17 Thread Sricharan R
Hi Magnus,



>> Magnus, do you have a suggestion?
> 
> Thanks for your efforts guys!
> 
> I've recently been working on up-porting the IPMMU patches and
> addressing review comments. Now with my local driver stack on top of
> v4.12-rc (a95cfad) I did not notice these issues initially since I
> only tested devices with IPMMU enabled. Once these issues were pointed
> out to me by Geert I have now reproduced the 64-bit ARM specific ones
> on r8a7796 Salvator-X.
> 
> On my r8a7796 platform I'm using the following IOMMU and DMA Engine devices:
> 
> IOMMU device IPMMU-DS0 - Connected to SYS-DMAC0
> IOMMU device IPMMU-DS1 - Connected to SYS-DMAC1 and SYS-DMAC2
> IOMMU device IPMMU-MM - Root device serving IPMMU-DS0 and IPMMU-DS1
> 
> For testing the serial port SCIF1 is used with DMA Engine devices
> SYS-DMAC1 or SYS-DMAC2.
> 
> The software environment is configured as follows:
> - The DTS comes with all devices above enabled except IPMMU-DS0 which
> comes with status = "disabled".
> - The IPMMU driver is during run time only allowing use of SYS-DMAC2.
> For other devices ->of_xlate() returns -ENODEV.
> 
> The above used to work just fine with v4.11 or earlier.
> 
> My observations for v4.12-rc:
> 
> 1) Default state for a95cfad
> 
> The devices SYS-DMAC0 and SYS-DMAC1 will never probe. However SYS-DMAC2 is 
> fine.
> 
> 2) After applying "[PATCH] iommu: of: Fix check for returning EPROBE_DEFER" 
> [1]
> 
> This fixes SYS-DMAC0 that now probes and operates without IPMMU-DS0 as
> expected. Same as v4.11 or earlier.
> 
> 3) After also applying "[PATCH] of: iommu: Ignore all errors except
> EPROBE_DEFER" [2]
> 
> This fixes SYS-DMAC1 that now probes and operates without IPMMU-DS1 as
> expected. Same as v4.11 or earlier.
> 
> With fix [1] and [2] things seem back to normal. Unless I'm mistaken

Thanks, will use this as your Tested-by.

Regards,
 Sricharan

> it also seems that [1] allows me to drop the similar patch "[PATCH/RFC
> v2 1/4] iommu/of: Skip IOMMU devices disabled in DT".
> 
> Thanks for your help.
> 
> Cheers,
> 
> / magnus
> 
> 
> [1] https://lkml.org/lkml/2017/5/16/25
> [2] https://www.spinics.net/lists/arm-kernel/msg581485.html
> [3] https://patchwork.kernel.org/patch/9540605/
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu: of: Fix check for returning EPROBE_DEFER

2017-05-16 Thread Sricharan R
Hi,

On 5/16/2017 7:39 PM, Jonathan Neuschäfer wrote:
> Hi, I have a few suggestions on how to make this commit message more
> readable:
> 
> On Tue, May 16, 2017 at 10:54:13AM +0530, Sricharan R wrote:
>> While returning EPROBE_DEFER for iommu masters
> 
> Add a comma at the end of this line
> 
>> take in to account of iommu nodes that could be
> 
> s/in to/into/
> s/of iommu/of_iommu/
> 

ok, will correct the above.

Regards,
 Sricharan

>> marked in DT as 'status=disabled', in which case
>> simply return NULL and let the master's probe
>> continue rather than deferring.
>>
>> Signed-off-by: Sricharan R 
>> Tested-by: Will Deacon 
>> Acked-by: Will Deacon 
> 
> 
> Thanks,
> Jonathan Neuschäfer
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH] ARM: dma-mapping: Don't tear third-party mappings

2017-05-16 Thread Sricharan R
orrect 
> mapping (created by arch_setup_dma_ops() while the IOMMU driver needs to take 
> care of mapping creation) exists.
> 

Feels correct not to reset this, the iommu drivers in question, seems to
creating mapping/attaching in add_device path (which gets called before the
clients gets probed) and when the iommu client gets deferred/reprobed that
does not happen again even after the first round.

>> With that (or firm reassurance that it's OK not to),
>>
>> Reviewed-by: Robin Murphy 
>>
>> Apologies for being too arm64-focused in the earlier reviews and
>> overlooking this. Should the patch supersede 8674/1 currently in
>> Russell's incoming box?
> 
> Yes I think it should. Could you please take care of that ?
> 
> You can also add my
> was
> Tested-by: Laurent Pinchart 
> 
> as I've tested that this paptch restores proper IOMMU operation on the 
> Renesas 
> R-Car H2 Lager board. I believe the problem related to Sricharan's patch 
> reported by Geert still affects us and needs to be addressed separately.

Thanks for the above, i had the same thing to be posted, was just testing it 
once.
There are three patches [1][2], already posted and third one for the issue that 
Geert
pointed i did below (Geert had a patch little differently to ignore -ENODEV).
I had this question previously for not propagating errors apart from 
EPROBE_DEFER,
did not have an issue reported at that time. Anyways if the below is ok, i will
just send the 3 patches in one set for easy picking up ?

[1] https://lkml.org/lkml/2017/5/16/25  
[2] The above one that you have. 
[3] The below one, if its fine ?

>From 4b379d4b852c41d7b5904c9a9e53deda94039f0a Mon Sep 17 00:00:00 2001
From: Sricharan R 
Date: Wed, 3 May 2017 14:54:11 +0530
Subject: [PATCH] of: iommu: Ignore all errors except EPROBE_DEFER

While deferring the probe of iommu masters,
xlate and add_device callback can passback error values
like -ENODEV, which means iommu cannot be connected
with that master for real reasons. So rather than
killing the master's probe for such errors, just
ignore the errors and let the master work without
an iommu.

Signed-off-by: Sricharan R 
---
 drivers/iommu/of_iommu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e6e9bec..750ab07 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -237,6 +237,10 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
ops = ERR_PTR(err);
}

+   /* Ignore all other errors apart from EPROBE_DEFER */
+   if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER))
+   ops = NULL;
+
return ops;
 }

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation



> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

Regards,
 Sricharan
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-16 Thread sricharan

Hi,

On 2017-05-16 19:40, Laurent Pinchart wrote:

Hi Robin,

On Tuesday 16 May 2017 15:04:55 Robin Murphy wrote:

On 16/05/17 08:17, Laurent Pinchart wrote:
> On Tuesday 16 May 2017 07:53:57 sricha...@codeaurora.org wrote:


[snip]


>> arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops()
>> ,dma_ops should be cleared in the teardown path. Otherwise
>> this causes problem when the probe of device is retried after
>> being deferred. The device's iommu structures are cleared
>> after EPROBEDEFER error, but on the next try dma_ops will still
>> be set to old value, which is not right.
>>
>> Signed-off-by: Sricharan R 
>> Reviewed-by: Robin Murphy 
>> ---
>>
>>   arch/arm/mm/dma-mapping.c | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
>> index ab4f745..a40f03e 100644
>> --- a/arch/arm/mm/dma-mapping.c
>> +++ b/arch/arm/mm/dma-mapping.c
>> @@ -2358,6 +2358,7 @@ static void arm_teardown_iommu_dma_ops(struct
>> device *dev)
>
>>__arm_iommu_detach_device(dev);
>>arm_iommu_release_mapping(mapping);
>> +  set_dma_ops(dev, NULL);
>>   }
>>   #else
>
> The subject mentions arch_teardown_dma_ops(), which I think is correct,
> but the patch adds the set_dma_ops() call to arm_teardown_iommu_dma_ops().
>
> However, the situation is perhaps more complex. Note the check at the
> beginning of arch_setup_dma_ops():
>/*
> * Don't override the dma_ops if they have already been set. Ideally
> * this should be the only location where dma_ops are set, remove this
> * check when all other callers of set_dma_ops will have disappeared.
> */
>if (dev->dma_ops)
>return;
>
> If you set the dma_ops to NULL in arm_teardown_iommu_dma_ops() or
> arch_teardown_dma_ops(), the next call to arch_setup_dma_ops() will
> override them. To be safe you should only set them to NULL if they have
> been set by arch_setup_dma_ops(). More than that, arch_teardown_dma_ops()
> should probably not call arm_teardown_iommu_dma_ops() at all if the
> dma_ops were set by arm_iommu_attach_device() and not
> arch_teardown_dma_ops().

Under what circumstances is that an issue? We'll only be tearing down
the DMA ops when unbinding the driver,


Or when deferring probe.

and I think it would be erroneous to expect the device to retain much 
state
after that. Everything else would be set up from scratch again if it 
get

reprobed later, so why not the DMA ops?


Because the DMA ops might have been set elsewhere than 
arch_setup_dma_ops().
If you look at the patch that added the above warning, its commit 
message

states

commit 26b37b946a5c2658dbc37dd5d6df40aaa9685d70 (iommu-joerg/arm/core)
Author: Laurent Pinchart 
Date:   Fri May 15 02:00:02 2015 +0300

arm: dma-mapping: Don't override dma_ops in arch_setup_dma_ops()

The arch_setup_dma_ops() function is in charge of setting dma_ops 
with a

call to set_dma_ops(). set_dma_ops() is also called from

- highbank and mvebu bus notifiers
- dmabounce (to be replaced with swiotlb)
- arm_iommu_attach_device

(arm_iommu_attach_device is itself called from IOMMU and bus master
device drivers)

To allow the arch_setup_dma_ops() call to be moved from device add 
time
to device probe time we must ensure that dma_ops already setup by 
any of

the above callers will not be overriden.

Aftering replacing dmabounce with swiotlb, converting IOMMU drivers 
to
of_xlate and taking care of highbank and mvebu, the workaround 
should be

removed.

I'm concerned about potentially breaking these if we unconditionally 
remove

the DMA ops and mapping.


arch_teardown_dma_ops does nothing if there is
no mapping (not behind iommu), dma_ops without iommu is ok.
But when the arm_iommu_create_mapping/arm_iommu_attach_device
was called previously in the iommu driver, after we teardown,
that path in the iommu driver which called those functions is not
replayed.

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


Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-16 Thread sricharan

Hi Laurent,

On 2017-05-16 12:47, Laurent Pinchart wrote:

Hi Sricharan,

On Tuesday 16 May 2017 07:53:57 sricha...@codeaurora.org wrote:

On 2017-05-16 03:04, Laurent Pinchart wrote:
> On Monday 15 May 2017 23:37:16 Laurent Pinchart wrote:
>> On Wednesday 03 May 2017 15:54:59 Sricharan R wrote:
>>> On 5/3/2017 3:24 PM, Robin Murphy wrote:
>>>> On 02/05/17 19:35, Geert Uytterhoeven wrote:
>>>>> On Fri, Feb 3, 2017 at 4:48 PM, Sricharan R wrote:
>>>>>> From: Laurent Pinchart 
>>>>>>
>>>>>> Failures to look up an IOMMU when parsing the DT iommus property
>>>>>> need to be handled separately from the .of_xlate() failures to
>>>>>> support deferred probing.
>>>>>>
>>>>>> The lack of a registered IOMMU can be caused by the lack of a driver
>>>>>> for the IOMMU, the IOMMU device probe not having been performed yet,
>>>>>> having been deferred, or having failed.
>>>>>>
>>>>>> The first case occurs when the device tree describes the bus master
>>>>>> and IOMMU topology correctly but no device driver exists for the
>>>>>> IOMMU yet or the device driver has not been compiled in. Return NULL,
>>>>>> the caller will configure the device without an IOMMU.
>>>>>>
>>>>>> The second and third cases are handled by deferring the probe of the
>>>>>> bus master device which will eventually get reprobed after the
>>>>>> IOMMU.
>>>>>>
>>>>>> The last case is currently handled by deferring the probe of the bus
>>>>>> master device as well. A mechanism to either configure the bus
>>>>>> master device without an IOMMU or to fail the bus master device probe
>>>>>> depending on whether the IOMMU is optional or mandatory would be a
>>>>>> good enhancement.
>>>>>>
>>>>>> Tested-by: Marek Szyprowski 
>>>>>> Signed-off-by: Laurent Pichart
>>>>>> 
>>>>>> Signed-off-by: Sricharan R 
>>>>>
>>>>> This patch broke Renesas R-Car Gen3 platforms in renesas-drivers.
>>>>> As the IOMMU nodes in DT are not yet enabled, all devices having
>>>>> iommus properties in DT now fail to probe.
>>>>
>>>> How exactly do they fail to probe? Per d7b0558230e4, if there are no
>>>> ops registered then they should merely defer until we reach the point
>>>> of giving up and ignoring the IOMMU. Is it just that you have no other
>>>> late-probing drivers or post-init module loads to kick the deferred
>>>> queue after that point? I did try to find a way to explicitly kick it
>>>> from a suitably late initcall, but there didn't seem to be any obvious
>>>> public interface - anyone have any suggestions?
>>>>
>>>> I think that's more of a general problem with the probe deferral
>>>> mechanism itself (I've seen the same thing happen with some of the
>>>> CoreSight stuff on Juno due to the number of inter-component
>>>> dependencies) rather than any specific fault of this series.
>>>
>>> I was thinking of an additional check like below to avoid the
>>> situation ?
>>>
>>> From 499b6e662f60f23740b8880882b0a16f16434501 Mon Sep 17 00:00:00 2001
>>> From: Sricharan R 
>>> Date: Wed, 3 May 2017 13:16:59 +0530
>>> Subject: [PATCH] iommu: of: Fix check for returning EPROBE_DEFER
>>>
>>> While returning EPROBE_DEFER for iommu masters
>>> take in to account of iommu nodes that could be
>>> marked in DT as 'status=disabled', in which case
>>> simply return NULL and let the master's probe
>>> continue rather than deferring.
>>>
>>> Signed-off-by: Sricharan R 
>>> ---
>>>
>>>  drivers/iommu/of_iommu.c | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
>>> index 9f44ee8..e6e9bec 100644
>>> --- a/drivers/iommu/of_iommu.c
>>> +++ b/drivers/iommu/of_iommu.c
>>> @@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct
>>> device_node *np)
>>>
>>> ops = iommu_ops_from_fwnode(fwnode);
>>> if ((ops && !ops->of_xlate) ||
>>> +   !of_device_is_available(iommu_spec->np) ||
>>> (!ops &&

[PATCH] iommu: of: Fix check for returning EPROBE_DEFER

2017-05-15 Thread Sricharan R
While returning EPROBE_DEFER for iommu masters
take in to account of iommu nodes that could be
marked in DT as 'status=disabled', in which case
simply return NULL and let the master's probe
continue rather than deferring.

Signed-off-by: Sricharan R 
Tested-by: Will Deacon 
Acked-by: Will Deacon 
---
 drivers/iommu/of_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 9f44ee8..e6e9bec 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node *np)
 
ops = iommu_ops_from_fwnode(fwnode);
if ((ops && !ops->of_xlate) ||
+   !of_device_is_available(iommu_spec->np) ||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-15 Thread sricharan

Hi Will,

On 2017-05-15 19:52, Will Deacon wrote:

Hi Sricharan,

On Wed, May 03, 2017 at 03:54:59PM +0530, Sricharan R wrote:

On 5/3/2017 3:24 PM, Robin Murphy wrote:
> On 02/05/17 19:35, Geert Uytterhoeven wrote:
>> On Fri, Feb 3, 2017 at 4:48 PM, Sricharan R  wrote:
>>> From: Laurent Pinchart 
>>>
>>> Failures to look up an IOMMU when parsing the DT iommus property need to
>>> be handled separately from the .of_xlate() failures to support deferred
>>> probing.
>>>
>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>> been deferred, or having failed.
>>>
>>> The first case occurs when the device tree describes the bus master and
>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>> or the device driver has not been compiled in. Return NULL, the caller
>>> will configure the device without an IOMMU.
>>>
>>> The second and third cases are handled by deferring the probe of the bus
>>> master device which will eventually get reprobed after the IOMMU.
>>>
>>> The last case is currently handled by deferring the probe of the bus
>>> master device as well. A mechanism to either configure the bus master
>>> device without an IOMMU or to fail the bus master device probe depending
>>> on whether the IOMMU is optional or mandatory would be a good
>>> enhancement.
>>>
>>> Tested-by: Marek Szyprowski 
>>> Signed-off-by: Laurent Pichart 
>>> Signed-off-by: Sricharan R 
>>
>> This patch broke Renesas R-Car Gen3 platforms in renesas-drivers.
>> As the IOMMU nodes in DT are not yet enabled, all devices having iommus
>> properties in DT now fail to probe.
>
> How exactly do they fail to probe? Per d7b0558230e4, if there are no ops
> registered then they should merely defer until we reach the point of
> giving up and ignoring the IOMMU. Is it just that you have no other
> late-probing drivers or post-init module loads to kick the deferred
> queue after that point? I did try to find a way to explicitly kick it
> from a suitably late initcall, but there didn't seem to be any obvious
> public interface - anyone have any suggestions?
>
> I think that's more of a general problem with the probe deferral
> mechanism itself (I've seen the same thing happen with some of the
> CoreSight stuff on Juno due to the number of inter-component
> dependencies) rather than any specific fault of this series.
>

I was thinking of an additional check like below to avoid the
situation ?

From 499b6e662f60f23740b8880882b0a16f16434501 Mon Sep 17 00:00:00 2001
From: Sricharan R 
Date: Wed, 3 May 2017 13:16:59 +0530
Subject: [PATCH] iommu: of: Fix check for returning EPROBE_DEFER

While returning EPROBE_DEFER for iommu masters
take in to account of iommu nodes that could be
marked in DT as 'status=disabled', in which case
simply return NULL and let the master's probe
continue rather than deferring.

Signed-off-by: Sricharan R 
---
 drivers/iommu/of_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 9f44ee8..e6e9bec 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct 
device_node *np)


ops = iommu_ops_from_fwnode(fwnode);
if ((ops && !ops->of_xlate) ||
+   !of_device_is_available(iommu_spec->np) ||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;


Without this patch, v4.12-rc1 hangs on my Juno waiting to mount the 
root
filesystem. The problem is that the USB controller is behind an SMMU 
which
is marked as 'status = "disabled"' in the devicetree. Whilst there was 
a
separate thread with Ard about exactly what this means in terms of the 
DMA

ops used by upstream devices, your patch above fixes the regression and
I think should go in regardless. The DMA ops issue will likely require
an additional DT binding anyway, to advertise the behaviour of the
IOMMU when it is disabled.

Tested-by: Will Deacon 
Acked-by: Will Deacon 

Could you resend it as a proper patch, please?


Sure, will send this as a separate patch.

Regards,
 Sricharan
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-15 Thread sricharan

Hi Laurent,

On 2017-05-16 03:04, Laurent Pinchart wrote:

Hi Sricharan,

On Monday 15 May 2017 23:37:16 Laurent Pinchart wrote:

On Wednesday 03 May 2017 15:54:59 Sricharan R wrote:
> On 5/3/2017 3:24 PM, Robin Murphy wrote:
>> On 02/05/17 19:35, Geert Uytterhoeven wrote:
>>> On Fri, Feb 3, 2017 at 4:48 PM, Sricharan R wrote:
>>>> From: Laurent Pinchart 
>>>>
>>>> Failures to look up an IOMMU when parsing the DT iommus property need
>>>> to be handled separately from the .of_xlate() failures to support
>>>> deferred probing.
>>>>
>>>> The lack of a registered IOMMU can be caused by the lack of a driver
>>>> for the IOMMU, the IOMMU device probe not having been performed yet,
>>>> having been deferred, or having failed.
>>>>
>>>> The first case occurs when the device tree describes the bus master
>>>> and IOMMU topology correctly but no device driver exists for the IOMMU
>>>> yet or the device driver has not been compiled in. Return NULL, the
>>>> caller will configure the device without an IOMMU.
>>>>
>>>> The second and third cases are handled by deferring the probe of the
>>>> bus master device which will eventually get reprobed after the IOMMU.
>>>>
>>>> The last case is currently handled by deferring the probe of the bus
>>>> master device as well. A mechanism to either configure the bus master
>>>> device without an IOMMU or to fail the bus master device probe
>>>> depending on whether the IOMMU is optional or mandatory would be a good
>>>> enhancement.
>>>>
>>>> Tested-by: Marek Szyprowski 
>>>> Signed-off-by: Laurent Pichart
>>>> 
>>>> Signed-off-by: Sricharan R 
>>>
>>> This patch broke Renesas R-Car Gen3 platforms in renesas-drivers.
>>> As the IOMMU nodes in DT are not yet enabled, all devices having iommus
>>> properties in DT now fail to probe.
>>
>> How exactly do they fail to probe? Per d7b0558230e4, if there are no ops
>> registered then they should merely defer until we reach the point of
>> giving up and ignoring the IOMMU. Is it just that you have no other
>> late-probing drivers or post-init module loads to kick the deferred
>> queue after that point? I did try to find a way to explicitly kick it
>> from a suitably late initcall, but there didn't seem to be any obvious
>> public interface - anyone have any suggestions?
>>
>> I think that's more of a general problem with the probe deferral
>> mechanism itself (I've seen the same thing happen with some of the
>> CoreSight stuff on Juno due to the number of inter-component
>> dependencies) rather than any specific fault of this series.
>
> I was thinking of an additional check like below to avoid the
> situation ?
>
> From 499b6e662f60f23740b8880882b0a16f16434501 Mon Sep 17 00:00:00 2001
> From: Sricharan R 
> Date: Wed, 3 May 2017 13:16:59 +0530
> Subject: [PATCH] iommu: of: Fix check for returning EPROBE_DEFER
>
> While returning EPROBE_DEFER for iommu masters
> take in to account of iommu nodes that could be
> marked in DT as 'status=disabled', in which case
> simply return NULL and let the master's probe
> continue rather than deferring.
>
> Signed-off-by: Sricharan R 
> ---
>
>  drivers/iommu/of_iommu.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 9f44ee8..e6e9bec 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node
> *np)
>
> ops = iommu_ops_from_fwnode(fwnode);
> if ((ops && !ops->of_xlate) ||
> +   !of_device_is_available(iommu_spec->np) ||
> (!ops && !of_iommu_driver_present(iommu_spec->np)))
> return NULL;

This looks good to me, but won't be enough. The ipmmu-vmsa driver in
v4.12-rc1 doesn't call iommu_device_register() and thus won't be found 
by
iommu_ops_from_fwnode(). Furthermore, it doesn't IOMMU_OF_DECLARE(), 
and

thus will always be considered as absent.

I agree that the ipmmu-vmsa driver needs to be fixed, but it would 
have been
nice to check existing IOMMU drivers before merging this patch 
series...


Please pardon the question, but has this patch series been tested on 
ARM32 ?


When the device is probed the arch_setup_dma_ops() function is called. 
It sets
the device's dma_ops and the mapping (in __arm_iommu_attach_device()). 
If
probe is deferred, arch_tea

Re: [PATCH 3/4] iommu: add qcom_iommu

2017-05-11 Thread Sricharan R
Hi,

On 5/11/2017 10:20 PM, Rob Clark wrote:
> On Thu, May 11, 2017 at 11:08 AM, Sricharan R  
> wrote:
>> Hi Rob,
>>
>> 
>>
>>> +static irqreturn_t qcom_iommu_fault(int irq, void *dev)
>>> +{
>>> + struct qcom_iommu_ctx *ctx = dev;
>>> + u32 fsr, fsynr;
>>> + unsigned long iova;
>>> +
>>> + fsr = iommu_readl(ctx, ARM_SMMU_CB_FSR);
>>> +
>>> + if (!(fsr & FSR_FAULT))
>>> + return IRQ_NONE;
>>> +
>>> + fsynr = iommu_readl(ctx, ARM_SMMU_CB_FSYNR0);
>>> + iova = iommu_readq(ctx, ARM_SMMU_CB_FAR);
>>> +
>>> + dev_err_ratelimited(ctx->dev,
>>> + "Unhandled context fault: fsr=0x%x, "
>>> + "iova=0x%08lx, fsynr=0x%x, cb=%d\n",
>>> + fsr, iova, fsynr, ctx->asid);
>>> +
>>> + iommu_writel(ctx, ARM_SMMU_CB_FSR, fsr);
>>
>> Just thinking if the clocks should be enabled in the fault handler
>> for handling cases that would happen out of the master context.
>> While global faults are one case, that is anyways is handled in
>> secure world for this case. Something like bootloader used the iommu
>> and not handled the fault, and getting the fault in kernel the
>> moment we enable the ctx. Atleast downstream seems to enable the
>> clocks in the fault handler explicitly.
> 
> hmm, I wonder if we should instead do something to clear interrupts
> when we initialize the context?
> 
> I guess we probably don't want to get fault irq's from the bootloader..

Right, better to clear it in the beginning and that could be added.


Regards,
 Sricharan

> 
> BR,
> -R
> 
>> Regards,
>>  Sricharan
>>
>>
>>> +
>>> + return IRQ_HANDLED;
>>> +}
>>> +
>>> +static int qcom_iommu_init_domain(struct iommu_domain *domain,
>>> +   struct qcom_iommu_dev *qcom_iommu,
>>> +   struct iommu_fwspec *fwspec)
>>> +{
>>> + struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
>>> + struct io_pgtable_ops *pgtbl_ops;
>>> + struct io_pgtable_cfg pgtbl_cfg;
>>> + int i, ret = 0;
>>> + u32 reg;
>>> +
>>> + mutex_lock(&qcom_domain->init_mutex);
>>> + if (qcom_domain->iommu)
>>> + goto out_unlock;
>>> +
>>> + pgtbl_cfg = (struct io_pgtable_cfg) {
>>> + .pgsize_bitmap  = qcom_iommu_ops.pgsize_bitmap,
>>> + .ias= 32,
>>> + .oas= 40,
>>> + .tlb= &qcom_gather_ops,
>>> + .iommu_dev  = qcom_iommu->dev,
>>> + };
>>> +
>>> + qcom_domain->iommu = qcom_iommu;
>>> + pgtbl_ops = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &pgtbl_cfg, fwspec);
>>> + if (!pgtbl_ops) {
>>> + dev_err(qcom_iommu->dev, "failed to allocate pagetable 
>>> ops\n");
>>> + ret = -ENOMEM;
>>> + goto out_clear_iommu;
>>> + }
>>> +
>>> + /* Update the domain's page sizes to reflect the page table format */
>>> + domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
>>> + domain->geometry.aperture_end = (1ULL << pgtbl_cfg.ias) - 1;
>>> + domain->geometry.force_aperture = true;
>>> +
>>> + for (i = 0; i < fwspec->num_ids; i++) {
>>> + struct qcom_iommu_ctx *ctx = to_ctx(fwspec, fwspec->ids[i]);
>>> +
>>> + if (!ctx->secure_init) {
>>> + ret = qcom_scm_restore_sec_cfg(qcom_iommu->sec_id, 
>>> ctx->asid);
>>> + if (ret) {
>>> + dev_err(qcom_iommu->dev, "secure init failed: 
>>> %d\n", ret);
>>> + goto out_clear_iommu;
>>> + }
>>> + ctx->secure_init = true;
>>> + }
>>> +
>>> + /* TTBRs */
>>> + iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
>>> + pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0] |
>>> + ((u64)ctx->asid << TTBRn_ASID_SHIFT));
>>> + iommu_writeq(ctx, ARM_SMMU_CB_TTBR1,
>>> +   

Re: [PATCH 3/4] iommu: add qcom_iommu

2017-05-11 Thread Sricharan R
Hi Rob,



> +static irqreturn_t qcom_iommu_fault(int irq, void *dev)
> +{
> + struct qcom_iommu_ctx *ctx = dev;
> + u32 fsr, fsynr;
> + unsigned long iova;
> +
> + fsr = iommu_readl(ctx, ARM_SMMU_CB_FSR);
> +
> + if (!(fsr & FSR_FAULT))
> + return IRQ_NONE;
> +
> + fsynr = iommu_readl(ctx, ARM_SMMU_CB_FSYNR0);
> + iova = iommu_readq(ctx, ARM_SMMU_CB_FAR);
> +
> + dev_err_ratelimited(ctx->dev,
> + "Unhandled context fault: fsr=0x%x, "
> + "iova=0x%08lx, fsynr=0x%x, cb=%d\n",
> + fsr, iova, fsynr, ctx->asid);
> +
> + iommu_writel(ctx, ARM_SMMU_CB_FSR, fsr);

Just thinking if the clocks should be enabled in the fault handler
for handling cases that would happen out of the master context.
While global faults are one case, that is anyways is handled in
secure world for this case. Something like bootloader used the iommu
and not handled the fault, and getting the fault in kernel the
moment we enable the ctx. Atleast downstream seems to enable the
clocks in the fault handler explicitly.

Regards,
 Sricharan


> +
> + return IRQ_HANDLED;
> +}
> +
> +static int qcom_iommu_init_domain(struct iommu_domain *domain,
> +   struct qcom_iommu_dev *qcom_iommu,
> +   struct iommu_fwspec *fwspec)
> +{
> + struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
> + struct io_pgtable_ops *pgtbl_ops;
> + struct io_pgtable_cfg pgtbl_cfg;
> + int i, ret = 0;
> + u32 reg;
> +
> + mutex_lock(&qcom_domain->init_mutex);
> + if (qcom_domain->iommu)
> + goto out_unlock;
> +
> + pgtbl_cfg = (struct io_pgtable_cfg) {
> + .pgsize_bitmap  = qcom_iommu_ops.pgsize_bitmap,
> + .ias= 32,
> + .oas= 40,
> + .tlb= &qcom_gather_ops,
> + .iommu_dev  = qcom_iommu->dev,
> + };
> +
> + qcom_domain->iommu = qcom_iommu;
> + pgtbl_ops = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &pgtbl_cfg, fwspec);
> + if (!pgtbl_ops) {
> + dev_err(qcom_iommu->dev, "failed to allocate pagetable ops\n");
> + ret = -ENOMEM;
> + goto out_clear_iommu;
> + }
> +
> + /* Update the domain's page sizes to reflect the page table format */
> + domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
> + domain->geometry.aperture_end = (1ULL << pgtbl_cfg.ias) - 1;
> + domain->geometry.force_aperture = true;
> +
> + for (i = 0; i < fwspec->num_ids; i++) {
> + struct qcom_iommu_ctx *ctx = to_ctx(fwspec, fwspec->ids[i]);
> +
> + if (!ctx->secure_init) {
> + ret = qcom_scm_restore_sec_cfg(qcom_iommu->sec_id, 
> ctx->asid);
> + if (ret) {
> + dev_err(qcom_iommu->dev, "secure init failed: 
> %d\n", ret);
> + goto out_clear_iommu;
> + }
> + ctx->secure_init = true;
> + }
> +
> + /* TTBRs */
> + iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
> + pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0] |
> + ((u64)ctx->asid << TTBRn_ASID_SHIFT));
> + iommu_writeq(ctx, ARM_SMMU_CB_TTBR1,
> + pgtbl_cfg.arm_lpae_s1_cfg.ttbr[1] |
> + ((u64)ctx->asid << TTBRn_ASID_SHIFT));
> +
> + /* TTBCR */
> + iommu_writel(ctx, ARM_SMMU_CB_TTBCR2,
> + (pgtbl_cfg.arm_lpae_s1_cfg.tcr >> 32) |
> + TTBCR2_SEP_UPSTREAM);
> + iommu_writel(ctx, ARM_SMMU_CB_TTBCR,
> + pgtbl_cfg.arm_lpae_s1_cfg.tcr);
> +
> + /* MAIRs (stage-1 only) */
> + iommu_writel(ctx, ARM_SMMU_CB_S1_MAIR0,
> + pgtbl_cfg.arm_lpae_s1_cfg.mair[0]);
> + iommu_writel(ctx, ARM_SMMU_CB_S1_MAIR1,
> + pgtbl_cfg.arm_lpae_s1_cfg.mair[1]);
> +
> + /* SCTLR */
> + reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE |
> + SCTLR_M | SCTLR_S1_ASIDPNE;
> +
> + if (IS_ENABLED(CONFIG_BIG_ENDIAN))
> + reg |= SCTLR_E;
> +
> + iommu_writel(ctx, ARM_SMMU_CB_SCTLR, reg);
> + }
> +
> + mutex_unlock(&qcom_domain->init_mutex);
&

Re: [PATCH V11 00/11] IOMMU probe deferral support

2017-05-08 Thread Sricharan R
Hi,

On 5/8/2017 4:53 PM, Marek Szyprowski wrote:
> Hi Sricharan,
> 
> On 2017-04-10 13:20, Sricharan R wrote:
>> This series calls the dma ops configuration for the devices
>> at a generic place so that it works for all busses.
>> The dma_configure_ops for a device is now called during
>> the device_attach callback just before the probe of the
>> bus/driver is called. Similarly dma_deconfigure is called during
>> device/driver_detach path.
>>
>> pci_bus_add_devices(platform/amba)(_device_create/driver_register)
>> | |
>> pci_bus_add_device (device_add/driver_register)
>> | |
>> device_attach   device_initial_probe
>> | |
>> __device_attach_driver__device_attach_driver
>> |
>> driver_probe_device
>> |
>> really_probe
>> |
>> dma_configure
>>
>> Similarly on the device/driver_unregister path __device_release_driver is
>> called which inturn calls dma_deconfigure.
>>
>> Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
>> against iommu-next and with 3-way merge applies on top of linux-next
>> as well (patch #8), because of "ACPI platform MSI support" from
>> Hanjun being merged.
>>* Tested with platform and pci devices for probe deferral
>>and reprobe on arm64 based platform.
> 
> I just noticed that in the meantime the following patch: "arm: dma-mapping:
> Reset the device's dma_ops" (https://patchwork.kernel.org/patch/9434105/ )
> has been dropped from this series.
> 
> Lack of it causes serious issues with deferred probe of devices, which are
> under IOMMU on ARM architecture. Please check where it got lost and push it
> to Russell's patch tracking system ASAP to get it during v4.12-rcX cycle.

ha, bad on me. I posted this patch independently from the series, but was not
added to patch system. Will add it now.

Regards,
 Sricharan

> 
>>
>> Previous post of this series [8].
>>
>> Please note that, i have kept the tested/acked tags intact from V8
>> because V9/10/11 were for more fixes that was added, so the original
>> tags that was given for the functional testing remains the same.
>>
>>   [V11]
>>   * No functional changes.
>>
>>   * Rebased on top of 4.11-rc6.
>>
>>   * Dropped patch#3 from V10, as a result have to make
>> a change in patch#7 to return a 'non-void' to fix a
>> build warning.
>>
>>   * Added Robin's and Rob's tags.
>>
>>   [V10]
>>   * Rebased on top of 4.11-rc5.
>> * Fixed coherent_dma_mask 64bit overflow issue [8]
>> for OF. The fix for OF was added as a separate
>> patch#6, since the issue is true even without probe deferral,
>> but gets reproduced with the probe deferral series.
>> Added Lorenzo's ACPI fix for coherent_dma_mask overflow
>> and the fix for dma_configure getting called more than
>> once for the same device.
>>
>>   * Also fixed an build issue caught by kbuild robot for
>> m68k arch. The issue was dma_(de)configure was not
>> getting defined for !CONFIG_HAS_DMA, so fixed that as well.
>>
>>   [V9]
>>   * Rebased on top of 4.11-rc1.
>>
>>   * Merged Robin's fixes for legacy binding issue,
>> pci devices with no iommu-map property and deferencing
>> of_iommu_table after init.
>> [V8]
>>   * Picked up all the acks and tested tags from Marek and
>> Hanjun for DT and ACPI patches respectively, since
>> no functional changes was done.
>>
>>   * Addressed Minor comments Sinan and Bjorn.
>>
>>   * Added Robin's fix for fixing the deferencing NULL for
>> of_iommu_table after init in patch #2.
>>
>>   * Rebased it on top of linux-next
>>
>>   [V7]
>>   * Updated the subject and commit log for patch #6 as per
>> comments from Lorenzo. No functional changes.
>>
>>   [V6]
>>   * Fixed a bug in dma_configure function pointed out by
>> Robin.
>>   * Reordered the patches as per comments from Robin and
>> Lorenzo.
>>   * Added Tags.
>>
>>   [V5]
>>   * Reworked the pci configuration code hanging outside and
>> pushed it to dma_configure as in PATCH#5,6,7.
>> Also added a couple of patches that Lorenzo

Re: [PATCH 3/4] iommu: add qcom_iommu

2017-05-05 Thread Sricharan R
< snip ..>
>> +
>> +static struct platform_driver qcom_iommu_driver = {
>> +   .driver = {
>> +   .name   = "qcom-iommu",
>> +   .of_match_table = of_match_ptr(qcom_iommu_of_match),
>> +   .pm = &qcom_iommu_pm_ops,
>> +   },
>> +   .probe  = qcom_iommu_device_probe,
>> +   .remove = qcom_iommu_device_remove,
>> +};
>> +module_platform_driver(qcom_iommu_driver);
>> +
>> +IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1", NULL);
> 
> Is this needed any more with deferred probe now?

Yes, because the __iommu_of_table is still used for to find out
the presence of the driver.

Regards,
 Sricharan

> 
>> +
>> +MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 2.9.3
>>

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-03 Thread Sricharan R
Hi,

On 5/3/2017 3:54 PM, Sricharan R wrote:
> Hi Robin,
> 
> On 5/3/2017 3:24 PM, Robin Murphy wrote:
>> Hi Geert,
>>
>> On 02/05/17 19:35, Geert Uytterhoeven wrote:
>>> Hi Sricharan,
>>>
>>> On Fri, Feb 3, 2017 at 4:48 PM, Sricharan R  
>>> wrote:
>>>> From: Laurent Pinchart 
>>>>
>>>> Failures to look up an IOMMU when parsing the DT iommus property need to
>>>> be handled separately from the .of_xlate() failures to support deferred
>>>> probing.
>>>>
>>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>>> been deferred, or having failed.
>>>>
>>>> The first case occurs when the device tree describes the bus master and
>>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>>> or the device driver has not been compiled in. Return NULL, the caller
>>>> will configure the device without an IOMMU.
>>>>
>>>> The second and third cases are handled by deferring the probe of the bus
>>>> master device which will eventually get reprobed after the IOMMU.
>>>>
>>>> The last case is currently handled by deferring the probe of the bus
>>>> master device as well. A mechanism to either configure the bus master
>>>> device without an IOMMU or to fail the bus master device probe depending
>>>> on whether the IOMMU is optional or mandatory would be a good
>>>> enhancement.
>>>>
>>>> Tested-by: Marek Szyprowski 
>>>> Signed-off-by: Laurent Pichart 
>>>> Signed-off-by: Sricharan R 
>>>
>>> This patch broke Renesas R-Car Gen3 platforms in renesas-drivers.
>>> As the IOMMU nodes in DT are not yet enabled, all devices having iommus
>>> properties in DT now fail to probe.
>>
>> How exactly do they fail to probe? Per d7b0558230e4, if there are no ops
>> registered then they should merely defer until we reach the point of
>> giving up and ignoring the IOMMU. Is it just that you have no other
>> late-probing drivers or post-init module loads to kick the deferred
>> queue after that point? I did try to find a way to explicitly kick it
>> from a suitably late initcall, but there didn't seem to be any obvious
>> public interface - anyone have any suggestions?
>>
>> I think that's more of a general problem with the probe deferral
>> mechanism itself (I've seen the same thing happen with some of the
>> CoreSight stuff on Juno due to the number of inter-component
>> dependencies) rather than any specific fault of this series.
>>
> 
> I was thinking of an additional check like below to avoid the
> situation ?
> 
> From 499b6e662f60f23740b8880882b0a16f16434501 Mon Sep 17 00:00:00 2001
> From: Sricharan R 
> Date: Wed, 3 May 2017 13:16:59 +0530
> Subject: [PATCH] iommu: of: Fix check for returning EPROBE_DEFER
> 
> While returning EPROBE_DEFER for iommu masters
> take in to account of iommu nodes that could be
> marked in DT as 'status=disabled', in which case
> simply return NULL and let the master's probe
> continue rather than deferring.
> 
> Signed-off-by: Sricharan R 
> ---
>  drivers/iommu/of_iommu.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 9f44ee8..e6e9bec 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node 
> *np)
> 
> ops = iommu_ops_from_fwnode(fwnode);
> if ((ops && !ops->of_xlate) ||
> +   !of_device_is_available(iommu_spec->np) ||
> (!ops && !of_iommu_driver_present(iommu_spec->np)))
> return NULL;
> 

While same as the other 'status=disabled' patch [1], better not to
defer the probe itself in the case ?

[1] https://patchwork.kernel.org/patch/9681211/

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V8 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-05-03 Thread Sricharan R
Hi Robin,

On 5/3/2017 3:24 PM, Robin Murphy wrote:
> Hi Geert,
> 
> On 02/05/17 19:35, Geert Uytterhoeven wrote:
>> Hi Sricharan,
>>
>> On Fri, Feb 3, 2017 at 4:48 PM, Sricharan R  wrote:
>>> From: Laurent Pinchart 
>>>
>>> Failures to look up an IOMMU when parsing the DT iommus property need to
>>> be handled separately from the .of_xlate() failures to support deferred
>>> probing.
>>>
>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>> been deferred, or having failed.
>>>
>>> The first case occurs when the device tree describes the bus master and
>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>> or the device driver has not been compiled in. Return NULL, the caller
>>> will configure the device without an IOMMU.
>>>
>>> The second and third cases are handled by deferring the probe of the bus
>>> master device which will eventually get reprobed after the IOMMU.
>>>
>>> The last case is currently handled by deferring the probe of the bus
>>> master device as well. A mechanism to either configure the bus master
>>> device without an IOMMU or to fail the bus master device probe depending
>>> on whether the IOMMU is optional or mandatory would be a good
>>> enhancement.
>>>
>>> Tested-by: Marek Szyprowski 
>>> Signed-off-by: Laurent Pichart 
>>> Signed-off-by: Sricharan R 
>>
>> This patch broke Renesas R-Car Gen3 platforms in renesas-drivers.
>> As the IOMMU nodes in DT are not yet enabled, all devices having iommus
>> properties in DT now fail to probe.
> 
> How exactly do they fail to probe? Per d7b0558230e4, if there are no ops
> registered then they should merely defer until we reach the point of
> giving up and ignoring the IOMMU. Is it just that you have no other
> late-probing drivers or post-init module loads to kick the deferred
> queue after that point? I did try to find a way to explicitly kick it
> from a suitably late initcall, but there didn't seem to be any obvious
> public interface - anyone have any suggestions?
> 
> I think that's more of a general problem with the probe deferral
> mechanism itself (I've seen the same thing happen with some of the
> CoreSight stuff on Juno due to the number of inter-component
> dependencies) rather than any specific fault of this series.
> 

I was thinking of an additional check like below to avoid the
situation ?

>From 499b6e662f60f23740b8880882b0a16f16434501 Mon Sep 17 00:00:00 2001
From: Sricharan R 
Date: Wed, 3 May 2017 13:16:59 +0530
Subject: [PATCH] iommu: of: Fix check for returning EPROBE_DEFER

While returning EPROBE_DEFER for iommu masters
take in to account of iommu nodes that could be
marked in DT as 'status=disabled', in which case
simply return NULL and let the master's probe
continue rather than deferring.

Signed-off-by: Sricharan R 
---
 drivers/iommu/of_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 9f44ee8..e6e9bec 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -118,6 +118,7 @@ static bool of_iommu_driver_present(struct device_node *np)

ops = iommu_ops_from_fwnode(fwnode);
if ((ops && !ops->of_xlate) ||
+   !of_device_is_available(iommu_spec->np) ||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation


Regards,
 Sricharan


> Robin.
> 
>> This can be fixed by either:
>>   - Disabling CONFIG_IPMMU_VMSA, or
>>   - Reverting commit 7b07cbefb68d486f (but keeping "int ret = 0;").
>>
>> Note that this was a bit hard to investigate, as R-Car Gen3 support wasn't
>> upstreamed yet, so bisection pointed to a merge commit.
>>
>>> ---
>>>  [*] Fixed minor comment from Bjorn for removing the pci.h header inclusion
>>>  in of_iommu.c
>>>
>>>  drivers/base/dma-mapping.c | 5 +++--
>>>  drivers/iommu/of_iommu.c   | 4 ++--
>>>  drivers/of/device.c| 7 ++-
>>>  include/linux/of_device.h  | 9 ++---
>>>  4 files changed, 17 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
>>> index 449b948..82bd45c 100644
>>> --- a/drivers/base/dma-mapping.c
>>> +++ b/drivers/base/dma-mapping.c
>

[PATCH V11 06/11] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices

2017-04-10 Thread Sricharan R
Configuring DMA ops at probe time will allow deferring device probe when
the IOMMU isn't available yet. The dma_configure for the device is
now called from the generic device_attach callback just before the
bus/driver probe is called. This way, configuring the DMA ops for the
device would be called at the same place for all bus_types, hence the
deferred probing mechanism should work for all buses as well.

pci_bus_add_devices(platform/amba)(_device_create/driver_register)
   | |
pci_bus_add_device (device_add/driver_register)
   | |
device_attach   device_initial_probe
   | |
__device_attach_driver__device_attach_driver
   |
driver_probe_device
   |
really_probe
   |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

This patch changes the dma ops configuration to probe time for
both OF and ACPI based platform/amba/pci bus devices.

Tested-by: Marek Szyprowski 
Tested-by: Hanjun Guo 
Reviewed-by: Robin Murphy 
Acked-by: Rob Herring 
Acked-by: Bjorn Helgaas  (drivers/pci part)
Acked-by: Rafael J. Wysocki 
Signed-off-by: Sricharan R 
---
 drivers/acpi/glue.c |  5 -
 drivers/base/dd.c   |  9 +
 drivers/base/dma-mapping.c  | 40 
 drivers/of/platform.c   |  5 +
 drivers/pci/probe.c | 28 
 include/linux/dma-mapping.h | 12 
 6 files changed, 62 insertions(+), 37 deletions(-)

diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index fb19e1c..c05f241 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -176,7 +176,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
struct list_head *physnode_list;
unsigned int node_id;
int retval = -EINVAL;
-   enum dev_dma_attr attr;
 
if (has_acpi_companion(dev)) {
if (acpi_dev) {
@@ -233,10 +232,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
if (!has_acpi_companion(dev))
ACPI_COMPANION_SET(dev, acpi_dev);
 
-   attr = acpi_get_dma_attr(acpi_dev);
-   if (attr != DEV_DMA_NOT_SUPPORTED)
-   acpi_dma_configure(dev, attr);
-
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
   physical_node_name);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a1fbf55..4882f06 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -19,6 +19,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -356,6 +357,10 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
if (ret)
goto pinctrl_bind_failed;
 
+   ret = dma_configure(dev);
+   if (ret)
+   goto dma_failed;
+
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev_name(dev));
@@ -417,6 +422,8 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
goto done;
 
 probe_failed:
+   dma_deconfigure(dev);
+dma_failed:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
@@ -826,6 +833,8 @@ static void __device_release_driver(struct device *dev, 
struct device *parent)
drv->remove(dev);
 
device_links_driver_cleanup(dev);
+   dma_deconfigure(dev);
+
devres_release_all(dev);
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index efd71cf..449b948 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -7,9 +7,11 @@
  * This file is released under the GPLv2.
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -341,3 +343,41 @@ void dma_common_free_remap(void *cpu_addr, size_t size, 
unsigned long vm_flags)
vunmap(cpu_addr);
 }
 #endif
+
+/*
+ * Common configuration to enable DMA API use for a device
+ */
+#include 
+
+int dma_configure(struct device *dev)
+{
+   struct device *bridge = NULL, *dma_dev = dev;
+   enum dev_dma_attr attr;
+
+   if (dev_is_pci(dev)) {
+   bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+   dma_dev = bridge;
+   if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
+   dma_dev->parent->of_node)
+   dma_dev = dma_dev->parent;
+   }
+
+   if (dma_dev->of_node) {
+   of_dma_configure(dev, dma_dev

[PATCH V11 04/11] ACPI/IORT: Add function to check SMMUs drivers presence

2017-04-10 Thread Sricharan R
From: Lorenzo Pieralisi 

The IOMMU probe deferral implementation requires a mechanism to detect
if drivers for SMMU components are built-in in the kernel to detect
whether IOMMU configuration for a given device should be deferred (ie
SMMU drivers present but still not probed) or not (drivers not present).

Add a simple function to IORT to detect if SMMU drivers for SMMU
components managed by IORT are built-in in the kernel.

Tested-by: Hanjun Guo 
Signed-off-by: Lorenzo Pieralisi 
Reviewed-by: Robin Murphy 
Cc: Sricharan R 
---
 drivers/acpi/arm64/iort.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 4a5bb96..3dd9ec3 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -523,6 +523,19 @@ static int arm_smmu_iort_xlate(struct device *dev, u32 
streamid,
return ret;
 }
 
+static inline bool iort_iommu_driver_enabled(u8 type)
+{
+   switch (type) {
+   case ACPI_IORT_NODE_SMMU_V3:
+   return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
+   case ACPI_IORT_NODE_SMMU:
+   return IS_BUILTIN(CONFIG_ARM_SMMU);
+   default:
+   pr_warn("IORT node type %u does not describe an SMMU\n", type);
+   return false;
+   }
+}
+
 static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
struct acpi_iort_node *node,
u32 streamid)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error

2017-04-10 Thread Sricharan R
This is an equivalent to the DT's handling of the iommu master's probe
with deferred probing when the corrsponding iommu is not probed yet.
The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the firmware describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Hanjun Guo 
Reviewed-by: Robin Murphy 
[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
  called multiple times for same device]
Signed-off-by: Lorenzo Pieralisi 
Signed-off-by: Sricharan R 
---
 drivers/acpi/arm64/iort.c  | 33 -
 drivers/acpi/scan.c| 11 ---
 drivers/base/dma-mapping.c |  2 +-
 include/acpi/acpi_bus.h|  2 +-
 include/linux/acpi.h   |  7 +--
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 3dd9ec3..e323ece 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
device *dev,
const struct iommu_ops *ops = NULL;
int ret = -ENODEV;
struct fwnode_handle *iort_fwnode;
+   struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+
+   /*
+* If we already translated the fwspec there
+* is nothing left to do, return the iommu_ops.
+*/
+   if (fwspec && fwspec->ops)
+   return fwspec->ops;
 
if (node) {
iort_fwnode = iort_get_fwnode(node);
@@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
device *dev,
return NULL;
 
ops = iommu_ops_from_fwnode(iort_fwnode);
+   /*
+* If the ops look-up fails, this means that either
+* the SMMU drivers have not been probed yet or that
+* the SMMU drivers are not built in the kernel;
+* Depending on whether the SMMU drivers are built-in
+* in the kernel or not, defer the IOMMU configuration
+* or just abort it.
+*/
if (!ops)
-   return NULL;
+   return iort_iommu_driver_enabled(node->type) ?
+  ERR_PTR(-EPROBE_DEFER) : NULL;
 
ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
}
@@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct 
device *dev)
 
while (parent) {
ops = iort_iommu_xlate(dev, parent, streamid);
+   if (IS_ERR_OR_NULL(ops))
+   return ops;
 
parent = iort_node_get_id(node, &streamid,
  IORT_IOMMU_TYPE, i++);
}
}
 
+   /*
+* If we have reason to believe the IOMMU driver missed the initial
+* add_device callback for dev, replay it to get things in order.
+*/
+   if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+   dev->bus && !dev->iommu_group) {
+   int err = ops->add_device(dev);
+
+   if (err)
+   ops = ERR_PTR(err);
+   }
+
return ops;
 }
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1926918..2a513cc 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device 
*adev)
  * @dev: The pointer to the device
  * @attr: device dma attributes
  */
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 {
const struct iommu_ops *iommu;
+   u64 size;
 
iort_set_dma_mask(dev);
 
iommu = iort_iommu_configure(dev);
+   if (IS_ERR(iommu))
+   return PTR_ERR(iommu);
 
+   size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
/*
 * Assume dma valid range starts at 0 and covers the whole
 * coherent_dma_mask.
 */
-   arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
- 

[PATCH V11 10/11] iommu/arm-smmu: Clean up early-probing workarounds

2017-04-10 Thread Sricharan R
From: Robin Murphy 

Now that the appropriate ordering is enforced via probe-deferral of
masters in core code, rip it all out and bask in the simplicity.

Tested-by: Hanjun Guo 
Acked-by: Will Deacon 
Signed-off-by: Robin Murphy 
[Sricharan: Rebased on top of ACPI IORT SMMU series]
Signed-off-by: Sricharan R 
---
 drivers/iommu/arm-smmu-v3.c |  46 +-
 drivers/iommu/arm-smmu.c| 110 +++-
 2 files changed, 49 insertions(+), 107 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 5806a6a..9497800 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2761,51 +2761,9 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
.probe  = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
 };
+module_platform_driver(arm_smmu_driver);
 
-static int __init arm_smmu_init(void)
-{
-   static bool registered;
-   int ret = 0;
-
-   if (!registered) {
-   ret = platform_driver_register(&arm_smmu_driver);
-   registered = !ret;
-   }
-   return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
-   return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
-   int ret = arm_smmu_init();
-
-   if (ret)
-   return ret;
-
-   if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
-   return -ENODEV;
-
-   return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init acpi_smmu_v3_init(struct acpi_table_header *table)
-{
-   if (iort_node_match(ACPI_IORT_NODE_SMMU_V3))
-   return arm_smmu_init();
-
-   return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu_v3, ACPI_SIG_IORT, acpi_smmu_v3_init);
-#endif
+IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
 MODULE_AUTHOR("Will Deacon ");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index abf6496..be53b02 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2075,6 +2075,23 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
return 0;
 }
 
+static void arm_smmu_bus_init(void)
+{
+   /* Oh, for a proper bus abstraction */
+   if (!iommu_present(&platform_bus_type))
+   bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+#ifdef CONFIG_ARM_AMBA
+   if (!iommu_present(&amba_bustype))
+   bus_set_iommu(&amba_bustype, &arm_smmu_ops);
+#endif
+#ifdef CONFIG_PCI
+   if (!iommu_present(&pci_bus_type)) {
+   pci_request_acs();
+   bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
+   }
+#endif
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
struct resource *res;
@@ -2180,21 +2197,30 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
arm_smmu_device_reset(smmu);
arm_smmu_test_smr_masks(smmu);
 
-   /* Oh, for a proper bus abstraction */
-   if (!iommu_present(&platform_bus_type))
-   bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
-#ifdef CONFIG_ARM_AMBA
-   if (!iommu_present(&amba_bustype))
-   bus_set_iommu(&amba_bustype, &arm_smmu_ops);
-#endif
-#ifdef CONFIG_PCI
-   if (!iommu_present(&pci_bus_type)) {
-   pci_request_acs();
-   bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
-   }
-#endif
+   /*
+* For ACPI and generic DT bindings, an SMMU will be probed before
+* any device which might need it, so we want the bus ops in place
+* ready to handle default domain setup as soon as any SMMU exists.
+*/
+   if (!using_legacy_binding)
+   arm_smmu_bus_init();
+
+   return 0;
+}
+
+/*
+ * With the legacy DT binding in play, though, we have no guarantees about
+ * probe order, but then we're also not doing default domains, so we can
+ * delay setting bus ops until we're sure every possible SMMU is ready,
+ * and that way ensure that no add_device() calls get missed.
+ */
+static int arm_smmu_legacy_bus_init(void)
+{
+   if (using_legacy_binding)
+   arm_smmu_bus_init();
return 0;
 }
+device_initcall_sync(arm_smmu_legacy_bus_init);
 
 static int arm_smmu_device_remove(struct platform_device *pdev)
 {
@@ -2219,56 +2245,14 @@ static int arm_smmu_device_remove(struct 
platform_device *pdev)
.probe  = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
 };
-
-static int __init arm_smmu_init(void)
-{
-   static bool registered;
-   int ret = 0;
-
-   if (!registered) {
-   re

[PATCH V11 11/11] ACPI/IORT: Remove linker section for IORT entries probing

2017-04-10 Thread Sricharan R
From: Lorenzo Pieralisi 

The IORT linker section introduced by commit 34ceea275f62
("ACPI/IORT: Introduce linker section for IORT entries probing")
was needed to make sure SMMU drivers are registered (and therefore
probed) in the kernel before devices using the SMMU have a chance
to probe in turn.

Through the introduction of deferred IOMMU configuration the linker
section based IORT probing infrastructure is not needed any longer, in
that device/SMMU probe dependencies are managed through the probe
deferral mechanism, making the IORT linker section infrastructure
unused, so that it can be removed.

Remove the unused IORT linker section probing infrastructure
from the kernel to complete the ACPI IORT IOMMU configure probe
deferral mechanism implementation.

Tested-by: Hanjun Guo 
Reviewed-by: Robin Murphy 
Signed-off-by: Lorenzo Pieralisi 
Cc: Sricharan R 
---
 drivers/acpi/arm64/iort.c | 2 --
 include/asm-generic/vmlinux.lds.h | 1 -
 include/linux/acpi_iort.h | 3 ---
 3 files changed, 6 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index e323ece..e7b1940 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1000,6 +1000,4 @@ void __init acpi_iort_init(void)
}
 
iort_init_platform_devices();
-
-   acpi_probe_device_table(iort);
 }
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 0968d13..9faa26c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -566,7 +566,6 @@
IRQCHIP_OF_MATCH_TABLE()\
ACPI_PROBE_TABLE(irqchip)   \
ACPI_PROBE_TABLE(clksrc)\
-   ACPI_PROBE_TABLE(iort)  \
EARLYCON_TABLE()
 
 #define INIT_TEXT  \
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 77e0809..f167e1d04 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -52,7 +52,4 @@ const struct iommu_ops *iort_iommu_configure(struct device 
*dev)
 { return NULL; }
 #endif
 
-#define IORT_ACPI_DECLARE(name, table_id, fn)  \
-   ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn)
-
 #endif /* __ACPI_IORT_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V11 05/11] of: device: Fix overflow of coherent_dma_mask

2017-04-10 Thread Sricharan R
Size of the dma-range is calculated as coherent_dma_mask + 1
and passed to arch_setup_dma_ops further. It overflows when
the coherent_dma_mask is set for full 64 bits 0x,
resulting in size getting passed as 0 wrongly. Fix this by
passsing in max(mask, mask + 1). Note that in this case
when the mask is set to full 64bits, we will be passing the mask
itself to arch_setup_dma_ops instead of the size. The real fix
for this should be to make arch_setup_dma_ops receive the
mask and handle it, to be done in the future.

Reviewed-by: Robin Murphy 
Acked-by: Rob Herring 
Signed-off-by: Sricharan R 
---
 drivers/of/device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 0d378c0..e1ae9e7 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -107,7 +107,7 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
-   size = dev->coherent_dma_mask + 1;
+   size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
} else {
offset = PFN_DOWN(paddr - dma_addr);
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V11 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-04-10 Thread Sricharan R
From: Laurent Pinchart 

Failures to look up an IOMMU when parsing the DT iommus property need to
be handled separately from the .of_xlate() failures to support deferred
probing.

The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the device tree describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Marek Szyprowski 
Reviewed-by: Robin Murphy 
Acked-by: Rob Herring 
Signed-off-by: Laurent Pichart 
Signed-off-by: Sricharan R 
---

 [V11] Small change to return non-void value in one of returns
   in of_dma_configure, as a result of dropping patch #3 from
   previous V10. No functional impact.

 drivers/base/dma-mapping.c | 5 +++--
 drivers/iommu/of_iommu.c   | 4 ++--
 drivers/of/device.c| 9 +++--
 include/linux/of_device.h  | 9 ++---
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 449b948..82bd45c 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -353,6 +353,7 @@ int dma_configure(struct device *dev)
 {
struct device *bridge = NULL, *dma_dev = dev;
enum dev_dma_attr attr;
+   int ret = 0;
 
if (dev_is_pci(dev)) {
bridge = pci_get_host_bridge_device(to_pci_dev(dev));
@@ -363,7 +364,7 @@ int dma_configure(struct device *dev)
}
 
if (dma_dev->of_node) {
-   of_dma_configure(dev, dma_dev->of_node);
+   ret = of_dma_configure(dev, dma_dev->of_node);
} else if (has_acpi_companion(dma_dev)) {
attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
if (attr != DEV_DMA_NOT_SUPPORTED)
@@ -373,7 +374,7 @@ int dma_configure(struct device *dev)
if (bridge)
pci_put_host_bridge_device(bridge);
 
-   return 0;
+   return ret;
 }
 
 void dma_deconfigure(struct device *dev)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index c8be889..9f44ee8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -236,7 +236,7 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
ops = ERR_PTR(err);
}
 
-   return IS_ERR(ops) ? NULL : ops;
+   return ops;
 }
 
 static int __init of_iommu_init(void)
@@ -247,7 +247,7 @@ static int __init of_iommu_init(void)
for_each_matching_node_and_match(np, matches, &match) {
const of_iommu_init_fn init_fn = match->data;
 
-   if (init_fn(np))
+   if (init_fn && init_fn(np))
pr_err("Failed to initialise IOMMU %s\n",
of_node_full_name(np));
}
diff --git a/drivers/of/device.c b/drivers/of/device.c
index e1ae9e7..8bd3d8c 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -82,7 +82,7 @@ int of_device_add(struct platform_device *ofdev)
  * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
  * to fix up DMA configuration.
  */
-void of_dma_configure(struct device *dev, struct device_node *np)
+int of_dma_configure(struct device *dev, struct device_node *np)
 {
u64 dma_addr, paddr, size;
int ret;
@@ -123,7 +123,7 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
 
if (!size) {
dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
-   return;
+   return -EINVAL;
}
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}
@@ -144,10 +144,15 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
coherent ? " " : " not ");
 
iommu = of_iommu_configure(dev, np);
+   if (IS_ERR(iommu))
+   return PTR_ERR(iommu);
+
dev_dbg(dev, "device is%sbehind an iommu\n",
iommu ? " " : " not ");
 
arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
+
+   return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index af98455..2cacdd8 100644
--- a/i

[PATCH V11 09/11] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops

2017-04-10 Thread Sricharan R
With arch_setup_dma_ops now being called late during device's probe after
the device's iommu is probed, the notifier trick required to handle the
early setup of dma_ops before the iommu group gets created is not
required. So removing the notifier's here.

Tested-by: Marek Szyprowski 
Tested-by: Hanjun Guo 
Acked-by: Will Deacon 
Signed-off-by: Sricharan R 
[rm: clean up even more]
Signed-off-by: Robin Murphy 
---
 arch/arm64/mm/dma-mapping.c | 142 ++--
 1 file changed, 18 insertions(+), 124 deletions(-)

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 81cdb2e..b465759 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -813,34 +813,26 @@ static void __iommu_unmap_sg_attrs(struct device *dev,
.mapping_error = iommu_dma_mapping_error,
 };
 
-/*
- * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
- * everything it needs to - the device is only partially created and the
- * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
- * need this delayed attachment dance. Once IOMMU probe ordering is sorted
- * to move the arch_setup_dma_ops() call later, all the notifier bits below
- * become unnecessary, and will go away.
- */
-struct iommu_dma_notifier_data {
-   struct list_head list;
-   struct device *dev;
-   const struct iommu_ops *ops;
-   u64 dma_base;
-   u64 size;
-};
-static LIST_HEAD(iommu_dma_masters);
-static DEFINE_MUTEX(iommu_dma_notifier_lock);
+static int __init __iommu_dma_init(void)
+{
+   return iommu_dma_init();
+}
+arch_initcall(__iommu_dma_init);
 
-static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-  u64 dma_base, u64 size)
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ const struct iommu_ops *ops)
 {
-   struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+   struct iommu_domain *domain;
+
+   if (!ops)
+   return;
 
/*
-* If the IOMMU driver has the DMA domain support that we require,
-* then the IOMMU core will have already configured a group for this
-* device, and allocated the default domain for that group.
+* The IOMMU core code allocates the default DMA domain, which the
+* underlying IOMMU driver needs to support via the dma-iommu layer.
 */
+   domain = iommu_get_domain_for_dev(dev);
+
if (!domain)
goto out_err;
 
@@ -851,109 +843,11 @@ static bool do_iommu_attach(struct device *dev, const 
struct iommu_ops *ops,
dev->dma_ops = &iommu_dma_ops;
}
 
-   return true;
+   return;
+
 out_err:
-   pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA 
ops\n",
+pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA 
ops\n",
 dev_name(dev));
-   return false;
-}
-
-static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
- u64 dma_base, u64 size)
-{
-   struct iommu_dma_notifier_data *iommudata;
-
-   iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
-   if (!iommudata)
-   return;
-
-   iommudata->dev = dev;
-   iommudata->ops = ops;
-   iommudata->dma_base = dma_base;
-   iommudata->size = size;
-
-   mutex_lock(&iommu_dma_notifier_lock);
-   list_add(&iommudata->list, &iommu_dma_masters);
-   mutex_unlock(&iommu_dma_notifier_lock);
-}
-
-static int __iommu_attach_notifier(struct notifier_block *nb,
-  unsigned long action, void *data)
-{
-   struct iommu_dma_notifier_data *master, *tmp;
-
-   if (action != BUS_NOTIFY_BIND_DRIVER)
-   return 0;
-
-   mutex_lock(&iommu_dma_notifier_lock);
-   list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
-   if (data == master->dev && do_iommu_attach(master->dev,
-   master->ops, master->dma_base, master->size)) {
-   list_del(&master->list);
-   kfree(master);
-   break;
-   }
-   }
-   mutex_unlock(&iommu_dma_notifier_lock);
-   return 0;
-}
-
-static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
-{
-   struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
-   int ret;
-
-   if (!nb)
-   return -ENOMEM;
-
-   nb->notifier_call = __iommu_attach_notifier;
-
-   ret = bus_register_notifier(bus, nb);
-   if (ret) {
-   pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops 
unavailable on bus '%s'\n",
-   bus->name);
-  

[PATCH V11 00/11] IOMMU probe deferral support

2017-04-10 Thread Sricharan R
nux/kernel/git/lpieralisi/linux.git 
iommu/probe-deferral
[6] http://www.spinics.net/lists/linux-pci/msg57992.html
[7] https://www.spinics.net/lists/arm-kernel/msg556209.html
[8] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/01557.html

Laurent Pinchart (2):
  of: dma: Make of_dma_deconfigure() public
  iommu: of: Handle IOMMU lookup failure with deferred probing or error

Lorenzo Pieralisi (2):
  ACPI/IORT: Add function to check SMMUs drivers presence
  ACPI/IORT: Remove linker section for IORT entries probing

Robin Murphy (3):
  iommu/of: Refactor of_iommu_configure() for error handling
  iommu/of: Prepare for deferred IOMMU configuration
  iommu/arm-smmu: Clean up early-probing workarounds

Sricharan R (4):
  of: device: Fix overflow of coherent_dma_mask
  of/acpi: Configure dma operations at probe time for platform/amba/pci
bus devices
  drivers: acpi: Handle IOMMU lookup failure with deferred probing or
error
  arm64: dma-mapping: Remove the notifier trick to handle early setting
of dma_ops

 arch/arm64/mm/dma-mapping.c   | 142 +-
 drivers/acpi/arm64/iort.c |  48 -
 drivers/acpi/glue.c   |   5 --
 drivers/acpi/scan.c   |  11 ++-
 drivers/base/dd.c |   9 +++
 drivers/base/dma-mapping.c|  41 +++
 drivers/iommu/arm-smmu-v3.c   |  46 +---
 drivers/iommu/arm-smmu.c  | 110 +
 drivers/iommu/of_iommu.c  | 126 -
 drivers/of/device.c   |  23 +-
 drivers/of/platform.c |  10 +--
 drivers/pci/probe.c   |  28 
 include/acpi/acpi_bus.h   |   2 +-
 include/asm-generic/vmlinux.lds.h |   1 -
 include/linux/acpi.h  |   7 +-
 include/linux/acpi_iort.h |   3 -
 include/linux/dma-mapping.h   |  12 
 include/linux/of_device.h |  10 ++-
 18 files changed, 312 insertions(+), 322 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V11 02/11] iommu/of: Prepare for deferred IOMMU configuration

2017-04-10 Thread Sricharan R
From: Robin Murphy 

IOMMU configuration represents unchanging properties of the hardware,
and as such should only need happen once in a device's lifetime, but
the necessary interaction with the IOMMU device and driver complicates
exactly when that point should be.

Since the only reasonable tool available for handling the inter-device
dependency is probe deferral, we need to prepare of_iommu_configure()
to run later than it is currently called (i.e. at driver probe rather
than device creation), to handle being retried, and to tell whether a
not-yet present IOMMU should be waited for or skipped (by virtue of
having declared a built-in driver or not).

Tested-by: Marek Szyprowski 
Signed-off-by: Robin Murphy 
---
 drivers/iommu/of_iommu.c | 43 ++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 8f4e599..c8be889 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,19 @@ int of_get_dma_window(struct device_node *dn, const char 
*prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static bool of_iommu_driver_present(struct device_node *np)
+{
+   /*
+* If the IOMMU still isn't ready by the time we reach init, assume
+* it never will be. We don't want to defer indefinitely, nor attempt
+* to dereference __iommu_of_table after it's been freed.
+*/
+   if (system_state > SYSTEM_BOOTING)
+   return false;
+
+   return of_match_node(&__iommu_of_table, np);
+}
+
 static const struct iommu_ops
 *of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
 {
@@ -104,12 +117,20 @@ int of_get_dma_window(struct device_node *dn, const char 
*prefix, int index,
int err;
 
ops = iommu_ops_from_fwnode(fwnode);
-   if (!ops || !ops->of_xlate)
+   if ((ops && !ops->of_xlate) ||
+   (!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;
 
err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
if (err)
return ERR_PTR(err);
+   /*
+* The otherwise-empty fwspec handily serves to indicate the specific
+* IOMMU device we're waiting for, which will be useful if we ever get
+* a proper probe-ordering dependency mechanism in future.
+*/
+   if (!ops)
+   return ERR_PTR(-EPROBE_DEFER);
 
err = ops->of_xlate(dev, iommu_spec);
if (err)
@@ -186,14 +207,34 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
   struct device_node *master_np)
 {
const struct iommu_ops *ops;
+   struct iommu_fwspec *fwspec = dev->iommu_fwspec;
 
if (!master_np)
return NULL;
 
+   if (fwspec) {
+   if (fwspec->ops)
+   return fwspec->ops;
+
+   /* In the deferred case, start again from scratch */
+   iommu_fwspec_free(dev);
+   }
+
if (dev_is_pci(dev))
ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
else
ops = of_platform_iommu_init(dev, master_np);
+   /*
+* If we have reason to believe the IOMMU driver missed the initial
+* add_device callback for dev, replay it to get things in order.
+*/
+   if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+   dev->bus && !dev->iommu_group) {
+   int err = ops->add_device(dev);
+
+   if (err)
+   ops = ERR_PTR(err);
+   }
 
return IS_ERR(ops) ? NULL : ops;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V11 03/11] of: dma: Make of_dma_deconfigure() public

2017-04-10 Thread Sricharan R
From: Laurent Pinchart 

As part of moving DMA initializing to probe time the
of_dma_deconfigure() function will need to be called from different
source files. Make it public and move it to drivers/of/device.c where
the of_dma_configure() function is.

Tested-by: Marek Szyprowski 
Reviewed-by: Robin Murphy 
Acked-by: Rob Herring 
Signed-off-by: Laurent Pinchart 
---
 drivers/of/device.c   | 12 
 drivers/of/platform.c |  5 -
 include/linux/of_device.h |  3 +++
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index b1e6beb..0d378c0 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -151,6 +151,18 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
+/**
+ * of_dma_deconfigure - Clean up DMA configuration
+ * @dev:   Device for which to clean up DMA configuration
+ *
+ * Clean up all configuration performed by of_dma_configure_ops() and free all
+ * resources that have been allocated.
+ */
+void of_dma_deconfigure(struct device *dev)
+{
+   arch_teardown_dma_ops(dev);
+}
+
 int of_device_register(struct platform_device *pdev)
 {
device_initialize(&pdev->dev);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5dfcc96..5344db5 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -158,11 +158,6 @@ struct platform_device *of_device_alloc(struct device_node 
*np,
 }
 EXPORT_SYMBOL(of_device_alloc);
 
-static void of_dma_deconfigure(struct device *dev)
-{
-   arch_teardown_dma_ops(dev);
-}
-
 /**
  * of_platform_device_create_pdata - Alloc, initialize and register an 
of_device
  * @np: pointer to node to create device for
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index c12dace..af98455 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -56,6 +56,7 @@ static inline struct device_node *of_cpu_device_node_get(int 
cpu)
 }
 
 void of_dma_configure(struct device *dev, struct device_node *np);
+void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
 static inline int of_driver_match_device(struct device *dev,
@@ -105,6 +106,8 @@ static inline struct device_node 
*of_cpu_device_node_get(int cpu)
 }
 static inline void of_dma_configure(struct device *dev, struct device_node *np)
 {}
+static inline void of_dma_deconfigure(struct device *dev)
+{}
 #endif /* CONFIG_OF */
 
 #endif /* _LINUX_OF_DEVICE_H */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V11 01/11] iommu/of: Refactor of_iommu_configure() for error handling

2017-04-10 Thread Sricharan R
From: Robin Murphy 

In preparation for some upcoming cleverness, rework the control flow in
of_iommu_configure() to minimise duplication and improve the propogation
of errors. It's also as good a time as any to switch over from the
now-just-a-compatibility-wrapper of_iommu_get_ops() to using the generic
IOMMU instance interface directly.

Tested-by: Marek Szyprowski 
Signed-off-by: Robin Murphy 
---
 drivers/iommu/of_iommu.c | 83 +++-
 1 file changed, 53 insertions(+), 30 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 2683e9f..8f4e599 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,28 @@ int of_get_dma_window(struct device_node *dn, const char 
*prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static const struct iommu_ops
+*of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
+{
+   const struct iommu_ops *ops;
+   struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
+   int err;
+
+   ops = iommu_ops_from_fwnode(fwnode);
+   if (!ops || !ops->of_xlate)
+   return NULL;
+
+   err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
+   if (err)
+   return ERR_PTR(err);
+
+   err = ops->of_xlate(dev, iommu_spec);
+   if (err)
+   return ERR_PTR(err);
+
+   return ops;
+}
+
 static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 {
struct of_phandle_args *iommu_spec = data;
@@ -105,10 +127,11 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, 
void *data)
 }
 
 static const struct iommu_ops
-*of_pci_iommu_configure(struct pci_dev *pdev, struct device_node *bridge_np)
+*of_pci_iommu_init(struct pci_dev *pdev, struct device_node *bridge_np)
 {
const struct iommu_ops *ops;
struct of_phandle_args iommu_spec;
+   int err;
 
/*
 * Start by tracing the RID alias down the PCI topology as
@@ -123,56 +146,56 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, 
void *data)
 * bus into the system beyond, and which IOMMU it ends up at.
 */
iommu_spec.np = NULL;
-   if (of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
-  "iommu-map-mask", &iommu_spec.np, iommu_spec.args))
-   return NULL;
+   err = of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
+"iommu-map-mask", &iommu_spec.np,
+iommu_spec.args);
+   if (err)
+   return err == -ENODEV ? NULL : ERR_PTR(err);
 
-   ops = iommu_ops_from_fwnode(&iommu_spec.np->fwnode);
-   if (!ops || !ops->of_xlate ||
-   iommu_fwspec_init(&pdev->dev, &iommu_spec.np->fwnode, ops) ||
-   ops->of_xlate(&pdev->dev, &iommu_spec))
-   ops = NULL;
+   ops = of_iommu_xlate(&pdev->dev, &iommu_spec);
 
of_node_put(iommu_spec.np);
return ops;
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-  struct device_node *master_np)
+static const struct iommu_ops
+*of_platform_iommu_init(struct device *dev, struct device_node *np)
 {
struct of_phandle_args iommu_spec;
-   struct device_node *np;
const struct iommu_ops *ops = NULL;
int idx = 0;
 
-   if (dev_is_pci(dev))
-   return of_pci_iommu_configure(to_pci_dev(dev), master_np);
-
/*
 * We don't currently walk up the tree looking for a parent IOMMU.
 * See the `Notes:' section of
 * Documentation/devicetree/bindings/iommu/iommu.txt
 */
-   while (!of_parse_phandle_with_args(master_np, "iommus",
-  "#iommu-cells", idx,
-  &iommu_spec)) {
-   np = iommu_spec.np;
-   ops = iommu_ops_from_fwnode(&np->fwnode);
-
-   if (!ops || !ops->of_xlate ||
-   iommu_fwspec_init(dev, &np->fwnode, ops) ||
-   ops->of_xlate(dev, &iommu_spec))
-   goto err_put_node;
-
-   of_node_put(np);
+   while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells",
+  idx, &iommu_spec)) {
+   ops = of_iommu_xlate(dev, &iommu_spec);
+   of_node_put(iommu_spec.np);
idx++;
+   if (IS_ERR_OR_NULL(ops))
+   break;
}
 
return ops;
+}
+
+const struct iommu_ops *of_iommu_configure(struct device *dev,
+  struct device_node *master_np)
+{
+   const struct iommu_ops *ops;
+
+   if (!master_np)
+   return NULL;
+
+   if (dev_is_pci(dev))
+   ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
+   else
+   ops = of_platform_iommu_init(d

Re: [PATCH V3 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2017-04-09 Thread Sricharan R

Hi Jordon,

On 4/7/2017 11:31 PM, Jordan Crouse wrote:

On Tue, Apr 04, 2017 at 12:39:14PM -0700, Stephen Boyd wrote:

On 04/03, Will Deacon wrote:

On Fri, Mar 31, 2017 at 10:58:16PM -0400, Rob Clark wrote:

On Fri, Mar 31, 2017 at 1:54 PM, Will Deacon  wrote:

On Thu, Mar 09, 2017 at 09:05:43PM +0530, Sricharan R wrote:

This series provides the support for turning on the arm-smmu's
clocks/power domains using runtime pm. This is done using the
recently introduced device links patches, which lets the symmu's
runtime to follow the master's runtime pm, so the smmu remains
powered only when the masters use it.


Do you have any numbers for the power savings you achieve with this?
How often do we actually manage to stop the SMMU clocks on an SoC with
a handful of masters?

In other words, is this too coarse-grained to be useful, or is it common
that all the devices upstream of the SMMU are suspended?


well, if you think about a phone/tablet with a command mode panel,
pretty much all devices will be suspended most of the time ;-)


Well, that's really what I was asking about. I assumed that periodic
modem/radio transactions would keep the SMMU clocked, so would like to get a
rough idea of the power savings achieved with this coarse-grained approach.


Sometimes we distribute SMMUs to each IP block in the system and
let each one of those live in their own clock + power domain. In
these cases, the SMMU can be powered down along with the only IP
block that uses it. Furthermore, sometimes we put the IP block
and the SMMU inside the same power domain to really tie the two
together, so we definitely have cases where all devices (device?)
upstream of the SMMU are suspended. And in the case of
multimedia, it could be very often that something like the camera
app isn't open and thus the SMMU dedicated for the camera can be
powered down.

Other times we have two SMMUs in the system where one is
dedicated to GPU and the other is "everything else". Even in
these cases, we can suspend the GPU one when the GPU is inactive
because it's the only consumer. The other SMMU might not be as
fine grained, but I think we still power it down quite often
because the consumers are mostly multimedia devices that aren't
active when the display is off.


And just to confuse things even further: with per-instance pagetables we have an
interest in forcing the SMMU clocks *on* because we don't know when the GPU
might try to hit the registers to switch a pagetable and if somebody in the
pipeline is actively trying to do power management at the same time hilarity
will ensue.



Ok, with per-process pagetables which gpu handles by itself, is the gpu driver
not going to keep its own clocks pm_runtime active before handing it over
to the firmware ? which would in this case take care of having the iommu clocks
also enabled because of the device links in the behind.


The alternative to pm_runtime is the downstream driver that probes the SMMU
clocks from DT and frobs them itself. I think we can agree that is far less
reasonable.


The idea here was to keep the iommu clocks only represented inside the IOMMU DT
and handled by that driver. This works fine with the video decoder which is
already fully pm_runtime enabled and works fine with basic gpu testing. Do you
see any issues in testing this with the per-process pagetables ?

Regards,
 Sricharan

--
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V10 06/12] of: device: Fix overflow of coherent_dma_mask

2017-04-06 Thread Sricharan R

Hi Frank,

On 4/7/2017 1:04 AM, Frank Rowand wrote:

On 04/06/17 04:01, Sricharan R wrote:

Hi Frank,

On 4/6/2017 12:31 PM, Frank Rowand wrote:

On 04/04/17 03:18, Sricharan R wrote:

Size of the dma-range is calculated as coherent_dma_mask + 1
and passed to arch_setup_dma_ops further. It overflows when
the coherent_dma_mask is set for full 64 bits 0x,
resulting in size getting passed as 0 wrongly. Fix this by
passsing in max(mask, mask + 1). Note that in this case
when the mask is set to full 64bits, we will be passing the mask
itself to arch_setup_dma_ops instead of the size. The real fix
for this should be to make arch_setup_dma_ops receive the
mask and handle it, to be done in the future.

Signed-off-by: Sricharan R 
---
 drivers/of/device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index c17c19d..c2ae6bb 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -107,7 +107,7 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
 ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
 if (ret < 0) {
 dma_addr = offset = 0;
-size = dev->coherent_dma_mask + 1;
+size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
 } else {
 offset = PFN_DOWN(paddr - dma_addr);
 dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);



NACK.

Passing an invalid size to arch_setup_dma_ops() is only part of the problem.
size is also used in of_dma_configure() before calling arch_setup_dma_ops():

dev->coherent_dma_mask = min(dev->coherent_dma_mask,
 DMA_BIT_MASK(ilog2(dma_addr + size)));
*dev->dma_mask = min((*dev->dma_mask),
 DMA_BIT_MASK(ilog2(dma_addr + size)));

which would be incorrect for size == 0xULL when
dma_addr != 0.  So the proposed fix really is not papering over
the base problem very well.



Ok, but with your fix for of_dma_get_range and the above fix,
dma_addr will be '0' when size = 0xULL,
but DMA_BIT_MASK(ilog2(dma_addr + size)) would be wrong though,
making coherent_dma_mask to be smaller 0x7fffULL.


Yes, that was my point.  Setting size to 0x7fffULL
affects several places.  Another potential location (based only
on the function header comment, not from reading the code) is
iommu_dma_init_domain().  The header comment says:

* @base and @size should be exact multiples of IOMMU page granularity to
* avoid rounding surprises.



ok, this is the same problem that should get solved when arch_setup_dma_ops
is prepared to take mask instead of size. It would still work as said above
with a smaller mask than specified.


I have not read enough context to really understand of_dma_configure(), but
it seems there is yet another issue in how the error return case from
of_dma_get_range() is handled (with the existing code, as well as if
my patch gets accepted).  An error return value can mean _either_
there is no dma-ranges property _or_ "an other problem occurred".  Should
the "an other problem occurred" case be handled by defaulting size to
a value based on dev->coherent_dma_mask (the current case) or should the
attempt to set up the DMA configuration just fail?


The handling of return error value looks like separate item, but looks
like its correct with what is there now. (ie) when of_dma_get_range fails
either because 'dma-ranges property' populated in DT (or) because of some
erroneous DT setting, better to set the mask which the driver has specified
and ignore DT. So the above patch just corrects a mistake in that path.

Regards,
 Sricharan

--
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V10 06/12] of: device: Fix overflow of coherent_dma_mask

2017-04-06 Thread Sricharan R

Hi Frank,

On 4/6/2017 12:31 PM, Frank Rowand wrote:

On 04/04/17 03:18, Sricharan R wrote:

Size of the dma-range is calculated as coherent_dma_mask + 1
and passed to arch_setup_dma_ops further. It overflows when
the coherent_dma_mask is set for full 64 bits 0x,
resulting in size getting passed as 0 wrongly. Fix this by
passsing in max(mask, mask + 1). Note that in this case
when the mask is set to full 64bits, we will be passing the mask
itself to arch_setup_dma_ops instead of the size. The real fix
for this should be to make arch_setup_dma_ops receive the
mask and handle it, to be done in the future.

Signed-off-by: Sricharan R 
---
 drivers/of/device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index c17c19d..c2ae6bb 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -107,7 +107,7 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
-   size = dev->coherent_dma_mask + 1;
+   size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
} else {
offset = PFN_DOWN(paddr - dma_addr);
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);



NACK.

Passing an invalid size to arch_setup_dma_ops() is only part of the problem.
size is also used in of_dma_configure() before calling arch_setup_dma_ops():

dev->coherent_dma_mask = min(dev->coherent_dma_mask,
 DMA_BIT_MASK(ilog2(dma_addr + size)));
*dev->dma_mask = min((*dev->dma_mask),
 DMA_BIT_MASK(ilog2(dma_addr + size)));

which would be incorrect for size == 0xULL when
dma_addr != 0.  So the proposed fix really is not papering over
the base problem very well.



Ok, but with your fix for of_dma_get_range and the above fix,
dma_addr will be '0' when size = 0xULL,
but DMA_BIT_MASK(ilog2(dma_addr + size)) would be wrong though,
making coherent_dma_mask to be smaller 0x7fffULL.

Regards,
 Sricharan


I agree that the proper solution involves passing a mask instead
of a size to arch_setup_dma_ops().



--
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V10 03/12] of: dma: Move range size workaround to of_dma_get_range()

2017-04-06 Thread Sricharan R

Hi Frank,

On 4/6/2017 11:54 AM, Frank Rowand wrote:

On 04/04/17 03:18, Sricharan R wrote:

From: Laurent Pinchart 

Invalid dma-ranges values should be worked around when retrieving the
DMA range in of_dma_get_range(), not by all callers of the function.
This isn't much of a problem now that we have a single caller, but that
situation will change when moving DMA configuration to device probe
time.


Please drop this patch from the series.  I just now sent Rob an
alternative that reflects other changes that have occurred since
this patch series was first created many, many moons ago
(https://lkml.org/lkml/2017/4/6/53).


ok, would drop this.

Regards,
 Sricharan

--
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V10 07/12] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices

2017-04-04 Thread Sricharan R

Hi Robin,

On 4/4/2017 5:47 PM, Robin Murphy wrote:

On 04/04/17 11:18, Sricharan R wrote:

Configuring DMA ops at probe time will allow deferring device probe when
the IOMMU isn't available yet. The dma_configure for the device is
now called from the generic device_attach callback just before the
bus/driver probe is called. This way, configuring the DMA ops for the
device would be called at the same place for all bus_types, hence the
deferred probing mechanism should work for all buses as well.

pci_bus_add_devices(platform/amba)(_device_create/driver_register)
   | |
pci_bus_add_device (device_add/driver_register)
   | |
device_attach   device_initial_probe
   | |
__device_attach_driver__device_attach_driver
   |
driver_probe_device
   |
really_probe
   |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

This patch changes the dma ops configuration to probe time for
both OF and ACPI based platform/amba/pci bus devices.


Reviewed-by: Robin Murphy 

It's possible we could subsume {of,acpi}_dma_deconfigure() into
dma_deconfigure() entirely in future if it becomes clear that neither of
them will ever need to do anything firmware-specific, but I think for
now it's probably safer to keep the current symmetry - calling
arch_teardown_dma_ops() twice is benign (and even if it weren't, I'd say
it really should be!)



Ya, calling it twice should cause no harm. If nothing firmware specific
gets added this could simply be put in deconfigure itself in future.
Thanks for all the reviews !!

Regards,
 Sricharan




Robin.


Tested-by: Marek Szyprowski 
Tested-by: Hanjun Guo 
Acked-by: Bjorn Helgaas  (drivers/pci part)
Acked-by: Rafael J. Wysocki 
Signed-off-by: Sricharan R 
---

 [V10] Added dummy dma_(de)configure functions in case
   of !CONFIG_HAS_DMA to avoid build breaks.

 drivers/acpi/glue.c |  5 -
 drivers/base/dd.c   |  9 +
 drivers/base/dma-mapping.c  | 40 
 drivers/of/platform.c   |  5 +
 drivers/pci/probe.c | 28 
 include/linux/dma-mapping.h | 12 
 6 files changed, 62 insertions(+), 37 deletions(-)

diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index fb19e1c..c05f241 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -176,7 +176,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
struct list_head *physnode_list;
unsigned int node_id;
int retval = -EINVAL;
-   enum dev_dma_attr attr;

if (has_acpi_companion(dev)) {
if (acpi_dev) {
@@ -233,10 +232,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
if (!has_acpi_companion(dev))
ACPI_COMPANION_SET(dev, acpi_dev);

-   attr = acpi_get_dma_attr(acpi_dev);
-   if (attr != DEV_DMA_NOT_SUPPORTED)
-   acpi_dma_configure(dev, attr);
-
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
   physical_node_name);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a1fbf55..4882f06 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -19,6 +19,7 @@

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -356,6 +357,10 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
if (ret)
goto pinctrl_bind_failed;

+   ret = dma_configure(dev);
+   if (ret)
+   goto dma_failed;
+
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev_name(dev));
@@ -417,6 +422,8 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
goto done;

 probe_failed:
+   dma_deconfigure(dev);
+dma_failed:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
@@ -826,6 +833,8 @@ static void __device_release_driver(struct device *dev, 
struct device *parent)
drv->remove(dev);

device_links_driver_cleanup(dev);
+   dma_deconfigure(dev);
+
devres_release_all(dev);
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index efd71cf..449b948 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -7,9 +7,11 @@
  * This file is released under the GPLv2.
  */

+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 

@@ -

[PATCH V10 11/12] iommu/arm-smmu: Clean up early-probing workarounds

2017-04-04 Thread Sricharan R
From: Robin Murphy 

Now that the appropriate ordering is enforced via probe-deferral of
masters in core code, rip it all out and bask in the simplicity.

Tested-by: Hanjun Guo 
Acked-by: Will Deacon 
Signed-off-by: Robin Murphy 
[Sricharan: Rebased on top of ACPI IORT SMMU series]
Signed-off-by: Sricharan R 
---
 drivers/iommu/arm-smmu-v3.c |  46 +-
 drivers/iommu/arm-smmu.c| 110 +++-
 2 files changed, 49 insertions(+), 107 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 591bb96..4362139 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2761,51 +2761,9 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
.probe  = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
 };
+module_platform_driver(arm_smmu_driver);
 
-static int __init arm_smmu_init(void)
-{
-   static bool registered;
-   int ret = 0;
-
-   if (!registered) {
-   ret = platform_driver_register(&arm_smmu_driver);
-   registered = !ret;
-   }
-   return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
-   return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
-   int ret = arm_smmu_init();
-
-   if (ret)
-   return ret;
-
-   if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
-   return -ENODEV;
-
-   return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init acpi_smmu_v3_init(struct acpi_table_header *table)
-{
-   if (iort_node_match(ACPI_IORT_NODE_SMMU_V3))
-   return arm_smmu_init();
-
-   return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu_v3, ACPI_SIG_IORT, acpi_smmu_v3_init);
-#endif
+IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
 MODULE_AUTHOR("Will Deacon ");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index b493c99..792fe7d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2075,6 +2075,23 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
return 0;
 }
 
+static void arm_smmu_bus_init(void)
+{
+   /* Oh, for a proper bus abstraction */
+   if (!iommu_present(&platform_bus_type))
+   bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+#ifdef CONFIG_ARM_AMBA
+   if (!iommu_present(&amba_bustype))
+   bus_set_iommu(&amba_bustype, &arm_smmu_ops);
+#endif
+#ifdef CONFIG_PCI
+   if (!iommu_present(&pci_bus_type)) {
+   pci_request_acs();
+   bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
+   }
+#endif
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
struct resource *res;
@@ -2180,21 +2197,30 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
arm_smmu_device_reset(smmu);
arm_smmu_test_smr_masks(smmu);
 
-   /* Oh, for a proper bus abstraction */
-   if (!iommu_present(&platform_bus_type))
-   bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
-#ifdef CONFIG_ARM_AMBA
-   if (!iommu_present(&amba_bustype))
-   bus_set_iommu(&amba_bustype, &arm_smmu_ops);
-#endif
-#ifdef CONFIG_PCI
-   if (!iommu_present(&pci_bus_type)) {
-   pci_request_acs();
-   bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
-   }
-#endif
+   /*
+* For ACPI and generic DT bindings, an SMMU will be probed before
+* any device which might need it, so we want the bus ops in place
+* ready to handle default domain setup as soon as any SMMU exists.
+*/
+   if (!using_legacy_binding)
+   arm_smmu_bus_init();
+
+   return 0;
+}
+
+/*
+ * With the legacy DT binding in play, though, we have no guarantees about
+ * probe order, but then we're also not doing default domains, so we can
+ * delay setting bus ops until we're sure every possible SMMU is ready,
+ * and that way ensure that no add_device() calls get missed.
+ */
+static int arm_smmu_legacy_bus_init(void)
+{
+   if (using_legacy_binding)
+   arm_smmu_bus_init();
return 0;
 }
+device_initcall_sync(arm_smmu_legacy_bus_init);
 
 static int arm_smmu_device_remove(struct platform_device *pdev)
 {
@@ -2219,56 +2245,14 @@ static int arm_smmu_device_remove(struct 
platform_device *pdev)
.probe  = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
 };
-
-static int __init arm_smmu_init(void)
-{
-   static bool registered;
-   int ret = 0;
-
-   if (!registered) {
-   re

[PATCH V10 12/12] ACPI/IORT: Remove linker section for IORT entries probing

2017-04-04 Thread Sricharan R
From: Lorenzo Pieralisi 

The IORT linker section introduced by commit 34ceea275f62
("ACPI/IORT: Introduce linker section for IORT entries probing")
was needed to make sure SMMU drivers are registered (and therefore
probed) in the kernel before devices using the SMMU have a chance
to probe in turn.

Through the introduction of deferred IOMMU configuration the linker
section based IORT probing infrastructure is not needed any longer, in
that device/SMMU probe dependencies are managed through the probe
deferral mechanism, making the IORT linker section infrastructure
unused, so that it can be removed.

Remove the unused IORT linker section probing infrastructure
from the kernel to complete the ACPI IORT IOMMU configure probe
deferral mechanism implementation.

Tested-by: Hanjun Guo 
Signed-off-by: Lorenzo Pieralisi 
Cc: Robin Murphy 
Cc: Sricharan R 
---
 drivers/acpi/arm64/iort.c | 2 --
 include/asm-generic/vmlinux.lds.h | 1 -
 include/linux/acpi_iort.h | 3 ---
 3 files changed, 6 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index e323ece..e7b1940 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1000,6 +1000,4 @@ void __init acpi_iort_init(void)
}
 
iort_init_platform_devices();
-
-   acpi_probe_device_table(iort);
 }
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 0968d13..9faa26c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -566,7 +566,6 @@
IRQCHIP_OF_MATCH_TABLE()\
ACPI_PROBE_TABLE(irqchip)   \
ACPI_PROBE_TABLE(clksrc)\
-   ACPI_PROBE_TABLE(iort)  \
EARLYCON_TABLE()
 
 #define INIT_TEXT  \
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 77e0809..f167e1d04 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -52,7 +52,4 @@ const struct iommu_ops *iort_iommu_configure(struct device 
*dev)
 { return NULL; }
 #endif
 
-#define IORT_ACPI_DECLARE(name, table_id, fn)  \
-   ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn)
-
 #endif /* __ACPI_IORT_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V10 09/12] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error

2017-04-04 Thread Sricharan R
This is an equivalent to the DT's handling of the iommu master's probe
with deferred probing when the corrsponding iommu is not probed yet.
The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the firmware describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Hanjun Guo 
[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
  called multiple times for same device]
Signed-off-by: Lorenzo Pieralisi 
Signed-off-by: Sricharan R 
---

 [V10] Added Lorenzo's ACPI fix for coherent_dma_mask overflow
   and the fix for dma_configure getting called more than
   once for the same device.

 drivers/acpi/arm64/iort.c  | 33 -
 drivers/acpi/scan.c| 11 ---
 drivers/base/dma-mapping.c |  2 +-
 include/acpi/acpi_bus.h|  2 +-
 include/linux/acpi.h   |  7 +--
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 3dd9ec3..e323ece 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
device *dev,
const struct iommu_ops *ops = NULL;
int ret = -ENODEV;
struct fwnode_handle *iort_fwnode;
+   struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+
+   /*
+* If we already translated the fwspec there
+* is nothing left to do, return the iommu_ops.
+*/
+   if (fwspec && fwspec->ops)
+   return fwspec->ops;
 
if (node) {
iort_fwnode = iort_get_fwnode(node);
@@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct 
device *dev,
return NULL;
 
ops = iommu_ops_from_fwnode(iort_fwnode);
+   /*
+* If the ops look-up fails, this means that either
+* the SMMU drivers have not been probed yet or that
+* the SMMU drivers are not built in the kernel;
+* Depending on whether the SMMU drivers are built-in
+* in the kernel or not, defer the IOMMU configuration
+* or just abort it.
+*/
if (!ops)
-   return NULL;
+   return iort_iommu_driver_enabled(node->type) ?
+  ERR_PTR(-EPROBE_DEFER) : NULL;
 
ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
}
@@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct 
device *dev)
 
while (parent) {
ops = iort_iommu_xlate(dev, parent, streamid);
+   if (IS_ERR_OR_NULL(ops))
+   return ops;
 
parent = iort_node_get_id(node, &streamid,
  IORT_IOMMU_TYPE, i++);
}
}
 
+   /*
+* If we have reason to believe the IOMMU driver missed the initial
+* add_device callback for dev, replay it to get things in order.
+*/
+   if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+   dev->bus && !dev->iommu_group) {
+   int err = ops->add_device(dev);
+
+   if (err)
+   ops = ERR_PTR(err);
+   }
+
return ops;
 }
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1926918..2a513cc 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device 
*adev)
  * @dev: The pointer to the device
  * @attr: device dma attributes
  */
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 {
const struct iommu_ops *iommu;
+   u64 size;
 
iort_set_dma_mask(dev);
 
iommu = iort_iommu_configure(dev);
+   if (IS_ERR(iommu))
+   return PTR_ERR(iommu);
 
+   size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
/*
 * Assume dma valid range starts at 0 and covers the 

[PATCH V10 10/12] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops

2017-04-04 Thread Sricharan R
With arch_setup_dma_ops now being called late during device's probe after
the device's iommu is probed, the notifier trick required to handle the
early setup of dma_ops before the iommu group gets created is not
required. So removing the notifier's here.

Tested-by: Marek Szyprowski 
Tested-by: Hanjun Guo 
Acked-by: Will Deacon 
Signed-off-by: Sricharan R 
[rm: clean up even more]
Signed-off-by: Robin Murphy 
---
 arch/arm64/mm/dma-mapping.c | 142 ++--
 1 file changed, 18 insertions(+), 124 deletions(-)

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 81cdb2e..b465759 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -813,34 +813,26 @@ static void __iommu_unmap_sg_attrs(struct device *dev,
.mapping_error = iommu_dma_mapping_error,
 };
 
-/*
- * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
- * everything it needs to - the device is only partially created and the
- * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
- * need this delayed attachment dance. Once IOMMU probe ordering is sorted
- * to move the arch_setup_dma_ops() call later, all the notifier bits below
- * become unnecessary, and will go away.
- */
-struct iommu_dma_notifier_data {
-   struct list_head list;
-   struct device *dev;
-   const struct iommu_ops *ops;
-   u64 dma_base;
-   u64 size;
-};
-static LIST_HEAD(iommu_dma_masters);
-static DEFINE_MUTEX(iommu_dma_notifier_lock);
+static int __init __iommu_dma_init(void)
+{
+   return iommu_dma_init();
+}
+arch_initcall(__iommu_dma_init);
 
-static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-  u64 dma_base, u64 size)
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ const struct iommu_ops *ops)
 {
-   struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+   struct iommu_domain *domain;
+
+   if (!ops)
+   return;
 
/*
-* If the IOMMU driver has the DMA domain support that we require,
-* then the IOMMU core will have already configured a group for this
-* device, and allocated the default domain for that group.
+* The IOMMU core code allocates the default DMA domain, which the
+* underlying IOMMU driver needs to support via the dma-iommu layer.
 */
+   domain = iommu_get_domain_for_dev(dev);
+
if (!domain)
goto out_err;
 
@@ -851,109 +843,11 @@ static bool do_iommu_attach(struct device *dev, const 
struct iommu_ops *ops,
dev->dma_ops = &iommu_dma_ops;
}
 
-   return true;
+   return;
+
 out_err:
-   pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA 
ops\n",
+pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA 
ops\n",
 dev_name(dev));
-   return false;
-}
-
-static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
- u64 dma_base, u64 size)
-{
-   struct iommu_dma_notifier_data *iommudata;
-
-   iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
-   if (!iommudata)
-   return;
-
-   iommudata->dev = dev;
-   iommudata->ops = ops;
-   iommudata->dma_base = dma_base;
-   iommudata->size = size;
-
-   mutex_lock(&iommu_dma_notifier_lock);
-   list_add(&iommudata->list, &iommu_dma_masters);
-   mutex_unlock(&iommu_dma_notifier_lock);
-}
-
-static int __iommu_attach_notifier(struct notifier_block *nb,
-  unsigned long action, void *data)
-{
-   struct iommu_dma_notifier_data *master, *tmp;
-
-   if (action != BUS_NOTIFY_BIND_DRIVER)
-   return 0;
-
-   mutex_lock(&iommu_dma_notifier_lock);
-   list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
-   if (data == master->dev && do_iommu_attach(master->dev,
-   master->ops, master->dma_base, master->size)) {
-   list_del(&master->list);
-   kfree(master);
-   break;
-   }
-   }
-   mutex_unlock(&iommu_dma_notifier_lock);
-   return 0;
-}
-
-static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
-{
-   struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
-   int ret;
-
-   if (!nb)
-   return -ENOMEM;
-
-   nb->notifier_call = __iommu_attach_notifier;
-
-   ret = bus_register_notifier(bus, nb);
-   if (ret) {
-   pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops 
unavailable on bus '%s'\n",
-   bus->name);
-  

[PATCH V10 08/12] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-04-04 Thread Sricharan R
From: Laurent Pinchart 

Failures to look up an IOMMU when parsing the DT iommus property need to
be handled separately from the .of_xlate() failures to support deferred
probing.

The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the device tree describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Marek Szyprowski 
Signed-off-by: Laurent Pichart 
Signed-off-by: Sricharan R 
---
 drivers/base/dma-mapping.c | 5 +++--
 drivers/iommu/of_iommu.c   | 4 ++--
 drivers/of/device.c| 7 ++-
 include/linux/of_device.h  | 9 ++---
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 449b948..82bd45c 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -353,6 +353,7 @@ int dma_configure(struct device *dev)
 {
struct device *bridge = NULL, *dma_dev = dev;
enum dev_dma_attr attr;
+   int ret = 0;
 
if (dev_is_pci(dev)) {
bridge = pci_get_host_bridge_device(to_pci_dev(dev));
@@ -363,7 +364,7 @@ int dma_configure(struct device *dev)
}
 
if (dma_dev->of_node) {
-   of_dma_configure(dev, dma_dev->of_node);
+   ret = of_dma_configure(dev, dma_dev->of_node);
} else if (has_acpi_companion(dma_dev)) {
attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
if (attr != DEV_DMA_NOT_SUPPORTED)
@@ -373,7 +374,7 @@ int dma_configure(struct device *dev)
if (bridge)
pci_put_host_bridge_device(bridge);
 
-   return 0;
+   return ret;
 }
 
 void dma_deconfigure(struct device *dev)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index c8be889..9f44ee8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -236,7 +236,7 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
ops = ERR_PTR(err);
}
 
-   return IS_ERR(ops) ? NULL : ops;
+   return ops;
 }
 
 static int __init of_iommu_init(void)
@@ -247,7 +247,7 @@ static int __init of_iommu_init(void)
for_each_matching_node_and_match(np, matches, &match) {
const of_iommu_init_fn init_fn = match->data;
 
-   if (init_fn(np))
+   if (init_fn && init_fn(np))
pr_err("Failed to initialise IOMMU %s\n",
of_node_full_name(np));
}
diff --git a/drivers/of/device.c b/drivers/of/device.c
index c2ae6bb..bea8aec 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -82,7 +82,7 @@ int of_device_add(struct platform_device *ofdev)
  * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
  * to fix up DMA configuration.
  */
-void of_dma_configure(struct device *dev, struct device_node *np)
+int of_dma_configure(struct device *dev, struct device_node *np)
 {
u64 dma_addr, paddr, size;
int ret;
@@ -129,10 +129,15 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
coherent ? " " : " not ");
 
iommu = of_iommu_configure(dev, np);
+   if (IS_ERR(iommu))
+   return PTR_ERR(iommu);
+
dev_dbg(dev, "device is%sbehind an iommu\n",
iommu ? " " : " not ");
 
arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
+
+   return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index af98455..2cacdd8 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -55,7 +55,7 @@ static inline struct device_node *of_cpu_device_node_get(int 
cpu)
return of_node_get(cpu_dev->of_node);
 }
 
-void of_dma_configure(struct device *dev, struct device_node *np);
+int of_dma_configure(struct device *dev, struct device_node *np);
 void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
@@ -104,8 +104,11 @@ static inline struct device_node 
*of_cpu_device_node_get(int cpu)
 {
return NULL;
 }
-static inline void of_dma_configure(struct device *dev, struct device_node *np)
-{}
+
+static inline int of

[PATCH V10 02/12] iommu/of: Prepare for deferred IOMMU configuration

2017-04-04 Thread Sricharan R
From: Robin Murphy 

IOMMU configuration represents unchanging properties of the hardware,
and as such should only need happen once in a device's lifetime, but
the necessary interaction with the IOMMU device and driver complicates
exactly when that point should be.

Since the only reasonable tool available for handling the inter-device
dependency is probe deferral, we need to prepare of_iommu_configure()
to run later than it is currently called (i.e. at driver probe rather
than device creation), to handle being retried, and to tell whether a
not-yet present IOMMU should be waited for or skipped (by virtue of
having declared a built-in driver or not).

Tested-by: Marek Szyprowski 
Signed-off-by: Robin Murphy 
---
 drivers/iommu/of_iommu.c | 43 ++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 8f4e599..c8be889 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,19 @@ int of_get_dma_window(struct device_node *dn, const char 
*prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static bool of_iommu_driver_present(struct device_node *np)
+{
+   /*
+* If the IOMMU still isn't ready by the time we reach init, assume
+* it never will be. We don't want to defer indefinitely, nor attempt
+* to dereference __iommu_of_table after it's been freed.
+*/
+   if (system_state > SYSTEM_BOOTING)
+   return false;
+
+   return of_match_node(&__iommu_of_table, np);
+}
+
 static const struct iommu_ops
 *of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
 {
@@ -104,12 +117,20 @@ int of_get_dma_window(struct device_node *dn, const char 
*prefix, int index,
int err;
 
ops = iommu_ops_from_fwnode(fwnode);
-   if (!ops || !ops->of_xlate)
+   if ((ops && !ops->of_xlate) ||
+   (!ops && !of_iommu_driver_present(iommu_spec->np)))
return NULL;
 
err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
if (err)
return ERR_PTR(err);
+   /*
+* The otherwise-empty fwspec handily serves to indicate the specific
+* IOMMU device we're waiting for, which will be useful if we ever get
+* a proper probe-ordering dependency mechanism in future.
+*/
+   if (!ops)
+   return ERR_PTR(-EPROBE_DEFER);
 
err = ops->of_xlate(dev, iommu_spec);
if (err)
@@ -186,14 +207,34 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
   struct device_node *master_np)
 {
const struct iommu_ops *ops;
+   struct iommu_fwspec *fwspec = dev->iommu_fwspec;
 
if (!master_np)
return NULL;
 
+   if (fwspec) {
+   if (fwspec->ops)
+   return fwspec->ops;
+
+   /* In the deferred case, start again from scratch */
+   iommu_fwspec_free(dev);
+   }
+
if (dev_is_pci(dev))
ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
else
ops = of_platform_iommu_init(dev, master_np);
+   /*
+* If we have reason to believe the IOMMU driver missed the initial
+* add_device callback for dev, replay it to get things in order.
+*/
+   if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+   dev->bus && !dev->iommu_group) {
+   int err = ops->add_device(dev);
+
+   if (err)
+   ops = ERR_PTR(err);
+   }
 
return IS_ERR(ops) ? NULL : ops;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V10 05/12] ACPI/IORT: Add function to check SMMUs drivers presence

2017-04-04 Thread Sricharan R
From: Lorenzo Pieralisi 

The IOMMU probe deferral implementation requires a mechanism to detect
if drivers for SMMU components are built-in in the kernel to detect
whether IOMMU configuration for a given device should be deferred (ie
SMMU drivers present but still not probed) or not (drivers not present).

Add a simple function to IORT to detect if SMMU drivers for SMMU
components managed by IORT are built-in in the kernel.

Tested-by: Hanjun Guo 
Signed-off-by: Lorenzo Pieralisi 
Cc: Robin Murphy 
Cc: Sricharan R 
---
 drivers/acpi/arm64/iort.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 4a5bb96..3dd9ec3 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -523,6 +523,19 @@ static int arm_smmu_iort_xlate(struct device *dev, u32 
streamid,
return ret;
 }
 
+static inline bool iort_iommu_driver_enabled(u8 type)
+{
+   switch (type) {
+   case ACPI_IORT_NODE_SMMU_V3:
+   return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
+   case ACPI_IORT_NODE_SMMU:
+   return IS_BUILTIN(CONFIG_ARM_SMMU);
+   default:
+   pr_warn("IORT node type %u does not describe an SMMU\n", type);
+   return false;
+   }
+}
+
 static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
struct acpi_iort_node *node,
u32 streamid)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V10 03/12] of: dma: Move range size workaround to of_dma_get_range()

2017-04-04 Thread Sricharan R
From: Laurent Pinchart 

Invalid dma-ranges values should be worked around when retrieving the
DMA range in of_dma_get_range(), not by all callers of the function.
This isn't much of a problem now that we have a single caller, but that
situation will change when moving DMA configuration to device probe
time.

Tested-by: Marek Szyprowski 
Signed-off-by: Laurent Pinchart 
---
 drivers/of/address.c | 20 ++--
 drivers/of/device.c  | 15 ---
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 02b2903..6aeb816 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -819,8 +819,8 @@ void __iomem *of_io_request_and_map(struct device_node *np, 
int index,
  * CPU addr (phys_addr_t)  : pna cells
  * size: nsize cells
  *
- * It returns -ENODEV if "dma-ranges" property was not found
- * for this device in DT.
+ * Return 0 on success, -ENODEV if the "dma-ranges" property was not found for
+ * this device in DT, or -EINVAL if the CPU address or size is invalid.
  */
 int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 
*size)
 {
@@ -880,6 +880,22 @@ int of_dma_get_range(struct device_node *np, u64 
*dma_addr, u64 *paddr, u64 *siz
*dma_addr = dmaaddr;
 
*size = of_read_number(ranges + naddr + pna, nsize);
+   /*
+* DT nodes sometimes incorrectly set the size as a mask. Work around
+* those incorrect DT by computing the size as mask + 1.
+*/
+   if (*size & 1) {
+   pr_warn("%s: size 0x%llx for dma-range in node(%s) set as 
mask\n",
+   __func__, *size, np->full_name);
+   *size = *size + 1;
+   }
+
+   if (!*size) {
+   pr_err("%s: invalid size zero for dma-range in node(%s)\n",
+  __func__, np->full_name);
+   ret = -EINVAL;
+   goto out;
+   }
 
pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n",
 *dma_addr, *paddr, *size);
diff --git a/drivers/of/device.c b/drivers/of/device.c
index b1e6beb..09dedd0 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -110,21 +110,6 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
size = dev->coherent_dma_mask + 1;
} else {
offset = PFN_DOWN(paddr - dma_addr);
-
-   /*
-* Add a work around to treat the size as mask + 1 in case
-* it is defined in DT as a mask.
-*/
-   if (size & 1) {
-   dev_warn(dev, "Invalid size 0x%llx for dma-range\n",
-size);
-   size = size + 1;
-   }
-
-   if (!size) {
-   dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
-   return;
-   }
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V10 06/12] of: device: Fix overflow of coherent_dma_mask

2017-04-04 Thread Sricharan R
Size of the dma-range is calculated as coherent_dma_mask + 1
and passed to arch_setup_dma_ops further. It overflows when
the coherent_dma_mask is set for full 64 bits 0x,
resulting in size getting passed as 0 wrongly. Fix this by
passsing in max(mask, mask + 1). Note that in this case
when the mask is set to full 64bits, we will be passing the mask
itself to arch_setup_dma_ops instead of the size. The real fix
for this should be to make arch_setup_dma_ops receive the
mask and handle it, to be done in the future.

Signed-off-by: Sricharan R 
---
 drivers/of/device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index c17c19d..c2ae6bb 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -107,7 +107,7 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
-   size = dev->coherent_dma_mask + 1;
+   size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
} else {
offset = PFN_DOWN(paddr - dma_addr);
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V10 04/12] of: dma: Make of_dma_deconfigure() public

2017-04-04 Thread Sricharan R
From: Laurent Pinchart 

As part of moving DMA initializing to probe time the
of_dma_deconfigure() function will need to be called from different
source files. Make it public and move it to drivers/of/device.c where
the of_dma_configure() function is.

Tested-by: Marek Szyprowski 
Signed-off-by: Laurent Pinchart 
---
 drivers/of/device.c   | 12 
 drivers/of/platform.c |  5 -
 include/linux/of_device.h |  3 +++
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 09dedd0..c17c19d 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -136,6 +136,18 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
+/**
+ * of_dma_deconfigure - Clean up DMA configuration
+ * @dev:   Device for which to clean up DMA configuration
+ *
+ * Clean up all configuration performed by of_dma_configure_ops() and free all
+ * resources that have been allocated.
+ */
+void of_dma_deconfigure(struct device *dev)
+{
+   arch_teardown_dma_ops(dev);
+}
+
 int of_device_register(struct platform_device *pdev)
 {
device_initialize(&pdev->dev);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5dfcc96..5344db5 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -158,11 +158,6 @@ struct platform_device *of_device_alloc(struct device_node 
*np,
 }
 EXPORT_SYMBOL(of_device_alloc);
 
-static void of_dma_deconfigure(struct device *dev)
-{
-   arch_teardown_dma_ops(dev);
-}
-
 /**
  * of_platform_device_create_pdata - Alloc, initialize and register an 
of_device
  * @np: pointer to node to create device for
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index c12dace..af98455 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -56,6 +56,7 @@ static inline struct device_node *of_cpu_device_node_get(int 
cpu)
 }
 
 void of_dma_configure(struct device *dev, struct device_node *np);
+void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
 static inline int of_driver_match_device(struct device *dev,
@@ -105,6 +106,8 @@ static inline struct device_node 
*of_cpu_device_node_get(int cpu)
 }
 static inline void of_dma_configure(struct device *dev, struct device_node *np)
 {}
+static inline void of_dma_deconfigure(struct device *dev)
+{}
 #endif /* CONFIG_OF */
 
 #endif /* _LINUX_OF_DEVICE_H */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH V10 07/12] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices

2017-04-04 Thread Sricharan R
Configuring DMA ops at probe time will allow deferring device probe when
the IOMMU isn't available yet. The dma_configure for the device is
now called from the generic device_attach callback just before the
bus/driver probe is called. This way, configuring the DMA ops for the
device would be called at the same place for all bus_types, hence the
deferred probing mechanism should work for all buses as well.

pci_bus_add_devices(platform/amba)(_device_create/driver_register)
   | |
pci_bus_add_device (device_add/driver_register)
   | |
device_attach   device_initial_probe
   | |
__device_attach_driver__device_attach_driver
   |
driver_probe_device
   |
really_probe
   |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

This patch changes the dma ops configuration to probe time for
both OF and ACPI based platform/amba/pci bus devices.

Tested-by: Marek Szyprowski 
Tested-by: Hanjun Guo 
Acked-by: Bjorn Helgaas  (drivers/pci part)
Acked-by: Rafael J. Wysocki 
Signed-off-by: Sricharan R 
---

 [V10] Added dummy dma_(de)configure functions in case
   of !CONFIG_HAS_DMA to avoid build breaks.

 drivers/acpi/glue.c |  5 -
 drivers/base/dd.c   |  9 +
 drivers/base/dma-mapping.c  | 40 
 drivers/of/platform.c   |  5 +
 drivers/pci/probe.c | 28 
 include/linux/dma-mapping.h | 12 
 6 files changed, 62 insertions(+), 37 deletions(-)

diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index fb19e1c..c05f241 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -176,7 +176,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
struct list_head *physnode_list;
unsigned int node_id;
int retval = -EINVAL;
-   enum dev_dma_attr attr;
 
if (has_acpi_companion(dev)) {
if (acpi_dev) {
@@ -233,10 +232,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
if (!has_acpi_companion(dev))
ACPI_COMPANION_SET(dev, acpi_dev);
 
-   attr = acpi_get_dma_attr(acpi_dev);
-   if (attr != DEV_DMA_NOT_SUPPORTED)
-   acpi_dma_configure(dev, attr);
-
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
   physical_node_name);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a1fbf55..4882f06 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -19,6 +19,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -356,6 +357,10 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
if (ret)
goto pinctrl_bind_failed;
 
+   ret = dma_configure(dev);
+   if (ret)
+   goto dma_failed;
+
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev_name(dev));
@@ -417,6 +422,8 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
goto done;
 
 probe_failed:
+   dma_deconfigure(dev);
+dma_failed:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
@@ -826,6 +833,8 @@ static void __device_release_driver(struct device *dev, 
struct device *parent)
drv->remove(dev);
 
device_links_driver_cleanup(dev);
+   dma_deconfigure(dev);
+
devres_release_all(dev);
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index efd71cf..449b948 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -7,9 +7,11 @@
  * This file is released under the GPLv2.
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -341,3 +343,41 @@ void dma_common_free_remap(void *cpu_addr, size_t size, 
unsigned long vm_flags)
vunmap(cpu_addr);
 }
 #endif
+
+/*
+ * Common configuration to enable DMA API use for a device
+ */
+#include 
+
+int dma_configure(struct device *dev)
+{
+   struct device *bridge = NULL, *dma_dev = dev;
+   enum dev_dma_attr attr;
+
+   if (dev_is_pci(dev)) {
+   bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+   dma_dev = bridge;
+   if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
+   dma_dev->parent->of_node)
+   dma_dev = dma_dev->parent;
+   }
+
+   if (dma_dev->of_

[PATCH V10 01/12] iommu/of: Refactor of_iommu_configure() for error handling

2017-04-04 Thread Sricharan R
From: Robin Murphy 

In preparation for some upcoming cleverness, rework the control flow in
of_iommu_configure() to minimise duplication and improve the propogation
of errors. It's also as good a time as any to switch over from the
now-just-a-compatibility-wrapper of_iommu_get_ops() to using the generic
IOMMU instance interface directly.

Tested-by: Marek Szyprowski 
Signed-off-by: Robin Murphy 
---
 drivers/iommu/of_iommu.c | 83 +++-
 1 file changed, 53 insertions(+), 30 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 2683e9f..8f4e599 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,28 @@ int of_get_dma_window(struct device_node *dn, const char 
*prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static const struct iommu_ops
+*of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
+{
+   const struct iommu_ops *ops;
+   struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
+   int err;
+
+   ops = iommu_ops_from_fwnode(fwnode);
+   if (!ops || !ops->of_xlate)
+   return NULL;
+
+   err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
+   if (err)
+   return ERR_PTR(err);
+
+   err = ops->of_xlate(dev, iommu_spec);
+   if (err)
+   return ERR_PTR(err);
+
+   return ops;
+}
+
 static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 {
struct of_phandle_args *iommu_spec = data;
@@ -105,10 +127,11 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, 
void *data)
 }
 
 static const struct iommu_ops
-*of_pci_iommu_configure(struct pci_dev *pdev, struct device_node *bridge_np)
+*of_pci_iommu_init(struct pci_dev *pdev, struct device_node *bridge_np)
 {
const struct iommu_ops *ops;
struct of_phandle_args iommu_spec;
+   int err;
 
/*
 * Start by tracing the RID alias down the PCI topology as
@@ -123,56 +146,56 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, 
void *data)
 * bus into the system beyond, and which IOMMU it ends up at.
 */
iommu_spec.np = NULL;
-   if (of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
-  "iommu-map-mask", &iommu_spec.np, iommu_spec.args))
-   return NULL;
+   err = of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
+"iommu-map-mask", &iommu_spec.np,
+iommu_spec.args);
+   if (err)
+   return err == -ENODEV ? NULL : ERR_PTR(err);
 
-   ops = iommu_ops_from_fwnode(&iommu_spec.np->fwnode);
-   if (!ops || !ops->of_xlate ||
-   iommu_fwspec_init(&pdev->dev, &iommu_spec.np->fwnode, ops) ||
-   ops->of_xlate(&pdev->dev, &iommu_spec))
-   ops = NULL;
+   ops = of_iommu_xlate(&pdev->dev, &iommu_spec);
 
of_node_put(iommu_spec.np);
return ops;
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-  struct device_node *master_np)
+static const struct iommu_ops
+*of_platform_iommu_init(struct device *dev, struct device_node *np)
 {
struct of_phandle_args iommu_spec;
-   struct device_node *np;
const struct iommu_ops *ops = NULL;
int idx = 0;
 
-   if (dev_is_pci(dev))
-   return of_pci_iommu_configure(to_pci_dev(dev), master_np);
-
/*
 * We don't currently walk up the tree looking for a parent IOMMU.
 * See the `Notes:' section of
 * Documentation/devicetree/bindings/iommu/iommu.txt
 */
-   while (!of_parse_phandle_with_args(master_np, "iommus",
-  "#iommu-cells", idx,
-  &iommu_spec)) {
-   np = iommu_spec.np;
-   ops = iommu_ops_from_fwnode(&np->fwnode);
-
-   if (!ops || !ops->of_xlate ||
-   iommu_fwspec_init(dev, &np->fwnode, ops) ||
-   ops->of_xlate(dev, &iommu_spec))
-   goto err_put_node;
-
-   of_node_put(np);
+   while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells",
+  idx, &iommu_spec)) {
+   ops = of_iommu_xlate(dev, &iommu_spec);
+   of_node_put(iommu_spec.np);
idx++;
+   if (IS_ERR_OR_NULL(ops))
+   break;
}
 
return ops;
+}
+
+const struct iommu_ops *of_iommu_configure(struct device *dev,
+  struct device_node *master_np)
+{
+   const struct iommu_ops *ops;
+
+   if (!master_np)
+   return NULL;
+
+   if (dev_is_pci(dev))
+   ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
+   else
+   ops = of_platform_iommu_init(d

[PATCH V10 00/12] IOMMU probe deferral support

2017-04-04 Thread Sricharan R
with deferred probing or error

Lorenzo Pieralisi (2):
  ACPI/IORT: Add function to check SMMUs drivers presence
  ACPI/IORT: Remove linker section for IORT entries probing

Robin Murphy (3):
  iommu/of: Refactor of_iommu_configure() for error handling
  iommu/of: Prepare for deferred IOMMU configuration
  iommu/arm-smmu: Clean up early-probing workarounds

Sricharan R (4):
  of: device: Fix overflow of coherent_dma_mask
  of/acpi: Configure dma operations at probe time for platform/amba/pci
bus devices
  drivers: acpi: Handle IOMMU lookup failure with deferred probing or
error
  arm64: dma-mapping: Remove the notifier trick to handle early setting
of dma_ops

 arch/arm64/mm/dma-mapping.c   | 142 +-
 drivers/acpi/arm64/iort.c |  48 -
 drivers/acpi/glue.c   |   5 --
 drivers/acpi/scan.c   |  11 ++-
 drivers/base/dd.c |   9 +++
 drivers/base/dma-mapping.c|  41 +++
 drivers/iommu/arm-smmu-v3.c   |  46 +---
 drivers/iommu/arm-smmu.c  | 110 +
 drivers/iommu/of_iommu.c  | 126 -
 drivers/of/address.c  |  20 +-
 drivers/of/device.c   |  36 +-
 drivers/of/platform.c |  10 +--
 drivers/pci/probe.c   |  28 
 include/acpi/acpi_bus.h   |   2 +-
 include/asm-generic/vmlinux.lds.h |   1 -
 include/linux/acpi.h  |   7 +-
 include/linux/acpi_iort.h |   3 -
 include/linux/dma-mapping.h   |  12 
 include/linux/of_device.h |  10 ++-
 19 files changed, 329 insertions(+), 338 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH V3 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2017-04-03 Thread Sricharan R

Hi Will,

On 4/3/2017 10:53 PM, Will Deacon wrote:

On Fri, Mar 31, 2017 at 10:58:16PM -0400, Rob Clark wrote:

On Fri, Mar 31, 2017 at 1:54 PM, Will Deacon  wrote:

On Thu, Mar 09, 2017 at 09:05:43PM +0530, Sricharan R wrote:

This series provides the support for turning on the arm-smmu's
clocks/power domains using runtime pm. This is done using the
recently introduced device links patches, which lets the symmu's
runtime to follow the master's runtime pm, so the smmu remains
powered only when the masters use it.


Do you have any numbers for the power savings you achieve with this?
How often do we actually manage to stop the SMMU clocks on an SoC with
a handful of masters?

In other words, is this too coarse-grained to be useful, or is it common
that all the devices upstream of the SMMU are suspended?


well, if you think about a phone/tablet with a command mode panel,
pretty much all devices will be suspended most of the time ;-)


Well, that's really what I was asking about. I assumed that periodic
modem/radio transactions would keep the SMMU clocked, so would like to get a
rough idea of the power savings achieved with this coarse-grained approach.



One main reason for introducing this was to enable power for
the iommus separately in those places where the iommu gets
accessed without the context of the master, pm runtime was
done to use the device links feature and also those iommus
had their power-domains to be enabled (during the iommu probe,
faults) (downstream was modelling those power-domains as
'regulators' which was not correct) and have to be clocked
as well.

I was in the process of trying to measure the power difference
that this would achieve. One concern here is, this series depends
on the device link between master and iommu.
So essentially the masters have to be pm runtime adapted fully
to use this. For my testing i was using couple of them (mdp, gpu),
by just enabling pm runtime for them, not full pm runtime though.
But i will come-up with the numbers by instrumenting little more.
The downstream code explicitly turns on the iommu clocks/regulators
in the standalone path (called without master context and after
that, lets the master to control the iommu clocks ( the iommu
clocks are populated in master DT data as well), so ensures iommu
is clocked only when really needed by the master. So number
measured from downstream should also give the power numbers in
another way.

Regards,
 Sricharan

--
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a 
member of Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH V9 00/11] IOMMU probe deferral support

2017-03-28 Thread Sricharan R

Hi,

On 3/28/2017 7:45 PM, Shameerali Kolothum Thodi wrote:




-Original Message-
From: Sricharan R [mailto:sricha...@codeaurora.org]
Sent: Tuesday, March 28, 2017 5:54 AM
To: Robin Murphy; Shameerali Kolothum Thodi; Wangzhou (B);
will.dea...@arm.com; j...@8bytes.org; lorenzo.pieral...@arm.com;
iommu@lists.linux-foundation.org; linux-arm-ker...@lists.infradead.org;
linux-arm-...@vger.kernel.org; m.szyprow...@samsung.com;
bhelg...@google.com; linux-...@vger.kernel.org; linux-
a...@vger.kernel.org; t...@semihalf.com; hanjun@linaro.org;
ok...@codeaurora.org
Subject: Re: [PATCH V9 00/11] IOMMU probe deferral support

Hi,


[...]


 From the logs its clear that  when ixgbevf driver originally probes
and adds the device  to smmu  the dma mask is 32, but when it binds
to vfio-pci, it becomes 64 bit.


Just to add to that, the mask is set to 64 bit in the ixgebvf driver
probe[1]


Aha, but of course it's still the same struct device getting bound to
VFIO later, so whatever mask the first driver set is still in there
when we go through of_dma_configure() the second time (and the fact
that we go through more than once being the new behaviour). So yes,
this is a legitimate problem and we really do need to be robust
against size overflow. I reckon the below tweak of your fix is
probably the way to go; cleaning up the arch_setup_dma_ops() interface

can happen later.




ok, i will add this fix separately and also the acpi fix that lorenzo has
suggested in patch #8 in to the series after testing confirmation.


I can confirm that the patches fixes the issues reported here . Both
DT and ACPI works now.



Thanks for the testing. Will repost with the fixes.

Regards,
 Sricharan

--
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a 
member of Code Aurora Forum, hosted by The Linux Foundation

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


Re: [V9, 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error

2017-03-28 Thread Sricharan R

Hi,

On 3/28/2017 8:30 PM, Rob Herring wrote:

On Fri, Mar 10, 2017 at 12:30:57AM +0530, Sricharan R wrote:

From: Laurent Pinchart 

Failures to look up an IOMMU when parsing the DT iommus property need to
be handled separately from the .of_xlate() failures to support deferred
probing.

The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the device tree describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Marek Szyprowski 
Signed-off-by: Laurent Pichart 
Signed-off-by: Sricharan R 
---
 drivers/base/dma-mapping.c | 5 +++--
 drivers/iommu/of_iommu.c   | 4 ++--
 drivers/of/device.c| 7 ++-
 include/linux/of_device.h  | 9 ++---
 4 files changed, 17 insertions(+), 8 deletions(-)


Maybe it is the same issue reported for VFIO, but virtio-pci is broken
with v8 of this series. Bisecting blames this commit which looks like it
hasn't changeed.


Ya, as Robin mentioned it was broken at patch #2 and
comes out after this patch. I am going to repost this series with
couple of more fixes added as well.



Rob

P.S. Doesn't look like you have copied the DT maintainers nor list for
the DT changes.


Ha, really sorry about that. will add it.

Regards,
 Sricharan

--
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a 
member of Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH V9 00/11] IOMMU probe deferral support

2017-03-27 Thread Sricharan R

Hi,


On 24/03/17 09:27, Shameerali Kolothum Thodi wrote:

Hi Sricharan,


-Original Message-
From: Sricharan R [mailto:sricha...@codeaurora.org]

[...]

Looks like this triggers the start of the bug.
So the below check in iommu_dma_init_domain fails,

 if (domain->geometry.force_aperture) {
 if (base > domain->geometry.aperture_end ||
 base + size <= domain->geometry.aperture_start) {

and the rest goes out of sync after that. Can you print out the base,
aperture_start and end values to see why the check fails ?


dev_info(dev, "0x%llx 0x%llx, 0x%llx 0x%llx, 0x%llx 0x%llx\n", base, size,

domain->geometry.aperture_start, domain->geometry.aperture_end,
*dev->dma_mask, dev->coherent_dma_mask);


[  183.752100] ixgbevf :81:10.0: 0x0 0x1, 0x0 0x,

0x 0x

.
[  319.508037] vfio-pci :81:10.0: 0x0 0x0, 0x0 0x,

0x 0x


Yes, size seems to be the problem here. When the VF  device gets

attached

to vfio-pci,

somehow the dev->coherent_dma_mask is set to 64 bits and size

become

zero.

AFAICS, this is either down to patch 3 (which should apply on its own
easily enough for testing), or patch 6, implying that somehow the
vfio-pci device gets its DMA mask widened to 64 bits somewhere between
very soon after after creation (where we originally called
of_dma_configure()) and immediately before probe (where we now call

it).


Either way I guess this is yet more motivation to write that "change the
arch_setup_dma_ops() interface to take a mask instead of a size" patch...


Just applying the patch 3 and binding the device into vfio-pci is fine. Please
find the
log below (with  dev_info debug added to iommu_dma_init_domain ).
...
[  142.851906] iommu: Adding device :81:10.0 to group 6
[  142.852063] ixgbevf :81:10.0: 0x0 0x1, 0x0 0x,
0x 0x   >dev_info()
[  142.852836] ixgbevf :81:10.0: enabling device ( -> 0002)
[  142.852962] ixgbe :81:00.0 eth0: VF Reset msg received from vf 0
[  142.853833] ixgbe :81:00.0: VF 0 has no MAC address assigned, you
may have to assign one manually
[  142.863956] ixgbevf :81:10.0: MAC address not assigned by
administrator.
[  142.863960] ixgbevf :81:10.0: Assigning random MAC address
[  142.865689] ixgbevf :81:10.0: da:9f:f8:1e:57:3a
[  142.865692] ixgbevf :81:10.0: MAC: 1
[  142.865693] ixgbevf :81:10.0: Intel(R) 82599 Virtual Function
[  142.939145] ixgbe :81:00.0 eth0: NIC Link is Up 1 Gbps, Flow Control:
None
[  152.902894] nfs: server 172.18.45.166 not responding, still trying
[  188.980933] nfs: server 172.18.45.166 not responding, still trying
[  188.981298] nfs: server 172.18.45.166 OK
[  188.981593] nfs: server 172.18.45.166 OK
[  221.755626] VFIO - User Level meta-driver version: 0.3
...

Applied up to patch 6, and the issue appeared,

[  145.212351] iommu: Adding device :81:10.0 to group 5
[  145.212367] ixgbevf :81:10.0: 0x0 0x1, 0x0 0x,
0x 0x
[  145.213261] ixgbevf :81:10.0: enabling device ( -> 0002)
[  145.213394] ixgbe :81:00.0 eth0: VF Reset msg received from vf 0
[  145.214272] ixgbe :81:00.0: VF 0 has no MAC address assigned, you
may have to assign one manually
[  145.224379] ixgbevf :81:10.0: MAC address not assigned by
administrator.
[  145.224384] ixgbevf :81:10.0: Assigning random MAC address
[  145.225941] ixgbevf :81:10.0: 1a:85:06:48:a7:19
[  145.225944] ixgbevf :81:10.0: MAC: 1
[  145.225946] ixgbevf :81:10.0: Intel(R) 82599 Virtual Function
[  145.299961] ixgbe :81:00.0 eth0: NIC Link is Up 1 Gbps, Flow Control:
None
[  154.947742] nfs: server 172.18.45.166 not responding, still trying
[  191.025780] nfs: server 172.18.45.166 not responding, still trying
[  191.026122] nfs: server 172.18.45.166 OK
[  191.026317] nfs: server 172.18.45.166 OK
[  263.706402] VFIO - User Level meta-driver version: 0.3
[  269.757613] vfio-pci :81:10.0: 0x0 0x0, 0x0 0x, 
0x
0x
[  269.757617] specified DMA range outside IOMMU capability
[  269.757618] Failed to set up IOMMU for device :81:10.0; retaining
platform DMA ops

 From the logs its clear that  when ixgbevf driver originally probes and adds
the device
 to smmu  the dma mask is 32, but when it binds to vfio-pci, it becomes 64 bit.


Just to add to that, the mask is set to 64 bit in the ixgebvf driver probe[1]


Aha, but of course it's still the same struct device getting bound to
VFIO later, so whatever mask the first driver set is still in there when
we go through of_dma_configure() the second time (and the fact that we
go through more than once being the new behaviour). So yes, this is a
legitimate problem and we really do need to be robust against size
overflow. I reckon the below tweak of your f

Re: [PATCH V9 00/11] IOMMU probe deferral support

2017-03-24 Thread Sricharan R

Hi Shameer,



[  414.700493] specified DMA range outside IOMMU capability

<-- error here

[  414.700496] Failed to set up IOMMU for device 0002:81:10.0; retaining

platform DMA ops<-- error here

Looks like this triggers the start of the bug.
So the below check in iommu_dma_init_domain fails,

 if (domain->geometry.force_aperture) {
 if (base > domain->geometry.aperture_end ||
 base + size <= domain->geometry.aperture_start) {

and the rest goes out of sync after that. Can you print out the base,
aperture_start and end values to see why the check fails ?


dev_info(dev, "0x%llx 0x%llx, 0x%llx 0x%llx, 0x%llx 0x%llx\n", base, size, 
domain->geometry.aperture_start, domain->geometry.aperture_end, *dev->dma_mask, 
dev->coherent_dma_mask);

[  183.752100] ixgbevf :81:10.0: 0x0 0x1, 0x0 0x, 
0x 0x
.
[  319.508037] vfio-pci :81:10.0: 0x0 0x0, 0x0 0x, 
0x 0x

Yes, size seems to be the problem here. When the VF  device gets attached to 
vfio-pci,
somehow the dev->coherent_dma_mask is set to 64 bits and size become zero.

@@ -107,7 +107,7 @@ int of_dma_configure(struct device *dev, struct device_node 
*np)
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
 -  size = ';
 +  size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);



But without this series, size is still set as
dev->coherent_dma_mask + 1 , somehow not sure how it works
fine in that case ?

I remember i had this change in the V7 patchset, but later
dropped it for the reason that this change is not relevant
for this series, but should be there/sent to address the 64bit
overflow separately.


@@ -1386,7 +1387,8 @@ int acpi_dma_configure(struct device *dev, enum 
dev_dma_attr attr)
 * Assume dma valid range starts at 0 and covers the whole
 * coherent_dma_mask.
 */
 -  arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
 +  size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
 +  arch_setup_dma_ops(dev, 0, size, iommu,
   attr == DEV_DMA_COHERENT);

With the above fixes, DT boot works fine. But we still get the below crash on 
ACPI


[  402.581445] kernel BUG at drivers/iommu/arm-smmu-v3.c:1064!


Looks like this happens when the ste_live becomes true during
the initial attach, but later without an detach,
attach once again happens from vfio. Just thinking why the
detach_dev is not happening only in ACPI case. Actually not
having any of arm-smmuv3 or ACPI based setup in my place.
Can i get some help by having some logs from the arm-smmv3
driver ?


[  402.587007] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[  402.592479] Modules linked in: vfio_iommu_type1 vfio_pci irqbypass

vfio_virqfd vfio ixgbevf ixgb



The change that this series does is trying to add the dma/iommu ops to the
device after the iommu is actually probed.
So in your working case, does the device initially gets hooked to iommu_ops
and the above same check passes in working case ?


I believe so. Because didn't notice the "specified DMA range outside IOMMU 
capability"
in the working case.


ok, as i said above not sure why the overflow does not affect without
this series.

Regards,
 Sricharan




Thanks,
Shameer
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a 
member of Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH V9 00/11] IOMMU probe deferral support

2017-03-24 Thread Sricharan R

Hi Zhou,

On 3/24/2017 9:23 AM, Zhou Wang wrote:

On 2017/3/10 3:00, Sricharan R wrote:

This series calls the dma ops configuration for the devices
at a generic place so that it works for all busses.
The dma_configure_ops for a device is now called during
the device_attach callback just before the probe of the
bus/driver is called. Similarly dma_deconfigure is called during
device/driver_detach path.

pci_bus_add_devices(platform/amba)(_device_create/driver_register)
   | |
pci_bus_add_device (device_add/driver_register)
   | |
device_attach   device_initial_probe
   | |
__device_attach_driver__device_attach_driver
   |
driver_probe_device
   |
really_probe
   |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

Rebased the series against mainline 4.11-rc1. Applies and builds cleanly
against mainline and linux-next. There is a conflict with patch#9
against iommu-next, but that should go away eventually as iommu-next
is rebased against 4.11-rc1.

* Tested with platform and pci devices for probe deferral
  and reprobe on arm64 based platform.


Hi Sricharan,

I applied this series on v4.11-rc1 to test PCIe pass through in HiSilicon
D05 board(with Intel 82599 networking card). It failed.

After I used:

echo vfio-pci > /sys/bus/pci/devices/0002:81:10.0/driver_override
echo 0002:81:10.0 > /sys/bus/pci/drivers/ixgbevf/unbind
echo 0002:81:10.0 > /sys/bus/pci/drivers_probe

to bind vfio-pci driver to Intel 82599 networking card VF.

I got log in host:
[...]
[  414.275818] ixgbevf: Intel(R) 10 Gigabit PCI Express Virtual Function 
Network Driver - version 3.2.2-k
[  414.275824] ixgbevf: Copyright (c) 2009 - 2015 Intel Corporation.
[  414.276647] ixgbe 0002:81:00.0 eth12: SR-IOV enabled with 1 VFs
[  414.342252] pcieport 0002:80:00.0: can't derive routing for PCI INT A
[  414.342255] ixgbe 0002:81:00.0: PCI INT A: no GSI
[  414.343348] ixgbe 0002:81:00.0: Multiqueue Enabled: Rx Queue count = 4, Tx 
Queue count = 4
[  414.448135] pci 0002:81:10.0: [8086:10ed] type 00 class 0x02
[  414.448713] iommu: Adding device 0002:81:10.0 to group 4
[  414.449798] ixgbevf 0002:81:10.0: enabling device ( -> 0002)
[  414.451101] ixgbevf 0002:81:10.0: PF still in reset state.  Is the PF 
interface up?
[  414.451103] ixgbevf 0002:81:10.0: Assigning random MAC address
[  414.451414] ixgbevf 0002:81:10.0: be:30:8f:ed:f8:02
[  414.451417] ixgbevf 0002:81:10.0: MAC: 1
[  414.451418] ixgbevf 0002:81:10.0: Intel(R) 82599 Virtual Function
[  414.464271] VFIO - User Level meta-driver version: 0.3
[  414.570074] ixgbe 0002:81:00.0: registered PHC device on eth12
[  414.700493] specified DMA range outside IOMMU capability
  <-- error here
[  414.700496] Failed to set up IOMMU for device 0002:81:10.0; retaining platform 
DMA ops<-- error here


Looks like this triggers the start of the bug.
So the below check in iommu_dma_init_domain fails,

if (domain->geometry.force_aperture) {
if (base > domain->geometry.aperture_end ||
base + size <= domain->geometry.aperture_start) {

and the rest goes out of sync after that. Can you print out the
base, aperture_start and end values to see why the check fails ?

The change that this series does is trying to add the
dma/iommu ops to the device after the iommu is actually probed.
So in your working case, does the device initially gets hooked
to iommu_ops and the above same check passes in working case ?

Regards,
 Sricharan


[  414.748043] ixgbe 0002:81:00.0 eth12: detected SFP+: 5
[  414.922277] ixgbe 0002:81:00.0 eth12: NIC Link is Up 10 Gbps, Flow Control: 
RX/TX

Then I tried to boot up VM using:

qemu-system-aarch64 \
-machine virt,gic-version=3 \
-enable-kvm \
-cpu host \
-m 1024 \
-kernel ./Image_vm \
-initrd ./minifs.cpio.gz \
-nographic \
-net none -device vfio-pci,host=0002:81:10.0,id=net0

I got this error:

root@ubuntu:~/scripts# ./qemu_run.sh
[  402.581445] kernel BUG at drivers/iommu/arm-smmu-v3.c:1064!
[  402.587007] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[  402.592479] Modules linked in: vfio_iommu_type1 vfio_pci irqbypass 
vfio_virqfd vfio ixgbevf ixgb   
 e mdio [last unloaded: 
vfio_iommu_type1]
[  402.604733] CPU: 26 PID: 4437 Comm: qemu-system-aar Not tainted 
4.11.0-rc1-g4b62e7fa #21
[  402.612809] Hardware name: Huawei Taishan 2280 /D05, BIOS Hisilicon D05 UEFI 
16.12 Release 02/22 
   /2017
[  402.622013] task: 8017e2161a00 task.stack: 8017e5a8c000
[  402.627926] PC is at arm_smmu_write_strtab_ent+0x1b4/0x1b8
[  402.633399] LR is at 

Re: [PATCH v2 5/5] iommu: Allow default domain type to be set on the kernel command line

2017-03-23 Thread Sricharan R

Hi,

Replying again, as there was some issue with mailer last time.

On 3/21/2017 11:47 PM, Will Deacon wrote:

On Tue, Mar 21, 2017 at 05:46:29PM +, Robin Murphy wrote:

On 21/03/17 17:21, Will Deacon wrote:

On Tue, Mar 21, 2017 at 04:45:27PM +0100, Joerg Roedel wrote:

On Fri, Mar 10, 2017 at 08:49:36PM +, Will Deacon wrote:

@@ -1014,8 +1027,8 @@ struct iommu_group *iommu_group_get_for_dev(struct device 
*dev)
 * IOMMU driver.
 */
if (!group->default_domain) {
-   group->default_domain = __iommu_domain_alloc(dev->bus,
-IOMMU_DOMAIN_DMA);
+   group->default_domain =
+   __iommu_domain_alloc(dev->bus, iommu_def_domain_type);


It would be good to have a fall-back here if we are talking to an IOMMU
driver that uses default domains, but does not support identity-mapped
domains (yet). Exynos and Rockchip IOMMU drivers seem to fall into this
category. A dev_warn() also makes sense in case allocating a identity
domain fails.


Sure, something like the diff below?

Will

--->8


diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 42a842e3f95f..f787626a745d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1027,10 +1027,19 @@ struct iommu_group *iommu_group_get_for_dev(struct 
device *dev)
 * IOMMU driver.
 */
if (!group->default_domain) {
-   group->default_domain =
-   __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
+   struct iommu_domain *dom;
+
+   dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
+   if (!dom) {
+   dev_warn(dev,
+"failed to allocate default IOMMU domain of type 
%u; falling back to IOMMU_DOMAIN_DMA",
+iommu_def_domain_type);


Conversely, that's going to be noisy if iommu_def_domain_type was
IOMMU_DOMAIN_DMA to begin with. I think it makes sense to warn if the
user asked for a specific default domain type on the command line and
that didn't work, but maybe not to bother otherwise. Plus, if they asked
for passthrough, then not allocating a default domain at all is probably
closer to the desired result than installing a DMA ops domain would be.


You're right -- I'll hack this about to check if the default type isn't
DOMAIN_DMA before warning about the allocation failure.


if some master devices want 'IDENTITY_DOMAIN' as default (because
those devices do not want any iommu resources to be used/dma_ops to be
set) and some 'DMA_DOMAIN' as default, then should the default be
'DMA_DOMAIN' and then masters needing IDENTITY_DOMAIN explicitly do an
detach_dev later. This [1] was adding the support for detach_dev
of the default DMA_DOMAINs.

[1] https://patchwork.codeaurora.org/patch/164933/

Regards,
 Sricharan
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 5/5] iommu: Allow default domain type to be set on the kernel command line

2017-03-23 Thread Sricharan R

Hi,

On 3/21/2017 11:47 PM, Will Deacon wrote:

On Tue, Mar 21, 2017 at 05:46:29PM +, Robin Murphy wrote:

On 21/03/17 17:21, Will Deacon wrote:

On Tue, Mar 21, 2017 at 04:45:27PM +0100, Joerg Roedel wrote:

On Fri, Mar 10, 2017 at 08:49:36PM +, Will Deacon wrote:

@@ -1014,8 +1027,8 @@ struct iommu_group *iommu_group_get_for_dev(struct device 
*dev)
 * IOMMU driver.
 */
if (!group->default_domain) {
-   group->default_domain = __iommu_domain_alloc(dev->bus,
-IOMMU_DOMAIN_DMA);
+   group->default_domain =
+   __iommu_domain_alloc(dev->bus, iommu_def_domain_type);


It would be good to have a fall-back here if we are talking to an IOMMU
driver that uses default domains, but does not support identity-mapped
domains (yet). Exynos and Rockchip IOMMU drivers seem to fall into this
category. A dev_warn() also makes sense in case allocating a identity
domain fails.


Sure, something like the diff below?

Will

--->8


diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 42a842e3f95f..f787626a745d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1027,10 +1027,19 @@ struct iommu_group *iommu_group_get_for_dev(struct 
device *dev)
 * IOMMU driver.
 */
if (!group->default_domain) {
-   group->default_domain =
-   __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
+   struct iommu_domain *dom;
+
+   dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
+   if (!dom) {
+   dev_warn(dev,
+"failed to allocate default IOMMU domain of type 
%u; falling back to IOMMU_DOMAIN_DMA",
+iommu_def_domain_type);


Conversely, that's going to be noisy if iommu_def_domain_type was
IOMMU_DOMAIN_DMA to begin with. I think it makes sense to warn if the
user asked for a specific default domain type on the command line and
that didn't work, but maybe not to bother otherwise. Plus, if they asked
for passthrough, then not allocating a default domain at all is probably
closer to the desired result than installing a DMA ops domain would be.


You're right -- I'll hack this about to check if the default type isn't
DOMAIN_DMA before warning about the allocation failure.


if some master devices want 'IDENTITY_DOMAIN' as default (because  those 
devices do not want any iommu resources to be used/dma_ops to be set) 
and some 'DMA_DOMAIN' as default, then should the default be 
'DMA_DOMAIN' and then masters needing IDENTITY_DOMAIN explicitly do an

detach_dev later. This [1] was adding the support for detach_dev
of the default DMA_DOMAINs.

[1] https://patchwork.codeaurora.org/patch/164933/

Regards,
 Sricharan
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


  1   2   3   4   5   >