Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp8606516ybl; Thu, 16 Jan 2020 20:46:27 -0800 (PST) X-Google-Smtp-Source: APXvYqy7xC1qoZRE3QDUYaYMlAaVBl7EY/T6NPgysbSep5oa5wJ14a3hmKt3tTAJTb6QYepOUQQv X-Received: by 2002:aca:ef82:: with SMTP id n124mr2157280oih.88.1579236387472; Thu, 16 Jan 2020 20:46:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579236387; cv=none; d=google.com; s=arc-20160816; b=BL0mkWA3hWLQ49O+sS2Kj85j2qHuh/gswGEmILpGJnJO5gu3Qpef9nomUkfK4RhPU6 0jK/3fjsISmi7rdH0ehn2EnUaa5r8KhJX92CZ+Y+kQA18dcODZWt2w7e47b1H+YZG1mT mHJMbVkAmVZb0HfDlQM1xzFHACf3aEipCFNLMBIP+exjdWjS5S9pxn0C+yOCAazGM/uu /Ps0jCr5FHH/zb3633xv0LjVproJqC4xbix530pCUSKl2mhLe9hVthJh1XzgoRO8UhIf IBsP6GQbMnftVprycR7RwQByiobZUYnFRgVFEpLesYgCTgUUd9OQYOeNtgo9lWCnWv4E Exxw== 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=xZjWuzDMLArThev18tuhVBr4WdEc12NmBb1aZ8sV2jU=; b=rR6Vo/ITnI31D65b5lHpSkXj/pXDPEmJZ7HoqltagFhDspxJZEHjhQ2gCFAGgzkmSh ldkLTDb3EokLtRo0ELuERJ/J+EmcB1RKjbXCYgMe5IeLl9wG7IG0jlVZ3cxQhWWae3oe DHwYSD8RidA6vucA6tB8tHRDPPxCenkGU4wfFVEJgMjp1Vjjy+dLaiDOAZmD1kUECyUV u/PlhYbhGDhmb0da5+3jccHnGHMD+Jhr+U78RjWAdwJeCxzSD8oTcNXDy20ZuIB7ggVQ GByXz7jVD66peOch/bv6exbvYLPkmPNgIg4i5HHMirUIaVpkyA+AJf95GZ9wwN0DHLZF fMbg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=aJdsVQYF; 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 w4si13945577otp.30.2020.01.16.20.46.16; Thu, 16 Jan 2020 20:46:27 -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=aJdsVQYF; 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 S2390617AbgAPXsH (ORCPT + 99 others); Thu, 16 Jan 2020 18:48:07 -0500 Received: from mail.kernel.org ([198.145.29.99]:46592 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390582AbgAPXUM (ORCPT ); Thu, 16 Jan 2020 18:20:12 -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 957162077C; Thu, 16 Jan 2020 23:20:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579216812; bh=rpdbu4Jen9+5y4bcylnIVxaxVx/B/5xUdOd/zh/AEZE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aJdsVQYFYygoWtbfiRDRjnjMsuL2qTCoyIg7wY5f+KyMuWwRShG/iC6A6YJblsUsB s5QhhruJBaqjCJXOKpDx0eboJd+PMfN9IVTCn4mceCjDUp2dBEpzHubjhc170IpeuM +Al1dzwPytiv7qAP7LIGE0dRDKako0gqduie+Yf0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Olivier Moysan , Mark Brown Subject: [PATCH 5.4 012/203] ASoC: stm32: spdifrx: fix race condition in irq handler Date: Fri, 17 Jan 2020 00:15:29 +0100 Message-Id: <20200116231745.944702043@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200116231745.218684830@linuxfoundation.org> References: <20200116231745.218684830@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 @@ -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; @@ -665,7 +667,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; @@ -733,14 +734,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; } @@ -749,9 +755,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) @@ -827,8 +836,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); } @@ -932,6 +945,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);