From 5b1fd5953199b448060ced40b3e000091c4acdc0 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Mon, 24 Apr 2023 11:32:43 +0530 Subject: [PATCH 01/12] soc: reduce the auto suspend timeout when swr event finished the APSS would suspend within ~120ms after audio off, if system suspend swrm_suspend() is called before swrm_runtime_suspend. The clock stop sequence require writing IPC and expect interrupt, which would stop the APSS to be suspended. Reduce the auto suspend time specifically when swr event is done can call the swrm_runtime_suspend Change-Id: Iee0c9143d65e5a8e68a8e20ab73bea9def1920bd Signed-off-by: Junkai Cai Signed-off-by: Soumya Managoli --- soc/swr-mstr-ctrl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 752d5c2b2940..2cd057c34b71 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1738,6 +1738,8 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n", __func__); pm_runtime_mark_last_busy(swrm->dev); + if (!enable) + pm_runtime_set_autosuspend_delay(swrm->dev, 80); pm_runtime_put_autosuspend(swrm->dev); } exit: @@ -3327,6 +3329,9 @@ exit: if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); + dev_dbg(dev, "%s: pm_runtime: suspend done state: %d\n", + __func__, swrm->state); + pm_runtime_set_autosuspend_delay(dev, auto_suspend_timer); return ret; } #endif /* CONFIG_PM */ From 19791049de77c8fea4ce4bd689aba9bcd3bc557a Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Mon, 24 Apr 2023 12:08:53 +0530 Subject: [PATCH 02/12] soc: swr-mstr-ctrl: add new lock to sync runtime_resume and runtime_suspend runtime_suspend may get from multi functions and reslock is unlock and lock inbetween which may cause clk count mismatch with multi rutime_suspend called. Add new lock to make sure runtime_suspend is run in sequence. Change-Id: Ie465ded6dc1db1244035e9f4d216466b630df82b Signed-off-by: Meng Wang Signed-off-by: Soumya Managoli --- soc/swr-mstr-ctrl.c | 9 +++++++++ soc/swr-mstr-ctrl.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 2cd057c34b71..a41b2f5cee97 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2850,6 +2850,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->clklock); mutex_init(&swrm->devlock); mutex_init(&swrm->pm_lock); + mutex_init(&swrm->runtime_lock); swrm->wlock_holders = 0; swrm->pm_state = SWRM_PM_SLEEPABLE; init_waitqueue_head(&swrm->pm_wq); @@ -3022,6 +3023,7 @@ err_irq_fail: mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->pm_lock); pm_qos_remove_request(&swrm->pm_qos_req); + mutex_destroy(&swrm->runtime_lock); err_pdata_fail: err_memory_fail: @@ -3061,6 +3063,7 @@ static int swrm_remove(struct platform_device *pdev) mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->pm_lock); pm_qos_remove_request(&swrm->pm_qos_req); + mutex_destroy(&swrm->runtime_lock); devm_kfree(&pdev->dev, swrm); return 0; } @@ -3092,6 +3095,7 @@ static int swrm_runtime_resume(struct device *dev) dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n", __func__, swrm->state); + mutex_lock(&swrm->runtime_lock); mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { @@ -3103,6 +3107,7 @@ static int swrm_runtime_resume(struct device *dev) if (swrm->req_clk_switch) swrm->req_clk_switch = false; mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); return 0; } if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { @@ -3120,6 +3125,7 @@ static int swrm_runtime_resume(struct device *dev) pr_err("%s: irq data is NULL\n", __func__); mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); return IRQ_NONE; } mutex_lock(&swrm->irq_lock); @@ -3211,6 +3217,7 @@ exit: if (swrm->req_clk_switch) swrm->req_clk_switch = false; mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); return ret; } @@ -3232,6 +3239,7 @@ static int swrm_runtime_suspend(struct device *dev) swrm->state = SWR_MSTR_SSR; return 0; } + mutex_lock(&swrm->runtime_lock); mutex_lock(&swrm->reslock); mutex_lock(&swrm->force_down_lock); current_state = swrm->state; @@ -3329,6 +3337,7 @@ exit: if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); dev_dbg(dev, "%s: pm_runtime: suspend done state: %d\n", __func__, swrm->state); pm_runtime_set_autosuspend_delay(dev, auto_suspend_timer); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 8cb613aaf125..1793d8bdfa09 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H @@ -134,6 +135,7 @@ struct swr_mstr_ctrl { struct mutex reslock; struct mutex pm_lock; struct mutex irq_lock; + struct mutex runtime_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; char __iomem *swrm_hctl_reg; From 2e8272c7f65eef6b66a5effeae48fa8921193ad9 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Tue, 16 May 2023 12:01:48 +0530 Subject: [PATCH 03/12] dsp: afe: Add check for num_channels Check for valid num_channels before accessing. Change-Id: I8f39d12e2f5f52fa145fbd3aed2b023afaa2b53b Signed-off-by: Soumya Managoli --- dsp/q6afe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index a08843a74d31..5954c67019ba 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -1249,6 +1249,9 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) sizeof(struct afe_port_mod_evt_rsp_hdr)); uint32_t *dc_presence_flag = num_channels + 1; + if (*num_channels < 1 || *num_channels > 4) + return -EINVAL; + for (i = 0; i < *num_channels; i++) { if (dc_presence_flag[i] == 1) dc_detected = true; From 502410201aea011ac06adc47548ad7b3ee81db7e Mon Sep 17 00:00:00 2001 From: Shalini Manjunatha Date: Mon, 17 Apr 2023 16:49:39 +0530 Subject: [PATCH 04/12] dsp: q6core: validate payload size before access for AVCS Payload size is not checked before payload access for AVCS. Check size to avoid out-of-boundary memory access. Change-Id: I6de3342617bd4f3fb8849ad2230dd57c07469372 Signed-off-by: Shalini Manjunatha --- dsp/q6core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dsp/q6core.c b/dsp/q6core.c index 35fc8a801261..6684b2a7d0df 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -475,6 +475,12 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) case AVCS_CMD_RSP_LOAD_MODULES: pr_debug("%s: Received AVCS_CMD_RSP_LOAD_MODULES\n", __func__); + if (data->payload_size != ((sizeof(struct avcs_load_unload_modules_sec_payload) + * rsp_payload->num_modules) + sizeof(uint32_t))) { + pr_err("%s: payload size greater than expected size %d\n", + __func__,data->payload_size); + return -EINVAL; + } memcpy(rsp_payload, data->payload, data->payload_size); q6core_lcl.avcs_module_resp_received = 1; wake_up(&q6core_lcl.avcs_module_load_unload_wait); @@ -1037,6 +1043,8 @@ int32_t q6core_avcs_load_unload_modules(struct avcs_load_unload_modules_payload return -ENOMEM; } + rsp_payload->num_modules = num_modules; + memcpy((uint8_t *)mod + sizeof(struct apr_hdr) + sizeof(struct avcs_load_unload_modules_meminfo), payload, payload_size); From 2046b3b25bf86a7c9f5cae612b3d1863ffb800de Mon Sep 17 00:00:00 2001 From: Shalini Manjunatha Date: Mon, 10 Apr 2023 16:19:35 +0530 Subject: [PATCH 05/12] dsp: afe: check for param size before copying check for the proper param size before copying, to avoid buffer overflow. Change-Id: I70c52e6ab76f528ea3714784ab9013b070839c40 Signed-off-by: Shalini Manjunatha --- dsp/q6afe.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index a08843a74d31..d1acb5c9fe0e 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -786,32 +786,74 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, switch (param_hdr.param_id) { case AFE_PARAM_ID_CALIB_RES_CFG_V2: expected_size += sizeof(struct asm_calib_res_cfg); + if (param_hdr.param_size != sizeof(struct asm_calib_res_cfg)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.calib_data; break; case AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS: expected_size += sizeof(struct afe_sp_th_vi_ftm_params); + if (param_hdr.param_size != sizeof(struct afe_sp_th_vi_ftm_params)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.th_vi_resp; break; case AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_PARAMS: expected_size += sizeof(struct afe_sp_th_vi_v_vali_params); + if (param_hdr.param_size != sizeof(struct afe_sp_th_vi_v_vali_params)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.th_vi_v_vali_resp; break; case AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS: expected_size += sizeof(struct afe_sp_ex_vi_ftm_params); + if (param_hdr.param_size != sizeof(struct afe_sp_ex_vi_ftm_params)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.ex_vi_resp; break; case AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING: expected_size += sizeof( struct afe_sp_rx_tmax_xmax_logging_param); + if (param_hdr.param_size != sizeof(struct afe_sp_rx_tmax_xmax_logging_param)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.xt_logging_resp; break; case AFE_PARAM_ID_SP_V4_CALIB_RES_CFG: expected_size += sizeof( struct afe_sp_v4_param_th_vi_calib_res_cfg); + if (param_hdr.param_size != sizeof( + struct afe_sp_v4_param_th_vi_calib_res_cfg)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.spv4_calib_data; break; case AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS: num_ch = data_start[0]; + if (num_ch > SP_V2_NUM_MAX_SPKRS) { + pr_err("%s: Error: num_ch %d is greater than expected\n", + __func__,num_ch); + return -EINVAL; + } + if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)))) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } this_afe.spv4_th_vi_ftm_rcvd_param_size = param_hdr.param_size; data_dest = (u32 *)&this_afe.spv4_th_vi_ftm_resp; expected_size += @@ -820,6 +862,18 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS: num_ch = data_start[0]; + if (num_ch > SP_V2_NUM_MAX_SPKRS) { + pr_err("%s: Error: num_ch %d is greater than expected\n", + __func__,num_ch); + return -EINVAL; + } + if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_v_vali_params)))) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } this_afe.spv4_v_vali_rcvd_param_size = param_hdr.param_size; data_dest = (u32 *)&this_afe.spv4_v_vali_resp; expected_size += @@ -829,6 +883,18 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS: num_ch = data_start[0]; + if (num_ch > SP_V2_NUM_MAX_SPKRS) { + pr_err("%s: Error: num_ch %d is greater than expected\n", + __func__,num_ch); + return -EINVAL; + } + if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)))) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } this_afe.spv4_ex_vi_ftm_rcvd_param_size = param_hdr.param_size; data_dest = (u32 *)&this_afe.spv4_ex_vi_ftm_resp; expected_size += @@ -837,6 +903,18 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING: num_ch = data_start[0]; + if (num_ch > SP_V2_NUM_MAX_SPKRS) { + pr_err("%s: Error: num_ch %d is greater than expected\n", + __func__,num_ch); + return -EINVAL; + } + if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (num_ch * + sizeof(struct afe_sp_v4_channel_tmax_xmax_params)))) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } this_afe.spv4_max_log_rcvd_param_size = param_hdr.param_size; data_dest = (u32 *)&this_afe.spv4_max_log_resp; expected_size += From b7599b3751572fe071963f97ad3d705c06038278 Mon Sep 17 00:00:00 2001 From: Shalini Manjunatha Date: Wed, 5 Apr 2023 16:35:10 +0530 Subject: [PATCH 06/12] dsp: asm: validate payload size before access Payload size is not checked before payload access. Check size to avoid out-of-boundary memory access. Change-Id: I1bd8281ad263b8c0102335504a740312755b8d15 Signed-off-by: Shalini Manjunatha --- dsp/q6asm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index ed84f225f017..ea4db1956da2 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -2434,6 +2435,15 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) config_debug_fs_read_cb(); + if (data->payload_size != (READDONE_IDX_SEQ_ID + 1) * sizeof(uint32_t)) { + pr_err("%s: payload size of %d is less than expected %d.\n", + __func__, data->payload_size, + ((READDONE_IDX_SEQ_ID + 1) * sizeof(uint32_t))); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return -EINVAL; + } dev_vdbg(ac->dev, "%s: ReadDone: status=%d buff_add=0x%x act_size=%d offset=%d\n", __func__, payload[READDONE_IDX_STATUS], payload[READDONE_IDX_BUFADD_LSW], From 1a2e110c2399f5741a8e815cc2238d0d1f09c77f Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Mon, 29 May 2023 14:12:05 +0530 Subject: [PATCH 07/12] ASoC: msm-pcm-voip: Avoid interger underflow There is no check for voip pkt pkt_len,if it contains the min required data. This can lead to integer underflow. Add check for the same. Change-Id: I40242429542b6c32a0e6c3bbe03975c244c2f61a Signed-off-by: Soumya Managoli --- asoc/msm-pcm-voip-v2.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c index c926fa4e3037..cb71831fd22b 100644 --- a/asoc/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -368,7 +368,7 @@ static void voip_process_ul_pkt(uint8_t *voc_pkt, case MODE_AMR: { if (pkt_len <= DSP_FRAME_HDR_LEN) { pr_err("%s: pkt_len %d is < required len\n", - pkt_len); + __func__, pkt_len); spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags); return; @@ -395,7 +395,7 @@ static void voip_process_ul_pkt(uint8_t *voc_pkt, case MODE_4GV_NW: { if (pkt_len <= DSP_FRAME_HDR_LEN) { pr_err("%s: pkt_len %d is < required len\n", - pkt_len); + __func__, pkt_len); spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags); return; @@ -439,7 +439,7 @@ static void voip_process_ul_pkt(uint8_t *voc_pkt, if (pkt_len <= 2 * DSP_FRAME_HDR_LEN) { pr_err("%s: pkt_len %d is < required len\n", - pkt_len); + __func__, pkt_len); spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags); return; @@ -479,6 +479,14 @@ static void voip_process_ul_pkt(uint8_t *voc_pkt, buf_node->frame.frm_hdr.timestamp = timestamp; voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + if (pkt_len <= 2 * DSP_FRAME_HDR_LEN) { + pr_err("%s: pkt_len %d is < required len\n", + __func__, pkt_len); + spin_unlock_irqrestore(&prtd->dsp_ul_lock, + dsp_flags); + return; + } + /* There are two frames in the buffer. Length * of the second frame: */ From e21e857f42e1690dc3ba2dcb2b5667026f371c40 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Thu, 25 May 2023 11:20:59 +0530 Subject: [PATCH 08/12] ASoC: msm-pcm-host-voice: Address buffer overflow in hpcm playback copy Add buf len check for the playback data before copy to avoid OOB issues. Change-Id: I737d09e275463292365cd183b9a43d09ff9ccbf2 Signed-off-by: Soumya Managoli --- asoc/msm-pcm-host-voice-v2.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 3319e3dceb67..ad5ab90bee1a 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -663,6 +663,13 @@ static void hpcm_copy_playback_data_from_queue(struct dai_data *dai_data, struct hpcm_buf_node, list); list_del(&buf_node->list); *len = buf_node->frame.len; + + if (*len > HPCM_MAX_VOC_PKT_SIZE) { + pr_err("%s: Playback data len %d overflow\n", + __func__, *len); + return; + } + memcpy((u8 *)dai_data->vocpcm_ion_buffer.kvaddr, &buf_node->frame.voc_pkt[0], buf_node->frame.len); @@ -690,8 +697,8 @@ static void hpcm_copy_capture_data_to_queue(struct dai_data *dai_data, if (dai_data->substream == NULL) return; - if (len >= HPCM_MAX_VOC_PKT_SIZE) { - pr_err("%s: Copy capture data len %d is > HPCM_MAX_VOC_PKT_SIZE\n", + if (len > HPCM_MAX_VOC_PKT_SIZE) { + pr_err("%s: Copy capture data len %d overflow\n", __func__, len); return; } From 7db940a090a27a749678221e7bc87fc18f187779 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Mon, 10 Apr 2023 15:28:02 +0530 Subject: [PATCH 09/12] dsp: afe: Add check for sidetone iir config copy size Avoid OOB access of sidetone iir config array when iir_num_biquad_stages returned from cal block is > 10 Change-Id: I45b95e8bdd1a993a526590c94cf2f9a85c12af37 Signed-off-by: Soumya Managoli --- dsp/q6afe.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index a08843a74d31..ccd0b349d66e 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -8652,6 +8652,14 @@ static int afe_sidetone_iir(u16 tx_port_id) pr_debug("%s: adding 2 to size:%d\n", __func__, size); size = size + 2; } + + if (size > MAX_SIDETONE_IIR_DATA_SIZE) { + pr_err("%s: iir_config size is out of bounds:%d\n", __func__, size); + mutex_unlock(&this_afe.cal_data[cal_index]->lock); + ret = -EINVAL; + goto done; + } + memcpy(&filter_data.iir_config, &st_iir_cal_info->iir_config, size); mutex_unlock(&this_afe.cal_data[cal_index]->lock); From 40946c4d07bb630e47955ad508533c67edde9c24 Mon Sep 17 00:00:00 2001 From: Vijay Kumar Maddula Date: Thu, 13 Apr 2023 17:49:15 +0530 Subject: [PATCH 10/12] asoc: swrm: disable bus reset based on swrm verison Bus reset is creating mismatch in interrupt generation sequence and leading to audio playback mute. Disabling bus reset for soundwire master version 1.5 Change-Id: I1d41a8d11d1f86c8a538f0b8d234bb6d001268ad Signed-off-by: Vijay Kumar Maddula --- soc/swr-mstr-ctrl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index a41b2f5cee97..098f2fe1c36c 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -3165,7 +3165,9 @@ static int swrm_runtime_resume(struct device *dev) } swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); - swr_master_write(swrm, SWRM_MCP_BUS_CTRL, 0x01); + if (swrm->version > SWRM_VERSION_1_5) + swr_master_write(swrm, SWRM_MCP_BUS_CTRL, 0x01); + swrm_master_init(swrm); /* wait for hw enumeration to complete */ usleep_range(100, 105); From 1a53e0ded7c01fe2f345ed06aad3120b2a6b0327 Mon Sep 17 00:00:00 2001 From: Boyuan Yan Date: Mon, 29 May 2023 12:36:30 +0530 Subject: [PATCH 11/12] ASoC: Add the judgment for TDM Add support to remove unnecessary TDM route where TDM is not need. Change-Id: I56aee33cbb9ecbc190fc24bfa14a071263661292 Signed-off-by: Boyuan Yan --- asoc/msm-pcm-routing-v2.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d77844984bdb..696dc7fe8e90 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -36106,6 +36106,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia5 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, @@ -36122,7 +36123,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia6 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, @@ -36131,6 +36131,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia6 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia6 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif + {"MultiMedia6 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -36236,6 +36238,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia10 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, {"MultiMedia16 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, @@ -36252,6 +36255,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia16 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia16 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia16 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, +#endif {"MultiMedia16 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, @@ -36286,6 +36290,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia18 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia18 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, {"MultiMedia18 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia18 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, @@ -36294,6 +36299,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia18 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia18 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia18 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, @@ -36305,6 +36311,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia19 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, {"MultiMedia19 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia19 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, @@ -36313,6 +36320,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia19 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia19 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -36323,6 +36331,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia28 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia28 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, {"MultiMedia28 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia28 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, @@ -36331,6 +36340,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia28 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia28 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia28 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -36341,6 +36351,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia29 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia29 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, {"MultiMedia29 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia29 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, @@ -36349,6 +36360,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia29 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia29 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia29 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, From f47869b550cbc8c98c8c80b37cc2107f4650ec38 Mon Sep 17 00:00:00 2001 From: Shalini Manjunatha Date: Tue, 16 May 2023 16:57:11 +0530 Subject: [PATCH 12/12] ASoC: msm-pcm-q6-v2: Add dsp buf check Fix is to add check for this ADSP returned buf offset + size, if it is within the available buf size range Change-Id: I400cc4f5c07164f0a9b405ebea144ea0ae4b6cf2 Signed-off-by: Shalini Manjunatha --- asoc/msm-pcm-q6-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index b26ae17520c7..bb19c4b7d386 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1336,7 +1336,7 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, goto fail; } - if (size == 0 || size < prtd->pcm_count) { + if ((size == 0 || size < prtd->pcm_count) && ((offset + size) < prtd->pcm_count)) { memset(bufptr + offset + size, 0, prtd->pcm_count - size); if (fbytes > prtd->pcm_count) size = xfer = prtd->pcm_count;