From patchwork Fri Feb 2 06:40:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542144 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 0F55A17556; Fri, 2 Feb 2024 06:40:54 +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=1706856056; cv=none; b=izGO5c6lS4Mrv3MAH5UaernchAhCt2oCjb3+95SQYHl8b4yyj8Jb6VcK6KvHRX6d3Mq2j7Pa5B9IHFq3VAo5gqwu9WZo6Cu4nF/YESRuk5pJKaX1nRkv+iyDw120jn6iXXlK+cDeHgm5kutBrb+T80YfoxVMKTTFp7Ti37mUUpA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856056; c=relaxed/simple; bh=VnjGikD3+8LM3EsshRS2+CpJ6NioY50g7djKTdknQjs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=efdyhnNpY04bh+YFJ+uX1F7Hnot+mtKSjurKVcTmGRmpj/mNuz7xmWIvAbxTP7Xkz9Id8elpZuQpn3nbd5byPW9ouCYJLQG70t/zcVnzIXMtjSWNHIMitjwSC310Q4oP9Bo3zoCeoqFZFFMpDHXy2uf7QSJ/D0y/vUruFAeTCvE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=BFI81TRL; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="BFI81TRL" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4123pr9b023855; Fri, 2 Feb 2024 06:40:52 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=5/ViGItAQDCuANO6a8Sh tZBeE3FMPpo+n5Za9x3lcSI=; b=BFI81TRL4PJ98Ji7E2uU3LzGX31g07QOVu2w 13+nvmm2gt/y1r0NdDs7SH/mjFLNhB/7P5mksra7jk/7Q/4pPM85Hk1fHb1PLI9D IQy5LL4VORYpSW9X0IwpsQgc46acLnjzJ/IpRVT/Y9ySDMw6opC3YqyeS+XmSvof +UmhO8JGj3qPCqJhjr0I0WK1kdW+0VI83W9OZ1hmZl1gcprOW9h6LaQUFW1VIc8b v2WH7Fv5pNcHWIJvV44KArebWd04R4abLULJDlrZn8+J/YUiLuVcUeZPjsyKueuR D3tu4yJhnygmA0AilDqCQ6boSmLfP6hHQPm4mTfbnCI3ojge2A== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pwc0n2s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:40:52 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126epZj004451 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:40:51 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:40:49 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 01/16] misc: fastrpc: Redesign remote heap management Date: Fri, 2 Feb 2024 12:10:24 +0530 Message-ID: <20240202064039.15505-2-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: tRpx9zjprpDtcfOvHuqzzc_C_ooDs4B1 X-Proofpoint-ORIG-GUID: tRpx9zjprpDtcfOvHuqzzc_C_ooDs4B1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 clxscore=1015 phishscore=0 bulkscore=0 mlxscore=0 suspectscore=0 adultscore=0 priorityscore=1501 malwarescore=0 impostorscore=0 lowpriorityscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Current remote heap design comes with problems where all types of buffers are getting added to interrupted list and also user unmap request is not handled properly. Add changes to maintain list in a way that it can be properly managed and used at different audio PD specific scenarios. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 180 +++++++++++++++++++++++++++++++---------- 1 file changed, 139 insertions(+), 41 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 1c6c62a7f7f5..f3ef5e194f11 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -196,6 +196,7 @@ struct fastrpc_buf { struct dma_buf *dmabuf; struct device *dev; void *virt; + u32 flag; u64 phys; u64 size; /* Lock for dma buf attachments */ @@ -273,11 +274,11 @@ struct fastrpc_channel_ctx { struct kref refcount; /* Flag if dsp attributes are cached */ bool valid_attributes; + bool staticpd_status; u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES]; struct fastrpc_device *secure_fdevice; struct fastrpc_device *fdevice; - struct fastrpc_buf *remote_heap; - struct list_head invoke_interrupted_mmaps; + struct list_head rmaps; bool secure; bool unsigned_support; u64 dma_mask; @@ -326,7 +327,7 @@ static void fastrpc_free_map(struct kref *ref) err = qcom_scm_assign_mem(map->phys, map->size, &src_perms, &perm, 1); if (err) { - dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", + dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", map->phys, map->size, err); return; } @@ -817,7 +818,7 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, map->attr = attr; err = qcom_scm_assign_mem(map->phys, (u64)map->size, &src_perms, dst_perms, 2); if (err) { - dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d", + dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", map->phys, map->size, err); goto map_err; } @@ -1139,7 +1140,6 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, struct fastrpc_invoke_args *args) { struct fastrpc_invoke_ctx *ctx = NULL; - struct fastrpc_buf *buf, *b; int err = 0; @@ -1200,13 +1200,6 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, fastrpc_context_put(ctx); } - if (err == -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); @@ -1231,14 +1224,48 @@ static bool is_session_rejected(struct fastrpc_user *fl, bool unsigned_pd_reques return false; } +static int fastrpc_mmap_remove_ssr(struct fastrpc_channel_ctx *cctx) +{ + struct fastrpc_buf *buf, *b; + int err = 0; + + list_for_each_entry_safe(buf, b, &cctx->rmaps, node) { + if (cctx->vmcount) { + u64 src_perms = 0; + struct qcom_scm_vmperm dst_perms; + u32 i; + + for (i = 0; i < cctx->vmcount; i++) + src_perms |= BIT(cctx->vmperms[i].vmid); + + dst_perms.vmid = QCOM_SCM_VMID_HLOS; + dst_perms.perm = QCOM_SCM_PERM_RWX; + err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, + &src_perms, &dst_perms, 1); + if (err) { + pr_err("%s: Failed to assign memory phys 0x%llx size 0x%llx err %d\n", + __func__, buf->phys, buf->size, err); + return err; + } + } + list_del(&buf->node); + fastrpc_buf_free(buf); + } + + return 0; +} + static int fastrpc_init_create_static_process(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_init_create_static init; struct fastrpc_invoke_args *args; struct fastrpc_phy_page pages[1]; + struct fastrpc_buf *buf = NULL; + u64 phys = 0, size = 0; char *name; int err; + bool scm_done = false; struct { int pgid; u32 namelen; @@ -1271,24 +1298,29 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, goto err_name; } - if (!fl->cctx->remote_heap) { - err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen, - &fl->cctx->remote_heap); + if (!fl->cctx->staticpd_status) { + err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen, &buf); if (err) goto err_name; + phys = buf->phys; + size = buf->size; /* Map if we have any heap VMIDs associated with this ADSP Static Process. */ if (fl->cctx->vmcount) { - err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, - (u64)fl->cctx->remote_heap->size, + err = qcom_scm_assign_mem(phys, (u64)size, &fl->cctx->perms, fl->cctx->vmperms, fl->cctx->vmcount); if (err) { - dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d", - fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", + phys, size, err); goto err_map; } + scm_done = true; } + fl->cctx->staticpd_status = true; + spin_lock(&fl->lock); + list_add_tail(&buf->node, &fl->cctx->rmaps); + spin_unlock(&fl->lock); } inbuf.pgid = fl->tgid; @@ -1304,8 +1336,8 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, args[1].length = inbuf.namelen; args[1].fd = -1; - pages[0].addr = fl->cctx->remote_heap->phys; - pages[0].size = fl->cctx->remote_heap->size; + pages[0].addr = phys; + pages[0].size = size; args[2].ptr = (u64)(uintptr_t) pages; args[2].length = sizeof(*pages); @@ -1322,7 +1354,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, return 0; err_invoke: - if (fl->cctx->vmcount) { + if (fl->cctx->vmcount && scm_done) { u64 src_perms = 0; struct qcom_scm_vmperm dst_perms; u32 i; @@ -1332,15 +1364,18 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, dst_perms.vmid = QCOM_SCM_VMID_HLOS; dst_perms.perm = QCOM_SCM_PERM_RWX; - err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, - (u64)fl->cctx->remote_heap->size, + err = qcom_scm_assign_mem(phys, (u64)size, &src_perms, &dst_perms, 1); if (err) - dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", - fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", + phys, size, err); } err_map: - fastrpc_buf_free(fl->cctx->remote_heap); + fl->cctx->staticpd_status = false; + spin_lock(&fl->lock); + list_del(&buf->node); + spin_unlock(&fl->lock); + fastrpc_buf_free(buf); err_name: kfree(name); err: @@ -1807,6 +1842,26 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf * err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]); if (!err) { + if (buf->flag == ADSP_MMAP_REMOTE_HEAP_ADDR) { + if (fl->cctx->vmcount) { + u64 src_perms = 0; + struct qcom_scm_vmperm dst_perms; + u32 i; + + for (i = 0; i < fl->cctx->vmcount; i++) + src_perms |= BIT(fl->cctx->vmperms[i].vmid); + + dst_perms.vmid = QCOM_SCM_VMID_HLOS; + dst_perms.perm = QCOM_SCM_PERM_RWX; + err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, + &src_perms, &dst_perms, 1); + if (err) { + dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", + buf->phys, buf->size, err); + return err; + } + } + } dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr); spin_lock(&fl->lock); list_del(&buf->node); @@ -1823,7 +1878,12 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_buf *buf = NULL, *iter, *b; struct fastrpc_req_munmap req; + struct fastrpc_munmap_req_msg req_msg; + struct fastrpc_map *map = NULL, *iterm, *m; struct device *dev = fl->sctx->dev; + struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; + int err = 0; + u32 sc; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; @@ -1837,13 +1897,52 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp) } spin_unlock(&fl->lock); - if (!buf) { - dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n", - req.vaddrout, req.size); + if (buf) { + err = fastrpc_req_munmap_impl(fl, buf); + return err; + } + + spin_lock(&fl->lock); + list_for_each_entry_safe(iter, b, &fl->cctx->rmaps, node) { + if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) { + buf = iter; + break; + } + } + spin_unlock(&fl->lock); + if (buf) { + err = fastrpc_req_munmap_impl(fl, buf); + return err; + } + spin_lock(&fl->lock); + list_for_each_entry_safe(iterm, m, &fl->maps, node) { + if (iterm->raddr == req.vaddrout) { + map = iterm; + break; + } + } + spin_unlock(&fl->lock); + if (!map) { + dev_err(dev, "map not in list\n"); return -EINVAL; } - return fastrpc_req_munmap_impl(fl, buf); + req_msg.pgid = fl->tgid; + req_msg.size = map->size; + req_msg.vaddr = map->raddr; + + args[0].ptr = (u64) (uintptr_t) &req_msg; + args[0].length = sizeof(req_msg); + + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MUNMAP, 1, 0); + err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, + &args[0]); + if (err) + dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n", map->fd, map->raddr); + else + fastrpc_map_put(map); + + return err; } static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) @@ -1909,6 +2008,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) /* update the buffer to be able to deallocate the memory on the DSP */ buf->raddr = (uintptr_t) rsp_msg.vaddr; + buf->flag = req.flags; /* let the client know the address to use */ req.vaddrout = rsp_msg.vaddr; @@ -1918,14 +2018,17 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, &fl->cctx->perms, fl->cctx->vmperms, fl->cctx->vmcount); if (err) { - dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", + dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", buf->phys, buf->size, err); goto err_assign; } } spin_lock(&fl->lock); - list_add_tail(&buf->node, &fl->mmaps); + if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) + list_add_tail(&buf->node, &fl->cctx->rmaps); + else + list_add_tail(&buf->node, &fl->mmaps); spin_unlock(&fl->lock); if (copy_to_user((void __user *)argp, &req, sizeof(req))) { @@ -2332,7 +2435,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) rdev->dma_mask = &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); + INIT_LIST_HEAD(&data->rmaps); spin_lock_init(&data->lock); idr_init(&data->ctx_idr); data->domain_id = domain_id; @@ -2370,13 +2473,14 @@ static void fastrpc_notify_users(struct fastrpc_user *user) static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) { struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev); - struct fastrpc_buf *buf, *b; struct fastrpc_user *user; unsigned long flags; /* No invocations past this point */ spin_lock_irqsave(&cctx->lock, flags); cctx->rpdev = NULL; + cctx->staticpd_status = false; + fastrpc_mmap_remove_ssr(cctx); list_for_each_entry(user, &cctx->users, user) fastrpc_notify_users(user); spin_unlock_irqrestore(&cctx->lock, flags); @@ -2387,12 +2491,6 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) if (cctx->secure_fdevice) misc_deregister(&cctx->secure_fdevice->miscdev); - 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); - of_platform_depopulate(&rpdev->dev); fastrpc_channel_ctx_put(cctx); From patchwork Fri Feb 2 06:40:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542145 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 0E39D17597; Fri, 2 Feb 2024 06:40:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856058; cv=none; b=DaGOMcxU0F9ltKpMfVpaiMLOWub0wTU1vtKLiuwrllBvF68t+JkOdHEUC2a7zG/MQN2lJFRaHM2ps2f32hu9TA/2PLtdzJSCBJ1TwtoOjAtEDGVT8ebLpyvLeLV4Md53utO3kPc7xuO0X2qpS9K04AdtC3Qb3S1S8LQzjq/e/nk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856058; c=relaxed/simple; bh=cGkQjKoIQDiN5Xq6LV6z19OREy/bAcog1FZAPK4hZIs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UlspnC1tAzUmHFyVaBX+ISMFSHe579ebOJs2NMyW3jtsfwZgJm3hxVOv2qEcB5PUOJzpyGnnW88Fy38FJh8jGfpf4KpyAE+J20PVzImb5o+Znltv+45j1gQH2GPM8bO8g7aTr7aPhQbGud5v4MCBLXroFKOPKJuLvJFcwf7i9Jw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=kB0Pf2cP; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="kB0Pf2cP" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4121kC81006539; Fri, 2 Feb 2024 06:40:55 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=kmJ087AWbTEua6Ah3N05 woyURUtVhIvftBj2hPjPeWM=; b=kB0Pf2cP75CyEeV5Jc+jECwbs+jsoFputKut pWnGvZTu0uXKxfkJDSpJh+ZAX3kchPNHTntDMWyOybNyehJ29/97ADXyq4oYNf/h YYkDitBJjHTuL8a+auTLcVe0sDkT2hnwH0N8ZRz0hHw650hkXwyFGCo5nO3YQd0p IEPUdd4l8kkwwOd//FONjJiaSnIySYh/+HKLz6qXuqVEwR/MrzkZDB2YL5YWA3lW Iln2AUUayx+MFgu1WjrEVh09efGD59oKbglDiJFka2Qz5REq85I4lLRQa15XpQBa 7qSaJkL6fIOkqbjy3Cvv0OD6hldbq3979FYs0igUQWqMkP2WMg== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pu00n2m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:40:54 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126esaR027209 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:40:54 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:40:52 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 02/16] misc: fastrpc: Add support for unsigned PD Date: Fri, 2 Feb 2024 12:10:25 +0530 Message-ID: <20240202064039.15505-3-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: ip1CSRe35apCOx3u3JmC0ViHFYrSznYg X-Proofpoint-ORIG-GUID: ip1CSRe35apCOx3u3JmC0ViHFYrSznYg X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxscore=0 mlxlogscore=999 suspectscore=0 lowpriorityscore=0 impostorscore=0 bulkscore=0 clxscore=1015 adultscore=0 spamscore=0 priorityscore=1501 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Unsigned PD requires more initial memory to spawn. Also most of the memory request are allocated from userspace. Add support for unsigned PD by increasing init memory size and handling mapping request for cases other than DSP heap grow requests. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 184 ++++++++++++++++++++++++++--------------- 1 file changed, 118 insertions(+), 66 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index f3ef5e194f11..bdce5469de19 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -38,7 +38,7 @@ #define FASTRPC_INIT_HANDLE 1 #define FASTRPC_DSP_UTILITIES_HANDLE 2 #define FASTRPC_CTXID_MASK (0xFF0) -#define INIT_FILELEN_MAX (2 * 1024 * 1024) +#define INIT_FILELEN_MAX (5 * 1024 * 1024) #define INIT_FILE_NAMELEN_MAX (128) #define FASTRPC_DEVICE_NAME "fastrpc" @@ -303,6 +303,7 @@ struct fastrpc_user { int tgid; int pd; bool is_secure_dev; + bool is_unsigned_pd; /* Lock for lists */ spinlock_t lock; /* lock for allocations */ @@ -1403,7 +1404,6 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, u32 siglen; } inbuf; u32 sc; - bool unsigned_module = false; args = kcalloc(FASTRPC_CREATE_PROCESS_NARGS, sizeof(*args), GFP_KERNEL); if (!args) @@ -1415,9 +1415,9 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, } if (init.attrs & FASTRPC_MODE_UNSIGNED_MODULE) - unsigned_module = true; + fl->is_unsigned_pd = true; - if (is_session_rejected(fl, unsigned_module)) { + if (is_session_rejected(fl, fl->is_unsigned_pd)) { err = -ECONNREFUSED; goto err; } @@ -1486,6 +1486,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, goto err_invoke; kfree(args); + fastrpc_map_put(map); return 0; @@ -1953,98 +1954,149 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) struct fastrpc_mmap_rsp_msg rsp_msg; struct fastrpc_phy_page pages; struct fastrpc_req_mmap req; + struct fastrpc_map *map = NULL; struct device *dev = fl->sctx->dev; int err; u32 sc; + unsigned long flags; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; - if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) { - dev_err(dev, "flag not supported 0x%x\n", req.flags); + if (req.flags == ADSP_MMAP_ADD_PAGES || req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) { + if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->is_unsigned_pd) { + dev_err(dev, "secure memory allocation is not supported in unsigned PD\n"); + return -EINVAL; + } + if (req.vaddrin && !fl->is_unsigned_pd) { + dev_err(dev, "adding user allocated pages is not supported\n"); + return -EINVAL; + } - return -EINVAL; - } + if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) + err = fastrpc_remote_heap_alloc(fl, dev, req.size, &buf); + else + err = fastrpc_buf_alloc(fl, dev, req.size, &buf); - if (req.vaddrin) { - dev_err(dev, "adding user allocated pages is not supported\n"); - return -EINVAL; - } + if (err) { + dev_err(dev, "failed to allocate buffer\n"); + return err; + } - if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) - err = fastrpc_remote_heap_alloc(fl, dev, req.size, &buf); - else - err = fastrpc_buf_alloc(fl, dev, req.size, &buf); + req_msg.pgid = fl->tgid; + req_msg.flags = req.flags; + req_msg.vaddr = req.vaddrin; + req_msg.num = sizeof(pages); - if (err) { - dev_err(dev, "failed to allocate buffer\n"); - return err; - } + args[0].ptr = (u64) (uintptr_t) &req_msg; + args[0].length = sizeof(req_msg); - req_msg.pgid = fl->tgid; - req_msg.flags = req.flags; - req_msg.vaddr = req.vaddrin; - req_msg.num = sizeof(pages); + pages.addr = buf->phys; + pages.size = buf->size; - args[0].ptr = (u64) (uintptr_t) &req_msg; - args[0].length = sizeof(req_msg); + args[1].ptr = (u64) (uintptr_t) &pages; + args[1].length = sizeof(pages); - pages.addr = buf->phys; - pages.size = buf->size; + args[2].ptr = (u64) (uintptr_t) &rsp_msg; + args[2].length = sizeof(rsp_msg); - args[1].ptr = (u64) (uintptr_t) &pages; - args[1].length = sizeof(pages); + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1); + err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, + &args[0]); + if (err) { + dev_err(dev, "mmap error (len 0x%08llx)\n", buf->size); + goto err_invoke; + } - args[2].ptr = (u64) (uintptr_t) &rsp_msg; - args[2].length = sizeof(rsp_msg); + /* update the buffer to be able to deallocate the memory on the DSP */ + buf->raddr = (uintptr_t) rsp_msg.vaddr; + buf->flag = req.flags; - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1); - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, - &args[0]); - if (err) { - dev_err(dev, "mmap error (len 0x%08llx)\n", buf->size); - goto err_invoke; - } + /* let the client know the address to use */ + req.vaddrout = rsp_msg.vaddr; - /* update the buffer to be able to deallocate the memory on the DSP */ - buf->raddr = (uintptr_t) rsp_msg.vaddr; - buf->flag = req.flags; + /* Add memory to static PD pool, protection thru hypervisor */ + if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { + err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, + &fl->cctx->perms, fl->cctx->vmperms, fl->cctx->vmcount); + if (err) { + dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", + buf->phys, buf->size, err); + goto err_assign; + } + } - /* let the client know the address to use */ - req.vaddrout = rsp_msg.vaddr; + if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) { + spin_lock_irqsave(&fl->cctx->lock, flags); + list_add_tail(&buf->node, &fl->cctx->rmaps); + spin_unlock_irqrestore(&fl->cctx->lock, flags); + } else { + spin_lock(&fl->lock); + list_add_tail(&buf->node, &fl->mmaps); + spin_unlock(&fl->lock); + } - /* Add memory to static PD pool, protection thru hypervisor */ - if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { - err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, - &fl->cctx->perms, fl->cctx->vmperms, fl->cctx->vmcount); - if (err) { - dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", - buf->phys, buf->size, err); + if (copy_to_user((void __user *)argp, &req, sizeof(req))) { + err = -EFAULT; goto err_assign; } - } + } else { + err = fastrpc_map_create(fl, req.fd, req.size, 0, &map); + if (err) { + dev_err(dev, "failed to map buffer, fd = %d\n", req.fd); + return err; + } - spin_lock(&fl->lock); - if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) - list_add_tail(&buf->node, &fl->cctx->rmaps); - else - list_add_tail(&buf->node, &fl->mmaps); - spin_unlock(&fl->lock); + req_msg.pgid = fl->tgid; + req_msg.flags = req.flags; + req_msg.vaddr = req.vaddrin; + req_msg.num = sizeof(pages); - if (copy_to_user((void __user *)argp, &req, sizeof(req))) { - err = -EFAULT; - goto err_assign; - } + args[0].ptr = (u64) (uintptr_t) &req_msg; + args[0].length = sizeof(req_msg); - dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n", - buf->raddr, buf->size); + pages.addr = map->phys; + pages.size = map->size; + args[1].ptr = (u64) (uintptr_t) &pages; + args[1].length = sizeof(pages); + + args[2].ptr = (u64) (uintptr_t) &rsp_msg; + args[2].length = sizeof(rsp_msg); + + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1); + + err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, + &args[0]); + if (err) { + dev_err(dev, "mmap error (len 0x%08llx)\n", map->size); + goto err_invoke; + } + + /* update the buffer to be able to deallocate the memory on the DSP */ + map->raddr = (uintptr_t) rsp_msg.vaddr; + + /* let the client know the address to use */ + req.vaddrout = rsp_msg.vaddr; + + if (copy_to_user((void __user *)argp, &req, sizeof(req))) { + err = -EFAULT; + goto err_assign; + } + } return 0; err_assign: - fastrpc_req_munmap_impl(fl, buf); + if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) + fastrpc_map_put(map); + else + fastrpc_req_munmap_impl(fl, buf); + err_invoke: - fastrpc_buf_free(buf); + if (map) + fastrpc_map_put(map); + if (buf) + fastrpc_buf_free(buf); return err; } From patchwork Fri Feb 2 06:40:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542146 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 5C3E41799E; Fri, 2 Feb 2024 06:40:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856061; cv=none; b=cOa9e1YLYHWGS3FaIX2+sbSS6iwoN+iE+88CkSKPLzNZJyUlmdCBjBtpIQuh4RXSSL9bVoeotGqJGbYv0AG5SBE0P0CvQzFZfCYvHn8SXRSOH9ZXCUcq6GQnhsGeM700XLcddt9dRS+h6GnIQAFE4uxdOw72xrrNw2PGOArYtmM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856061; c=relaxed/simple; bh=wv0RdXaPzOQFI/dSNphF2oKnr0c/b6g6w8ucASw1vZY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Y4kLbasWFwufU2OtyMRrKvqn7d2C12W1hRm6ROSta4yqAjcUX7RToeMSLVqF+N5PaiyuLxLFsb6xwxv0dlpPfWsgakQrjkx0fiouTOqbvBFqcgPCfFCEg85GX4hCsabPCOwAz/h7NmjwIw/6MXw/v7P/Ph34mP3N+Id65M70xFg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=BIT0YhsY; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="BIT0YhsY" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4121dIhb017196; Fri, 2 Feb 2024 06:40:57 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=yEjPmzOUm8KJS57P/SFd BTDisFXia25b4e5x+Agt1WY=; b=BIT0YhsY85iAvC7uonHNaIT4rrS9nURHI8hu ZefTtkJZR75rcLFcqfE13G1v1AmJtg7mvc4LJ1tv7ec8oQgxt/cGx+2irgJz3aEl 9hL4FhivZK6Ls8N38zAJ36/7F6AEz0Duz3mQbzmNGupv6TVbMRphMs0afGre8saM v1hZRg1YeAJ5wfFBg2hmDn62GVxA3o7gtGmu4vtGq+dVQqGxUd7fq5/3ytG29tsI EqJv8tTayAy9+WmSQGcXhtED7zLFdHtwZDkkWc5ctPtFlkdszCA4i87ntva/Hunc TbAAr+8bzQrgWhmml7vjS1J6HxRjJl12CcrOWqigusWzsWxuFA== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pwm0mr4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:40:57 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126eu54004518 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:40:56 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:40:54 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 03/16] misc: fastrpc: Add static PD restart support Date: Fri, 2 Feb 2024 12:10:26 +0530 Message-ID: <20240202064039.15505-4-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: V9sUXhK_gNHwGwXlLO0Xri5NkyzAcH_A X-Proofpoint-ORIG-GUID: V9sUXhK_gNHwGwXlLO0Xri5NkyzAcH_A X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 suspectscore=0 phishscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 bulkscore=0 adultscore=0 mlxscore=0 mlxlogscore=999 impostorscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Static PDs on the audio and sensor domains are expected to support PD restart. The kernel resource handling for the PDs are expected to be handled by fastrpc driver. For this, there is a requirement of PD service locator to get the event notifications for static PD services. Also when events are received, the driver needs to handle based on PD states. Added changes to add service locator for audio and sensor domain static PDs and handle the PD restart sequence. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 216 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 204 insertions(+), 12 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index bdce5469de19..e9b3b3b00aed 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -22,6 +22,7 @@ #include #include #include +#include #define ADSP_DOMAIN_ID (0) #define MDSP_DOMAIN_ID (1) @@ -29,6 +30,7 @@ #define CDSP_DOMAIN_ID (3) #define FASTRPC_DEV_MAX 4 /* adsp, mdsp, slpi, cdsp*/ #define FASTRPC_MAX_SESSIONS 14 +#define FASTRPC_MAX_SPD 4 #define FASTRPC_MAX_VMIDS 16 #define FASTRPC_ALIGN 128 #define FASTRPC_MAX_FDLIST 16 @@ -105,6 +107,18 @@ #define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev) +#define AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME "audio_pdr_adsp" +#define AUDIO_PDR_ADSP_SERVICE_NAME "avs/audio" +#define ADSP_AUDIOPD_NAME "msm/adsp/audio_pd" + +#define SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME "sensors_pdr_adsp" +#define SENSORS_PDR_ADSP_SERVICE_NAME "tms/servreg" +#define ADSP_SENSORPD_NAME "msm/adsp/sensor_pd" + +#define SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME "sensors_pdr_slpi" +#define SENSORS_PDR_SLPI_SERVICE_NAME SENSORS_PDR_ADSP_SERVICE_NAME +#define SLPI_SENSORPD_NAME "msm/slpi/sensor_pd" + static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp", "sdsp", "cdsp"}; struct fastrpc_phy_page { @@ -260,6 +274,16 @@ struct fastrpc_session_ctx { bool valid; }; +struct fastrpc_static_pd { + char *servloc_name; + char *spdname; + void *pdrhandle; + u64 pdrcount; + u64 prevpdrcount; + atomic_t ispdup; + struct fastrpc_channel_ctx *cctx; +}; + struct fastrpc_channel_ctx { int domain_id; int sesscount; @@ -268,6 +292,7 @@ struct fastrpc_channel_ctx { struct qcom_scm_vmperm vmperms[FASTRPC_MAX_VMIDS]; struct rpmsg_device *rpdev; struct fastrpc_session_ctx session[FASTRPC_MAX_SESSIONS]; + struct fastrpc_static_pd spd[FASTRPC_MAX_SPD]; spinlock_t lock; struct idr ctx_idr; struct list_head users; @@ -304,6 +329,7 @@ struct fastrpc_user { int pd; bool is_secure_dev; bool is_unsigned_pd; + char *servloc_name; /* Lock for lists */ spinlock_t lock; /* lock for allocations */ @@ -1256,6 +1282,41 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_channel_ctx *cctx) return 0; } +static int fastrpc_mmap_remove_pdr(struct fastrpc_user *fl) +{ + int i, err = 0, session = -1; + + if (!fl) + return -EBADF; + + for (i = 0; i < FASTRPC_MAX_SPD ; i++) { + if (!fl->cctx->spd[i].servloc_name) + continue; + if (!strcmp(fl->servloc_name, fl->cctx->spd[i].servloc_name)) { + session = i; + break; + } + } + + if (i >= FASTRPC_MAX_SPD) + return -EUSERS; + + if (atomic_read(&fl->cctx->spd[session].ispdup) == 0) + return -ENOTCONN; + + if (fl->cctx->spd[session].pdrcount != + fl->cctx->spd[session].prevpdrcount) { + err = fastrpc_mmap_remove_ssr(fl->cctx); + if (err) + dev_info(&fl->cctx->rpdev->dev, + "failed to unmap remote heap (err %d)\n", err); + fl->cctx->spd[session].prevpdrcount = + fl->cctx->spd[session].pdrcount; + } + + return err; +} + static int fastrpc_init_create_static_process(struct fastrpc_user *fl, char __user *argp) { @@ -1299,6 +1360,18 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, goto err_name; } + fl->servloc_name = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME; + + if (!strcmp(name, "audiopd")) { + /* + * Remove any previous mappings in case process is trying + * to reconnect after a PD restart on remote subsystem. + */ + err = fastrpc_mmap_remove_pdr(fl); + if (err) + goto err_name; + } + if (!fl->cctx->staticpd_status) { err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen, &buf); if (err) @@ -1688,6 +1761,12 @@ static int fastrpc_init_attach(struct fastrpc_user *fl, int pd) args[0].fd = -1; sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0); fl->pd = pd; + if (pd == SENSORS_PD) { + if (fl->cctx->domain_id == ADSP_DOMAIN_ID) + fl->servloc_name = SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME; + else if (fl->cctx->domain_id == SDSP_DOMAIN_ID) + fl->servloc_name = SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME; + } return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]); @@ -2281,6 +2360,72 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, return err; } +static void fastrpc_notify_users(struct fastrpc_user *user) +{ + struct fastrpc_invoke_ctx *ctx; + + spin_lock(&user->lock); + list_for_each_entry(ctx, &user->pending, node) { + ctx->retval = -EPIPE; + complete(&ctx->work); + } + spin_unlock(&user->lock); +} + +static void fastrpc_notify_pdr_drivers(struct fastrpc_channel_ctx *cctx, + char *servloc_name) +{ + struct fastrpc_user *fl; + unsigned long flags; + + spin_lock_irqsave(&cctx->lock, flags); + list_for_each_entry(fl, &cctx->users, user) { + if (fl->servloc_name && !strcmp(servloc_name, fl->servloc_name)) + fastrpc_notify_users(fl); + } + spin_unlock_irqrestore(&cctx->lock, flags); +} + +static void fastrpc_pdr_cb(int state, char *service_path, void *priv) +{ + struct fastrpc_static_pd *spd = (struct fastrpc_static_pd *)priv; + struct fastrpc_channel_ctx *cctx; + unsigned long flags; + + if (!spd) + return; + + cctx = spd->cctx; + switch (state) { + case SERVREG_SERVICE_STATE_DOWN: + dev_info(&cctx->rpdev->dev, + "%s: %s (%s) is down for PDR on %s\n", + __func__, spd->spdname, + spd->servloc_name, + domains[cctx->domain_id]); + spin_lock_irqsave(&cctx->lock, flags); + spd->pdrcount++; + atomic_set(&spd->ispdup, 0); + spin_unlock_irqrestore(&cctx->lock, flags); + if (!strcmp(spd->servloc_name, + AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME)) + cctx->staticpd_status = false; + + fastrpc_notify_pdr_drivers(cctx, spd->servloc_name); + break; + case SERVREG_SERVICE_STATE_UP: + dev_info(&cctx->rpdev->dev, + "%s: %s (%s) is up for PDR on %s\n", + __func__, spd->spdname, + spd->servloc_name, + domains[cctx->domain_id]); + atomic_set(&spd->ispdup, 1); + break; + default: + break; + } +} + static const struct file_operations fastrpc_fops = { .open = fastrpc_device_open, .release = fastrpc_device_release, @@ -2402,6 +2547,39 @@ static int fastrpc_device_register(struct device *dev, struct fastrpc_channel_ct return err; } +static int fastrpc_setup_service_locator(struct fastrpc_channel_ctx *cctx, char *client_name, + char *service_name, char *service_path, int domain, int spd_session) +{ + int err = 0; + struct pdr_handle *handle = NULL; + struct pdr_service *service = NULL; + + /* Register the service locator's callback function */ + handle = pdr_handle_alloc(fastrpc_pdr_cb, &cctx->spd[spd_session]); + if (IS_ERR(handle)) { + err = PTR_ERR(handle); + goto bail; + } + cctx->spd[spd_session].pdrhandle = handle; + cctx->spd[spd_session].servloc_name = client_name; + cctx->spd[spd_session].spdname = service_path; + cctx->spd[spd_session].cctx = cctx; + service = pdr_add_lookup(handle, service_name, service_path); + if (IS_ERR(service)) { + err = PTR_ERR(service); + goto bail; + } + pr_info("fastrpc: %s: pdr_add_lookup enabled for %s (%s, %s)\n", + __func__, service_name, client_name, service_path); + +bail: + if (err) { + pr_warn("fastrpc: %s: failed for %s (%s, %s)with err %d\n", + __func__, service_name, client_name, service_path, err); + } + return err; +} + static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) { struct device *rdev = &rpdev->dev; @@ -2481,6 +2659,25 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) goto fdev_error; } + if (domain_id == ADSP_DOMAIN_ID) { + err = fastrpc_setup_service_locator(data, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, + AUDIO_PDR_ADSP_SERVICE_NAME, ADSP_AUDIOPD_NAME, domain_id, 0); + if (err) + goto populate_error; + + err = fastrpc_setup_service_locator(data, + SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME, + SENSORS_PDR_ADSP_SERVICE_NAME, ADSP_SENSORPD_NAME, domain_id, 1); + if (err) + goto populate_error; + } else if (domain_id == SDSP_DOMAIN_ID) { + err = fastrpc_setup_service_locator(data, + SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME, + SENSORS_PDR_SLPI_SERVICE_NAME, SLPI_SENSORPD_NAME, domain_id, 0); + if (err) + goto populate_error; + } + kref_init(&data->refcount); dev_set_drvdata(&rpdev->dev, data); @@ -2510,18 +2707,6 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) return err; } -static void fastrpc_notify_users(struct fastrpc_user *user) -{ - struct fastrpc_invoke_ctx *ctx; - - spin_lock(&user->lock); - list_for_each_entry(ctx, &user->pending, node) { - ctx->retval = -EPIPE; - complete(&ctx->work); - } - spin_unlock(&user->lock); -} - static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) { struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev); @@ -2537,6 +2722,13 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) fastrpc_notify_users(user); spin_unlock_irqrestore(&cctx->lock, flags); + if (cctx->domain_id == ADSP_DOMAIN_ID) { + pdr_handle_release(cctx->spd[0].pdrhandle); + pdr_handle_release(cctx->spd[1].pdrhandle); + } else if (cctx->domain_id == SDSP_DOMAIN_ID) { + pdr_handle_release(cctx->spd[0].pdrhandle); + } + if (cctx->fdevice) misc_deregister(&cctx->fdevice->miscdev); From patchwork Fri Feb 2 06:40:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542147 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 87FD917BC4; Fri, 2 Feb 2024 06:41:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856063; cv=none; b=f0VxZs0klDxXGkBDD3t0cfN5WdeKueicLenArp8vmP6c+nSR9Uv1dkm/rlbG0H9+c/j4rx7/tMojz5OL0YUfV/lZN8tEQYrtSJbi/Y3vTLqCO/8KMhC0sTIFa3dnoJHj95Maevdy9eHwr2lF5rxJxAbi6j8RZrqkpUj12onAl6U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856063; c=relaxed/simple; bh=z8Hl4Row7jHBjKpjUgB/iPmEhZlIT54bqwO6dLRmvnA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IKriK/XirGgt6ijgm9JvfqhJpBckguAvyKzWU0y8GjWASKHCQsRuy7ACJ9OU7v/MUPJ4hloKNKzXy+WvK+BDXEbZun+ltbwSK0euUJuS+5BkjeBxOuy1MgvM24GWRisVEahWdX+fIgRa7kyXLsAw/Xp2O8XoePws6MWRZsBCXqo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=lgnjqB8u; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="lgnjqB8u" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4121WpWI016165; Fri, 2 Feb 2024 06:40:59 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=Sl3W08GaQhaM1wUGx42U K2YbK6VW2S43yYXRozc45pc=; b=lgnjqB8ugRoegAcwKB0xxljzbK3TB3aFVJO3 frYTTRdR8fmW536i6WK6Q+zKOmfBmoXd0wmzoa6QQ6oenvJNlhtzWoRkPqF7Jyft Tkzrgqsn110nspJyz/DTLnIGObWV+RtiCd0Y2A49lJl4T2RVFvFZaGon3E8dWapn c45DQKuubIuHZ2HMEUWUlpsZ9irAw9Zc5ouCMt7ExhBFTANZbVMOKgJXQ/KR6rs7 +p9X6pJtoPS8EmPJjET2LfNY2APAAH2dnbgPtYZHKDC218VWd00BdbecpQujBc1W nWnUbrwtAVoYbJlDL0mHYibHG2yGC/ewwIS8XdRXMZYUQ8V4cw== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pu00n2p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:40:59 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126ewgP014145 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:40:58 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:40:56 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 04/16] misc: fastrpc: Add fastrpc multimode invoke request support Date: Fri, 2 Feb 2024 12:10:27 +0530 Message-ID: <20240202064039.15505-5-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: ekeOz-716vevabMD4LsO6s20ESLzsJUV X-Proofpoint-ORIG-GUID: ekeOz-716vevabMD4LsO6s20ESLzsJUV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxscore=0 mlxlogscore=999 suspectscore=0 lowpriorityscore=0 impostorscore=0 bulkscore=0 clxscore=1015 adultscore=0 spamscore=0 priorityscore=1501 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Multimode invocation request is intended to support multiple different type of requests. This will include enhanced invoke request to support CRC check and performance counter enablement. This will also support few driver level user controllable mechanisms like usage of shared context banks, wakelock support, etc. This IOCTL is also added with the aim to support few new fastrpc features like DSP PD notification framework, DSP Signalling mechanism etc. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 176 ++++++++++++++++++++++++++---------- include/uapi/misc/fastrpc.h | 26 ++++++ 2 files changed, 154 insertions(+), 48 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index e9b3b3b00aed..a7e959beabd4 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -601,7 +601,7 @@ static void fastrpc_get_buff_overlaps(struct fastrpc_invoke_ctx *ctx) static struct fastrpc_invoke_ctx *fastrpc_context_alloc( struct fastrpc_user *user, u32 kernel, u32 sc, - struct fastrpc_invoke_args *args) + struct fastrpc_enhanced_invoke *invoke) { struct fastrpc_channel_ctx *cctx = user->cctx; struct fastrpc_invoke_ctx *ctx = NULL; @@ -632,7 +632,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( kfree(ctx); return ERR_PTR(-ENOMEM); } - ctx->args = args; + ctx->args = (struct fastrpc_invoke_args *)invoke->inv.args; fastrpc_get_buff_overlaps(ctx); } @@ -1163,11 +1163,11 @@ static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, } static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, - u32 handle, u32 sc, - struct fastrpc_invoke_args *args) + struct fastrpc_enhanced_invoke *invoke) { struct fastrpc_invoke_ctx *ctx = NULL; - + struct fastrpc_invoke *inv = &invoke->inv; + u32 handle, sc; int err = 0; if (!fl->sctx) @@ -1176,12 +1176,14 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, if (!fl->cctx->rpdev) return -EPIPE; + handle = inv->handle; + sc = inv->sc; if (handle == FASTRPC_INIT_HANDLE && !kernel) { dev_warn_ratelimited(fl->sctx->dev, "user app trying to send a kernel RPC message (%d)\n", handle); return -EPERM; } - ctx = fastrpc_context_alloc(fl, kernel, sc, args); + ctx = fastrpc_context_alloc(fl, kernel, sc, invoke); if (IS_ERR(ctx)) return PTR_ERR(ctx); @@ -1322,6 +1324,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, { struct fastrpc_init_create_static init; struct fastrpc_invoke_args *args; + struct fastrpc_enhanced_invoke ioctl; struct fastrpc_phy_page pages[1]; struct fastrpc_buf *buf = NULL; u64 phys = 0, size = 0; @@ -1333,7 +1336,6 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, u32 namelen; u32 pageslen; } inbuf; - u32 sc; args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL); if (!args) @@ -1417,10 +1419,11 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, args[2].length = sizeof(*pages); args[2].fd = -1; - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_STATIC, 3, 0); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_STATIC, 3, 0); + ioctl.inv.args = (u64)args; - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, - sc, args); + err = fastrpc_internal_invoke(fl, true, &ioctl); if (err) goto err_invoke; @@ -1463,6 +1466,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, { struct fastrpc_init_create init; struct fastrpc_invoke_args *args; + struct fastrpc_enhanced_invoke ioctl; struct fastrpc_phy_page pages[1]; struct fastrpc_map *map = NULL; struct fastrpc_buf *imem = NULL; @@ -1476,7 +1480,6 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, u32 attrs; u32 siglen; } inbuf; - u32 sc; args = kcalloc(FASTRPC_CREATE_PROCESS_NARGS, sizeof(*args), GFP_KERNEL); if (!args) @@ -1549,12 +1552,13 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, args[5].length = sizeof(inbuf.siglen); args[5].fd = -1; - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0); if (init.attrs) - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 4, 0); + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 4, 0); + ioctl.inv.args = (u64)args; - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, - sc, args); + err = fastrpc_internal_invoke(fl, true, &ioctl); if (err) goto err_invoke; @@ -1607,17 +1611,19 @@ static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx, static int fastrpc_release_current_dsp_process(struct fastrpc_user *fl) { struct fastrpc_invoke_args args[1]; + struct fastrpc_enhanced_invoke ioctl; int tgid = 0; - u32 sc; tgid = fl->tgid; args[0].ptr = (u64)(uintptr_t) &tgid; args[0].length = sizeof(tgid); args[0].fd = -1; - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0); - return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, - sc, &args[0]); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0); + ioctl.inv.args = (u64)args; + + return fastrpc_internal_invoke(fl, true, &ioctl); } static int fastrpc_device_release(struct inode *inode, struct file *file) @@ -1753,13 +1759,12 @@ static int fastrpc_dmabuf_alloc(struct fastrpc_user *fl, char __user *argp) static int fastrpc_init_attach(struct fastrpc_user *fl, int pd) { struct fastrpc_invoke_args args[1]; + struct fastrpc_enhanced_invoke ioctl; int tgid = fl->tgid; - u32 sc; args[0].ptr = (u64)(uintptr_t) &tgid; args[0].length = sizeof(tgid); args[0].fd = -1; - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0); fl->pd = pd; if (pd == SENSORS_PD) { if (fl->cctx->domain_id == ADSP_DOMAIN_ID) @@ -1768,13 +1773,17 @@ static int fastrpc_init_attach(struct fastrpc_user *fl, int pd) fl->servloc_name = SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME; } - return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, - sc, &args[0]); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0); + ioctl.inv.args = (u64)args; + + return fastrpc_internal_invoke(fl, true, &ioctl); } static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_invoke_args *args = NULL; + struct fastrpc_enhanced_invoke ioctl; struct fastrpc_invoke inv; u32 nscalars; int err; @@ -1796,16 +1805,70 @@ static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) } } - err = fastrpc_internal_invoke(fl, false, inv.handle, inv.sc, args); + ioctl.inv = inv; + ioctl.inv.args = (u64)args; + + err = fastrpc_internal_invoke(fl, false, &ioctl); kfree(args); return err; } +static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) +{ + struct fastrpc_enhanced_invoke einv; + struct fastrpc_invoke_args *args = NULL; + struct fastrpc_ioctl_multimode_invoke invoke; + u32 nscalars; + int err, i; + + if (copy_from_user(&invoke, argp, sizeof(invoke))) + return -EFAULT; + + for (i = 0; i < 8; i++) { + if (invoke.reserved[i] != 0) + return -EINVAL; + } + if (invoke.rsvd != 0) + return -EINVAL; + + switch (invoke.req) { + case FASTRPC_INVOKE: + /* nscalars is truncated here to max supported value */ + if (copy_from_user(&einv, (void __user *)(uintptr_t)invoke.invparam, + invoke.size)) + return -EFAULT; + for (i = 0; i < 8; i++) { + if (einv.reserved[i] != 0) + return -EINVAL; + } + nscalars = REMOTE_SCALARS_LENGTH(einv.inv.sc); + if (nscalars) { + args = kcalloc(nscalars, sizeof(*args), GFP_KERNEL); + if (!args) + return -ENOMEM; + if (copy_from_user(args, (void __user *)(uintptr_t)einv.inv.args, + nscalars * sizeof(*args))) { + kfree(args); + return -EFAULT; + } + } + einv.inv.args = (u64)args; + err = fastrpc_internal_invoke(fl, false, &einv); + kfree(args); + break; + default: + err = -ENOTTY; + break; + } + return err; +} + static int fastrpc_get_info_from_dsp(struct fastrpc_user *fl, uint32_t *dsp_attr_buf, uint32_t dsp_attr_buf_len) { struct fastrpc_invoke_args args[2] = { 0 }; + struct fastrpc_enhanced_invoke ioctl; /* Capability filled in userspace */ dsp_attr_buf[0] = 0; @@ -1818,8 +1881,11 @@ static int fastrpc_get_info_from_dsp(struct fastrpc_user *fl, uint32_t *dsp_attr args[1].fd = -1; fl->pd = USER_PD; - return fastrpc_internal_invoke(fl, true, FASTRPC_DSP_UTILITIES_HANDLE, - FASTRPC_SCALARS(0, 1, 1), args); + ioctl.inv.handle = FASTRPC_DSP_UTILITIES_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(0, 1, 1); + ioctl.inv.args = (u64)args; + + return fastrpc_internal_invoke(fl, true, &ioctl); } static int fastrpc_get_info_from_kernel(struct fastrpc_ioctl_capability *cap, @@ -1906,10 +1972,10 @@ static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp) static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *buf) { struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; + struct fastrpc_enhanced_invoke ioctl; struct fastrpc_munmap_req_msg req_msg; struct device *dev = fl->sctx->dev; int err; - u32 sc; req_msg.pgid = fl->tgid; req_msg.size = buf->size; @@ -1918,9 +1984,11 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf * args[0].ptr = (u64) (uintptr_t) &req_msg; args[0].length = sizeof(req_msg); - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MUNMAP, 1, 0); - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, - &args[0]); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MUNMAP, 1, 0); + ioctl.inv.args = (u64)args; + + err = fastrpc_internal_invoke(fl, true, &ioctl); if (!err) { if (buf->flag == ADSP_MMAP_REMOTE_HEAP_ADDR) { if (fl->cctx->vmcount) { @@ -1962,8 +2030,8 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp) struct fastrpc_map *map = NULL, *iterm, *m; struct device *dev = fl->sctx->dev; struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; + struct fastrpc_enhanced_invoke ioctl; int err = 0; - u32 sc; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; @@ -2014,9 +2082,10 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp) args[0].ptr = (u64) (uintptr_t) &req_msg; args[0].length = sizeof(req_msg); - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MUNMAP, 1, 0); - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, - &args[0]); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MUNMAP, 1, 0); + ioctl.inv.args = (u64)args; + err = fastrpc_internal_invoke(fl, true, &ioctl); if (err) dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n", map->fd, map->raddr); else @@ -2028,6 +2097,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp) static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_invoke_args args[3] = { [0 ... 2] = { 0 } }; + struct fastrpc_enhanced_invoke ioctl; struct fastrpc_buf *buf = NULL; struct fastrpc_mmap_req_msg req_msg; struct fastrpc_mmap_rsp_msg rsp_msg; @@ -2036,7 +2106,6 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) struct fastrpc_map *map = NULL; struct device *dev = fl->sctx->dev; int err; - u32 sc; unsigned long flags; if (copy_from_user(&req, argp, sizeof(req))) @@ -2079,9 +2148,11 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) args[2].ptr = (u64) (uintptr_t) &rsp_msg; args[2].length = sizeof(rsp_msg); - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1); - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, - &args[0]); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1); + ioctl.inv.args = (u64)args; + + err = fastrpc_internal_invoke(fl, true, &ioctl); if (err) { dev_err(dev, "mmap error (len 0x%08llx)\n", buf->size); goto err_invoke; @@ -2143,10 +2214,11 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) args[2].ptr = (u64) (uintptr_t) &rsp_msg; args[2].length = sizeof(rsp_msg); - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1); + ioctl.inv.args = (u64)args; - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, - &args[0]); + err = fastrpc_internal_invoke(fl, true, &ioctl); if (err) { dev_err(dev, "mmap error (len 0x%08llx)\n", map->size); goto err_invoke; @@ -2183,10 +2255,10 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_mem_unmap *req) { struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; + struct fastrpc_enhanced_invoke ioctl; struct fastrpc_map *map = NULL, *iter, *m; struct fastrpc_mem_unmap_req_msg req_msg = { 0 }; int err = 0; - u32 sc; struct device *dev = fl->sctx->dev; spin_lock(&fl->lock); @@ -2212,9 +2284,11 @@ static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_me args[0].ptr = (u64) (uintptr_t) &req_msg; args[0].length = sizeof(req_msg); - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_UNMAP, 1, 0); - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, - &args[0]); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_UNMAP, 1, 0); + ioctl.inv.args = (u64)args; + + err = fastrpc_internal_invoke(fl, true, &ioctl); if (err) { dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n", map->fd, map->raddr); return err; @@ -2237,6 +2311,7 @@ static int fastrpc_req_mem_unmap(struct fastrpc_user *fl, char __user *argp) static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_invoke_args args[4] = { [0 ... 3] = { 0 } }; + struct fastrpc_enhanced_invoke ioctl; struct fastrpc_mem_map_req_msg req_msg = { 0 }; struct fastrpc_mmap_rsp_msg rsp_msg = { 0 }; struct fastrpc_mem_unmap req_unmap = { 0 }; @@ -2245,7 +2320,6 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) struct device *dev = fl->sctx->dev; struct fastrpc_map *map = NULL; int err; - u32 sc; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; @@ -2281,8 +2355,11 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) args[3].ptr = (u64) (uintptr_t) &rsp_msg; args[3].length = sizeof(rsp_msg); - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_MAP, 3, 1); - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]); + ioctl.inv.handle = FASTRPC_INIT_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_MAP, 3, 1); + ioctl.inv.args = (u64)args; + + err = fastrpc_internal_invoke(fl, true, &ioctl); if (err) { dev_err(dev, "mem mmap error, fd %d, vaddr %llx, size %lld\n", req.fd, req.vaddrin, map->size); @@ -2322,6 +2399,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, case FASTRPC_IOCTL_INVOKE: err = fastrpc_invoke(fl, argp); break; + case FASTRPC_IOCTL_MULTIMODE_INVOKE: + err = fastrpc_multimode_invoke(fl, argp); + break; case FASTRPC_IOCTL_INIT_ATTACH: err = fastrpc_init_attach(fl, ROOT_PD); break; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index f33d914d8f46..45c15be1de58 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -16,6 +16,7 @@ #define FASTRPC_IOCTL_INIT_CREATE_STATIC _IOWR('R', 9, struct fastrpc_init_create_static) #define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map) #define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap) +#define FASTRPC_IOCTL_MULTIMODE_INVOKE _IOWR('R', 12, struct fastrpc_ioctl_multimode_invoke) #define FASTRPC_IOCTL_GET_DSP_INFO _IOWR('R', 13, struct fastrpc_ioctl_capability) /** @@ -80,6 +81,31 @@ struct fastrpc_invoke { __u64 args; }; +struct fastrpc_enhanced_invoke { + struct fastrpc_invoke inv; + __u64 crc; + __u64 perf_kernel; + __u64 perf_dsp; + __u32 reserved[8]; /* keeping reserved bits for new requirements */ +}; + +struct fastrpc_ioctl_multimode_invoke { + __u32 req; + __u32 rsvd; /* padding field */ + __u64 invparam; + __u64 size; + __u32 reserved[8]; /* keeping reserved bits for new requirements */ +}; + +enum fastrpc_multimode_invoke_type { + FASTRPC_INVOKE = 1, + FASTRPC_INVOKE_ENHANCED = 2, + FASTRPC_INVOKE_CONTROL = 3, + FASTRPC_INVOKE_DSPSIGNAL = 4, + FASTRPC_INVOKE_NOTIF = 5, + FASTRPC_INVOKE_MULTISESSION = 6, +}; + struct fastrpc_init_create { __u32 filelen; /* elf file length */ __s32 filefd; /* fd for the file */ From patchwork Fri Feb 2 06:40:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542148 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 E797E18026; Fri, 2 Feb 2024 06:41:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856065; cv=none; b=q6pDRFYc4345eTasuHNjVj4g7UWcmmtx9Zbp1YvU3QfLVAj04gaRbjNkTks5DQcfI3mwNUFs4/2J2IgYo1ZCzuOJhOD2Rx8b9hvO/2QEdaI3/sq5Qcxcyj1YV9GuMvTf9EpjhtxBpjpFjBT8r4Tx5k0qtpv9F/R4gA9UDFeR57A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856065; c=relaxed/simple; bh=UyzhH5dir1DGPXoMaktPym+zMHTmhgmj4z4SIuQ9gw4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Vo2F7rM6fTfUVi3Xk35SraUMU2e56Pb2JY/m3m/uKufL6BlUrJONV0zQIdIf3F4K71snENTXGCPdNxhQA4v6t4f78jumig3mD11YU9ccXull/bLTq4bnxd1O2TDvkZamG+PX3qvfMM4mn7Oz0hzueqDbOn4kvEvZHBnQ+70eQnQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=OUIOEuCO; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="OUIOEuCO" Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4124C2BA011810; Fri, 2 Feb 2024 06:41:01 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=i76Yi8m96sprBRJec6bt Nir7FxuxNQ50HS8A/sQSrag=; b=OUIOEuCOAEr8Jnl7X1qRIi9pTsskaJSuporr K4UtA9lqugR8+hHMuYetFSdgluqK7758fH2mVn6nEnLWtM1/OU2kVdhY8x5Ok9mL IWCVTy0zBCnhlXR5Z7YRRVps9p94yxZ+EIp3FZd6rDm5Wfp1+L8iQg7wyvCBkCTc 9JOB+2tHX7GBtSrOLVHHi8k+l8JKxPwNE4RmjV3cZDzs0sm82Yl2PNPiZzvo4fMx A1gBOYH5l5RjYiEuwYS728VBVD21aDK1+OjcZRaDlSqqsXp4ZdlOkj2mYG9Jnec1 YyySWj6fOt3L5AJU61gYfHG+csI2I1hccqikfeeXGsLIuR9a9g== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pu1rnd5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:01 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126f0Ql027239 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:00 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:40:58 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 05/16] misc: fastrpc: Add CRC support for remote buffers Date: Fri, 2 Feb 2024 12:10:28 +0530 Message-ID: <20240202064039.15505-6-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: WCSlZx4IKL-cxzVI0zBdT2URgac4Mnq3 X-Proofpoint-ORIG-GUID: WCSlZx4IKL-cxzVI0zBdT2URgac4Mnq3 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 mlxscore=0 impostorscore=0 clxscore=1015 mlxlogscore=999 malwarescore=0 lowpriorityscore=0 phishscore=0 priorityscore=1501 adultscore=0 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 CRC check for input and output argument helps in ensuring data consistency over a remote call. If user intends to enable CRC check, first local user CRC is calculated at user end and a CRC buffer is passed to DSP to capture remote CRC values. DSP is expected to write to the remote CRC buffer which is then compared at user level with the local CRC values. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index a7e959beabd4..a1b910459a90 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -639,6 +639,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( /* Released in fastrpc_context_put() */ fastrpc_channel_ctx_get(cctx); + ctx->crc = (u32 *)(uintptr_t)invoke->crc; ctx->sc = sc; ctx->retval = -1; ctx->pid = current->pid; @@ -1095,6 +1096,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, struct fastrpc_invoke_buf *list; struct fastrpc_phy_page *pages; u64 *fdlist; + u32 *crclist; int i, inbufs, outbufs, handles; inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); @@ -1102,7 +1104,8 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, handles = REMOTE_SCALARS_INHANDLES(ctx->sc) + REMOTE_SCALARS_OUTHANDLES(ctx->sc); list = fastrpc_invoke_buf_start(rpra, ctx->nscalars); pages = fastrpc_phy_page_start(list, ctx->nscalars); - fdlist = (uint64_t *)(pages + inbufs + outbufs + handles); + fdlist = (u64 *)(pages + inbufs + outbufs + handles); + crclist = (u32 *)(fdlist + FASTRPC_MAX_FDLIST); for (i = inbufs; i < ctx->nbufs; ++i) { if (!ctx->maps[i]) { @@ -1127,6 +1130,11 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, fastrpc_map_put(mmap); } + if (ctx->crc && crclist && rpra) { + if (copy_to_user((void __user *)ctx->crc, crclist, + FASTRPC_MAX_CRCLIST * sizeof(u32))) + return -EFAULT; + } return 0; } @@ -1834,6 +1842,7 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) switch (invoke.req) { case FASTRPC_INVOKE: + case FASTRPC_INVOKE_ENHANCED: /* nscalars is truncated here to max supported value */ if (copy_from_user(&einv, (void __user *)(uintptr_t)invoke.invparam, invoke.size)) From patchwork Fri Feb 2 06:40:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542149 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 E02821799F; Fri, 2 Feb 2024 06:41:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856067; cv=none; b=QFqhW8qhIzvVxIt21oUlihO+KFIXy3YpDrpyOdpw1Zuw9KDiLe/pdcr9/+rTk/zRS5PUGAxtlJ+b3Dp9s5MdsmxXVmVTfSytwo7LtzraNeO2yuhyNx8boswzPqovfuRXkO36BHLUAMolf5YXz/O18tDgD/0wbESqWMJn8YeX2Qw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856067; c=relaxed/simple; bh=e4GvRAWwK96yhzVq+gR2KS/40O1uNixKY6sanJMyQlQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=a1vaRCYNj7tl+WOgcBj6TV7kfJDZPeWSgDhReLqFflGtGd9XgOH8XRKA5lgxNqgWOfQyTpu8vmIEufEdlj117vSMBzqgZC8SYMmVXRgyRRuK8SvYiLUmTQZC5Vh+Eu4faIbnmOSlgldtFw6zFQQCpzq9v9hNvXRhorZoFEGV+m8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=d0cDRUzE; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="d0cDRUzE" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4121XeLo016772; Fri, 2 Feb 2024 06:41:03 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=N3Dv48xtfmlwAEC+/v+R dWKgQQYo/NY0vTk4yRTUSvs=; b=d0cDRUzEK/BDA1IdDhvy+3q0NQyZ4tdS2fWk ElQ38jBVVOO5ey0r1J/+VxySuerSh2Ly0arc77AqSwvTYsrQccXqMY1taCWzPcXX NT+LIvgw5rGGAQM35TjMab8RCHo3m9jxuFvkL0L6VfieCyWgz3ip8b5ARuNeV0Kj 6xLMDrAzAaQF+ysokBw5tPAF7w0MU2tEvxU6iiqTlAqXB23IvTs5PhxyahJv75Kt hfjs25dM+WFIn1VG0av3BJfcx41OgdGFgYXefWsV5ZBRB4JbGfbo9MuceewZTh5q gJ99jzuzglq3mQ37/TBdhJNmSN9g/8Qx4q3hG3tGavDZxdmCZw== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pu4gn9h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:03 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126f2gF027303 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:02 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:00 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 06/16] misc: fastrpc: Capture kernel and DSP performance counters Date: Fri, 2 Feb 2024 12:10:29 +0530 Message-ID: <20240202064039.15505-7-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: kSfhfFZkRobm2K2ew-rKWKo_rm277FNK X-Proofpoint-ORIG-GUID: kSfhfFZkRobm2K2ew-rKWKo_rm277FNK X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 impostorscore=0 mlxscore=0 malwarescore=0 phishscore=0 lowpriorityscore=0 mlxlogscore=999 clxscore=1015 bulkscore=0 spamscore=0 adultscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Add support to capture kernel performance counters for different kernel level operations. These counters collects the information for remote call and copies the information to a buffer shared by user. Collection of DSP performance counters is also added as part of this change. DSP updates the performance information in the metadata which is then copied to a buffer passed by the users. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 136 ++++++++++++++++++++++++++++++++++-- include/uapi/misc/fastrpc.h | 14 ++++ 2 files changed, 143 insertions(+), 7 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index a1b910459a90..33687d7f9a28 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,8 @@ #define FASTRPC_ALIGN 128 #define FASTRPC_MAX_FDLIST 16 #define FASTRPC_MAX_CRCLIST 64 +#define FASTRPC_KERNEL_PERF_LIST (PERF_KEY_MAX) +#define FASTRPC_DSP_PERF_LIST 12 #define FASTRPC_PHYS(p) ((p) & 0xffffffff) #define FASTRPC_CTX_MAX (256) #define FASTRPC_INIT_HANDLE 1 @@ -119,6 +122,27 @@ #define SENSORS_PDR_SLPI_SERVICE_NAME SENSORS_PDR_ADSP_SERVICE_NAME #define SLPI_SENSORPD_NAME "msm/slpi/sensor_pd" +#define PERF_END ((void)0) + +#define PERF(enb, cnt, ff) \ + {\ + struct timespec64 startT = {0};\ + uint64_t *counter = cnt;\ + if (enb && counter) {\ + ktime_get_real_ts64(&startT);\ + } \ + ff ;\ + if (enb && counter) {\ + *counter += getnstimediff(&startT);\ + } \ + } + +#define GET_COUNTER(perf_ptr, offset) \ + (perf_ptr != NULL ?\ + (((offset >= 0) && (offset < PERF_KEY_MAX)) ?\ + (uint64_t *)(perf_ptr + offset)\ + : (uint64_t *)NULL) : (uint64_t *)NULL) + static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp", "sdsp", "cdsp"}; struct fastrpc_phy_page { @@ -243,6 +267,19 @@ struct fastrpc_map { struct kref refcount; }; +struct fastrpc_perf { + u64 count; + u64 flush; + u64 map; + u64 copy; + u64 link; + u64 getargs; + u64 putargs; + u64 invargs; + u64 invoke; + u64 tid; +}; + struct fastrpc_invoke_ctx { int nscalars; int nbufs; @@ -251,6 +288,8 @@ struct fastrpc_invoke_ctx { int tgid; u32 sc; u32 *crc; + u64 *perf_kernel; + u64 *perf_dsp; u64 ctxid; u64 msg_sz; struct kref refcount; @@ -265,6 +304,7 @@ struct fastrpc_invoke_ctx { struct fastrpc_invoke_args *args; struct fastrpc_buf_overlap *olaps; struct fastrpc_channel_ctx *cctx; + struct fastrpc_perf *perf; }; struct fastrpc_session_ctx { @@ -325,6 +365,7 @@ struct fastrpc_user { struct fastrpc_session_ctx *sctx; struct fastrpc_buf *init_mem; + u32 profile; int tgid; int pd; bool is_secure_dev; @@ -336,6 +377,17 @@ struct fastrpc_user { struct mutex mutex; }; +static inline int64_t getnstimediff(struct timespec64 *start) +{ + int64_t ns; + struct timespec64 ts, b; + + ktime_get_real_ts64(&ts); + b = timespec64_sub(ts, *start); + ns = timespec64_to_ns(&b); + return ns; +} + static void fastrpc_free_map(struct kref *ref) { struct fastrpc_map *map; @@ -521,6 +573,9 @@ static void fastrpc_context_free(struct kref *ref) if (ctx->buf) fastrpc_buf_free(ctx->buf); + if (ctx->fl->profile) + kfree(ctx->perf); + spin_lock_irqsave(&cctx->lock, flags); idr_remove(&cctx->ctx_idr, ctx->ctxid >> 4); spin_unlock_irqrestore(&cctx->lock, flags); @@ -640,6 +695,14 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( fastrpc_channel_ctx_get(cctx); ctx->crc = (u32 *)(uintptr_t)invoke->crc; + ctx->perf_dsp = (u64 *)(uintptr_t)invoke->perf_dsp; + ctx->perf_kernel = (u64 *)(uintptr_t)invoke->perf_kernel; + if (ctx->fl->profile) { + ctx->perf = kzalloc(sizeof(*(ctx->perf)), GFP_KERNEL); + if (!ctx->perf) + return ERR_PTR(-ENOMEM); + ctx->perf->tid = ctx->fl->tgid; + } ctx->sc = sc; ctx->retval = -1; ctx->pid = current->pid; @@ -903,7 +966,8 @@ static int fastrpc_get_meta_size(struct fastrpc_invoke_ctx *ctx) sizeof(struct fastrpc_invoke_buf) + sizeof(struct fastrpc_phy_page)) * ctx->nscalars + sizeof(u64) * FASTRPC_MAX_FDLIST + - sizeof(u32) * FASTRPC_MAX_CRCLIST; + sizeof(u32) * FASTRPC_MAX_CRCLIST + + sizeof(u32) + sizeof(u64) * FASTRPC_DSP_PERF_LIST; return size; } @@ -970,16 +1034,22 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) int inbufs, i, oix, err = 0; u64 len, rlen, pkt_size; u64 pg_start, pg_end; + u64 *perf_counter = NULL; uintptr_t args; int metalen; + if (ctx->fl->profile) + perf_counter = (u64 *)ctx->perf + PERF_COUNT; + inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); metalen = fastrpc_get_meta_size(ctx); pkt_size = fastrpc_get_payload_size(ctx, metalen); + PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP), err = fastrpc_create_maps(ctx); if (err) return err; + PERF_END); ctx->msg_sz = pkt_size; @@ -1012,6 +1082,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) if (ctx->maps[i]) { struct vm_area_struct *vma = NULL; + PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP), rpra[i].buf.pv = (u64) ctx->args[i].ptr; pages[i].addr = ctx->maps[i]->phys; @@ -1026,9 +1097,9 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) pg_end = ((ctx->args[i].ptr + len - 1) & PAGE_MASK) >> PAGE_SHIFT; pages[i].size = (pg_end - pg_start + 1) * PAGE_SIZE; - + PERF_END); } else { - + PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_COPY), if (ctx->olaps[oix].offset == 0) { rlen -= ALIGN(args, FASTRPC_ALIGN) - args; args = ALIGN(args, FASTRPC_ALIGN); @@ -1050,12 +1121,14 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) pages[i].size = (pg_end - pg_start + 1) * PAGE_SIZE; args = args + mlen; rlen -= mlen; + PERF_END); } if (i < inbufs && !ctx->maps[i]) { void *dst = (void *)(uintptr_t)rpra[i].buf.pv; void *src = (void *)(uintptr_t)ctx->args[i].ptr; + PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_COPY), if (!kernel) { if (copy_from_user(dst, (void __user *)src, len)) { @@ -1065,6 +1138,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) } else { memcpy(dst, src, len); } + PERF_END); } } @@ -1095,9 +1169,9 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, struct fastrpc_map *mmap = NULL; struct fastrpc_invoke_buf *list; struct fastrpc_phy_page *pages; - u64 *fdlist; - u32 *crclist; - int i, inbufs, outbufs, handles; + u64 *fdlist, *perf_dsp_list; + u32 *crclist, *poll; + int i, inbufs, outbufs, handles, perferr; inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc); @@ -1106,6 +1180,8 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, pages = fastrpc_phy_page_start(list, ctx->nscalars); fdlist = (u64 *)(pages + inbufs + outbufs + handles); crclist = (u32 *)(fdlist + FASTRPC_MAX_FDLIST); + poll = (u32 *)(crclist + FASTRPC_MAX_CRCLIST); + perf_dsp_list = (u64 *)(poll + 1); for (i = inbufs; i < ctx->nbufs; ++i) { if (!ctx->maps[i]) { @@ -1135,6 +1211,12 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, FASTRPC_MAX_CRCLIST * sizeof(u32))) return -EFAULT; } + if (ctx->perf_dsp && perf_dsp_list) { + perferr = copy_to_user((void __user *)ctx->perf_dsp, + perf_dsp_list, FASTRPC_DSP_PERF_LIST * sizeof(u64)); + if (perferr) + dev_info(fl->sctx->dev, "Warning: failed to copy perf data %d\n", perferr); + } return 0; } @@ -1170,13 +1252,32 @@ static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, } +static void fastrpc_update_invoke_count(u32 handle, u64 *perf_counter, + struct timespec64 *invoket) +{ + u64 *invcount, *count; + + invcount = GET_COUNTER(perf_counter, PERF_INVOKE); + if (invcount) + *invcount += getnstimediff(invoket); + + count = GET_COUNTER(perf_counter, PERF_COUNT); + if (count) + *count += 1; +} + static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, struct fastrpc_enhanced_invoke *invoke) { struct fastrpc_invoke_ctx *ctx = NULL; struct fastrpc_invoke *inv = &invoke->inv; u32 handle, sc; - int err = 0; + u64 *perf_counter = NULL; + int err = 0, perferr = 0; + struct timespec64 invoket = {0}; + + if (fl->profile) + ktime_get_real_ts64(&invoket); if (!fl->sctx) return -EINVAL; @@ -1195,16 +1296,22 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, if (IS_ERR(ctx)) return PTR_ERR(ctx); + if (fl->profile) + perf_counter = (u64 *)ctx->perf + PERF_COUNT; + PERF(fl->profile, GET_COUNTER(perf_counter, PERF_GETARGS), err = fastrpc_get_args(kernel, ctx); if (err) goto bail; + PERF_END); /* make sure that all CPU memory writes are seen by DSP */ dma_wmb(); + PERF(fl->profile, GET_COUNTER(perf_counter, PERF_LINK), /* Send invoke buffer to remote dsp */ err = fastrpc_invoke_send(fl->sctx, ctx, kernel, handle); if (err) goto bail; + PERF_END); if (kernel) { if (!wait_for_completion_timeout(&ctx->work, 10 * HZ)) @@ -1218,10 +1325,12 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, /* make sure that all memory writes by DSP are seen by CPU */ dma_rmb(); + PERF(fl->profile, GET_COUNTER(perf_counter, PERF_PUTARGS), /* populate all the output buffers with results */ err = fastrpc_put_args(ctx, kernel); if (err) goto bail; + PERF_END); /* Check the response from remote dsp */ err = ctx->retval; @@ -1235,6 +1344,15 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, list_del(&ctx->node); spin_unlock(&fl->lock); fastrpc_context_put(ctx); + } else if (ctx) { + if (fl->profile && !err) + fastrpc_update_invoke_count(handle, perf_counter, &invoket); + if (fl->profile && ctx->perf && ctx->perf_kernel) { + perferr = copy_to_user((void __user *)ctx->perf_kernel, + ctx->perf, FASTRPC_KERNEL_PERF_LIST * sizeof(u64)); + if (perferr) + dev_info(fl->sctx->dev, "Warning: failed to copy perf data %d\n", perferr); + } } if (err) @@ -1828,6 +1946,7 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) struct fastrpc_invoke_args *args = NULL; struct fastrpc_ioctl_multimode_invoke invoke; u32 nscalars; + u64 *perf_kernel; int err, i; if (copy_from_user(&invoke, argp, sizeof(invoke))) @@ -1862,6 +1981,9 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) return -EFAULT; } } + perf_kernel = (u64 *)(uintptr_t)einv.perf_kernel; + if (perf_kernel) + fl->profile = true; einv.inv.args = (u64)args; err = fastrpc_internal_invoke(fl, false, &einv); kfree(args); diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index 45c15be1de58..559a3aea85b9 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -166,4 +166,18 @@ struct fastrpc_ioctl_capability { __u32 reserved[4]; }; +enum fastrpc_perfkeys { + PERF_COUNT = 0, + PERF_FLUSH = 1, + PERF_MAP = 2, + PERF_COPY = 3, + PERF_LINK = 4, + PERF_GETARGS = 5, + PERF_PUTARGS = 6, + PERF_INVARGS = 7, + PERF_INVOKE = 8, + PERF_TID = 9, + PERF_KEY_MAX = 10, +}; + #endif /* __QCOM_FASTRPC_H__ */ From patchwork Fri Feb 2 06:40:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542150 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 10612182C5; Fri, 2 Feb 2024 06:41:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856069; cv=none; b=Fdy3Mzl88MFiTKHSmrlsEYHAcL+fx2qQfCtuN1ucdy21E8H8LGFlTbAbOXX8pCj7UXh4ahlD4JKM6/P0Xhhf0cRAb4LYMkI3akJZeyy43gVSeUcjOdkqYwCiRZ/NeylHtJ8i5UDgewd3BPURlgnYN0o+FPZhpxBpIVHqF3FR274= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856069; c=relaxed/simple; bh=rWI9e2DBhsoZBuc6IiXSA/pVRd/KzaC9Fd3vD/Srqnk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Vz5m01WXE3197tO+F8gPtMkNOVYNv5SUYtvMbmMH6zneF3F+sZSjrysRykcJ2alFZPv1iwVJhjj39eB8kY0DVb308fVluAFtpj8o8zQa+TrGWpRZKfkZBMBehp8w/vjPdSBKuTBDGdwO9rD0jBLahgOaLSPaIRVtRkjVne95ySY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=HwIbOlln; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="HwIbOlln" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41256WXW024813; Fri, 2 Feb 2024 06:41:06 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=rtQEAGVD2KwsUx1lAIcO Ah9wMAKg3iWfDCz1mhH+fBE=; b=HwIbOlln5+5kfNlVSSjzwXkk0C4hjuVKvk64 LT+w/VhFIVZLsj57OFUTKlZP+CsyIBsE/VWMOGr3IgQmkLmVJHzBTD7t+9ou44Re jUsiJ7t6o+P5TmJ7A6l51N31K9hbxE5MLWaVCKELIeeHb6WqhFRA9wLLsWhnCl8V I0sw50VfZswBeYSvkE1f8O90axTOUToFHdY5uQ02MCoNYUkno6+eSD7KCyxfpAJZ vu5hSEu8lrMkczF9YjAGsQv/tosdgEzbbHdTJ7P2EiXIQPZIHdEFWbHVRrvY42XW DafDipnllKcajj9RPnTWUYzhnFxYAhEd6qAbjK2ZJKSZa8pggQ== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0ptw8nd5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:05 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126f4IY014264 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:04 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:02 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 07/16] misc: fastrpc: Add support to save and restore interrupted Date: Fri, 2 Feb 2024 12:10:30 +0530 Message-ID: <20240202064039.15505-8-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: yzZLk49h6HHm_O9by3JREjYyyYMSj_oX X-Proofpoint-GUID: yzZLk49h6HHm_O9by3JREjYyyYMSj_oX X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 bulkscore=0 malwarescore=0 mlxscore=0 lowpriorityscore=0 phishscore=0 clxscore=1015 mlxlogscore=999 adultscore=0 impostorscore=0 suspectscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 For any remote call, driver sends a message to DSP using RPMSG framework. After message is sent, there is a wait on a completion object at driver which is completed when DSP response is received. There is a possibility that a signal is received while waiting causing the wait function to return -ERESTARTSYS. In this case the context should be saved and it should get restored for the next invocation for the thread. Adding changes to support saving and restoring of interrupted fastrpc contexts. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 83 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 33687d7f9a28..88f065e78bc2 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -359,6 +359,7 @@ struct fastrpc_user { struct list_head user; struct list_head maps; struct list_head pending; + struct list_head interrupted; struct list_head mmaps; struct fastrpc_channel_ctx *cctx; @@ -740,6 +741,40 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( return ERR_PTR(ret); } +static struct fastrpc_invoke_ctx *fastrpc_context_restore_interrupted( + struct fastrpc_user *fl, struct fastrpc_invoke *inv) +{ + struct fastrpc_invoke_ctx *ctx = NULL, *ictx = NULL, *n; + + spin_lock(&fl->lock); + list_for_each_entry_safe(ictx, n, &fl->interrupted, node) { + if (ictx->pid == current->pid) { + if (inv->sc != ictx->sc || ictx->fl != fl) { + dev_err(ictx->fl->sctx->dev, + "interrupted sc (0x%x) or fl (%pK) does not match with invoke sc (0x%x) or fl (%pK)\n", + ictx->sc, ictx->fl, inv->sc, fl); + spin_unlock(&fl->lock); + return ERR_PTR(-EINVAL); + } + ctx = ictx; + list_del(&ctx->node); + list_add_tail(&ctx->node, &fl->pending); + break; + } + } + spin_unlock(&fl->lock); + return ctx; +} + +static void fastrpc_context_save_interrupted( + struct fastrpc_invoke_ctx *ctx) +{ + spin_lock(&ctx->fl->lock); + list_del(&ctx->node); + list_add_tail(&ctx->node, &ctx->fl->interrupted); + spin_unlock(&ctx->fl->lock); +} + static struct sg_table * fastrpc_map_dma_buf(struct dma_buf_attachment *attachment, enum dma_data_direction dir) @@ -1292,6 +1327,14 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, return -EPERM; } + if (!kernel) { + ctx = fastrpc_context_restore_interrupted(fl, inv); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + if (ctx) + goto wait; + } + ctx = fastrpc_context_alloc(fl, kernel, sc, invoke); if (IS_ERR(ctx)) return PTR_ERR(ctx); @@ -1313,6 +1356,7 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, goto bail; PERF_END); +wait: if (kernel) { if (!wait_for_completion_timeout(&ctx->work, 10 * HZ)) err = -ETIMEDOUT; @@ -1338,12 +1382,9 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, goto bail; bail: - if (err != -ERESTARTSYS && err != -ETIMEDOUT) { - /* We are done with this compute context */ - spin_lock(&fl->lock); - list_del(&ctx->node); - spin_unlock(&fl->lock); - fastrpc_context_put(ctx); + if (err == -ERESTARTSYS) { + if (ctx) + fastrpc_context_save_interrupted(ctx); } else if (ctx) { if (fl->profile && !err) fastrpc_update_invoke_count(handle, perf_counter, &invoket); @@ -1353,6 +1394,10 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, if (perferr) dev_info(fl->sctx->dev, "Warning: failed to copy perf data %d\n", perferr); } + spin_lock(&fl->lock); + list_del(&ctx->node); + spin_unlock(&fl->lock); + fastrpc_context_put(ctx); } if (err) @@ -1734,6 +1779,25 @@ static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx, spin_unlock_irqrestore(&cctx->lock, flags); } +static void fastrpc_context_list_free(struct fastrpc_user *fl) +{ + struct fastrpc_invoke_ctx *ctx, *n; + + list_for_each_entry_safe(ctx, n, &fl->interrupted, node) { + spin_lock(&fl->lock); + list_del(&ctx->node); + spin_unlock(&fl->lock); + fastrpc_context_put(ctx); + } + + list_for_each_entry_safe(ctx, n, &fl->pending, node) { + spin_lock(&fl->lock); + list_del(&ctx->node); + spin_unlock(&fl->lock); + fastrpc_context_put(ctx); + } +} + static int fastrpc_release_current_dsp_process(struct fastrpc_user *fl) { struct fastrpc_invoke_args args[1]; @@ -1756,7 +1820,6 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) { struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data; struct fastrpc_channel_ctx *cctx = fl->cctx; - struct fastrpc_invoke_ctx *ctx, *n; struct fastrpc_map *map, *m; struct fastrpc_buf *buf, *b; unsigned long flags; @@ -1770,10 +1833,7 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) if (fl->init_mem) fastrpc_buf_free(fl->init_mem); - list_for_each_entry_safe(ctx, n, &fl->pending, node) { - list_del(&ctx->node); - fastrpc_context_put(ctx); - } + fastrpc_context_list_free(fl); list_for_each_entry_safe(map, m, &fl->maps, node) fastrpc_map_put(map); @@ -1814,6 +1874,7 @@ static int fastrpc_device_open(struct inode *inode, struct 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); From patchwork Fri Feb 2 06:40:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542151 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 B468618643; Fri, 2 Feb 2024 06:41:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856071; cv=none; b=e7FjeLU8C0hZA69sKlrIw19vjMhn9EHL9NzpJ4Im98Z5ZYBL5zukW3ynAgQMLsZ6YXyZSsf+3ttrz1GcRjJgoXsuq3ezkPGE+Tq29/6w2zni7hiqWPG5S7KQw2YPquzNwx6PHpanFk9nJHxaCCjhhPDjSRAybLei+5i1gg69JKk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856071; c=relaxed/simple; bh=O3ZlBs2M/gymncReU73N8tFP0+d/YXl/Z1mBNb1xC4s=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gBdE678I5dAK7MtdCPK5T6OWVYtH/E+buB8eh6iK+kkGKZ+zUzowTmKwYvX33m0dG9AbrX5YfVKDSVdsCWQjJGKWqxiGT7yfvTHhYtepBcTeci2rQEdELGglA6+TPuT9jSuh9x13x7235NQ1eRLOA5l1wO66cqQ+Vn6sVED1Ne4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=nPYKcRPO; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="nPYKcRPO" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4123e9Ea013493; Fri, 2 Feb 2024 06:41:08 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=4Wwnw63uGnopclSZhO2/ bG9bPOdkqKSvCNvqNY3G/TY=; b=nPYKcRPODkYCRwCvleI3BMQtGlh3TwARNOzL 3D1d61P/FSGzScuUbu6DZC41/Xs2OoJdCvs6CEJxsfKR5MbKGDCUq96ZKmbIp/OT GtmObR9LVo7VKwXJwoA3cIsmpzCC51ERqJYCaPKY9ycd1S0RMGUSThYj8XqUTURn dqhVfvRwB/qmfpcyL+i76SHdkNkKRoeBif315huCKxQcRzUMsn8ahJtlIi5cgcSP Wz1eiDWn23+N9IHbseoWUxlu2OYibJwN3wmzyP0ZpQWoXrQC3dWc5WEjnxhbtkWT 2HXrsMr9hDUN8F8q7T12N52/TManpjnKtf6keYA0KKBq6Xb6pw== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pu4gn9n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:07 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126f6KC014282 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:06 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:05 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 08/16] misc: fastrpc: Add support to allocate shared context bank Date: Fri, 2 Feb 2024 12:10:31 +0530 Message-ID: <20240202064039.15505-9-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: OIbYSNkpy2iFAfFdD-q9ESj2m-J2th9Z X-Proofpoint-ORIG-GUID: OIbYSNkpy2iFAfFdD-q9ESj2m-J2th9Z X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 impostorscore=0 mlxscore=0 malwarescore=0 phishscore=0 lowpriorityscore=0 mlxlogscore=999 clxscore=1015 bulkscore=0 spamscore=0 adultscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Context banks could be set as a shared one using a DT propery "qcom,nsessions". The property takes the number of session to be created of the context bank. This change provides a control mechanism for user to use shared context banks for light weight processes. The session is set as shared while its creation and if a user requests for shared context bank, the same will be allocated during process initialization. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 117 ++++++++++++++++++++++++------------ include/uapi/misc/fastrpc.h | 21 +++++++ 2 files changed, 99 insertions(+), 39 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 88f065e78bc2..9f67cfbc0222 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -312,6 +312,7 @@ struct fastrpc_session_ctx { int sid; bool used; bool valid; + bool sharedcb; }; struct fastrpc_static_pd { @@ -371,6 +372,7 @@ struct fastrpc_user { int pd; bool is_secure_dev; bool is_unsigned_pd; + bool sharedcb; char *servloc_name; /* Lock for lists */ spinlock_t lock; @@ -879,6 +881,37 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = { .release = fastrpc_release, }; +static struct fastrpc_session_ctx *fastrpc_session_alloc( + struct fastrpc_channel_ctx *cctx, bool sharedcb) +{ + struct fastrpc_session_ctx *session = NULL; + unsigned long flags; + int i; + + spin_lock_irqsave(&cctx->lock, flags); + for (i = 0; i < cctx->sesscount; i++) { + if (!cctx->session[i].used && cctx->session[i].valid && + cctx->session[i].sharedcb == sharedcb) { + cctx->session[i].used = true; + session = &cctx->session[i]; + break; + } + } + spin_unlock_irqrestore(&cctx->lock, flags); + + return session; +} + +static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx, + struct fastrpc_session_ctx *session) +{ + unsigned long flags; + + spin_lock_irqsave(&cctx->lock, flags); + session->used = false; + spin_unlock_irqrestore(&cctx->lock, flags); +} + static int fastrpc_map_create(struct fastrpc_user *fl, int fd, u64 len, u32 attr, struct fastrpc_map **ppmap) { @@ -1545,6 +1578,12 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, goto err_name; } + fl->sctx = fastrpc_session_alloc(fl->cctx, fl->sharedcb); + if (!fl->sctx) { + err = -EBUSY; + goto err_name; + } + if (!fl->cctx->staticpd_status) { err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen, &buf); if (err) @@ -1674,6 +1713,12 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, goto err; } + fl->sctx = fastrpc_session_alloc(fl->cctx, fl->sharedcb); + if (!fl->sctx) { + err = -EBUSY; + goto err; + } + inbuf.pgid = fl->tgid; inbuf.namelen = strlen(current->comm) + 1; inbuf.filelen = init.filelen; @@ -1749,36 +1794,6 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, return err; } -static struct fastrpc_session_ctx *fastrpc_session_alloc( - struct fastrpc_channel_ctx *cctx) -{ - struct fastrpc_session_ctx *session = NULL; - unsigned long flags; - int i; - - spin_lock_irqsave(&cctx->lock, flags); - for (i = 0; i < cctx->sesscount; i++) { - if (!cctx->session[i].used && cctx->session[i].valid) { - cctx->session[i].used = true; - session = &cctx->session[i]; - break; - } - } - spin_unlock_irqrestore(&cctx->lock, flags); - - return session; -} - -static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx, - struct fastrpc_session_ctx *session) -{ - unsigned long flags; - - spin_lock_irqsave(&cctx->lock, flags); - session->used = false; - spin_unlock_irqrestore(&cctx->lock, flags); -} - static void fastrpc_context_list_free(struct fastrpc_user *fl) { struct fastrpc_invoke_ctx *ctx, *n; @@ -1882,15 +1897,6 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->cctx = cctx; fl->is_secure_dev = fdevice->secure; - fl->sctx = fastrpc_session_alloc(cctx); - if (!fl->sctx) { - dev_err(&cctx->rpdev->dev, "No session available\n"); - mutex_destroy(&fl->mutex); - kfree(fl); - - return -EBUSY; - } - spin_lock_irqsave(&cctx->lock, flags); list_add_tail(&fl->user, &cctx->users); spin_unlock_irqrestore(&cctx->lock, flags); @@ -1949,6 +1955,10 @@ static int fastrpc_init_attach(struct fastrpc_user *fl, int pd) struct fastrpc_enhanced_invoke ioctl; int tgid = fl->tgid; + fl->sctx = fastrpc_session_alloc(fl->cctx, fl->sharedcb); + if (!fl->sctx) + return -EBUSY; + args[0].ptr = (u64)(uintptr_t) &tgid; args[0].length = sizeof(tgid); args[0].fd = -1; @@ -2001,11 +2011,33 @@ static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) return err; } +static int fastrpc_internal_control(struct fastrpc_user *fl, + struct fastrpc_internal_control *cp) +{ + int err = 0; + + if (!fl) + return -EBADF; + if (!cp) + return -EINVAL; + + switch (cp->req) { + case FASTRPC_CONTROL_SMMU: + fl->sharedcb = cp->smmu.sharedcb; + break; + default: + err = -EBADRQC; + break; + } + return err; +} + static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_enhanced_invoke einv; struct fastrpc_invoke_args *args = NULL; struct fastrpc_ioctl_multimode_invoke invoke; + struct fastrpc_internal_control cp = {0}; u32 nscalars; u64 *perf_kernel; int err, i; @@ -2049,6 +2081,12 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) err = fastrpc_internal_invoke(fl, false, &einv); kfree(args); break; + case FASTRPC_INVOKE_CONTROL: + if (copy_from_user(&cp, (void __user *)(uintptr_t)invoke.invparam, sizeof(cp))) + return -EFAULT; + + err = fastrpc_internal_control(fl, &cp); + break; default: err = -ENOTTY; break; @@ -2738,6 +2776,7 @@ static int fastrpc_cb_probe(struct platform_device *pdev) if (sessions > 0) { struct fastrpc_session_ctx *dup_sess; + sess->sharedcb = true; for (i = 1; i < sessions; i++) { if (cctx->sesscount >= FASTRPC_MAX_SESSIONS) break; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index 559a3aea85b9..d29188e43b21 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -166,6 +166,27 @@ struct fastrpc_ioctl_capability { __u32 reserved[4]; }; +enum fastrpc_control_type { + FASTRPC_CONTROL_LATENCY = 1, + FASTRPC_CONTROL_SMMU = 2, + FASTRPC_CONTROL_KALLOC = 3, + FASTRPC_CONTROL_WAKELOCK = 4, + FASTRPC_CONTROL_PM = 5, + FASTRPC_CONTROL_DSPPROCESS_CLEAN = 6, + FASTRPC_CONTROL_RPC_POLL = 7, + FASTRPC_CONTROL_ASYNC_WAKE = 8, + FASTRPC_CONTROL_NOTIF_WAKE = 9, +}; + +struct fastrpc_ctrl_smmu { + u32 sharedcb; /* Set to SMMU share context bank */ +}; + +struct fastrpc_internal_control { + u32 req; + struct fastrpc_ctrl_smmu smmu; +}; + enum fastrpc_perfkeys { PERF_COUNT = 0, PERF_FLUSH = 1, From patchwork Fri Feb 2 06:40:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542152 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 2406B18E20; Fri, 2 Feb 2024 06:41:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856074; cv=none; b=MzVI7ytc+QwQi41xVb334psosejI9GYVbR5ZSam8Lpye94RTxjVdEQVM3hRqJljsbW5XcgZRV2/gdfAov2gNHc6NwIpoO5yz6MtnzIGqIud4warPl98Ld6Eiv8jUqwdqhZAC+0xWpdhCmh45thoSykrlIyrGjBih0dhjIu2ERVY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856074; c=relaxed/simple; bh=4B9Ns6TsZjVKi9CwB+d9xAswYYoNPECimUxLdYg5rhU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tUxrELfcFWAO5+yNFmmU+wQ9vFHDI9nHM2Cqa+8p1mlDKchNKA9eYLTYFAWQDcspEtb6dLUE09QBAan1zNX75iX7RNW6cGurC2fbS2Ez0xmp9RjnDCf/H/DgT/MXVB67Ep+R7k7RsivSbqWP2mUGGQJfUYO+IZ+SUcFBoEhNGi0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=Pb8Pnu4t; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="Pb8Pnu4t" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4124UfDn001619; Fri, 2 Feb 2024 06:41:10 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=3QpRhw1cE6x/zr+zQ2qt AXOixpxYsDMJLq6tAH40KCU=; b=Pb8Pnu4teQ2zYtCMI0X5SVBpAg2zDbZ1ovWW 3nklIgfIlx+Tl16VLwk5EMLZ0yWRdK3kvO3gPGQjLYxvfInKAnKSE5rojJPaKTU6 BXoDgBne4wH4i+bgAVoW1E9XGmTIYP7QU9yn32vl1k4KIL8e7MnoxfhRrs647eFN EEmZ7WPl3EHjk0jS6eTIodINSkbV3/oNmdPI/aHtKQjEDuCrLtv3nwwnEObuZveN hhH1V/tS+AK7Aci9ICxqUigHv4eepgdjQ3AXaUJ+Bp8aw/TGw8Rxo4HKOvl+9nBT RbodFJgVzwA1eWlsxrrY/VlCCrq/AQ7iFXYsemMwpOlM3BysCA== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pu00n3a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:09 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126f8Va014299 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:09 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:07 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 09/16] misc: fastrpc: Add early wakeup support for fastRPC driver Date: Fri, 2 Feb 2024 12:10:32 +0530 Message-ID: <20240202064039.15505-10-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: u8ybO9ggLff3-XsJDEJa0MmYoayDRL7m X-Proofpoint-ORIG-GUID: u8ybO9ggLff3-XsJDEJa0MmYoayDRL7m X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxscore=0 mlxlogscore=999 suspectscore=0 lowpriorityscore=0 impostorscore=0 bulkscore=0 clxscore=1015 adultscore=0 spamscore=0 priorityscore=1501 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 CPU wake up and context switch latency are significant in FastRPC overhead for remote calls. As part of this change, DSP sends early signal of completion to CPU and FastRPC driver detects early signal on the given context and starts polling on a memory for actual completion. Multiple different response flags are added to support DSP user early hint of approximate time of completion, early response from DSP user to wake up CPU and poll on memory for actual completion. Complete signal is also added which is sent by DSP user in case of timeout after early response is sent. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 267 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 254 insertions(+), 13 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 9f67cfbc0222..e4bb01bad7fb 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -108,6 +108,19 @@ #define USER_PD (1) #define SENSORS_PD (2) +#define FASTRPC_RSP_VERSION2 2 +/* Early wake up poll completion number received from remoteproc */ +#define FASTRPC_EARLY_WAKEUP_POLL (0xabbccdde) +/* timeout in us for polling until memory barrier */ +#define FASTRPC_POLL_TIME_MEM_UPDATE (500) +/* timeout in us for busy polling after early response from remoteproc */ +#define FASTRPC_POLL_TIME (4000) +/* timeout in us for polling completion signal after user early hint */ +#define FASTRPC_USER_EARLY_HINT_TIMEOUT (500) +/* CPU feature information to DSP */ +#define FASTRPC_CPUINFO_DEFAULT (0) +#define FASTRPC_CPUINFO_EARLY_WAKEUP (1) + #define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev) #define AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME "audio_pdr_adsp" @@ -143,6 +156,27 @@ (uint64_t *)(perf_ptr + offset)\ : (uint64_t *)NULL) : (uint64_t *)NULL) +/* Response types supported for RPC calls + * Difference between response and signal terms used here - + * response carries return value where as signal is just a notification without return value + */ +enum fastrpc_response_flags { + /* normal job completion response */ + NORMAL_RESPONSE = 0, + /* early response, cpu will poll on memory for actual completion */ + EARLY_RESPONSE = 1, + /* user hint before completion with estimated completion time */ + USER_EARLY_SIGNAL = 2, + /* extra completion clear signal to cpu when DSP updating poll + * memory later than 2 ms after sending early response + */ + COMPLETE_SIGNAL = 3, + /* status notification response of DSP User PD */ + STATUS_RESPONSE = 4, + /* process updates poll memory instead of glink response */ + POLL_MODE = 5, +}; + static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp", "sdsp", "cdsp"}; struct fastrpc_phy_page { @@ -220,6 +254,14 @@ struct fastrpc_invoke_rsp { int retval; /* invoke return value */ }; +struct fastrpc_invoke_rspv2 { + u64 ctx; /* invoke caller context */ + int retval; /* invoke return value */ + u32 flags; /* early response flags */ + u32 early_wake_time; /* user hint in us */ + u32 version; /* version number */ +}; + struct fastrpc_buf_overlap { u64 start; u64 end; @@ -287,11 +329,17 @@ struct fastrpc_invoke_ctx { int pid; int tgid; u32 sc; + /* user hint of completion time in us */ + u32 early_wake_time; u32 *crc; u64 *perf_kernel; u64 *perf_dsp; u64 ctxid; u64 msg_sz; + /* work done status flag */ + bool is_work_done; + /* response flags from remote processor */ + enum fastrpc_response_flags rsp_flags; struct kref refcount; struct list_head node; /* list of ctxs */ struct completion work; @@ -347,7 +395,9 @@ struct fastrpc_channel_ctx { struct list_head rmaps; bool secure; bool unsigned_support; + bool cpuinfo_status; u64 dma_mask; + u64 cpuinfo_todsp; }; struct fastrpc_device { @@ -711,6 +761,8 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( ctx->pid = current->pid; ctx->tgid = user->tgid; ctx->cctx = cctx; + ctx->rsp_flags = NORMAL_RESPONSE; + ctx->is_work_done = false; init_completion(&ctx->work); INIT_WORK(&ctx->put_work, fastrpc_context_put_wq); @@ -1320,6 +1372,117 @@ static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, } +static int poll_for_remote_response(struct fastrpc_invoke_ctx *ctx, u32 timeout) +{ + int err = -EIO, i, j; + u32 sc = ctx->sc; + struct fastrpc_invoke_buf *list; + struct fastrpc_phy_page *pages; + u64 *fdlist = NULL; + u32 *crclist = NULL, *poll = NULL; + unsigned int inbufs, outbufs, handles; + + /* calculate poll memory location */ + inbufs = REMOTE_SCALARS_INBUFS(sc); + outbufs = REMOTE_SCALARS_OUTBUFS(sc); + handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc); + list = fastrpc_invoke_buf_start(ctx->rpra, ctx->nscalars); + pages = fastrpc_phy_page_start(list, ctx->nscalars); + fdlist = (u64 *)(pages + inbufs + outbufs + handles); + crclist = (u32 *)(fdlist + FASTRPC_MAX_FDLIST); + poll = (u32 *)(crclist + FASTRPC_MAX_CRCLIST); + + /* poll on memory for DSP response. Return failure on timeout */ + for (i = 0, j = 0; i < timeout; i++, j++) { + if (*poll == FASTRPC_EARLY_WAKEUP_POLL) { + /* Remote processor sent early response */ + err = 0; + break; + } + if (j == FASTRPC_POLL_TIME_MEM_UPDATE) { + /* make sure that all poll memory writes by DSP are seen by CPU */ + dma_rmb(); + j = 0; + } + udelay(1); + } + return err; +} + +static inline int fastrpc_wait_for_response(struct fastrpc_invoke_ctx *ctx, + u32 kernel) +{ + int interrupted = 0; + + if (kernel) + wait_for_completion(&ctx->work); + else + interrupted = wait_for_completion_interruptible(&ctx->work); + + return interrupted; +} + +static void fastrpc_wait_for_completion(struct fastrpc_invoke_ctx *ctx, + int *ptr_interrupted, u32 kernel) +{ + int err, i = 0; + bool wait_resp = false; + u32 wTimeout = FASTRPC_USER_EARLY_HINT_TIMEOUT; + u32 wakeTime = ctx->early_wake_time; + + do { + switch (ctx->rsp_flags) { + /* Try polling on completion with timeout */ + case USER_EARLY_SIGNAL: + /* Try wait if completion time is less than timeout + * disable preempt to avoid context switch latency + */ + preempt_disable(); + i = 0; + wait_resp = false; + for (; wakeTime < wTimeout && i < wTimeout; i++) { + wait_resp = try_wait_for_completion(&ctx->work); + if (wait_resp) + break; + udelay(1); + } + preempt_enable(); + if (!wait_resp) { + *ptr_interrupted = fastrpc_wait_for_response(ctx, kernel); + if (*ptr_interrupted || ctx->is_work_done) + return; + } + break; + /* Busy poll on memory for actual job done */ + case EARLY_RESPONSE: + err = poll_for_remote_response(ctx, FASTRPC_POLL_TIME); + /* Mark job done if poll on memory successful or + * wait for completion if poll on memory timeout + */ + if (!err) { + ctx->is_work_done = true; + return; + } + if (!ctx->is_work_done) { + *ptr_interrupted = fastrpc_wait_for_response(ctx, kernel); + if (*ptr_interrupted || ctx->is_work_done) + return; + } + break; + case COMPLETE_SIGNAL: + case NORMAL_RESPONSE: + *ptr_interrupted = fastrpc_wait_for_response(ctx, kernel); + if (*ptr_interrupted || ctx->is_work_done) + return; + break; + default: + *ptr_interrupted = -EBADR; + dev_err(ctx->fl->sctx->dev, "unsupported response type:0x%x\n", ctx->rsp_flags); + break; + } + } while (!ctx->is_work_done); +} + static void fastrpc_update_invoke_count(u32 handle, u64 *perf_counter, struct timespec64 *invoket) { @@ -1341,7 +1504,7 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, struct fastrpc_invoke *inv = &invoke->inv; u32 handle, sc; u64 *perf_counter = NULL; - int err = 0, perferr = 0; + int err = 0, perferr = 0, interrupted = 0; struct timespec64 invoket = {0}; if (fl->profile) @@ -1390,15 +1553,17 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, PERF_END); wait: - if (kernel) { - if (!wait_for_completion_timeout(&ctx->work, 10 * HZ)) - err = -ETIMEDOUT; - } else { - err = wait_for_completion_interruptible(&ctx->work); + fastrpc_wait_for_completion(ctx, &interrupted, kernel); + if (interrupted != 0) { + err = interrupted; + goto bail; } - - if (err) + if (!ctx->is_work_done) { + err = -ETIMEDOUT; + dev_err(fl->sctx->dev, "Error: Invalid workdone state for handle 0x%x, sc 0x%x\n", + handle, sc); goto bail; + } /* make sure that all memory writes by DSP are seen by CPU */ dma_rmb(); @@ -2162,6 +2327,36 @@ static int fastrpc_get_info_from_kernel(struct fastrpc_ioctl_capability *cap, return 0; } +static int fastrpc_send_cpuinfo_to_dsp(struct fastrpc_user *fl) +{ + int err = 0; + u64 cpuinfo = 0; + struct fastrpc_invoke_args args[1]; + struct fastrpc_enhanced_invoke ioctl; + + if (!fl) + return -EBADF; + + cpuinfo = fl->cctx->cpuinfo_todsp; + /* return success if already updated to remote processor */ + if (fl->cctx->cpuinfo_status) + return 0; + + args[0].ptr = (u64)(uintptr_t)&cpuinfo; + args[0].length = sizeof(cpuinfo); + args[0].fd = -1; + + ioctl.inv.handle = FASTRPC_DSP_UTILITIES_HANDLE; + ioctl.inv.sc = FASTRPC_SCALARS(1, 1, 0); + ioctl.inv.args = (u64)args; + + err = fastrpc_internal_invoke(fl, true, &ioctl); + if (!err) + fl->cctx->cpuinfo_status = true; + + return err; +} + static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_ioctl_capability cap = {0}; @@ -2634,6 +2829,8 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, break; case FASTRPC_IOCTL_INIT_ATTACH: err = fastrpc_init_attach(fl, ROOT_PD); + if (!err) + fastrpc_send_cpuinfo_to_dsp(fl); break; case FASTRPC_IOCTL_INIT_ATTACH_SNS: err = fastrpc_init_attach(fl, SENSORS_PD); @@ -2953,6 +3150,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) err = fastrpc_device_register(rdev, data, secure_dsp, domains[domain_id]); if (err) goto fdev_error; + data->cpuinfo_todsp = FASTRPC_CPUINFO_DEFAULT; break; case CDSP_DOMAIN_ID: data->unsigned_support = true; @@ -2964,6 +3162,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) err = fastrpc_device_register(rdev, data, false, domains[domain_id]); if (err) goto fdev_error; + data->cpuinfo_todsp = FASTRPC_CPUINFO_EARLY_WAKEUP; break; default: err = -EINVAL; @@ -3051,31 +3250,73 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) fastrpc_channel_ctx_put(cctx); } +static void fastrpc_notify_user_ctx(struct fastrpc_invoke_ctx *ctx, int retval, + u32 rsp_flags, u32 early_wake_time) +{ + ctx->retval = retval; + ctx->rsp_flags = (enum fastrpc_response_flags)rsp_flags; + switch (rsp_flags) { + case NORMAL_RESPONSE: + case COMPLETE_SIGNAL: + /* normal and complete response with return value */ + ctx->is_work_done = true; + complete(&ctx->work); + break; + case USER_EARLY_SIGNAL: + /* user hint of approximate time of completion */ + ctx->early_wake_time = early_wake_time; + break; + case EARLY_RESPONSE: + /* rpc framework early response with return value */ + complete(&ctx->work); + break; + default: + break; + } +} + static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 addr) { struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev); struct fastrpc_invoke_rsp *rsp = data; + struct fastrpc_invoke_rspv2 *rspv2 = NULL; struct fastrpc_invoke_ctx *ctx; unsigned long flags; unsigned long ctxid; + u32 rsp_flags = 0; + u32 early_wake_time = 0; if (len < sizeof(*rsp)) return -EINVAL; + if (len >= sizeof(*rspv2)) { + rspv2 = data; + if (rspv2) { + early_wake_time = rspv2->early_wake_time; + rsp_flags = rspv2->flags; + } + } ctxid = ((rsp->ctx & FASTRPC_CTXID_MASK) >> 4); spin_lock_irqsave(&cctx->lock, flags); ctx = idr_find(&cctx->ctx_idr, ctxid); - spin_unlock_irqrestore(&cctx->lock, flags); if (!ctx) { - dev_err(&rpdev->dev, "No context ID matches response\n"); - return -ENOENT; + dev_info(&cctx->rpdev->dev, "Warning: No context ID matches response\n"); + spin_unlock_irqrestore(&cctx->lock, flags); + return 0; } - ctx->retval = rsp->retval; - complete(&ctx->work); + if (rspv2) { + if (rspv2->version != FASTRPC_RSP_VERSION2) { + dev_err(&cctx->rpdev->dev, "Incorrect response version %d\n", rspv2->version); + spin_unlock_irqrestore(&cctx->lock, flags); + return -EINVAL; + } + } + fastrpc_notify_user_ctx(ctx, rsp->retval, rsp_flags, early_wake_time); + spin_unlock_irqrestore(&cctx->lock, flags); /* * The DMA buffer associated with the context cannot be freed in From patchwork Fri Feb 2 06:40:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542153 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 1C833199D9; Fri, 2 Feb 2024 06:41:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856075; cv=none; b=VBAg2+Lnd3pJVXQQWvaExw9QyftM96HmXuZ+B5pOethrCy9r78I3q5apIuldGGsYA8TWly37usFCKyx0Emjs0sPEfFutQYChooIE7y7sZZhF9kZTwI0nunOf981287HIYCbmsbpOyq24gByOeJrtAV2I9ux1YiDH69chs9JaUsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856075; c=relaxed/simple; bh=2Ehjwo/Vd5r9E7HGbSQo9oSfejaHbQjOK+/5kozcDWA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XXyrAp7F1RGt8KIyev5qyN30urSQ7UJQ/DETRddOw6lzDbwdewTaDrIZs+ZsyLuHsvV4QBVs7s0clDM4qSsWuwpbfWIE/3zOKxI5TsXQAvnxuVgQG7ctknJaRdKzr6qw2U0I/TEiivmX3qJvVfsmY7IRh8zygMuNa4S3l0jx/PI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=F9KS1R1l; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="F9KS1R1l" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4122EMM2004186; Fri, 2 Feb 2024 06:41:12 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=RDPZHWX7iZQRiYXsY0lU h79KcCxlXrs4AtNhueuf94E=; b=F9KS1R1l9UxcXDXBvGKbilTgEvVxZQOZUaKh lvuI3nWNwrJj4XQ91vUpefC+y6vOXF+xadMl5qFltq8QtEGmnO16fuZDe8Ab10KG H1ZZA6IxozJb3/txb6r/k43Ipfc1hkdeN+NncDFdWem+ndj0W31U5zOlSPnu/HRF D4w71p+STmgtLr3x4QhDzNI49TKgGrSn00FyqKuLYTvqWc/lNY37MH+SGlW950Ni MMgbv/Uoehksa2YTu9MLszRhDsyyVt9bPQpSMv3zvWeGhJ+gL8O2oX/CG7Xbie3Y pofOmgjNSvIzcnI4MMxjaWJY0mmZPScyvFjQhjnrTDhzRLSiOQ== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0ptw8ndb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:11 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126fBoV004683 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:11 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:09 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 10/16] misc: fastrpc: Add polling mode support for fastRPC driver Date: Fri, 2 Feb 2024 12:10:33 +0530 Message-ID: <20240202064039.15505-11-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: 4ZWYRrCMAxlqkSM-X-xIVyf6altgtwF3 X-Proofpoint-GUID: 4ZWYRrCMAxlqkSM-X-xIVyf6altgtwF3 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 bulkscore=0 malwarescore=0 mlxscore=0 lowpriorityscore=0 phishscore=0 clxscore=1015 mlxlogscore=857 adultscore=0 impostorscore=0 suspectscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 For any remote call to DSP, after sending an invocation message, fastRPC driver waits for glink response and during this time the CPU can go into low power modes. Adding a polling mode support with which fastRPC driver will poll continuously on a memory after sending a message to remote subsystem which will eliminate CPU wakeup and scheduling latencies and reduce fastRPC overhead. With this change, DSP always sends a glink response which will get ignored if polling mode didn't time out. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 50 +++++++++++++++++++++++++++++++++++++ include/uapi/misc/fastrpc.h | 10 +++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index e4bb01bad7fb..296ddae0ef7c 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -111,6 +111,8 @@ #define FASTRPC_RSP_VERSION2 2 /* Early wake up poll completion number received from remoteproc */ #define FASTRPC_EARLY_WAKEUP_POLL (0xabbccdde) +/* Poll response number from remote processor for call completion */ +#define FASTRPC_POLL_RESPONSE (0xdecaf) /* timeout in us for polling until memory barrier */ #define FASTRPC_POLL_TIME_MEM_UPDATE (500) /* timeout in us for busy polling after early response from remoteproc */ @@ -418,11 +420,15 @@ struct fastrpc_user { struct fastrpc_buf *init_mem; u32 profile; + /* Threads poll for specified timeout and fall back to glink wait */ + u32 poll_timeout; int tgid; int pd; bool is_secure_dev; bool is_unsigned_pd; bool sharedcb; + /* If set, threads will poll for DSP response instead of glink wait */ + bool poll_mode; char *servloc_name; /* Lock for lists */ spinlock_t lock; @@ -1398,6 +1404,11 @@ static int poll_for_remote_response(struct fastrpc_invoke_ctx *ctx, u32 timeout) /* Remote processor sent early response */ err = 0; break; + } else if (*poll == FASTRPC_POLL_RESPONSE) { + err = 0; + ctx->is_work_done = true; + ctx->retval = 0; + break; } if (j == FASTRPC_POLL_TIME_MEM_UPDATE) { /* make sure that all poll memory writes by DSP are seen by CPU */ @@ -1475,6 +1486,15 @@ static void fastrpc_wait_for_completion(struct fastrpc_invoke_ctx *ctx, if (*ptr_interrupted || ctx->is_work_done) return; break; + case POLL_MODE: + err = poll_for_remote_response(ctx, ctx->fl->poll_timeout); + + /* If polling timed out, move to normal response state */ + if (err) + ctx->rsp_flags = NORMAL_RESPONSE; + else + *ptr_interrupted = 0; + break; default: *ptr_interrupted = -EBADR; dev_err(ctx->fl->sctx->dev, "unsupported response type:0x%x\n", ctx->rsp_flags); @@ -2176,6 +2196,33 @@ static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) return err; } +static int fastrpc_manage_poll_mode(struct fastrpc_user *fl, u32 enable, u32 timeout) +{ + const unsigned int MAX_POLL_TIMEOUT_US = 10000; + + if ((fl->cctx->domain_id != CDSP_DOMAIN_ID) || (fl->pd != USER_PD)) { + dev_err(&fl->cctx->rpdev->dev, "poll mode only allowed for dynamic CDSP process\n"); + return -EPERM; + } + if (timeout > MAX_POLL_TIMEOUT_US) { + dev_err(&fl->cctx->rpdev->dev, "poll timeout %u is greater than max allowed value %u\n", + timeout, MAX_POLL_TIMEOUT_US); + return -EBADMSG; + } + spin_lock(&fl->lock); + if (enable) { + fl->poll_mode = true; + fl->poll_timeout = timeout; + } else { + fl->poll_mode = false; + fl->poll_timeout = 0; + } + spin_unlock(&fl->lock); + dev_info(&fl->cctx->rpdev->dev, "updated poll mode to %d, timeout %u\n", enable, timeout); + + return 0; +} + static int fastrpc_internal_control(struct fastrpc_user *fl, struct fastrpc_internal_control *cp) { @@ -2190,6 +2237,9 @@ static int fastrpc_internal_control(struct fastrpc_user *fl, case FASTRPC_CONTROL_SMMU: fl->sharedcb = cp->smmu.sharedcb; break; + case FASTRPC_CONTROL_RPC_POLL: + err = fastrpc_manage_poll_mode(fl, cp->lp.enable, cp->lp.latency); + break; default: err = -EBADRQC; break; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index d29188e43b21..b4959cc4d254 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -182,9 +182,17 @@ struct fastrpc_ctrl_smmu { u32 sharedcb; /* Set to SMMU share context bank */ }; +struct fastrpc_ctrl_latency { + u32 enable; /* latency control enable */ + u32 latency; /* latency request in us */ +}; + struct fastrpc_internal_control { u32 req; - struct fastrpc_ctrl_smmu smmu; + union { + struct fastrpc_ctrl_smmu smmu; + struct fastrpc_ctrl_latency lp; + }; }; enum fastrpc_perfkeys { From patchwork Fri Feb 2 06:40:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542154 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 DCD001B270; Fri, 2 Feb 2024 06:41:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856077; cv=none; b=nVrA6ypHmqRnExqsFhFyS3ejOtwYFlWy9bR6KUzAsNmpxi2ttR8ugcUK66fBe8vpPre7s1PK3DcQAwQsY8kd1AK2PothN2ZEvFNL/c+F1TMBlUoIK6KIXb/ZLi3CXh0lKoPCnXAsm1egtHtaKj9lqUh86guXMIjizGkfcw1hRXU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856077; c=relaxed/simple; bh=4bnnNMYYYlB/cbIX2lYhws2/CHK4wfi5gAQ7sg8tPt4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pWt2zagSzo0hOgmMtyjEGwPtf8TnqdAsx3/OTcq9LcWvzP5XKzjDxCKJgtCdQBW9m/oQNbEhHYRcWUlHcHPGQ5/xpAIBQ+dRwr0A3rbeqL8na//+gEcPyntLwf4m1F9sEeInsHU4+SQ6tVm1tg9/ERmOUBd0vJRRgOgwlvqOzW4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=Ho080c1n; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="Ho080c1n" Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4125FB4r028624; Fri, 2 Feb 2024 06:41:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=dmmCuWVG2ShrxZrY/6s3 kX8rD27eOxSyusFWzsvSpqM=; b=Ho080c1njtj3jfqWPBl5+z5kE+RmtpXJYQVl aYX3OrYRjvaLteWJPkXtxYXRF27+SWWrv0uwiDywK8rl/+9CPNr+qHMt6IDtMuzH TmWOYyHxJUNJdfWLeRvuoWD1S46D6wHjGNFqsR6DiyWKwWtYupeHugegl4iZDWMR zuyXjHYhBjAsjZ3cTMbU8W+B9xLhE1Mws9iOJ5jlMjZ7+U6Y5QffFv+zeT1p4L8c FB4DzznLO1cBzZek04L49bTXhQnkg9hb8Y1S5g1S8qu8wctT9Py4uj7QBxjNmh94 jYyot98PJjbUQdUcb+CSg9QLew6vseMl9vURQsakfNQuTAbz9g== Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pu1rndv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:14 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126fDaf002584 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:13 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:11 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 11/16] misc: fastrpc: Add DSP PD notification support Date: Fri, 2 Feb 2024 12:10:34 +0530 Message-ID: <20240202064039.15505-12-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: RCcKHZek-LUR4kHTf-pRE6tjgaAXBH_D X-Proofpoint-ORIG-GUID: RCcKHZek-LUR4kHTf-pRE6tjgaAXBH_D X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 mlxscore=0 impostorscore=0 clxscore=1015 mlxlogscore=999 malwarescore=0 lowpriorityscore=0 phishscore=0 priorityscore=1501 adultscore=0 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Current driver design does not provide any notification regarding the status of used PD on DSP. Only when user makes a FastRPC invocation, they get to know if the process has been killed on DSP. Notifying status of user PD can help users to restart the DSP PD session. Co-developed-by: Anandu Krishnan E Signed-off-by: Anandu Krishnan E Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 139 +++++++++++++++++++++++++++++++++++- include/uapi/misc/fastrpc.h | 14 ++++ 2 files changed, 152 insertions(+), 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 296ddae0ef7c..d4a4ad54a5c9 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -122,6 +122,8 @@ /* CPU feature information to DSP */ #define FASTRPC_CPUINFO_DEFAULT (0) #define FASTRPC_CPUINFO_EARLY_WAKEUP (1) +/* Process status notifications from DSP will be sent with this unique context */ +#define FASTRPC_NOTIF_CTX_RESERVED 0xABCDABCD #define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev) @@ -264,6 +266,13 @@ struct fastrpc_invoke_rspv2 { u32 version; /* version number */ }; +struct dsp_notif_rsp { + u64 ctx; /* response context */ + u32 type; /* Notification type */ + int pid; /* user process pid */ + u32 status; /* userpd status notification */ +}; + struct fastrpc_buf_overlap { u64 start; u64 end; @@ -324,6 +333,21 @@ struct fastrpc_perf { u64 tid; }; +struct fastrpc_notif_queue { + /* Number of pending status notifications in queue */ + atomic_t notif_queue_count; + /* Wait queue to synchronize notifier thread and response */ + wait_queue_head_t notif_wait_queue; + /* IRQ safe spin lock for protecting notif queue */ + spinlock_t nqlock; +}; + +struct fastrpc_notif_rsp { + struct list_head notifn; + u32 domain; + enum fastrpc_status_flags status; +}; + struct fastrpc_invoke_ctx { int nscalars; int nbufs; @@ -414,10 +438,13 @@ struct fastrpc_user { struct list_head pending; struct list_head interrupted; struct list_head mmaps; + struct list_head notif_queue; struct fastrpc_channel_ctx *cctx; struct fastrpc_session_ctx *sctx; struct fastrpc_buf *init_mem; + /* Process status notification queue */ + struct fastrpc_notif_queue proc_state_notif; u32 profile; /* Threads poll for specified timeout and fall back to glink wait */ @@ -2196,6 +2223,99 @@ static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) return err; } +static void fastrpc_queue_pd_status(struct fastrpc_user *fl, int domain, int status) +{ + struct fastrpc_notif_rsp *notif_rsp = NULL; + unsigned long flags; + + notif_rsp = kzalloc(sizeof(*notif_rsp), GFP_ATOMIC); + if (!notif_rsp) + return; + + notif_rsp->status = status; + notif_rsp->domain = domain; + + spin_lock_irqsave(&fl->proc_state_notif.nqlock, flags); + list_add_tail(¬if_rsp->notifn, &fl->notif_queue); + atomic_add(1, &fl->proc_state_notif.notif_queue_count); + wake_up_interruptible(&fl->proc_state_notif.notif_wait_queue); + spin_unlock_irqrestore(&fl->proc_state_notif.nqlock, flags); +} + +static void fastrpc_notif_find_process(int domain, struct fastrpc_channel_ctx *cctx, struct dsp_notif_rsp *notif) +{ + bool is_process_found = false; + unsigned long irq_flags = 0; + struct fastrpc_user *user; + + spin_lock_irqsave(&cctx->lock, irq_flags); + list_for_each_entry(user, &cctx->users, user) { + if (user->tgid == notif->pid) { + is_process_found = true; + break; + } + } + spin_unlock_irqrestore(&cctx->lock, irq_flags); + + if (!is_process_found) + return; + fastrpc_queue_pd_status(user, domain, notif->status); +} + +static int fastrpc_wait_on_notif_queue( + struct fastrpc_internal_notif_rsp *notif_rsp, + struct fastrpc_user *fl) +{ + int err = 0; + unsigned long flags; + struct fastrpc_notif_rsp *notif, *inotif, *n; + +read_notif_status: + err = wait_event_interruptible(fl->proc_state_notif.notif_wait_queue, + atomic_read(&fl->proc_state_notif.notif_queue_count)); + if (err) { + kfree(notif); + return err; + } + + spin_lock_irqsave(&fl->proc_state_notif.nqlock, flags); + list_for_each_entry_safe(inotif, n, &fl->notif_queue, notifn) { + list_del(&inotif->notifn); + atomic_sub(1, &fl->proc_state_notif.notif_queue_count); + notif = inotif; + break; + } + spin_unlock_irqrestore(&fl->proc_state_notif.nqlock, flags); + + if (notif) { + notif_rsp->status = notif->status; + notif_rsp->domain = notif->domain; + } else {// Go back to wait if ctx is invalid + dev_err(fl->sctx->dev, "Invalid status notification response\n"); + goto read_notif_status; + } + + kfree(notif); + return err; +} + +static int fastrpc_get_notif_response( + struct fastrpc_internal_notif_rsp *notif, + void *param, struct fastrpc_user *fl) +{ + int err = 0; + + err = fastrpc_wait_on_notif_queue(notif, fl); + if (err) + return err; + + if (copy_to_user((void __user *)param, notif, + sizeof(struct fastrpc_internal_notif_rsp))) + return -EFAULT; + + return 0; +} + static int fastrpc_manage_poll_mode(struct fastrpc_user *fl, u32 enable, u32 timeout) { const unsigned int MAX_POLL_TIMEOUT_US = 10000; @@ -2253,6 +2373,7 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) struct fastrpc_invoke_args *args = NULL; struct fastrpc_ioctl_multimode_invoke invoke; struct fastrpc_internal_control cp = {0}; + struct fastrpc_internal_notif_rsp notif; u32 nscalars; u64 *perf_kernel; int err, i; @@ -2302,6 +2423,10 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) err = fastrpc_internal_control(fl, &cp); break; + case FASTRPC_INVOKE_NOTIF: + err = fastrpc_get_notif_response(¬if, + (void *)invoke.invparam, fl); + break; default: err = -ENOTTY; break; @@ -3278,8 +3403,10 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) cctx->rpdev = NULL; cctx->staticpd_status = false; fastrpc_mmap_remove_ssr(cctx); - list_for_each_entry(user, &cctx->users, user) + list_for_each_entry(user, &cctx->users, user) { + fastrpc_queue_pd_status(user, cctx->domain_id, FASTRPC_DSP_SSR); fastrpc_notify_users(user); + } spin_unlock_irqrestore(&cctx->lock, flags); if (cctx->domain_id == ADSP_DOMAIN_ID) { @@ -3331,12 +3458,22 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev); struct fastrpc_invoke_rsp *rsp = data; struct fastrpc_invoke_rspv2 *rspv2 = NULL; + struct dsp_notif_rsp *notif = (struct dsp_notif_rsp *)data; struct fastrpc_invoke_ctx *ctx; unsigned long flags; unsigned long ctxid; u32 rsp_flags = 0; u32 early_wake_time = 0; + if (notif->ctx == FASTRPC_NOTIF_CTX_RESERVED) { + if (notif->type == STATUS_RESPONSE && len >= sizeof(*notif)) { + fastrpc_notif_find_process(cctx->domain_id, cctx, notif); + return 0; + } else { + return -ENOENT; + } + } + if (len < sizeof(*rsp)) return -EINVAL; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index b4959cc4d254..a3bc6666a653 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -195,6 +195,12 @@ struct fastrpc_internal_control { }; }; +struct fastrpc_internal_notif_rsp { + u32 domain; /* Domain of User PD */ + u32 session; /* Session ID of User PD */ + u32 status; /* Status of the process */ +}; + enum fastrpc_perfkeys { PERF_COUNT = 0, PERF_FLUSH = 1, @@ -209,4 +215,12 @@ enum fastrpc_perfkeys { PERF_KEY_MAX = 10, }; +enum fastrpc_status_flags { + FASTRPC_USERPD_UP = 0, + FASTRPC_USERPD_EXIT = 1, + FASTRPC_USERPD_FORCE_KILL = 2, + FASTRPC_USERPD_EXCEPTION = 3, + FASTRPC_DSP_SSR = 4, +}; + #endif /* __QCOM_FASTRPC_H__ */ From patchwork Fri Feb 2 06:40:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542155 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 1AA1D2C1A4; Fri, 2 Feb 2024 06:41:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856079; cv=none; b=rGXPMnQyZii923MxeFl6J0mRM1Fge2/+ox7IrnmEa+vIUSC7CCaoCkavjg42M/vDrZOkcYhtxbtQGHe7zp/qSV4a7te4RNNcEIsy9lw5hAcTTEY0pdSsmrugsHImps4crpHx1z5fEXcs9RqOsRMM03Z52UhFrLhzs38Ygx8Hoys= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856079; c=relaxed/simple; bh=1lIbGo/2OziT53zdE91LvXzUa34Sa/eIpMungQw96p0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rn3RZ0bB8mQmo4k7u+2PZiO9Dp7nc1kDWVsMaT5PSJjlLNKFJNz4/7Qkp3W1PGafZbOw1yzZv+M0bxBsX84YV8WcMPdePg2ymlMBbqqx0K9o+Dk1g7dNc/PpKUYHnsXv/yCQB0DKUyszBPbwSJ1fEIaIHcs6i0TXUjz7J7RZdm8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=lGjSRLdf; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="lGjSRLdf" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4126Jjn6006809; Fri, 2 Feb 2024 06:41:16 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=c0WEn7PDNbcN5mbu7n7y lJu5j7la+dT4GWYZ7RDLOa4=; b=lGjSRLdfSwv/OXfcKmYdz07s1bgFtjEvQdKq wXLjLpxleOrYgXrFYKx51km+BYi6uOCajuTmdPxds2bcRZF9BjlWdv8L0PpGB5HD Swsm9DnwIwkHMQg5eYuFxT22T0jSszNENjuNAbP40VGOnzwAh7v21qV4ibOU5aai SeZnYxkzwYG8Kku0QgMS54FWR1wCJG9QlCCIyf768TZq9VmvOI7qP/MoR8eT/Hgn pfgxPsMlJspZrLQeeJ46qAt+y2KkJ8ml+oXsmjON+FvYDMXTWPTkbwWiGcoNC9+T qoCHh3UO/+dBaR215X1HVcYrnGjTYg36Ifvfv7lmEFzf+dtUWw== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pu00n3p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:16 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126fFCV027515 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:15 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:13 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 12/16] misc: fastrpc: Add support for users to clean up DSP user PD Date: Fri, 2 Feb 2024 12:10:35 +0530 Message-ID: <20240202064039.15505-13-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: tyeGU-yEyKpxEj1cJQVYCunYuKPLrxRl X-Proofpoint-ORIG-GUID: tyeGU-yEyKpxEj1cJQVYCunYuKPLrxRl X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxscore=0 mlxlogscore=796 suspectscore=0 lowpriorityscore=0 impostorscore=0 bulkscore=0 clxscore=1015 adultscore=0 spamscore=0 priorityscore=1501 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Add a control mechanism for users to clean up DSP user PD. This method can be used by users for handling any unexpected hang scenarios on DSP PD. User can clean up DSP PD and restart the user PD again. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index d4a4ad54a5c9..d1be89f84214 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -2360,6 +2360,11 @@ static int fastrpc_internal_control(struct fastrpc_user *fl, case FASTRPC_CONTROL_RPC_POLL: err = fastrpc_manage_poll_mode(fl, cp->lp.enable, cp->lp.latency); break; + case FASTRPC_CONTROL_DSPPROCESS_CLEAN: + err = fastrpc_release_current_dsp_process(fl); + if (!err) + fastrpc_queue_pd_status(fl, fl->cctx->domain_id, FASTRPC_USERPD_FORCE_KILL); + break; default: err = -EBADRQC; break; From patchwork Fri Feb 2 06:40:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542156 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 494843FB21; Fri, 2 Feb 2024 06:41:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856082; cv=none; b=jfa2neG++meNYJ35b7VnOgITTtPvewT+xZ0/SvrwTl7PsFFsrbvYX4JXXCEKQermCgfCFRyny/4y6BthqNACT1tyiGcZ4dYNePwtKuIUDg2KiQ6y5BMOIZueC9gBsaXhirqwrIt74PfMOWoHWzXVa+QlO3VGfNmNX1bHAh8wnuo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856082; c=relaxed/simple; bh=gF/SqtpTVB0DrzlvGPiFFaaJ9ERAGRdeoV6n2gPpPlE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ceZjomqRGj90kEZsK8F0RUzQWyHAhf8x7Pat+yXfnvNhVXfP1TFutYcceVZeVaiBKMWwZz11jKbHo+kpGgqgPHwAzY8Kfq2vSC5ZawCvROKQh7KiwvlV0PN8c04D8R366hKK7rvd51AFjbKudIUDv06XBEQXSkwt/OyYuED6uvg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=R9X5OUl0; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="R9X5OUl0" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4124IO66014103; Fri, 2 Feb 2024 06:41:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=T/2V3UuvVLP6wtSt1VgJ YGNQTOa4VMRME2NKbAkkap0=; b=R9X5OUl047IwGyS7ulrCIy4tnV9fDzeySAw0 +HEVw2f82/DTU3ClS0ro/t1r99UtN2+dULIRAH2SwHKDGtHbChRsSmW/A16XkV2z ON5dObHQNnSTc4vDY62YJJ/UCVPQnIUoYgf/PXu7fZjXKT4FtWBNdqXMSrMiQ1nx Eh8MHgICjyde2oIR1Z2phmej2ACyCF9f3wwFTzsg5v51WDwSFVoZltvmdNFTRUYU d4t+hO/5AAUThLtgxt+ZmMm9jo44PFCpV/hnmFjEUauTruSbjck29dhSxorFmMnR s9PNbuxYOdS7umIZeecQj087/9XyEO9BWtJArCiYr4iASUm3LQ== Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pu00n3t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:18 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126fH0X001074 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:17 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:15 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 13/16] misc: fastrpc: Add wakelock management support Date: Fri, 2 Feb 2024 12:10:36 +0530 Message-ID: <20240202064039.15505-14-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: uKlEbjQky6_3nahxRcTyisKByp15Pad_ X-Proofpoint-ORIG-GUID: uKlEbjQky6_3nahxRcTyisKByp15Pad_ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxscore=0 mlxlogscore=999 suspectscore=0 lowpriorityscore=0 impostorscore=0 bulkscore=0 clxscore=1015 adultscore=0 spamscore=0 priorityscore=1501 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 CPU can go into suspend mode at anytime. Users might have a requirement to keep the CPU awake until they get a response for their remote call to DSP. Wakelock management can be used to achieve this requirement. Co-developed-by: Anandu Krishnan E Signed-off-by: Anandu Krishnan E Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 98 ++++++++++++++++++++++++++++++++++++- include/uapi/misc/fastrpc.h | 10 ++++ 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index d1be89f84214..2b24d1f96978 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -125,6 +125,11 @@ /* Process status notifications from DSP will be sent with this unique context */ #define FASTRPC_NOTIF_CTX_RESERVED 0xABCDABCD +/* Maximum PM timeout that can be voted through fastrpc */ +#define FASTRPC_MAX_PM_TIMEOUT_MS 50 +#define FASTRPC_NON_SECURE_WAKE_SOURCE_CLIENT_NAME "fastrpc-non_secure" +#define FASTRPC_SECURE_WAKE_SOURCE_CLIENT_NAME "fastrpc-secure" + #define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev) #define AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME "audio_pdr_adsp" @@ -419,6 +424,10 @@ struct fastrpc_channel_ctx { struct fastrpc_device *secure_fdevice; struct fastrpc_device *fdevice; struct list_head rmaps; + /* Secure subsystems like ADSP/SLPI will use secure client */ + struct wakeup_source *wake_source_secure; + /* Non-secure subsystem like CDSP will use regular client */ + struct wakeup_source *wake_source; bool secure; bool unsigned_support; bool cpuinfo_status; @@ -449,6 +458,8 @@ struct fastrpc_user { u32 profile; /* Threads poll for specified timeout and fall back to glink wait */ u32 poll_timeout; + u32 ws_timeout; + u32 wake_enable; int tgid; int pd; bool is_secure_dev; @@ -997,6 +1008,43 @@ static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx, spin_unlock_irqrestore(&cctx->lock, flags); } +static void fastrpc_pm_awake(struct fastrpc_user *fl, + u32 is_secure_channel) +{ + struct fastrpc_channel_ctx *cctx = fl->cctx; + struct wakeup_source *wake_source = NULL; + + /* + * Vote with PM to abort any suspend in progress and + * keep system awake for specified timeout + */ + if (is_secure_channel) + wake_source = cctx->wake_source_secure; + else + wake_source = cctx->wake_source; + + if (wake_source) + pm_wakeup_ws_event(wake_source, fl->ws_timeout, true); +} + +static void fastrpc_pm_relax(struct fastrpc_user *fl, + u32 is_secure_channel) +{ + struct fastrpc_channel_ctx *cctx = fl->cctx; + struct wakeup_source *wake_source = NULL; + + if (!fl->wake_enable) + return; + + if (is_secure_channel) + wake_source = cctx->wake_source_secure; + else + wake_source = cctx->wake_source; + + if (wake_source) + __pm_relax(wake_source); +} + static int fastrpc_map_create(struct fastrpc_user *fl, int fd, u64 len, u32 attr, struct fastrpc_map **ppmap) { @@ -2070,6 +2118,7 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) fastrpc_buf_free(buf); } + fastrpc_pm_relax(fl, cctx->secure); fastrpc_session_free(cctx, fl->sctx); fastrpc_channel_ctx_put(cctx); @@ -2357,14 +2406,32 @@ static int fastrpc_internal_control(struct fastrpc_user *fl, case FASTRPC_CONTROL_SMMU: fl->sharedcb = cp->smmu.sharedcb; break; - case FASTRPC_CONTROL_RPC_POLL: - err = fastrpc_manage_poll_mode(fl, cp->lp.enable, cp->lp.latency); + case FASTRPC_CONTROL_WAKELOCK: + if (!fl->is_secure_dev) { + dev_err(&fl->cctx->rpdev->dev, + "PM voting not allowed for non-secure device node"); + err = -EPERM; + return err; + } + fl->wake_enable = cp->wp.enable; + break; + case FASTRPC_CONTROL_PM: + if (!fl->wake_enable) + return -EACCES; + if (cp->pm.timeout > FASTRPC_MAX_PM_TIMEOUT_MS) + fl->ws_timeout = FASTRPC_MAX_PM_TIMEOUT_MS; + else + fl->ws_timeout = cp->pm.timeout; + fastrpc_pm_awake(fl, fl->cctx->secure); break; case FASTRPC_CONTROL_DSPPROCESS_CLEAN: err = fastrpc_release_current_dsp_process(fl); if (!err) fastrpc_queue_pd_status(fl, fl->cctx->domain_id, FASTRPC_USERPD_FORCE_KILL); break; + case FASTRPC_CONTROL_RPC_POLL: + err = fastrpc_manage_poll_mode(fl, cp->lp.enable, cp->lp.latency); + break; default: err = -EBADRQC; break; @@ -3268,6 +3335,21 @@ static int fastrpc_setup_service_locator(struct fastrpc_channel_ctx *cctx, char return err; } +static void fastrpc_register_wakeup_source(struct device *dev, + const char *client_name, struct wakeup_source **device_wake_source) +{ + struct wakeup_source *wake_source = NULL; + + wake_source = wakeup_source_register(dev, client_name); + if (IS_ERR_OR_NULL(wake_source)) { + dev_err(dev, "wakeup_source_register failed for dev %s, client %s with err %ld\n", + dev_name(dev), client_name, PTR_ERR(wake_source)); + return; + } + + *device_wake_source = wake_source; +} + static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) { struct device *rdev = &rpdev->dev; @@ -3368,6 +3450,13 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) goto populate_error; } + if (data->fdevice) + fastrpc_register_wakeup_source(data->fdevice->miscdev.this_device, + FASTRPC_NON_SECURE_WAKE_SOURCE_CLIENT_NAME, &data->wake_source); + if (data->secure_fdevice) + fastrpc_register_wakeup_source(data->secure_fdevice->miscdev.this_device, + FASTRPC_SECURE_WAKE_SOURCE_CLIENT_NAME, &data->wake_source_secure); + kref_init(&data->refcount); dev_set_drvdata(&rpdev->dev, data); @@ -3421,6 +3510,11 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) pdr_handle_release(cctx->spd[0].pdrhandle); } + if (cctx->wake_source) + wakeup_source_unregister(cctx->wake_source); + if (cctx->wake_source_secure) + wakeup_source_unregister(cctx->wake_source_secure); + if (cctx->fdevice) misc_deregister(&cctx->fdevice->miscdev); diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index a3bc6666a653..f4c73f6774f7 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -187,11 +187,21 @@ struct fastrpc_ctrl_latency { u32 latency; /* latency request in us */ }; +struct fastrpc_ctrl_wakelock { + u32 enable; /* wakelock control enable */ +}; + +struct fastrpc_ctrl_pm { + u32 timeout; /* timeout(in ms) for PM to keep system awake */ +}; + struct fastrpc_internal_control { u32 req; union { struct fastrpc_ctrl_smmu smmu; struct fastrpc_ctrl_latency lp; + struct fastrpc_ctrl_wakelock wp; + struct fastrpc_ctrl_pm pm; }; }; From patchwork Fri Feb 2 06:40:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542157 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 C596942AB7; Fri, 2 Feb 2024 06:41:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856084; cv=none; b=sHMScPGXYiEnKJcSxsw3kKHHZg9XkjPxak/CBPMvUjx6MWbyWJe71nn3GNcEdbJPw57HQcDS5TTesdMhrdRYfm9LMW4fFBerOeAVO0Aqg24SpAA7Eil/TAH8hV5HZ84w/NqIqav0jfu3w5iQoHzxgxD60kZP6sy1T6XVRNL0tpo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856084; c=relaxed/simple; bh=JL0DIv+VF9YRGSN9do61lVc5IDaNIsYbdQOYrCPKYmc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GNNGubF1qPyqGAnVLn0htpbc4Cf8AR+1kSbtaNH7qwQXubK/npuRNb+ZPOfpUJft5muoHLyGXMh9tA9nBXGXBEvApY+b3gtjbuZbaKu77XO6f5vNlPYO4HnSJA8e5cDE2uvW3msh/GVXe1SukSQDVy2VrXEoVFcUVjL2gG46Cbk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=TcmBwT3M; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="TcmBwT3M" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4124F1FC010830; Fri, 2 Feb 2024 06:41:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=Qlbhx7H2XDYQRwGKn2D4 ycN1Eozp5p4+oSgz4em7FHw=; b=TcmBwT3M40UlJt5SjUkrYNX1BOB0rVrsoAFn rLBevsp2FdzkABnV3JcF43ofGpVxPHdLQECJbbNJz3DmyfLe/E4I1ZDe6hSrXgYG KSLgZ/jLEoOIkck9u5BRTHUK3xLBWcATB87vitAogrH71rRm+hg0yPgAfqlEY4rS 4YIBE9J6knLFReJFxYZ4zqIb5z0c5buVPASOqq8iVbh+O7vUu2E2LD9cZzyDjhOc uvrSmenk2Z7jzJBsrbhAE6tYcn3dbPFOTPYLvUCAPx4m9rqI4PycweGthCOYUDks 6AdvDvUypckFnt4PmQkppx+Apppi53/0nxJPhNReRg7mOuqJfQ== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0pwjgmjk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:20 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126fJJk027603 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:19 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:17 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 14/16] misc: fastrpc: Add DSP signal support Date: Fri, 2 Feb 2024 12:10:37 +0530 Message-ID: <20240202064039.15505-15-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: YerLg_Qz1V2GIXQjGrs5Gchb4WNgeh4G X-Proofpoint-ORIG-GUID: YerLg_Qz1V2GIXQjGrs5Gchb4WNgeh4G X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 phishscore=0 mlxlogscore=415 malwarescore=0 suspectscore=0 adultscore=0 priorityscore=1501 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020045 Add a dedicated signaling channel between fastrpc driver and DSP root PD, with a new dsp signaling interface between the userspace framework and drivers. This makes dspqueue signaling latency comparable to or better than synchronous FastRPC calls, and reduces the processing overhead since the signaling code path is simpler than synchronous FastRPC calls. Co-developed-by: Anandu Krishnan E Signed-off-by: Anandu Krishnan E Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 307 +++++++++++++++++++++++++++++++++++- include/uapi/misc/fastrpc.h | 17 ++ 2 files changed, 323 insertions(+), 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 2b24d1f96978..0308f717456f 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -144,6 +144,10 @@ #define SENSORS_PDR_SLPI_SERVICE_NAME SENSORS_PDR_ADSP_SERVICE_NAME #define SLPI_SENSORPD_NAME "msm/slpi/sensor_pd" +#define FASTRPC_DSPSIGNAL_TIMEOUT_NONE 0xffffffff +#define FASTRPC_DSPSIGNAL_NUM_SIGNALS 1024 +#define FASTRPC_DSPSIGNAL_GROUP_SIZE 256 + #define PERF_END ((void)0) #define PERF(enb, cnt, ff) \ @@ -470,8 +474,25 @@ struct fastrpc_user { char *servloc_name; /* Lock for lists */ spinlock_t lock; + /* lock for dsp signals */ + spinlock_t dspsignals_lock; /* lock for allocations */ struct mutex mutex; + struct mutex signal_create_mutex; + /* Completion objects and state for dspsignals */ + struct fastrpc_dspsignal *signal_groups[FASTRPC_DSPSIGNAL_NUM_SIGNALS / FASTRPC_DSPSIGNAL_GROUP_SIZE]; +}; + +enum fastrpc_dspsignal_state { + DSPSIGNAL_STATE_UNUSED = 0, + DSPSIGNAL_STATE_PENDING, + DSPSIGNAL_STATE_SIGNALED, + DSPSIGNAL_STATE_CANCELED, +}; + +struct fastrpc_dspsignal { + struct completion comp; + int state; }; static inline int64_t getnstimediff(struct timespec64 *start) @@ -2098,6 +2119,7 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) struct fastrpc_map *map, *m; struct fastrpc_buf *buf, *b; unsigned long flags; + int i; fastrpc_release_current_dsp_process(fl); @@ -2122,6 +2144,10 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) fastrpc_session_free(cctx, fl->sctx); fastrpc_channel_ctx_put(cctx); + for (i = 0; i < (FASTRPC_DSPSIGNAL_NUM_SIGNALS / FASTRPC_DSPSIGNAL_GROUP_SIZE); i++) + kfree(fl->signal_groups[i]); + + mutex_destroy(&fl->signal_create_mutex); mutex_destroy(&fl->mutex); kfree(fl); file->private_data = NULL; @@ -2149,6 +2175,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) filp->private_data = fl; spin_lock_init(&fl->lock); mutex_init(&fl->mutex); + spin_lock_init(&fl->dspsignals_lock); + mutex_init(&fl->signal_create_mutex); INIT_LIST_HEAD(&fl->pending); INIT_LIST_HEAD(&fl->interrupted); INIT_LIST_HEAD(&fl->maps); @@ -2439,12 +2467,235 @@ static int fastrpc_internal_control(struct fastrpc_user *fl, return err; } +static int fastrpc_dspsignal_signal(struct fastrpc_user *fl, + struct fastrpc_internal_dspsignal *fsig) +{ + int err = 0; + struct fastrpc_channel_ctx *cctx = NULL; + u64 msg = 0; + u32 signal_id = fsig->signal_id; + + cctx = fl->cctx; + + if (!(signal_id < FASTRPC_DSPSIGNAL_NUM_SIGNALS)) + return -EINVAL; + + msg = (((uint64_t)fl->tgid) << 32) | ((uint64_t)fsig->signal_id); + err = rpmsg_send(cctx->rpdev->ept, (void *)&msg, sizeof(msg)); + + return err; +} + +static int fastrpc_dspsignal_wait(struct fastrpc_user *fl, + struct fastrpc_internal_dspsignal *fsig) +{ + int err = 0; + unsigned long timeout = usecs_to_jiffies(fsig->timeout_usec); + u32 signal_id = fsig->signal_id; + struct fastrpc_dspsignal *s = NULL; + long ret = 0; + unsigned long irq_flags = 0; + + if (!(signal_id < FASTRPC_DSPSIGNAL_NUM_SIGNALS)) + return -EINVAL; + + spin_lock_irqsave(&fl->dspsignals_lock, irq_flags); + if (fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE] != NULL) { + struct fastrpc_dspsignal *group = + fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE]; + + s = &group[signal_id % FASTRPC_DSPSIGNAL_GROUP_SIZE]; + } + if ((s == NULL) || (s->state == DSPSIGNAL_STATE_UNUSED)) { + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + dev_err(&fl->cctx->rpdev->dev, "Unknown signal id %u\n", signal_id); + return -ENOENT; + } + if (s->state != DSPSIGNAL_STATE_PENDING) { + if ((s->state == DSPSIGNAL_STATE_CANCELED) || (s->state == DSPSIGNAL_STATE_UNUSED)) + err = -EINTR; + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + dev_dbg(&fl->cctx->rpdev->dev, "Signal %u in state %u, complete wait immediately", + signal_id, s->state); + return err; + } + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + + if (timeout != 0xffffffff) + ret = wait_for_completion_interruptible_timeout(&s->comp, timeout); + else + ret = wait_for_completion_interruptible(&s->comp); + + if (ret == 0) { + dev_dbg(&fl->cctx->rpdev->dev, "Wait for signal %u timed out\n", signal_id); + return -ETIMEDOUT; + } else if (ret < 0) { + dev_err(&fl->cctx->rpdev->dev, "Wait for signal %u failed %d\n", signal_id, (int)ret); + return ret; + } + + spin_lock_irqsave(&fl->dspsignals_lock, irq_flags); + if (s->state == DSPSIGNAL_STATE_SIGNALED) { + s->state = DSPSIGNAL_STATE_PENDING; + } else if ((s->state == DSPSIGNAL_STATE_CANCELED) || (s->state == DSPSIGNAL_STATE_UNUSED)) { + dev_err(&fl->cctx->rpdev->dev, "Signal %u cancelled or destroyed\n", signal_id); + err = -EINTR; + } + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + + return err; +} + +static int fastrpc_dspsignal_create(struct fastrpc_user *fl, + struct fastrpc_internal_dspsignal *fsig) +{ + int err = 0; + u32 signal_id = fsig->signal_id; + struct fastrpc_dspsignal *group, *sig; + unsigned long irq_flags = 0; + + if (!(signal_id < FASTRPC_DSPSIGNAL_NUM_SIGNALS)) + return -EINVAL; + + mutex_lock(&fl->signal_create_mutex); + spin_lock_irqsave(&fl->dspsignals_lock, irq_flags); + + group = fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE]; + if (group == NULL) { + int i; + + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + group = kcalloc(FASTRPC_DSPSIGNAL_GROUP_SIZE, sizeof(*group), + GFP_KERNEL); + if (group == NULL) { + mutex_unlock(&fl->signal_create_mutex); + return -ENOMEM; + } + + for (i = 0; i < FASTRPC_DSPSIGNAL_GROUP_SIZE; i++) { + sig = &group[i]; + init_completion(&sig->comp); + sig->state = DSPSIGNAL_STATE_UNUSED; + } + spin_lock_irqsave(&fl->dspsignals_lock, irq_flags); + fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE] = group; + } + + sig = &group[signal_id % FASTRPC_DSPSIGNAL_GROUP_SIZE]; + if (sig->state != DSPSIGNAL_STATE_UNUSED) { + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + mutex_unlock(&fl->signal_create_mutex); + dev_err(&fl->cctx->rpdev->dev, "Attempting to create signal %u already in use (state %u)\n", + signal_id, sig->state); + return -EBUSY; + } + + sig->state = DSPSIGNAL_STATE_PENDING; + reinit_completion(&sig->comp); + + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + mutex_unlock(&fl->signal_create_mutex); + + return err; +} + +static int fastrpc_dspsignal_destroy(struct fastrpc_user *fl, + struct fastrpc_internal_dspsignal *fsig) +{ + u32 signal_id = fsig->signal_id; + struct fastrpc_dspsignal *s = NULL; + unsigned long irq_flags = 0; + + if (!(signal_id < FASTRPC_DSPSIGNAL_NUM_SIGNALS)) + return -EINVAL; + + spin_lock_irqsave(&fl->dspsignals_lock, irq_flags); + + if (fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE] != NULL) { + struct fastrpc_dspsignal *group = + fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE]; + + s = &group[signal_id % FASTRPC_DSPSIGNAL_GROUP_SIZE]; + } + if ((s == NULL) || (s->state == DSPSIGNAL_STATE_UNUSED)) { + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + dev_err(&fl->cctx->rpdev->dev, "Attempting to destroy unused signal %u\n", signal_id); + return -ENOENT; + } + + s->state = DSPSIGNAL_STATE_UNUSED; + complete_all(&s->comp); + + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + + return 0; +} + +static int fastrpc_dspsignal_cancel_wait(struct fastrpc_user *fl, + struct fastrpc_internal_dspsignal *fsig) +{ + u32 signal_id = fsig->signal_id; + struct fastrpc_dspsignal *s = NULL; + unsigned long irq_flags = 0; + + if (!(signal_id < FASTRPC_DSPSIGNAL_NUM_SIGNALS)) + return -EINVAL; + + spin_lock_irqsave(&fl->dspsignals_lock, irq_flags); + + if (fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE] != NULL) { + struct fastrpc_dspsignal *group = + fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE]; + + s = &group[signal_id % FASTRPC_DSPSIGNAL_GROUP_SIZE]; + } + if ((s == NULL) || (s->state == DSPSIGNAL_STATE_UNUSED)) { + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + dev_err(&fl->cctx->rpdev->dev, "Attempting to cancel unused signal %u\n", signal_id); + return -ENOENT; + } + + if (s->state != DSPSIGNAL_STATE_CANCELED) { + s->state = DSPSIGNAL_STATE_CANCELED; + complete_all(&s->comp); + } + + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); + + return 0; +} + +static int fastrpc_invoke_dspsignal(struct fastrpc_user *fl, struct fastrpc_internal_dspsignal *fsig) +{ + int err = 0; + + switch (fsig->req) { + case FASTRPC_DSPSIGNAL_SIGNAL: + err = fastrpc_dspsignal_signal(fl, fsig); + break; + case FASTRPC_DSPSIGNAL_WAIT: + err = fastrpc_dspsignal_wait(fl, fsig); + break; + case FASTRPC_DSPSIGNAL_CREATE: + err = fastrpc_dspsignal_create(fl, fsig); + break; + case FASTRPC_DSPSIGNAL_DESTROY: + err = fastrpc_dspsignal_destroy(fl, fsig); + break; + case FASTRPC_DSPSIGNAL_CANCEL_WAIT: + err = fastrpc_dspsignal_cancel_wait(fl, fsig); + break; + } + return err; +} + static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_enhanced_invoke einv; struct fastrpc_invoke_args *args = NULL; struct fastrpc_ioctl_multimode_invoke invoke; struct fastrpc_internal_control cp = {0}; + struct fastrpc_internal_dspsignal *fsig = NULL; struct fastrpc_internal_notif_rsp notif; u32 nscalars; u64 *perf_kernel; @@ -2465,7 +2716,7 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) case FASTRPC_INVOKE_ENHANCED: /* nscalars is truncated here to max supported value */ if (copy_from_user(&einv, (void __user *)(uintptr_t)invoke.invparam, - invoke.size)) + sizeof(struct fastrpc_enhanced_invoke))) return -EFAULT; for (i = 0; i < 8; i++) { if (einv.reserved[i] != 0) @@ -2495,6 +2746,19 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp) err = fastrpc_internal_control(fl, &cp); break; + case FASTRPC_INVOKE_DSPSIGNAL: + if (invoke.size > sizeof(*fsig)) + return -EINVAL; + fsig = kzalloc(invoke.size, GFP_KERNEL); + if (!fsig) + return -ENOMEM; + if (copy_from_user(fsig, (void __user *)(uintptr_t)invoke.invparam, + sizeof(*fsig))) { + kfree(fsig); + return -EFAULT; + } + err = fastrpc_invoke_dspsignal(fl, fsig); + break; case FASTRPC_INVOKE_NOTIF: err = fastrpc_get_notif_response(¬if, (void *)invoke.invparam, fl); @@ -3526,6 +3790,42 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) fastrpc_channel_ctx_put(cctx); } +static void fastrpc_handle_signal_rpmsg(uint64_t msg, struct fastrpc_channel_ctx *cctx) +{ + u32 pid = msg >> 32; + u32 signal_id = msg & 0xffffffff; + struct fastrpc_user *fl; + unsigned long irq_flags = 0; + + if (signal_id >= FASTRPC_DSPSIGNAL_NUM_SIGNALS) + return; + + list_for_each_entry(fl, &cctx->users, user) { + if (fl->tgid == pid) + break; + } + + spin_lock_irqsave(&fl->dspsignals_lock, irq_flags); + if (fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE]) { + struct fastrpc_dspsignal *group = + fl->signal_groups[signal_id / FASTRPC_DSPSIGNAL_GROUP_SIZE]; + struct fastrpc_dspsignal *sig = + &group[signal_id % FASTRPC_DSPSIGNAL_GROUP_SIZE]; + if ((sig->state == DSPSIGNAL_STATE_PENDING) || + (sig->state == DSPSIGNAL_STATE_SIGNALED)) { + complete(&sig->comp); + sig->state = DSPSIGNAL_STATE_SIGNALED; + } else if (sig->state == DSPSIGNAL_STATE_UNUSED) { + pr_err("Received unknown signal %u for PID %u\n", + signal_id, pid); + } + } else { + pr_err("Received unknown signal %u for PID %u\n", + signal_id, pid); + } + spin_unlock_irqrestore(&fl->dspsignals_lock, irq_flags); +} + static void fastrpc_notify_user_ctx(struct fastrpc_invoke_ctx *ctx, int retval, u32 rsp_flags, u32 early_wake_time) { @@ -3564,6 +3864,11 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, u32 rsp_flags = 0; u32 early_wake_time = 0; + if (len == sizeof(uint64_t)) { + fastrpc_handle_signal_rpmsg(*((uint64_t *)data), cctx); + return 0; + } + if (notif->ctx == FASTRPC_NOTIF_CTX_RESERVED) { if (notif->type == STATUS_RESPONSE && len >= sizeof(*notif)) { fastrpc_notif_find_process(cctx->domain_id, cctx, notif); diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index f4c73f6774f7..7053a5b6b16b 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -211,6 +211,15 @@ struct fastrpc_internal_notif_rsp { u32 status; /* Status of the process */ }; +struct fastrpc_internal_dspsignal { + u32 req; + u32 signal_id; + union { + u32 flags; + u32 timeout_usec; + }; +}; + enum fastrpc_perfkeys { PERF_COUNT = 0, PERF_FLUSH = 1, @@ -225,6 +234,14 @@ enum fastrpc_perfkeys { PERF_KEY_MAX = 10, }; +enum fastrpc_dspsignal_type { + FASTRPC_DSPSIGNAL_SIGNAL = 1, + FASTRPC_DSPSIGNAL_WAIT = 2, + FASTRPC_DSPSIGNAL_CREATE = 3, + FASTRPC_DSPSIGNAL_DESTROY = 4, + FASTRPC_DSPSIGNAL_CANCEL_WAIT = 5, +}; + enum fastrpc_status_flags { FASTRPC_USERPD_UP = 0, FASTRPC_USERPD_EXIT = 1, From patchwork Fri Feb 2 06:40:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542158 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 68C6547A76; Fri, 2 Feb 2024 06:41:24 +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=1706856086; cv=none; b=CRTuxeOjrA1oHkIynJlZhRS2mufLJ3YQMcEh4Xnq9YgME7GUiBJl3++eUFxrnyHL6Df65zTtV50oZ9Uz+yvaYXXxZpueSVtyrq7ZLHfvNCovIDT1L3QLd9gMkVpo4vLlZB32z7tfQN6JyPa8gELSGZJz723geO+EZAR5kSbB9xI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856086; c=relaxed/simple; bh=qbNEGZz2C4Gx3HMPisN75TK8yz+GYjwi6ez/CMvVt6o=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=mDHiDsUhVpF6cBTfHm7ZaurNfdVWXhE+M78QSdZV16AOJk4lMysLiHZ3XrLQBYSJ2pmdex7sV7l4sj3ALdJjpNTfTkO8e/Yx1zvZ3konH+x52pyBaQXmDK1rxuKXUZwqo2+eHps0OUJykqk1jcShyBNi+eE9OBVcEECtTcFXVMM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=YWCb/Qxe; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="YWCb/Qxe" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4126A0IY017772; Fri, 2 Feb 2024 06:41:22 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=LCXm5lUyxmruJ09/Ia5z NnoeixYPjyKFDjc2aPuwBcM=; b=YWCb/QxeUO512bf1XYcGTvzSUUY8dVYr+uEW hJALsDgpmO5pdjsQZlf+ipIiXg/8jCUdNQANSX/bbMu2UEVaEKUuIeNs1PO+u8ff MN+hflJj8dZAWgBQ1kn0dho+8o0YXjgCTTpPUSsxHHCp2OfAlVOxCDMa12ubXESX 7fUiidjoF8U3ODsjsDgc69kzZmkzv5LuuwjKsx8bs4D6xTng0oE2GdaaLUGtslZt fWOra5AgQciKjipfgwjQySESr+cxqPONX0JLclxcyh1LBYx4S5evTWScP6jqnr4v BJGqW2kfmP552X+Q+FcGaDoLX6WXzeobCpoGex1I4xozbPVfjA== Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0ptxgnpg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:22 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126fLfE002710 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:21 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:19 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 15/16] misc: fastrpc: Restrict untrusted apk to spawn privileged PD Date: Fri, 2 Feb 2024 12:10:38 +0530 Message-ID: <20240202064039.15505-16-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: -YarlE4HGTE6R_7E4QvVLmPChXBLSlkc X-Proofpoint-GUID: -YarlE4HGTE6R_7E4QvVLmPChXBLSlkc X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 adultscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 spamscore=0 suspectscore=0 mlxlogscore=581 mlxscore=0 phishscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Untrusted application can attach to guestOS and staticPD if it can make root PD, sensors PD or audio PD attach request. This is a potential security issue as the untrusted application can crash rootPD or staticPD. Restrict attach to guestOS or staticPD request if request is being made using non-secure device node. Also for untrusted dynamic processes, DSP HAL process opens the device node on behalf of the application. Add a check to restrict such untrusted applications from offloading to signed PD. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 0308f717456f..4aa4e36bebc3 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -471,6 +471,7 @@ struct fastrpc_user { bool sharedcb; /* If set, threads will poll for DSP response instead of glink wait */ bool poll_mode; + bool untrusted_process; char *servloc_name; /* Lock for lists */ spinlock_t lock; @@ -1722,20 +1723,24 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, static bool is_session_rejected(struct fastrpc_user *fl, bool unsigned_pd_request) { - /* Check if the device node is non-secure and channel is secure*/ + /* Check if the device node is non-secure and channel is secure */ if (!fl->is_secure_dev && fl->cctx->secure) { /* * Allow untrusted applications to offload only to Unsigned PD when * channel is configured as secure and block untrusted apps on channel * that does not support unsigned PD offload */ - if (!fl->cctx->unsigned_support || !unsigned_pd_request) { - dev_err(&fl->cctx->rpdev->dev, "Error: Untrusted application trying to offload to signed PD"); - return true; - } + if (!fl->cctx->unsigned_support || !unsigned_pd_request) + goto reject_session; } + /* Check if untrusted process is trying to offload to signed PD */ + if (fl->untrusted_process && !unsigned_pd_request) + goto reject_session; return false; +reject_session: + dev_err(&fl->cctx->rpdev->dev, "Error: Untrusted application trying to offload to signed PD"); + return true; } static int fastrpc_mmap_remove_ssr(struct fastrpc_channel_ctx *cctx) @@ -1822,6 +1827,11 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, u32 pageslen; } inbuf; + if (!fl->is_secure_dev) { + dev_err(&fl->cctx->rpdev->dev, "untrusted app trying to attach to privileged DSP PD\n"); + return -EACCES; + } + args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL); if (!args) return -ENOMEM; @@ -1981,11 +1991,19 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, goto err; } + /* + * Third-party apps don't have permission to open the fastrpc device, so + * it is opened on their behalf by DSP HAL. This is detected by + * comparing current PID with the one stored during device open. + */ + if (current->tgid != fl->tgid) + fl->untrusted_process = true; + if (init.attrs & FASTRPC_MODE_UNSIGNED_MODULE) fl->is_unsigned_pd = true; if (is_session_rejected(fl, fl->is_unsigned_pd)) { - err = -ECONNREFUSED; + err = -EACCES; goto err; } @@ -2244,6 +2262,11 @@ static int fastrpc_init_attach(struct fastrpc_user *fl, int pd) struct fastrpc_enhanced_invoke ioctl; int tgid = fl->tgid; + if (!fl->is_secure_dev) { + dev_err(&fl->cctx->rpdev->dev, "untrusted app trying to attach to privileged DSP PD\n"); + return -EACCES; + } + fl->sctx = fastrpc_session_alloc(fl->cctx, fl->sharedcb); if (!fl->sctx) return -EBUSY; From patchwork Fri Feb 2 06:40:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ekansh Gupta X-Patchwork-Id: 13542159 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 A937B481A5; Fri, 2 Feb 2024 06:41:26 +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=1706856088; cv=none; b=jvRGiG9imlAqpO7UpHot6urrnYUX0RKYebkjmOYOBLK/E2f/APm0Zih56LdkYfz5VMOv+sjh6ApnLzioJ+egPSIEu/PrOccmMQJHKv1grs7ID7929+3xQEK7+md3Bnr8jS/T5vyf6Hd3xJBHQ7hxSwcZlQlvRkxf2E/crMFSQ98= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706856088; c=relaxed/simple; bh=ZDnGKGfbR/v3Yx+LWz4vHfhF/MSvu7CCgdFnaeoJrQM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=afUb2iRpfBuQkrP+2w4mWMSR1dulfosAdPVl35eqY65uV06rzIPh2+tjo5Xs0L8lXbbgH52M5jrjldUrFpoevrao+FEPZTLGPs3Co9j2dVq9EDXLpXJf3jgX0Gsz0eQM9sPbItp9awcdyRxZIGGGGteC5zt908syrzObGWuXm8Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=eJ6aqHIm; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="eJ6aqHIm" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 4124aHeJ005911; Fri, 2 Feb 2024 06:41:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=joizP/oCmG0LM1+iiXJ4 kYTWEPaLDXDLpePwjwt1kV0=; b=eJ6aqHIm1IZ+4TntyRvYcDjEH6HLcT+fKvrH tXp2HOnjDOdHbkOza6lqfc3ji4jfHbgzJqPsy5ZqnvCvkkFN/rMBWRkSIIDUgF+d ahlQ9DUCneog5qj8as2WAiNiK3zrN0/nh0+UwL/1IVIefr9NwhzLFeAREs2QmIpe xDT4Ri3/7EpyeO1pH9+7mvTHQjrgOzggXYe2lU2sXS4eX+bSclZkNoEOUWa+bwWO lgWYmSh0UzPQwceL1J1PPiLlj9ahc/ae+iOb617UwlbRP4bMMQmxaX/ogK7NYi/W USFFyuDiApIQUxXcKvMxRg52w3bE6sLuVYSqpe1rxBnJHvX3YQ== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w0ptu0nya-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 02 Feb 2024 06:41:24 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4126fNxW004876 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 2 Feb 2024 06:41:23 GMT Received: from hu-ekangupt-hyd.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 1 Feb 2024 22:41:21 -0800 From: Ekansh Gupta To: , CC: , Subject: [PATCH v1 16/16] misc: fastrpc: Add system unsigned PD support Date: Fri, 2 Feb 2024 12:10:39 +0530 Message-ID: <20240202064039.15505-17-quic_ekangupt@quicinc.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20240202064039.15505-1-quic_ekangupt@quicinc.com> References: <20240202064039.15505-1-quic_ekangupt@quicinc.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 7oMHNIU_IpdEdGw41FrG_bnTeYlAvhMN X-Proofpoint-ORIG-GUID: 7oMHNIU_IpdEdGw41FrG_bnTeYlAvhMN X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-01_10,2024-01-31_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 suspectscore=0 phishscore=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 bulkscore=0 mlxlogscore=999 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402020047 Trusted CPU applications currently offload to signed PDs on CDSP to gain some additional services provided by root PD. Unsigned PDs have access to limited root PD services that may not be sufficient for all use-cases. Signed PDs have a higher dynamic loading latency which impacts the performance of applications. Limited root PD services could be opened up for unsigned PDs but that should be restricted for untrusted processes. For this requirement, System unsigned PD is introduced which will be same as Unsigned PD for most part but will have access to more root PD services. Add changes to offload trusted applications to System unsigned PD when unsigned offload is requested. Signed-off-by: Ekansh Gupta --- drivers/misc/fastrpc.c | 7 +++++++ include/uapi/misc/fastrpc.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 4aa4e36bebc3..2f893c94dcc8 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -2002,11 +2002,18 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, if (init.attrs & FASTRPC_MODE_UNSIGNED_MODULE) fl->is_unsigned_pd = true; + /* Disregard any system unsigned PD attribute from userspace */ + init.attrs &= (~FASTRPC_MODE_SYSTEM_UNSIGNED_PD); + if (is_session_rejected(fl, fl->is_unsigned_pd)) { err = -EACCES; goto err; } + /* Trusted apps will be launched as system unsigned PDs */ + if (!fl->untrusted_process && fl->is_unsigned_pd) + init.attrs |= FASTRPC_MODE_SYSTEM_UNSIGNED_PD; + if (init.filelen > INIT_FILELEN_MAX) { err = -EINVAL; goto err; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index 7053a5b6b16b..d0fb01e7277d 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -63,6 +63,8 @@ enum fastrpc_proc_attr { FASTRPC_MODE_SYSTEM_PROCESS = (1 << 5), /* Macro for Prvileged Process */ FASTRPC_MODE_PRIVILEGED = (1 << 6), + /* Macro for system unsigned PD */ + FASTRPC_MODE_SYSTEM_UNSIGNED_PD = (1 << 17), }; /* Fastrpc attribute for memory protection of buffers */