aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2017-09-28 10:55:01 -0400
committerJoerg Roedel <jroedel@suse.de>2017-10-02 09:45:25 -0400
commit32b124492bdf974f68eaef1bde80dc8058aef002 (patch)
tree65e5538efdefea61e632c17112f0e511dd2b7b10
parentabbb8a09384f69f7bb05936879e51933c146afba (diff)
iommu/io-pgtable-arm: Convert to IOMMU API TLB sync
Now that the core API issues its own post-unmap TLB sync call, push that operation out from the io-pgtable-arm internals into the users. For now, we leave the invalidation implicit in the unmap operation, since none of the current users would benefit much from any change to that. CC: Magnus Damm <damm+renesas@opensource.se> CC: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/arm-smmu-v3.c10
-rw-r--r--drivers/iommu/arm-smmu.c20
-rw-r--r--drivers/iommu/io-pgtable-arm.c7
-rw-r--r--drivers/iommu/ipmmu-vmsa.c10
4 files changed, 36 insertions, 11 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index e67ba6c40faf..ee0c7b73cff7 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1743,6 +1743,14 @@ arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
1743 return ops->unmap(ops, iova, size); 1743 return ops->unmap(ops, iova, size);
1744} 1744}
1745 1745
1746static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
1747{
1748 struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
1749
1750 if (smmu)
1751 __arm_smmu_tlb_sync(smmu);
1752}
1753
1746static phys_addr_t 1754static phys_addr_t
1747arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) 1755arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
1748{ 1756{
@@ -1963,6 +1971,8 @@ static struct iommu_ops arm_smmu_ops = {
1963 .map = arm_smmu_map, 1971 .map = arm_smmu_map,
1964 .unmap = arm_smmu_unmap, 1972 .unmap = arm_smmu_unmap,
1965 .map_sg = default_iommu_map_sg, 1973 .map_sg = default_iommu_map_sg,
1974 .flush_iotlb_all = arm_smmu_iotlb_sync,
1975 .iotlb_sync = arm_smmu_iotlb_sync,
1966 .iova_to_phys = arm_smmu_iova_to_phys, 1976 .iova_to_phys = arm_smmu_iova_to_phys,
1967 .add_device = arm_smmu_add_device, 1977 .add_device = arm_smmu_add_device,
1968 .remove_device = arm_smmu_remove_device, 1978 .remove_device = arm_smmu_remove_device,
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 3bdb799d3b4b..e4a82d70d446 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -250,6 +250,7 @@ enum arm_smmu_domain_stage {
250struct arm_smmu_domain { 250struct arm_smmu_domain {
251 struct arm_smmu_device *smmu; 251 struct arm_smmu_device *smmu;
252 struct io_pgtable_ops *pgtbl_ops; 252 struct io_pgtable_ops *pgtbl_ops;
253 const struct iommu_gather_ops *tlb_ops;
253 struct arm_smmu_cfg cfg; 254 struct arm_smmu_cfg cfg;
254 enum arm_smmu_domain_stage stage; 255 enum arm_smmu_domain_stage stage;
255 struct mutex init_mutex; /* Protects smmu pointer */ 256 struct mutex init_mutex; /* Protects smmu pointer */
@@ -735,7 +736,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
735 enum io_pgtable_fmt fmt; 736 enum io_pgtable_fmt fmt;
736 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); 737 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
737 struct arm_smmu_cfg *cfg = &smmu_domain->cfg; 738 struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
738 const struct iommu_gather_ops *tlb_ops;
739 739
740 mutex_lock(&smmu_domain->init_mutex); 740 mutex_lock(&smmu_domain->init_mutex);
741 if (smmu_domain->smmu) 741 if (smmu_domain->smmu)
@@ -813,7 +813,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
813 ias = min(ias, 32UL); 813 ias = min(ias, 32UL);
814 oas = min(oas, 32UL); 814 oas = min(oas, 32UL);
815 } 815 }
816 tlb_ops = &arm_smmu_s1_tlb_ops; 816 smmu_domain->tlb_ops = &arm_smmu_s1_tlb_ops;
817 break; 817 break;
818 case ARM_SMMU_DOMAIN_NESTED: 818 case ARM_SMMU_DOMAIN_NESTED:
819 /* 819 /*
@@ -833,9 +833,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
833 oas = min(oas, 40UL); 833 oas = min(oas, 40UL);
834 } 834 }
835 if (smmu->version == ARM_SMMU_V2) 835 if (smmu->version == ARM_SMMU_V2)
836 tlb_ops = &arm_smmu_s2_tlb_ops_v2; 836 smmu_domain->tlb_ops = &arm_smmu_s2_tlb_ops_v2;
837 else 837 else
838 tlb_ops = &arm_smmu_s2_tlb_ops_v1; 838 smmu_domain->tlb_ops = &arm_smmu_s2_tlb_ops_v1;
839 break; 839 break;
840 default: 840 default:
841 ret = -EINVAL; 841 ret = -EINVAL;
@@ -863,7 +863,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
863 .pgsize_bitmap = smmu->pgsize_bitmap, 863 .pgsize_bitmap = smmu->pgsize_bitmap,
864 .ias = ias, 864 .ias = ias,
865 .oas = oas, 865 .oas = oas,
866 .tlb = tlb_ops, 866 .tlb = smmu_domain->tlb_ops,
867 .iommu_dev = smmu->dev, 867 .iommu_dev = smmu->dev,
868 }; 868 };
869 869
@@ -1259,6 +1259,14 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
1259 return ops->unmap(ops, iova, size); 1259 return ops->unmap(ops, iova, size);
1260} 1260}
1261 1261
1262static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
1263{
1264 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
1265
1266 if (smmu_domain->tlb_ops)
1267 smmu_domain->tlb_ops->tlb_sync(smmu_domain);
1268}
1269
1262static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain, 1270static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
1263 dma_addr_t iova) 1271 dma_addr_t iova)
1264{ 1272{
@@ -1562,6 +1570,8 @@ static struct iommu_ops arm_smmu_ops = {
1562 .map = arm_smmu_map, 1570 .map = arm_smmu_map,
1563 .unmap = arm_smmu_unmap, 1571 .unmap = arm_smmu_unmap,
1564 .map_sg = default_iommu_map_sg, 1572 .map_sg = default_iommu_map_sg,
1573 .flush_iotlb_all = arm_smmu_iotlb_sync,
1574 .iotlb_sync = arm_smmu_iotlb_sync,
1565 .iova_to_phys = arm_smmu_iova_to_phys, 1575 .iova_to_phys = arm_smmu_iova_to_phys,
1566 .add_device = arm_smmu_add_device, 1576 .add_device = arm_smmu_add_device,
1567 .remove_device = arm_smmu_remove_device, 1577 .remove_device = arm_smmu_remove_device,
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index e8018a308868..51e5c43caed1 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -609,7 +609,6 @@ static int __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
609static int arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, 609static int arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
610 size_t size) 610 size_t size)
611{ 611{
612 size_t unmapped;
613 struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); 612 struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
614 arm_lpae_iopte *ptep = data->pgd; 613 arm_lpae_iopte *ptep = data->pgd;
615 int lvl = ARM_LPAE_START_LVL(data); 614 int lvl = ARM_LPAE_START_LVL(data);
@@ -617,11 +616,7 @@ static int arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
617 if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias))) 616 if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias)))
618 return 0; 617 return 0;
619 618
620 unmapped = __arm_lpae_unmap(data, iova, size, lvl, ptep); 619 return __arm_lpae_unmap(data, iova, size, lvl, ptep);
621 if (unmapped)
622 io_pgtable_tlb_sync(&data->iop);
623
624 return unmapped;
625} 620}
626 621
627static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops, 622static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 195d6e93ac71..af8140054273 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -619,6 +619,14 @@ static size_t ipmmu_unmap(struct iommu_domain *io_domain, unsigned long iova,
619 return domain->iop->unmap(domain->iop, iova, size); 619 return domain->iop->unmap(domain->iop, iova, size);
620} 620}
621 621
622static void ipmmu_iotlb_sync(struct iommu_domain *io_domain)
623{
624 struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
625
626 if (domain->mmu)
627 ipmmu_tlb_flush_all(domain);
628}
629
622static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain, 630static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain,
623 dma_addr_t iova) 631 dma_addr_t iova)
624{ 632{
@@ -876,6 +884,8 @@ static const struct iommu_ops ipmmu_ops = {
876 .detach_dev = ipmmu_detach_device, 884 .detach_dev = ipmmu_detach_device,
877 .map = ipmmu_map, 885 .map = ipmmu_map,
878 .unmap = ipmmu_unmap, 886 .unmap = ipmmu_unmap,
887 .flush_iotlb_all = ipmmu_iotlb_sync,
888 .iotlb_sync = ipmmu_iotlb_sync,
879 .map_sg = default_iommu_map_sg, 889 .map_sg = default_iommu_map_sg,
880 .iova_to_phys = ipmmu_iova_to_phys, 890 .iova_to_phys = ipmmu_iova_to_phys,
881 .add_device = ipmmu_add_device_dma, 891 .add_device = ipmmu_add_device_dma,