From 8d831fcdcd846d5cc55b09303049f0f9303f5050 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Tue, 2 Feb 2021 15:30:35 -0800 Subject: [PATCH] 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: Chris Lew Suggested-by: David Collins Signed-off-by: Subbaraman Narayanamurthy --- drivers/soc/qcom/pmic_glink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index 62c28a4132ea..0423e14c9941 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c @@ -1,6 +1,6 @@ // 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,