aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/pci_sun4v.c
diff options
context:
space:
mode:
authorTushar Dave <tushar.n.dave@oracle.com>2016-10-28 13:12:41 -0400
committerDavid S. Miller <davem@davemloft.net>2016-11-18 14:16:59 -0500
commitf0248c1524fae654e9746e6843b9657fb3917387 (patch)
tree5dafe1d2017a8d84a14c6b7b603344b5ea8e2e52 /arch/sparc/kernel/pci_sun4v.c
parentc88c545bf3202ca2cdb45df93eb40e3bcdbb3742 (diff)
sparc64: Add ATU (new IOMMU) support
ATU (Address Translation Unit) is a new IOMMU in SPARC supported with Hypervisor IOMMU v2 APIs. Current SPARC IOMMU supports only 32bit address ranges and one TSB per PCIe root complex that has a 2GB per root complex DVMA space limit. The limit has become a scalability bottleneck nowadays that a typical 10G/40G NIC can consume 300MB-500MB DVMA space per instance. When DVMA resource is exhausted, devices will not be usable since the driver can't allocate DVMA. ATU removes bottleneck by allowing guest os to create IOTSB of size 32G (or more) with 64bit address ranges available in ATU HW. 32G is more than enough DVMA space to be shared by all PCIe devices under root complex contrast to 2G space provided by legacy IOMMU. ATU allows PCIe devices to use 64bit DMA addressing. Devices which choose to use 32bit DMA mask will continue to work with the existing legacy IOMMU. Signed-off-by: Tushar Dave <tushar.n.dave@oracle.com> Reviewed-by: chris hyser <chris.hyser@oracle.com> Acked-by: Sowmini Varadhan <sowmini.varadhan@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/pci_sun4v.c')
-rw-r--r--arch/sparc/kernel/pci_sun4v.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index db57d8acdc01..2afb86c73da9 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -44,6 +44,9 @@ static struct vpci_version vpci_versions[] = {
44 { .major = 1, .minor = 1 }, 44 { .major = 1, .minor = 1 },
45}; 45};
46 46
47static unsigned long vatu_major = 1;
48static unsigned long vatu_minor = 1;
49
47#define PGLIST_NENTS (PAGE_SIZE / sizeof(u64)) 50#define PGLIST_NENTS (PAGE_SIZE / sizeof(u64))
48 51
49struct iommu_batch { 52struct iommu_batch {
@@ -581,6 +584,107 @@ static unsigned long probe_existing_entries(struct pci_pbm_info *pbm,
581 return cnt; 584 return cnt;
582} 585}
583 586
587static int pci_sun4v_atu_alloc_iotsb(struct pci_pbm_info *pbm)
588{
589 struct atu *atu = pbm->iommu->atu;
590 struct atu_iotsb *iotsb;
591 void *table;
592 u64 table_size;
593 u64 iotsb_num;
594 unsigned long order;
595 unsigned long err;
596
597 iotsb = kzalloc(sizeof(*iotsb), GFP_KERNEL);
598 if (!iotsb) {
599 err = -ENOMEM;
600 goto out_err;
601 }
602 atu->iotsb = iotsb;
603
604 /* calculate size of IOTSB */
605 table_size = (atu->size / IO_PAGE_SIZE) * 8;
606 order = get_order(table_size);
607 table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
608 if (!table) {
609 err = -ENOMEM;
610 goto table_failed;
611 }
612 iotsb->table = table;
613 iotsb->ra = __pa(table);
614 iotsb->dvma_size = atu->size;
615 iotsb->dvma_base = atu->base;
616 iotsb->table_size = table_size;
617 iotsb->page_size = IO_PAGE_SIZE;
618
619 /* configure and register IOTSB with HV */
620 err = pci_sun4v_iotsb_conf(pbm->devhandle,
621 iotsb->ra,
622 iotsb->table_size,
623 iotsb->page_size,
624 iotsb->dvma_base,
625 &iotsb_num);
626 if (err) {
627 pr_err(PFX "pci_iotsb_conf failed error: %ld\n", err);
628 goto iotsb_conf_failed;
629 }
630 iotsb->iotsb_num = iotsb_num;
631
632 return 0;
633
634iotsb_conf_failed:
635 free_pages((unsigned long)table, order);
636table_failed:
637 kfree(iotsb);
638out_err:
639 return err;
640}
641
642static int pci_sun4v_atu_init(struct pci_pbm_info *pbm)
643{
644 struct atu *atu = pbm->iommu->atu;
645 unsigned long err;
646 const u64 *ranges;
647 const u32 *page_size;
648 int len;
649
650 ranges = of_get_property(pbm->op->dev.of_node, "iommu-address-ranges",
651 &len);
652 if (!ranges) {
653 pr_err(PFX "No iommu-address-ranges\n");
654 return -EINVAL;
655 }
656
657 page_size = of_get_property(pbm->op->dev.of_node, "iommu-pagesizes",
658 NULL);
659 if (!page_size) {
660 pr_err(PFX "No iommu-pagesizes\n");
661 return -EINVAL;
662 }
663
664 /* There are 4 iommu-address-ranges supported. Each range is pair of
665 * {base, size}. The ranges[0] and ranges[1] are 32bit address space
666 * while ranges[2] and ranges[3] are 64bit space. We want to use 64bit
667 * address ranges to support 64bit addressing. Because 'size' for
668 * address ranges[2] and ranges[3] are same we can select either of
669 * ranges[2] or ranges[3] for mapping. However due to 'size' is too
670 * large for OS to allocate IOTSB we are using fix size 32G
671 * (ATU_64_SPACE_SIZE) which is more than enough for all PCIe devices
672 * to share.
673 */
674 atu->ranges = (struct atu_ranges *)ranges;
675 atu->base = atu->ranges[3].base;
676 atu->size = ATU_64_SPACE_SIZE;
677
678 /* Create IOTSB */
679 err = pci_sun4v_atu_alloc_iotsb(pbm);
680 if (err) {
681 pr_err(PFX "Error creating ATU IOTSB\n");
682 return err;
683 }
684
685 return 0;
686}
687
584static int pci_sun4v_iommu_init(struct pci_pbm_info *pbm) 688static int pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
585{ 689{
586 static const u32 vdma_default[] = { 0x80000000, 0x80000000 }; 690 static const u32 vdma_default[] = { 0x80000000, 0x80000000 };
@@ -918,6 +1022,18 @@ static int pci_sun4v_pbm_init(struct pci_pbm_info *pbm,
918 1022
919 pci_sun4v_scan_bus(pbm, &op->dev); 1023 pci_sun4v_scan_bus(pbm, &op->dev);
920 1024
1025 /* if atu_init fails its not complete failure.
1026 * we can still continue using legacy iommu.
1027 */
1028 if (pbm->iommu->atu) {
1029 err = pci_sun4v_atu_init(pbm);
1030 if (err) {
1031 kfree(pbm->iommu->atu);
1032 pbm->iommu->atu = NULL;
1033 pr_err(PFX "ATU init failed, err=%d\n", err);
1034 }
1035 }
1036
921 pbm->next = pci_pbm_root; 1037 pbm->next = pci_pbm_root;
922 pci_pbm_root = pbm; 1038 pci_pbm_root = pbm;
923 1039
@@ -931,8 +1047,10 @@ static int pci_sun4v_probe(struct platform_device *op)
931 struct pci_pbm_info *pbm; 1047 struct pci_pbm_info *pbm;
932 struct device_node *dp; 1048 struct device_node *dp;
933 struct iommu *iommu; 1049 struct iommu *iommu;
1050 struct atu *atu;
934 u32 devhandle; 1051 u32 devhandle;
935 int i, err = -ENODEV; 1052 int i, err = -ENODEV;
1053 static bool hv_atu = true;
936 1054
937 dp = op->dev.of_node; 1055 dp = op->dev.of_node;
938 1056
@@ -954,6 +1072,19 @@ static int pci_sun4v_probe(struct platform_device *op)
954 pr_info(PFX "Registered hvapi major[%lu] minor[%lu]\n", 1072 pr_info(PFX "Registered hvapi major[%lu] minor[%lu]\n",
955 vpci_major, vpci_minor); 1073 vpci_major, vpci_minor);
956 1074
1075 err = sun4v_hvapi_register(HV_GRP_ATU, vatu_major, &vatu_minor);
1076 if (err) {
1077 /* don't return an error if we fail to register the
1078 * ATU group, but ATU hcalls won't be available.
1079 */
1080 hv_atu = false;
1081 pr_err(PFX "Could not register hvapi ATU err=%d\n",
1082 err);
1083 } else {
1084 pr_info(PFX "Registered hvapi ATU major[%lu] minor[%lu]\n",
1085 vatu_major, vatu_minor);
1086 }
1087
957 dma_ops = &sun4v_dma_ops; 1088 dma_ops = &sun4v_dma_ops;
958 } 1089 }
959 1090
@@ -991,6 +1122,14 @@ static int pci_sun4v_probe(struct platform_device *op)
991 } 1122 }
992 1123
993 pbm->iommu = iommu; 1124 pbm->iommu = iommu;
1125 iommu->atu = NULL;
1126 if (hv_atu) {
1127 atu = kzalloc(sizeof(*atu), GFP_KERNEL);
1128 if (!atu)
1129 pr_err(PFX "Could not allocate atu\n");
1130 else
1131 iommu->atu = atu;
1132 }
994 1133
995 err = pci_sun4v_pbm_init(pbm, op, devhandle); 1134 err = pci_sun4v_pbm_init(pbm, op, devhandle);
996 if (err) 1135 if (err)
@@ -1001,6 +1140,7 @@ static int pci_sun4v_probe(struct platform_device *op)
1001 return 0; 1140 return 0;
1002 1141
1003out_free_iommu: 1142out_free_iommu:
1143 kfree(iommu->atu);
1004 kfree(pbm->iommu); 1144 kfree(pbm->iommu);
1005 1145
1006out_free_controller: 1146out_free_controller: