Skip to content

Commit 2a91891

Browse files
guixinliu1995jgunthorpe
authored andcommitted
iommufd: Register iommufd mock devices with fwspec
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/[email protected] Fixes: 17de3f5 ("iommu: Retire bus ops") Signed-off-by: Guixin Liu <[email protected]> Reviewed-by: Lu Baolu <[email protected]> Tested-by: Qinyun Tan <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 1d235d8 commit 2a91891

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

drivers/iommu/iommu-priv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ void iommu_device_unregister_bus(struct iommu_device *iommu,
3737
const struct bus_type *bus,
3838
struct notifier_block *nb);
3939

40+
int iommu_mock_device_add(struct device *dev, struct iommu_device *iommu);
41+
4042
struct iommu_attach_handle *iommu_attach_handle_get(struct iommu_group *group,
4143
ioasid_t pasid,
4244
unsigned int type);

drivers/iommu/iommu.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ void iommu_device_unregister_bus(struct iommu_device *iommu,
304304
struct notifier_block *nb)
305305
{
306306
bus_unregister_notifier(bus, nb);
307+
fwnode_remove_software_node(iommu->fwnode);
307308
iommu_device_unregister(iommu);
308309
}
309310
EXPORT_SYMBOL_GPL(iommu_device_unregister_bus);
@@ -326,6 +327,12 @@ int iommu_device_register_bus(struct iommu_device *iommu,
326327
if (err)
327328
return err;
328329

330+
iommu->fwnode = fwnode_create_software_node(NULL, NULL);
331+
if (IS_ERR(iommu->fwnode)) {
332+
bus_unregister_notifier(bus, nb);
333+
return PTR_ERR(iommu->fwnode);
334+
}
335+
329336
spin_lock(&iommu_device_lock);
330337
list_add_tail(&iommu->list, &iommu_device_list);
331338
spin_unlock(&iommu_device_lock);
@@ -335,9 +342,28 @@ int iommu_device_register_bus(struct iommu_device *iommu,
335342
iommu_device_unregister_bus(iommu, bus, nb);
336343
return err;
337344
}
345+
WRITE_ONCE(iommu->ready, true);
338346
return 0;
339347
}
340348
EXPORT_SYMBOL_GPL(iommu_device_register_bus);
349+
350+
int iommu_mock_device_add(struct device *dev, struct iommu_device *iommu)
351+
{
352+
int rc;
353+
354+
mutex_lock(&iommu_probe_device_lock);
355+
rc = iommu_fwspec_init(dev, iommu->fwnode);
356+
mutex_unlock(&iommu_probe_device_lock);
357+
358+
if (rc)
359+
return rc;
360+
361+
rc = device_add(dev);
362+
if (rc)
363+
iommu_fwspec_free(dev);
364+
return rc;
365+
}
366+
EXPORT_SYMBOL_GPL(iommu_mock_device_add);
341367
#endif
342368

343369
static struct dev_iommu *dev_iommu_get(struct device *dev)

drivers/iommu/iommufd/selftest.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,7 @@ static struct mock_dev *mock_dev_create(unsigned long dev_flags)
11261126
goto err_put;
11271127
}
11281128

1129-
rc = device_add(&mdev->dev);
1129+
rc = iommu_mock_device_add(&mdev->dev, &mock_iommu.iommu_dev);
11301130
if (rc)
11311131
goto err_put;
11321132
return mdev;

0 commit comments

Comments
 (0)