From abe13e9a561d6b3e82b21362c0d6dd3ecd8a5b13 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Sat, 21 May 2022 11:35:05 +0800 Subject: [PATCH 01/10] rpmsg: char: Add mutex protection for rpmsg_eptdev_open() There is no mutex protection for rpmsg_eptdev_open(), especially for eptdev->ept read and write operation. It may cause issues when multiple instances call rpmsg_eptdev_open() in parallel,the return state may be success or EBUSY. Fixes: 964e8bedd5a1 ("rpmsg: char: Return an error if device already open") Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1653104105-16779-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mathieu Poirier --- drivers/rpmsg/rpmsg_char.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c index b6183d4f62a2..4f2189111494 100644 --- a/drivers/rpmsg/rpmsg_char.c +++ b/drivers/rpmsg/rpmsg_char.c @@ -120,8 +120,11 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp) struct rpmsg_device *rpdev = eptdev->rpdev; struct device *dev = &eptdev->dev; - if (eptdev->ept) + mutex_lock(&eptdev->ept_lock); + if (eptdev->ept) { + mutex_unlock(&eptdev->ept_lock); return -EBUSY; + } get_device(dev); @@ -137,11 +140,13 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp) if (!ept) { dev_err(dev, "failed to open %s\n", eptdev->chinfo.name); put_device(dev); + mutex_unlock(&eptdev->ept_lock); return -EINVAL; } eptdev->ept = ept; filp->private_data = eptdev; + mutex_unlock(&eptdev->ept_lock); return 0; } From 353d9214682e65c55cdffad8c82139a3321c5f13 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 25 May 2022 11:12:01 +0200 Subject: [PATCH 02/10] rpmsg: mtk_rpmsg: Fix circular locking dependency During execution of the worker that's used to register rpmsg devices we are safely locking the channels mutex but, when creating a new endpoint for such devices, we are registering a IPI on the SCP, which then makes the SCP to trigger an interrupt, lock its own mutex and in turn register more subdevices. This creates a circular locking dependency situation, as the mtk_rpmsg channels_lock will then depend on the SCP IPI lock. [ 15.447736] ====================================================== [ 15.460158] WARNING: possible circular locking dependency detected [ 15.460161] 5.17.0-next-20220324+ #399 Not tainted [ 15.460165] ------------------------------------------------------ [ 15.460166] kworker/0:3/155 is trying to acquire lock: [ 15.460170] ffff5b4d0eaf1308 (&scp->ipi_desc[i].lock){+.+.}-{4:4}, at: scp_ipi_lock+0x34/0x50 [mtk_scp_ipi] [ 15.504958] [] but task is already holding lock: [ 15.504960] ffff5b4d0e8f1918 (&mtk_subdev->channels_lock){+.+.}-{4:4}, at: mtk_register_device_work_function+0x50/0x1cc [mtk_rpmsg] [ 15.504978] [] which lock already depends on the new lock. [ 15.504980] [] the existing dependency chain (in reverse order) is: [ 15.504982] [] -> #1 (&mtk_subdev->channels_lock){+.+.}-{4:4}: [ 15.504990] lock_acquire+0x68/0x84 [ 15.504999] __mutex_lock+0xa4/0x3e0 [ 15.505007] mutex_lock_nested+0x40/0x70 [ 15.505012] mtk_rpmsg_ns_cb+0xe4/0x134 [mtk_rpmsg] [ 15.641684] mtk_rpmsg_ipi_handler+0x38/0x64 [mtk_rpmsg] [ 15.641693] scp_ipi_handler+0xbc/0x180 [mtk_scp] [ 15.663905] mt8192_scp_irq_handler+0x44/0xa4 [mtk_scp] [ 15.663915] scp_irq_handler+0x6c/0xa0 [mtk_scp] [ 15.685779] irq_thread_fn+0x34/0xa0 [ 15.685785] irq_thread+0x18c/0x240 [ 15.685789] kthread+0x104/0x110 [ 15.709579] ret_from_fork+0x10/0x20 [ 15.709586] [] -> #0 (&scp->ipi_desc[i].lock){+.+.}-{4:4}: [ 15.731271] __lock_acquire+0x11e4/0x1910 [ 15.740367] lock_acquire.part.0+0xd8/0x220 [ 15.749813] lock_acquire+0x68/0x84 [ 15.757861] __mutex_lock+0xa4/0x3e0 [ 15.766084] mutex_lock_nested+0x40/0x70 [ 15.775006] scp_ipi_lock+0x34/0x50 [mtk_scp_ipi] [ 15.785503] scp_ipi_register+0x40/0xa4 [mtk_scp_ipi] [ 15.796697] scp_register_ipi+0x1c/0x30 [mtk_scp] [ 15.807194] mtk_rpmsg_create_ept+0xa0/0x108 [mtk_rpmsg] [ 15.818912] rpmsg_create_ept+0x44/0x60 [ 15.827660] cros_ec_rpmsg_probe+0x15c/0x1f0 [ 15.837282] rpmsg_dev_probe+0x128/0x1d0 [ 15.846203] really_probe.part.0+0xa4/0x2a0 [ 15.855649] __driver_probe_device+0xa0/0x150 [ 15.865443] driver_probe_device+0x48/0x150 [ 15.877157] __device_attach_driver+0xc0/0x12c [ 15.889359] bus_for_each_drv+0x80/0xe0 [ 15.900330] __device_attach+0xe4/0x190 [ 15.911303] device_initial_probe+0x1c/0x2c [ 15.922969] bus_probe_device+0xa8/0xb0 [ 15.933927] device_add+0x3a8/0x8a0 [ 15.944193] device_register+0x28/0x40 [ 15.954970] rpmsg_register_device+0x5c/0xa0 [ 15.966782] mtk_register_device_work_function+0x148/0x1cc [mtk_rpmsg] [ 15.983146] process_one_work+0x294/0x664 [ 15.994458] worker_thread+0x7c/0x45c [ 16.005069] kthread+0x104/0x110 [ 16.014789] ret_from_fork+0x10/0x20 [ 16.025201] [] other info that might help us debug this: [ 16.047769] Possible unsafe locking scenario: [ 16.063942] CPU0 CPU1 [ 16.075166] ---- ---- [ 16.086376] lock(&mtk_subdev->channels_lock); [ 16.097592] lock(&scp->ipi_desc[i].lock); [ 16.113188] lock(&mtk_subdev->channels_lock); [ 16.129482] lock(&scp->ipi_desc[i].lock); [ 16.140020] [] *** DEADLOCK *** [ 16.158282] 4 locks held by kworker/0:3/155: [ 16.168978] #0: ffff5b4d00008748 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x1fc/0x664 [ 16.190017] #1: ffff80000953bdc8 ((work_completion)(&mtk_subdev->register_work)){+.+.}-{0:0}, at: process_one_work+0x1fc/0x664 [ 16.215269] #2: ffff5b4d0e8f1918 (&mtk_subdev->channels_lock){+.+.}-{4:4}, at: mtk_register_device_work_function+0x50/0x1cc [mtk_rpmsg] [ 16.242131] #3: ffff5b4d05964190 (&dev->mutex){....}-{4:4}, at: __device_attach+0x44/0x190 To solve this, simply unlock the channels_lock mutex before calling mtk_rpmsg_register_device() and relock it right after, as safety is still ensured by the locking mechanism that happens right after through SCP. Fixes: 7017996951fd ("rpmsg: add rpmsg support for mt8183 SCP.") Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220525091201.14210-1-angelogioacchino.delregno@collabora.com Signed-off-by: Mathieu Poirier --- drivers/rpmsg/mtk_rpmsg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/rpmsg/mtk_rpmsg.c b/drivers/rpmsg/mtk_rpmsg.c index 5b4404b8be4c..d1213c33da20 100644 --- a/drivers/rpmsg/mtk_rpmsg.c +++ b/drivers/rpmsg/mtk_rpmsg.c @@ -234,7 +234,9 @@ static void mtk_register_device_work_function(struct work_struct *register_work) if (info->registered) continue; + mutex_unlock(&subdev->channels_lock); ret = mtk_rpmsg_register_device(subdev, &info->info); + mutex_lock(&subdev->channels_lock); if (ret) { dev_err(&pdev->dev, "Can't create rpmsg_device\n"); continue; From 416b992b05c94cd691a1909f10e333f02cb81e56 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Mon, 25 Apr 2022 09:17:23 +0200 Subject: [PATCH 03/10] rpmsg: Fix parameter naming for announce_create/destroy ops The parameter associated to the announce_create and announce_destroy ops functions is not an endpoint but a rpmsg device. Signed-off-by: Arnaud Pouliquen Link: https://lore.kernel.org/r/20220425071723.774050-1-arnaud.pouliquen@foss.st.com Signed-off-by: Mathieu Poirier --- drivers/rpmsg/rpmsg_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rpmsg/rpmsg_internal.h b/drivers/rpmsg/rpmsg_internal.h index a22cd4abe7d1..39b646d0d40d 100644 --- a/drivers/rpmsg/rpmsg_internal.h +++ b/drivers/rpmsg/rpmsg_internal.h @@ -41,8 +41,8 @@ struct rpmsg_device_ops { rpmsg_rx_cb_t cb, void *priv, struct rpmsg_channel_info chinfo); - int (*announce_create)(struct rpmsg_device *ept); - int (*announce_destroy)(struct rpmsg_device *ept); + int (*announce_create)(struct rpmsg_device *rpdev); + int (*announce_destroy)(struct rpmsg_device *rpdev); }; /** From d7bd416d35121c95fe47330e09a5c04adbc5f928 Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Fri, 24 Jun 2022 10:41:20 +0800 Subject: [PATCH 04/10] rpmsg: Fix possible refcount leak in rpmsg_register_device_override() rpmsg_register_device_override need to call put_device to free vch when driver_set_override fails. Fix this by adding a put_device() to the error path. Fixes: bb17d110cbf2 ("rpmsg: Fix calling device_lock() on non-initialized device") Reviewed-by: Krzysztof Kozlowski Signed-off-by: Hangyu Hua Link: https://lore.kernel.org/r/20220624024120.11576-1-hbh25y@gmail.com Signed-off-by: Mathieu Poirier --- drivers/rpmsg/rpmsg_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index 290c1f02da10..5a47cad89fdc 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -618,6 +618,7 @@ int rpmsg_register_device_override(struct rpmsg_device *rpdev, strlen(driver_override)); if (ret) { dev_err(dev, "device_set_override failed: %d\n", ret); + put_device(dev); return ret; } } From 99de6509c4135f1d1ceb98c42fa02d249b28b40f Mon Sep 17 00:00:00 2001 From: Saud Farooqui Date: Thu, 23 Jun 2022 14:20:47 +0500 Subject: [PATCH 05/10] rpmsg: Strcpy is not safe, use strscpy_pad() instead Replace strcpy() with strscpy_pad() for copying the rpmsg device name in rpmsg_register_device_override(). Reported-by: kernel test robot Signed-off-by: Saud Farooqui Link: https://lore.kernel.org/r/PA4P189MB14210AA95DCA3715AFA7F4A68BB59@PA4P189MB1421.EURP189.PROD.OUTLOOK.COM Signed-off-by: Mathieu Poirier --- drivers/rpmsg/rpmsg_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index 5a47cad89fdc..d6dde00efdae 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -604,7 +604,7 @@ int rpmsg_register_device_override(struct rpmsg_device *rpdev, int ret; if (driver_override) - strcpy(rpdev->id.name, driver_override); + strscpy_pad(rpdev->id.name, driver_override, RPMSG_NAME_SIZE); dev_set_name(dev, "%s.%s.%d.%d", dev_name(dev->parent), rpdev->id.name, rpdev->src, rpdev->dst); From 766279a8f85df32345dbda03b102ca1ee3d5ddea Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 May 2022 09:33:28 +0200 Subject: [PATCH 06/10] rpmsg: qcom: glink: replace strncpy() with strscpy_pad() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The use of strncpy() is considered deprecated for NUL-terminated strings[1]. Replace strncpy() with strscpy_pad(), to keep existing pad-behavior of strncpy, similarly to commit 08de420a8014 ("rpmsg: glink: Replace strncpy() with strscpy_pad()"). This fixes W=1 warning: In function ‘qcom_glink_rx_close’, inlined from ‘qcom_glink_work’ at ../drivers/rpmsg/qcom_glink_native.c:1638:4: drivers/rpmsg/qcom_glink_native.c:1549:17: warning: ‘strncpy’ specified bound 32 equals destination size [-Wstringop-truncation] 1549 | strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); [1] https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings Signed-off-by: Krzysztof Kozlowski Reviewed-by: Stephen Boyd Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220519073330.7187-1-krzysztof.kozlowski@linaro.org --- drivers/rpmsg/qcom_glink_native.c | 2 +- drivers/rpmsg/qcom_smd.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 07586514991f..5bc5a0a6a8a7 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1546,7 +1546,7 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid) cancel_work_sync(&channel->intent_work); if (channel->rpdev) { - strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); + strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); chinfo.src = RPMSG_ADDR_ANY; chinfo.dst = RPMSG_ADDR_ANY; diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 1957b27c4cf3..f41a065ed007 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -1089,7 +1089,7 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel) /* Assign public information to the rpmsg_device */ rpdev = &qsdev->rpdev; - strncpy(rpdev->id.name, channel->name, RPMSG_NAME_SIZE); + strscpy_pad(rpdev->id.name, channel->name, RPMSG_NAME_SIZE); rpdev->src = RPMSG_ADDR_ANY; rpdev->dst = RPMSG_ADDR_ANY; @@ -1323,7 +1323,7 @@ static void qcom_channel_state_worker(struct work_struct *work) spin_unlock_irqrestore(&edge->channels_lock, flags); - strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); + strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); chinfo.src = RPMSG_ADDR_ANY; chinfo.dst = RPMSG_ADDR_ANY; rpmsg_unregister_device(&edge->dev, &chinfo); From 6c3ebc96ffefbc48297d7c2fd266e9cb78e6941e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 May 2022 09:33:29 +0200 Subject: [PATCH 07/10] rpmsg: qcom: glink: remove unused name The qcom_glink.name is read from DTS but never used further, never referenced, so drop it. This also fixes kerneldoc warning: drivers/rpmsg/qcom_glink_native.c:125: warning: Function parameter or member 'name' not described in 'qcom_glink' Signed-off-by: Krzysztof Kozlowski Reviewed-by: Stephen Boyd Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220519073330.7187-2-krzysztof.kozlowski@linaro.org --- drivers/rpmsg/qcom_glink_native.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 5bc5a0a6a8a7..72a1c0fd091d 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -98,8 +98,6 @@ struct glink_core_rx_intent { struct qcom_glink { struct device *dev; - const char *name; - struct mbox_client mbox_client; struct mbox_chan *mbox_chan; @@ -1755,10 +1753,6 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, if (ret) dev_err(dev, "failed to add groups\n"); - ret = of_property_read_string(dev->of_node, "label", &glink->name); - if (ret < 0) - glink->name = dev->of_node->name; - glink->mbox_client.dev = dev; glink->mbox_client.knows_txdone = true; glink->mbox_chan = mbox_request_channel(&glink->mbox_client, 0); From 101042f4c0eb2daa331b4f7ce32c6d547114830a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 19 May 2022 09:33:30 +0200 Subject: [PATCH 08/10] rpmsg: qcom: correct kerneldoc Correct kerneldoc warnings like: drivers/rpmsg/qcom_glink_ssr.c:45: warning: expecting prototype for G(). Prototype was for GLINK_SSR_DO_CLEANUP() instead Also fix meaning of 'flag' argument. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Stephen Boyd Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220519073330.7187-3-krzysztof.kozlowski@linaro.org --- drivers/rpmsg/qcom_glink_ssr.c | 2 +- drivers/rpmsg/qcom_smd.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_ssr.c b/drivers/rpmsg/qcom_glink_ssr.c index dea929c6045d..776d64446879 100644 --- a/drivers/rpmsg/qcom_glink_ssr.c +++ b/drivers/rpmsg/qcom_glink_ssr.c @@ -39,7 +39,7 @@ struct cleanup_done_msg { __le32 seq_num; }; -/** +/* * G-Link SSR protocol commands */ #define GLINK_SSR_DO_CLEANUP 0 diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index f41a065ed007..c87413a5bf6c 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -729,11 +729,11 @@ static int qcom_smd_write_fifo(struct qcom_smd_channel *channel, } /** - * qcom_smd_send - write data to smd channel + * __qcom_smd_send - write data to smd channel * @channel: channel handle * @data: buffer of data to write * @len: number of bytes to write - * @wait: flag to indicate if write has ca wait + * @wait: flag to indicate if write can wait * * This is a blocking write of len bytes into the channel's tx ring buffer and * signal the remote end. It will sleep until there is enough space available From 65382585f067d4256ba087934f30f85c9b6984de Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Wed, 11 May 2022 16:07:37 +0400 Subject: [PATCH 09/10] rpmsg: qcom_smd: Fix refcount leak in qcom_smd_parse_edge of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Fixes: 53e2822e56c7 ("rpmsg: Introduce Qualcomm SMD backend") Signed-off-by: Miaoqian Lin Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220511120737.57374-1-linmq006@gmail.com --- drivers/rpmsg/qcom_smd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index c87413a5bf6c..1044cf03c542 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -1383,6 +1383,7 @@ static int qcom_smd_parse_edge(struct device *dev, } edge->ipc_regmap = syscon_node_to_regmap(syscon_np); + of_node_put(syscon_np); if (IS_ERR(edge->ipc_regmap)) { ret = PTR_ERR(edge->ipc_regmap); goto put_node; From 7113ac825371c17c15e2d0be79d850e5e16d3328 Mon Sep 17 00:00:00 2001 From: Xuezhi Zhang Date: Tue, 7 Jun 2022 20:06:49 +0800 Subject: [PATCH 10/10] rpmsg: convert sysfs snprintf to sysfs_emit Fix the following coccicheck warning: drivers/rpmsg/qcom_glink_native.c:1677:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Xuezhi Zhang Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220607120649.78436-1-zhangxuezhi1@coolpad.com --- drivers/rpmsg/qcom_glink_native.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 72a1c0fd091d..115c0a1eddb1 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1672,7 +1672,7 @@ static ssize_t rpmsg_name_show(struct device *dev, if (ret < 0) name = dev->of_node->name; - return snprintf(buf, RPMSG_NAME_SIZE, "%s\n", name); + return sysfs_emit(buf, "%s\n", name); } static DEVICE_ATTR_RO(rpmsg_name);