From 47fb597026ca9eb314fc81e445e546995d962211 Mon Sep 17 00:00:00 2001 From: Shivakumar Malke Date: Thu, 1 Feb 2024 19:00:11 +0530 Subject: [PATCH 1/3] msm: camera: memmgr: Add missing calls of put buf to avoid leak This change add calls to put cpu buf in few scenarios. CRs-Fixed: 3578162 Change-Id: Iab6aa0324b5072390b38df296c7acee00f5102a1 Signed-off-by: Vikram Sharma Signed-off-by: Nirmal Abraham Signed-off-by: Shivakumar Malke Signed-off-by: Pranav Sanwal --- drivers/cam_isp/cam_isp_context.c | 8 +- drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c | 8 +- drivers/cam_req_mgr/cam_mem_mgr.c | 83 ++++++++++++------- drivers/cam_req_mgr/cam_mem_mgr.h | 4 +- .../cam_actuator/cam_actuator_core.c | 7 +- .../cam_csiphy/cam_csiphy_core.c | 4 +- .../cam_eeprom/cam_eeprom_core.c | 13 ++- .../cam_flash/cam_flash_core.c | 83 ++++++++++++++++++- .../cam_sensor_module/cam_ois/cam_ois_core.c | 41 ++++++++- .../cam_sensor/cam_sensor_core.c | 5 +- .../cam_sensor_utils/cam_sensor_util.c | 9 +- drivers/cam_utils/cam_common_util.h | 8 ++ drivers/cam_utils/cam_packet_util.c | 3 +- 13 files changed, 225 insertions(+), 51 deletions(-) diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index f9d0c147e78f0..da0a59be23533 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -363,6 +363,7 @@ static int cam_isp_ctx_dump_req( if (dump_to_buff) { if (!cpu_addr || !offset || !buf_len) { CAM_ERR(CAM_ISP, "Invalid args"); + cam_mem_put_cpu_buf(req_isp->cfg[i].handle); break; } dump_info.src_start = buf_start; @@ -373,8 +374,10 @@ static int cam_isp_ctx_dump_req( rc = cam_cdm_util_dump_cmd_bufs_v2( &dump_info); *offset = dump_info.dst_offset; - if (rc) + if (rc) { + cam_mem_put_cpu_buf(req_isp->cfg[i].handle); return rc; + } } else cam_cdm_util_dump_cmd_buf(buf_start, buf_end); cam_mem_put_cpu_buf(req_isp->cfg[i].handle); @@ -841,7 +844,6 @@ static int __cam_isp_ctx_handle_buf_done_for_req_list( req_isp->fence_map_out[i].sync_id, CAM_SYNC_STATE_SIGNALED_ERROR, CAM_SYNC_ISP_EVENT_BUBBLE); - list_add_tail(&req->list, &ctx->free_req_list); CAM_DBG(CAM_REQ, "Move active request %lld to free list(cnt = %d) [flushed], ctx %u", diff --git a/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c b/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c index 877e655cdb325..64ed8f3603482 100644 --- a/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c +++ b/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2022, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -2217,8 +2217,6 @@ static int cam_ope_mgr_process_cmd_buf_req(struct cam_ope_hw_mgr *hw_mgr, ope_request->ope_kmd_buf.cpu_addr, ope_request->ope_kmd_buf.iova_addr, ope_request->ope_kmd_buf.iova_cdm_addr); - cam_mem_put_cpu_buf(cmd_buf->mem_handle); - break; } else if (cmd_buf->cmd_buf_usage == OPE_CMD_BUF_DEBUG) { ope_request->ope_debug_buf.cpu_addr = @@ -2233,8 +2231,6 @@ static int cam_ope_mgr_process_cmd_buf_req(struct cam_ope_hw_mgr *hw_mgr, cmd_buf->offset; CAM_DBG(CAM_OPE, "dbg buf = %x", ope_request->ope_debug_buf.cpu_addr); - cam_mem_put_cpu_buf(cmd_buf->mem_handle); - break; } cam_mem_put_cpu_buf(cmd_buf->mem_handle); break; @@ -4209,7 +4205,7 @@ static void cam_ope_mgr_dump_pf_data( if (rc) { CAM_ERR(CAM_OPE, "CAM_OPE_CMD_MATCH_PID_MID failed %d", rc); - return; + return; } *resource_type = ope_pid_mid_args.match_res; diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index 7b7acba371d18..9e2efb911cbd9 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/cam_req_mgr/cam_mem_mgr.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -26,32 +26,19 @@ static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED); static void cam_mem_mgr_print_tbl(void) { int i; - uint64_t ms, tmp, hrs, min, sec; - struct timespec64 *ts = NULL; + uint64_t ms, hrs, min, sec; struct timespec64 current_ts; - ktime_get_real_ts64(&(current_ts)); - tmp = current_ts.tv_sec; - ms = (current_ts.tv_nsec) / 1000000; - sec = do_div(tmp, 60); - min = do_div(tmp, 60); - hrs = do_div(tmp, 24); - + CAM_GET_TIMESTAMP(current_ts); + CAM_CONVERT_TIMESTAMP_FORMAT(current_ts, hrs, min, sec, ms); CAM_INFO(CAM_MEM, "***%llu:%llu:%llu:%llu Mem mgr table dump***", hrs, min, sec, ms); for (i = 1; i < CAM_MEM_BUFQ_MAX; i++) { - if (tbl.bufq[i].active) { - ts = &tbl.bufq[i].timestamp; - tmp = ts->tv_sec; - ms = (ts->tv_nsec) / 1000000; - sec = do_div(tmp, 60); - min = do_div(tmp, 60); - hrs = do_div(tmp, 24); - CAM_INFO(CAM_MEM, - "%llu:%llu:%llu:%llu idx %d fd %d size %llu", - hrs, min, sec, ms, i, tbl.bufq[i].fd, - tbl.bufq[i].len); - } + CAM_CONVERT_TIMESTAMP_FORMAT((tbl.bufq[i].timestamp), hrs, min, sec, ms); + CAM_INFO(CAM_MEM, + "%llu:%llu:%llu:%llu idx %d fd %d size %llu active %d buf_handle %d refCount %d", + hrs, min, sec, ms, i, tbl.bufq[i].fd, tbl.bufq[i].len, tbl.bufq[i].active, + tbl.bufq[i].buf_handle, kref_read(&tbl.bufq[i].krefcount)); } } @@ -208,7 +195,8 @@ static int32_t cam_mem_get_slot(void) set_bit(idx, tbl.bitmap); tbl.bufq[idx].active = true; - ktime_get_real_ts64(&(tbl.bufq[idx].timestamp)); + tbl.bufq[idx].release_deferred = false; + CAM_GET_TIMESTAMP((tbl.bufq[idx].timestamp)); mutex_init(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.m_lock); @@ -220,6 +208,7 @@ static void cam_mem_put_slot(int32_t idx) mutex_lock(&tbl.m_lock); mutex_lock(&tbl.bufq[idx].q_lock); tbl.bufq[idx].active = false; + tbl.bufq[idx].release_deferred = false; tbl.bufq[idx].is_internal = false; memset(&tbl.bufq[idx].timestamp, 0, sizeof(struct timespec64)); mutex_unlock(&tbl.bufq[idx].q_lock); @@ -696,6 +685,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) if (idx < 0) { CAM_ERR(CAM_MEM, "Failed in getting mem slot, idx=%d", idx); rc = -ENOMEM; + cam_mem_mgr_print_tbl(); goto slot_fail; } @@ -853,6 +843,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) CAM_ERR(CAM_MEM, "Failed in getting mem slot, idx=%d, fd=%d", idx, cmd->fd); rc = -ENOMEM; + cam_mem_mgr_print_tbl(); goto slot_fail; } @@ -1036,6 +1027,7 @@ static int cam_mem_mgr_cleanup_table(void) tbl.bufq[i].num_hdl = 0; tbl.bufq[i].dma_buf = NULL; tbl.bufq[i].active = false; + tbl.bufq[i].release_deferred = false; tbl.bufq[i].is_internal = false; mutex_unlock(&tbl.bufq[i].q_lock); mutex_destroy(&tbl.bufq[i].q_lock); @@ -1095,6 +1087,7 @@ static void cam_mem_util_unmap(struct kref *kref) mutex_lock(&tbl.bufq[idx].q_lock); tbl.bufq[idx].active = false; tbl.bufq[idx].vaddr = 0; + tbl.bufq[idx].release_deferred = false; mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.m_lock); @@ -1159,6 +1152,8 @@ void cam_mem_put_cpu_buf(int32_t buf_handle) { int rc = 0; int idx; + uint64_t ms, hrs, min, sec; + struct timespec64 current_ts; if (!buf_handle) { CAM_ERR(CAM_MEM, "Invalid buf_handle"); @@ -1184,11 +1179,25 @@ void cam_mem_put_cpu_buf(int32_t buf_handle) return; } - if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap)) + if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap)) { + CAM_GET_TIMESTAMP(current_ts); + CAM_CONVERT_TIMESTAMP_FORMAT(current_ts, hrs, min, sec, ms); CAM_DBG(CAM_MEM, - "Called unmap from here, buf_handle: %u, idx: %d", - buf_handle, idx); - + "%llu:%llu:%llu:%llu Called unmap from here, buf_handle: %u, idx: %d", + hrs, min, sec, ms, buf_handle, idx); + } else if (tbl.bufq[idx].release_deferred) { + CAM_CONVERT_TIMESTAMP_FORMAT((tbl.bufq[idx].timestamp), hrs, min, sec, ms); + CAM_ERR(CAM_MEM, + "%llu:%llu:%llu:%llu idx %d fd %d size %llu active %d buf_handle %d refCount %d", + hrs, min, sec, ms, idx, tbl.bufq[idx].fd, tbl.bufq[idx].len, + tbl.bufq[idx].active, tbl.bufq[idx].buf_handle, + kref_read(&tbl.bufq[idx].krefcount)); + CAM_GET_TIMESTAMP(current_ts); + CAM_CONVERT_TIMESTAMP_FORMAT(current_ts, hrs, min, sec, ms); + CAM_ERR(CAM_MEM, + "%llu:%llu:%llu:%llu Not unmapping even after defer, buf_handle: %u, idx: %d", + hrs, min, sec, ms, buf_handle, idx); + } } EXPORT_SYMBOL(cam_mem_put_cpu_buf); @@ -1197,6 +1206,8 @@ int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd) { int idx; int rc = 0; + uint64_t ms, hrs, min, sec; + struct timespec64 current_ts; if (!atomic_read(&cam_mem_mgr_state)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); @@ -1228,12 +1239,22 @@ int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd) } CAM_DBG(CAM_MEM, "Releasing hdl = %x, idx = %d", cmd->buf_handle, idx); - - if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap)) + if (kref_put(&tbl.bufq[idx].krefcount, cam_mem_util_unmap)) { CAM_DBG(CAM_MEM, "Called unmap from here, buf_handle: %u, idx: %d", cmd->buf_handle, idx); - + } else { + rc = -EINVAL; + CAM_GET_TIMESTAMP(current_ts); + CAM_CONVERT_TIMESTAMP_FORMAT(current_ts, hrs, min, sec, ms); + CAM_CONVERT_TIMESTAMP_FORMAT((tbl.bufq[idx].timestamp), hrs, min, sec, ms); + CAM_ERR(CAM_MEM, + "%llu:%llu:%llu:%llu idx %d fd %d size %llu active %d buf_handle %d refCount %d", + hrs, min, sec, ms, idx, tbl.bufq[idx].fd, tbl.bufq[idx].len, + tbl.bufq[idx].active, tbl.bufq[idx].buf_handle, + kref_read(&tbl.bufq[idx].krefcount)); + tbl.bufq[idx].release_deferred = true; + } return rc; } @@ -1336,6 +1357,7 @@ int cam_mem_mgr_request_mem(struct cam_mem_mgr_request_desc *inp, if (idx < 0) { CAM_ERR(CAM_MEM, "Failed in getting mem slot, idx=%d", idx); rc = -ENOMEM; + cam_mem_mgr_print_tbl(); goto slot_fail; } @@ -1492,6 +1514,7 @@ int cam_mem_mgr_reserve_memory_region(struct cam_mem_mgr_request_desc *inp, if (idx < 0) { CAM_ERR(CAM_MEM, "Failed in getting mem slot, idx=%d", idx); rc = -ENOMEM; + cam_mem_mgr_print_tbl(); goto slot_fail; } diff --git a/drivers/cam_req_mgr/cam_mem_mgr.h b/drivers/cam_req_mgr/cam_mem_mgr.h index 74c7c9280768d..2a78827271ad8 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.h +++ b/drivers/cam_req_mgr/cam_mem_mgr.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_MEM_MGR_H_ @@ -39,6 +39,7 @@ enum cam_smmu_mapping_client { * @vaddr: IOVA of buffer * @kmdvaddr: Kernel virtual address * @active: state of the buffer + * @release_deferred: Buffer is deferred for release. * @is_imported: Flag indicating if buffer is imported from an FD in user space * @is_internal: Flag indicating kernel allocated buffer * @timestamp: Timestamp at which this entry in tbl was made @@ -59,6 +60,7 @@ struct cam_mem_buf_queue { uint64_t vaddr; uintptr_t kmdvaddr; bool active; + bool release_deferred; bool is_imported; bool is_internal; struct timespec64 timestamp; diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c index d8c052ac313b0..6d3c7a50207b1 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -522,6 +522,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, cmd_buf = (uint32_t *)generic_ptr; if (!cmd_buf) { CAM_ERR(CAM_ACTUATOR, "invalid cmd buf"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); rc = -EINVAL; goto end; } @@ -530,6 +531,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, sizeof(struct common_header)))) { CAM_ERR(CAM_ACTUATOR, "Invalid length for sensor cmd"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); rc = -EINVAL; goto end; } @@ -546,6 +548,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Failed to parse slave info: %d", rc); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); goto end; } break; @@ -561,6 +564,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, CAM_ERR(CAM_ACTUATOR, "Failed:parse power settings: %d", rc); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); goto end; } break; @@ -581,6 +585,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, CAM_ERR(CAM_ACTUATOR, "Failed:parse init settings: %d", rc); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); goto end; } break; diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 8f1e55a8791c0..59946e481246e 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -433,6 +433,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, index = cam_csiphy_get_instance_offset(csiphy_dev, cfg_dev->dev_handle); if (index < 0 || index >= csiphy_dev->session_max_device_support) { CAM_ERR(CAM_CSIPHY, "index in invalid: %d", index); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); return -EINVAL; } @@ -442,6 +443,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, CAM_ERR(CAM_CSIPHY, "Wrong configuration lane_cnt: %u", cam_cmd_csiphy_info->lane_cnt); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); return rc; } diff --git a/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index e36578e7a59e0..b43fe126938ca 100644 --- a/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1113,6 +1113,7 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl, } if (buf_size <= io_cfg->offsets[0]) { CAM_ERR(CAM_EEPROM, "Not enough buffer"); + cam_mem_put_cpu_buf(io_cfg->mem_handle[0]); rc = -EINVAL; return rc; } @@ -1125,6 +1126,7 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl, if (!read_buffer) { CAM_ERR(CAM_EEPROM, "invalid buffer to copy data"); + cam_mem_put_cpu_buf(io_cfg->mem_handle[0]); rc = -EINVAL; return rc; } @@ -1133,6 +1135,7 @@ static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl, if (remain_len < e_ctrl->cal_data.num_data) { CAM_ERR(CAM_EEPROM, "failed to copy, Invalid size"); + cam_mem_put_cpu_buf(io_cfg->mem_handle[0]); rc = -EINVAL; return rc; } @@ -1248,6 +1251,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) "Inval cam_packet strut size: %zu, len_of_buff: %zu", sizeof(struct cam_packet), pkt_len); rc = -EINVAL; + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -1258,6 +1262,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) if (cam_packet_util_validate_packet(csl_packet, remain_len)) { CAM_ERR(CAM_EEPROM, "Invalid packet params"); + cam_mem_put_cpu_buf(dev_config.packet_handle); rc = -EINVAL; return rc; } @@ -1269,6 +1274,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) e_ctrl->soc_info.dev->of_node, e_ctrl); if (rc < 0) { CAM_ERR(CAM_EEPROM, "Failed: rc : %d", rc); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } rc = cam_eeprom_get_cal_data(e_ctrl, csl_packet); @@ -1284,6 +1290,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) if (rc) { CAM_ERR(CAM_EEPROM, "Failed in parsing the pkt"); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -1342,6 +1349,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) csl_packet, e_ctrl); if (rc < 0) { CAM_ERR(CAM_EEPROM, "Failed: rc : %d", rc); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -1363,6 +1371,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) e_ctrl->eebin_info.size); if (rc < 0) { CAM_ERR(CAM_EEPROM, "Failed in erase : %d", rc); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -1372,6 +1381,7 @@ static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) rc = cam_eeprom_write(e_ctrl); if (rc < 0) { CAM_ERR(CAM_EEPROM, "Failed: rc : %d", rc); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -1397,6 +1407,7 @@ power_down: memdata_free: vfree(e_ctrl->cal_data.mapdata); error: + cam_mem_put_cpu_buf(dev_config.packet_handle); kfree(power_info->power_setting); kfree(power_info->power_down_setting); power_info->power_setting = NULL; diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index 26c433f2ce61f..029ec542d491a 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1026,6 +1026,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "Inval cam_packet strut size: %zu, len_of_buff: %zu", sizeof(struct cam_packet), len_of_buffer); + cam_mem_put_cpu_buf(config.packet_handle); return -EINVAL; } @@ -1036,6 +1037,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (cam_packet_util_validate_packet(csl_packet, remain_len)) { CAM_ERR(CAM_FLASH, "Invalid packet params"); + cam_mem_put_cpu_buf(config.packet_handle); return -EINVAL; } @@ -1046,6 +1048,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_DBG(CAM_FLASH, "reject request %lld, last request to flush %lld", csl_packet->header.request_id, fctrl->last_flush_req); + cam_mem_put_cpu_buf(config.packet_handle); return -EINVAL; } @@ -1072,12 +1075,15 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle, &generic_ptr, &len_of_buffer); if (rc < 0) { + cam_mem_put_cpu_buf(config.packet_handle); CAM_ERR(CAM_FLASH, "Failed to get cpu buf"); return rc; } cmd_buf = (uint32_t *)generic_ptr; if (!cmd_buf) { CAM_ERR(CAM_FLASH, "invalid cmd buf"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return -EINVAL; } @@ -1085,6 +1091,8 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) (cmd_desc[i].offset > (len_of_buffer - sizeof(struct common_header)))) { + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); CAM_ERR(CAM_FLASH, "invalid cmd buf length"); return -EINVAL; } @@ -1102,6 +1110,8 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (len_of_buffer < sizeof(struct cam_flash_init)) { CAM_ERR(CAM_FLASH, "Not enough buffer"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return -EINVAL; } @@ -1121,6 +1131,8 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "Failed parsing slave info: rc: %d", rc); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } cmd_length_in_bytes = @@ -1147,6 +1159,8 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc) { CAM_ERR(CAM_FLASH, "Failed update power settings"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } break; @@ -1166,6 +1180,8 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc < 0) { CAM_ERR(CAM_FLASH, "pkt parsing failed: %d", rc); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } cmd_length_in_bytes = @@ -1182,6 +1198,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) power_info = &fctrl->power_info; if (!power_info) { CAM_ERR(CAM_FLASH, "Power_info is NULL"); + cam_mem_put_cpu_buf(config.packet_handle); return -EINVAL; } @@ -1193,6 +1210,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "failed to fill vreg params for power up rc:%d", rc); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1205,6 +1223,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "failed to fill vreg params power down rc:%d", rc); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1212,12 +1231,14 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc) { CAM_ERR(CAM_FLASH, "Enable Regulator Failed rc = %d", rc); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } rc = fctrl->func_tbl.apply_setting(fctrl, 0); if (rc) { CAM_ERR(CAM_FLASH, "cannot apply settings rc = %d", rc); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1248,6 +1269,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc) { CAM_ERR(CAM_FLASH, "Failed in parsing i2c packets"); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } if ((fctrl->flash_state == CAM_FLASH_STATE_ACQUIRE) || @@ -1276,6 +1298,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc) { CAM_ERR(CAM_FLASH, "Failed in Deleting the err: %d", rc); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } } @@ -1289,12 +1312,14 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc) { CAM_ERR(CAM_FLASH, "Failed in parsing i2c NRT packets"); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } rc = fctrl->func_tbl.apply_setting(fctrl, 0); if (rc) CAM_ERR(CAM_FLASH, "Apply setting failed: %d", rc); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } case CAM_PKT_NOP_OPCODE: { @@ -1306,6 +1331,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) "Rxed NOP packets without linking"); fctrl->i2c_data.per_frame[frm_offset].is_settings_valid = false; + cam_mem_put_cpu_buf(config.packet_handle); return 0; } i2c_reg_settings = @@ -1343,6 +1369,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) default: CAM_ERR(CAM_FLASH, "Wrong Opcode : %d", (csl_packet->header.op_code & 0xFFFFFF)); + cam_mem_put_cpu_buf(config.packet_handle); return -EINVAL; } update_req_mgr: @@ -1368,6 +1395,7 @@ update_req_mgr: CAM_ERR(CAM_FLASH, "Failed in adding request: %llu to request manager", csl_packet->header.request_id); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } CAM_DBG(CAM_FLASH, @@ -1434,6 +1462,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "Inval cam_packet strut size: %zu, len_of_buff: %zu", sizeof(struct cam_packet), len_of_buffer); + cam_mem_put_cpu_buf(config.packet_handle); rc = -EINVAL; return rc; } @@ -1445,6 +1474,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (cam_packet_util_validate_packet(csl_packet, remain_len)) { CAM_ERR(CAM_FLASH, "Invalid packet params"); + cam_mem_put_cpu_buf(config.packet_handle); rc = -EINVAL; return rc; } @@ -1456,6 +1486,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_WARN(CAM_FLASH, "reject request %lld, last request to flush %d", csl_packet->header.request_id, fctrl->last_flush_req); + cam_mem_put_cpu_buf(config.packet_handle); rc = -EINVAL; return rc; } @@ -1472,12 +1503,15 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle, &cmd_buf_ptr, &len_of_buffer); if (rc) { + cam_mem_put_cpu_buf(config.packet_handle); CAM_ERR(CAM_FLASH, "Fail in get buffer: %d", rc); return rc; } if ((len_of_buffer < sizeof(struct cam_flash_init)) || (cmd_desc->offset > (len_of_buffer - sizeof(struct cam_flash_init)))) { + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); CAM_ERR(CAM_FLASH, "Not enough buffer"); rc = -EINVAL; return rc; @@ -1508,6 +1542,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (remain_len < sizeof(struct cam_flash_set_on_off)) { CAM_ERR(CAM_FLASH, "Not enough buffer"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1516,12 +1552,16 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (!flash_operation_info) { CAM_ERR(CAM_FLASH, "flash_operation_info Null"); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); rc = -EINVAL; return rc; } if (flash_operation_info->count > CAM_FLASH_MAX_LED_TRIGGERS) { CAM_ERR(CAM_FLASH, "led count out of limit"); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); rc = -EINVAL; return rc; } @@ -1550,6 +1590,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "Wrong cmd_type = %d", cam_flash_info->cmd_type); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1578,6 +1620,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc) { CAM_ERR(CAM_FLASH, "Fail in get buffer: 0x%x", cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1585,6 +1628,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) (cmd_desc->offset > (len_of_buffer - sizeof(struct common_header)))) { CAM_ERR(CAM_FLASH, "not enough buffer"); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); rc = -EINVAL; return rc; } @@ -1614,6 +1659,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (remain_len < sizeof(struct cam_flash_set_on_off)) { CAM_ERR(CAM_FLASH, "Not enough buffer"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1623,11 +1670,15 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "flash_operation_info Null"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } if (flash_operation_info->count > CAM_FLASH_MAX_LED_TRIGGERS) { CAM_ERR(CAM_FLASH, "led count out of limit"); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); rc = -EINVAL; return rc; } @@ -1658,6 +1709,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) default: CAM_ERR(CAM_FLASH, "Wrong cmd_type = %d", cmn_hdr->cmd_type); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); rc = -EINVAL; return rc; } @@ -1673,6 +1726,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle, &cmd_buf_ptr, &len_of_buffer); if (rc) { + cam_mem_put_cpu_buf(config.packet_handle); CAM_ERR(CAM_FLASH, "Fail in get buffer: %d", rc); return rc; } @@ -1682,6 +1736,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) (len_of_buffer - sizeof(struct common_header)))) { CAM_ERR(CAM_FLASH, "Not enough buffer"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } remain_len = len_of_buffer - cmd_desc->offset; @@ -1695,6 +1751,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (remain_len < sizeof(struct cam_flash_set_on_off)) { CAM_ERR(CAM_FLASH, "Not enough buffer"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } flash_operation_info = @@ -1703,12 +1761,16 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "flash_operation_info Null"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } if (flash_operation_info->count > CAM_FLASH_MAX_LED_TRIGGERS) { CAM_ERR(CAM_FLASH, "led count out of limit"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1728,6 +1790,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc) CAM_ERR(CAM_FLASH, "Apply setting failed: %d", rc); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } case CAMERA_SENSOR_FLASH_CMD_TYPE_QUERYCURR: { @@ -1736,6 +1800,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (remain_len < sizeof(struct cam_flash_query_curr)) { CAM_ERR(CAM_FLASH, "Not enough buffer"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } flash_query_info = @@ -1750,6 +1816,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc) { CAM_ERR(CAM_FLASH, "Query current failed with rc=%d", rc); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } flash_query_info->query_current_ma = query_curr_ma; @@ -1760,6 +1828,8 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (remain_len < sizeof(struct cam_flash_set_rer)) { CAM_ERR(CAM_FLASH, "Not enough buffer"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } flash_rer_info = (struct cam_flash_set_rer *)cmd_buf; @@ -1767,12 +1837,16 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "flash_rer_info Null"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } if (flash_rer_info->count > CAM_FLASH_MAX_LED_TRIGGERS) { CAM_ERR(CAM_FLASH, "led count out of limit"); rc = -EINVAL; + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1796,11 +1870,15 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (rc) CAM_ERR(CAM_FLASH, "apply_setting failed: %d", rc); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } default: CAM_ERR(CAM_FLASH, "Wrong cmd_type : %d", cmn_hdr->cmd_type); + cam_mem_put_cpu_buf(cmd_desc->mem_handle); + cam_mem_put_cpu_buf(config.packet_handle); rc = -EINVAL; return rc; } @@ -1817,6 +1895,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) "Rxed NOP packets without linking"); fctrl->per_frame[frm_offset].cmn_attr.is_settings_valid = false; + cam_mem_put_cpu_buf(config.packet_handle); return -EINVAL; } @@ -1831,6 +1910,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "Wrong Opcode : %d", (csl_packet->header.op_code & 0xFFFFFF)); rc = -EINVAL; + cam_mem_put_cpu_buf(config.packet_handle); return rc; } @@ -1860,6 +1940,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_ERR(CAM_FLASH, "Failed in adding request: %llu to request manager", csl_packet->header.request_id); + cam_mem_put_cpu_buf(config.packet_handle); return rc; } CAM_DBG(CAM_FLASH, diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c index 586c1dcd21e20..e62e00d88d276 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -519,6 +519,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_ERR(CAM_OIS, "Inval cam_packet strut size: %zu, len_of_buff: %zu", sizeof(struct cam_packet), pkt_len); + cam_mem_put_cpu_buf(dev_config.packet_handle); return -EINVAL; } @@ -529,6 +530,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (cam_packet_util_validate_packet(csl_packet, remain_len)) { CAM_ERR(CAM_OIS, "Invalid packet params"); + cam_mem_put_cpu_buf(dev_config.packet_handle); return -EINVAL; } @@ -554,11 +556,14 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (rc < 0) { CAM_ERR(CAM_OIS, "Failed to get cpu buf : 0x%x", cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } cmd_buf = (uint32_t *)generic_ptr; if (!cmd_buf) { CAM_ERR(CAM_OIS, "invalid cmd buf"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(dev_config.packet_handle); return -EINVAL; } @@ -567,6 +572,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) sizeof(struct common_header)))) { CAM_ERR(CAM_OIS, "Invalid length for sensor cmd"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(dev_config.packet_handle); return -EINVAL; } remain_len = len_of_buff - cmd_desc[i].offset; @@ -580,6 +587,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (rc < 0) { CAM_ERR(CAM_OIS, "Failed in parsing slave info"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } break; @@ -594,6 +603,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (rc) { CAM_ERR(CAM_OIS, "Failed: parse power settings"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } break; @@ -612,6 +623,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (rc < 0) { CAM_ERR(CAM_OIS, "init parsing failed: %d", rc); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } } else if ((o_ctrl->is_ois_calib != 0) && @@ -629,6 +642,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (rc < 0) { CAM_ERR(CAM_OIS, "Calib parsing failed: %d", rc); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } } @@ -641,6 +656,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) rc = cam_ois_power_up(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, " OIS Power up failed"); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } o_ctrl->cam_ois_state = CAM_OIS_CONFIG; @@ -698,6 +714,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_WARN(CAM_OIS, "Not in right state to control OIS: %d", o_ctrl->cam_ois_state); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } offset = (uint32_t *)&csl_packet->payload; @@ -711,12 +728,14 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) cmd_desc, 1, NULL); if (rc < 0) { CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } rc = cam_ois_apply_settings(o_ctrl, i2c_reg_settings); if (rc < 0) { CAM_ERR(CAM_OIS, "Cannot apply mode settings"); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -724,6 +743,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (rc < 0) { CAM_ERR(CAM_OIS, "Fail deleting Mode data: rc: %d", rc); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } break; @@ -736,6 +756,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_WARN(CAM_OIS, "Not in right state to read OIS: %d", o_ctrl->cam_ois_state); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } CAM_DBG(CAM_OIS, "number of I/O configs: %d:", @@ -743,6 +764,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (csl_packet->num_io_configs == 0) { CAM_ERR(CAM_OIS, "No I/O configs to process"); rc = -EINVAL; + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -756,6 +778,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (io_cfg == NULL) { CAM_ERR(CAM_OIS, "I/O config is invalid(NULL)"); rc = -EINVAL; + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -769,6 +792,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) cmd_desc, 1, &io_cfg[0]); if (rc < 0) { CAM_ERR(CAM_OIS, "OIS read pkt parsing failed: %d", rc); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -778,6 +802,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (rc < 0) { CAM_ERR(CAM_OIS, "cannot read data rc: %d", rc); delete_request(&i2c_read_settings); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -788,6 +813,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_ERR(CAM_OIS, "write qtimer failed rc: %d", rc); delete_request(&i2c_read_settings); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } } @@ -796,6 +822,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (rc < 0) { CAM_ERR(CAM_OIS, "Failed in deleting the read settings"); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } break; @@ -806,6 +833,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_ERR(CAM_OIS, "Not in right state to write time to OIS: %d", o_ctrl->cam_ois_state); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } offset = (uint32_t *)&csl_packet->payload; @@ -819,18 +847,21 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) cmd_desc, 1, NULL); if (rc < 0) { CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } rc = cam_ois_update_time(i2c_reg_settings); if (rc < 0) { CAM_ERR(CAM_OIS, "Cannot update time"); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } rc = cam_ois_apply_settings(o_ctrl, i2c_reg_settings); if (rc < 0) { CAM_ERR(CAM_OIS, "Cannot apply mode settings"); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } @@ -838,6 +869,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (rc < 0) { CAM_ERR(CAM_OIS, "Fail deleting Mode data: rc: %d", rc); + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; } break; @@ -845,13 +877,16 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) default: CAM_ERR(CAM_OIS, "Invalid Opcode: %d", (csl_packet->header.op_code & 0xFFFFFF)); + cam_mem_put_cpu_buf(dev_config.packet_handle); return -EINVAL; } - cam_mem_put_cpu_buf(dev_config.packet_handle); - if (!rc) + if (!rc) { + cam_mem_put_cpu_buf(dev_config.packet_handle); return rc; + } pwr_dwn: + cam_mem_put_cpu_buf(dev_config.packet_handle); cam_ois_power_down(o_ctrl); return rc; } diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 08637ce6a8346..999fec0383247 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -571,6 +571,7 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl) if (cmd_desc[i].offset >= len) { CAM_ERR(CAM_SENSOR, "offset past length of buffer"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); rc = -EINVAL; goto end; } @@ -578,6 +579,7 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl) if (cmd_desc[i].length > remain_len) { CAM_ERR(CAM_SENSOR, "Not enough buffer provided for cmd"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); rc = -EINVAL; goto end; } @@ -590,6 +592,7 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl) if (rc < 0) { CAM_ERR(CAM_SENSOR, "Failed to parse the command Buffer Header"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); goto end; } cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); diff --git a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index c90510e954d69..87b032580527b 100644 --- a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -309,6 +309,7 @@ static int32_t cam_sensor_get_io_buffer( CAM_ERR(CAM_SENSOR, "invalid size:io_cfg->offsets[0]: %d, buf_size: %d", io_cfg->offsets[0], buf_size); + cam_mem_put_cpu_buf(io_cfg->mem_handle[0]); return -EINVAL; } i2c_settings->read_buff = @@ -354,6 +355,7 @@ int32_t cam_sensor_util_write_qtimer_to_io_buffer( CAM_ERR(CAM_SENSOR, "invalid size:io_cfg->offsets[0]: %d, buf_size: %d", io_cfg->offsets[0], buf_size); + cam_mem_put_cpu_buf(io_cfg->mem_handle[0]); return -EINVAL; } @@ -364,6 +366,7 @@ int32_t cam_sensor_util_write_qtimer_to_io_buffer( CAM_ERR(CAM_SENSOR, "not enough size for qtimer, target_size:%d", target_size); + cam_mem_put_cpu_buf(io_cfg->mem_handle[0]); return -EINVAL; } @@ -374,12 +377,12 @@ int32_t cam_sensor_util_write_qtimer_to_io_buffer( } memcpy((void *)target_buf, &qtime_ns, sizeof(uint64_t)); + cam_mem_put_cpu_buf(io_cfg->mem_handle[0]); } else { CAM_ERR(CAM_SENSOR, "Invalid direction: %d", io_cfg->direction); rc = -EINVAL; } - cam_mem_put_cpu_buf(io_cfg->mem_handle[0]); return rc; } @@ -568,6 +571,7 @@ int cam_sensor_i2c_command_parser( (cmd_desc[i].offset > (len_of_buff - sizeof(struct common_header)))) { CAM_ERR(CAM_SENSOR, "buffer provided too small"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); return -EINVAL; } cmd_buf = (uint32_t *)generic_ptr; @@ -576,6 +580,7 @@ int cam_sensor_i2c_command_parser( remain_len -= cmd_desc[i].offset; if (remain_len < cmd_desc[i].length) { CAM_ERR(CAM_SENSOR, "buffer provided too small"); + cam_mem_put_cpu_buf(cmd_desc[i].mem_handle); return -EINVAL; } diff --git a/drivers/cam_utils/cam_common_util.h b/drivers/cam_utils/cam_common_util.h index 60fd2f629c3d4..867aa5753f5af 100644 --- a/drivers/cam_utils/cam_common_util.h +++ b/drivers/cam_utils/cam_common_util.h @@ -32,6 +32,14 @@ } \ }) +#define CAM_CONVERT_TIMESTAMP_FORMAT(ts, hrs, min, sec, ms) \ +({ \ + uint64_t tmp = ((ts).tv_sec); \ + (ms) = ((ts).tv_nsec) / 1000000; \ + (sec) = do_div(tmp, 60); \ + (min) = do_div(tmp, 60); \ + (hrs) = do_div(tmp, 24); \ +}) /** * cam_common_util_get_string_index() diff --git a/drivers/cam_utils/cam_packet_util.c b/drivers/cam_utils/cam_packet_util.c index 790956ad92f9b..04721f0b616b4 100644 --- a/drivers/cam_utils/cam_packet_util.c +++ b/drivers/cam_utils/cam_packet_util.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -32,6 +32,7 @@ int cam_packet_util_get_cmd_mem_addr(int handle, uint32_t **buf_addr, if (kmd_buf_addr && *len) { *buf_addr = (uint32_t *)kmd_buf_addr; } else { + cam_mem_put_cpu_buf(handle); CAM_ERR(CAM_UTIL, "Invalid addr and length :%zd", *len); rc = -ENOMEM; } From c9cd58783edf24b9dc554a30d01f035dd8721632 Mon Sep 17 00:00:00 2001 From: Shivi Mangal Date: Tue, 16 Jan 2024 13:50:21 +0530 Subject: [PATCH 2/3] msm: camera: sensor: Proper handling of race condition in util api Power count is coming from user space which can be modified due to access to shared memory. This change scopes the data locally so as to avoid vulnerability of count being modified by external means while executing due to being in shared memory. CRs-Fixed: 3691744. Change-Id: I57d13435453195f8aab0c9aad4414d290274ff81 Signed-off-by: Shivi Mangal --- .../cam_sensor_utils/cam_sensor_util.c | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index c90510e954d69..b4d43b3c65a8c 100644 --- a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1325,22 +1325,29 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, int32_t i = 0, pwr_up = 0, pwr_down = 0; struct cam_sensor_power_setting *pwr_settings; void *ptr = cmd_buf, *scr; - struct cam_cmd_power *pwr_cmd = (struct cam_cmd_power *)cmd_buf; struct common_header *cmm_hdr = (struct common_header *)cmd_buf; + struct cam_cmd_power *pwr_cmd = + kzalloc(sizeof(struct cam_cmd_power), GFP_KERNEL); + if (!pwr_cmd) + return -ENOMEM; + memcpy(pwr_cmd, cmd_buf, sizeof(struct cam_cmd_power)); if (!pwr_cmd || !cmd_length || cmd_buf_len < (size_t)cmd_length || cam_sensor_validate(cmd_buf, cmd_buf_len)) { CAM_ERR(CAM_SENSOR, "Invalid Args: pwr_cmd %pK, cmd_length: %d", pwr_cmd, cmd_length); - return -EINVAL; + rc = -EINVAL; + goto free_power_command; } power_info->power_setting_size = 0; power_info->power_setting = kzalloc(sizeof(struct cam_sensor_power_setting) * MAX_POWER_CONFIG, GFP_KERNEL); - if (!power_info->power_setting) - return -ENOMEM; + if (!power_info->power_setting) { + rc = -ENOMEM; + goto free_power_command; + } power_info->power_down_setting_size = 0; power_info->power_down_setting = @@ -1350,7 +1357,8 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, kfree(power_info->power_setting); power_info->power_setting = NULL; power_info->power_setting_size = 0; - return -ENOMEM; + rc = -ENOMEM; + goto free_power_command; } while (tot_size < cmd_length) { @@ -1534,7 +1542,7 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, } } - return rc; + goto free_power_command; free_power_settings: kfree(power_info->power_down_setting); kfree(power_info->power_setting); @@ -1542,6 +1550,9 @@ free_power_settings: power_info->power_setting = NULL; power_info->power_down_setting_size = 0; power_info->power_setting_size = 0; +free_power_command: + kfree(pwr_cmd); + pwr_cmd = NULL; return rc; } From 7440c110a444750f8c84c2cd6168e7d487463232 Mon Sep 17 00:00:00 2001 From: Shivi Mangal Date: Tue, 16 Jan 2024 13:50:21 +0530 Subject: [PATCH 3/3] msm: camera: sensor: Proper handling of race condition in util api Power count is coming from user space which can be modified due to access to shared memory. This change scopes the data locally so as to avoid vulnerability of count being modified by external means while executing due to being in shared memory. CRs-Fixed: 3691744. Change-Id: I57d13435453195f8aab0c9aad4414d290274ff81 Signed-off-by: Shivi Mangal (cherry picked from commit c9cd58783edf24b9dc554a30d01f035dd8721632) --- .../cam_sensor_utils/cam_sensor_util.c | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index c90510e954d69..b4d43b3c65a8c 100644 --- a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1325,22 +1325,29 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, int32_t i = 0, pwr_up = 0, pwr_down = 0; struct cam_sensor_power_setting *pwr_settings; void *ptr = cmd_buf, *scr; - struct cam_cmd_power *pwr_cmd = (struct cam_cmd_power *)cmd_buf; struct common_header *cmm_hdr = (struct common_header *)cmd_buf; + struct cam_cmd_power *pwr_cmd = + kzalloc(sizeof(struct cam_cmd_power), GFP_KERNEL); + if (!pwr_cmd) + return -ENOMEM; + memcpy(pwr_cmd, cmd_buf, sizeof(struct cam_cmd_power)); if (!pwr_cmd || !cmd_length || cmd_buf_len < (size_t)cmd_length || cam_sensor_validate(cmd_buf, cmd_buf_len)) { CAM_ERR(CAM_SENSOR, "Invalid Args: pwr_cmd %pK, cmd_length: %d", pwr_cmd, cmd_length); - return -EINVAL; + rc = -EINVAL; + goto free_power_command; } power_info->power_setting_size = 0; power_info->power_setting = kzalloc(sizeof(struct cam_sensor_power_setting) * MAX_POWER_CONFIG, GFP_KERNEL); - if (!power_info->power_setting) - return -ENOMEM; + if (!power_info->power_setting) { + rc = -ENOMEM; + goto free_power_command; + } power_info->power_down_setting_size = 0; power_info->power_down_setting = @@ -1350,7 +1357,8 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, kfree(power_info->power_setting); power_info->power_setting = NULL; power_info->power_setting_size = 0; - return -ENOMEM; + rc = -ENOMEM; + goto free_power_command; } while (tot_size < cmd_length) { @@ -1534,7 +1542,7 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, } } - return rc; + goto free_power_command; free_power_settings: kfree(power_info->power_down_setting); kfree(power_info->power_setting); @@ -1542,6 +1550,9 @@ free_power_settings: power_info->power_setting = NULL; power_info->power_down_setting_size = 0; power_info->power_setting_size = 0; +free_power_command: + kfree(pwr_cmd); + pwr_cmd = NULL; return rc; }