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

vfio/spapr: Always clear TCEs before unsetting the window

The PAPR expects the TCE table to have no entries at the time of
unset window(i.e. remove-pe). The TCE clear right now is done
before freeing the iommu table. On pSeries, the unset window
makes those entries inaccessible to the OS and the H_PUT/GET calls
fail on them with H_CONSTRAINED.

On PowerNV, this has no side effect as the TCE clear can be done
before the DMA window removal as well.

Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/171923273535.1397.1236742071894414895.stgit@linux.ibm.com

authored by

Shivaprasad G Bhat and committed by
Michael Ellerman
4ba2fdff aed6e494

+9 -4
+9 -4
drivers/vfio/vfio_iommu_spapr_tce.c
··· 364 364 if (!tbl) 365 365 continue; 366 366 367 - tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size); 368 367 tce_iommu_free_table(container, tbl); 369 368 } 370 369 ··· 719 720 720 721 BUG_ON(!tbl->it_size); 721 722 723 + tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size); 724 + 722 725 /* Detach groups from IOMMUs */ 723 726 list_for_each_entry(tcegrp, &container->group_list, next) { 724 727 table_group = iommu_group_get_iommudata(tcegrp->grp); ··· 739 738 } 740 739 741 740 /* Free table */ 742 - tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size); 743 741 tce_iommu_free_table(container, tbl); 744 742 container->tables[num] = NULL; 745 743 ··· 1197 1197 return; 1198 1198 } 1199 1199 1200 - for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) 1201 - if (container->tables[i]) 1200 + for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { 1201 + if (container->tables[i]) { 1202 + tce_iommu_clear(container, container->tables[i], 1203 + container->tables[i]->it_offset, 1204 + container->tables[i]->it_size); 1202 1205 table_group->ops->unset_window(table_group, i); 1206 + } 1207 + } 1203 1208 } 1204 1209 1205 1210 static long tce_iommu_take_ownership(struct tce_container *container,