]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iommufd: Register iommufd mock devices with fwspec
authorGuixin Liu <kanie@linux.alibaba.com>
Thu, 25 Sep 2025 05:47:30 +0000 (13:47 +0800)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 30 Sep 2025 12:54:12 +0000 (09:54 -0300)
Since the bus ops were retired the iommu subsystem changed to using fwspec
to match the iommu driver to the iommu device. If a device has a NULL
fwspec then it is matched to the first iommu driver with a NULL fwspec,
effectively disabling support for systems with more than one non-fwspec
iommu driver.

Thus, if the iommufd selfest are run in an x86 system that registers a
non-fwspec iommu driver they fail to bind their mock devices to the mock
iommu driver.

Fix this by allocating a software fwnode for mock iommu driver's
iommu_device, and set it to the device which mock iommu driver created.

This is done by adding a new helper iommu_mock_device_add() which abuses
the internals of the fwspec system to establish a fwspec before the device
is added and is careful not to leak it. A matching dummy fwspec is
automatically added to the mock iommu driver.

Test by "make -C toosl/testing/selftests TARGETS=iommu run_tests":
PASSED: 229 / 229 tests passed.

In addition, this issue is also can be found on amd platform, and
also tested on a amd machine.

Link: https://patch.msgid.link/r/20250925054730.3877-1-kanie@linux.alibaba.com
Fixes: 17de3f5fdd35 ("iommu: Retire bus ops")
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Tested-by: Qinyun Tan <qinyuntan@linux.alibaba.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/iommu/iommu-priv.h
drivers/iommu/iommu.c
drivers/iommu/iommufd/selftest.c

index e236b932e7668a1979862decb7cfff92c443c9e0..c95394cd03a770a4358a77be8b923178833cd0a2 100644 (file)
@@ -37,6 +37,8 @@ void iommu_device_unregister_bus(struct iommu_device *iommu,
                                 const struct bus_type *bus,
                                 struct notifier_block *nb);
 
+int iommu_mock_device_add(struct device *dev, struct iommu_device *iommu);
+
 struct iommu_attach_handle *iommu_attach_handle_get(struct iommu_group *group,
                                                    ioasid_t pasid,
                                                    unsigned int type);
index 060ebe330ee163918da95dfdbb2d006efa819571..59244c744eabd2d4f783fa91d3b8567b4ac703e4 100644 (file)
@@ -304,6 +304,7 @@ void iommu_device_unregister_bus(struct iommu_device *iommu,
                                 struct notifier_block *nb)
 {
        bus_unregister_notifier(bus, nb);
+       fwnode_remove_software_node(iommu->fwnode);
        iommu_device_unregister(iommu);
 }
 EXPORT_SYMBOL_GPL(iommu_device_unregister_bus);
@@ -326,6 +327,12 @@ int iommu_device_register_bus(struct iommu_device *iommu,
        if (err)
                return err;
 
+       iommu->fwnode = fwnode_create_software_node(NULL, NULL);
+       if (IS_ERR(iommu->fwnode)) {
+               bus_unregister_notifier(bus, nb);
+               return PTR_ERR(iommu->fwnode);
+       }
+
        spin_lock(&iommu_device_lock);
        list_add_tail(&iommu->list, &iommu_device_list);
        spin_unlock(&iommu_device_lock);
@@ -335,9 +342,28 @@ int iommu_device_register_bus(struct iommu_device *iommu,
                iommu_device_unregister_bus(iommu, bus, nb);
                return err;
        }
+       WRITE_ONCE(iommu->ready, true);
        return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_device_register_bus);
+
+int iommu_mock_device_add(struct device *dev, struct iommu_device *iommu)
+{
+       int rc;
+
+       mutex_lock(&iommu_probe_device_lock);
+       rc = iommu_fwspec_init(dev, iommu->fwnode);
+       mutex_unlock(&iommu_probe_device_lock);
+
+       if (rc)
+               return rc;
+
+       rc = device_add(dev);
+       if (rc)
+               iommu_fwspec_free(dev);
+       return rc;
+}
+EXPORT_SYMBOL_GPL(iommu_mock_device_add);
 #endif
 
 static struct dev_iommu *dev_iommu_get(struct device *dev)
index 61686603c7693434a71cfbaea26e262bae1ae8b3..de178827a078a9d96d7c7b265eb2a3d80a7c3a1d 100644 (file)
@@ -1126,7 +1126,7 @@ static struct mock_dev *mock_dev_create(unsigned long dev_flags)
                goto err_put;
        }
 
-       rc = device_add(&mdev->dev);
+       rc = iommu_mock_device_add(&mdev->dev, &mock_iommu.iommu_dev);
        if (rc)
                goto err_put;
        return mdev;