From 0204c76b587b09a3f2906c62d50e7179c3d18872 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Mon, 21 Dec 2020 22:17:26 +0530 Subject: [PATCH] msm: camera: jpeg: Add more data in case of smmu pf When we have smmu page fault of unmapped address and active flag is false we can cache and store unmapped address and print in case of error. Added check for last flushed req during config hw for jpeg as well. CRs-Fixed: 2834236 Change-Id: I9b9bb735587799871f9bdef94985f6269ca6a29d Signed-off-by: Vikram Sharma --- drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c | 9 ++++++ drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h | 2 ++ drivers/cam_req_mgr/cam_mem_mgr.c | 16 ++++++++--- drivers/cam_req_mgr/cam_mem_mgr.h | 32 ++++++++++++---------- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 737a681dfcb3..fc1d8c507af2 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -643,6 +643,14 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) p_cfg_req->dev_type = ctx_data->jpeg_dev_acquire_info.dev_type; request_id = (uintptr_t)config_args->priv; + if (request_id <= ctx_data->last_flush_req) { + CAM_WARN(CAM_JPEG, + "Anomaly submitting flushed req %llu [last_flush %llu] in ctx %u", + request_id, ctx_data->last_flush_req); + mutex_unlock(&hw_mgr->hw_mgr_mutex); + return -EINVAL; + } + p_cfg_req->req_id = request_id; p_cfg_req->num_hw_entry_processed = 0; hw_update_entries = config_args->hw_update_entries; @@ -1085,6 +1093,7 @@ static int cam_jpeg_mgr_hw_flush(void *hw_mgr_priv, void *flush_hw_args) return -EINVAL; } + ctx_data->last_flush_req = flush_args->last_flush_req; switch (flush_args->flush_type) { case CAM_FLUSH_TYPE_ALL: rc = cam_jpeg_mgr_flush(hw_mgr_priv, ctx_data); diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h index 9de5f2950d3a..6af8e9e0df35 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h @@ -98,6 +98,7 @@ struct cam_jpeg_hw_cfg_req { * @in_use: Flag for context usage * @wait_complete: Completion info * @cdm_cmd: Cdm cmd submitted for that context. + * @last_flush_req: req id which was flushed last. */ struct cam_jpeg_hw_ctx_data { void *context_priv; @@ -107,6 +108,7 @@ struct cam_jpeg_hw_ctx_data { bool in_use; struct completion wait_complete; struct cam_cdm_bl_request *cdm_cmd; + uint64_t last_flush_req; }; /** diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index a8db5ef8b744..900d7537966f 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/cam_req_mgr/cam_mem_mgr.c @@ -244,8 +244,9 @@ int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle, return -ENOENT; if (!tbl.bufq[idx].active) { - CAM_ERR(CAM_MEM, "Buffer at idx=%d is already unmapped,", - idx); + CAM_ERR(CAM_MEM, + "Buffer at idx=%d is already unmapped, vaddr 0x%x unmaped_vaddr 0x%x", + idx, tbl.bufq[idx].vaddr, tbl.bufq[idx].unmaped_vaddr); return -EAGAIN; } @@ -757,6 +758,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) tbl.bufq[idx].kmdvaddr = kvaddr; tbl.bufq[idx].vaddr = hw_vaddr; + tbl.bufq[idx].unmaped_vaddr = 0; tbl.bufq[idx].dma_buf = dmabuf; tbl.bufq[idx].len = cmd->len; tbl.bufq[idx].num_hdl = cmd->num_hdl; @@ -883,10 +885,12 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) CAM_MEM_MGR_SET_SECURE_HDL(tbl.bufq[idx].buf_handle, true); tbl.bufq[idx].kmdvaddr = 0; - if (cmd->num_hdl > 0) + if (cmd->num_hdl > 0) { tbl.bufq[idx].vaddr = hw_vaddr; - else + tbl.bufq[idx].unmaped_vaddr = 0; + } else { tbl.bufq[idx].vaddr = 0; + } tbl.bufq[idx].dma_buf = dmabuf; tbl.bufq[idx].len = len; @@ -1020,6 +1024,7 @@ static int cam_mem_mgr_cleanup_table(void) tbl.bufq[i].flags = 0; tbl.bufq[i].buf_handle = -1; tbl.bufq[i].vaddr = 0; + tbl.bufq[i].unmaped_vaddr = 0; tbl.bufq[i].len = 0; memset(tbl.bufq[i].hdls, 0, sizeof(int32_t) * tbl.bufq[i].num_hdl); @@ -1078,6 +1083,7 @@ static int cam_mem_util_unmap(int32_t idx, /* Deactivate the buffer queue to prevent multiple unmap */ mutex_lock(&tbl.bufq[idx].q_lock); tbl.bufq[idx].active = false; + tbl.bufq[idx].unmaped_vaddr = tbl.bufq[idx].vaddr; tbl.bufq[idx].vaddr = 0; mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.m_lock); @@ -1294,6 +1300,7 @@ int cam_mem_mgr_request_mem(struct cam_mem_mgr_request_desc *inp, tbl.bufq[idx].kmdvaddr = kvaddr; tbl.bufq[idx].vaddr = iova; + tbl.bufq[idx].unmaped_vaddr = 0; tbl.bufq[idx].len = inp->size; tbl.bufq[idx].num_hdl = num_hdl; @@ -1443,6 +1450,7 @@ int cam_mem_mgr_reserve_memory_region(struct cam_mem_mgr_request_desc *inp, tbl.bufq[idx].kmdvaddr = 0; tbl.bufq[idx].vaddr = iova; + tbl.bufq[idx].unmaped_vaddr = 0; tbl.bufq[idx].len = request_len; tbl.bufq[idx].num_hdl = num_hdl; diff --git a/drivers/cam_req_mgr/cam_mem_mgr.h b/drivers/cam_req_mgr/cam_mem_mgr.h index b4310db58d2b..c9931fc4f06b 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.h +++ b/drivers/cam_req_mgr/cam_mem_mgr.h @@ -26,21 +26,22 @@ enum cam_smmu_mapping_client { /** * struct cam_mem_buf_queue * - * @dma_buf: pointer to the allocated dma_buf in the table - * @q_lock: mutex lock for buffer - * @hdls: list of mapped handles - * @num_hdl: number of handles - * @fd: file descriptor of buffer - * @buf_handle: unique handle for buffer - * @align: alignment for allocation - * @len: size of buffer - * @flags: attributes of buffer - * @vaddr: IOVA of buffer - * @kmdvaddr: Kernel virtual address - * @active: state of the buffer - * @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 + * @dma_buf: pointer to the allocated dma_buf in the table + * @q_lock: mutex lock for buffer + * @hdls: list of mapped handles + * @num_hdl: number of handles + * @fd: file descriptor of buffer + * @buf_handle: unique handle for buffer + * @align: alignment for allocation + * @len: size of buffer + * @flags: attributes of buffer + * @vaddr: IOVA of buffer + * @kmdvaddr: Kernel virtual address + * @active: state of the buffer + * @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 + * @unmaped_vaddr: This will cache the vaddr if it is unmapped. */ struct cam_mem_buf_queue { struct dma_buf *dma_buf; @@ -53,6 +54,7 @@ struct cam_mem_buf_queue { size_t len; uint32_t flags; uint64_t vaddr; + uint64_t unmaped_vaddr; uintptr_t kmdvaddr; bool active; bool is_imported;