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

powerpc/powernv/ioda2: Add TCE invalidation for all attached groups

The iommu_table struct keeps a list of IOMMU groups it is used for.
At the moment there is just a single group attached but further
patches will add TCE table sharing. When sharing is enabled, TCE cache
in each PE needs to be invalidated so does the patch.

This does not change pnv_pci_ioda1_tce_invalidate() as there is no plan
to enable TCE table sharing on PHBs older than IODA2.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Alexey Kardashevskiy and committed by
Michael Ellerman
e57080f1 5780fb04

+23 -12
+23 -12
arch/powerpc/platforms/powernv/pci-ioda.c
··· 24 24 #include <linux/msi.h> 25 25 #include <linux/memblock.h> 26 26 #include <linux/iommu.h> 27 + #include <linux/rculist.h> 27 28 28 29 #include <asm/sections.h> 29 30 #include <asm/io.h> ··· 1766 1765 __raw_writeq(cpu_to_be64(val), phb->ioda.tce_inval_reg); 1767 1766 } 1768 1767 1769 - static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl, 1770 - unsigned long index, unsigned long npages, bool rm) 1768 + static void pnv_pci_ioda2_do_tce_invalidate(unsigned pe_number, bool rm, 1769 + __be64 __iomem *invalidate, unsigned shift, 1770 + unsigned long index, unsigned long npages) 1771 1771 { 1772 - struct iommu_table_group_link *tgl = list_first_entry_or_null( 1773 - &tbl->it_group_list, struct iommu_table_group_link, 1774 - next); 1775 - struct pnv_ioda_pe *pe = container_of(tgl->table_group, 1776 - struct pnv_ioda_pe, table_group); 1777 1772 unsigned long start, end, inc; 1778 - __be64 __iomem *invalidate = rm ? 1779 - (__be64 __iomem *)pe->phb->ioda.tce_inval_reg_phys : 1780 - pe->phb->ioda.tce_inval_reg; 1781 - const unsigned shift = tbl->it_page_shift; 1782 1773 1783 1774 /* We'll invalidate DMA address in PE scope */ 1784 1775 start = 0x2ull << 60; 1785 - start |= (pe->pe_number & 0xFF); 1776 + start |= (pe_number & 0xFF); 1786 1777 end = start; 1787 1778 1788 1779 /* Figure out the start, end and step */ ··· 1789 1796 else 1790 1797 __raw_writeq(cpu_to_be64(start), invalidate); 1791 1798 start += inc; 1799 + } 1800 + } 1801 + 1802 + static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl, 1803 + unsigned long index, unsigned long npages, bool rm) 1804 + { 1805 + struct iommu_table_group_link *tgl; 1806 + 1807 + list_for_each_entry_rcu(tgl, &tbl->it_group_list, next) { 1808 + struct pnv_ioda_pe *pe = container_of(tgl->table_group, 1809 + struct pnv_ioda_pe, table_group); 1810 + __be64 __iomem *invalidate = rm ? 1811 + (__be64 __iomem *)pe->phb->ioda.tce_inval_reg_phys : 1812 + pe->phb->ioda.tce_inval_reg; 1813 + 1814 + pnv_pci_ioda2_do_tce_invalidate(pe->pe_number, rm, 1815 + invalidate, tbl->it_page_shift, 1816 + index, npages); 1792 1817 } 1793 1818 } 1794 1819