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:
Alexey Kardashevskiy
2015-06-05 16:35:08 +10:00
committad av Michael Ellerman
förälder decbda2572
incheckning b348aa6529
8 ändrade filer med 152 tillägg och 92 borttagningar

Visa fil

@@ -190,10 +190,11 @@ static void tce_iommu_release(void *iommu_data)
{
struct tce_container *container = iommu_data;
WARN_ON(container->tbl && !container->tbl->it_group);
WARN_ON(container->tbl && !container->tbl->it_table_group->group);
if (container->tbl && container->tbl->it_group)
tce_iommu_detach_group(iommu_data, container->tbl->it_group);
if (container->tbl && container->tbl->it_table_group->group)
tce_iommu_detach_group(iommu_data,
container->tbl->it_table_group->group);
tce_iommu_disable(container);
mutex_destroy(&container->lock);
@@ -345,7 +346,7 @@ static long tce_iommu_ioctl(void *iommu_data,
if (!tbl)
return -ENXIO;
BUG_ON(!tbl->it_group);
BUG_ON(!tbl->it_table_group->group);
minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);
@@ -433,11 +434,12 @@ static long tce_iommu_ioctl(void *iommu_data,
mutex_unlock(&container->lock);
return 0;
case VFIO_EEH_PE_OP:
if (!container->tbl || !container->tbl->it_group)
if (!container->tbl || !container->tbl->it_table_group->group)
return -ENODEV;
return vfio_spapr_iommu_eeh_ioctl(container->tbl->it_group,
cmd, arg);
return vfio_spapr_iommu_eeh_ioctl(
container->tbl->it_table_group->group,
cmd, arg);
}
return -ENOTTY;
@@ -457,7 +459,8 @@ static int tce_iommu_attach_group(void *iommu_data,
iommu_group_id(iommu_group), iommu_group); */
if (container->tbl) {
pr_warn("tce_vfio: Only one group per IOMMU container is allowed, existing id=%d, attaching id=%d\n",
iommu_group_id(container->tbl->it_group),
iommu_group_id(container->tbl->
it_table_group->group),
iommu_group_id(iommu_group));
ret = -EBUSY;
goto unlock_exit;
@@ -491,13 +494,13 @@ static void tce_iommu_detach_group(void *iommu_data,
if (tbl != container->tbl) {
pr_warn("tce_vfio: detaching group #%u, expected group is #%u\n",
iommu_group_id(iommu_group),
iommu_group_id(tbl->it_group));
iommu_group_id(tbl->it_table_group->group));
goto unlock_exit;
}
if (container->enabled) {
pr_warn("tce_vfio: detaching group #%u from enabled container, forcing disable\n",
iommu_group_id(tbl->it_group));
iommu_group_id(tbl->it_table_group->group));
tce_iommu_disable(container);
}