Skip to content

Commit a7efdfa

Browse files
committed
iommu: Fix race between OF and IOMMU device probe codepaths
Something something not sure if this is fully correct. Signed-off-by: Hector Martin <[email protected]>
1 parent 7ebe885 commit a7efdfa

2 files changed

Lines changed: 18 additions & 4 deletions

File tree

drivers/iommu/iommu.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,12 +333,13 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
333333
return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids);
334334
}
335335

336+
DEFINE_MUTEX(iommu_probe_device_lock);
337+
336338
static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
337339
{
338340
const struct iommu_ops *ops = dev->bus->iommu_ops;
339341
struct iommu_device *iommu_dev;
340342
struct iommu_group *group;
341-
static DEFINE_MUTEX(iommu_probe_device_lock);
342343
int ret;
343344

344345
if (!ops)

drivers/iommu/of_iommu.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,20 +107,30 @@ static int of_iommu_configure_device(struct device_node *master_np,
107107
of_iommu_configure_dev(master_np, dev);
108108
}
109109

110+
extern struct mutex iommu_probe_device_lock;
111+
110112
const struct iommu_ops *of_iommu_configure(struct device *dev,
111113
struct device_node *master_np,
112114
const u32 *id)
113115
{
114116
const struct iommu_ops *ops = NULL;
115-
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
117+
struct iommu_fwspec *fwspec;
116118
int err = NO_IOMMU;
117119

118-
if (!master_np)
120+
mutex_lock(&iommu_probe_device_lock);
121+
122+
if (!master_np) {
123+
mutex_unlock(&iommu_probe_device_lock);
119124
return NULL;
125+
}
126+
127+
fwspec = dev_iommu_fwspec_get(dev);
120128

121129
if (fwspec) {
122-
if (fwspec->ops)
130+
if (fwspec->ops) {
131+
mutex_unlock(&iommu_probe_device_lock);
123132
return fwspec->ops;
133+
}
124134

125135
/* In the deferred case, start again from scratch */
126136
iommu_fwspec_free(dev);
@@ -155,6 +165,9 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
155165
fwspec = dev_iommu_fwspec_get(dev);
156166
ops = fwspec->ops;
157167
}
168+
169+
mutex_unlock(&iommu_probe_device_lock);
170+
158171
/*
159172
* If we have reason to believe the IOMMU driver missed the initial
160173
* probe for dev, replay it to get things in order.

0 commit comments

Comments
 (0)