On Thu, 2014-07-24 at 18:48 +1000, Alexey Kardashevskiy wrote: > The tce_build/tce_build_rm callbacks are used to implement H_PUT_TCE/etc > hypercalls. The PAPR spec does not allow to fail if the TCE is not empty. > However we cannot just overwrite the existing TCE value with the new one > as we still have to do page counting. > > This adds an optional @old_tces return parameter. If it is not NULL, > it must point to an array of @npages size where the callbacks will > store old TCE values. Since tce_build receives virtual addresses, > the old_tces array will contain virtual addresses as well. > > As this patch is mechanical, no change in behaviour is expected.
You missed a few iommu's in the conversion ... pasemi, cell, ... Ben. > Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> > Reviewed-by: Gavin Shan <gws...@linux.vnet.ibm.com> > --- > arch/powerpc/include/asm/machdep.h | 2 ++ > arch/powerpc/kernel/iommu.c | 8 +++++--- > arch/powerpc/platforms/powernv/pci.c | 13 ++++++++----- > arch/powerpc/platforms/pseries/iommu.c | 7 +++++-- > arch/powerpc/sysdev/dart_iommu.c | 1 + > 5 files changed, 21 insertions(+), 10 deletions(-) > > diff --git a/arch/powerpc/include/asm/machdep.h > b/arch/powerpc/include/asm/machdep.h > index f92b0b5..f11596c 100644 > --- a/arch/powerpc/include/asm/machdep.h > +++ b/arch/powerpc/include/asm/machdep.h > @@ -69,6 +69,7 @@ struct machdep_calls { > long index, > long npages, > unsigned long uaddr, > + unsigned long *old_tces, > enum dma_data_direction direction, > struct dma_attrs *attrs); > void (*tce_free)(struct iommu_table *tbl, > @@ -83,6 +84,7 @@ struct machdep_calls { > long index, > long npages, > unsigned long uaddr, > + long *old_tces, > enum dma_data_direction direction, > struct dma_attrs *attrs); > void (*tce_free_rm)(struct iommu_table *tbl, > diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c > index 5af2319..ccf7510 100644 > --- a/arch/powerpc/kernel/iommu.c > +++ b/arch/powerpc/kernel/iommu.c > @@ -324,7 +324,8 @@ static dma_addr_t iommu_alloc(struct device *dev, struct > iommu_table *tbl, > /* Put the TCEs in the HW table */ > build_fail = ppc_md.tce_build(tbl, entry, npages, > (unsigned long)page & > - IOMMU_PAGE_MASK(tbl), direction, attrs); > + IOMMU_PAGE_MASK(tbl), NULL, direction, > + attrs); > > /* ppc_md.tce_build() only returns non-zero for transient errors. > * Clean up the table bitmap in this case and return > @@ -497,7 +498,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table > *tbl, > /* Insert into HW table */ > build_fail = ppc_md.tce_build(tbl, entry, npages, > vaddr & IOMMU_PAGE_MASK(tbl), > - direction, attrs); > + NULL, direction, attrs); > if(unlikely(build_fail)) > goto failure; > > @@ -1059,7 +1060,8 @@ int iommu_tce_build(struct iommu_table *tbl, unsigned > long entry, > oldtce = ppc_md.tce_get(tbl, entry); > /* Add new entry if it is not busy */ > if (!(oldtce & (TCE_PCI_WRITE | TCE_PCI_READ))) > - ret = ppc_md.tce_build(tbl, entry, 1, hwaddr, direction, NULL); > + ret = ppc_md.tce_build(tbl, entry, 1, hwaddr, NULL, > + direction, NULL); > > spin_unlock(&(pool->lock)); > > diff --git a/arch/powerpc/platforms/powernv/pci.c > b/arch/powerpc/platforms/powernv/pci.c > index cc54e3b..4b764c2 100644 > --- a/arch/powerpc/platforms/powernv/pci.c > +++ b/arch/powerpc/platforms/powernv/pci.c > @@ -572,7 +572,8 @@ static void pnv_tce_invalidate(struct iommu_table *tbl, > __be64 *startp, > } > > static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, > - unsigned long uaddr, enum dma_data_direction direction, > + unsigned long uaddr, unsigned long *old_tces, > + enum dma_data_direction direction, > struct dma_attrs *attrs, bool rm) > { > u64 proto_tce; > @@ -597,12 +598,12 @@ static int pnv_tce_build(struct iommu_table *tbl, long > index, long npages, > } > > static int pnv_tce_build_vm(struct iommu_table *tbl, long index, long npages, > - unsigned long uaddr, > + unsigned long uaddr, unsigned long *old_tces, > enum dma_data_direction direction, > struct dma_attrs *attrs) > { > - return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs, > - false); > + return pnv_tce_build(tbl, index, npages, uaddr, old_tces, direction, > + attrs, false); > } > > static void pnv_tce_free(struct iommu_table *tbl, long index, long npages, > @@ -630,10 +631,12 @@ static unsigned long pnv_tce_get(struct iommu_table > *tbl, long index) > > static int pnv_tce_build_rm(struct iommu_table *tbl, long index, long npages, > unsigned long uaddr, > + long *old_tces, > enum dma_data_direction direction, > struct dma_attrs *attrs) > { > - return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs, true); > + return pnv_tce_build(tbl, index, npages, uaddr, old_tces, direction, > + attrs, true); > } > > static void pnv_tce_free_rm(struct iommu_table *tbl, long index, long npages) > diff --git a/arch/powerpc/platforms/pseries/iommu.c > b/arch/powerpc/platforms/pseries/iommu.c > index a047754..6c70b7c 100644 > --- a/arch/powerpc/platforms/pseries/iommu.c > +++ b/arch/powerpc/platforms/pseries/iommu.c > @@ -82,6 +82,7 @@ static void tce_invalidate_pSeries_sw(struct iommu_table > *tbl, > > static int tce_build_pSeries(struct iommu_table *tbl, long index, > long npages, unsigned long uaddr, > + unsigned long *old_tces, > enum dma_data_direction direction, > struct dma_attrs *attrs) > { > @@ -138,6 +139,7 @@ static void tce_freemulti_pSeriesLP(struct iommu_table*, > long, long); > > static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, > long npages, unsigned long uaddr, > + unsigned long *old_tces, > enum dma_data_direction direction, > struct dma_attrs *attrs) > { > @@ -181,6 +183,7 @@ static DEFINE_PER_CPU(__be64 *, tce_page); > > static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, > long npages, unsigned long uaddr, > + unsigned long *old_tces, > enum dma_data_direction direction, > struct dma_attrs *attrs) > { > @@ -195,7 +198,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table > *tbl, long tcenum, > > if (npages == 1) { > return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, > - direction, attrs); > + old_tces, direction, attrs); > } > > local_irq_save(flags); /* to protect tcep and the page behind it */ > @@ -211,7 +214,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table > *tbl, long tcenum, > if (!tcep) { > local_irq_restore(flags); > return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, > - direction, attrs); > + old_tces, direction, attrs); > } > __get_cpu_var(tce_page) = tcep; > } > diff --git a/arch/powerpc/sysdev/dart_iommu.c > b/arch/powerpc/sysdev/dart_iommu.c > index 9e5353f..0d3cf7c 100644 > --- a/arch/powerpc/sysdev/dart_iommu.c > +++ b/arch/powerpc/sysdev/dart_iommu.c > @@ -162,6 +162,7 @@ static void dart_flush(struct iommu_table *tbl) > > static int dart_build(struct iommu_table *tbl, long index, > long npages, unsigned long uaddr, > + unsigned long *old_tces, > enum dma_data_direction direction, > struct dma_attrs *attrs) > { _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev