Skip to content

Commit 6eb4da8

Browse files
jgunthorpejoergroedel
authored andcommitted
iommu: Have __iommu_probe_device() check for already probed devices
This is a step toward making __iommu_probe_device() self contained. It should, under proper locking, check if the device is already associated with an iommu driver and resolve parallel probes. All but one of the callers open code this test using two different means, but they all rely on dev->iommu_group. Currently the bus_iommu_probe()/probe_iommu_group() and probe_acpi_namespace_devices() rejects already probed devices with an unlocked read of dev->iommu_group. The OF and ACPI "replay" functions use device_iommu_mapped() which is the same read without the pointless refcount. Move this test into __iommu_probe_device() and put it under the iommu_probe_device_lock. The store to dev->iommu_group is in iommu_group_add_device() which is also called under this lock for iommu driver devices, making it properly locked. The only path that didn't have this check is the hotplug path triggered by BUS_NOTIFY_ADD_DEVICE. The only way to get dev->iommu_group assigned outside the probe path is via iommu_group_add_device(). Today the only caller is VFIO no-iommu which never associates with an iommu driver. Thus adding this additional check is safe. Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Lu Baolu <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 06c2afb commit 6eb4da8

File tree

4 files changed

+11
-19
lines changed

4 files changed

+11
-19
lines changed

drivers/acpi/scan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1581,7 +1581,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
15811581
* If we have reason to believe the IOMMU driver missed the initial
15821582
* iommu_probe_device() call for dev, replay it to get things in order.
15831583
*/
1584-
if (!err && dev->bus && !device_iommu_mapped(dev))
1584+
if (!err && dev->bus)
15851585
err = iommu_probe_device(dev);
15861586

15871587
/* Ignore all other errors apart from EPROBE_DEFER */

drivers/iommu/intel/iommu.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3756,7 +3756,6 @@ static int __init probe_acpi_namespace_devices(void)
37563756
for_each_active_dev_scope(drhd->devices,
37573757
drhd->devices_cnt, i, dev) {
37583758
struct acpi_device_physical_node *pn;
3759-
struct iommu_group *group;
37603759
struct acpi_device *adev;
37613760

37623761
if (dev->bus != &acpi_bus_type)
@@ -3766,12 +3765,6 @@ static int __init probe_acpi_namespace_devices(void)
37663765
mutex_lock(&adev->physical_node_lock);
37673766
list_for_each_entry(pn,
37683767
&adev->physical_node_list, node) {
3769-
group = iommu_group_get(pn->dev);
3770-
if (group) {
3771-
iommu_group_put(group);
3772-
continue;
3773-
}
3774-
37753768
ret = iommu_probe_device(pn->dev);
37763769
if (ret)
37773770
break;

drivers/iommu/iommu.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -351,9 +351,16 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
351351
* but for now enforcing a simple global ordering is fine.
352352
*/
353353
mutex_lock(&iommu_probe_device_lock);
354+
355+
/* Device is probed already if in a group */
356+
if (dev->iommu_group) {
357+
ret = 0;
358+
goto out_unlock;
359+
}
360+
354361
if (!dev_iommu_get(dev)) {
355362
ret = -ENOMEM;
356-
goto err_unlock;
363+
goto out_unlock;
357364
}
358365

359366
if (!try_module_get(ops->owner)) {
@@ -399,7 +406,7 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
399406
err_free:
400407
dev_iommu_free(dev);
401408

402-
err_unlock:
409+
out_unlock:
403410
mutex_unlock(&iommu_probe_device_lock);
404411

405412
return ret;
@@ -1711,16 +1718,8 @@ struct iommu_domain *iommu_group_default_domain(struct iommu_group *group)
17111718
static int probe_iommu_group(struct device *dev, void *data)
17121719
{
17131720
struct list_head *group_list = data;
1714-
struct iommu_group *group;
17151721
int ret;
17161722

1717-
/* Device is probed already if in a group */
1718-
group = iommu_group_get(dev);
1719-
if (group) {
1720-
iommu_group_put(group);
1721-
return 0;
1722-
}
1723-
17241723
ret = __iommu_probe_device(dev, group_list);
17251724
if (ret == -ENODEV)
17261725
ret = 0;

drivers/iommu/of_iommu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
159159
* If we have reason to believe the IOMMU driver missed the initial
160160
* probe for dev, replay it to get things in order.
161161
*/
162-
if (!err && dev->bus && !device_iommu_mapped(dev))
162+
if (!err && dev->bus)
163163
err = iommu_probe_device(dev);
164164

165165
/* Ignore all other errors apart from EPROBE_DEFER */

0 commit comments

Comments
 (0)