From cf0fd404455ce13850cc15423a3c2958933de384 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Wed, 4 Sep 2019 10:54:58 +0300 Subject: firmware: imx: warn on unexpected RX The imx_scu_call_rpc function returns the result inside the same "msg" struct containing the transmitted message. This is implemented by holding a pointer to msg (which is usually on the stack) in sc_imx_rpc and writing to it from imx_scu_rx_callback. This means that if the have_resp parameter is incorrect or SCU sends an unexpected response for any reason the most likely result is kernel stack corruption. Fix this by only setting sc_imx_rpc.msg for the duration of the imx_scu_call_rpc call and warning in imx_scu_rx_callback if unset. Print the unexpected response data to help debugging. Signed-off-by: Leonard Crestez Acked-by: Anson Huang Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/firmware') diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c index 04a24a863d6e..869be7a5172c 100644 --- a/drivers/firmware/imx/imx-scu.c +++ b/drivers/firmware/imx/imx-scu.c @@ -107,6 +107,12 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg) struct imx_sc_rpc_msg *hdr; u32 *data = msg; + if (!sc_ipc->msg) { + dev_warn(sc_ipc->dev, "unexpected rx idx %d 0x%08x, ignore!\n", + sc_chan->idx, *data); + return; + } + if (sc_chan->idx == 0) { hdr = msg; sc_ipc->rx_size = hdr->size; @@ -165,7 +171,8 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp) mutex_lock(&sc_ipc->lock); reinit_completion(&sc_ipc->done); - sc_ipc->msg = msg; + if (have_resp) + sc_ipc->msg = msg; sc_ipc->count = 0; ret = imx_scu_ipc_write(sc_ipc, msg); if (ret < 0) { @@ -187,6 +194,7 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp) } out: + sc_ipc->msg = NULL; mutex_unlock(&sc_ipc->lock); dev_dbg(sc_ipc->dev, "RPC SVC done\n"); -- cgit v1.2.3-58-ga151 From 51f5afabc07a13e3d030076c772a1c36e1687b99 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Mon, 7 Oct 2019 09:15:59 +0800 Subject: firmware: imx: Skip return value check for some special SCU firmware APIs The SCU firmware does NOT always have return value stored in message header's function element even the API has response data, those special APIs are defined as void function in SCU firmware, so they should be treated as return success always. Signed-off-by: Anson Huang Reviewed-by: Marco Felsch Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/firmware') diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c index 869be7a5172c..03b43b7a6d1d 100644 --- a/drivers/firmware/imx/imx-scu.c +++ b/drivers/firmware/imx/imx-scu.c @@ -162,6 +162,7 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg) */ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp) { + uint8_t saved_svc, saved_func; struct imx_sc_rpc_msg *hdr; int ret; @@ -171,8 +172,11 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp) mutex_lock(&sc_ipc->lock); reinit_completion(&sc_ipc->done); - if (have_resp) + if (have_resp) { sc_ipc->msg = msg; + saved_svc = ((struct imx_sc_rpc_msg *)msg)->svc; + saved_func = ((struct imx_sc_rpc_msg *)msg)->func; + } sc_ipc->count = 0; ret = imx_scu_ipc_write(sc_ipc, msg); if (ret < 0) { @@ -191,6 +195,16 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp) /* response status is stored in hdr->func field */ hdr = msg; ret = hdr->func; + /* + * Some special SCU firmware APIs do NOT have return value + * in hdr->func, but they do have response data, those special + * APIs are defined as void function in SCU firmware, so they + * should be treated as return success always. + */ + if ((saved_svc == IMX_SC_RPC_SVC_MISC) && + (saved_func == IMX_SC_MISC_FUNC_UNIQUE_ID || + saved_func == IMX_SC_MISC_FUNC_GET_BUTTON_STATUS)) + ret = 0; } out: -- cgit v1.2.3-58-ga151 From 0e4e8cc30a2940c57448af1376e40d3c0996fb29 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Mon, 14 Oct 2019 18:32:28 +0300 Subject: firmware: imx: Remove call to devm_of_platform_populate IMX DSP device is created by SOF layer. The current call to devm_of_platform_populate is not needed and it doesn't produce any effects. Fixes: ffbf23d50353915d ("firmware: imx: Add DSP IPC protocol interface) Signed-off-by: Daniel Baluta Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/firmware') diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c index a43d2db5cbdb..4265e9dbed84 100644 --- a/drivers/firmware/imx/imx-dsp.c +++ b/drivers/firmware/imx/imx-dsp.c @@ -114,7 +114,7 @@ static int imx_dsp_probe(struct platform_device *pdev) dev_info(dev, "NXP i.MX DSP IPC initialized\n"); - return devm_of_platform_populate(dev); + return 0; out: kfree(chan_name); for (j = 0; j < i; j++) { -- cgit v1.2.3-58-ga151 From e4f9eefbb8a976bb86dbdc9d2dd1a2a113801464 Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Tue, 22 Oct 2019 16:40:09 +0100 Subject: firmware: imx: add missing include of Include for the declarations of the functions exported from this driver. This fixes the following sparse warnings: drivers/firmware/imx/imx-scu-irq.c:45:5: warning: symbol 'imx_scu_irq_register_notifier' was not declared. Should it be static? drivers/firmware/imx/imx-scu-irq.c:52:5: warning: symbol 'imx_scu_irq_unregister_notifier' was not declared. Should it be static? drivers/firmware/imx/imx-scu-irq.c:97:5: warning: symbol 'imx_scu_irq_group_enable' was not declared. Should it be static? drivers/firmware/imx/imx-scu-irq.c:130:5: warning: symbol 'imx_scu_enable_general_irq_channel' was not declared. Should it be static? Signed-off-by: Ben Dooks (Codethink) Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu-irq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/firmware') diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index 687121f8c4d5..db655e87cdc8 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -8,6 +8,7 @@ #include #include +#include #include #define IMX_SC_IRQ_FUNC_ENABLE 1 -- cgit v1.2.3-58-ga151