From f4a952f180d2a028d500ff7f61b6d96fe972e5d0 Mon Sep 17 00:00:00 2001 From: Depeng Shao Date: Sat, 22 May 2021 15:01:58 +0800 Subject: [PATCH 1/4] msm: camera: reqmgr: Reset the slot if it is applied This change reset the slot when the next req is applied, it should be caused by some exception before, we need to reset this slot in case we applied wrong req to sub devices. CRs-Fixed: 2949657 Change-Id: I0b5f7b1d8450ed355701090b185812fb7a6b6e06 Signed-off-by: Depeng Shao --- drivers/cam_req_mgr/cam_req_mgr_core.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index 9881516daf3d..5f6f3ae3e8b0 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -759,6 +759,24 @@ static int __cam_req_mgr_check_next_req_slot( CAM_DBG(CAM_CRM, "idx: %d: slot->status %d", idx, slot->status); + /* + * Some slot can't be reset due to irq congestion and + * performance issue, we need to reset it when we + * want to move to this slot. + */ + if (slot->status == CRM_SLOT_STATUS_REQ_APPLIED) { + CAM_WARN(CAM_CRM, + "slot[%d] wasn't reset, reset it now", + idx); + if (in_q->last_applied_idx == idx) { + CAM_WARN(CAM_CRM, + "last_applied_idx: %d", + in_q->last_applied_idx); + in_q->last_applied_idx = -1; + } + __cam_req_mgr_reset_req_slot(link, idx); + } + /* Check if there is new req from CSL, if not complete req */ if (slot->status == CRM_SLOT_STATUS_NO_REQ) { rc = __cam_req_mgr_check_for_lower_pd_devices(link); From 028478e7dff4fb6f1c73b3511a2594a24e63deec Mon Sep 17 00:00:00 2001 From: Kai Xing Date: Sat, 7 May 2022 15:48:00 +0530 Subject: [PATCH 2/4] msm: camera: fd: fix compile error for kernel 5.4 Function definition error: delete static keyword. CRs-Fixed: 3191744 Change-Id: Ifea089f47de02233b31695146b1ddacfbaec35a8 Signed-off-by: Kai Xing --- drivers/cam_fd/cam_fd_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cam_fd/cam_fd_dev.c b/drivers/cam_fd/cam_fd_dev.c index e34c9bcc1e0b..3797a1145846 100644 --- a/drivers/cam_fd/cam_fd_dev.c +++ b/drivers/cam_fd/cam_fd_dev.c @@ -62,7 +62,7 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, return 0; } -static int cam_fd_dev_close_internal(struct v4l2_subdev *sd, +int cam_fd_dev_close_internal(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct cam_fd_dev *fd_dev = &g_fd_dev; From cfb8c413c9bc1786ddf408cf655e4141dd771673 Mon Sep 17 00:00:00 2001 From: daopingl Date: Fri, 27 May 2022 17:58:36 +0800 Subject: [PATCH 3/4] msm: camera: utils: modify debug function logic there are only 8k stack in 32 bit system, this change used to make the temp variables be contorl by the parameters, which can decrase the stack resource cost under default debug settings and finally improve the stability of multi camera cases. CRs-fixed: 3193708 Change-Id: If0f33cc310d64c83c0e4781a5de61483ebc35769 Signed-off-by: daopingl --- drivers/cam_utils/cam_debug_util.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/cam_utils/cam_debug_util.c b/drivers/cam_utils/cam_debug_util.c index d4ea078119c9..5f1a3f7f4876 100644 --- a/drivers/cam_utils/cam_debug_util.c +++ b/drivers/cam_utils/cam_debug_util.c @@ -257,12 +257,11 @@ const char *cam_get_tag_name(unsigned int tag_id) void cam_debug_log(unsigned int module_id, const char *func, const int line, const char *fmt, ...) { - char str_buffer[STR_BUFFER_MAX_LENGTH]; - va_list args; - - va_start(args, fmt); - if (debug_mdl & module_id) { + char str_buffer[STR_BUFFER_MAX_LENGTH]; + va_list args; + + va_start(args, fmt); vsnprintf(str_buffer, STR_BUFFER_MAX_LENGTH, fmt, args); if ((debug_type == 0) || (debug_type == 2)) { @@ -281,9 +280,9 @@ void cam_debug_log(unsigned int module_id, const char *func, const int line, func, line, str_buffer); trace_cam_log_debug(trace_buffer); } - } - va_end(args); + va_end(args); + } } void cam_debug_trace(unsigned int tag, unsigned int module_id, From 336163ddec3594386364bbff62ffcdaf1d9462ff Mon Sep 17 00:00:00 2001 From: Yash Upadhyay Date: Wed, 6 Apr 2022 09:28:19 +0530 Subject: [PATCH 4/4] msm: camera: memmgr: Avoid TOCTOU buffer access on multiple use of same fd Fd is a user-accessible value, referring it multiple times leads to TOCTOU issues. Dma_buf can be freed after the 1st use of fd and userspace can create another dma_buf but with same fd. In such scenario, during 2nd use of fd, we may get a different dma_buf with different length. To avoid this, we can use same dma_buf instead of retrieving it twice using same fd. In this change FD is accessed only once in syscall. CRs-Fixed: 3159446 Change-Id: I00eb6dd3d798165f5c6c0bd59feabe80a68592b1 Signed-off-by: Yash Upadhyay --- drivers/cam_req_mgr/cam_mem_mgr.c | 15 ++++++------ drivers/cam_smmu/cam_smmu_api.c | 39 ++++++++----------------------- drivers/cam_smmu/cam_smmu_api.h | 4 ++-- 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index ee227f943272..369f6639638f 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/cam_req_mgr/cam_mem_mgr.c @@ -577,7 +577,7 @@ static int cam_mem_util_check_map_flags(struct cam_mem_mgr_map_cmd *cmd) static int cam_mem_util_map_hw_va(uint32_t flags, int32_t *mmu_hdls, int32_t num_hdls, - int fd, + int fd, struct dma_buf *dmabuf, dma_addr_t *hw_vaddr, size_t *len, enum cam_smmu_region_id region, @@ -606,7 +606,8 @@ static int cam_mem_util_map_hw_va(uint32_t flags, fd, dir, hw_vaddr, - len); + len, + dmabuf); if (rc < 0) { CAM_ERR(CAM_MEM, @@ -624,7 +625,8 @@ static int cam_mem_util_map_hw_va(uint32_t flags, (dma_addr_t *)hw_vaddr, len, region, - is_internal); + is_internal, + dmabuf); if (rc < 0) { CAM_ERR(CAM_MEM, @@ -716,6 +718,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) cmd->mmu_hdls, cmd->num_hdl, fd, + dmabuf, &hw_vaddr, &len, region, @@ -856,6 +859,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) cmd->mmu_hdls, cmd->num_hdl, cmd->fd, + dmabuf, &hw_vaddr, &len, CAM_SMMU_REGION_IO, @@ -1109,8 +1113,6 @@ static int cam_mem_util_unmap(int32_t idx, if (cam_mem_util_unmap_hw_va(idx, region, client)) CAM_ERR(CAM_MEM, "Failed, dmabuf=%pK", tbl.bufq[idx].dma_buf); - if (client == CAM_SMMU_MAPPING_KERNEL) - tbl.bufq[idx].dma_buf = NULL; } mutex_lock(&tbl.m_lock); @@ -1126,8 +1128,7 @@ static int cam_mem_util_unmap(int32_t idx, tbl.bufq[idx].is_imported, tbl.bufq[idx].dma_buf); - if (tbl.bufq[idx].dma_buf) - dma_buf_put(tbl.bufq[idx].dma_buf); + dma_buf_put(tbl.bufq[idx].dma_buf); tbl.bufq[idx].fd = -1; tbl.bufq[idx].dma_buf = NULL; diff --git a/drivers/cam_smmu/cam_smmu_api.c b/drivers/cam_smmu/cam_smmu_api.c index 0083d8674d65..de9433ff59f6 100644 --- a/drivers/cam_smmu/cam_smmu_api.c +++ b/drivers/cam_smmu/cam_smmu_api.c @@ -262,7 +262,7 @@ static struct cam_dma_buff_info *cam_smmu_find_mapping_by_virt_address(int idx, static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, bool dis_delayed_unmap, enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, size_t *len_ptr, - enum cam_smmu_region_id region_id, bool is_internal); + enum cam_smmu_region_id region_id, bool is_internal, struct dma_buf *dmabuf); static int cam_smmu_map_kernel_buffer_and_add_to_list(int idx, struct dma_buf *buf, enum dma_data_direction dma_dir, @@ -2028,7 +2028,7 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf, if (IS_ERR_OR_NULL(attach)) { rc = PTR_ERR(attach); CAM_ERR(CAM_SMMU, "Error: dma buf attach failed"); - goto err_put; + goto err_out; } if (region_id == CAM_SMMU_REGION_SHARED) { @@ -2175,8 +2175,6 @@ err_unmap_sg: dma_buf_unmap_attachment(attach, table, dma_dir); err_detach: dma_buf_detach(buf, attach); -err_put: - dma_buf_put(buf); err_out: return rc; } @@ -2185,14 +2183,10 @@ err_out: static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, bool dis_delayed_unmap, enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, size_t *len_ptr, - enum cam_smmu_region_id region_id, bool is_internal) + enum cam_smmu_region_id region_id, bool is_internal, struct dma_buf *buf) { int rc = -1; struct cam_dma_buff_info *mapping_info = NULL; - struct dma_buf *buf = NULL; - - /* returns the dma_buf structure related to an fd */ - buf = dma_buf_get(ion_fd); rc = cam_smmu_map_buffer_validate(buf, idx, dma_dir, paddr_ptr, len_ptr, region_id, dis_delayed_unmap, &mapping_info); @@ -2316,7 +2310,6 @@ static int cam_smmu_unmap_buf_and_remove_from_list( dma_buf_detach(mapping_info->buf, mapping_info->attach); - dma_buf_put(mapping_info->buf); if (iommu_cb_set.map_profile_enable) { CAM_GET_TIMESTAMP(ts2); @@ -2817,10 +2810,9 @@ handle_err: static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd, enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, - size_t *len_ptr) + size_t *len_ptr, struct dma_buf *dmabuf) { int rc = 0; - struct dma_buf *dmabuf = NULL; struct dma_buf_attachment *attach = NULL; struct sg_table *table = NULL; struct cam_sec_buff_info *mapping_info; @@ -2829,15 +2821,6 @@ static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd, *paddr_ptr = (dma_addr_t)NULL; *len_ptr = (size_t)0; - dmabuf = dma_buf_get(ion_fd); - if (IS_ERR_OR_NULL((void *)(dmabuf))) { - CAM_ERR(CAM_SMMU, - "Error: dma buf get failed, idx=%d, ion_fd=%d", - idx, ion_fd); - rc = PTR_ERR(dmabuf); - goto err_out; - } - /* * ion_phys() is deprecated. call dma_buf_attach() and * dma_buf_map_attachment() to get the buffer's physical @@ -2849,7 +2832,7 @@ static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd, "Error: dma buf attach failed, idx=%d, ion_fd=%d", idx, ion_fd); rc = PTR_ERR(attach); - goto err_put; + goto err_out; } attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; @@ -2895,15 +2878,14 @@ err_unmap_sg: dma_buf_unmap_attachment(attach, table, dma_dir); err_detach: dma_buf_detach(dmabuf, attach); -err_put: - dma_buf_put(dmabuf); err_out: return rc; } int cam_smmu_map_stage2_iova(int handle, int ion_fd, enum cam_smmu_map_dir dir, - dma_addr_t *paddr_ptr, size_t *len_ptr) + dma_addr_t *paddr_ptr, size_t *len_ptr, + struct dma_buf *dmabuf) { int idx, rc; enum dma_data_direction dma_dir; @@ -2962,7 +2944,7 @@ int cam_smmu_map_stage2_iova(int handle, goto get_addr_end; } rc = cam_smmu_map_stage2_buffer_and_add_to_list(idx, ion_fd, dma_dir, - paddr_ptr, len_ptr); + paddr_ptr, len_ptr, dmabuf); if (rc < 0) { CAM_ERR(CAM_SMMU, "Error: mapping or add list fail, idx=%d, handle=%d, fd=%d, rc=%d", @@ -2998,7 +2980,6 @@ static int cam_smmu_secure_unmap_buf_and_remove_from_list( dma_buf_unmap_attachment(mapping_info->attach, mapping_info->table, mapping_info->dir); dma_buf_detach(mapping_info->buf, mapping_info->attach); - dma_buf_put(mapping_info->buf); mapping_info->buf = NULL; list_del_init(&mapping_info->list); @@ -3116,7 +3097,7 @@ static int cam_smmu_map_iova_validate_params(int handle, int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, enum cam_smmu_map_dir dir, dma_addr_t *paddr_ptr, size_t *len_ptr, enum cam_smmu_region_id region_id, - bool is_internal) + bool is_internal, struct dma_buf *dmabuf) { int idx, rc = 0; struct timespec64 *ts = NULL; @@ -3180,7 +3161,7 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, rc = cam_smmu_map_buffer_and_add_to_list(idx, ion_fd, dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, - region_id, is_internal); + region_id, is_internal, dmabuf); if (rc < 0) { CAM_ERR(CAM_SMMU, "mapping or add list fail cb:%s idx=%d, fd=%d, region=%d, rc=%d", diff --git a/drivers/cam_smmu/cam_smmu_api.h b/drivers/cam_smmu/cam_smmu_api.h index 81c0170a8eb8..2db6945c54c6 100644 --- a/drivers/cam_smmu/cam_smmu_api.h +++ b/drivers/cam_smmu/cam_smmu_api.h @@ -128,7 +128,7 @@ int cam_smmu_ops(int handle, enum cam_smmu_ops_param op); */ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, enum cam_smmu_map_dir dir, dma_addr_t *dma_addr, size_t *len_ptr, - enum cam_smmu_region_id region_id, bool is_internal); + enum cam_smmu_region_id region_id, bool is_internal, struct dma_buf *dmabuf); /** * @brief : Maps kernel space IOVA for calling driver @@ -304,7 +304,7 @@ int cam_smmu_put_iova(int handle, int ion_fd); */ int cam_smmu_map_stage2_iova(int handle, int ion_fd, enum cam_smmu_map_dir dir, dma_addr_t *dma_addr, - size_t *len_ptr); + size_t *len_ptr, struct dma_buf *dmabuf); /** * @brief Unmaps secure memopry for SMMU handle