Skip to content

Commit 17bad52

Browse files
committed
iommufd: Add enforced_cache_coherency to iommufd_hw_pagetable_alloc()
Logically the HWPT should have the coherency set properly for the device that it is being created for when it is created. This was happening implicitly if the immediate_attach was set because iommufd_hw_pagetable_attach() does it as the first thing. Do it unconditionally so !immediate_attach works properly. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Lu Baolu <[email protected]> Tested-by: Nicolin Chen <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent d03f133 commit 17bad52

File tree

3 files changed

+32
-15
lines changed

3 files changed

+32
-15
lines changed

drivers/iommu/iommufd/device.c

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -338,22 +338,11 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
338338
goto err_unlock;
339339
}
340340

341-
/*
342-
* Try to upgrade the domain we have, it is an iommu driver bug to
343-
* report IOMMU_CAP_ENFORCE_CACHE_COHERENCY but fail
344-
* enforce_cache_coherency when there are no devices attached to the
345-
* domain.
346-
*/
347-
if (idev->enforce_cache_coherency && !hwpt->enforce_cache_coherency) {
348-
if (hwpt->domain->ops->enforce_cache_coherency)
349-
hwpt->enforce_cache_coherency =
350-
hwpt->domain->ops->enforce_cache_coherency(
351-
hwpt->domain);
352-
if (!hwpt->enforce_cache_coherency) {
353-
WARN_ON(list_empty(&idev->igroup->device_list));
354-
rc = -EINVAL;
341+
/* Try to upgrade the domain we have */
342+
if (idev->enforce_cache_coherency) {
343+
rc = iommufd_hw_pagetable_enforce_cc(hwpt);
344+
if (rc)
355345
goto err_unlock;
356-
}
357346
}
358347

359348
rc = iopt_table_enforce_dev_resv_regions(&hwpt->ioas->iopt, idev->dev,

drivers/iommu/iommufd/hw_pagetable.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ void iommufd_hw_pagetable_destroy(struct iommufd_object *obj)
2525
refcount_dec(&hwpt->ioas->obj.users);
2626
}
2727

28+
int iommufd_hw_pagetable_enforce_cc(struct iommufd_hw_pagetable *hwpt)
29+
{
30+
if (hwpt->enforce_cache_coherency)
31+
return 0;
32+
33+
if (hwpt->domain->ops->enforce_cache_coherency)
34+
hwpt->enforce_cache_coherency =
35+
hwpt->domain->ops->enforce_cache_coherency(
36+
hwpt->domain);
37+
if (!hwpt->enforce_cache_coherency)
38+
return -EINVAL;
39+
return 0;
40+
}
41+
2842
/**
2943
* iommufd_hw_pagetable_alloc() - Get an iommu_domain for a device
3044
* @ictx: iommufd context
@@ -60,6 +74,19 @@ iommufd_hw_pagetable_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
6074
goto out_abort;
6175
}
6276

77+
/*
78+
* Set the coherency mode before we do iopt_table_add_domain() as some
79+
* iommus have a per-PTE bit that controls it and need to decide before
80+
* doing any maps. It is an iommu driver bug to report
81+
* IOMMU_CAP_ENFORCE_CACHE_COHERENCY but fail enforce_cache_coherency on
82+
* a new domain.
83+
*/
84+
if (idev->enforce_cache_coherency) {
85+
rc = iommufd_hw_pagetable_enforce_cc(hwpt);
86+
if (WARN_ON(rc))
87+
goto out_abort;
88+
}
89+
6390
/*
6491
* immediate_attach exists only to accommodate iommu drivers that cannot
6592
* directly allocate a domain. These drivers do not finish creating the

drivers/iommu/iommufd/iommufd_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ struct iommufd_hw_pagetable {
254254
struct iommufd_hw_pagetable *
255255
iommufd_hw_pagetable_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
256256
struct iommufd_device *idev, bool immediate_attach);
257+
int iommufd_hw_pagetable_enforce_cc(struct iommufd_hw_pagetable *hwpt);
257258
int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
258259
struct iommufd_device *idev);
259260
struct iommufd_hw_pagetable *

0 commit comments

Comments
 (0)