From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 557403E63A4 for ; Wed, 8 Jul 2026 09:00:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783501227; cv=none; b=hUf9ch+g1E12c6eAWdx4HuJw9LeVzbbt40uleV89ejFR1/RkA9qGXlQYYbMqYwdH73643RzvNsWKWr9e2oojkoEVdC0iKNxd97HxeWPxhIXI638DzFNdmWk1Ii/EfSTc35QndxvPhEBsM8s4kYfB/zxUY7SHcn8ZXKcFWN2onNQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783501227; c=relaxed/simple; bh=2zMjeYJ+1ak6XHLCk9VkRQSzeHjH1fPpMM/wkfBT8tE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Q7FwV8zkpPk+ZWTRl6iLrxovPkmQ4Fyx27Z542FZkrsYbG8wJ3XLPv6wiYf5tuDl8FUFXHRVQo4xSJqvRh125PmhUcj8oFafXou+aX+jJVio/IOnmmx0MkvX5B/0yXo677AJddwV/olP20x1fWEmCMGjs7bPgmmdGaeO7W8JP1g= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k91u+TW6; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="k91u+TW6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 83F6B1F00A3A; Wed, 8 Jul 2026 09:00:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783501226; bh=LIP5sA6CbF1eR02kWXqug5HbdDA/BAiLc/L7lQ0febQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=k91u+TW6gJfK8oS31dlL3XO7svN77k+kpwfskIgDaee53ff7l3UnBBdbgnJzAW+6s a0kHorJUu9zYQlewOgkMpplz0lT0pPXy8zkkUopxSoZ1qGVONp28EMFNXFJhyiwX/6 H9hnrhKAc8rAo/vO2U7UhsiNVjpF7VpNLNA12ZqTObfYqfqOtNtyHyisvUoXGECY3J MhIuontO24DYRHteJ+6wAmqdNEww8yeE70vFLKsnLi6l3GQbfy5Uivv7uvRvfykHkU T2YCi0ETouvDJ+hVTMYvBX4zMDSf86V9bkjHUcI6lsaX/8HVFnMKNmYij6peA3LuiE bSnyK+DWxJzmg== From: Sudeep Holla Date: Wed, 08 Jul 2026 09:59:57 +0100 Subject: [PATCH v4 01/16] firmware: arm_scmi: Publish channel state before callbacks Precedence: bulk X-Mailing-List: arm-scmi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260708-scmi_core_fixes-v4-1-53142cd60b63@kernel.org> References: <20260708-scmi_core_fixes-v4-0-53142cd60b63@kernel.org> In-Reply-To: <20260708-scmi_core_fixes-v4-0-53142cd60b63@kernel.org> To: arm-scmi@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Cristian Marussi X-Mailer: b4 0.15.2 Transport setup can enable callbacks before the setup routine returns. mailbox_chan_setup() registers the mailbox client with mbox_request_channel(), and the mailbox controller startup path can enable interrupt delivery before SCMI mailbox channel state has been published. Similarly, smc_chan_setup() requests the optional A2P completion IRQ before the SMC transport has made its cinfo pointer visible. If a pending or spurious callback fires in those windows, the transport RX callback can dereference a NULL transport cinfo pointer. Publishing only the transport-private pointer is not sufficient either: an early callback can enter the SCMI core before scmi_chan_setup() has assigned cinfo->handle. The core derives scmi_info from cinfo->handle in the RX path, so a NULL handle can still fault even when the transport-private cinfo is valid. Assign cinfo->handle before invoking the transport setup callback. Publish the mailbox and SMC transport-private channel state before requesting the mailbox channels or IRQ, and clear the early-published pointers again on setup failure. Also unwind mailbox setup devres resources on failure so an optional RX setup error that is ignored by the core does not leave stale transport state behind. Fixes: 5c8a47a5a91d ("firmware: arm_scmi: Make scmi core independent of the transport type") Reported-by: Sashiko Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/driver.c | 2 +- drivers/firmware/arm_scmi/transports/mailbox.c | 18 +++++++++++++----- drivers/firmware/arm_scmi/transports/smc.c | 15 +++++++++------ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 3e0d975ec94c..1d1f5d25d773 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -2782,6 +2782,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, cinfo->id = prot_id; cinfo->dev = &tdev->dev; + cinfo->handle = &info->handle; ret = info->desc->ops->chan_setup(cinfo, info->dev, tx); if (ret) { of_node_put(of_node); @@ -2814,7 +2815,6 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, return ret; } - cinfo->handle = &info->handle; return 0; } diff --git a/drivers/firmware/arm_scmi/transports/mailbox.c b/drivers/firmware/arm_scmi/transports/mailbox.c index ae0f67e6cc45..b6459fbb8151 100644 --- a/drivers/firmware/arm_scmi/transports/mailbox.c +++ b/drivers/firmware/arm_scmi/transports/mailbox.c @@ -211,13 +211,18 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, cl->tx_block = false; cl->knows_txdone = tx; + cinfo->transport_info = smbox; + smbox->cinfo = cinfo; + mutex_init(&smbox->chan_lock); + smbox->chan = mbox_request_channel(cl, tx ? 0 : p2a_chan); if (IS_ERR(smbox->chan)) { ret = PTR_ERR(smbox->chan); + smbox->chan = NULL; if (ret != -EPROBE_DEFER) dev_err(cdev, "failed to request SCMI %s mailbox\n", desc); - return ret; + goto err_clear_cinfo; } /* Additional unidirectional channel for TX if needed */ @@ -241,11 +246,14 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, } } - cinfo->transport_info = smbox; - smbox->cinfo = cinfo; - mutex_init(&smbox->chan_lock); - return 0; + +err_clear_cinfo: + cinfo->transport_info = NULL; + smbox->cinfo = NULL; + devm_iounmap(dev, smbox->shmem); + devm_kfree(dev, smbox); + return ret; } static int mailbox_chan_free(int id, void *p, void *data) diff --git a/drivers/firmware/arm_scmi/transports/smc.c b/drivers/firmware/arm_scmi/transports/smc.c index 21abb571e4f2..1fce3ccdeb7f 100644 --- a/drivers/firmware/arm_scmi/transports/smc.c +++ b/drivers/firmware/arm_scmi/transports/smc.c @@ -172,6 +172,13 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, scmi_info->param_page = SHMEM_PAGE(res.start); scmi_info->param_offset = SHMEM_OFFSET(res.start); } + + scmi_info->func_id = func_id; + scmi_info->cap_id = cap_id; + scmi_info->cinfo = cinfo; + smc_channel_lock_init(scmi_info); + cinfo->transport_info = scmi_info; + /* * If there is an interrupt named "a2p", then the service and * completion of a message is signaled by an interrupt rather than by @@ -183,18 +190,14 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, IRQF_NO_SUSPEND, dev_name(dev), scmi_info); if (ret) { dev_err(dev, "failed to setup SCMI smc irq\n"); + cinfo->transport_info = NULL; + scmi_info->cinfo = NULL; return ret; } } else { cinfo->no_completion_irq = true; } - scmi_info->func_id = func_id; - scmi_info->cap_id = cap_id; - scmi_info->cinfo = cinfo; - smc_channel_lock_init(scmi_info); - cinfo->transport_info = scmi_info; - return 0; } -- 2.43.0