[PATCH v4 09/24] iommu: Add group pointer to struct group_device
Nicolin Chen
nicolinc at nvidia.com
Mon May 18 20:38:52 PDT 2026
Though group pointer is in general available at dev->iommu_group, it would
be NULLed by iommu_deinit_device() holding group->mutex.
To introduce an asynchronous worker that would hold the mutex as well, its
disable_work_sync() can only get called afterwards outside the mutex. Then,
using dev->iommu_group would crash the kernel.
Add a group pointer to the gdev to prepare for that. No functional change.
Drop group arguments next to gdev in function parameters.
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
drivers/iommu/iommu.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 4116b28258bde..f745083c032d6 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -84,6 +84,7 @@ enum gdev_blocked {
};
struct group_device {
+ struct iommu_group *group;
struct list_head list;
struct device *dev;
char *name;
@@ -177,8 +178,7 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
const char *buf, size_t count);
static struct group_device *iommu_group_alloc_device(struct iommu_group *group,
struct device *dev);
-static void __iommu_group_free_device(struct iommu_group *group,
- struct group_device *grp_dev);
+static void __iommu_group_free_device(struct group_device *grp_dev);
static void iommu_domain_init(struct iommu_domain *domain, unsigned int type,
const struct iommu_ops *ops);
@@ -727,7 +727,7 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
iommu_deinit_device(dev);
mutex_unlock(&group->mutex);
if (!IS_ERR(gdev))
- __iommu_group_free_device(group, gdev);
+ __iommu_group_free_device(gdev);
iommu_group_put(group);
return ret;
@@ -751,9 +751,9 @@ int iommu_probe_device(struct device *dev)
return 0;
}
-static void __iommu_group_free_device(struct iommu_group *group,
- struct group_device *grp_dev)
+static void __iommu_group_free_device(struct group_device *grp_dev)
{
+ struct iommu_group *group = grp_dev->group;
struct device *dev = grp_dev->dev;
lockdep_assert_not_held(&group->mutex);
@@ -797,7 +797,7 @@ static void __iommu_group_remove_device(struct device *dev)
mutex_unlock(&group->mutex);
if (to_free)
- __iommu_group_free_device(group, to_free);
+ __iommu_group_free_device(to_free);
/*
* Pairs with the get in iommu_init_device() or
* iommu_group_add_device()
@@ -1304,6 +1304,7 @@ static struct group_device *iommu_group_alloc_device(struct iommu_group *group,
return ERR_PTR(-ENOMEM);
device->dev = dev;
+ device->group = group;
/* Keep dev alive for any in-flight RCU reader of grp_dev->dev. */
get_device(dev);
@@ -4161,9 +4162,9 @@ static int group_device_cmp_dma_alias(struct pci_dev *dev, u16 alias,
&alias);
}
-static bool group_device_dma_alias_is_blocked(struct iommu_group *group,
- struct group_device *gdev)
+static bool group_device_dma_alias_is_blocked(struct group_device *gdev)
{
+ struct iommu_group *group = gdev->group;
struct group_device *sibling;
lockdep_assert_held(&group->mutex);
@@ -4263,7 +4264,7 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev, int reset_result)
if (WARN_ON(!gdev->blocked))
return;
- if (group_device_dma_alias_is_blocked(group, gdev)) {
+ if (group_device_dma_alias_is_blocked(gdev)) {
/*
* FIXME: DMA aliased devices share the same RID, which would be
* convoluted to handle, as "gdev->blocked" is not sufficient:
--
2.43.0
More information about the linux-arm-kernel
mailing list