|
@@ -1245,6 +1245,8 @@ static void tce_iommu_release_ownership_ddw(struct tce_container *container,
|
|
|
static long tce_iommu_take_ownership_ddw(struct tce_container *container,
|
|
|
struct iommu_table_group *table_group)
|
|
|
{
|
|
|
+ long i, ret = 0;
|
|
|
+
|
|
|
if (!table_group->ops->create_table || !table_group->ops->set_window ||
|
|
|
!table_group->ops->release_ownership) {
|
|
|
WARN_ON_ONCE(1);
|
|
@@ -1253,7 +1255,27 @@ static long tce_iommu_take_ownership_ddw(struct tce_container *container,
|
|
|
|
|
|
table_group->ops->take_ownership(table_group);
|
|
|
|
|
|
+ /* Set all windows to the new group */
|
|
|
+ for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
|
|
|
+ struct iommu_table *tbl = container->tables[i];
|
|
|
+
|
|
|
+ if (!tbl)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ ret = table_group->ops->set_window(table_group, i, tbl);
|
|
|
+ if (ret)
|
|
|
+ goto release_exit;
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
+
|
|
|
+release_exit:
|
|
|
+ for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i)
|
|
|
+ table_group->ops->unset_window(table_group, i);
|
|
|
+
|
|
|
+ table_group->ops->release_ownership(table_group);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int tce_iommu_attach_group(void *iommu_data,
|