Skip to content

Commit 34f327a

Browse files
committed
iommufd: Keep track of each device's reserved regions instead of groups
The driver facing API in the iommu core makes the reserved regions per-device. An algorithm in the core code consolidates the regions of all the devices in a group to return the group view. To allow for devices to be hotplugged into the group iommufd would re-load the entire group's reserved regions for each device, just in case they changed. Further iommufd already has to deal with duplicated/overlapping reserved regions as it must union all the groups together. Thus simplify all of this to just use the device reserved regions interface directly from the iommu driver. Link: https://lore.kernel.org/r/[email protected] Suggested-by: Kevin Tian <[email protected]> Reviewed-by: Lu Baolu <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Tested-by: Nicolin Chen <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 8d0e2e9 commit 34f327a

File tree

3 files changed

+16
-23
lines changed

3 files changed

+16
-23
lines changed

drivers/iommu/iommufd/device.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,8 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
356356
}
357357
}
358358

359-
rc = iopt_table_enforce_group_resv_regions(&hwpt->ioas->iopt, idev->dev,
360-
idev->igroup->group,
361-
&sw_msi_start);
359+
rc = iopt_table_enforce_dev_resv_regions(
360+
&hwpt->ioas->iopt, idev->dev, &sw_msi_start);
362361
if (rc)
363362
goto err_unlock;
364363

drivers/iommu/iommufd/io_pagetable.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,25 +1169,22 @@ void iopt_remove_access(struct io_pagetable *iopt,
11691169
up_write(&iopt->domains_rwsem);
11701170
}
11711171

1172-
/* Narrow the valid_iova_itree to include reserved ranges from a group. */
1173-
int iopt_table_enforce_group_resv_regions(struct io_pagetable *iopt,
1174-
struct device *device,
1175-
struct iommu_group *group,
1176-
phys_addr_t *sw_msi_start)
1172+
/* Narrow the valid_iova_itree to include reserved ranges from a device. */
1173+
int iopt_table_enforce_dev_resv_regions(struct io_pagetable *iopt,
1174+
struct device *dev,
1175+
phys_addr_t *sw_msi_start)
11771176
{
11781177
struct iommu_resv_region *resv;
1179-
struct iommu_resv_region *tmp;
1180-
LIST_HEAD(group_resv_regions);
1178+
LIST_HEAD(resv_regions);
11811179
unsigned int num_hw_msi = 0;
11821180
unsigned int num_sw_msi = 0;
11831181
int rc;
11841182

11851183
down_write(&iopt->iova_rwsem);
1186-
rc = iommu_get_group_resv_regions(group, &group_resv_regions);
1187-
if (rc)
1188-
goto out_unlock;
1184+
/* FIXME: drivers allocate memory but there is no failure propogated */
1185+
iommu_get_resv_regions(dev, &resv_regions);
11891186

1190-
list_for_each_entry(resv, &group_resv_regions, list) {
1187+
list_for_each_entry(resv, &resv_regions, list) {
11911188
if (resv->type == IOMMU_RESV_DIRECT_RELAXABLE)
11921189
continue;
11931190

@@ -1199,7 +1196,7 @@ int iopt_table_enforce_group_resv_regions(struct io_pagetable *iopt,
11991196
}
12001197

12011198
rc = iopt_reserve_iova(iopt, resv->start,
1202-
resv->length - 1 + resv->start, device);
1199+
resv->length - 1 + resv->start, dev);
12031200
if (rc)
12041201
goto out_reserved;
12051202
}
@@ -1214,11 +1211,9 @@ int iopt_table_enforce_group_resv_regions(struct io_pagetable *iopt,
12141211
goto out_free_resv;
12151212

12161213
out_reserved:
1217-
__iopt_remove_reserved_iova(iopt, device);
1214+
__iopt_remove_reserved_iova(iopt, dev);
12181215
out_free_resv:
1219-
list_for_each_entry_safe(resv, tmp, &group_resv_regions, list)
1220-
kfree(resv);
1221-
out_unlock:
1216+
iommu_put_resv_regions(dev, &resv_regions);
12221217
up_write(&iopt->iova_rwsem);
12231218
return rc;
12241219
}

drivers/iommu/iommufd/iommufd_private.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,9 @@ int iopt_table_add_domain(struct io_pagetable *iopt,
7676
struct iommu_domain *domain);
7777
void iopt_table_remove_domain(struct io_pagetable *iopt,
7878
struct iommu_domain *domain);
79-
int iopt_table_enforce_group_resv_regions(struct io_pagetable *iopt,
80-
struct device *device,
81-
struct iommu_group *group,
82-
phys_addr_t *sw_msi_start);
79+
int iopt_table_enforce_dev_resv_regions(struct io_pagetable *iopt,
80+
struct device *dev,
81+
phys_addr_t *sw_msi_start);
8382
int iopt_set_allow_iova(struct io_pagetable *iopt,
8483
struct rb_root_cached *allowed_iova);
8584
int iopt_reserve_iova(struct io_pagetable *iopt, unsigned long start,

0 commit comments

Comments
 (0)