Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv
On Mon, 2013-07-08 at 17:31 +1000, Alexey Kardashevskiy wrote: > btw is phys_addr_t correct here? Yes. Cheers, Ben. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv
On 07/08/2013 05:20 PM, Benjamin Herrenschmidt wrote: > On Mon, 2013-07-08 at 14:44 +1000, Alexey Kardashevskiy wrote: > >> diff --git a/arch/powerpc/platforms/powernv/pci.h >> b/arch/powerpc/platforms/powernv/pci.h >> index 25d76c4..7ea82c1 100644 >> --- a/arch/powerpc/platforms/powernv/pci.h >> +++ b/arch/powerpc/platforms/powernv/pci.h >> @@ -52,6 +52,7 @@ struct pnv_ioda_pe { >> int tce32_seg; >> int tce32_segcount; >> struct iommu_table tce32_table; >> +phys_addr_t it_index_rm; > > Please > > The fact that we hijack the it_index field of the iommu table > for the virtual address is bad enough, but really don't need > to perpetuate this :-) > > Call the field something decent such as "tce_inval_reg_phys" Yes we can. I just find it veeery attractive when I can grep "\http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv
On Mon, 2013-07-08 at 14:44 +1000, Alexey Kardashevskiy wrote: > diff --git a/arch/powerpc/platforms/powernv/pci.h > b/arch/powerpc/platforms/powernv/pci.h > index 25d76c4..7ea82c1 100644 > --- a/arch/powerpc/platforms/powernv/pci.h > +++ b/arch/powerpc/platforms/powernv/pci.h > @@ -52,6 +52,7 @@ struct pnv_ioda_pe { > int tce32_seg; > int tce32_segcount; > struct iommu_table tce32_table; > + phys_addr_t it_index_rm; Please The fact that we hijack the it_index field of the iommu table for the virtual address is bad enough, but really don't need to perpetuate this :-) Call the field something decent such as "tce_inval_reg_phys" Cheers, Ben. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv
On Mon, 2013-07-08 at 14:44 +1000, Alexey Kardashevskiy wrote: diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 25d76c4..7ea82c1 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -52,6 +52,7 @@ struct pnv_ioda_pe { int tce32_seg; int tce32_segcount; struct iommu_table tce32_table; + phys_addr_t it_index_rm; Please The fact that we hijack the it_index field of the iommu table for the virtual address is bad enough, but really don't need to perpetuate this :-) Call the field something decent such as tce_inval_reg_phys Cheers, Ben. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv
On 07/08/2013 05:20 PM, Benjamin Herrenschmidt wrote: On Mon, 2013-07-08 at 14:44 +1000, Alexey Kardashevskiy wrote: diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 25d76c4..7ea82c1 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -52,6 +52,7 @@ struct pnv_ioda_pe { int tce32_seg; int tce32_segcount; struct iommu_table tce32_table; +phys_addr_t it_index_rm; Please The fact that we hijack the it_index field of the iommu table for the virtual address is bad enough, but really don't need to perpetuate this :-) Call the field something decent such as tce_inval_reg_phys Yes we can. I just find it veeery attractive when I can grep \it_ and get all users of iommu_table. btw is phys_addr_t correct here? -- Alexey -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv
On Mon, 2013-07-08 at 17:31 +1000, Alexey Kardashevskiy wrote: btw is phys_addr_t correct here? Yes. Cheers, Ben. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] powerpc: add real mode support for dma operations on powernv
The existing TCE machine calls (tce_build and tce_free) only support virtual mode as they call __raw_writeq for TCE invalidation what fails in real mode. This introduces tce_build_rm and tce_free_rm real mode versions which do mostly the same but use "Store Doubleword Caching Inhibited Indexed" instruction for TCE invalidation. This new feature is going to be utilized by real mode support of VFIO. Signed-off-by: Alexey Kardashevskiy --- Changes: 2013/08/07: * tested on p7ioc and fixed a bug with realmode addresses Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/include/asm/machdep.h| 12 + arch/powerpc/platforms/powernv/pci-ioda.c | 43 ++- arch/powerpc/platforms/powernv/pci.c | 38 ++- arch/powerpc/platforms/powernv/pci.h | 3 ++- 4 files changed, 77 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 92386fc..0c19eef 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -75,6 +75,18 @@ struct machdep_calls { long index); void(*tce_flush)(struct iommu_table *tbl); + /* _rm versions are for real mode use only */ + int (*tce_build_rm)(struct iommu_table *tbl, +long index, +long npages, +unsigned long uaddr, +enum dma_data_direction direction, +struct dma_attrs *attrs); + void(*tce_free_rm)(struct iommu_table *tbl, + long index, + long npages); + void(*tce_flush_rm)(struct iommu_table *tbl); + void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size, unsigned long flags, void *caller); void(*iounmap)(volatile void __iomem *token); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index d200594..8a70003 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -68,6 +68,12 @@ define_pe_printk_level(pe_err, KERN_ERR); define_pe_printk_level(pe_warn, KERN_WARNING); define_pe_printk_level(pe_info, KERN_INFO); +static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr) +{ + __asm__ __volatile__("stdcix %0,0,%1" + : : "r" (val), "r" (paddr) : "memory"); +} + static int pnv_ioda_alloc_pe(struct pnv_phb *phb) { unsigned long pe; @@ -452,10 +458,13 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) } } -static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, -u64 *startp, u64 *endp) +static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe, +struct iommu_table *tbl, +u64 *startp, u64 *endp, bool rm) { - u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; + u64 __iomem *invalidate = rm? + (u64 __iomem *)pe->it_index_rm: + (u64 __iomem *)tbl->it_index; unsigned long start, end, inc; start = __pa(startp); @@ -482,7 +491,10 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, mb(); /* Ensure above stores are visible */ while (start <= end) { -__raw_writeq(start, invalidate); + if (rm) + __raw_rm_writeq(start, invalidate); + else + __raw_writeq(start, invalidate); start += inc; } @@ -494,10 +506,12 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe, struct iommu_table *tbl, -u64 *startp, u64 *endp) +u64 *startp, u64 *endp, bool rm) { unsigned long start, end, inc; - u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; + u64 __iomem *invalidate = rm? + (u64 __iomem *)pe->it_index_rm: + (u64 __iomem *)tbl->it_index; /* We'll invalidate DMA address in PE scope */ start = 0x2ul << 60; @@ -513,22 +527,25 @@ static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe, mb(); while (start <= end) { - __raw_writeq(start, invalidate); + if (rm) + __raw_rm_writeq(start, invalidate); + else + __raw_writeq(start, invalidate); start += inc; } } void
[PATCH v2] powerpc: add real mode support for dma operations on powernv
The existing TCE machine calls (tce_build and tce_free) only support virtual mode as they call __raw_writeq for TCE invalidation what fails in real mode. This introduces tce_build_rm and tce_free_rm real mode versions which do mostly the same but use Store Doubleword Caching Inhibited Indexed instruction for TCE invalidation. This new feature is going to be utilized by real mode support of VFIO. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Changes: 2013/08/07: * tested on p7ioc and fixed a bug with realmode addresses Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- arch/powerpc/include/asm/machdep.h| 12 + arch/powerpc/platforms/powernv/pci-ioda.c | 43 ++- arch/powerpc/platforms/powernv/pci.c | 38 ++- arch/powerpc/platforms/powernv/pci.h | 3 ++- 4 files changed, 77 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 92386fc..0c19eef 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -75,6 +75,18 @@ struct machdep_calls { long index); void(*tce_flush)(struct iommu_table *tbl); + /* _rm versions are for real mode use only */ + int (*tce_build_rm)(struct iommu_table *tbl, +long index, +long npages, +unsigned long uaddr, +enum dma_data_direction direction, +struct dma_attrs *attrs); + void(*tce_free_rm)(struct iommu_table *tbl, + long index, + long npages); + void(*tce_flush_rm)(struct iommu_table *tbl); + void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size, unsigned long flags, void *caller); void(*iounmap)(volatile void __iomem *token); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index d200594..8a70003 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -68,6 +68,12 @@ define_pe_printk_level(pe_err, KERN_ERR); define_pe_printk_level(pe_warn, KERN_WARNING); define_pe_printk_level(pe_info, KERN_INFO); +static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr) +{ + __asm__ __volatile__(stdcix %0,0,%1 + : : r (val), r (paddr) : memory); +} + static int pnv_ioda_alloc_pe(struct pnv_phb *phb) { unsigned long pe; @@ -452,10 +458,13 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) } } -static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, -u64 *startp, u64 *endp) +static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe, +struct iommu_table *tbl, +u64 *startp, u64 *endp, bool rm) { - u64 __iomem *invalidate = (u64 __iomem *)tbl-it_index; + u64 __iomem *invalidate = rm? + (u64 __iomem *)pe-it_index_rm: + (u64 __iomem *)tbl-it_index; unsigned long start, end, inc; start = __pa(startp); @@ -482,7 +491,10 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, mb(); /* Ensure above stores are visible */ while (start = end) { -__raw_writeq(start, invalidate); + if (rm) + __raw_rm_writeq(start, invalidate); + else + __raw_writeq(start, invalidate); start += inc; } @@ -494,10 +506,12 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe, struct iommu_table *tbl, -u64 *startp, u64 *endp) +u64 *startp, u64 *endp, bool rm) { unsigned long start, end, inc; - u64 __iomem *invalidate = (u64 __iomem *)tbl-it_index; + u64 __iomem *invalidate = rm? + (u64 __iomem *)pe-it_index_rm: + (u64 __iomem *)tbl-it_index; /* We'll invalidate DMA address in PE scope */ start = 0x2ul 60; @@ -513,22 +527,25 @@ static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe, mb(); while (start = end) { - __raw_writeq(start, invalidate); + if (rm) + __raw_rm_writeq(start, invalidate); + else + __raw_writeq(start, invalidate); start += inc; } } void