Merge "msm: camera: cre: Fix null pointer dereference in CRE driver" into camera-kernel.lnx.7.0
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
477f423ee1
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#include <linux/mutex.h>
|
||||
@@ -760,38 +760,38 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
|
||||
task_data = (struct cre_cmd_work_data *)data;
|
||||
|
||||
mutex_lock(&hw_mgr->hw_mgr_mutex);
|
||||
mutex_lock(&ctx_data->ctx_mutex);
|
||||
|
||||
if (ctx_data->ctx_state != CRE_CTX_STATE_ACQUIRED) {
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
CAM_ERR(CAM_CRE, "ctx id :%u is not in use",
|
||||
ctx_data->ctx_id);
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (task_data->req_idx >= CAM_CTX_REQ_MAX) {
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
CAM_ERR(CAM_CRE, "Invalid reqIdx = %llu",
|
||||
task_data->req_idx);
|
||||
return -EINVAL;
|
||||
task_data->req_idx);
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (task_data->request_id <= ctx_data->last_flush_req) {
|
||||
CAM_WARN(CAM_CRE,
|
||||
"request %lld has been flushed, reject packet", task_data->request_id);
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
cre_req = ctx_data->req_list[task_data->req_idx];
|
||||
if (cre_req->request_id > ctx_data->last_flush_req)
|
||||
ctx_data->last_flush_req = 0;
|
||||
|
||||
if (cre_req->request_id <= ctx_data->last_flush_req) {
|
||||
CAM_WARN(CAM_CRE,
|
||||
"request %lld has been flushed, reject packet",
|
||||
cre_req->request_id, ctx_data->last_flush_req);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!cam_cre_is_pending_request(ctx_data)) {
|
||||
CAM_WARN(CAM_CRE, "no pending req, req %lld last flush %lld",
|
||||
cre_req->request_id, ctx_data->last_flush_req);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
hw_mgr = task_data->data;
|
||||
num_batch = cre_req->num_batch;
|
||||
@@ -815,7 +815,8 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
|
||||
cam_cre_device_timer_reset(cre_hw_mgr);
|
||||
CAM_ERR(CAM_CRE,
|
||||
"Timedout waiting for bufdone on last frame");
|
||||
return -ETIMEDOUT;
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
} else {
|
||||
reinit_completion(&ctx_data->cre_top->bufdone);
|
||||
CAM_INFO(CAM_CRE,
|
||||
@@ -827,6 +828,8 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
|
||||
cam_cre_mgr_update_reg_set(hw_mgr, cre_req, i);
|
||||
cam_cre_ctx_wait_for_idle_irq(ctx_data);
|
||||
}
|
||||
err:
|
||||
mutex_unlock(&ctx_data->ctx_mutex);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
|
||||
return rc;
|
||||
@@ -857,16 +860,16 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
|
||||
cfg_req = list_first_entry(&hw_mgr->hw_config_req_list,
|
||||
struct cam_cre_hw_cfg_req, list);
|
||||
if (!cfg_req) {
|
||||
CAM_ERR(CAM_JPEG, "no request");
|
||||
CAM_ERR(CAM_CRE, "Hw config req list empty");
|
||||
rc = -EFAULT;
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
return rc;
|
||||
}
|
||||
list_del_init(&cfg_req->list);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
|
||||
if (cfg_req->ctx_id < 0) {
|
||||
CAM_ERR(CAM_CRE, "No valid context to handle error");
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -877,18 +880,25 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
|
||||
if (ctx->ctx_state != CRE_CTX_STATE_ACQUIRED) {
|
||||
CAM_DBG(CAM_CRE, "ctx id: %d not in right state: %d",
|
||||
cfg_req->ctx_id, ctx->ctx_state);
|
||||
mutex_unlock(&ctx->ctx_mutex);
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
active_req_idx = find_next_bit(ctx->bitmap, ctx->bits, ctx->last_done_req_idx);
|
||||
CAM_DBG(CAM_CRE, "Ctx %d active_req_idx %d last_done_req_idx %d", ctx->ctx_id,
|
||||
active_req_idx, ctx->last_done_req_idx);
|
||||
|
||||
if (active_req_idx >= CAM_CTX_REQ_MAX) {
|
||||
CAM_WARN(CAM_CRE, "ctx %d not valid req idx active_req_idx %d", active_req_idx);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
active_req = ctx->req_list[active_req_idx];
|
||||
if (!active_req) {
|
||||
CAM_ERR(CAM_CRE, "Active req cannot be null");
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (irq_data.error) {
|
||||
@@ -924,8 +934,10 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
|
||||
ctx->req_list[active_req_idx] = NULL;
|
||||
}
|
||||
}
|
||||
end:
|
||||
list_add_tail(&cfg_req->list, &hw_mgr->free_req_list);
|
||||
mutex_unlock(&ctx->ctx_mutex);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2344,6 +2356,7 @@ static int cam_cre_mgr_enqueue_config(struct cam_cre_hw_mgr *hw_mgr,
|
||||
task_data = (struct cre_cmd_work_data *)task->payload;
|
||||
task_data->data = (void *)hw_mgr;
|
||||
task_data->req_idx = cre_req->req_idx;
|
||||
task_data->request_id = cre_req->request_id;
|
||||
task_data->type = CRE_WORKQ_TASK_CMD_TYPE;
|
||||
task->process_cb = cam_cre_mgr_process_cmd;
|
||||
|
||||
@@ -2366,7 +2379,6 @@ static int cam_cre_mgr_config_hw(void *hw_priv, void *hw_config_args)
|
||||
struct cam_cre_request *cre_req = NULL;
|
||||
struct cam_cre_hw_cfg_req *cfg_req = NULL;
|
||||
|
||||
CAM_DBG(CAM_CRE, "E");
|
||||
if (!hw_mgr || !config_args) {
|
||||
CAM_ERR(CAM_CRE, "Invalid arguments %pK %pK",
|
||||
hw_mgr, config_args);
|
||||
@@ -2382,18 +2394,16 @@ static int cam_cre_mgr_config_hw(void *hw_priv, void *hw_config_args)
|
||||
mutex_lock(&hw_mgr->hw_mgr_mutex);
|
||||
mutex_lock(&ctx_data->ctx_mutex);
|
||||
if (ctx_data->ctx_state != CRE_CTX_STATE_ACQUIRED) {
|
||||
mutex_unlock(&ctx_data->ctx_mutex);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
CAM_ERR(CAM_CRE, "ctx id :%u is not in use",
|
||||
ctx_data->ctx_id);
|
||||
return -EINVAL;
|
||||
rc= -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (list_empty(&hw_mgr->free_req_list)) {
|
||||
mutex_unlock(&ctx_data->ctx_mutex);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
CAM_ERR(CAM_JPEG, "list empty");
|
||||
return -ENOMEM;
|
||||
CAM_ERR(CAM_CRE, "No request in free list");
|
||||
rc = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
cfg_req = list_first_entry(&hw_mgr->free_req_list,
|
||||
@@ -2405,14 +2415,19 @@ static int cam_cre_mgr_config_hw(void *hw_priv, void *hw_config_args)
|
||||
cam_cre_mgr_cre_clk_update(hw_mgr, ctx_data, cre_req->req_idx);
|
||||
ctx_data->req_list[cre_req->req_idx]->submit_timestamp = ktime_get();
|
||||
|
||||
CAM_DBG(CAM_CRE, "ctx id :%u req id %lld", ctx_data->ctx_id, cre_req->request_id);
|
||||
|
||||
cfg_req->req_id = cre_req->request_id;
|
||||
cfg_req->ctx_id = ctx_data->ctx_id;
|
||||
|
||||
if (cre_req->request_id <= ctx_data->last_flush_req)
|
||||
if (cre_req->request_id <= ctx_data->last_flush_req) {
|
||||
CAM_WARN(CAM_CRE,
|
||||
"Anomaly submitting flushed req %llu [last_flush %llu] in ctx %u",
|
||||
cre_req->request_id, ctx_data->last_flush_req,
|
||||
ctx_data->ctx_id);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
list_add_tail(&cfg_req->list, &hw_mgr->hw_config_req_list);
|
||||
|
||||
@@ -2429,6 +2444,7 @@ static int cam_cre_mgr_config_hw(void *hw_priv, void *hw_config_args)
|
||||
return rc;
|
||||
config_err:
|
||||
cam_cre_mgr_handle_config_err(config_args, ctx_data);
|
||||
end:
|
||||
mutex_unlock(&ctx_data->ctx_mutex);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
return rc;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 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_CRE_HW_MGR_H
|
||||
@@ -146,14 +146,16 @@ struct cam_cre_clk_info {
|
||||
/**
|
||||
* struct cre_cmd_work_data
|
||||
*
|
||||
* @type: Type of work data
|
||||
* @data: Private data
|
||||
* @req_id: Request Idx
|
||||
* @type: Type of work data
|
||||
* @data: Private data
|
||||
* @req_idx: Request Idx
|
||||
* @request_id: Request id
|
||||
*/
|
||||
struct cre_cmd_work_data {
|
||||
uint32_t type;
|
||||
void *data;
|
||||
int64_t req_idx;
|
||||
uint64_t request_id;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -46,8 +47,8 @@ static int cam_cre_top_reset(struct cam_cre_hw *cre_hw_info,
|
||||
cam_io_w_mb(top_reg_val->irq_mask,
|
||||
cre_hw_info->top_reg_offset->base + top_reg->irq_mask);
|
||||
|
||||
/* CRE SW RESET */
|
||||
cam_io_w_mb(top_reg_val->sw_reset_cmd,
|
||||
/* CRE HW RESET */
|
||||
cam_io_w_mb(top_reg_val->hw_reset_cmd,
|
||||
cre_hw_info->top_reg_offset->base + top_reg->reset_cmd);
|
||||
|
||||
rc = wait_for_completion_timeout(
|
||||
|
Reference in New Issue
Block a user