Message ID | e701030cbf91b441f60d2d6788885f679317fad6.1626283714.git.robin.murphy@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | iommu: Unify iova_to_phys for identity domains | expand |
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@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@linux.intel.com> Best regards, baolu > > return domain->ops->iova_to_phys(domain, iova); >
On 2021-07-15 02:38, Lu Baolu wrote: > 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@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; Yeah, I put IOMMU_DOMAIN_BLOCKED last as the least likely condition since it's really just for completeness - I don't think it's possible to see it legitimately used at the moment - but on second look I think ops->iova_to_phys == NULL is equally theoretical now, so maybe I could be removing that and we just make it mandatory for any new drivers? > Anyway, > > Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Thanks! Robin. > > Best regards, > baolu > >> return domain->ops->iova_to_phys(domain, iova); >>
On Wed, Jul 14, 2021 at 06:28:34PM +0100, 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@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(-) Applied to iommu/core, thanks.
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; return domain->ops->iova_to_phys(domain, iova);
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@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(-)