[PATCH] iommu: Unify iova_to_phys for identity domains

Lu Baolu baolu.lu at linux.intel.com
Wed Jul 14 18:38:24 PDT 2021


On 7/15/21 1:28 AM, Robin Murphy wrote:
> If people are going to insist on calling iommu_iova_to_phys()
> pointlessly and expecting it to work, we can at least do ourselves a
> favour by handling those cases in the core code, rather than repeatedly
> across an inconsistent handful of drivers.
> 
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>   drivers/iommu/amd/io_pgtable.c              | 3 ---
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 3 ---
>   drivers/iommu/arm/arm-smmu/arm-smmu.c       | 3 ---
>   drivers/iommu/iommu.c                       | 6 +++++-
>   4 files changed, 5 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
> index bb0ee5c9fde7..182c93a43efd 100644
> --- a/drivers/iommu/amd/io_pgtable.c
> +++ b/drivers/iommu/amd/io_pgtable.c
> @@ -493,9 +493,6 @@ static phys_addr_t iommu_v1_iova_to_phys(struct io_pgtable_ops *ops, unsigned lo
>   	unsigned long offset_mask, pte_pgsize;
>   	u64 *pte, __pte;
>   
> -	if (pgtable->mode == PAGE_MODE_NONE)
> -		return iova;
> -
>   	pte = fetch_pte(pgtable, iova, &pte_pgsize);
>   
>   	if (!pte || !IOMMU_PTE_PRESENT(*pte))
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 3e87a9cf6da3..c9fdd0d097be 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2481,9 +2481,6 @@ arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
>   {
>   	struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
>   
> -	if (domain->type == IOMMU_DOMAIN_IDENTITY)
> -		return iova;
> -
>   	if (!ops)
>   		return 0;
>   
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index 0f181f76c31b..0d04eafa3fdb 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -1317,9 +1317,6 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
>   	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>   	struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
>   
> -	if (domain->type == IOMMU_DOMAIN_IDENTITY)
> -		return iova;
> -
>   	if (!ops)
>   		return 0;
>   
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 43a2041d9629..7c16f977b5a6 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2371,7 +2371,11 @@ EXPORT_SYMBOL_GPL(iommu_detach_group);
>   
>   phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
>   {
> -	if (unlikely(domain->ops->iova_to_phys == NULL))
> +	if (domain->type == IOMMU_DOMAIN_IDENTITY)
> +		return iova;
> +
> +	if (unlikely(domain->ops->iova_to_phys == NULL) ||
> +	    domain->type == IOMMU_DOMAIN_BLOCKED)
>   		return 0;

Nit:
Logically we only needs ops->iova_to_phys for DMA and UNMANAGED domains,
so it looks better if we have

	if (domain->type == IOMMU_DOMAIN_BLOCKED ||
	    unlikely(domain->ops->iova_to_phys == NULL))
		return 0;

Anyway,

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>

Best regards,
baolu

>   
>   	return domain->ops->iova_to_phys(domain, iova);
> 



More information about the linux-arm-kernel mailing list