iommu: Allow taking a reference on a group directly
Subsystems (3)
Robin Murphy
reviewerPATCH v2 1/5 iommu: Allow taking a reference on a group directly
iommu_group_get_for_dev() expects that the IOMMU driver's device_group callback return a group with a reference held for the given device. Whilst allocating a new group is fine, and pci_device_group() correctly handles reusing an existing group, there is no general means for IOMMU drivers doing their own group lookup to take additional references on an existing group pointer without having to also store device pointers or resort to elaborate trickery.
Add an IOMMU-driver-specific function to fill the hole.
---
v2: Fix the function name; clarify what exactly its callers are fixing.
drivers/iommu/iommu.c | 13 +++++++++++++ include/linux/iommu.h | 1 + 2 files changed, 14 insertions(+)
drivers/iommu/iommu.c +13 -0
@@ -552,6 +552,19 @@ struct iommu_group *iommu_group_get(struct device *dev)EXPORT_SYMBOL_GPL (iommu_group_get);/** +* iommu_group_ref_get - Increment reference on a group +* @group: the group to use, must not be NULL +* +* This function is called by iommu drivers to take additional references on an +* existing group. Returns the given group for convenience. +*/ +struct iommu_group *iommu_group_ref_get (struct iommu_group *group) +{ +kobject_get (group->devices_kobj); +return group; +} + +/** * iommu_group_put - Decrement group reference * @group: the group to use *
include/linux/iommu.h +1 -0
@@ -253,6 +253,7 @@ extern void iommu_group_remove_device(struct device *dev);extern int iommu_group_for_each_dev (struct iommu_group *group,void *data,int (*fn)(struct device *,void *));extern struct iommu_group *iommu_group_get (struct device *dev); +extern struct iommu_group *iommu_group_ref_get (struct iommu_group *group);extern void iommu_group_put (struct iommu_group *group);extern int iommu_group_register_notifier (struct iommu_group *group,struct notifier_block *nb);
Signature · 1 line
2.10.2.dirty
Robin Murphy
reviewerPATCH v2 2/5 iommu/arm-smmu: Fix group refcounting
When arm_smmu_device_group() finds an existing group due to Stream ID aliasing, it should be taking an additional reference on that group. Otherwise, the caller of iommu_group_get_for_dev() will inadvertently remove the reference taken by iommu_group_add_device(), and the group will be freed prematurely if any device is removed.
--- drivers/iommu/arm-smmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/arm-smmu.c +1 -1
@@ -1478,7 +1478,7 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) }if (group) -return group; +return iommu_group_ref_get (group);if (dev_is_pci (dev)) group =pci_device_group (dev);
Signature · 1 line
2.10.2.dirty
Robin Murphy
reviewerPATCH v2 3/5 iommu/amd: Fix group refcounting
In reply to Robin MurphyIf acpihid_device_group() finds an existing group for the relevant devid, it should be taking an additional reference on that group. Otherwise, the caller of iommu_group_get_for_dev() will inadvertently remove the reference taken by iommu_group_add_device(), and the group will be freed prematurely if any device is removed.
--- drivers/iommu/amd_iommu.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iommu/amd_iommu.c +2 -0
@@ -373,6 +373,8 @@ static struct iommu_group *acpihid_device_group(struct device *dev)if (!entry->group) entry->group =generic_device_group (dev); +else +iommu_group_ref_get (entry->group);return entry->group; }
Signature · 1 line
2.10.2.dirty
Robin Murphy
reviewerPATCH v2 4/5 iommu/mediatek: Fix M4Uv2 group refcounting
In reply to Robin MurphyFor each subsequent device assigned to the m4u_group after its initial allocation, we need to take an additional reference. Otherwise, the caller of iommu_group_get_for_dev() will inadvertently remove the reference taken by iommu_group_add_device(), and the group will be freed prematurely if any device is removed.
--- drivers/iommu/mtk_iommu.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iommu/mtk_iommu.c +2 -0
@@ -410,6 +410,8 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev) data->m4u_group =iommu_group_alloc ();if (IS_ERR (data->m4u_group))dev_err (dev,"Failed to allocate M4U IOMMU group\n" ); + }else { +iommu_group_ref_get (data->m4u_group); }return data->m4u_group; }
Signature · 1 line
2.10.2.dirty
Robin Murphy
reviewerPATCH v2 5/5 iommu/mediatek: Fix M4Uv1 group refcounting
In reply to Robin MurphyFor each subsequent device assigned to the m4u_group after its initial allocation, we need to take an additional reference. Otherwise, the caller of iommu_group_get_for_dev() will inadvertently remove the reference taken by iommu_group_add_device(), and the group will be freed prematurely if any device is removed.
--- drivers/iommu/mtk_iommu_v1.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iommu/mtk_iommu_v1.c +2 -0
@@ -502,6 +502,8 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev) data->m4u_group =iommu_group_alloc ();if (IS_ERR (data->m4u_group))dev_err (dev,"Failed to allocate M4U IOMMU group\n" ); + }else { +iommu_group_ref_get (data->m4u_group); }return data->m4u_group; }
Signature · 1 line
2.10.2.dirty
PATCH v2 1/5 iommu: Allow taking a reference on a group directly
In reply to Robin MurphyQuoted 12 lines · Robin Murphy
iommu_group_get_for_dev()expects that the IOMMU driver'sdevice_groupcallback return a group with a reference held for the given device. Whilst allocating a new group is fine, andpci_device_group()correctly handles reusing an existing group, there is no general means for IOMMU drivers doing their own group lookup to take additional references on an existing group pointer without having to also store device pointers or resort to elaborate trickery.Add an IOMMU-driver-specific function to fill the hole.
Acked-by Sricharan R <[email protected]>Signed-off-by Robin Murphy <[email protected]>
Quoted 7 lines
---
v2: Fix the function name; clarify what exactly its callers are fixing.
drivers/iommu/iommu.c | 13 +++++++++++++ include/linux/iommu.h | 1 + 2 files changed, 14 insertions(+)
Applied the series, thanks Robin.