Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d831fcd authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

soc: qcom: pmic_glink: Fix a race condition in accessing rx_list



Currently, rx_list is updated from pmic_glink_rpmsg_callback()
with the new message received and the workqueue is queued for
pmic_glink_rx_work() to deliver it to the client. However, there
is a possibility that a race condition can occur when this list
is manipulated from pmic_glink_rpmsg_callback() in interrupt
context and pmic_glink_rx_work() from process context. Fix it by
using rx_lock before using list_* in pmic_glink_rx_work().

Change-Id: Ib10671d89d60e4b33f1a9666f4af08bb09d1a53b
Suggested-by: default avatarChris Lew <clew@codeaurora.org>
Suggested-by: default avatarDavid Collins <collinsd@codeaurora.org>
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 73db1046
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"PMIC_GLINK: %s: " fmt, __func__
@@ -474,15 +474,17 @@ static void pmic_glink_rx_work(struct work_struct *work)
	struct pmic_glink_buf *pbuf, *tmp;
	unsigned long flags;

	spin_lock_irqsave(&pdev->rx_lock, flags);
	if (!list_empty(&pdev->rx_list)) {
		list_for_each_entry_safe(pbuf, tmp, &pdev->rx_list, node) {
			spin_unlock_irqrestore(&pdev->rx_lock, flags);
			pmic_glink_rx_callback(pdev, pbuf);
			spin_lock_irqsave(&pdev->rx_lock, flags);
			list_del(&pbuf->node);
			spin_unlock_irqrestore(&pdev->rx_lock, flags);
			kfree(pbuf);
		}
	}
	spin_unlock_irqrestore(&pdev->rx_lock, flags);
}

static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data,