From c3940ee39d184ebfdda3e5186014c47c394fff50 Mon Sep 17 00:00:00 2001 From: Vikas C Sajjan Date: Fri, 14 Sep 2012 18:23:35 +0900 Subject: [PATCH] ASoC: Samsung: Protect the dma pointer position access Takes spin lock to protect prtd->dma_pos from concurrent access by the driver and the tasklet BUG=chrome-os-partner:12565 TEST=ran multimedia tests for audio, video and webgl Change-Id: I29054e75d01eb7a10401dbc75a17fca13e24ea0e Signed-off-by: Abhinav Kochhar Reviewed-on: https://gerrit.chromium.org/gerrit/33298 Reviewed-by: Dylan Reid Tested-by: Vikas Sajjan --- sound/soc/samsung/dma.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index 154eac5e232c..30250ef3f688 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -119,9 +119,11 @@ static void audio_buffdone(void *data) pr_debug("Entered %s\n", __func__); if (prtd->state & ST_RUNNING) { + spin_lock(&prtd->lock); prtd->dma_pos += prtd->dma_period; if (prtd->dma_pos >= prtd->dma_end) prtd->dma_pos = prtd->dma_start; + spin_unlock(&prtd->lock); if (substream) snd_pcm_period_elapsed(substream); @@ -271,6 +273,7 @@ dma_pointer(struct snd_pcm_substream *substream) struct runtime_data *prtd = runtime->private_data; unsigned long offset; unsigned long xfd; /* Number of bytes transfered by current dma. */ + unsigned int ret = 0; pr_debug("Entered %s\n", __func__); @@ -278,11 +281,14 @@ dma_pointer(struct snd_pcm_substream *substream) * more accurate number. Otherwise, assume no bytes have been * transfered. */ - xfd = prtd->dma_period; if (prtd->params->ops->residue) - xfd -= prtd->params->ops->residue(prtd->params->ch); + ret = prtd->params->ops->residue(prtd->params->ch); + + spin_lock(&prtd->lock); + xfd = prtd->dma_period - ret; offset = prtd->dma_pos + xfd - prtd->dma_start; + spin_unlock(&prtd->lock); /* we seem to be getting the odd error from the pcm library due * to out-of-bounds pointers. this is maybe due to the dma engine -- 2.20.1