Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp591180ybl; Wed, 4 Dec 2019 07:45:07 -0800 (PST) X-Google-Smtp-Source: APXvYqyxf4Cl/XwwhcKMQoPa7Eznv6LvWT+j7uyx33PC1ESCccVc95WGPVShWyfQB6go9vugdZ6t X-Received: by 2002:aca:c08b:: with SMTP id q133mr2957364oif.46.1575474307689; Wed, 04 Dec 2019 07:45:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1575474307; cv=none; d=google.com; s=arc-20160816; b=DE80JhYZHAsupU9ft4NHQfM5G52/38ZxRwPteT9hgkCB+ErCTokhkB1b2Z+kufc14w pcjUfYRTU958KLnoQOpoWUI38m1CLbFj+ddoBTFEe41h8lcuk31XQW+9WLolI8qf8cxr mvTFwiIIpBKignaJIziABS5MJkNaOg0EyHsABwTbPmpS3TG8JsC57rsPZdG6ueB87uQY fwSGkRw+6aLouoRTqDAfN4FQM2Luiq8LyAi/tyoQ24aPEfnYLeDaN9mfBmZ6glMvJVip 8y/7DG/6Xc1Ru/n6ocAuxCxRaSP4cxgA60kW+PeAogIlH3LW8WIGLsIw67JhvNCesJKf d0NQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:to:from:dkim-signature; bh=/Ivbs5G2+L1Rrc5+1dFeG7M8SNidljHJiN8CJkige+g=; b=OMU00uSuxqs4Y+8E9mE9/R8zXErzU6SQu6AGgrZ9dZPiluvD+CJRSYP3ihiCpWYUBc lEf9ABf85TF5gVswDZWTPQif1jtFX17QfUiwauTxBfftNUETuvVz6fU6kSa2VstbI8bh eNQGvLuOoD80cycO+8dw6ejHaZfT9H9c9ldFfEkGRF7grv0qlvRIgVD5GSVxcSaSKU9M 9QSD/WmvIFrQg1wH5iIVVZwr5bYdN7FJksvMAnq2/aiuyP4BBAGasiyoZP0Xhcv2K6p7 A4U+khKvrQka9u+X3eXNcuaEu+p8OuQ4Ck/7DAgOFpdW+VnvlYXUXNdCDQL01LGlPrW1 pXCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@st.com header.s=STMicroelectronics header.b=h8Tme4nv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=st.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w4si3550500otq.144.2019.12.04.07.44.53; Wed, 04 Dec 2019 07:45:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@st.com header.s=STMicroelectronics header.b=h8Tme4nv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=st.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728410AbfLDPoN (ORCPT + 99 others); Wed, 4 Dec 2019 10:44:13 -0500 Received: from mx07-00178001.pphosted.com ([62.209.51.94]:11748 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728214AbfLDPoG (ORCPT ); Wed, 4 Dec 2019 10:44:06 -0500 Received: from pps.filterd (m0046668.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id xB4FgVgC032652; Wed, 4 Dec 2019 16:43:43 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=/Ivbs5G2+L1Rrc5+1dFeG7M8SNidljHJiN8CJkige+g=; b=h8Tme4nvLLlY/9qoSFvj6UuDZ/eEfS5kNssmr9SCyoK4sxvBsGhjzsaXDXFbjARmksMv dleCQqMEJB09ZnXODnuwjk39/byMd+xTuzJP/iC3ZHMMQ9MBvP9Pn7UN8aPL5UeGTHqo notwOfy9lY7iaqP82hBIIsMagJrvUom+jYSdIASNO/eRqcAZBQx2yvDRTQsArACHOZxv RdHJtVTaoagpZia1p3zWPQbfGIkkxKM4d+cMave7DSatLl+h4dQY2hVLUf/BwY+BHCwc 1T3nU5ggx8WrlA2o+St0sVZd9oi3ECJpB+QsWMNZYVVbYwOmEu0hnGvtwwSWkWMx1Pu+ hA== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 2wkes2wxy7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 04 Dec 2019 16:43:43 +0100 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 4B83310002A; Wed, 4 Dec 2019 16:43:43 +0100 (CET) Received: from Webmail-eu.st.com (sfhdag6node2.st.com [10.75.127.17]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 3EFAD2C71B5; Wed, 4 Dec 2019 16:43:43 +0100 (CET) Received: from localhost (10.75.127.45) by SFHDAG6NODE2.st.com (10.75.127.17) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Wed, 4 Dec 2019 16:43:42 +0100 From: Olivier Moysan To: , , , , , , , , , , Subject: [PATCH 2/3] ASoC: stm32: spdifrx: fix race condition in irq handler Date: Wed, 4 Dec 2019 16:43:32 +0100 Message-ID: <20191204154333.7152-3-olivier.moysan@st.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191204154333.7152-1-olivier.moysan@st.com> References: <20191204154333.7152-1-olivier.moysan@st.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.75.127.45] X-ClientProxiedBy: SFHDAG8NODE2.st.com (10.75.127.23) To SFHDAG6NODE2.st.com (10.75.127.17) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.95,18.0.572 definitions=2019-12-04_03:2019-12-04,2019-12-04 signatures=0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When snd_pcm_stop() is called in interrupt routine, substream context may have already been released. Add protection on substream context. Fixes: 03e4d5d56fa5 ("ASoC: stm32: Add SPDIFRX support") Signed-off-by: Olivier Moysan --- sound/soc/stm/stm32_spdifrx.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c index 9c6beb610c17..3cb8e6db3eeb 100644 --- a/sound/soc/stm/stm32_spdifrx.c +++ b/sound/soc/stm/stm32_spdifrx.c @@ -220,6 +220,7 @@ * @slave_config: dma slave channel runtime config pointer * @phys_addr: SPDIFRX registers physical base address * @lock: synchronization enabling lock + * @irq_lock: prevent race condition with IRQ on stream state * @cs: channel status buffer * @ub: user data buffer * @irq: SPDIFRX interrupt line @@ -240,6 +241,7 @@ struct stm32_spdifrx_data { struct dma_slave_config slave_config; dma_addr_t phys_addr; spinlock_t lock; /* Sync enabling lock */ + spinlock_t irq_lock; /* Prevent race condition on stream state */ unsigned char cs[SPDIFRX_CS_BYTES_NB]; unsigned char ub[SPDIFRX_UB_BYTES_NB]; int irq; @@ -667,7 +669,6 @@ static const struct regmap_config stm32_h7_spdifrx_regmap_conf = { static irqreturn_t stm32_spdifrx_isr(int irq, void *devid) { struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid; - struct snd_pcm_substream *substream = spdifrx->substream; struct platform_device *pdev = spdifrx->pdev; unsigned int cr, mask, sr, imr; unsigned int flags, sync_state; @@ -747,14 +748,19 @@ static irqreturn_t stm32_spdifrx_isr(int irq, void *devid) return IRQ_HANDLED; } - if (substream) - snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); + spin_lock(&spdifrx->irq_lock); + if (spdifrx->substream) + snd_pcm_stop(spdifrx->substream, + SNDRV_PCM_STATE_DISCONNECTED); + spin_unlock(&spdifrx->irq_lock); return IRQ_HANDLED; } - if (err_xrun && substream) - snd_pcm_stop_xrun(substream); + spin_lock(&spdifrx->irq_lock); + if (err_xrun && spdifrx->substream) + snd_pcm_stop_xrun(spdifrx->substream); + spin_unlock(&spdifrx->irq_lock); return IRQ_HANDLED; } @@ -763,9 +769,12 @@ static int stm32_spdifrx_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); + unsigned long flags; int ret; + spin_lock_irqsave(&spdifrx->irq_lock, flags); spdifrx->substream = substream; + spin_unlock_irqrestore(&spdifrx->irq_lock, flags); ret = clk_prepare_enable(spdifrx->kclk); if (ret) @@ -841,8 +850,12 @@ static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); + unsigned long flags; + spin_lock_irqsave(&spdifrx->irq_lock, flags); spdifrx->substream = NULL; + spin_unlock_irqrestore(&spdifrx->irq_lock, flags); + clk_disable_unprepare(spdifrx->kclk); } @@ -946,6 +959,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev) spdifrx->pdev = pdev; init_completion(&spdifrx->cs_completion); spin_lock_init(&spdifrx->lock); + spin_lock_init(&spdifrx->irq_lock); platform_set_drvdata(pdev, spdifrx); -- 2.17.1