From 6caf574d5a4d0fd8f3f99ecf7d7afbd6a09b869a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 2 Jun 2025 14:27:52 +0200 Subject: [PATCH] 6.15-stable patches added patches: iommu-avoid-introducing-more-races.patch iommu-handle-yet-another-race-around-registration.patch --- .../iommu-avoid-introducing-more-races.patch | 50 ++++++++ ...yet-another-race-around-registration.patch | 119 ++++++++++++++++++ queue-6.15/series | 2 + 3 files changed, 171 insertions(+) create mode 100644 queue-6.15/iommu-avoid-introducing-more-races.patch create mode 100644 queue-6.15/iommu-handle-yet-another-race-around-registration.patch diff --git a/queue-6.15/iommu-avoid-introducing-more-races.patch b/queue-6.15/iommu-avoid-introducing-more-races.patch new file mode 100644 index 0000000000..9e97f054ed --- /dev/null +++ b/queue-6.15/iommu-avoid-introducing-more-races.patch @@ -0,0 +1,50 @@ +From 0c8e9c148e29a983e67060fb4944a8ca79d4362a Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Tue, 11 Mar 2025 15:19:25 +0000 +Subject: iommu: Avoid introducing more races + +From: Robin Murphy + +commit 0c8e9c148e29a983e67060fb4944a8ca79d4362a upstream. + +Although the lock-juggling is only a temporary workaround, we don't want +it to make things avoidably worse. Jason was right to be nervous, since +bus_iommu_probe() doesn't care *which* IOMMU instance it's probing for, +so it probably is possible for one walk to finish a probe which a +different walk started, thus we do want to check for that. + +Also there's no need to drop the lock just to have of_iommu_configure() +do nothing when a fwspec already exists; check that directly and avoid +opening a window at all in that (still somewhat likely) case. + +Suggested-by: Jason Gunthorpe +Signed-off-by: Robin Murphy +Reviewed-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/09d901ad11b3a410fbb6e27f7d04ad4609c3fe4a.1741706365.git.robin.murphy@arm.com +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iommu/iommu.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/iommu/iommu.c ++++ b/drivers/iommu/iommu.c +@@ -422,13 +422,15 @@ static int iommu_init_device(struct devi + * is buried in the bus dma_configure path. Properly unpicking that is + * still a big job, so for now just invoke the whole thing. The device + * already having a driver bound means dma_configure has already run and +- * either found no IOMMU to wait for, or we're in its replay call right +- * now, so either way there's no point calling it again. ++ * found no IOMMU to wait for, so there's no point calling it again. + */ +- if (!dev->driver && dev->bus->dma_configure) { ++ if (!dev->iommu->fwspec && !dev->driver && dev->bus->dma_configure) { + mutex_unlock(&iommu_probe_device_lock); + dev->bus->dma_configure(dev); + mutex_lock(&iommu_probe_device_lock); ++ /* If another instance finished the job for us, skip it */ ++ if (!dev->iommu || dev->iommu_group) ++ return -ENODEV; + } + /* + * At this point, relevant devices either now have a fwspec which will diff --git a/queue-6.15/iommu-handle-yet-another-race-around-registration.patch b/queue-6.15/iommu-handle-yet-another-race-around-registration.patch new file mode 100644 index 0000000000..4fc402c3b4 --- /dev/null +++ b/queue-6.15/iommu-handle-yet-another-race-around-registration.patch @@ -0,0 +1,119 @@ +From da33e87bd2bfc63531cf7448a3cd7a3d42182f08 Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Thu, 24 Apr 2025 18:41:28 +0100 +Subject: iommu: Handle yet another race around registration + +From: Robin Murphy + +commit da33e87bd2bfc63531cf7448a3cd7a3d42182f08 upstream. + +Next up on our list of race windows to close is another one during +iommu_device_register() - it's now OK again for multiple instances to +run their bus_iommu_probe() in parallel, but an iommu_probe_device() can +still also race against a running bus_iommu_probe(). As Johan has +managed to prove, this has now become a lot more visible on DT platforms +wth driver_async_probe where a client driver is attempting to probe in +parallel with its IOMMU driver - although commit b46064a18810 ("iommu: +Handle race with default domain setup") resolves this from the client +driver's point of view, this isn't before of_iommu_configure() has had +the chance to attempt to "replay" a probe that the bus walk hasn't even +tried yet, and so still cause the out-of-order group allocation +behaviour that we're trying to clean up (and now warning about). + +The most reliable thing to do here is to explicitly keep track of the +"iommu_device_register() is still running" state, so we can then +special-case the ops lookup for the replay path (based on dev->iommu +again) to let that think it's still waiting for the IOMMU driver to +appear at all. This still leaves the longstanding theoretical case of +iommu_bus_notifier() being triggered during bus_iommu_probe(), but it's +not so simple to defer a notifier, and nobody's ever reported that being +a visible issue, so let's quietly kick that can down the road for now... + +Reported-by: Johan Hovold +Fixes: bcb81ac6ae3c ("iommu: Get DT/ACPI parsing into the proper probe path") +Signed-off-by: Robin Murphy +Link: https://lore.kernel.org/r/88d54c1b48fed8279aa47d30f3d75173685bb26a.1745516488.git.robin.murphy@arm.com +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iommu/iommu.c | 26 ++++++++++++++++++-------- + include/linux/iommu.h | 2 ++ + 2 files changed, 20 insertions(+), 8 deletions(-) + +--- a/drivers/iommu/iommu.c ++++ b/drivers/iommu/iommu.c +@@ -277,6 +277,8 @@ int iommu_device_register(struct iommu_d + err = bus_iommu_probe(iommu_buses[i]); + if (err) + iommu_device_unregister(iommu); ++ else ++ WRITE_ONCE(iommu->ready, true); + return err; + } + EXPORT_SYMBOL_GPL(iommu_device_register); +@@ -2832,31 +2834,39 @@ bool iommu_default_passthrough(void) + } + EXPORT_SYMBOL_GPL(iommu_default_passthrough); + +-const struct iommu_ops *iommu_ops_from_fwnode(const struct fwnode_handle *fwnode) ++static const struct iommu_device *iommu_from_fwnode(const struct fwnode_handle *fwnode) + { +- const struct iommu_ops *ops = NULL; +- struct iommu_device *iommu; ++ const struct iommu_device *iommu, *ret = NULL; + + spin_lock(&iommu_device_lock); + list_for_each_entry(iommu, &iommu_device_list, list) + if (iommu->fwnode == fwnode) { +- ops = iommu->ops; ++ ret = iommu; + break; + } + spin_unlock(&iommu_device_lock); +- return ops; ++ return ret; ++} ++ ++const struct iommu_ops *iommu_ops_from_fwnode(const struct fwnode_handle *fwnode) ++{ ++ const struct iommu_device *iommu = iommu_from_fwnode(fwnode); ++ ++ return iommu ? iommu->ops : NULL; + } + + int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode) + { +- const struct iommu_ops *ops = iommu_ops_from_fwnode(iommu_fwnode); ++ const struct iommu_device *iommu = iommu_from_fwnode(iommu_fwnode); + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + +- if (!ops) ++ if (!iommu) + return driver_deferred_probe_check_state(dev); ++ if (!dev->iommu && !READ_ONCE(iommu->ready)) ++ return -EPROBE_DEFER; + + if (fwspec) +- return ops == iommu_fwspec_ops(fwspec) ? 0 : -EINVAL; ++ return iommu->ops == iommu_fwspec_ops(fwspec) ? 0 : -EINVAL; + + if (!dev_iommu_get(dev)) + return -ENOMEM; +--- a/include/linux/iommu.h ++++ b/include/linux/iommu.h +@@ -750,6 +750,7 @@ struct iommu_domain_ops { + * @dev: struct device for sysfs handling + * @singleton_group: Used internally for drivers that have only one group + * @max_pasids: number of supported PASIDs ++ * @ready: set once iommu_device_register() has completed successfully + */ + struct iommu_device { + struct list_head list; +@@ -758,6 +759,7 @@ struct iommu_device { + struct device *dev; + struct iommu_group *singleton_group; + u32 max_pasids; ++ bool ready; + }; + + /** diff --git a/queue-6.15/series b/queue-6.15/series index f7e0d80e14..e7e290861f 100644 --- a/queue-6.15/series +++ b/queue-6.15/series @@ -45,3 +45,5 @@ perf-arm-cmn-add-cmn-s3-acpi-binding.patch pidfs-move-o_rdwr-into-pidfs_alloc_file.patch coredump-fix-error-handling-for-replace_fd.patch coredump-hand-a-pidfd-to-the-usermode-coredump-helper.patch +iommu-avoid-introducing-more-races.patch +iommu-handle-yet-another-race-around-registration.patch -- 2.47.2