diff options
| author | Laxminath Kasam <lkasam@codeaurora.org> | 2014-12-27 15:12:10 +0530 |
|---|---|---|
| committer | Ethan Chen <intervigil@gmail.com> | 2015-04-01 16:28:27 -0700 |
| commit | 633e305482d6005809d5a2153e4a018b8995a67c (patch) | |
| tree | 7b3ef0279d5eae64ed60c26d43f9489cdf482767 | |
| parent | fb7f6414e406ee73033113d41af60dd31b91541c (diff) | |
ASoC: msm: qdsp6v2: fix null pointer access during SSR
While SSR in progress, CMD_CLOSE is sent to asm driver
and at the same time ac->apr handle is set to NULL
as part of RESET_EVENTS callback to this driver.
As both contexts are not synchronized, sometimes
ac->apr handle structure is dereferenced after it
is set to NULL. Fix the issue by having synchronization
between the two contexts.
Change-Id: I0840fbf8281e48f20293ef3d797ff67a3e10e757
Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
| -rw-r--r-- | sound/soc/msm/qdsp6v2/q6asm.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 7e65b72e5ca..82ebd09e4d4 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1458,6 +1458,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } if (data->opcode == RESET_EVENTS) { + mutex_lock(&ac->cmd_lock); atomic_set(&ac->reset, 1); if (ac->apr == NULL) ac->apr = ac->apr2; @@ -1473,6 +1474,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) atomic_set(&ac->cmd_state, 0); wake_up(&ac->time_wait); wake_up(&ac->cmd_wait); + mutex_unlock(&ac->cmd_lock); return 0; } @@ -1881,12 +1883,13 @@ static void __q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, { dev_vdbg(ac->dev, "%s: pkt_size=%d cmd_flg=%d session=%d stream_id=%d\n", __func__, pkt_size, cmd_flg, ac->session, stream_id); + mutex_lock(&ac->cmd_lock); if (ac->apr == NULL) { pr_err("%s: AC APR handle NULL", __func__); + mutex_unlock(&ac->cmd_lock); return; } - mutex_lock(&ac->cmd_lock); hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \ APR_HDR_LEN(sizeof(struct apr_hdr)),\ APR_PKT_VER); |
