Forráskód Böngészése

Merge 6ddbe8dd37b748357a6b74fb4e6c549f3c4d1bb0 on remote branch

Change-Id: Ia63d563807055565dbc7177973ed95c9687379be
Linux Build Service Account 8 hónapja
szülő
commit
3e345ff86c
2 módosított fájl, 106 hozzáadás és 66 törlés
  1. 33 1
      drivers/cam_core/cam_context.h
  2. 73 65
      drivers/cam_core/cam_context_utils.c

+ 33 - 1
drivers/cam_core/cam_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_CONTEXT_H_
@@ -276,6 +276,38 @@ struct cam_context {
 	struct timespec64              cdm_done_ts;
 };
 
+/**
+ * struct cam_context_stream_dump - camera context stream information
+ *
+ * @hw_mgr_ctx_id:         Hw Mgr context id returned from hw mgr
+ * @dev_id:                ID of device associated
+ * @dev_hdl:               Device handle
+ * @link_hdl:              Link handle
+ * @sessoin_hdl:           Session handle
+ * @refcount:              Context object refcount
+ * @last_flush_req:        Last request to flush
+ * @state:                 Current state for top level state machine
+ */
+struct cam_context_stream_dump {
+	uint32_t                       hw_mgr_ctx_id;
+	uint32_t                       dev_id;
+	uint32_t                       dev_hdl;
+	uint32_t                       link_hdl;
+	uint32_t                       session_hdl;
+	uint32_t                       refcount;
+	uint32_t                       last_flush_req;
+	enum cam_context_state         state;
+};
+
+/**
+ * struct cam_context_each_req_info - camera each request information
+ *
+ * @request_id:         request id
+ */
+struct cam_context_each_req_info {
+	uint64_t              request_id;
+};
+
 /**
  * struct cam_context_dump_header -  Function for context dump header
  *

+ 73 - 65
drivers/cam_core/cam_context_utils.c

@@ -1487,6 +1487,40 @@ end:
 	return rc;
 }
 
+static int cam_context_dump_data_validaion(void *src, void *dest,
+		uint32_t base_len, uint32_t actual_len, uint32_t bytes_required)
+{
+	if (base_len + bytes_required >= actual_len) {
+		CAM_ERR(CAM_CTXT, "actual len %pK base len %pK",
+			actual_len, base_len);
+		return -ENOSPC;
+	}
+	memcpy(dest, src, bytes_required);
+	return 0;
+}
+
+static int cam_context_stream_dump_validation(struct cam_context *ctx,
+	uint64_t *addr, uint32_t local_len, uint32_t buf_len)
+{
+	struct cam_context_stream_dump   stream_dump;
+
+	stream_dump.hw_mgr_ctx_id =  ctx->hw_mgr_ctx_id;
+	stream_dump.dev_id =         ctx->dev_id;
+	stream_dump.dev_hdl =        ctx->dev_hdl;
+	stream_dump.link_hdl =       ctx->link_hdl;
+	stream_dump.session_hdl =    ctx->session_hdl;
+	stream_dump.refcount    =    refcount_read(&(ctx->refcount.refcount));
+	stream_dump.last_flush_req = ctx->last_flush_req;
+	stream_dump.state =          ctx->state;
+	if (cam_context_dump_data_validaion(&stream_dump, addr,
+		local_len, buf_len,
+		sizeof(struct cam_context_stream_dump))) {
+		CAM_WARN(CAM_CTXT, "failed to copy the stream info");
+		return -ENOSPC;
+	}
+	return 0;
+}
+
 static int cam_context_user_dump(struct cam_context *ctx,
 	struct cam_hw_dump_args *dump_args)
 {
@@ -1498,6 +1532,7 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	uint32_t                         min_len;
 	size_t                           buf_len, remain_len;
 	uintptr_t                        cpu_addr;
+	uint32_t                         local_len;
 
 	if (!ctx || !dump_args) {
 		CAM_ERR(CAM_CORE, "Invalid parameters %pK %pK",
@@ -1555,73 +1590,19 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	/* Dump context info */
 	dst = (uint8_t *)cpu_addr + dump_args->offset;
 	hdr = (struct cam_context_dump_header *)dst;
+	local_len =
+		(dump_args->offset + sizeof(struct cam_context_dump_header));
 	scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
 		"%s_CTX_INFO:", ctx->dev_name);
 	hdr->word_size = sizeof(uint64_t);
 	addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
 	start = addr;
-	*addr++ = ctx->hw_mgr_ctx_id;
-	*addr++ = ctx->dev_id;
-	*addr++ = ctx->dev_hdl;
-	*addr++ = ctx->link_hdl;
-	*addr++ = ctx->session_hdl;
-	*addr++ = refcount_read(&(ctx->refcount.refcount));
-	*addr++ = ctx->last_flush_req;
-	*addr++ = ctx->state;
-	hdr->size = hdr->word_size * (addr - start);
-	dump_args->offset += hdr->size +
-		sizeof(struct cam_context_dump_header);
-
-	/* Dump pending request IDs */
-	dst = (uint8_t *)cpu_addr + dump_args->offset;
-	hdr = (struct cam_context_dump_header *)dst;
-	scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
-		"%s_OUT_FENCE_PENDING_REQUESTS:", ctx->dev_name);
-	hdr->word_size = sizeof(uint64_t);
-	addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
-	start = addr;
-	if (!list_empty(&ctx->pending_req_list)) {
-		list_for_each_entry_safe(req, req_temp, &ctx->pending_req_list, list) {
-			*addr++ = req->request_id;
-		}
-	}
-
-	hdr->size = hdr->word_size * (addr - start);
-	dump_args->offset += hdr->size +
-		sizeof(struct cam_context_dump_header);
-
-	/* Dump wait request IDs */
-	dst = (uint8_t *)cpu_addr + dump_args->offset;
-	hdr = (struct cam_context_dump_header *)dst;
-	scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
-		"%s_OUT_FENCE_APPLIED_REQUESTS:", ctx->dev_name);
-	hdr->word_size = sizeof(uint64_t);
-	addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
-	start = addr;
-	if (!list_empty(&ctx->wait_req_list)) {
-		list_for_each_entry_safe(req, req_temp, &ctx->wait_req_list, list) {
-			*addr++ = req->request_id;
-		}
-	}
-
-	hdr->size = hdr->word_size * (addr - start);
-	dump_args->offset += hdr->size +
-		sizeof(struct cam_context_dump_header);
-
-	/* Dump active request IDs */
-	dst = (uint8_t *)cpu_addr + dump_args->offset;
-	hdr = (struct cam_context_dump_header *)dst;
-	scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
-		"%s_OUT_FENCE_ACTIVE_REQUESTS:", ctx->dev_name);
-	hdr->word_size = sizeof(uint64_t);
-	addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
-	start = addr;
-	if (!list_empty(&ctx->active_req_list)) {
-		list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) {
-			*addr++ = req->request_id;
-		}
+	if (cam_context_stream_dump_validation(ctx, addr, local_len, buf_len)) {
+		CAM_WARN(CAM_CTXT, "%s_CTX_INFO failed to copy the stream info ", ctx->dev_name);
+		cam_mem_put_cpu_buf(dump_args->buf_handle);
+		return -ENOSPC;
 	}
-
+	addr = addr + sizeof(struct cam_context_stream_dump);
 	hdr->size = hdr->word_size * (addr - start);
 	dump_args->offset += hdr->size +
 		sizeof(struct cam_context_dump_header);
@@ -1632,6 +1613,8 @@ static int cam_context_user_dump(struct cam_context *ctx,
 			for (i = 0; i < req->num_out_map_entries; i++) {
 				dst = (uint8_t *)cpu_addr + dump_args->offset;
 				hdr = (struct cam_context_dump_header *)dst;
+				local_len = dump_args->offset +
+					sizeof(struct cam_context_dump_header);
 				scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
 					"%s_OUT_FENCE_REQUEST_APPLIED.%d.%d.%d:",
 					ctx->dev_name,
@@ -1641,7 +1624,14 @@ static int cam_context_user_dump(struct cam_context *ctx,
 				hdr->word_size = sizeof(uint64_t);
 				addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
 				start = addr;
-				*addr++ = req->request_id;
+				if (cam_context_dump_data_validaion(&req->request_id, addr,
+					local_len, buf_len,
+					sizeof(struct cam_context_each_req_info))) {
+					CAM_WARN(CAM_CTXT, "%s_CTX_INFO waiting_req: failed to copy the request info",
+						ctx->dev_name);
+					goto cleanup;
+				}
+				addr = addr + sizeof(struct cam_context_each_req_info);
 				hdr->size = hdr->word_size * (addr - start);
 				dump_args->offset += hdr->size +
 					sizeof(struct cam_context_dump_header);
@@ -1655,6 +1645,8 @@ static int cam_context_user_dump(struct cam_context *ctx,
 			for (i = 0; i < req->num_out_map_entries; i++) {
 				dst = (uint8_t *)cpu_addr + dump_args->offset;
 				hdr = (struct cam_context_dump_header *)dst;
+				local_len = dump_args->offset +
+					sizeof(struct cam_context_dump_header);
 				scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
 					"%s_OUT_FENCE_REQUEST_PENDING.%d.%d.%d:",
 					ctx->dev_name,
@@ -1664,7 +1656,14 @@ static int cam_context_user_dump(struct cam_context *ctx,
 				hdr->word_size = sizeof(uint64_t);
 				addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
 				start = addr;
-				*addr++ = req->request_id;
+				if (cam_context_dump_data_validaion(&req->request_id, addr,
+					local_len, buf_len,
+					sizeof(struct cam_context_each_req_info))) {
+					CAM_WARN(CAM_CTXT, "%s_CTX_INFO pending_req: failed to copy the request info",
+						ctx->dev_name);
+					goto cleanup;
+				}
+				addr = addr + sizeof(struct cam_context_each_req_info);
 				hdr->size = hdr->word_size * (addr - start);
 				dump_args->offset += hdr->size +
 					sizeof(struct cam_context_dump_header);
@@ -1678,6 +1677,8 @@ static int cam_context_user_dump(struct cam_context *ctx,
 			for (i = 0; i < req->num_out_map_entries; i++) {
 				dst = (uint8_t *)cpu_addr + dump_args->offset;
 				hdr = (struct cam_context_dump_header *)dst;
+				local_len = dump_args->offset +
+					sizeof(struct cam_context_dump_header);
 				scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
 					"%s_OUT_FENCE_REQUEST_ACTIVE.%d.%d.%d:",
 					ctx->dev_name,
@@ -1687,14 +1688,21 @@ static int cam_context_user_dump(struct cam_context *ctx,
 				hdr->word_size = sizeof(uint64_t);
 				addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
 				start = addr;
-				*addr++ = req->request_id;
+				if (cam_context_dump_data_validaion(&req->request_id, addr,
+					local_len, buf_len,
+					sizeof(struct cam_context_each_req_info))) {
+					CAM_WARN(CAM_CTXT, "%s_CTX_INFO active_req: failed to copy the request info",
+						ctx->dev_name);
+					goto cleanup;
+				}
+				addr = addr + sizeof(struct cam_context_each_req_info);
 				hdr->size = hdr->word_size * (addr - start);
 				dump_args->offset += hdr->size +
 					sizeof(struct cam_context_dump_header);
 			}
 		}
 	}
-
+cleanup:
 	cam_mem_put_cpu_buf(dump_args->buf_handle);
 	return 0;
 }