]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.4/asoc-intel-avoid-oops-if-dma-setup-fails.patch
4.4-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.4 / asoc-intel-avoid-oops-if-dma-setup-fails.patch
1 From 0efa3334d65b7f421ba12382dfa58f6ff5bf83c4 Mon Sep 17 00:00:00 2001
2 From: Ross Zwisler <zwisler@chromium.org>
3 Date: Mon, 29 Apr 2019 12:25:17 -0600
4 Subject: ASoC: Intel: avoid Oops if DMA setup fails
5
6 From: Ross Zwisler <zwisler@chromium.org>
7
8 commit 0efa3334d65b7f421ba12382dfa58f6ff5bf83c4 upstream.
9
10 Currently in sst_dsp_new() if we get an error return from sst_dma_new()
11 we just print an error message and then still complete the function
12 successfully. This means that we are trying to run without sst->dma
13 properly set up, which will result in NULL pointer dereference when
14 sst->dma is later used. This was happening for me in
15 sst_dsp_dma_get_channel():
16
17 struct sst_dma *dma = dsp->dma;
18 ...
19 dma->ch = dma_request_channel(mask, dma_chan_filter, dsp);
20
21 This resulted in:
22
23 BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
24 IP: sst_dsp_dma_get_channel+0x4f/0x125 [snd_soc_sst_firmware]
25
26 Fix this by adding proper error handling for the case where we fail to
27 set up DMA.
28
29 This change only affects Haswell and Broadwell systems. Baytrail
30 systems explicilty opt-out of DMA via sst->pdata->resindex_dma_base
31 being set to -1.
32
33 Signed-off-by: Ross Zwisler <zwisler@google.com>
34 Cc: stable@vger.kernel.org
35 Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
36 Signed-off-by: Mark Brown <broonie@kernel.org>
37 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
38
39 ---
40 sound/soc/intel/common/sst-dsp.c | 8 ++++++--
41 1 file changed, 6 insertions(+), 2 deletions(-)
42
43 --- a/sound/soc/intel/common/sst-dsp.c
44 +++ b/sound/soc/intel/common/sst-dsp.c
45 @@ -463,11 +463,15 @@ struct sst_dsp *sst_dsp_new(struct devic
46 goto irq_err;
47
48 err = sst_dma_new(sst);
49 - if (err)
50 - dev_warn(dev, "sst_dma_new failed %d\n", err);
51 + if (err) {
52 + dev_err(dev, "sst_dma_new failed %d\n", err);
53 + goto dma_err;
54 + }
55
56 return sst;
57
58 +dma_err:
59 + free_irq(sst->irq, sst);
60 irq_err:
61 if (sst->ops->free)
62 sst->ops->free(sst);