Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp8554548ybl; Thu, 16 Jan 2020 19:28:16 -0800 (PST) X-Google-Smtp-Source: APXvYqwHexnRAZVKefcRj0cRTjXPnARb2z3/dOSU/pkkYWrQquBCOy6/+qw7D1nGHhdRN+l9RxVl X-Received: by 2002:aca:51c9:: with SMTP id f192mr2010709oib.10.1579231696265; Thu, 16 Jan 2020 19:28:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579231696; cv=none; d=google.com; s=arc-20160816; b=soPQiwKlAzlcT9V03+fIRnP/YCtz1A/oKBN4FkdnBVVpU+oq6aJRQMKCUmSurtKUHM ldjcCZ8Rp5K3Td3BpXlmKImadk1/iopupus4/E7csgY8PQJFlPTtGstIoZT6WTo6RLLd zhRbAS+yyMeKkfyNMT+xofE1xVy+9w44TbDCeOOeOwN61mtRJq27Gn4cwc7H3XqHJ74o 8LJgPo/gmTSuAEDr/kuEV+6DK9/pcFq/cHDZGH9F38RlSfrMfuHdVMMWRqj6qcXnBjCn ouNL3zYQwYds7YMZtTrHNR50HL4bbO5c8kxnbVFXSaeUCi3Qt8+p2+pbtIlqvcXLd8Cw Zc7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=PBTCU+V40LmsMTSPxuQ6cKLmc/G51wXIjRMI7shfCVQ=; b=sHXFB++Po07GYsLhiyruLo4m/0r6mADArGOoOdoa03BwFQnC364jMysHYwv8vaYRot dhTHDoDn3p1WRtEQVVQ+2Y1So5HoaHg/czbpxbrB1eYTJbf1uDD+lWqODr6Miob3aaIF uXCg0OayqqqVnz67PjpWCHzd1IfN8Hcn014NCKueFA9hISlo8DdwnEo99pND4X3Ais87 +tqgFfbAnuZ9ic9+RptG0Y3nmf0X/PKX0vkC8b2WpkyBdfVTBUOGcw1eXlghu/OhiI8Q vTCuTh519khRG3twxW/96eZSagAXmPSsDgKnzrtjwksiw45XH9PSH6nH8SOzLiR/mdcX Z1rw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=RGjRAi6O; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q9si12443370oij.125.2020.01.16.19.28.04; Thu, 16 Jan 2020 19:28:16 -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=@kernel.org header.s=default header.b=RGjRAi6O; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404254AbgAPXgS (ORCPT + 99 others); Thu, 16 Jan 2020 18:36:18 -0500 Received: from mail.kernel.org ([198.145.29.99]:40206 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732981AbgAPXbk (ORCPT ); Thu, 16 Jan 2020 18:31:40 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AB608206D9; Thu, 16 Jan 2020 23:31:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579217500; bh=r3CjGXlTky99boRzd8VktX2hXmeXhqpzLTfCpBadJw0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RGjRAi6OFx+nzeQ8/wamB72hjvJd421KYQ1K4LV7jVa1xPGHy54PoDoh365zhJeet OuKu4ctwTFAhhqgpkB5QlkFTkip4KqOiDybN2kzYlek84Ftlvdzi+E2OKiSdZw5y9E 92s0aytcHYAeE5d6vptiDF3X1uc1X3VGzz/nzIyo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Olivier Moysan , Mark Brown Subject: [PATCH 4.14 23/71] ASoC: stm32: spdifrx: fix race condition in irq handler Date: Fri, 17 Jan 2020 00:18:21 +0100 Message-Id: <20200116231712.748003784@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200116231709.377772748@linuxfoundation.org> References: <20200116231709.377772748@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Olivier Moysan commit 86e1956af4c863d653136fd6e5694adf2054dbaa upstream. 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 Link: https://lore.kernel.org/r/20191204154333.7152-3-olivier.moysan@st.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/stm/stm32_spdifrx.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) --- a/sound/soc/stm/stm32_spdifrx.c +++ b/sound/soc/stm/stm32_spdifrx.c @@ -213,6 +213,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 @@ -233,6 +234,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; @@ -646,7 +648,6 @@ static const struct regmap_config stm32_ 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; @@ -714,14 +715,19 @@ static irqreturn_t stm32_spdifrx_isr(int regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, SPDIFRX_CR_SPDIFEN_MASK, cr); - 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; } @@ -730,9 +736,12 @@ static int stm32_spdifrx_startup(struct 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) @@ -804,8 +813,12 @@ static void stm32_spdifrx_shutdown(struc 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); } @@ -910,6 +923,7 @@ static int stm32_spdifrx_probe(struct pl spdifrx->pdev = pdev; init_completion(&spdifrx->cs_completion); spin_lock_init(&spdifrx->lock); + spin_lock_init(&spdifrx->irq_lock); platform_set_drvdata(pdev, spdifrx);