浏览代码

dsp-kernel: Move the ssrcount access within a critical section

The subsystem ssrcount is write-protected with a channel mutex. In a
few places, the code accesses it outside the critical section, which
can result in false reads during a race condition. To address this,
move the ssrcount access within a critical section.

Change-Id: I7df1e05fd892277a10514e3759f7ea67c51bac3b
Signed-off-by: Santosh <[email protected]>
Santosh Sakore 1 年之前
父节点
当前提交
a5ee0494e9
共有 1 个文件被更改,包括 12 次插入5 次删除
  1. 12 5
      dsp/adsprpc.c

+ 12 - 5
dsp/adsprpc.c

@@ -3510,9 +3510,11 @@ int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
 		trace_fastrpc_msg("context_free: end");
 	}
 	if (!kernel) {
+		mutex_lock(&fl->apps->channel[cid].smd_mutex);
 		if (VALID_FASTRPC_CID(cid)
 			&& (fl->ssrcount != fl->apps->channel[cid].ssrcount))
 			err = -ECONNRESET;
+		mutex_unlock(&fl->apps->channel[cid].smd_mutex);
 	}
 
 invoke_end:
@@ -6726,8 +6728,8 @@ int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
 			}
 		}
 		fl->cid = cid;
-		fl->ssrcount = fl->apps->channel[cid].ssrcount;
 		mutex_lock(&fl->apps->channel[cid].smd_mutex);
+		fl->ssrcount = fl->apps->channel[cid].ssrcount;
 		err = fastrpc_session_alloc_locked(&fl->apps->channel[cid],
 				0, fl->sharedcb, fl->pd_type, &fl->sctx);
 		mutex_unlock(&fl->apps->channel[cid].smd_mutex);
@@ -7919,7 +7921,9 @@ void fastrpc_restart_drivers(int cid)
 	struct fastrpc_apps *me = &gfa;
 
 	fastrpc_notify_drivers(me, cid);
+	mutex_lock(&me->channel[cid].smd_mutex);
 	me->channel[cid].ssrcount++;
+	mutex_unlock(&me->channel[cid].smd_mutex);
 }
 
 static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
@@ -7933,9 +7937,14 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
 	int cid = -1;
 	struct timespec64 startT = {0};
 	unsigned long irq_flags = 0;
+	uint64_t ssrcount = 0;
 
 	ctx = container_of(nb, struct fastrpc_channel_ctx, nb);
 	cid = ctx - &me->channel[0];
+	/* ssrcount should be read within a critical section */
+	mutex_lock(&me->channel[cid].smd_mutex);
+	ssrcount = ctx->ssrcount;
+	mutex_unlock(&me->channel[cid].smd_mutex);
 	switch (code) {
 	case QCOM_SSR_BEFORE_SHUTDOWN:
 		fastrpc_rproc_trace_events(gcinfo[cid].subsys,
@@ -7968,13 +7977,11 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
 			"QCOM_SSR_BEFORE_POWERUP", "fastrpc_restart_notifier-enter");
 		pr_info("adsprpc: %s: subsystem %s is about to start\n",
 			__func__, gcinfo[cid].subsys);
-		if (cid == CDSP_DOMAIN_ID && dump_enabled() &&
-				ctx->ssrcount)
+		if (cid == CDSP_DOMAIN_ID && dump_enabled() && ssrcount)
 			fastrpc_update_ramdump_status(cid);
 		fastrpc_notify_drivers(me, cid);
 		/* Skip ram dump collection in first boot */
-		if (cid == CDSP_DOMAIN_ID && dump_enabled() &&
-				ctx->ssrcount) {
+		if (cid == CDSP_DOMAIN_ID && dump_enabled() && ssrcount) {
 			mutex_lock(&me->channel[cid].smd_mutex);
 			fastrpc_print_debug_data(cid);
 			mutex_unlock(&me->channel[cid].smd_mutex);