On 07/28/2014 11:18 AM, Benjamin Herrenschmidt wrote: > On Thu, 2014-07-24 at 18:48 +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. > > I disagree with the name change. take_ownership() is the right semantic > at the high level, but down to the actual table, it *is* about disabling > bypass.
It is still pnv_pci_ioda2_set_bypass() :-/ take_ownership() is a callback of PNV IOMMU group. s/take_ownership/set_bypass/ ? > >> 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 | 18 +++++++++++------- >> drivers/vfio/vfio_iommu_spapr_tce.c | 16 ++++++++++++++++ >> 5 files changed, 29 insertions(+), 20 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 8bfe98f..5ee4987 100644 >> --- a/arch/powerpc/include/asm/tce.h >> +++ b/arch/powerpc/include/asm/tce.h >> @@ -58,6 +58,8 @@ struct spapr_tce_iommu_ops { >> struct iommu_table *(*get_table)( >> struct spapr_tce_iommu_group *data, >> phys_addr_t addr); >> + 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 e203314..06984d5 100644 >> --- a/arch/powerpc/kernel/iommu.c >> +++ b/arch/powerpc/kernel/iommu.c >> @@ -1116,14 +1116,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); >> @@ -1138,10 +1130,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 495137b..f828c57 100644 >> --- a/arch/powerpc/platforms/powernv/pci-ioda.c >> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c >> @@ -709,10 +709,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; >> >> @@ -752,15 +750,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 enable) >> +{ >> + struct pnv_ioda_pe *pe = data->iommu_owner; >> + >> + pnv_pci_ioda2_set_bypass(pe, !enable); >> } >> >> static struct spapr_tce_iommu_ops pnv_pci_ioda2_ops = { >> .get_table = pnv_ioda1_iommu_get_table, >> + .take_ownership = pnv_ioda2_take_ownership, >> }; >> >> static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, >> diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c >> b/drivers/vfio/vfio_iommu_spapr_tce.c >> index 917c854..05b2f11 100644 >> --- a/drivers/vfio/vfio_iommu_spapr_tce.c >> +++ b/drivers/vfio/vfio_iommu_spapr_tce.c >> @@ -78,6 +78,13 @@ static long tce_iommu_account_memlimit(struct iommu_table >> *tbl, bool inc) >> return ret; >> } >> >> +static void tce_iommu_take_ownership_notify(struct spapr_tce_iommu_group >> *data, >> + bool enable) >> +{ >> + if (data && data->ops && data->ops->take_ownership) >> + data->ops->take_ownership(data, enable); >> +} >> + >> static int tce_iommu_enable(struct tce_container *container) >> { >> int ret = 0; >> @@ -386,6 +393,12 @@ static int tce_iommu_attach_group(void *iommu_data, >> ret = iommu_take_ownership(tbl); >> if (!ret) >> container->grp = iommu_group; >> + /* >> + * 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 >> + */ >> + tce_iommu_take_ownership_notify(data, true); >> } >> >> mutex_unlock(&container->lock); >> @@ -423,6 +436,9 @@ static void tce_iommu_detach_group(void *iommu_data, >> BUG_ON(!tbl); >> >> iommu_release_ownership(tbl); >> + >> + /* Kernel owns the device now, we can restore bypass */ >> + tce_iommu_take_ownership_notify(data, false); >> } >> mutex_unlock(&container->lock); >> } > > > _______________________________________________ > Linuxppc-dev mailing list > Linuxppc-dev@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/linuxppc-dev > -- Alexey _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev