Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/pseries/iommu: Use the iommu table[0] for IOV VF's DDW

This patch basically brings consistency with PowerNV approach
to use the first freely available iommu table when the default
window is removed.

The pSeries iommu code convention has been that the table[0] is
for the default 32 bit DMA window and the table[1] is for the
64 bit DDW.

With VFs having only 1 DMA window, the default has to be removed
for creating the larger DMA window. The existing code uses the
table[1] for that, while marking the table[0] as NULL. This is
fine as long as the host driver itself uses the device.

For the VFIO user, on pSeries there is no way to skip table[0]
as the VFIO subdriver uses the first freely available table.
The window 0, when created as 64-bit DDW in that context would
still be on table[0], as the maximum number of windows is 1.

This won't have any impact for the host driver as the table is
fetched from the device's iommu_table_base.

Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
[mpe: Rebase and resolve conflicts]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/171923272328.1397.1817843961216868850.stgit@linux.ibm.com

authored by

Shivaprasad G Bhat and committed by
Michael Ellerman
aed6e494 6af67f2d

+7 -5
+7 -5
arch/powerpc/platforms/pseries/iommu.c
··· 155 155 #endif 156 156 157 157 /* Default DMA window table is at index 0, while DDW at 1. SR-IOV 158 - * adapters only have table on index 1. 158 + * adapters only have table on index 0(if not direct mapped). 159 159 */ 160 160 if (table_group->tables[0]) 161 161 iommu_tce_table_put(table_group->tables[0]); ··· 1555 1555 clean_dma_window(pdn, win64->value); 1556 1556 goto out_del_list; 1557 1557 } 1558 + if (default_win_removed) { 1559 + iommu_tce_table_put(pci->table_group->tables[0]); 1560 + pci->table_group->tables[0] = NULL; 1561 + set_iommu_table_base(&dev->dev, NULL); 1562 + } 1558 1563 } 1559 1564 1560 1565 if (dynamic_mapping) { ··· 1597 1592 &iommu_table_lpar_multi_ops); 1598 1593 iommu_init_table(newtbl, pci->phb->node, start, end); 1599 1594 1600 - pci->table_group->tables[1] = newtbl; 1595 + pci->table_group->tables[default_win_removed ? 0 : 1] = newtbl; 1601 1596 1602 1597 set_iommu_table_base(&dev->dev, newtbl); 1603 1598 } 1604 1599 1605 1600 if (default_win_removed) { 1606 - iommu_tce_table_put(pci->table_group->tables[0]); 1607 - pci->table_group->tables[0] = NULL; 1608 - 1609 1601 /* default_win is valid here because default_win_removed == true */ 1610 1602 of_remove_property(pdn, default_win); 1611 1603 dev_info(&dev->dev, "Removed default DMA window for %pOF\n", pdn);