Переглянути джерело

msm: eva: Validate instance before deleting

The change will avoid panic during DSP session deletion in case
an invaid instance pointer passed in. Disable suspend early
during core init.

Change-Id: I0ec1e95d17a65b26fb29c970889926d9507bf554
Signed-off-by: George Shen <[email protected]>
George Shen 3 роки тому
батько
коміт
2b303bbbf4
4 змінених файлів з 23 додано та 2 видалено
  1. 1 1
      msm/eva/cvp_hfi.c
  2. 20 0
      msm/eva/msm_cvp_common.c
  3. 1 0
      msm/eva/msm_cvp_common.h
  4. 1 1
      msm/eva/msm_cvp_dsp.c

+ 1 - 1
msm/eva/cvp_hfi.c

@@ -1777,6 +1777,7 @@ static int iris_hfi_core_init(void *device)
 
 	dprintk(CVP_CORE, "Core initializing\n");
 
+	pm_stay_awake(dev->res->pdev->dev.parent);
 	mutex_lock(&dev->lock);
 
 	dev->bus_vote.data =
@@ -1787,7 +1788,6 @@ static int iris_hfi_core_init(void *device)
 		goto err_no_mem;
 	}
 
-	pm_stay_awake(dev->res->pdev->dev.parent);
 	dev->bus_vote.data_count = 1;
 	dev->bus_vote.data->power_mode = CVP_POWER_TURBO;
 

+ 20 - 0
msm/eva/msm_cvp_common.c

@@ -1591,5 +1591,25 @@ error:
 }
 
 
+bool is_cvp_inst_valid(struct msm_cvp_inst *inst)
+{
+	struct msm_cvp_core *core;
+	struct msm_cvp_inst *sess;
+
+	core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
+	if (!core)
+		return false;
 
+	mutex_lock(&core->lock);
+	list_for_each_entry(sess, &core->instances, list) {
+		if (inst == sess) {
+			if (kref_read(&inst->kref)) {
+				mutex_unlock(&core->lock);
+				return true;
+			}
+		}
+	}
+	mutex_unlock(&core->lock);
+	return false;
+}
 

+ 1 - 0
msm/eva/msm_cvp_common.h

@@ -13,6 +13,7 @@ struct msm_cvp_inst *cvp_get_inst(struct msm_cvp_core *core,
 		void *session_id);
 struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core,
 		void *session_id);
+bool is_cvp_inst_valid(struct msm_cvp_inst *inst);
 void cvp_change_inst_state(struct msm_cvp_inst *inst,
 		enum instance_state state);
 struct msm_cvp_core *get_cvp_core(int core_id);

+ 1 - 1
msm/eva/msm_cvp_dsp.c

@@ -1403,7 +1403,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd)
 	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
-	if (!inst) {
+	if (!inst || !is_cvp_inst_valid(inst)) {
 		dprintk(CVP_ERR, "%s incorrect session ID\n", __func__);
 		cmd->ret = -1;
 		goto dsp_fail_delete;