From patchwork Fri Nov 30 10:46:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 152514 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp3502736ljp; Fri, 30 Nov 2018 02:48:24 -0800 (PST) X-Google-Smtp-Source: AFSGD/XgiqJvSyPVh4OwUOeFfKc7hGHnKh8AxJKDl3ErZWKGxVB0frxo/f/CmEQGH1nYxseD0qGo X-Received: by 2002:a63:d655:: with SMTP id d21mr3237706pgj.280.1543574904104; Fri, 30 Nov 2018 02:48:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543574904; cv=none; d=google.com; s=arc-20160816; b=Y79p0a+4aOozt6OphgMx4rRHIJtlsLZJZpRYBMIyU/MOSJ1xSh1fb0D4yk/xnw/HwJ Goz3aXitqcH2LM5yCkmTHf8doLpDM2xirq7J5dfiB/4s8PG/COe37HCax8YBqJvHqx7e 6ENnQz19pqD0EP3wwL8Db/B+vH1FXsX42SBq6Ua9RrWW2OAwc8a4s7d+B9eilYi7cNyp 33XswJsBUbW2fjwsbeUzph900Lvt+CrbaLat95Jqu4HBzSa2ve8OMNFIME5SI/V2SvIf kiwRm661pnXHz7SbjtJ6rdojaT5BfLSzSkxCQ+Et75zZDB5f4DZUnsy7EEHUbTk8lr4h xHTQ== 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=rp460mHVouQdCt0dxaOMsdLua3SS3yYIstuGzJqTGE0=; b=c9GP5TYrR0WRo9OT+9iE5viZOG9rAnpI/2/jxM2/puui0hf4vmlO6e6CVPDXgN4H9q lRt7uJRT6IrhRLGTCViJsXq+46V7j0GMOoGNuWGHYA59F9FdzETlj052ljyG+vn5Wzds Njq5pzmxledCOgZRatFrSUwRzsqwWv/KVpCVEsMv1jzOQLanUeQ9Aq3wv7OvmFUi+xTQ u0kvMwbhEhMmpcxmERRn4/ekknv6/zH5hNtzpjj2h5Qx8m7xtJMZl5rHQ3pCSpcg6sfc 0A4VRC6/H6t8KSOUlwr8WyEKWjkE3t4nimRC6adDuLxjbw4youiVNMqeKeIeCoSbL4AS m9qw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aTomd1IH; 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 r2si4636354pgk.389.2018.11.30.02.48.23; Fri, 30 Nov 2018 02:48:24 -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=aTomd1IH; 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 S1726837AbeK3V45 (ORCPT + 6 others); Fri, 30 Nov 2018 16:56:57 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:45479 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726958AbeK3V44 (ORCPT ); Fri, 30 Nov 2018 16:56:56 -0500 Received: by mail-wr1-f67.google.com with SMTP id v6so4789022wrr.12 for ; Fri, 30 Nov 2018 02:48:03 -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=rp460mHVouQdCt0dxaOMsdLua3SS3yYIstuGzJqTGE0=; b=aTomd1IHGP69i4CGKsSu31npbyEHjFKPKJU/HrpFw8xwYs8A4PuHHFULcQaJjKzdhY 7HBQMmRg4g6PmyZdCjO7C84WcehLjAigMGDK3o4pPxfL83ngDaZ5ZYwu0i7Cxbx+wzxX DEFq4VpgE2bodMx+ivCZcMUxjX2wdLfN6N9iE= 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=rp460mHVouQdCt0dxaOMsdLua3SS3yYIstuGzJqTGE0=; b=rdDr+tNwaZ7XbeXH5J3jCDFjkHjxDsgD8rG4RZql0EC1bSqZ3vuDboZi9SJdRZFaev Vak26pYW0mBVgsgs/+ysuzEhLHrGlvOT5YV13grWX+XoYUuNzimMSx57tUkdtyaWasFg u4pqFnD1ul4W+LFbzxzizG4hAXMKW5txpcTD+ljY2imniRc5mjpxO+/U3+ORp+uYr2pK qAmvapeC8RwzMXY7MpBYJRv7iXxD+SOgFD/5xtJk20/XwpEKnb5PpSctkct3BZiQ9L/d mi5wl+ZfoQg/ASFIhyQCjSdXZQSsgfYqcPdESN6DRnawHh/IxLVzye8fQOPvzb4u+GH1 T32g== X-Gm-Message-State: AA+aEWadHoKRoYrXj10TpgGnqamSyUCJ7yh+aCTjuXDDKJXVDbiw9VQj +CQR23amBMemXEqGLr2SSghSOg== X-Received: by 2002:adf:83e7:: with SMTP id 94mr4530139wre.278.1543574882300; Fri, 30 Nov 2018 02:48:02 -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 18sm6964211wmm.32.2018.11.30.02.48.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 30 Nov 2018 02:48:01 -0800 (PST) From: Srinivas Kandagatla To: robh+dt@kernel.org, gregkh@linuxfoundation.org, arnd@arndb.de Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, bjorn.andersson@linaro.org, linux-arm-msm@vger.kernel.org, bkumar@qti.qualcomm.com, thierry.escande@linaro.org, Srinivas Kandagatla Subject: [RFC PATCH 4/6] char: fastrpc: Add support for create remote init process Date: Fri, 30 Nov 2018 10:46:55 +0000 Message-Id: <20181130104657.14875-5-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181130104657.14875-1-srinivas.kandagatla@linaro.org> References: <20181130104657.14875-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 Signed-off-by: Srinivas Kandagatla --- drivers/char/fastrpc.c | 172 +++++++++++++++++++++++++++++++++++ include/uapi/linux/fastrpc.h | 18 ++++ 2 files changed, 190 insertions(+) -- 2.19.2 diff --git a/drivers/char/fastrpc.c b/drivers/char/fastrpc.c index 5bb224adc24f..3630e883d3f4 100644 --- a/drivers/char/fastrpc.c +++ b/drivers/char/fastrpc.c @@ -30,6 +30,8 @@ #define FASTRPC_PHYS(p) (p & 0xffffffff) #define FASTRPC_CTX_MAX (256) #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 +61,14 @@ #define FASTRPC_SCALARS(method, in, out) \ FASTRPC_BUILD_SCALARS(0, method, in, out, 0, 0) + +/* 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 cdev_to_cctx(d) container_of(d, struct fastrpc_channel_ctx, cdev) static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp", @@ -735,6 +745,130 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, return err; } + +static int fastrpc_init_process(struct fastrpc_user *fl, + struct fastrpc_ioctl_init *init) +{ + struct fastrpc_ioctl_invoke *ioctl; + struct fastrpc_phy_page pages[1]; + struct fastrpc_map *file = NULL, *mem = NULL; + struct fastrpc_buf *imem = NULL; + int err = 0; + + ioctl = kzalloc(sizeof(*ioctl), GFP_KERNEL); + if (!ioctl) + return -ENOMEM; + + if (init->flags == FASTRPC_INIT_ATTACH) { + remote_arg_t ra[1]; + int tgid = fl->tgid; + + ra[0].buf.pv = (void *)&tgid; + ra[0].buf.len = sizeof(tgid); + ioctl->handle = 1; + ioctl->sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0); + ioctl->pra = ra; + fl->pd = 0; + + err = fastrpc_internal_invoke(fl, 1, ioctl); + if (err) + goto bail; + } else if (init->flags == FASTRPC_INIT_CREATE) { + int memlen; + remote_arg_t ra[6]; + int fds[6]; + struct { + int pgid; + unsigned int namelen; + unsigned int filelen; + unsigned int pageslen; + int attrs; + int siglen; + } inbuf; + + inbuf.pgid = fl->tgid; + inbuf.namelen = strlen(current->comm) + 1; + inbuf.filelen = init->filelen; + fl->pd = 1; + + if (init->filelen) { + err = fastrpc_map_create(fl, init->filefd, + init->file, init->filelen, + &file); + if (err) + goto bail; + } + inbuf.pageslen = 1; + + if (init->mem) { + err = -EINVAL; + pr_err("adsprpc: %s: %s: ERROR: donated memory allocated in userspace\n", + current->comm, __func__); + 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) + goto bail; + + fl->init_mem = imem; + inbuf.pageslen = 1; + ra[0].buf.pv = (void *)&inbuf; + ra[0].buf.len = sizeof(inbuf); + fds[0] = 0; + + ra[1].buf.pv = (void *)current->comm; + ra[1].buf.len = inbuf.namelen; + fds[1] = 0; + + ra[2].buf.pv = (void *)init->file; + ra[2].buf.len = inbuf.filelen; + fds[2] = init->filefd; + + pages[0].addr = imem->phys; + pages[0].size = imem->size; + + ra[3].buf.pv = (void *)pages; + ra[3].buf.len = 1 * sizeof(*pages); + fds[3] = 0; + + inbuf.attrs = init->attrs; + ra[4].buf.pv = (void *)&(inbuf.attrs); + ra[4].buf.len = sizeof(inbuf.attrs); + fds[4] = 0; + + inbuf.siglen = init->siglen; + ra[5].buf.pv = (void *)&(inbuf.siglen); + ra[5].buf.len = sizeof(inbuf.siglen); + fds[5] = 0; + + ioctl->handle = 1; + ioctl->sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0); + if (init->attrs) + ioctl->sc = FASTRPC_SCALARS( + FASTRPC_RMID_INIT_CREATE_ATTR, 6, 0); + ioctl->pra = ra; + ioctl->fds = fds; + err = fastrpc_internal_invoke(fl, 1, ioctl); + if (err) + goto bail; + } else { + err = -ENOTTY; + } +bail: + kfree(ioctl); + + if (mem && err) + fastrpc_map_put(mem); + + if (file) + fastrpc_map_put(file); + + return err; +} + static struct fastrpc_session_ctx *fastrpc_session_alloc( struct fastrpc_channel_ctx *cctx, int secure) @@ -769,6 +903,25 @@ static const struct of_device_id fastrpc_match_table[] = { {} }; +static int fastrpc_release_current_dsp_process(struct fastrpc_user *fl) +{ + struct fastrpc_ioctl_invoke ioctl; + remote_arg_t ra[1]; + int tgid = 0; + + tgid = fl->tgid; + ra[0].buf.pv = (void *)&tgid; + ra[0].buf.len = sizeof(tgid); + ioctl.handle = 1; + ioctl.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0); + ioctl.pra = ra; + ioctl.fds = NULL; + ioctl.attrs = NULL; + ioctl.crc = NULL; + + return fastrpc_internal_invoke(fl, 1, &ioctl); +} + static int fastrpc_device_release(struct inode *inode, struct file *file) { struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data; @@ -776,6 +929,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); @@ -855,6 +1010,23 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, goto bail; break; } + case FASTRPC_IOCTL_INIT: { + struct fastrpc_ioctl_init init; + + init.attrs = 0; + init.siglen = 0; + err = copy_from_user(&init, argp, sizeof(init)); + if (err) + goto bail; + if (init.filelen > INIT_FILELEN_MAX) + goto bail; + if (init.memlen > INIT_MEMLEN_MAX) + goto bail; + err = fastrpc_init_process(fl, &init); + if (err) + goto bail; + } + break; default: err = -ENOTTY; pr_info("bad ioctl: %d\n", cmd); diff --git a/include/uapi/linux/fastrpc.h b/include/uapi/linux/fastrpc.h index 8fec66601337..6b596fc7ddf3 100644 --- a/include/uapi/linux/fastrpc.h +++ b/include/uapi/linux/fastrpc.h @@ -6,6 +6,12 @@ #include #define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_ioctl_invoke) +#define FASTRPC_IOCTL_INIT _IOWR('R', 4, struct fastrpc_ioctl_init) + +/* INIT a new process or attach to guestos */ +#define FASTRPC_INIT_ATTACH 0 +#define FASTRPC_INIT_CREATE 1 +#define FASTRPC_INIT_CREATE_STATIC 2 #define remote_arg64_t union remote_arg64 @@ -53,4 +59,16 @@ struct fastrpc_ioctl_invoke { unsigned int *crc; }; +struct fastrpc_ioctl_init { + uint32_t flags; /* one of FASTRPC_INIT_* macros */ + uintptr_t file; /* pointer to elf file */ + uint32_t filelen; /* elf file length */ + int32_t filefd; /* ION fd for the file */ + uintptr_t mem; /* mem for the PD */ + uint32_t memlen; /* mem length */ + int32_t memfd; /* fd for the mem */ + int attrs; + unsigned int siglen; +}; + #endif /* __QCOM_FASTRPC_H__ */ From patchwork Fri Nov 30 10:46:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 152511 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp3502505ljp; Fri, 30 Nov 2018 02:48:09 -0800 (PST) X-Google-Smtp-Source: AFSGD/X7xz9kPThZvORsaYM1H1nBIr+F9wBLlQvhWxnh6lSgCT3Iwf5AsksM35wES0RwT+dNI0++ X-Received: by 2002:a17:902:9a04:: with SMTP id v4mr5322362plp.34.1543574889146; Fri, 30 Nov 2018 02:48:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543574889; cv=none; d=google.com; s=arc-20160816; b=xj65JRxt2GeIY5yX3j/rHV/59lyv3rJ+4OssseV2QPCdd2sOsPLPr8iN646zo2TmlS VdegzMKPW+nSNDH0ZbsVPP9KITTU/eD0moVCGahtCoKnjBcjdC3nzIaDw99InVQSwPIm yuA91kydzWCbqERWBI0FJjv6L+OJDQ8OX+i4cYIxk8x1W7pnHvYgAkPcQqE+9okCg0HO VuCf3SQDAT1a+bYuZGrydDOBHaj4QZMW+QGMaj/fRqUk0N6h5av6r9tKdMcZgzyaXPwy a1Y5focyyC+32DbtPVd7BPzoXWPwyVhNUENXJh/CwjbFLh/1EhawCN4TBkU7nliwdcxK ZMUQ== 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=H9qjdn/c387gvtfUKEl5bxOl70UBdeJeDDgUe1gSkpE=; b=nRLdcU7pO9XdqfoB2Mb1HmLiAWD4ge0thm6dRsLVTus6dKeLmdSejmwNPX5QY12/9U Ok6IPaHYJoaj6+jUNr6odxBIzGfFVYazICFROeN2uCWphOi+AurAYGGesWhtStoNW/Gu SD8nPBMjXEBJtBu6o4MNRUep+tPOzWUHaqkmiZtdNVVDJ0+QD3AOU2iw87LHPRD0JRnf hgdFlPiI9Jft8hXF+sDT0UCER6if7DXPTB6TsSvs/3T5wt8Dpl8vLN0ny4DvxDW5anBP 3NVRVK8xuaXOFuqLeLIeq9sTf+HrrJ63d0FHvsOFIdjEA7g02R/m7NTKO07FzNKOjVW7 YV7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Nva1STv/"; 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 cd2si5810732plb.39.2018.11.30.02.48.08; Fri, 30 Nov 2018 02:48:09 -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="Nva1STv/"; 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 S1726930AbeK3V46 (ORCPT + 6 others); Fri, 30 Nov 2018 16:56:58 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:51214 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726976AbeK3V45 (ORCPT ); Fri, 30 Nov 2018 16:56:57 -0500 Received: by mail-wm1-f66.google.com with SMTP id s14so5315791wmh.1 for ; Fri, 30 Nov 2018 02:48:04 -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=H9qjdn/c387gvtfUKEl5bxOl70UBdeJeDDgUe1gSkpE=; b=Nva1STv/TgUvlEkf0QcVE8dinbAysbFyytKiD0H3cI6EtSxYjQZeAYvlcOeolkskDm bv1eaL2fmxHzbePFRfTruEzhtbmLc/V20hfM9BiYwRTkz+tSjKH6O4yS2pZHIdnSqWGy w4PrvPuJpkCTK7uxuFngQIFOel1GdwS0x1+II= 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=H9qjdn/c387gvtfUKEl5bxOl70UBdeJeDDgUe1gSkpE=; b=anNE1NmkMFMXJ4KtFrMjggFGCzDbGApZrlFXujnFTRmy2tOiUg5MC6CVSr2UGirnt8 dYv5OCoe7PRgjDkr64mjJIKEt3F1euoLPRX4C3ddx3Byr/h4+F2sA5SGxR9utvoYoaUs 3+pk6xv6ziJMnWR+65XrdgdaY1yWgiXjjziOo/tXVjlh6QbnVssHoBkM2X+Gps4X5J1W BFK3Oqv+H8+v3+fohH/rmCqAz1SsB8i+TNSFTT3p+CfwTuDL0lDCaW+61l7xKfKwS2Je 5TNw448XSLKYv1yFcMrc47lWCiZb+efaKHXsAaCveAKy3uU4lG5ZI3aimXQv9Vv9hRfR mdjw== X-Gm-Message-State: AA+aEWYA7XVQlHO+ciYVueZ3SdsbBKpD/kVVL0HDzAvqcyAL/xp3OX2G itZ2Nbk03b4QiaRyafhk1TNNkQ== X-Received: by 2002:a1c:2e0c:: with SMTP id u12mr4467144wmu.81.1543574883541; Fri, 30 Nov 2018 02:48:03 -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 18sm6964211wmm.32.2018.11.30.02.48.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 30 Nov 2018 02:48:02 -0800 (PST) From: Srinivas Kandagatla To: robh+dt@kernel.org, gregkh@linuxfoundation.org, arnd@arndb.de Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, bjorn.andersson@linaro.org, linux-arm-msm@vger.kernel.org, bkumar@qti.qualcomm.com, thierry.escande@linaro.org, Srinivas Kandagatla Subject: [RFC PATCH 5/6] char: fastrpc: Add support for dmabuf exporter Date: Fri, 30 Nov 2018 10:46:56 +0000 Message-Id: <20181130104657.14875-6-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181130104657.14875-1-srinivas.kandagatla@linaro.org> References: <20181130104657.14875-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. Signed-off-by: Srinivas Kandagatla --- drivers/char/fastrpc.c | 173 ++++++++++++++++++++++++++++++++++- include/uapi/linux/fastrpc.h | 8 ++ 2 files changed, 180 insertions(+), 1 deletion(-) -- 2.19.2 diff --git a/drivers/char/fastrpc.c b/drivers/char/fastrpc.c index 3630e883d3f4..3c52502eae9f 100644 --- a/drivers/char/fastrpc.c +++ b/drivers/char/fastrpc.c @@ -110,10 +110,20 @@ struct fastrpc_invoke_rsp { struct fastrpc_buf { struct fastrpc_user *fl; + struct dma_buf *dmabuf; struct device *dev; void *virt; uint64_t phys; size_t 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 { @@ -256,6 +266,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; @@ -394,6 +407,109 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( return ERR_PTR(err); } +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) +{ +} + +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, uintptr_t va, size_t len, struct fastrpc_map **ppmap) { @@ -989,7 +1105,8 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, char __user *argp = (char __user *)arg; int err; - if (!fl->sctx) { + if (!fl->sctx && cmd != FASTRPC_IOCTL_ALLOC_DMA_BUFF && + cmd != FASTRPC_IOCTL_FREE_DMA_BUFF) { fl->sctx = fastrpc_session_alloc(cctx, 0); if (!fl->sctx) return -ENOENT; @@ -1027,6 +1144,60 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, goto bail; } break; + + case FASTRPC_IOCTL_FREE_DMA_BUFF: { + struct dma_buf *buf; + uint32_t info; + + err = copy_from_user(&info, argp, sizeof(info)); + if (err) + goto bail; + + buf = dma_buf_get(info); + if (IS_ERR_OR_NULL(buf)) { + err = -EINVAL; + goto bail; + } + /* + * one for the last get and other for the ALLOC_DMA_BUFF ioctl + */ + dma_buf_put(buf); + dma_buf_put(buf); + } + break; + case FASTRPC_IOCTL_ALLOC_DMA_BUFF: { + struct fastrpc_ioctl_alloc_dma_buf bp; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct fastrpc_buf *buf = NULL; + + err = copy_from_user(&bp, argp, sizeof(bp)); + if (err) + goto bail; + + err = fastrpc_buf_alloc(fl, fl->dev, bp.size, &buf); + 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); + goto bail; + } + get_dma_buf(buf->dmabuf); + bp.fd = dma_buf_fd(buf->dmabuf, O_ACCMODE); + if (bp.fd < 0) { + dma_buf_put(buf->dmabuf); + err = -EINVAL; + goto bail; + } + + err = copy_to_user(argp, &bp, sizeof(bp)); + if (err) + goto bail; + + } + break; default: err = -ENOTTY; pr_info("bad ioctl: %d\n", cmd); diff --git a/include/uapi/linux/fastrpc.h b/include/uapi/linux/fastrpc.h index 6b596fc7ddf3..6b1ca29867fd 100644 --- a/include/uapi/linux/fastrpc.h +++ b/include/uapi/linux/fastrpc.h @@ -5,6 +5,8 @@ #include +#define FASTRPC_IOCTL_ALLOC_DMA_BUFF _IOWR('R', 1, struct fastrpc_ioctl_alloc_dma_buf) +#define FASTRPC_IOCTL_FREE_DMA_BUFF _IOWR('R', 2, uint32_t) #define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_ioctl_invoke) #define FASTRPC_IOCTL_INIT _IOWR('R', 4, struct fastrpc_ioctl_init) @@ -71,4 +73,10 @@ struct fastrpc_ioctl_init { unsigned int siglen; }; +struct fastrpc_ioctl_alloc_dma_buf { + int fd; /* fd */ + ssize_t size; /* size */ + uint32_t flags; /* flags to map with */ +}; + #endif /* __QCOM_FASTRPC_H__ */