From nobody Mon Jun 8 23:57:32 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEAD037B03B for ; Mon, 25 May 2026 12:42:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779712951; cv=none; b=nUdPRvWPRN9976v35PvsFHCACRn4mS/wjCpxon++k76AAY9aHuvLKQsy58WC6ah72UR+ip3QB3vAS3BOQsj1YS+OXDI/G5p/FsYwiyJk/cN7m1aVI1gpfxnzp8G1axFN/rIBf/n3554WhYTy+VKFmMB7sPLl7H7npAR9DXMlDR4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779712951; c=relaxed/simple; bh=cKySdc3wDGMGQNU6OFE+qNwjlkwK51EH0yLKilD/OOI=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=lpQjwImZakpoeDEEaIDtSUk7B5Ne66ofWBj6fLQ7Ciogh9MCCIxdoPmEbxee4gYeYP5d8A0uxKISowdyHiri/77Kgr3ZrvqEmKjms7ycFfDJt88qnBYBMl6QoSovr7iNXa8k8qOA2+l4o4FxAD2ytOSyID3XDkDx6cfaDL7ZuJ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=kRhdGVbp; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=ChRtsGNL; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="kRhdGVbp"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="ChRtsGNL" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64P7HxX8671784 for ; Mon, 25 May 2026 12:42:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:message-id:mime-version :subject:to; s=qcppdkim1; bh=gspTz+RCdd00FlSjfdVj6tl1b3B4ut3IzjE OfEUzLJI=; b=kRhdGVbpWTbKCytAZ8IksU24QLSo/2mOmI+OoxIahZpf2/zyX89 EfHL56uZifaPsSQTqPfNPtRd1pCC2vPRVwBnof36KcXCVSi053bo5YqKELoXlg3Z 4Kzw/UXqmQzxpxtk0M5IUACUXrEZ2NdQfpOzuS4b9d2lhWFENEPnXYMT2L0ZmEEV W2oEbq7NP0OrBATUkvm9l46V88Fx1rUlhPyGF6fsSNMvmkwrTOSG9ScgLLfmmyPy Y7CQsLN/Rqzm1WxZhNWzdnbLR4K1U3pKlMiCWraqaejFbmO+7swgocJV5FfpfKIO +746FT6wcQKvtzA3d4OxZmc6jCYo2dV65yQ== Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4eb4f3eku5-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 25 May 2026 12:42:28 +0000 (GMT) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-2babbeff9e4so104550655ad.0 for ; Mon, 25 May 2026 05:42:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1779712948; x=1780317748; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=gspTz+RCdd00FlSjfdVj6tl1b3B4ut3IzjEOfEUzLJI=; b=ChRtsGNLqKFF7B1hyiRCqvRIO48HoW28bTNfYc6W5lnFokvYcjI/JhK5QuAIY9k6Yl w8+Eh9GMVLWQamwic20bI1WikwpvDofm9lOtuOKVBb2238Frx1lyld3mRun5fnN5mX0b IhQuxVfKSsPbYqvYpjAIwqex4MNZtnLHZx0CCbAlj+p05lH0tpvnYkfAE9cnfVNDaIhx 8Nj6lgRD1AFDRcu2973WHGJihNyO2M2yHGo7fx1YIViXxlo6L3U5S2x+R5Vjs4e5NCOo 1AglEw6lVNa5lKlmyRiGeZiCjdRkPTGI3pEs1om8IXjDqesWQolO2xxIAILv2RxR7Spy 20gg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779712948; x=1780317748; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=gspTz+RCdd00FlSjfdVj6tl1b3B4ut3IzjEOfEUzLJI=; b=stERfgkxg83QgfjPf22FNbOOA2NKrSTYAIzKO4EyDq8UgO++iur6exQK7wxgi9xh// VTeHRQVQkoBm6d1i91vdFCsg5oM9HAdBc/80Zu56lM1nKQObhK6DsEjpy9hH8QM9X3K1 flK77RQrdnpfUijgJdNBFSE+pRIMTl2Y7mIfvPdbQhsBnCvYDEQ4nvCodkBIxVljZpzQ /8JGGYYaSPqp90dc1tNn22+AQs0e7loCqP6VvXjhKdM7DHVlrZqvM9nDKPOiU1oOrU8/ cUjk/MAfKdhW72jYM8jcPjMpUTLNitIDygie7AccyPEVcCl3fUGaPsZ4/Lu59po+3d4n hfmg== X-Forwarded-Encrypted: i=1; AFNElJ+ZJlGNKp4jI+G9prLGXLk8pyVbFOvmV0fifoHoCxFQRctMCqKIs7KCTkR063O8LpLRkC59B/ohOGN0538=@vger.kernel.org X-Gm-Message-State: AOJu0YyEThqB4rOASey5ya66tgxiOolk3Yv26xHw/VTdLwzI4Xu0PUlb 5Q55/JDnGqBWQ24Za1jNrBurBBFY+cop9Ws0NIurBWri8LBYWmku04JdKKxSqtuW1hi8BbV1tko 8nt9Bt+3WTPOIYSDmmTVyNFFbCcdy/4TGxPaarXLM6wLuStjvPuPM7e5OKDZy16BfCSk= X-Gm-Gg: Acq92OEhI04AjE7dwumn42frcR4fXsr5unFx/9qeyikyYPgLZ0Vn9JxiHCCD71eUI/P i9t1NlyZvD8UATFCHxxT0Bp9UX5FNTJ9o31JuYexXbXPJ7/5kRagmLOU8Ew9Y4u4wxcqc1/flhU Hhk6IQUrlWdwKjgHp7+furAHObUoQhpeuZQm2LHGyTzy4xHLBjUPX2zCkKfqUgUTwUyJ0MyMiR3 pZiBLtLZn/UOgj0P2izEGUF914LJWUZIH7E1lvdSzz1N8mf967TMXK9NPV61smRR5WhtMarr8hT Dxsnf3SQJyYXA3z4+p6mGtnbBzkkz03fV4HAWVVw02otE0AbiRw7iope8Ua+mWOlpjl3lT+IZHT 2wy6RSWmOIeo8k1B3NTqcVSMXMneP6kfcn6En+KNiRgYZGv4SZVe7Dl0= X-Received: by 2002:a17:902:f709:b0:2bc:dca9:f0ed with SMTP id d9443c01a7336-2beb087b062mr115484105ad.15.1779712948077; Mon, 25 May 2026 05:42:28 -0700 (PDT) X-Received: by 2002:a17:902:f709:b0:2bc:dca9:f0ed with SMTP id d9443c01a7336-2beb087b062mr115483825ad.15.1779712947431; Mon, 25 May 2026 05:42:27 -0700 (PDT) Received: from hu-anane-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2beb5205f16sm95717745ad.0.2026.05.25.05.42.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 May 2026 05:42:27 -0700 (PDT) From: Anandu Krishnan E To: srini@kernel.org, linux-arm-msm@vger.kernel.org Cc: gregkh@linuxfoundation.org, quic_bkumar@quicinc.com, linux-kernel@vger.kernel.org, quic_chennak@quicinc.com, dri-devel@lists.freedesktop.org, arnd@arndb.de, ekansh.gupta@oss.qualcomm.com, stable@kernel.org Subject: [PATCH v1] misc: fastrpc: fix context leak and hang on signal-interrupted invoke Date: Mon, 25 May 2026 18:12:22 +0530 Message-Id: <20260525124222.3082420-1-anandu.e@oss.qualcomm.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-ORIG-GUID: DOikK_RiynrCMcN35pXmvaNrL0DezWh5 X-Authority-Analysis: v=2.4 cv=WvYb99fv c=1 sm=1 tr=0 ts=6a1443b4 cx=c_pps a=IZJwPbhc+fLeJZngyXXI0A==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=htDFEa73CQMYf3Ekz7QA:9 a=uG9DUKGECoFWVXl0Dc02:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI1MDEzMSBTYWx0ZWRfX3csgHr8uQ37T tG2G4A1YBqUGNxWRzq0NI0BZdo/On1g+1i6iRCwQC878Kg9kzvaaNpXsELMojCSUtxQx75PIA6i HkYznGsrYLG/w4Kd2ig21soKTiF5RYtDk/ee2IqUn+ZZI9o7gdKoMApgc4vU/G/pAIwz9FpAT/M YJywCHoR+sIqDtFc0Qp/Of7gxYTWEokldOmzGCjfQnCzRUaBXAUCg3hWSaWqfiKksvdv6qiCRBN 4JUBTOMuB4U3oAOZvFYi9zB3hyhpn0ncZynhtC48+hiR2pvDBYbklfKq6hbhaYfxL8iZg1p/D7O hUTODyT560xJxM15gEkdix9uFu0YRJoNkvh1aIrtT6bdwTTpRgUIMtcz57KLxJW5v1ZP+KnGubj j8qJnOcAk/25F1N4htE1NmtlXeLVEHnVOfp3+KAVwMbxoyiHoRVby6K5nPghdf/ojHGdiNJNcDF b72vn7607HlUpYxVcAQ== X-Proofpoint-GUID: DOikK_RiynrCMcN35pXmvaNrL0DezWh5 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-25_03,2026-05-18_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 lowpriorityscore=0 spamscore=0 clxscore=1015 phishscore=0 adultscore=0 suspectscore=0 impostorscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605250131 Content-Type: text/plain; charset="utf-8" fastrpc invokes work by sending an RPC message to the DSP and blocking in wait_for_completion_interruptible() until the DSP responds. If a signal arrives during this wait, the syscall returns -ERESTARTSYS and the invoke context which holds the in-flight DMA buffers and completion state is left stranded in fl->pending. On the next syscall attempt (either auto-restarted by the kernel via SA_RESTART or manually retried by user-space after EINTR), a fresh context is allocated and the RPC message is re-sent to the DSP. This has two consequences: - The original context leaks in fl->pending until the file is closed. - The DSP receives a duplicate invocation. If the DSP was mid-way through processing the first request and had issued a reverse RPC call back to the host, the retry sends a new forward request instead of the expected reverse-RPC response. The DSP thread waiting for that response is never woken, causing a hang. Fix this by saving the interrupted context to a new fl->interrupted list on -ERESTARTSYS. When the same thread retries the invoke with a matching sc, restore the context and jump directly to the wait, skipping context allocation and message re-send. Also drain fl->interrupted on process exit and complete any sleeping contexts with -EPIPE when the rpmsg channel is removed. Fixes: 387f625585d1 ("misc: fastrpc: handle interrupted contexts") Cc: stable@kernel.org Signed-off-by: Anandu Krishnan E --- drivers/misc/fastrpc.c | 69 ++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 1080f9acf70a..22d0b0592c10 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -280,7 +280,6 @@ struct fastrpc_channel_ctx { struct fastrpc_device *secure_fdevice; struct fastrpc_device *fdevice; struct fastrpc_buf *remote_heap; - struct list_head invoke_interrupted_mmaps; bool secure; bool unsigned_support; u64 dma_mask; @@ -297,6 +296,7 @@ struct fastrpc_user { struct list_head user; struct list_head maps; struct list_head pending; + struct list_head interrupted; struct list_head mmaps; =20 struct fastrpc_channel_ctx *cctx; @@ -542,6 +542,36 @@ static void fastrpc_context_put_wq(struct work_struct = *work) fastrpc_context_put(ctx); } =20 +static void fastrpc_context_save_interrupted(struct fastrpc_invoke_ctx *ct= x) +{ + spin_lock(&ctx->fl->lock); + list_del(&ctx->node); + list_add_tail(&ctx->node, &ctx->fl->interrupted); + spin_unlock(&ctx->fl->lock); +} + +static struct fastrpc_invoke_ctx *fastrpc_context_restore_interrupted( + struct fastrpc_user *fl, u32 sc) +{ + struct fastrpc_invoke_ctx *ctx =3D NULL, *ictx, *n; + + spin_lock(&fl->lock); + list_for_each_entry_safe(ictx, n, &fl->interrupted, node) { + if (ictx->pid !=3D current->pid) + continue; + if (ictx->sc !=3D sc || ictx->fl !=3D fl) { + spin_unlock(&fl->lock); + return ERR_PTR(-EINVAL); + } + ctx =3D ictx; + list_del(&ctx->node); + list_add_tail(&ctx->node, &fl->pending); + break; + } + spin_unlock(&fl->lock); + return ctx; +} + #define CMP(aa, bb) ((aa) =3D=3D (bb) ? 0 : (aa) < (bb) ? -1 : 1) static int olaps_cmp(const void *a, const void *b) { @@ -1197,8 +1227,6 @@ static int fastrpc_internal_invoke(struct fastrpc_use= r *fl, u32 kernel, struct fastrpc_invoke_args *args) { struct fastrpc_invoke_ctx *ctx =3D NULL; - struct fastrpc_buf *buf, *b; - int err =3D 0; =20 if (!fl->sctx) @@ -1212,6 +1240,14 @@ static int fastrpc_internal_invoke(struct fastrpc_us= er *fl, u32 kernel, return -EPERM; } =20 + if (!kernel) { + ctx =3D fastrpc_context_restore_interrupted(fl, sc); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + if (ctx) + goto wait; + } + ctx =3D fastrpc_context_alloc(fl, kernel, sc, args); if (IS_ERR(ctx)) return PTR_ERR(ctx); @@ -1227,6 +1263,7 @@ static int fastrpc_internal_invoke(struct fastrpc_use= r *fl, u32 kernel, if (err) goto bail; =20 +wait: if (kernel) { if (!wait_for_completion_timeout(&ctx->work, 10 * HZ)) err =3D -ETIMEDOUT; @@ -1250,7 +1287,9 @@ static int fastrpc_internal_invoke(struct fastrpc_use= r *fl, u32 kernel, goto bail; =20 bail: - if (err !=3D -ERESTARTSYS && err !=3D -ETIMEDOUT) { + if (ctx && err =3D=3D -ERESTARTSYS) { + fastrpc_context_save_interrupted(ctx); + } else if (ctx && err !=3D -ETIMEDOUT) { /* We are done with this compute context */ spin_lock(&fl->lock); list_del(&ctx->node); @@ -1258,13 +1297,6 @@ static int fastrpc_internal_invoke(struct fastrpc_us= er *fl, u32 kernel, fastrpc_context_put(ctx); } =20 - if (err =3D=3D -ERESTARTSYS) { - list_for_each_entry_safe(buf, b, &fl->mmaps, node) { - list_del(&buf->node); - list_add_tail(&buf->node, &fl->cctx->invoke_interrupted_mmaps); - } - } - if (err) dev_dbg(fl->sctx->dev, "Error: Invoke Failed %d\n", err); =20 @@ -1598,6 +1630,11 @@ static int fastrpc_device_release(struct inode *inod= e, struct file *file) fastrpc_context_put(ctx); } =20 + list_for_each_entry_safe(ctx, n, &fl->interrupted, node) { + list_del(&ctx->node); + fastrpc_context_put(ctx); + } + list_for_each_entry_safe(map, m, &fl->maps, node) fastrpc_map_put(map); =20 @@ -1637,6 +1674,7 @@ static int fastrpc_device_open(struct inode *inode, s= truct file *filp) spin_lock_init(&fl->lock); mutex_init(&fl->mutex); INIT_LIST_HEAD(&fl->pending); + INIT_LIST_HEAD(&fl->interrupted); INIT_LIST_HEAD(&fl->maps); INIT_LIST_HEAD(&fl->mmaps); INIT_LIST_HEAD(&fl->user); @@ -2435,7 +2473,6 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *r= pdev) rdev->dma_mask =3D &data->dma_mask; dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32)); INIT_LIST_HEAD(&data->users); - INIT_LIST_HEAD(&data->invoke_interrupted_mmaps); spin_lock_init(&data->lock); idr_init(&data->ctx_idr); data->domain_id =3D domain_id; @@ -2467,13 +2504,16 @@ static void fastrpc_notify_users(struct fastrpc_use= r *user) ctx->retval =3D -EPIPE; complete(&ctx->work); } + list_for_each_entry(ctx, &user->interrupted, node) { + ctx->retval =3D -EPIPE; + complete(&ctx->work); + } spin_unlock(&user->lock); } =20 static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) { struct fastrpc_channel_ctx *cctx =3D dev_get_drvdata(&rpdev->dev); - struct fastrpc_buf *buf, *b; struct fastrpc_user *user; unsigned long flags; =20 @@ -2490,9 +2530,6 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device = *rpdev) if (cctx->secure_fdevice) misc_deregister(&cctx->secure_fdevice->miscdev); =20 - list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node) - list_del(&buf->node); - if (cctx->remote_heap) fastrpc_buf_free(cctx->remote_heap); =20 --=20 2.34.1