From a5ee0494e92d683e0d4ab6541dcc66e046e86e78 Mon Sep 17 00:00:00 2001 From: Santosh Sakore Date: Thu, 23 May 2024 19:39:22 +0530 Subject: [PATCH] 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 --- dsp/adsprpc.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/dsp/adsprpc.c b/dsp/adsprpc.c index dc104c39c5..a4753a1f78 100644 --- a/dsp/adsprpc.c +++ b/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);