msm: camera: reqmgr: Add protection for link reset

When crm close, call free link which free in_q.
The in_q ptr is null. It will result in null
in_q ptr deref when call notify trigger. So need
add spin lock to protect req data.

CRs-Fixed: 3488142
Change-Id: I25101f00e07bd56f1449085f2c6ce3ce3141adc3
Signed-off-by: Wang Kan <quic_wkan@quicinc.com>
This commit is contained in:
Wang Kan 2023-05-10 10:21:30 +08:00 committed by Camera Software Integration
parent 16be1306ef
commit 0f4492b985
2 changed files with 27 additions and 13 deletions

View File

@ -53,6 +53,7 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
{
int i = 0;
spin_lock_bh(&link->req.reset_link_spin_lock);
link->link_hdl = 0;
link->num_devs = 0;
link->max_delay = CAM_PIPELINE_DELAY_0;
@ -90,15 +91,17 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
link->try_for_internal_recovery = false;
link->is_sending_req = false;
atomic_set(&link->eof_event_cnt, 0);
mutex_lock(&link->lock);
link->properties_mask = CAM_LINK_PROPERTY_NONE;
mutex_unlock(&link->lock);
link->cont_empty_slots = 0;
__cam_req_mgr_reset_apply_data(link);
__cam_req_mgr_reset_state_monitor_array(link);
for (i = 0; i < MAXIMUM_LINKS_PER_SESSION - 1; i++)
link->sync_link[i] = NULL;
spin_unlock_bh(&link->req.reset_link_spin_lock);
mutex_lock(&link->lock);
link->properties_mask = CAM_LINK_PROPERTY_NONE;
mutex_unlock(&link->lock);
}
void cam_req_mgr_handle_core_shutdown(void)
@ -2901,7 +2904,6 @@ static void __cam_req_mgr_free_link(struct cam_req_mgr_core_link *link)
{
ptrdiff_t i;
kfree(link->req.in_q);
link->req.in_q = NULL;
link->parent = NULL;
i = link - g_links;
CAM_DBG(CAM_CRM, "free link index %d", i);
@ -4224,13 +4226,21 @@ static int cam_req_mgr_cb_notify_trigger(
trigger_id = trigger_data->trigger_id;
trigger = trigger_data->trigger;
spin_lock_bh(&link->req.reset_link_spin_lock);
in_q = link->req.in_q;
if (!in_q) {
CAM_DBG(CAM_CRM, "in_q ptr NULL, link_hdl %x", trigger_data->link_hdl);
spin_unlock_bh(&link->req.reset_link_spin_lock);
rc = -EINVAL;
goto end;
}
state.req_state = CAM_CRM_NOTIFY_TRIGGER;
state.req_id = in_q->slot[in_q->rd_idx].req_id;
state.dev_hdl = -1;
state.frame_id = trigger_data->frame_id;
__cam_req_mgr_update_state_monitor_array(link, &state);
spin_unlock_bh(&link->req.reset_link_spin_lock);
/*
* Reduce the workq overhead when there is
@ -5784,6 +5794,7 @@ int cam_req_mgr_core_device_init(void)
mutex_init(&g_links[i].lock);
spin_lock_init(&g_links[i].link_state_spin_lock);
spin_lock_init(&g_links[i].req.monitor_slock);
spin_lock_init(&g_links[i].req.reset_link_spin_lock);
atomic_set(&g_links[i].is_used, 0);
cam_req_mgr_core_link_reset(&g_links[i]);
}

View File

@ -376,15 +376,17 @@ struct cam_req_mgr_state_monitor {
/**
* struct cam_req_mgr_req_data
* @in_q : Poiner to Input request queue
* @l_tbl : unique pd request tables.
* @num_tbl : how many unique pd value devices are present
* @apply_data : Holds information about request id for a request
* @prev_apply_data : Holds information about request id for a previous
* applied request
* @state_monitor : used to track the request state in CRM
* @next_state_idx : indicates index to hold new request state
* @lock : mutex lock protecting request data ops.
* @in_q : Poiner to Input request queue
* @l_tbl : unique pd request tables.
* @num_tbl : how many unique pd value devices are present
* @apply_data : Holds information about request id for a request
* @prev_apply_data : Holds information about request id for a previous
* applied request
* @state_monitor : used to track the request state in CRM
* @next_state_idx : indicates index to hold new request state
* @lock : mutex lock protecting request data ops.
* @monitor_slock : spin lock protecting state mointor variables
* @reset_link_spin_lock : spin lock protecting link data ops when reset link
*/
struct cam_req_mgr_req_data {
struct cam_req_mgr_req_queue *in_q;
@ -397,6 +399,7 @@ struct cam_req_mgr_req_data {
int32_t next_state_idx;
struct mutex lock;
spinlock_t monitor_slock;
spinlock_t reset_link_spin_lock;
};
/**