From patchwork Fri Feb 8 17:11:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 157858 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2195216jaa; Fri, 8 Feb 2019 09:13:37 -0800 (PST) X-Google-Smtp-Source: AHgI3IYKSK9V1aM/Q4ncqPWT7O/TeQQzEd9V8oHuessaGKAuO68VKuWw5+cK0q3J1LkeDZD2+4oB X-Received: by 2002:a17:902:684:: with SMTP id 4mr23619117plh.3.1549646017568; Fri, 08 Feb 2019 09:13:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549646017; cv=none; d=google.com; s=arc-20160816; b=Xqcvg9OBeGTxgvhCmJ+dT8EHBLjB2P0pqivmjkBGgcxJGcjvq+xEcPGHHFTGyfRGYl iFFS2aBQB+ACtuNH0U36FqMU1JUmJDphERv1Qi1TaAitssZfogz9yqXCB/6nXKr/hDal 8JCw+mB3dC++mwwTXkdUJbcVSQF15prALcO5+ah1GYDjzGUrJ4k+yAvRKRhiZDzQ8ZqA yvJOc37kEcDBWLyETGOkybKlf+3wjW6iz5EMqL1e5hBqwaE8x9oVqxA5D77Z9GB1Ekl7 DaM6p0n0jAupmpQof9MUB3WwihKkfpQJgKLMzBGndON9dpzXahf/nuCiFls1tviULmhW jASQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Pw02RysD3yARf0G9aEsHcDFW4VSiASPNF5YAbP0ZM24=; b=gIR7GPQdz8MW52sGFcTb0hUtzC+8q7j7d5h4jwKCk31SXKc5mDU9l3R7X7sHyOOEoN OBum4MG9Dp1NwOjwFYiBQaGeNQcIHIzL6FqpA0gLsxJ8FxUEz4UwDjb3nE6Oc7SQbPtx clU6+br6d+h0awnF+WA6+QPhpQ50Xst9adplWrb9flq3vvfgNs5GBZB/LMqb7vLsV94N dbxOwRamjUrVddPC2vgAFX1rHBHADE6arYFdNBkztm5kMMOlvcg+f6beMDH5hasi7J56 3/z0i0+EQureKfevg1A5/j9P6APlNiJkDQpqvq/dObeIl3miVXC9zu+5FgEEY6vObaKL cOvA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aMyRio0w; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r5si2585928pgr.482.2019.02.08.09.13.37; Fri, 08 Feb 2019 09:13:37 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aMyRio0w; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727912AbfBHRNg (ORCPT + 7 others); Fri, 8 Feb 2019 12:13:36 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:36729 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727880AbfBHRNf (ORCPT ); Fri, 8 Feb 2019 12:13:35 -0500 Received: by mail-wm1-f66.google.com with SMTP id p6so4146607wmc.1 for ; Fri, 08 Feb 2019 09:13:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Pw02RysD3yARf0G9aEsHcDFW4VSiASPNF5YAbP0ZM24=; b=aMyRio0wQzWbiR+AyTuJpioEIXdfpo8+3i/n5R4zaIsRYWbm9O1uCvgYDr75XR39mC 1lTxFNDNmxtJzegSwfZfTMVXlevgyoBjW6+up3aICJrGhvWnELH/lPUbcyNKKhgvRSry I66BXAQgL0Sgcc9qADz/pCpCJJ+aCpzlpVpFGeiqLMvTpfrQJfRasLmE1EEl6Tz1GJyP iOhqICndPt7Sn4+Ehy6/ceLc7ht6Dl1E5WCuXJc3ZHwMHpsOdJiwFbxti/BXT3Wkl0Fg Dt/1HyPEYAX9y6h7wvozc+IlhV9a8PqODRjZubMmzeIPRRbVio95AE7yu+I8VMIQmB5c 43aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Pw02RysD3yARf0G9aEsHcDFW4VSiASPNF5YAbP0ZM24=; b=ojJP4xVO+5nPhGlFOD+La2wEee1YFeabrMS4qP6iOzO3CLaJo1kuPrLPXULGs1ocHQ ZmVmmV3kSMRwsSHWET1ltvVtKj7PvGCgsAKXhJHKStOB6KNcL+lRnjCtpVPlKMRsHBiR PkoKGPEDueSKt8B6q9AUwSeez8asPf0TTsa2FQCWw6W44fdzeaM5kzGLSQ8DOXxgoYeG SozGY+CfdKL0E7mgaJcoxWvNuqFQ7mVUIeRDrC1HFfKgjuZ+JPVg1AmP7g2KCwy4gO3p njc7Kw6baVT/4poizTfajGB+Dvl1Fq9CCTlJ75dHBpSp/vbxH0AeoNkdA4cW+NC9K9EW eYnQ== X-Gm-Message-State: AHQUAuZrjbfaTsopX2T6ztDc8VwvqXaFnuE1VVvWTJfalFWezQan3U6p jlY1+LXBlqccEpzSO756nDcXFw== X-Received: by 2002:a1c:f00a:: with SMTP id a10mr2730227wmb.148.1549646012897; Fri, 08 Feb 2019 09:13:32 -0800 (PST) Received: from srini-hackbox.lan (cpc89974-aztw32-2-0-cust43.18-1.cable.virginm.net. [86.30.250.44]) by smtp.gmail.com with ESMTPSA id f139sm4521634wmd.19.2019.02.08.09.13.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 08 Feb 2019 09:13:32 -0800 (PST) From: Srinivas Kandagatla To: gregkh@linuxfoundation.org, arnd@arndb.de Cc: robh+dt@kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, bjorn.andersson@linaro.org, bkumar@qti.qualcomm.com, linux-arm-msm@vger.kernel.org, Srinivas Kandagatla , Thierry Escande Subject: [PATCH v7 4/5] misc: fastrpc: Add support for create remote init process Date: Fri, 8 Feb 2019 17:11:26 +0000 Message-Id: <20190208171127.24168-5-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190208171127.24168-1-srinivas.kandagatla@linaro.org> References: <20190208171127.24168-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds support to create or attach remote shell process. The shell process called fastrpc_shell_0 is usually loaded on the DSP when a user process is spawned. Most of the work is derived from various downstream Qualcomm kernels. Credits to various Qualcomm authors who have contributed to this code. Specially Tharun Kumar Merugu Co-developed-by: Thierry Escande Signed-off-by: Thierry Escande Signed-off-by: Srinivas Kandagatla --- drivers/misc/fastrpc.c | 156 ++++++++++++++++++++++++++++++++++++ include/uapi/misc/fastrpc.h | 10 +++ 2 files changed, 166 insertions(+) -- 2.20.1 diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index cd69f8b308f6..ceb498487569 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -29,7 +29,10 @@ #define FASTRPC_MAX_CRCLIST 64 #define FASTRPC_PHYS(p) ((p) & 0xffffffff) #define FASTRPC_CTX_MAX (256) +#define FASTRPC_INIT_HANDLE 1 #define FASTRPC_CTXID_MASK (0xFF0) +#define INIT_FILELEN_MAX (2 * 1024 * 1024) +#define INIT_MEMLEN_MAX (8 * 1024 * 1024) #define FASTRPC_DEVICE_NAME "fastrpc" /* Retrives number of input buffers from the scalars parameter */ @@ -59,6 +62,14 @@ #define FASTRPC_SCALARS(method, in, out) \ FASTRPC_BUILD_SCALARS(0, method, in, out, 0, 0) +#define FASTRPC_CREATE_PROCESS_NARGS 6 +/* Remote Method id table */ +#define FASTRPC_RMID_INIT_ATTACH 0 +#define FASTRPC_RMID_INIT_RELEASE 1 +#define FASTRPC_RMID_INIT_CREATE 6 +#define FASTRPC_RMID_INIT_CREATE_ATTR 7 +#define FASTRPC_RMID_INIT_CREATE_STATIC 8 + #define miscdev_to_cctx(d) container_of(d, struct fastrpc_channel_ctx, miscdev) static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp", @@ -688,6 +699,109 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, return err; } +static int fastrpc_init_create_process(struct fastrpc_user *fl, + char __user *argp) +{ + struct fastrpc_init_create init; + struct fastrpc_invoke_args *args; + struct fastrpc_phy_page pages[1]; + struct fastrpc_map *map = NULL; + struct fastrpc_buf *imem = NULL; + int memlen; + int err; + struct { + int pgid; + u32 namelen; + u32 filelen; + u32 pageslen; + u32 attrs; + u32 siglen; + } inbuf; + u32 sc; + + args = kcalloc(FASTRPC_CREATE_PROCESS_NARGS, sizeof(*args), GFP_KERNEL); + if (!args) + return -ENOMEM; + + if (copy_from_user(&init, argp, sizeof(init))) { + err = -EFAULT; + goto bail; + } + + if (init.filelen > INIT_FILELEN_MAX) { + err = -EINVAL; + goto bail; + } + + inbuf.pgid = fl->tgid; + inbuf.namelen = strlen(current->comm) + 1; + inbuf.filelen = init.filelen; + inbuf.pageslen = 1; + inbuf.attrs = init.attrs; + inbuf.siglen = init.siglen; + fl->pd = 1; + + if (init.filelen && init.filefd) { + err = fastrpc_map_create(fl, init.filefd, init.filelen, &map); + if (err) + goto bail; + } + + memlen = ALIGN(max(INIT_FILELEN_MAX, (int)init.filelen * 4), + 1024 * 1024); + err = fastrpc_buf_alloc(fl, fl->sctx->dev, memlen, + &imem); + if (err) { + fastrpc_map_put(map); + goto bail; + } + + fl->init_mem = imem; + args[0].ptr = (u64)(uintptr_t)&inbuf; + args[0].length = sizeof(inbuf); + args[0].fd = -1; + + args[1].ptr = (u64)(uintptr_t)current->comm; + args[1].length = inbuf.namelen; + args[1].fd = -1; + + args[2].ptr = (u64) init.file; + args[2].length = inbuf.filelen; + args[2].fd = init.filefd; + + pages[0].addr = imem->phys; + pages[0].size = imem->size; + + args[3].ptr = (u64)(uintptr_t) pages; + args[3].length = 1 * sizeof(*pages); + args[3].fd = -1; + + args[4].ptr = (u64)(uintptr_t)&inbuf.attrs; + args[4].length = sizeof(inbuf.attrs); + args[4].fd = -1; + + args[5].ptr = (u64)(uintptr_t) &inbuf.siglen; + args[5].length = sizeof(inbuf.siglen); + args[5].fd = -1; + + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0); + if (init.attrs) + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 6, 0); + + err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, + sc, args); + + if (err) { + fastrpc_map_put(map); + fastrpc_buf_free(imem); + } + +bail: + kfree(args); + + return err; +} + static struct fastrpc_session_ctx *fastrpc_session_alloc( struct fastrpc_channel_ctx *cctx) { @@ -715,6 +829,23 @@ static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx, spin_unlock(&cctx->lock); } +static int fastrpc_release_current_dsp_process(struct fastrpc_user *fl) +{ + struct fastrpc_invoke_args args[1]; + int tgid = 0; + u32 sc; + + tgid = fl->tgid; + args[0].ptr = (u64)(uintptr_t) &tgid; + args[0].length = sizeof(tgid); + args[0].fd = -1; + args[0].reserved = 0; + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0); + + return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, + sc, &args[0]); +} + static int fastrpc_device_release(struct inode *inode, struct file *file) { struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data; @@ -722,6 +853,8 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) struct fastrpc_invoke_ctx *ctx, *n; struct fastrpc_map *map, *m; + fastrpc_release_current_dsp_process(fl); + spin_lock(&cctx->lock); list_del(&fl->user); spin_unlock(&cctx->lock); @@ -773,6 +906,23 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) return 0; } +static int fastrpc_init_attach(struct fastrpc_user *fl) +{ + struct fastrpc_invoke_args args[1]; + int tgid = fl->tgid; + u32 sc; + + args[0].ptr = (u64)(uintptr_t) &tgid; + args[0].length = sizeof(tgid); + args[0].fd = -1; + args[0].reserved = 0; + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0); + fl->pd = 0; + + return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, + sc, &args[0]); +} + static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_invoke_args *args = NULL; @@ -814,6 +964,12 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, case FASTRPC_IOCTL_INVOKE: err = fastrpc_invoke(fl, argp); break; + case FASTRPC_IOCTL_INIT_ATTACH: + err = fastrpc_init_attach(fl); + break; + case FASTRPC_IOCTL_INIT_CREATE: + err = fastrpc_init_create_process(fl, argp); + break; default: err = -ENOTTY; break; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index a69ef33dc37e..32d191c3b7bc 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -6,6 +6,8 @@ #include #define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_invoke) +#define FASTRPC_IOCTL_INIT_ATTACH _IO('R', 4) +#define FASTRPC_IOCTL_INIT_CREATE _IOWR('R', 5, struct fastrpc_init_create) struct fastrpc_invoke_args { __u64 ptr; @@ -20,4 +22,12 @@ struct fastrpc_invoke { __u64 args; }; +struct fastrpc_init_create { + __u32 filelen; /* elf file length */ + __s32 filefd; /* fd for the file */ + __u32 attrs; + __u32 siglen; + __u64 file; /* pointer to elf file */ +}; + #endif /* __QCOM_FASTRPC_H__ */ From patchwork Fri Feb 8 17:11:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 157860 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2195445jaa; Fri, 8 Feb 2019 09:13:50 -0800 (PST) X-Google-Smtp-Source: AHgI3IYUDK3ikpIHhsSF1E7iOwtdbKuTk8eKFRkwMDT5oqidBp7K9FPVqo2Sz1xMg1/VSK96NlhH X-Received: by 2002:a17:902:7581:: with SMTP id j1mr23642034pll.260.1549646030569; Fri, 08 Feb 2019 09:13:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549646030; cv=none; d=google.com; s=arc-20160816; b=iss0t9gOpIVoSs6H41QhANO0zn0yXGMS8Jt0mqUhGhoVnJ7BeToYAXCuoQcOiR0pGU wGKYQmc7URNqR2sdpYHMhvYX71rxPfuTp8v70YaCyNjLgiViidOb/WJvlZOLZSfBPjAt zBZY31+jbZ2zKNEamlDI35LC5iU9kex5C9K5BBxFrOmi44k1CE59YFQCqHtW2VIOEyiA RgTqh3NUgUqcFZa+hBR3AnutQsyOtFrZKTeROIYyqH/4fvdjueEAgMYBRlFHTU9CeQ7S mnM72dIWSZP53PBNd/FE++qw6OpS8v80M3qwfyeBzHS6Ij7F2D4Ix95eQ/4I5KXyL1XR Kbvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=jLAFz+SLcfOn5L8KoIvA61cF20ujkNrtIV9nbAA85VI=; b=kffNAK/l+7Idio0wMZQPIJmY8Cu+v97QzD2R9fhJqxoJ91+umRYSesbOHYSkaFJE5H DdiYXmCqUdUAnGzHzVSTztWqR9xmUUXQGByub9sc+ymdaJs34MG8mbrBoBelMDDEw/UY IcolvIaAuM2DVR6rLxq7HjeytGC+y6ICmpXWkGBy26Arwbhrcr5VpXp2KWe4LFHW6Snp RzoteK+aGQ1WabGC5NrVK8AdExDgSZUQyyfxUMiAldVM9hrDPfyC9DxpvT1DgHQwfs0S myosNWsvOFHPt2kTt419sqy+tUjgfxAyGyyMPX7CvaVGOP1J7OG9bykJ9trebjh42jCU uT2Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=j9ItVn2M; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p186si2537477pgp.37.2019.02.08.09.13.50; Fri, 08 Feb 2019 09:13:50 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=j9ItVn2M; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727918AbfBHRNh (ORCPT + 7 others); Fri, 8 Feb 2019 12:13:37 -0500 Received: from mail-wm1-f65.google.com ([209.85.128.65]:55849 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726869AbfBHRNg (ORCPT ); Fri, 8 Feb 2019 12:13:36 -0500 Received: by mail-wm1-f65.google.com with SMTP id r17so4169812wmh.5 for ; Fri, 08 Feb 2019 09:13:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jLAFz+SLcfOn5L8KoIvA61cF20ujkNrtIV9nbAA85VI=; b=j9ItVn2MqVk81W+x1MB5123Xi4cEDE3G2MYyX7Ihu2r3eLN6bHJBniJpE2YDQAHQbV cvuV1VYYNs/LPlRHk4GmFleiApxLL8Y52wxVNtPHiVy3XXZXZKBswlScV1npceFk5SKg f6KUlcb5MCAHDi9fIBsflwfLBiF9sxunVdyOdrSwQ127PyUHgBdK6Slj9sGlfMgHsR4u nWjCcV62GyWWHHN0HYkT5QweSVGNAZvMZtaa0goV6tDpMlGLW8YCR7f34l/eCMbCyYx9 wkevaivOYtjePxbdNIoyKzzfahzIrW7FuvQpBdDdgXo7EvhOnzD5otc34/PlsxlyIufk zaAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jLAFz+SLcfOn5L8KoIvA61cF20ujkNrtIV9nbAA85VI=; b=DoZb4gasWANZLencFaD8tXUy/zEh4DgJs8kPzcnHPWPF80wQBvNhE+T5g4s5j5n4fs WtMoOQrgDZoIz5t/ZMSxlhgwxGuSZ4U74I5WS7ebJ3rO4OxX9h5MR7nOAWECfguJWt6r agE4dzcBWjnjtm960nFvfPTN9uWMwFVssYaIZ6mmdJxKsonaBTpdwrJ+MtVEda4SLFSi sowrTbLP2eZnLUP6OfHPol5IErPpB/LcQOc49OrMzfwuL2g5SnkLXnxaD8jIPFzj6WrX ryr2vHOXcTCr32/6CkLA4BInTzgJKCHzTjIbq8ENTQtZqe6PfOovli1fK6f3uy4T9qCr LfDA== X-Gm-Message-State: AHQUAuaIAgM23tCsIa3lLbGvUunABiiSrup7PxRrZGleYTnW8VQav10e g5kcqBcwXMXVtiyabsNJYW4avQ== X-Received: by 2002:a7b:cd14:: with SMTP id f20mr11577525wmj.93.1549646014819; Fri, 08 Feb 2019 09:13:34 -0800 (PST) Received: from srini-hackbox.lan (cpc89974-aztw32-2-0-cust43.18-1.cable.virginm.net. [86.30.250.44]) by smtp.gmail.com with ESMTPSA id f139sm4521634wmd.19.2019.02.08.09.13.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 08 Feb 2019 09:13:33 -0800 (PST) From: Srinivas Kandagatla To: gregkh@linuxfoundation.org, arnd@arndb.de Cc: robh+dt@kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, bjorn.andersson@linaro.org, bkumar@qti.qualcomm.com, linux-arm-msm@vger.kernel.org, Srinivas Kandagatla , Thierry Escande Subject: [PATCH v7 5/5] misc: fastrpc: Add support for dmabuf exporter Date: Fri, 8 Feb 2019 17:11:27 +0000 Message-Id: <20190208171127.24168-6-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190208171127.24168-1-srinivas.kandagatla@linaro.org> References: <20190208171127.24168-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org User process can involve dealing with big buffer sizes, and also passing buffers from one compute context bank to other compute context bank for complex dsp algorithms. This patch adds support to fastrpc to make it a proper dmabuf exporter to avoid making copies of buffers. Co-developed-by: Thierry Escande Signed-off-by: Thierry Escande Signed-off-by: Srinivas Kandagatla --- drivers/misc/fastrpc.c | 184 ++++++++++++++++++++++++++++++++++++ include/uapi/misc/fastrpc.h | 8 ++ 2 files changed, 192 insertions(+) -- 2.20.1 diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index ceb498487569..4b0db33896df 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -106,10 +106,20 @@ struct fastrpc_invoke_rsp { struct fastrpc_buf { struct fastrpc_user *fl; + struct dma_buf *dmabuf; struct device *dev; void *virt; u64 phys; u64 size; + /* Lock for dma buf attachments */ + struct mutex lock; + struct list_head attachments; +}; + +struct fastrpc_dma_buf_attachment { + struct device *dev; + struct sg_table sgt; + struct list_head node; }; struct fastrpc_map { @@ -246,6 +256,9 @@ static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, if (!buf) return -ENOMEM; + INIT_LIST_HEAD(&buf->attachments); + mutex_init(&buf->lock); + buf->fl = fl; buf->virt = NULL; buf->phys = 0; @@ -360,6 +373,111 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( return ERR_PTR(ret); } +static struct sg_table * +fastrpc_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction dir) +{ + struct fastrpc_dma_buf_attachment *a = attachment->priv; + struct sg_table *table; + + table = &a->sgt; + + if (!dma_map_sg(attachment->dev, table->sgl, table->nents, dir)) + return ERR_PTR(-ENOMEM); + + return table; +} + +static void fastrpc_unmap_dma_buf(struct dma_buf_attachment *attach, + struct sg_table *table, + enum dma_data_direction dir) +{ + dma_unmap_sg(attach->dev, table->sgl, table->nents, dir); +} + +static void fastrpc_release(struct dma_buf *dmabuf) +{ + struct fastrpc_buf *buffer = dmabuf->priv; + + fastrpc_buf_free(buffer); +} + +static int fastrpc_dma_buf_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct fastrpc_dma_buf_attachment *a; + struct fastrpc_buf *buffer = dmabuf->priv; + int ret; + + a = kzalloc(sizeof(*a), GFP_KERNEL); + if (!a) + return -ENOMEM; + + ret = dma_get_sgtable(buffer->dev, &a->sgt, buffer->virt, + FASTRPC_PHYS(buffer->phys), buffer->size); + if (ret < 0) { + dev_err(buffer->dev, "failed to get scatterlist from DMA API\n"); + return -EINVAL; + } + + a->dev = attachment->dev; + INIT_LIST_HEAD(&a->node); + attachment->priv = a; + + mutex_lock(&buffer->lock); + list_add(&a->node, &buffer->attachments); + mutex_unlock(&buffer->lock); + + return 0; +} + +static void fastrpc_dma_buf_detatch(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct fastrpc_dma_buf_attachment *a = attachment->priv; + struct fastrpc_buf *buffer = dmabuf->priv; + + mutex_lock(&buffer->lock); + list_del(&a->node); + mutex_unlock(&buffer->lock); + kfree(a); +} + +static void *fastrpc_kmap(struct dma_buf *dmabuf, unsigned long pgnum) +{ + struct fastrpc_buf *buf = dmabuf->priv; + + return buf->virt ? buf->virt + pgnum * PAGE_SIZE : NULL; +} + +static void *fastrpc_vmap(struct dma_buf *dmabuf) +{ + struct fastrpc_buf *buf = dmabuf->priv; + + return buf->virt; +} + +static int fastrpc_mmap(struct dma_buf *dmabuf, + struct vm_area_struct *vma) +{ + struct fastrpc_buf *buf = dmabuf->priv; + size_t size = vma->vm_end - vma->vm_start; + + return dma_mmap_coherent(buf->dev, vma, buf->virt, + FASTRPC_PHYS(buf->phys), size); +} + +static const struct dma_buf_ops fastrpc_dma_buf_ops = { + .attach = fastrpc_dma_buf_attach, + .detach = fastrpc_dma_buf_detatch, + .map_dma_buf = fastrpc_map_dma_buf, + .unmap_dma_buf = fastrpc_unmap_dma_buf, + .mmap = fastrpc_mmap, + .map = fastrpc_kmap, + .vmap = fastrpc_vmap, + .release = fastrpc_release, +}; + static int fastrpc_map_create(struct fastrpc_user *fl, int fd, u64 len, struct fastrpc_map **ppmap) { @@ -906,6 +1024,66 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) return 0; } +static int fastrpc_dmabuf_free(struct fastrpc_user *fl, char __user *argp) +{ + struct dma_buf *buf; + int info; + + if (copy_from_user(&info, argp, sizeof(info))) + return -EFAULT; + + buf = dma_buf_get(info); + if (IS_ERR_OR_NULL(buf)) + return -EINVAL; + /* + * one for the last get and other for the ALLOC_DMA_BUFF ioctl + */ + dma_buf_put(buf); + dma_buf_put(buf); + + return 0; +} + +static int fastrpc_dmabuf_alloc(struct fastrpc_user *fl, char __user *argp) +{ + struct fastrpc_alloc_dma_buf bp; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct fastrpc_buf *buf = NULL; + int err; + + if (copy_from_user(&bp, argp, sizeof(bp))) + return -EFAULT; + + err = fastrpc_buf_alloc(fl, fl->sctx->dev, bp.size, &buf); + if (err) + return err; + exp_info.ops = &fastrpc_dma_buf_ops; + exp_info.size = bp.size; + exp_info.flags = O_RDWR; + exp_info.priv = buf; + buf->dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(buf->dmabuf)) { + err = PTR_ERR(buf->dmabuf); + fastrpc_buf_free(buf); + return err; + } + + bp.fd = dma_buf_fd(buf->dmabuf, O_ACCMODE); + if (bp.fd < 0) { + dma_buf_put(buf->dmabuf); + return -EINVAL; + } + + if (copy_to_user(argp, &bp, sizeof(bp))) { + dma_buf_put(buf->dmabuf); + return -EFAULT; + } + + get_dma_buf(buf->dmabuf); + + return 0; +} + static int fastrpc_init_attach(struct fastrpc_user *fl) { struct fastrpc_invoke_args args[1]; @@ -970,6 +1148,12 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, case FASTRPC_IOCTL_INIT_CREATE: err = fastrpc_init_create_process(fl, argp); break; + case FASTRPC_IOCTL_FREE_DMA_BUFF: + err = fastrpc_dmabuf_free(fl, argp); + break; + case FASTRPC_IOCTL_ALLOC_DMA_BUFF: + err = fastrpc_dmabuf_alloc(fl, argp); + break; default: err = -ENOTTY; break; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index 32d191c3b7bc..6d701af9fc42 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -5,6 +5,8 @@ #include +#define FASTRPC_IOCTL_ALLOC_DMA_BUFF _IOWR('R', 1, struct fastrpc_alloc_dma_buf) +#define FASTRPC_IOCTL_FREE_DMA_BUFF _IOWR('R', 2, __u32) #define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_invoke) #define FASTRPC_IOCTL_INIT_ATTACH _IO('R', 4) #define FASTRPC_IOCTL_INIT_CREATE _IOWR('R', 5, struct fastrpc_init_create) @@ -30,4 +32,10 @@ struct fastrpc_init_create { __u64 file; /* pointer to elf file */ }; +struct fastrpc_alloc_dma_buf { + __s32 fd; /* fd */ + __u32 flags; /* flags to map with */ + __u64 size; /* size */ +}; + #endif /* __QCOM_FASTRPC_H__ */