Bläddra i källkod

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 <[email protected]>
Yash Upadhyay 1 år sedan
förälder
incheckning
5736242bea

+ 3 - 1
drivers/cam_core/cam_hw_mgr_intf.h

@@ -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;
 };

+ 42 - 22
drivers/cam_isp/cam_isp_context.c

@@ -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,7 +7140,28 @@ static int __cam_isp_ctx_allocate_mem_hw_entries(
 		goto end;
 	}
 
+	ctx->out_map_entries = kcalloc(CAM_ISP_CTX_REQ_MAX, sizeof(struct cam_hw_fence_map_entry *),
+			GFP_KERNEL);
+
+	if (!ctx->out_map_entries) {
+		CAM_ERR(CAM_CTXT, "%s[%u] no memory for out_map_entries, link: 0x%x",
+			ctx->dev_name, ctx->ctx_id, ctx->link_hdl);
+		rc = -ENOMEM;
+		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);
@@ -7150,19 +7172,7 @@ static int __cam_isp_ctx_allocate_mem_hw_entries(
 			rc = -ENOMEM;
 			goto end;
 		}
-	}
-
-	ctx->out_map_entries = kcalloc(CAM_ISP_CTX_REQ_MAX, sizeof(struct cam_hw_fence_map_entry *),
-			GFP_KERNEL);
 
-	if (!ctx->out_map_entries) {
-		CAM_ERR(CAM_CTXT, "%s[%u] no memory for out_map_entries, link: 0x%x",
-			ctx->dev_name, ctx->ctx_id, ctx->link_hdl);
-		rc = -ENOMEM;
-		goto end;
-	}
-
-	for (i = 0; i < CAM_ISP_CTX_REQ_MAX; i++) {
 		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,

+ 2 - 2
drivers/cam_isp/cam_isp_context.h

@@ -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;

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -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) {

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -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) {