Re: [PATCH v2 04/13] powerpc/powernv: Convert/move set_bypass() callback to take_ownership()

2014-09-23 Thread Alex Williamson
On Tue, 2014-09-23 at 13:00 +1000, Alexey Kardashevskiy wrote:
 At the moment the iommu_table struct has a set_bypass() which enables/
 disables DMA bypass on IODA2 PHB. This is exposed to POWERPC IOMMU code
 which calls this callback when external IOMMU users such as VFIO are
 about to get over a PHB.
 
 Since the set_bypass() is not really an iommu_table function but PE's
 function, and we have an ops struct per IOMMU owner, let's move
 set_bypass() to the spapr_tce_iommu_ops struct.
 
 As arch/powerpc/kernel/iommu.c is more about POWERPC IOMMU tables and
 has very little to do with PEs, this moves take_ownership() calls to
 the VFIO SPAPR TCE driver.
 
 This renames set_bypass() to take_ownership() as it is not necessarily
 just enabling bypassing, it can be something else/more so let's give it
 a generic name. The bool parameter is inverted.
 
 Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
 Reviewed-by: Gavin Shan gws...@linux.vnet.ibm.com
 ---
  arch/powerpc/include/asm/iommu.h  |  1 -
  arch/powerpc/include/asm/tce.h|  2 ++
  arch/powerpc/kernel/iommu.c   | 12 
  arch/powerpc/platforms/powernv/pci-ioda.c | 20 
  drivers/vfio/vfio_iommu_spapr_tce.c   | 16 
  5 files changed, 30 insertions(+), 21 deletions(-)
 
 diff --git a/arch/powerpc/include/asm/iommu.h 
 b/arch/powerpc/include/asm/iommu.h
 index 84ee339..2b0b01d 100644
 --- a/arch/powerpc/include/asm/iommu.h
 +++ b/arch/powerpc/include/asm/iommu.h
 @@ -77,7 +77,6 @@ struct iommu_table {
  #ifdef CONFIG_IOMMU_API
   struct iommu_group *it_group;
  #endif
 - void (*set_bypass)(struct iommu_table *tbl, bool enable);
  };
  
  /* Pure 2^n version of get_order */
 diff --git a/arch/powerpc/include/asm/tce.h b/arch/powerpc/include/asm/tce.h
 index 9f159eb..e6355f9 100644
 --- a/arch/powerpc/include/asm/tce.h
 +++ b/arch/powerpc/include/asm/tce.h
 @@ -56,6 +56,8 @@ struct spapr_tce_iommu_ops {
   struct iommu_table *(*get_table)(
   struct spapr_tce_iommu_group *data,
   int num);
 + void (*take_ownership)(struct spapr_tce_iommu_group *data,
 + bool enable);

set is a better verb when using a bool to specify direction, imho.

This is pretty confusing now that we have

iommu_take_ownership()
data-ops-take_ownership(true)

iommu_release_ownership()
data-ops-take_ownership(false)

And there's zero comments here about what take_ownership is supposed to
provide, or get_table for that matter.

  };
  
  struct spapr_tce_iommu_group {
 diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
 index 1c5dae7..c2c8d9d 100644
 --- a/arch/powerpc/kernel/iommu.c
 +++ b/arch/powerpc/kernel/iommu.c
 @@ -1139,14 +1139,6 @@ int iommu_take_ownership(struct iommu_table *tbl)
   memset(tbl-it_map, 0xff, sz);
   iommu_clear_tces_and_put_pages(tbl, tbl-it_offset, tbl-it_size);
  
 - /*
 -  * Disable iommu bypass, otherwise the user can DMA to all of
 -  * our physical memory via the bypass window instead of just
 -  * the pages that has been explicitly mapped into the iommu
 -  */
 - if (tbl-set_bypass)
 - tbl-set_bypass(tbl, false);
 -
   return 0;
  }
  EXPORT_SYMBOL_GPL(iommu_take_ownership);
 @@ -1161,10 +1153,6 @@ void iommu_release_ownership(struct iommu_table *tbl)
   /* Restore bit#0 set by iommu_init_table() */
   if (tbl-it_offset == 0)
   set_bit(0, tbl-it_map);
 -
 - /* The kernel owns the device now, we can restore the iommu bypass */
 - if (tbl-set_bypass)
 - tbl-set_bypass(tbl, true);
  }
  EXPORT_SYMBOL_GPL(iommu_release_ownership);
  
 diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
 b/arch/powerpc/platforms/powernv/pci-ioda.c
 index 2d32a1c..8cb2f31 100644
 --- a/arch/powerpc/platforms/powernv/pci-ioda.c
 +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
 @@ -1105,10 +1105,8 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb 
 *phb,
   __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs));
  }
  
 -static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable)
 +static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable)
  {
 - struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe,
 -   tce32.table);
   uint16_t window_id = (pe-pe_number  1 ) + 1;
   int64_t rc;
  
 @@ -1136,7 +1134,7 @@ static void pnv_pci_ioda2_set_bypass(struct iommu_table 
 *tbl, bool enable)
* host side.
*/
   if (pe-pdev)
 - set_iommu_table_base(pe-pdev-dev, tbl);
 + set_iommu_table_base(pe-pdev-dev, pe-tce32.table);
   else
   pnv_ioda_setup_bus_dma(pe, pe-pbus, false);
   }
 @@ -1152,15 +1150,21 @@ static void pnv_pci_ioda2_setup_bypass_pe(struct 
 pnv_phb *phb,
   /* TVE #1 is selected 

[PATCH v2 04/13] powerpc/powernv: Convert/move set_bypass() callback to take_ownership()

2014-09-22 Thread Alexey Kardashevskiy
At the moment the iommu_table struct has a set_bypass() which enables/
disables DMA bypass on IODA2 PHB. This is exposed to POWERPC IOMMU code
which calls this callback when external IOMMU users such as VFIO are
about to get over a PHB.

Since the set_bypass() is not really an iommu_table function but PE's
function, and we have an ops struct per IOMMU owner, let's move
set_bypass() to the spapr_tce_iommu_ops struct.

As arch/powerpc/kernel/iommu.c is more about POWERPC IOMMU tables and
has very little to do with PEs, this moves take_ownership() calls to
the VFIO SPAPR TCE driver.

This renames set_bypass() to take_ownership() as it is not necessarily
just enabling bypassing, it can be something else/more so let's give it
a generic name. The bool parameter is inverted.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
Reviewed-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/iommu.h  |  1 -
 arch/powerpc/include/asm/tce.h|  2 ++
 arch/powerpc/kernel/iommu.c   | 12 
 arch/powerpc/platforms/powernv/pci-ioda.c | 20 
 drivers/vfio/vfio_iommu_spapr_tce.c   | 16 
 5 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 84ee339..2b0b01d 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -77,7 +77,6 @@ struct iommu_table {
 #ifdef CONFIG_IOMMU_API
struct iommu_group *it_group;
 #endif
-   void (*set_bypass)(struct iommu_table *tbl, bool enable);
 };
 
 /* Pure 2^n version of get_order */
diff --git a/arch/powerpc/include/asm/tce.h b/arch/powerpc/include/asm/tce.h
index 9f159eb..e6355f9 100644
--- a/arch/powerpc/include/asm/tce.h
+++ b/arch/powerpc/include/asm/tce.h
@@ -56,6 +56,8 @@ struct spapr_tce_iommu_ops {
struct iommu_table *(*get_table)(
struct spapr_tce_iommu_group *data,
int num);
+   void (*take_ownership)(struct spapr_tce_iommu_group *data,
+   bool enable);
 };
 
 struct spapr_tce_iommu_group {
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 1c5dae7..c2c8d9d 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1139,14 +1139,6 @@ int iommu_take_ownership(struct iommu_table *tbl)
memset(tbl-it_map, 0xff, sz);
iommu_clear_tces_and_put_pages(tbl, tbl-it_offset, tbl-it_size);
 
-   /*
-* Disable iommu bypass, otherwise the user can DMA to all of
-* our physical memory via the bypass window instead of just
-* the pages that has been explicitly mapped into the iommu
-*/
-   if (tbl-set_bypass)
-   tbl-set_bypass(tbl, false);
-
return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_take_ownership);
@@ -1161,10 +1153,6 @@ void iommu_release_ownership(struct iommu_table *tbl)
/* Restore bit#0 set by iommu_init_table() */
if (tbl-it_offset == 0)
set_bit(0, tbl-it_map);
-
-   /* The kernel owns the device now, we can restore the iommu bypass */
-   if (tbl-set_bypass)
-   tbl-set_bypass(tbl, true);
 }
 EXPORT_SYMBOL_GPL(iommu_release_ownership);
 
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 2d32a1c..8cb2f31 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1105,10 +1105,8 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb 
*phb,
__free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs));
 }
 
-static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable)
+static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable)
 {
-   struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe,
- tce32.table);
uint16_t window_id = (pe-pe_number  1 ) + 1;
int64_t rc;
 
@@ -1136,7 +1134,7 @@ static void pnv_pci_ioda2_set_bypass(struct iommu_table 
*tbl, bool enable)
 * host side.
 */
if (pe-pdev)
-   set_iommu_table_base(pe-pdev-dev, tbl);
+   set_iommu_table_base(pe-pdev-dev, pe-tce32.table);
else
pnv_ioda_setup_bus_dma(pe, pe-pbus, false);
}
@@ -1152,15 +1150,21 @@ static void pnv_pci_ioda2_setup_bypass_pe(struct 
pnv_phb *phb,
/* TVE #1 is selected by PCI address bit 59 */
pe-tce_bypass_base = 1ull  59;
 
-   /* Install set_bypass callback for VFIO */
-   pe-tce32.table.set_bypass = pnv_pci_ioda2_set_bypass;
-
/* Enable bypass by default */
-   pnv_pci_ioda2_set_bypass(pe-tce32.table, true);
+   pnv_pci_ioda2_set_bypass(pe, true);
+}
+
+static void pnv_ioda2_take_ownership(struct spapr_tce_iommu_group *data,
+bool