Skip to content

Commit f431a8c

Browse files
ShivaprasadGBhatmpe
authored andcommitted
powerpc/iommu: Reimplement the iommu_table_group_ops for pSeries
PPC64 IOMMU API defines iommu_table_group_ops which handles DMA windows for PEs, their ownership transfer, create/set/unset the TCE tables for the Dynamic DMA wundows(DDW). VFIOS uses these APIs for support on POWER. The commit 9d67c94 ("powerpc/iommu: Add "borrowing" iommu_table_group_ops") implemented partial support for this API with "borrow" mechanism wherein the DMA windows if created already by the host driver, they would be available for VFIO to use. Also, it didn't have the support to control/modify the window size or the IO page size. The current patch implements all the necessary iommu_table_group_ops APIs there by avoiding the "borrrowing". So, just the way it is on the PowerNV platform, with this patch the iommu table group ownership is transferred to the VFIO PPC subdriver, the iommu table, DMA windows creation/deletion all driven through the APIs. The pSeries uses the query-pe-dma-window, create-pe-dma-window and reset-pe-dma-window RTAS calls for DMA window creation, deletion and reset to defaul. The RTAs calls do show some minor differences to the way things are to be handled on the pSeries which are listed below. * On pSeries, the default DMA window size is "fixed" cannot be custom sized as requested by the user. For non-SRIOV VFs, It is fixed at 2GB and for SRIOV VFs, its variable sized based on the capacity assigned to it during the VF assignment to the LPAR. So, for the default DMA window alone the size if requested less than tce32_size, the smaller size is enforced using the iommu table->it_size. * The DMA start address for 32-bit window is 0, and for the 64-bit window in case of PowerNV is hardcoded to TVE select (bit 59) at 512PiB offset. This address is returned at the time of create_table() API call (even before the window is created), the subsequent set_window() call actually opens the DMA window. On pSeries, the DMA start address for 32-bit window is known from the 'ibm,dma-window' DT property. However, the 64-bit window start address is not known until the create-pe-dma RTAS call is made. So, the create_table() which returns the DMA window start address actually opens the DMA window and returns the DMA start address as returned by the Hypervisor for the create-pe-dma RTAS call. * The reset-pe-dma RTAS call resets the DMA windows and restores the default DMA window, however it does not clear the TCE table entries if there are any. In case of ownership transfer from platform domain which used direct mapping, the patch chooses remove-pe-dma instead of reset-pe for the 64-bit window intentionally so that the clear_dma_window() is called. Other than the DMA window management changes mentioned above, the patch also brings back the userspace view for the single level TCE as it existed before commit 090bad3 ("powerpc/powernv: Add indirect levels to it_userspace") along with the relavent refactoring. Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/171923275958.1397.907964437142542242.stgit@linux.ibm.com
1 parent 35146ea commit f431a8c

File tree

4 files changed

+543
-98
lines changed

4 files changed

+543
-98
lines changed

arch/powerpc/include/asm/iommu.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ struct iommu_table_group_ops {
183183
long (*unset_window)(struct iommu_table_group *table_group,
184184
int num);
185185
/* Switch ownership from platform code to external user (e.g. VFIO) */
186-
long (*take_ownership)(struct iommu_table_group *table_group);
186+
long (*take_ownership)(struct iommu_table_group *table_group, struct device *dev);
187187
/* Switch ownership from external user (e.g. VFIO) back to core */
188-
void (*release_ownership)(struct iommu_table_group *table_group);
188+
void (*release_ownership)(struct iommu_table_group *table_group, struct device *dev);
189189
};
190190

191191
struct iommu_table_group_link {

arch/powerpc/kernel/iommu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain,
11711171
* The domain being set to PLATFORM from earlier
11721172
* BLOCKED. The table_group ownership has to be released.
11731173
*/
1174-
table_group->ops->release_ownership(table_group);
1174+
table_group->ops->release_ownership(table_group, dev);
11751175
iommu_group_put(grp);
11761176

11771177
return 0;
@@ -1199,7 +1199,7 @@ spapr_tce_blocked_iommu_attach_dev(struct iommu_domain *platform_domain,
11991199
* also sets the dma_api ops
12001200
*/
12011201
table_group = iommu_group_get_iommudata(grp);
1202-
ret = table_group->ops->take_ownership(table_group);
1202+
ret = table_group->ops->take_ownership(table_group, dev);
12031203
iommu_group_put(grp);
12041204

12051205
return ret;

arch/powerpc/platforms/powernv/pci-ioda.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,7 +1537,8 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
15371537
}
15381538
}
15391539

1540-
static long pnv_ioda2_take_ownership(struct iommu_table_group *table_group)
1540+
static long pnv_ioda2_take_ownership(struct iommu_table_group *table_group,
1541+
struct device *dev __maybe_unused)
15411542
{
15421543
struct pnv_ioda_pe *pe = container_of(table_group, struct pnv_ioda_pe,
15431544
table_group);
@@ -1562,7 +1563,8 @@ static long pnv_ioda2_take_ownership(struct iommu_table_group *table_group)
15621563
return 0;
15631564
}
15641565

1565-
static void pnv_ioda2_release_ownership(struct iommu_table_group *table_group)
1566+
static void pnv_ioda2_release_ownership(struct iommu_table_group *table_group,
1567+
struct device *dev __maybe_unused)
15661568
{
15671569
struct pnv_ioda_pe *pe = container_of(table_group, struct pnv_ioda_pe,
15681570
table_group);

0 commit comments

Comments
 (0)