Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PPC: POWERNV: move iommu_add_device earlier

The current implementation of IOMMU on sPAPR does not use iommu_ops
and therefore does not call IOMMU API's bus_set_iommu() which
1) sets iommu_ops for a bus
2) registers a bus notifier
Instead, PCI devices are added to IOMMU groups from
subsys_initcall_sync(tce_iommu_init) which does basically the same
thing without using iommu_ops callbacks.

However Freescale PAMU driver (https://lkml.org/lkml/2013/7/1/158)
implements iommu_ops and when tce_iommu_init is called, every PCI device
is already added to some group so there is a conflict.

This patch does 2 things:
1. removes the loop in which PCI devices were added to groups and
adds explicit iommu_add_device() calls to add devices as soon as they get
the iommu_table pointer assigned to them.
2. moves a bus notifier to powernv code in order to avoid conflict with
the notifier from Freescale driver.

iommu_add_device() and iommu_del_device() are public now.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Alexey Kardashevskiy and committed by
Benjamin Herrenschmidt
d905c5df 7e1ce5a4

+72 -53
+26
arch/powerpc/include/asm/iommu.h
··· 101 101 */ 102 102 extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, 103 103 int nid); 104 + #ifdef CONFIG_IOMMU_API 104 105 extern void iommu_register_group(struct iommu_table *tbl, 105 106 int pci_domain_number, unsigned long pe_num); 107 + extern int iommu_add_device(struct device *dev); 108 + extern void iommu_del_device(struct device *dev); 109 + #else 110 + static inline void iommu_register_group(struct iommu_table *tbl, 111 + int pci_domain_number, 112 + unsigned long pe_num) 113 + { 114 + } 115 + 116 + static inline int iommu_add_device(struct device *dev) 117 + { 118 + return 0; 119 + } 120 + 121 + static inline void iommu_del_device(struct device *dev) 122 + { 123 + } 124 + #endif /* !CONFIG_IOMMU_API */ 125 + 126 + static inline void set_iommu_table_base_and_group(struct device *dev, 127 + void *base) 128 + { 129 + set_iommu_table_base(dev, base); 130 + iommu_add_device(dev); 131 + } 106 132 107 133 extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, 108 134 struct scatterlist *sglist, int nelems,
+4 -44
arch/powerpc/kernel/iommu.c
··· 1105 1105 } 1106 1106 EXPORT_SYMBOL_GPL(iommu_release_ownership); 1107 1107 1108 - static int iommu_add_device(struct device *dev) 1108 + int iommu_add_device(struct device *dev) 1109 1109 { 1110 1110 struct iommu_table *tbl; 1111 1111 int ret = 0; ··· 1134 1134 1135 1135 return ret; 1136 1136 } 1137 + EXPORT_SYMBOL_GPL(iommu_add_device); 1137 1138 1138 - static void iommu_del_device(struct device *dev) 1139 + void iommu_del_device(struct device *dev) 1139 1140 { 1140 1141 iommu_group_remove_device(dev); 1141 1142 } 1142 - 1143 - static int iommu_bus_notifier(struct notifier_block *nb, 1144 - unsigned long action, void *data) 1145 - { 1146 - struct device *dev = data; 1147 - 1148 - switch (action) { 1149 - case BUS_NOTIFY_ADD_DEVICE: 1150 - return iommu_add_device(dev); 1151 - case BUS_NOTIFY_DEL_DEVICE: 1152 - iommu_del_device(dev); 1153 - return 0; 1154 - default: 1155 - return 0; 1156 - } 1157 - } 1158 - 1159 - static struct notifier_block tce_iommu_bus_nb = { 1160 - .notifier_call = iommu_bus_notifier, 1161 - }; 1162 - 1163 - static int __init tce_iommu_init(void) 1164 - { 1165 - struct pci_dev *pdev = NULL; 1166 - 1167 - BUILD_BUG_ON(PAGE_SIZE < IOMMU_PAGE_SIZE); 1168 - 1169 - for_each_pci_dev(pdev) 1170 - iommu_add_device(&pdev->dev); 1171 - 1172 - bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb); 1173 - return 0; 1174 - } 1175 - 1176 - subsys_initcall_sync(tce_iommu_init); 1177 - 1178 - #else 1179 - 1180 - void iommu_register_group(struct iommu_table *tbl, 1181 - int pci_domain_number, unsigned long pe_num) 1182 - { 1183 - } 1143 + EXPORT_SYMBOL_GPL(iommu_del_device); 1184 1144 1185 1145 #endif /* CONFIG_IOMMU_API */
+4 -4
arch/powerpc/platforms/powernv/pci-ioda.c
··· 460 460 return; 461 461 462 462 pe = &phb->ioda.pe_array[pdn->pe_number]; 463 - set_iommu_table_base(&pdev->dev, &pe->tce32_table); 463 + set_iommu_table_base_and_group(&pdev->dev, &pe->tce32_table); 464 464 } 465 465 466 466 static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) ··· 468 468 struct pci_dev *dev; 469 469 470 470 list_for_each_entry(dev, &bus->devices, bus_list) { 471 - set_iommu_table_base(&dev->dev, &pe->tce32_table); 471 + set_iommu_table_base_and_group(&dev->dev, &pe->tce32_table); 472 472 if (dev->subordinate) 473 473 pnv_ioda_setup_bus_dma(pe, dev->subordinate); 474 474 } ··· 644 644 iommu_register_group(tbl, pci_domain_nr(pe->pbus), pe->pe_number); 645 645 646 646 if (pe->pdev) 647 - set_iommu_table_base(&pe->pdev->dev, tbl); 647 + set_iommu_table_base_and_group(&pe->pdev->dev, tbl); 648 648 else 649 649 pnv_ioda_setup_bus_dma(pe, pe->pbus); 650 650 ··· 722 722 iommu_init_table(tbl, phb->hose->node); 723 723 724 724 if (pe->pdev) 725 - set_iommu_table_base(&pe->pdev->dev, tbl); 725 + set_iommu_table_base_and_group(&pe->pdev->dev, tbl); 726 726 else 727 727 pnv_ioda_setup_bus_dma(pe, pe->pbus); 728 728
+1 -1
arch/powerpc/platforms/powernv/pci-p5ioc2.c
··· 92 92 pci_domain_nr(phb->hose->bus), phb->opal_id); 93 93 } 94 94 95 - set_iommu_table_base(&pdev->dev, &phb->p5ioc2.iommu_table); 95 + set_iommu_table_base_and_group(&pdev->dev, &phb->p5ioc2.iommu_table); 96 96 } 97 97 98 98 static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
+32 -1
arch/powerpc/platforms/powernv/pci.c
··· 536 536 pdn->iommu_table = pnv_pci_setup_bml_iommu(hose); 537 537 if (!pdn->iommu_table) 538 538 return; 539 - set_iommu_table_base(&pdev->dev, pdn->iommu_table); 539 + set_iommu_table_base_and_group(&pdev->dev, pdn->iommu_table); 540 540 } 541 541 542 542 static void pnv_pci_dma_dev_setup(struct pci_dev *pdev) ··· 657 657 ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs; 658 658 #endif 659 659 } 660 + 661 + static int tce_iommu_bus_notifier(struct notifier_block *nb, 662 + unsigned long action, void *data) 663 + { 664 + struct device *dev = data; 665 + 666 + switch (action) { 667 + case BUS_NOTIFY_ADD_DEVICE: 668 + return iommu_add_device(dev); 669 + case BUS_NOTIFY_DEL_DEVICE: 670 + if (dev->iommu_group) 671 + iommu_del_device(dev); 672 + return 0; 673 + default: 674 + return 0; 675 + } 676 + } 677 + 678 + static struct notifier_block tce_iommu_bus_nb = { 679 + .notifier_call = tce_iommu_bus_notifier, 680 + }; 681 + 682 + static int __init tce_iommu_bus_notifier_init(void) 683 + { 684 + BUILD_BUG_ON(PAGE_SIZE < IOMMU_PAGE_SIZE); 685 + 686 + bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb); 687 + return 0; 688 + } 689 + 690 + subsys_initcall_sync(tce_iommu_bus_notifier_init);
+5 -3
arch/powerpc/platforms/pseries/iommu.c
··· 687 687 iommu_table_setparms(phb, dn, tbl); 688 688 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); 689 689 iommu_register_group(tbl, pci_domain_nr(phb->bus), 0); 690 - set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table); 690 + set_iommu_table_base_and_group(&dev->dev, 691 + PCI_DN(dn)->iommu_table); 691 692 return; 692 693 } 693 694 ··· 700 699 dn = dn->parent; 701 700 702 701 if (dn && PCI_DN(dn)) 703 - set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table); 702 + set_iommu_table_base_and_group(&dev->dev, 703 + PCI_DN(dn)->iommu_table); 704 704 else 705 705 printk(KERN_WARNING "iommu: Device %s has no iommu table\n", 706 706 pci_name(dev)); ··· 1195 1193 pr_debug(" found DMA window, table: %p\n", pci->iommu_table); 1196 1194 } 1197 1195 1198 - set_iommu_table_base(&dev->dev, pci->iommu_table); 1196 + set_iommu_table_base_and_group(&dev->dev, pci->iommu_table); 1199 1197 } 1200 1198 1201 1199 static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)