[PATCH v42 4/7] firmware: imx: device context dedicated to priv
From: <hidden>
Date: 2026-08-24 17:33:41
Also in:
imx, linux-devicetree, linux-doc, lkml
Subsystem:
the rest · Maintainer:
Linus Torvalds
From: Pankaj Gupta <pankaj.gupta@nxp.com> Add priv_dev_ctx to prepare enabling misc-device context based send-receive path, to communicate with FW. No functionality change. Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Frank Li <Frank.Li@nxp.com> --- Changes from v40 to v41 - init_misc_device_context(): drop the pointless err_str local variable and the redundant 'int ret = -ENOMEM' initialiser; return -ENOMEM directly in both OOM paths. No message is printed for -ENOMEM as the MM subsystem already does that. - se_if_probe(): drop the redundant error-code argument (%x) from the dev_err_probe() format string for the init_misc_device_context() failure path; dev_err_probe() already logs the error code. - Add the mandatory trailing newline to every dev_err_probe() format string in se_ctrl.c that was missing one (seven call sites across get_se_soc_info(), se_if_request_channel(), and se_if_probe()). - ele_msg_send(): add missing trailing newline to both dev_err() format strings. --- drivers/firmware/imx/ele_base_msg.c | 15 +++++---- drivers/firmware/imx/ele_common.c | 66 +++++++++++++++++++++++-------------- drivers/firmware/imx/ele_common.h | 8 ++--- drivers/firmware/imx/se_ctrl.c | 33 +++++++++++++++++++ drivers/firmware/imx/se_ctrl.h | 9 +++++ 5 files changed, 95 insertions(+), 36 deletions(-)
diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
index a9a0fc16a553..d63dc4fbd4c8 100644
--- a/drivers/firmware/imx/ele_base_msg.c
+++ b/drivers/firmware/imx/ele_base_msg.c@@ -82,8 +82,9 @@ int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info) tx_msg->data[0] = upper_32_bits(get_info_addr); tx_msg->data[1] = lower_32_bits(get_info_addr); tx_msg->data[2] = sizeof(*s_info); - ret = ele_msg_send_rcv(priv, tx_msg, ELE_GET_INFO_REQ_MSG_SZ, rx_msg, - ELE_GET_INFO_RSP_MSG_SZ); + + ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_GET_INFO_REQ_MSG_SZ, + rx_msg, ELE_GET_INFO_RSP_MSG_SZ); if (ret < 0) { ele_get_info_cleanup(priv, get_info_data, get_info_addr, get_info_len); return ret;
@@ -143,8 +144,8 @@ int ele_ping(struct se_if_priv *priv) se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header, ELE_PING_REQ, ELE_PING_REQ_SZ, true); - ret = ele_msg_send_rcv(priv, tx_msg, ELE_PING_REQ_SZ, rx_msg, - ELE_PING_RSP_SZ); + ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_PING_REQ_SZ, + rx_msg, ELE_PING_RSP_SZ); if (ret < 0) return ret;
@@ -201,7 +202,7 @@ int ele_service_swap(struct se_if_priv *priv, if (ret) return -EINVAL; - ret = ele_msg_send_rcv(priv, tx_msg, ELE_SERVICE_SWAP_REQ_MSG_SZ, + ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_SERVICE_SWAP_REQ_MSG_SZ, rx_msg, ELE_SERVICE_SWAP_RSP_MSG_SZ); if (ret < 0) return ret;
@@ -257,7 +258,7 @@ int ele_fw_authenticate(struct se_if_priv *priv, dma_addr_t contnr_addr, tx_msg->data[1] = 0; tx_msg->data[2] = lower_32_bits(img_addr); - ret = ele_msg_send_rcv(priv, tx_msg, ELE_FW_AUTH_REQ_SZ, rx_msg, + ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_FW_AUTH_REQ_SZ, rx_msg, ELE_FW_AUTH_RSP_MSG_SZ); if (ret < 0) return ret;
@@ -305,7 +306,7 @@ int ele_debug_dump(struct se_if_priv *priv) do { memset(rx_msg, 0x0, ELE_DEBUG_DUMP_RSP_SZ); - ret = ele_msg_send_rcv(priv, tx_msg, ELE_DEBUG_DUMP_REQ_SZ, + ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_DEBUG_DUMP_REQ_SZ, rx_msg, ELE_DEBUG_DUMP_RSP_SZ); if (ret < 0) return ret;
diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
index 74cdac45231c..f7a6df5ea582 100644
--- a/drivers/firmware/imx/ele_common.c
+++ b/drivers/firmware/imx/ele_common.c@@ -47,7 +47,7 @@ int se_update_msg_chksum(u32 *msg, u32 msg_len) /** * ele_msg_rcv() - wait for a response from the secure enclave. - * @priv: pointer to the SE interface private data. + * @dev_ctx: pointer to the SE dev context data. * @se_clbk_hdl: callback handle whose completion will be signaled when the * response arrives. *
@@ -60,8 +60,9 @@ int se_update_msg_chksum(u32 *msg, u32 msg_len) * Return: number of bytes received on success, negative errno on error * (e.g. -ETIMEDOUT, -ERESTARTSYS). */ -int ele_msg_rcv(struct se_if_priv *priv, struct se_clbk_handle *se_clbk_hdl) +int ele_msg_rcv(struct se_if_device_ctx *dev_ctx, struct se_clbk_handle *se_clbk_hdl) { + struct se_if_priv *priv = dev_ctx->priv; bool is_rsp_wait_with_timeout = false; bool wait_uninterruptible = false; unsigned long remaining_jiffies;
@@ -150,7 +151,7 @@ int ele_msg_rcv(struct se_if_priv *priv, struct se_clbk_handle *se_clbk_hdl) /** * ele_msg_send() - send a message to the secure enclave over the mailbox. - * @priv: pointer to the SE interface private data. + * @dev_ctx: pointer to the SE device context. * @tx_msg: buffer containing the message to send. * @tx_msg_sz: size of @tx_msg in bytes; must match the size field in the * message header.
@@ -161,7 +162,7 @@ int ele_msg_rcv(struct se_if_priv *priv, struct se_clbk_handle *se_clbk_hdl) * * Return: @tx_msg_sz on success, negative errno on error. */ -int ele_msg_send(struct se_if_priv *priv, +int ele_msg_send(struct se_if_device_ctx *dev_ctx, void *tx_msg, int tx_msg_sz) {
@@ -173,9 +174,9 @@ int ele_msg_send(struct se_if_priv *priv, * carried in the message. */ if (header->size << 2 != tx_msg_sz) { - dev_err(priv->dev, - "User buf hdr: 0x%x, sz mismatched with input-sz (%d != %d).\n", - *(u32 *)header, header->size << 2, tx_msg_sz); + dev_err(dev_ctx->priv->dev, + "%s: User buf hdr: 0x%x, sz mismatched with input-sz (%d != %d).\n", + dev_ctx->devname, *(u32 *)header, header->size << 2, tx_msg_sz); return -EINVAL; }
@@ -185,9 +186,10 @@ int ele_msg_send(struct se_if_priv *priv, * caller-provided tx_msg pointer after mbox_send_message() returns, so * the caller-owned buffer may be released after a successful send. */ - err = mbox_send_message(priv->tx_chan, tx_msg); + err = mbox_send_message(dev_ctx->priv->tx_chan, tx_msg); if (err < 0) { - dev_err(priv->dev, "Error: mbox_send_message failure.\n"); + dev_err(dev_ctx->priv->dev, + "%s: Error: mbox_send_message failure.\n", dev_ctx->devname); return err; }
@@ -199,6 +201,7 @@ static void ele_msg_send_rcv_cleanup(struct se_if_priv *priv) unsigned long flags; spin_lock_irqsave(&priv->waiting_rsp_clbk_hdl.clbk_rx_lock, flags); + priv->waiting_rsp_clbk_hdl.dev_ctx = NULL; priv->waiting_rsp_clbk_hdl.rx_msg = NULL; priv->waiting_rsp_clbk_hdl.rx_msg_sz = 0; spin_unlock_irqrestore(&priv->waiting_rsp_clbk_hdl.clbk_rx_lock, flags);
@@ -206,7 +209,7 @@ static void ele_msg_send_rcv_cleanup(struct se_if_priv *priv) /** * ele_msg_send_rcv() - send a command and wait for the response. - * @priv: pointer to the SE interface private data. + * @dev_ctx: pointer to the dev_ctx data. * @tx_msg: buffer containing the command message to send. * @tx_msg_sz: size of @tx_msg in bytes. * @rx_msg: caller-provided buffer to receive the response into.
@@ -219,32 +222,34 @@ static void ele_msg_send_rcv_cleanup(struct se_if_priv *priv) * * Return: number of bytes received on success, negative errno on error. */ -int ele_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz, - void *rx_msg, int exp_rx_msg_sz) +int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx, void *tx_msg, + int tx_msg_sz, void *rx_msg, int exp_rx_msg_sz) { + struct se_if_priv *priv = dev_ctx->priv; unsigned long flags; int err; guard(mutex)(&priv->se_if_cmd_lock); if (atomic_read(&priv->fw_busy)) { - dev_dbg(priv->dev, "ELE became unresponsive.\n"); + dev_dbg(priv->dev, "%s: ELE became unresponsive.\n", dev_ctx->devname); return -EBUSY; } reinit_completion(&priv->waiting_rsp_clbk_hdl.done); /* Publish rx_msg/rx_msg_sz under the lock read by se_if_rx_callback(). */ spin_lock_irqsave(&priv->waiting_rsp_clbk_hdl.clbk_rx_lock, flags); + priv->waiting_rsp_clbk_hdl.dev_ctx = dev_ctx; priv->waiting_rsp_clbk_hdl.rx_msg_sz = exp_rx_msg_sz; priv->waiting_rsp_clbk_hdl.rx_msg = rx_msg; spin_unlock_irqrestore(&priv->waiting_rsp_clbk_hdl.clbk_rx_lock, flags); - err = ele_msg_send(priv, tx_msg, tx_msg_sz); + err = ele_msg_send(dev_ctx, tx_msg, tx_msg_sz); if (err < 0) { ele_msg_send_rcv_cleanup(priv); return err; } - err = ele_msg_rcv(priv, &priv->waiting_rsp_clbk_hdl); + err = ele_msg_rcv(dev_ctx, &priv->waiting_rsp_clbk_hdl); if (priv->waiting_rsp_clbk_hdl.signal_rcvd) { /*
@@ -255,7 +260,8 @@ int ele_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz, if (err > 0) err = -ERESTARTSYS; priv->waiting_rsp_clbk_hdl.signal_rcvd = false; - dev_dbg(priv->dev, "Err[0x%x]:Interrupted by signal.\n", err); + dev_dbg(priv->dev, "%s: Err[0x%x]:Interrupted by signal.\n", + dev_ctx->devname, err); } ele_msg_send_rcv_cleanup(priv);
@@ -290,6 +296,11 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg) { struct se_clbk_handle *se_clbk_hdl; struct device *dev = mbox_cl->dev; + /* + * devname_snap: a local copy of dev_ctx->devname taken while + * clbk_rx_lock is held. + */ + char devname_snap[32]; struct se_msg_hdr *header; bool sz_mismatch = false; struct se_if_priv *priv;
@@ -313,7 +324,7 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg) if (header->tag == priv->if_defs->cmd_tag) { se_clbk_hdl = &priv->cmd_receiver_clbk_hdl; spin_lock_irqsave(&se_clbk_hdl->clbk_rx_lock, flags); - if (!se_clbk_hdl->rx_msg) { + if (!se_clbk_hdl->dev_ctx || !se_clbk_hdl->rx_msg) { spin_unlock_irqrestore(&se_clbk_hdl->clbk_rx_lock, flags); dev_warn(dev, "No command receiver registered for message: %.8x\n", *((u32 *)header));
@@ -327,8 +338,8 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg) * SE_IOCTL_ENABLE_CMD_RCV and is not subject to the timeout/circuit- * breaker handling used for rsp_tag messages. */ - dev_dbg(dev, "Selecting cmd receiver: for mesg header:0x%x.\n", - *(u32 *)header); + dev_dbg(dev, "Selecting cmd receiver:%s for mesg header:0x%x.\n", + se_clbk_hdl->dev_ctx->devname, *(u32 *)header); /* * Pre-allocated buffer of MAX_NVM_MSG_LEN
@@ -343,13 +354,15 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg) * Clamp the copy length to the pre-allocated receiver buffer (MAX_NVM_MSG_LEN). */ se_clbk_hdl->rx_msg_sz = min(rx_msg_sz, MAX_NVM_MSG_LEN); + strscpy(devname_snap, se_clbk_hdl->dev_ctx->devname, + sizeof(devname_snap)); memcpy(se_clbk_hdl->rx_msg, msg, se_clbk_hdl->rx_msg_sz); complete(&se_clbk_hdl->done); spin_unlock_irqrestore(&se_clbk_hdl->clbk_rx_lock, flags); if (sz_mismatch) dev_err(dev, - "CMD-RCVER NVM: hdr(0x%x) with different sz(%d != %d).\n", - *(u32 *)header, + "%s: CMD-RCVER NVM: hdr(0x%x) with different sz(%d != %d).\n", + devname_snap, *(u32 *)header, (header->size << 2), rx_msg_sz); } else if (header->tag == priv->if_defs->rsp_tag) { bool exception_for_sz_mismatch = check_hdr_exception_for_sz(priv, header);
@@ -371,8 +384,8 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg) return; } exp_rx_msg_sz = se_clbk_hdl->rx_msg_sz; - dev_dbg(dev, "Selecting resp waiter: for mesg header:0x%x.\n", - *(u32 *)header); + dev_dbg(dev, "Selecting resp waiter:%s for mesg header:0x%x.\n", + se_clbk_hdl->dev_ctx->devname, *(u32 *)header); /* * For rsp_tag traffic, the sender provides the expected response
@@ -384,14 +397,17 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg) sz_mismatch = true; se_clbk_hdl->rx_msg_sz = min(rx_msg_sz, exp_rx_msg_sz); + /* Snapshot devname before complete() can free the context. */ + strscpy(devname_snap, se_clbk_hdl->dev_ctx->devname, + sizeof(devname_snap)); memcpy(se_clbk_hdl->rx_msg, msg, se_clbk_hdl->rx_msg_sz); complete(&se_clbk_hdl->done); spin_unlock_irqrestore(&se_clbk_hdl->clbk_rx_lock, flags); if (sz_mismatch) dev_err(dev, - "Rsp to CMD: hdr(0x%x) with different sz(%d != %d).\n", - *(u32 *)header, + "%s: Rsp to CMD: hdr(0x%x) with different sz(%d != %d).\n", + devname_snap, *(u32 *)header, (header->size << 2), exp_rx_msg_sz); } else { dev_err(dev, "Failed to select a device for message: %.8x\n",
diff --git a/drivers/firmware/imx/ele_common.h b/drivers/firmware/imx/ele_common.h
index 7bf2febefc45..07e6b6a1bafa 100644
--- a/drivers/firmware/imx/ele_common.h
+++ b/drivers/firmware/imx/ele_common.h@@ -16,12 +16,12 @@ int se_update_msg_chksum(u32 *msg, u32 msg_len); -int ele_msg_rcv(struct se_if_priv *priv, struct se_clbk_handle *se_clbk_hdl); +int ele_msg_rcv(struct se_if_device_ctx *dev_ctx, struct se_clbk_handle *se_clbk_hdl); -int ele_msg_send(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz); +int ele_msg_send(struct se_if_device_ctx *dev_ctx, void *tx_msg, int tx_msg_sz); -int ele_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz, - void *rx_msg, int exp_rx_msg_sz); +int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx, void *tx_msg, + int tx_msg_sz, void *rx_msg, int exp_rx_msg_sz); void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg);
diff --git a/drivers/firmware/imx/se_ctrl.c b/drivers/firmware/imx/se_ctrl.c
index 9e3f81a9a272..0792e5152436 100644
--- a/drivers/firmware/imx/se_ctrl.c
+++ b/drivers/firmware/imx/se_ctrl.c@@ -293,6 +293,29 @@ static int get_se_soc_info(struct se_if_priv *priv, const struct se_soc_info *se return 0; } +static int init_misc_device_context(struct se_if_priv *priv, int ch_id, + struct se_if_device_ctx **new_dev_ctx) +{ + struct se_if_device_ctx *dev_ctx; + + dev_ctx = kzalloc_obj(*dev_ctx, GFP_KERNEL); + if (!dev_ctx) + return -ENOMEM; + + dev_ctx->devname = kasprintf(GFP_KERNEL, "%s0_ch%d", + get_se_if_name(priv->if_defs->se_if_type), + ch_id); + if (!dev_ctx->devname) { + kfree(dev_ctx); + return -ENOMEM; + } + + dev_ctx->priv = priv; + *new_dev_ctx = dev_ctx; + + return 0; +} + static int se_if_request_channel(struct device *dev, struct mbox_chan **chan, struct mbox_client *cl, const char *name) {
@@ -337,6 +360,11 @@ static void se_if_probe_cleanup(void *plat_dev) dev_set_drvdata(dev, NULL); + if (priv->priv_dev_ctx) { + kfree(priv->priv_dev_ctx->devname); + kfree(priv->priv_dev_ctx); + } + kfree(priv); }
@@ -438,6 +466,11 @@ static int se_if_probe(struct platform_device *pdev) load_fw->imem_mgmt = true; } + ret = init_misc_device_context(priv, 0, &priv->priv_dev_ctx); + if (ret) + return dev_err_probe(dev, ret, + "Failed to create device contexts.\n"); + if (if_node->if_defs.se_if_type == SE_TYPE_ID_HSM) { ret = get_se_soc_info(priv, se_info); if (ret)
diff --git a/drivers/firmware/imx/se_ctrl.h b/drivers/firmware/imx/se_ctrl.h
index 54b2a262a2c3..dd4a1ea7e35a 100644
--- a/drivers/firmware/imx/se_ctrl.h
+++ b/drivers/firmware/imx/se_ctrl.h@@ -20,6 +20,7 @@ #define MESSAGING_VERSION_7 0x7 struct se_clbk_handle { + struct se_if_device_ctx *dev_ctx; struct completion done; bool signal_rcvd; u32 rx_msg_sz;
@@ -44,6 +45,12 @@ struct se_imem_buf { u32 state; }; +/* Private struct for each char device instance. */ +struct se_if_device_ctx { + struct se_if_priv *priv; + const char *devname; +}; + /* Header of the messages exchange with the EdgeLock Enclave */ struct se_msg_hdr { u8 ver;
@@ -106,6 +113,8 @@ struct se_if_priv { struct se_fw_load_info load_fw; atomic_t fw_busy; + + struct se_if_device_ctx *priv_dev_ctx; }; char *get_se_if_name(u8 se_if_id);
--
2.43.0