msm: camera: isp: Avoiding OOB in defer bufdone handling

Adds changes to dynamically allocate memory for defer bufdone
index array as per number of ports acquired instead of
hardcoded max resource value which could change target wise.

CRs-Fixed: 3788295
Change-Id: I5d5f43ac41e6abbac0b270eeaf97475b4e39a5d7
Signed-off-by: Yash Upadhyay <quic_yupadhya@quicinc.com>
This commit is contained in:
Yash Upadhyay
2024-04-29 15:36:52 +05:30
parent d32cda396b
commit 5736242bea
5 changed files with 50 additions and 26 deletions

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-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.
*/
#ifndef _CAM_HW_MGR_INTF_H_
@@ -175,6 +175,7 @@ struct cam_hw_acquire_stream_caps {
* if input splits into multiple paths,
* its updated per hardware
* @valid_acquired_hw: Valid num of acquired hardware
* @total_ports_acq Total ports acquired ipp+ppp+rdi
* @op_params: OP Params from hw_mgr to ctx
* @mini_dump_cb: Mini dump callback function
*
@@ -194,6 +195,7 @@ struct cam_hw_acquire_args {
uint32_t acquired_hw_id[CAM_MAX_ACQ_RES];
uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT];
uint32_t valid_acquired_hw;
uint32_t total_ports_acq;
struct cam_hw_acquire_stream_caps op_params;
cam_ctx_mini_dump_cb_func mini_dump_cb;
};

View File

@@ -6667,6 +6667,8 @@ static int __cam_isp_ctx_flush_dev_in_top_state(struct cam_context *ctx,
static void __cam_isp_ctx_free_mem_hw_entries(struct cam_context *ctx)
{
int i;
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *) ctx->ctx_priv;
if (ctx->out_map_entries) {
for (i = 0; i < CAM_ISP_CTX_REQ_MAX; i++) {
@@ -6698,6 +6700,13 @@ static void __cam_isp_ctx_free_mem_hw_entries(struct cam_context *ctx)
ctx->hw_update_entry = NULL;
}
if (ctx_isp) {
for (i = 0; i < CAM_ISP_CTX_REQ_MAX; i++) {
kfree(ctx_isp->req_isp[i].deferred_fence_map_index);
ctx_isp->req_isp[i].deferred_fence_map_index = NULL;
}
}
ctx->max_out_map_entries = 0;
ctx->max_in_map_entries = 0;
ctx->max_hw_update_entries = 0;
@@ -7090,6 +7099,8 @@ static int __cam_isp_ctx_allocate_mem_hw_entries(
struct cam_ctx_request *req;
struct cam_ctx_request *temp_req;
struct cam_isp_ctx_req *req_isp;
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *) ctx->ctx_priv;
if (!param->op_params.param_list[0])
max_res = CAM_ISP_CTX_RES_MAX;
@@ -7119,16 +7130,6 @@ static int __cam_isp_ctx_allocate_mem_hw_entries(
return -ENOMEM;
}
for (i = 0; i < CAM_ISP_CTX_REQ_MAX; i++) {
ctx->hw_update_entry[i] = kcalloc(ctx->max_hw_update_entries,
sizeof(struct cam_hw_update_entry), GFP_KERNEL);
if (!ctx->hw_update_entry[i]) {
CAM_ERR(CAM_CTXT, "%s[%u] no memory for hw_update_entry: %u, link: 0x%x",
ctx->dev_name, ctx->ctx_id, i, ctx->link_hdl);
return -ENOMEM;
}
}
ctx->in_map_entries = kcalloc(CAM_ISP_CTX_REQ_MAX, sizeof(struct cam_hw_fence_map_entry *),
GFP_KERNEL);
@@ -7139,19 +7140,6 @@ static int __cam_isp_ctx_allocate_mem_hw_entries(
goto end;
}
for (i = 0; i < CAM_ISP_CTX_REQ_MAX; i++) {
ctx->in_map_entries[i] = kcalloc(ctx->max_in_map_entries,
sizeof(struct cam_hw_fence_map_entry),
GFP_KERNEL);
if (!ctx->in_map_entries[i]) {
CAM_ERR(CAM_CTXT, "%s[%u] no memory for in_map_entries: %u, link: 0x%x",
ctx->dev_name, ctx->ctx_id, i, ctx->link_hdl);
rc = -ENOMEM;
goto end;
}
}
ctx->out_map_entries = kcalloc(CAM_ISP_CTX_REQ_MAX, sizeof(struct cam_hw_fence_map_entry *),
GFP_KERNEL);
@@ -7162,7 +7150,29 @@ static int __cam_isp_ctx_allocate_mem_hw_entries(
goto end;
}
for (i = 0; i < CAM_ISP_CTX_REQ_MAX; i++) {
ctx->hw_update_entry[i] = kcalloc(ctx->max_hw_update_entries,
sizeof(struct cam_hw_update_entry), GFP_KERNEL);
if (!ctx->hw_update_entry[i]) {
CAM_ERR(CAM_CTXT, "%s[%u] no memory for hw_update_entry: %u, link: 0x%x",
ctx->dev_name, ctx->ctx_id, i, ctx->link_hdl);
rc = -ENOMEM;
goto end;
}
ctx->in_map_entries[i] = kcalloc(ctx->max_in_map_entries,
sizeof(struct cam_hw_fence_map_entry),
GFP_KERNEL);
if (!ctx->in_map_entries[i]) {
CAM_ERR(CAM_CTXT, "%s[%u] no memory for in_map_entries: %u, link: 0x%x",
ctx->dev_name, ctx->ctx_id, i, ctx->link_hdl);
rc = -ENOMEM;
goto end;
}
ctx->out_map_entries[i] = kcalloc(ctx->max_out_map_entries,
sizeof(struct cam_hw_fence_map_entry),
GFP_KERNEL);
@@ -7173,6 +7183,16 @@ static int __cam_isp_ctx_allocate_mem_hw_entries(
rc = -ENOMEM;
goto end;
}
ctx_isp->req_isp[i].deferred_fence_map_index = kcalloc(param->total_ports_acq,
sizeof(uint32_t), GFP_KERNEL);
if (!ctx_isp->req_isp[i].deferred_fence_map_index) {
CAM_ERR(CAM_ISP, "%s[%d] no memory for defer fence map idx arr, ports:%u",
ctx->dev_name, ctx->ctx_id, param->total_ports_acq);
rc = -ENOMEM;
goto end;
}
}
list_for_each_entry_safe(req, temp_req,

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-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.
*/
#ifndef _CAM_ISP_CONTEXT_H_
@@ -196,7 +196,7 @@ struct cam_isp_ctx_req {
uint32_t num_fence_map_in;
uint32_t num_acked;
uint32_t num_deferred_acks;
uint32_t deferred_fence_map_index[CAM_ISP_CTX_RES_MAX];
uint32_t *deferred_fence_map_index;
int32_t bubble_report;
struct cam_isp_prepare_hw_update_data hw_update_data;
enum cam_hw_config_reapply_type reapply_type;

View File

@@ -5700,6 +5700,7 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
}
total_ports = total_pix_port + total_rdi_port + total_pd_port;
acquire_args->total_ports_acq = total_ports;
ife_ctx->res_list_ife_out = kcalloc(total_ports,
sizeof(struct cam_isp_hw_mgr_res), GFP_KERNEL);
if (!ife_ctx->res_list_ife_out) {

View File

@@ -2455,6 +2455,7 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
}
total_ports = total_pix_port + total_rdi_port + total_pd_port;
acquire_args->total_ports_acq = total_ports;
tfe_ctx->res_list_tfe_out = kcalloc(total_ports,
sizeof(struct cam_isp_hw_mgr_res), GFP_KERNEL);
if (!tfe_ctx->res_list_tfe_out) {