Skip to content

Commit

Permalink
vfio/spapr: Always clear TCEs before unsetting the window
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ShivaprasadGBhat authored and mpe committed Jun 28, 2024
1 parent aed6e49 commit 4ba2fdf
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions drivers/vfio/vfio_iommu_spapr_tce.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,6 @@ static void tce_iommu_release(void *iommu_data)
if (!tbl)
continue;

tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);
tce_iommu_free_table(container, tbl);
}

Expand Down Expand Up @@ -720,6 +719,8 @@ static long tce_iommu_remove_window(struct tce_container *container,

BUG_ON(!tbl->it_size);

tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);

/* Detach groups from IOMMUs */
list_for_each_entry(tcegrp, &container->group_list, next) {
table_group = iommu_group_get_iommudata(tcegrp->grp);
Expand All @@ -738,7 +739,6 @@ static long tce_iommu_remove_window(struct tce_container *container,
}

/* Free table */
tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);
tce_iommu_free_table(container, tbl);
container->tables[num] = NULL;

Expand Down Expand Up @@ -1197,9 +1197,14 @@ static void tce_iommu_release_ownership(struct tce_container *container,
return;
}

for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i)
if (container->tables[i])
for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
if (container->tables[i]) {
tce_iommu_clear(container, container->tables[i],
container->tables[i]->it_offset,
container->tables[i]->it_size);
table_group->ops->unset_window(table_group, i);
}
}
}

static long tce_iommu_take_ownership(struct tce_container *container,
Expand Down

0 comments on commit 4ba2fdf

Please sign in to comment.