powerpc/spapr: vfio: Replace iommu_table with iommu_table_group
Modern IBM POWERPC systems support multiple (currently two) TCE tables per IOMMU group (a.k.a. PE). This adds a iommu_table_group container for TCE tables. Right now just one table is supported. This defines iommu_table_group struct which stores pointers to iommu_group and iommu_table(s). This replaces iommu_table with iommu_table_group where iommu_table was used to identify a group: - iommu_register_group(); - iommudata of generic iommu_group; This removes @data from iommu_table as it_table_group provides same access to pnv_ioda_pe. For IODA, instead of embedding iommu_table, the new iommu_table_group keeps pointers to those. The iommu_table structs are allocated dynamically. For P5IOC2, both iommu_table_group and iommu_table are embedded into PE struct. As there is no EEH and SRIOV support for P5IOC2, iommu_free_table() should not be called on iommu_table struct pointers so we can keep it embedded in pnv_phb::p5ioc2. For pSeries, this replaces multiple calls of kzalloc_node() with a new iommu_pseries_alloc_group() helper and stores the table group struct pointer into the pci_dn struct. For release, a iommu_table_free_group() helper is added. This moves iommu_table struct allocation from SR-IOV code to the generic DMA initialization code in pnv_pci_ioda_setup_dma_pe and pnv_pci_ioda2_setup_dma_pe as this is where DMA is actually initialized. This change is here because those lines had to be changed anyway. This should cause no behavioural change. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> [aw: for the vfio related changes] Acked-by: Alex Williamson <alex.williamson@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:

committed by
Michael Ellerman

parent
decbda2572
commit
b348aa6529
@@ -889,11 +889,12 @@ EXPORT_SYMBOL_GPL(iommu_direction_to_tce_perm);
|
||||
*/
|
||||
static void group_release(void *iommu_data)
|
||||
{
|
||||
struct iommu_table *tbl = iommu_data;
|
||||
tbl->it_group = NULL;
|
||||
struct iommu_table_group *table_group = iommu_data;
|
||||
|
||||
table_group->group = NULL;
|
||||
}
|
||||
|
||||
void iommu_register_group(struct iommu_table *tbl,
|
||||
void iommu_register_group(struct iommu_table_group *table_group,
|
||||
int pci_domain_number, unsigned long pe_num)
|
||||
{
|
||||
struct iommu_group *grp;
|
||||
@@ -905,8 +906,8 @@ void iommu_register_group(struct iommu_table *tbl,
|
||||
PTR_ERR(grp));
|
||||
return;
|
||||
}
|
||||
tbl->it_group = grp;
|
||||
iommu_group_set_iommudata(grp, tbl, group_release);
|
||||
table_group->group = grp;
|
||||
iommu_group_set_iommudata(grp, table_group, group_release);
|
||||
name = kasprintf(GFP_KERNEL, "domain%d-pe%lx",
|
||||
pci_domain_number, pe_num);
|
||||
if (!name)
|
||||
@@ -1094,7 +1095,7 @@ int iommu_add_device(struct device *dev)
|
||||
}
|
||||
|
||||
tbl = get_iommu_table_base(dev);
|
||||
if (!tbl || !tbl->it_group) {
|
||||
if (!tbl || !tbl->it_table_group || !tbl->it_table_group->group) {
|
||||
pr_debug("%s: Skipping device %s with no tbl\n",
|
||||
__func__, dev_name(dev));
|
||||
return 0;
|
||||
@@ -1102,7 +1103,7 @@ int iommu_add_device(struct device *dev)
|
||||
|
||||
pr_debug("%s: Adding %s to iommu group %d\n",
|
||||
__func__, dev_name(dev),
|
||||
iommu_group_id(tbl->it_group));
|
||||
iommu_group_id(tbl->it_table_group->group));
|
||||
|
||||
if (PAGE_SIZE < IOMMU_PAGE_SIZE(tbl)) {
|
||||
pr_err("%s: Invalid IOMMU page size %lx (%lx) on %s\n",
|
||||
@@ -1111,7 +1112,7 @@ int iommu_add_device(struct device *dev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return iommu_group_add_device(tbl->it_group, dev);
|
||||
return iommu_group_add_device(tbl->it_table_group->group, dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iommu_add_device);
|
||||
|
||||
|
Reference in New Issue
Block a user