iommu: Move the iommu driver sysfs setup into iommu_init/deinit_device()
authorJason Gunthorpe <jgg@nvidia.com>
Tue, 6 Jun 2023 00:59:44 +0000 (21:59 -0300)
committerJoerg Roedel <jroedel@suse.de>
Fri, 14 Jul 2023 14:14:14 +0000 (16:14 +0200)
It makes logical sense that once the driver is attached to the device the
sysfs links appear, even if we haven't fully created the group_device or
attached the device to a domain.

Fix the missing error handling on sysfs creation since
iommu_init_device() can trivially handle this.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/6-v3-328044aa278c+45e49-iommu_probe_jgg@nvidia.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/iommu-sysfs.c
drivers/iommu/iommu.c

index 99869217fbec7d862af4bba0e0a6facbe34a7168..c8aba0e2a30d70b61a38e0395b36f07a83f228f6 100644 (file)
@@ -107,9 +107,6 @@ int iommu_device_link(struct iommu_device *iommu, struct device *link)
 {
        int ret;
 
-       if (!iommu || IS_ERR(iommu))
-               return -ENODEV;
-
        ret = sysfs_add_link_to_group(&iommu->dev->kobj, "devices",
                                      &link->kobj, dev_name(link));
        if (ret)
@@ -126,9 +123,6 @@ EXPORT_SYMBOL_GPL(iommu_device_link);
 
 void iommu_device_unlink(struct iommu_device *iommu, struct device *link)
 {
-       if (!iommu || IS_ERR(iommu))
-               return;
-
        sysfs_remove_link(&link->kobj, "iommu");
        sysfs_remove_link_from_group(&iommu->dev->kobj, "devices", dev_name(link));
 }
index f052f52958fdc5e3b601912b14315f9630830703..4688f61b7a4f2fd7b3ff457198a1e602c48ae756 100644 (file)
@@ -356,12 +356,16 @@ static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
                goto err_module_put;
        }
 
+       ret = iommu_device_link(iommu_dev, dev);
+       if (ret)
+               goto err_release;
+
        group = ops->device_group(dev);
        if (WARN_ON_ONCE(group == NULL))
                group = ERR_PTR(-EINVAL);
        if (IS_ERR(group)) {
                ret = PTR_ERR(group);
-               goto err_release;
+               goto err_unlink;
        }
        dev->iommu_group = group;
 
@@ -371,6 +375,8 @@ static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
                dev->iommu->attach_deferred = ops->is_attach_deferred(dev);
        return 0;
 
+err_unlink:
+       iommu_device_unlink(iommu_dev, dev);
 err_release:
        if (ops->release_device)
                ops->release_device(dev);
@@ -388,6 +394,8 @@ static void iommu_deinit_device(struct device *dev)
 
        lockdep_assert_held(&group->mutex);
 
+       iommu_device_unlink(dev->iommu->iommu_dev, dev);
+
        /*
         * release_device() must stop using any attached domain on the device.
         * If there are still other devices in the group they are not effected
@@ -462,7 +470,6 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
        iommu_group_put(group);
 
        mutex_unlock(&iommu_probe_device_lock);
-       iommu_device_link(dev->iommu->iommu_dev, dev);
 
        return 0;
 
@@ -584,8 +591,6 @@ static void iommu_release_device(struct device *dev)
        if (!dev->iommu || !group)
                return;
 
-       iommu_device_unlink(dev->iommu->iommu_dev, dev);
-
        __iommu_group_remove_device(dev);
 }