[PATCH v2 00/10] Refine the locking for dev->iommu_group

Jason Gunthorpe
2023-07-31T17:51:01Z

This series puts the core code usage of dev->iommu_group under a
consistent set of locking rules. Currently a lot of places in the code
access this value without any locking or READ_ONCE/etc techniques and it
is not clear how or why this is safe.

Make it so the following locking rules are used:

- It is readable by a probe'd device driver. So long as a device driver
is probed the dev->iommu_group will be guaranteed stable without further
locking. The reader should provide some kind of locking that ensure's
its remove() struct device_driver op cannot progress.

- Read/Write under the device_lock(), this primarily protects against
parallel probe of the same device, and parallel probe/remove. This is
useful for places that don't naturally have a device driver probed, and
should be rare.

- Read/Write under the global dev_iommu_group_lock. This is used during
probe time discovery of groups. Device drivers will scan unlocked
portions of the device tree to locate an already existing group. These
scans can access the dev->iommu_group under the global lock to single
thread determining and installing the group. This ensures that groups
are reliably formed.

Add locking assertions to enforce this.

Along the way remove a bunch of opencoded group touching in drivers trying
to implement a 'single group per driver' approach by providing a core helper
that does this common algorithm.

Overall this significantly reduces the number of places within
drivers/iommu calling iommu_group_get or touching groups at all.

This goes on top of Joerg's next tree, it needs the prior series
"Consolidate the probe_device path".

This is on github: https://github.com/jgunthorpe/linux/commits/iommu_group_locking

v2:
- Revise comments
- NULL singleton_group during iommu_device_unregister() for clarity
v1: https://lore.kernel.org/r/0-v1-3c8177327a47+256-iommu_group_locking_jgg@nvidia.com

Jason Gunthorpe (10):
iommu: Remove useless group refcounting
iommu: Add a lockdep assertion for remaining dev->iommu_group reads
iommu: Add generic_single_device_group()
iommu/sun50i: Convert to generic_single_device_group()
iommu/sprd: Convert to generic_single_device_group()
iommu/rockchip: Convert to generic_single_device_group()
iommu/ipmmu-vmsa: Convert to generic_single_device_group()
iommu/omap: Convert to generic_single_device_group()
iommu: Complete the locking for dev->iommu_group
iommu/intel: Fix missing locking for show_device_domain_translation()

drivers/iommu/intel/debugfs.c | 34 ++++----
drivers/iommu/iommu.c | 155 +++++++++++++++++++++------------
drivers/iommu/ipmmu-vmsa.c | 22 ++---
drivers/iommu/omap-iommu.c | 30 +------
drivers/iommu/omap-iommu.h | 2 +-
drivers/iommu/rockchip-iommu.c | 22 +----
drivers/iommu/sprd-iommu.c | 24 +----
drivers/iommu/sun50i-iommu.c | 29 ++----
include/linux/iommu.h | 3 +
9 files changed, 138 insertions(+), 183 deletions(-)

base-commit: a5003e75a1714857c01317d04982eef81331fe2f
--
2.41.0