From: Sudeep Holla <sudeep.holla@kernel.org>
To: arm-scmi@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Cc: Cristian Marussi <cristian.marussi@arm.com>
Subject: [PATCH v3 16/17] firmware: arm_scmi: Drop handle on protocol bind failures
Date: Fri, 03 Jul 2026 21:22:52 +0100 [thread overview]
Message-ID: <20260703-scmi_core_fixes-v3-16-5bae9766abfc@kernel.org> (raw)
In-Reply-To: <20260703-scmi_core_fixes-v3-0-5bae9766abfc@kernel.org>
The SCMI bus notifier acquires an SCMI handle when the driver core emits
BUS_NOTIFY_BIND_DRIVER, before invoking the protocol driver probe
callback. The protocol probe path only checks whether sdev->handle is
set.
If device_link_add() fails after the handle has been acquired, the
protocol device can still bind with a valid handle but without the
dependency link to the SCMI parent. A concurrent parent unbind can then
miss the child and tear down the SCMI instance while the child still
holds a handle into it.
If the protocol driver probe later fails, for example with
-EPROBE_DEFER, the driver core emits BUS_NOTIFY_DRIVER_NOT_BOUND rather
than BUS_NOTIFY_UNBOUND_DRIVER. The SCMI notifier only released the
handle on BUS_NOTIFY_UNBOUND_DRIVER, so each failed protocol-device bind
leaked the SCMI instance users refcount and left sdev->handle set after
the failed probe.
Make the link helper report failure and drop the acquired handle if the
link cannot be created. Also handle BUS_NOTIFY_DRIVER_NOT_BOUND in the
same cleanup path used for unbind so failed probes balance the earlier
BUS_NOTIFY_BIND_DRIVER acquisition.
Fixes: 971fc0665f13 ("firmware: arm_scmi: Move handle get/set helpers")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
---
drivers/firmware/arm_scmi/driver.c | 31 +++++++++++++++++++++++--------
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 12ebf32aa4da..894c3427bc0b 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2629,21 +2629,31 @@ static int scmi_handle_put(const struct scmi_handle *handle)
return 0;
}
-static void scmi_device_link_add(struct device *consumer,
+static bool scmi_device_link_add(struct device *consumer,
struct device *supplier)
{
struct device_link *link;
link = device_link_add(consumer, supplier, DL_FLAG_AUTOREMOVE_CONSUMER);
- WARN_ON(!link);
+ return !WARN_ON(!link);
+}
+
+static void scmi_clear_handle(struct scmi_device *scmi_dev)
+{
+ if (!scmi_dev->handle)
+ return;
+
+ scmi_handle_put(scmi_dev->handle);
+ scmi_dev->handle = NULL;
}
static void scmi_set_handle(struct scmi_device *scmi_dev)
{
scmi_dev->handle = scmi_handle_get(&scmi_dev->dev);
- if (scmi_dev->handle)
- scmi_device_link_add(&scmi_dev->dev, scmi_dev->handle->dev);
+ if (scmi_dev->handle &&
+ !scmi_device_link_add(&scmi_dev->dev, scmi_dev->handle->dev))
+ scmi_clear_handle(scmi_dev);
}
static int __scmi_xfer_info_init(struct scmi_info *sinfo,
@@ -2926,6 +2936,7 @@ static int scmi_bus_notifier(struct notifier_block *nb,
{
struct scmi_info *info = bus_nb_to_scmi_info(nb);
struct scmi_device *sdev = to_scmi_dev(data);
+ const char *status;
/* Skip devices of different SCMI instances */
if (sdev->dev.parent != info->dev)
@@ -2935,18 +2946,22 @@ static int scmi_bus_notifier(struct notifier_block *nb,
case BUS_NOTIFY_BIND_DRIVER:
/* setup handle now as the transport is ready */
scmi_set_handle(sdev);
+ status = "about to be BOUND.";
+ break;
+ case BUS_NOTIFY_DRIVER_NOT_BOUND:
+ scmi_clear_handle(sdev);
+ status = "NOT BOUND.";
break;
case BUS_NOTIFY_UNBOUND_DRIVER:
- scmi_handle_put(sdev->handle);
- sdev->handle = NULL;
+ scmi_clear_handle(sdev);
+ status = "UNBOUND.";
break;
default:
return NOTIFY_DONE;
}
dev_dbg(info->dev, "Device %s (%s) is now %s\n", dev_name(&sdev->dev),
- sdev->name, action == BUS_NOTIFY_BIND_DRIVER ?
- "about to be BOUND." : "UNBOUND.");
+ sdev->name, status);
return NOTIFY_OK;
}
--
2.43.0
next prev parent reply other threads:[~2026-07-03 20:25 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-03 20:22 [PATCH v3 00/17] firmware: arm_scmi: Fix SCMI core cleanup paths Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 01/17] firmware: arm_scmi: Fix OF node reference handling Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 02/17] firmware: arm_scmi: Fix transport device teardown lookup Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 03/17] firmware: arm_scmi: Clean up channels on setup failure Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 04/17] firmware: arm_scmi: Fix SCMI device destroy lifetimes Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 05/17] firmware: arm_scmi: Free transport channel on IDR failure Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 06/17] firmware: arm_scmi: Unregister device notifier before IDR teardown Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 07/17] firmware: arm_scmi: Unwind TX receiver mailbox setup failure Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 08/17] firmware: arm_scmi: Unwind P2A " Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 09/17] firmware: arm_scmi: Protect device request lookup with RCU Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 10/17] firmware: arm_scmi: Avoid IDR updates while cleaning channels Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 11/17] firmware: arm_scmi: Clear SystemPower flag on create failure Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 12/17] firmware: arm_scmi: Reject out of range DT protocol IDs Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 13/17] firmware: arm_scmi: Stop channels before notification teardown Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 14/17] firmware: arm_scmi: Publish channel state before mailbox request Sudeep Holla
2026-07-03 20:22 ` [PATCH v3 15/17] firmware: arm_scmi: Use channel ID for transport teardown Sudeep Holla
2026-07-03 20:22 ` Sudeep Holla [this message]
2026-07-03 20:22 ` [PATCH v3 17/17] firmware: arm_scmi: Clear virtio channel lists on free Sudeep Holla
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260703-scmi_core_fixes-v3-16-5bae9766abfc@kernel.org \
--to=sudeep.holla@kernel.org \
--cc=arm-scmi@vger.kernel.org \
--cc=cristian.marussi@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox