Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp8484535ybl; Thu, 16 Jan 2020 17:49:32 -0800 (PST) X-Google-Smtp-Source: APXvYqywnINgs/fuBbLGO+wl3gh+mWJXseYBjlEMGjd79dTACBObqlFFRG89R0V5dfKf3s/TvhZr X-Received: by 2002:a54:4896:: with SMTP id r22mr1767469oic.30.1579225772806; Thu, 16 Jan 2020 17:49:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579225772; cv=none; d=google.com; s=arc-20160816; b=J1zoZ0MyP+JuEbxqpJkZGYNLHyGicaWV5IJ9UL3O5Aq6NKUPJO0wxIU+shsA7SDLyq 95yOWnGAlYsDcX+isg/3kLZ0lg4DfYzxqGgA8iE5hh6gEprjZVV3fPfM52sKM9dJ8I9q 82vr+0RDS4iS9EwMgTdxPgj2YPOfMaYVY0l/FRKK/+YbuWegvmuC5NPLA8CZtP1ReJ2+ p5y+uDyajfMUQjff7UDHyoV3fUa9qIIGqsDsLb2qDGXBQT1QkKhNJX7qaq7lOVqNLMpK czmLr5Y1lq8FCm+NKtn4TUhvMe6TyDH1927wHOEnbTL6c5rlOH1F8rKj63uDFMG5On6D nR3A== 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=qnHe2HIbCaKUL0gNUjbJHTTgh09n8rjkcYsPA0sU5rM=; b=G+9873YYOtfQL4+HiUHMrP9QzJMek4lzqcapao19o0eo7O2LyCQT2wMh+xciuWCGFQ OtZg/PjC3F+bUlQybmOogFbeH15j2wcF7jDkloRUhGzSApqceVrF1gJtgBPFAGJK/dn2 i3PHFDPr43OcPzC0ffG/RrLLOEbfSC04skk1HJ+KB4tMsFTtPjyubHyu/twNHBiPccZG ij630+QivzJQnKpQYTT7n60J/NxV28/zJLLIwz4uIatj+KK8Excu9FF6e386kuNoVLx9 uZv0mw1iztc60PKL/fAV57Bmp7Ak23VvgNLsqtF85e/cHqFog/gfQtQeGyuEU34FHoCH Bq0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=lmLN5x5T; 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 k89si16201282otk.173.2020.01.16.17.49.21; Thu, 16 Jan 2020 17:49:32 -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=lmLN5x5T; 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 S2391077AbgAPX2S (ORCPT + 99 others); Thu, 16 Jan 2020 18:28:18 -0500 Received: from mail.kernel.org ([198.145.29.99]:60862 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389500AbgAPX2O (ORCPT ); Thu, 16 Jan 2020 18:28:14 -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 2BB50206D9; Thu, 16 Jan 2020 23:28:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579217291; bh=yWWbWA/a60bFs6M+W+yu8Q+ZUvBOx7ldAV+THpLEjR8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lmLN5x5T1TpMyc3MatDH2IM6iF+SOEy19mOMmVwaweYe7IQ90B1EzUY4AOKIYspoN PYj6daHS1cexiSxrEUaeFH9d10xeGlYWHzjbacK08JUSjQQmmVT0lhVV6qjdmnKzvV 231O5wvnYjh3+71GHSbRYt9dZCSbhy4IjYyIchyc= 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.19 22/84] ASoC: stm32: spdifrx: fix race condition in irq handler Date: Fri, 17 Jan 2020 00:17:56 +0100 Message-Id: <20200116231716.272428926@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200116231713.087649517@linuxfoundation.org> References: <20200116231713.087649517@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; @@ -645,7 +647,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; @@ -713,14 +714,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; } @@ -729,9 +735,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) @@ -807,8 +816,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); } @@ -912,6 +925,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);