mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
ASoC: msm: qdsp6: Fixed the issue unmap command is sent incorrectly
When session CLOSE command is sent right before session RUN command is acknowledged, callback function can mistakenly think that the next received acknowledgement is for CLOSE command instead of RUN command. This triggers driver to send memory unmap command to the Q6 while it is still processing the CLOSE command. Eventually, this leads to an invalid memory access and causes Q6 crash. Change-Id: Ib5d560fbcb7e8ced79cc1075a9f6bea3b55a86b6 CRs-Fixed: 377281 Signed-off-by: Jay Wang <jaywang@codeaurora.org>
This commit is contained in:
parent
0f74ac2734
commit
79a415c76b
2 changed files with 13 additions and 3 deletions
|
@ -151,6 +151,7 @@ struct audio_client {
|
|||
|
||||
atomic_t cmd_state;
|
||||
atomic_t time_flag;
|
||||
atomic_t nowait_cmd_cnt;
|
||||
wait_queue_head_t cmd_wait;
|
||||
wait_queue_head_t time_wait;
|
||||
|
||||
|
|
|
@ -805,6 +805,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
uint32_t token;
|
||||
unsigned long dsp_flags;
|
||||
uint32_t *payload;
|
||||
uint32_t wakeup_flag = 1;
|
||||
|
||||
|
||||
if ((ac == NULL) || (data == NULL)) {
|
||||
|
@ -816,7 +817,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
ac->session);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (atomic_read(&ac->nowait_cmd_cnt) > 0) {
|
||||
pr_debug("%s: nowait_cmd_cnt %d\n",
|
||||
__func__,
|
||||
atomic_read(&ac->nowait_cmd_cnt));
|
||||
atomic_dec(&ac->nowait_cmd_cnt);
|
||||
wakeup_flag = 0;
|
||||
}
|
||||
payload = data->payload;
|
||||
|
||||
if (data->opcode == RESET_EVENTS) {
|
||||
|
@ -862,7 +869,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
|
||||
case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
|
||||
case ASM_STREAM_CMD_OPEN_READ_COMPRESSED:
|
||||
if (atomic_read(&ac->cmd_state)) {
|
||||
if (atomic_read(&ac->cmd_state) && wakeup_flag) {
|
||||
atomic_set(&ac->cmd_state, 0);
|
||||
if (payload[1] == ADSP_EUNSUPPORTED)
|
||||
atomic_set(&ac->cmd_response, 1);
|
||||
|
@ -1618,12 +1625,12 @@ int q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
|
|||
run.flags = flags;
|
||||
run.msw_ts = msw_ts;
|
||||
run.lsw_ts = lsw_ts;
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &run);
|
||||
if (rc < 0) {
|
||||
pr_err("%s:Commmand run failed[%d]", __func__, rc);
|
||||
return -EINVAL;
|
||||
}
|
||||
atomic_inc(&ac->nowait_cmd_cnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3541,11 +3548,13 @@ int q6asm_cmd_nowait(struct audio_client *ac, int cmd)
|
|||
pr_debug("%s:session[%d]opcode[0x%x] ", __func__,
|
||||
ac->session,
|
||||
hdr.opcode);
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr);
|
||||
if (rc < 0) {
|
||||
pr_err("%s:Commmand 0x%x failed\n", __func__, hdr.opcode);
|
||||
goto fail_cmd;
|
||||
}
|
||||
atomic_inc(&ac->nowait_cmd_cnt);
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return -EINVAL;
|
||||
|
|
Loading…
Reference in a new issue