From patchwork Thu Jan 24 15:24:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 156483 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2087766jaa; Thu, 24 Jan 2019 07:26:19 -0800 (PST) X-Google-Smtp-Source: ALg8bN5bspImQCHB97e5MrLkbsqbMJRmyUt/ILCPdvOm3sbpCZGF8pkHYiLsRqY2Jxqfc7pIXAbW X-Received: by 2002:a63:1a0c:: with SMTP id a12mr6211861pga.157.1548343579257; Thu, 24 Jan 2019 07:26:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548343579; cv=none; d=google.com; s=arc-20160816; b=dD4MizcRCl3Sgw6UiFlhhzLAexFFhE5u0qTdZ4mmASPRJyPgeNppcnFywbE/NIu7yk E4jr8rmWc0LEZSYDBuQLPtXpMfb9GYvJy7G/U9HljqWcIfeG/4RYwbAp+nhzUJfKYcBq ZZVlxhGB65T4qgmjIuy9AGumflDvxqDC/tCcUpoMSoh6Wqqo2fZm4nYZWaAHOzLUl2pc HbvRTQwLb6TNmOxzrD3OE5M/LXeYYBd2NTZyOmCaHW8ERt7n7ew1eI8ZUxGY3DjjnFUI KNs29+A4d+fkDahDKiwikKd7b259WOhgPKt8HFxc/FOgoku73VjlfW0ysJFjaHbE0ukt ef9A== 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=HBoSjW/9C2BJWOWwi68QsUaCxo6aNQtRfwlrGXtdlvs=; b=JXPmPOhaFboayi9d/TVs4Mjpy6Hv8M9wTx5aY7zgEXF276O/haxJNY+YVKulLpRp0o PIJpdIVvOgedYC6yzrn8PVo62Jh32V747NEBPB/0nq7tzk9BZfaSTfWnq08LrzJHxvpf kJe5Kf/5tcZ9cc3k9T/A4CprvD1NdTV41DPBEQa6PoUQGGLK4UmfoBV/UaKT8VjU1Djr ypWNZ1/StPi8cxhun8SH95m/FrOh5jOqy+bJaLzzH28JV3XhbuWHz3uFojIwyO+UPpT7 Bn5NMzByDvZcypU7ax5WDqy605PKgOkRayKVj6cySV0k5qX9yhx543/BPQ09brBjLI46 vx9A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WAbWRb5o; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 x32si23174350pld.316.2019.01.24.07.26.18; Thu, 24 Jan 2019 07:26:19 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=WAbWRb5o; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 S1728737AbfAXP0R (ORCPT + 31 others); Thu, 24 Jan 2019 10:26:17 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:33149 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728648AbfAXPZw (ORCPT ); Thu, 24 Jan 2019 10:25:52 -0500 Received: by mail-wm1-f66.google.com with SMTP id r24so2616620wmh.0 for ; Thu, 24 Jan 2019 07:25:50 -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=HBoSjW/9C2BJWOWwi68QsUaCxo6aNQtRfwlrGXtdlvs=; b=WAbWRb5opunKVJHV2gvmr3SMyt9rlZ5menzvqdoDe5vTpvrbueGwR+iAM9KLAJfbmn 18mJmVVUnvuzAoXAIRg1nCcVMvUsMeMFcKoljyDiGBjzSrTJJ1lIvbKJ7SJJ6ofLZkc0 wnZrjYLvfbl0lOwrp7p6GC2iA35W7MkuOWRyU= 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=HBoSjW/9C2BJWOWwi68QsUaCxo6aNQtRfwlrGXtdlvs=; b=F0tG8nAIdxRbdMShxtJTbQXqiZkvx0nsGdViocgkEYP4dIO/djQllb+/RpFUqeyR9Z djvKKELgahmGVoiKBPTl/lo44bEPV2b/6csg7NZe45x1LzwERjgFJ0mFNShPwPk10cYP MSY7dLkyqscUeLgfbDZ05AGgMQRKe4wiPwj/753eRw4R7/wiOgnJA2iXxokEKW8UIKgZ 9KmhnVArDIVLr/7mJqbK4bBWm8+BN2keDYuKSxNMX7mQgdwj3WVzjX7RN/HsLL4V+ITN DKorU0nCRJrs8aN4IpWAw5aM4SqY2Z2oeuz85VuH+HTmxBLjuBAuSS12m4BoFiGB3Cda iVUw== X-Gm-Message-State: AJcUukcXB8xjkRxoYhlucY6FCvd8MN4KGsoyJW+1kQvrNQ8wSCAoyeca r82rxJVKz0AfOmpzgbxzUYQjrA== X-Received: by 2002:a1c:3c06:: with SMTP id j6mr2863882wma.27.1548343549819; Thu, 24 Jan 2019 07:25:49 -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 z12sm80371157wrh.35.2019.01.24.07.25.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 24 Jan 2019 07:25:49 -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, bkumar@qti.qualcomm.com, linux-arm-msm@vger.kernel.org, thierry.escande@linaro.org, Srinivas Kandagatla Subject: [PATCH v4 2/5] misc: fastrpc: Add Qualcomm fastrpc basic driver model Date: Thu, 24 Jan 2019 15:24:09 +0000 Message-Id: <20190124152412.10503-3-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190124152412.10503-1-srinivas.kandagatla@linaro.org> References: <20190124152412.10503-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds basic driver model for qualcomm fastrpc. Each DSP rpmsg channel is represented as fastrpc channel context and is exposed as a character driver for userspace interface. Each compute context bank is represented as fastrpc-session-context, which are dynamically managed by the channel context char device. Co-developed-by: Thierry Escande Signed-off-by: Thierry Escande Signed-off-by: Srinivas Kandagatla --- drivers/misc/Kconfig | 10 ++ drivers/misc/Makefile | 1 + drivers/misc/fastrpc.c | 323 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 334 insertions(+) create mode 100644 drivers/misc/fastrpc.c -- 2.20.1 diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index f417b06e11c5..7e0726253755 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -295,6 +295,16 @@ config QCOM_COINCELL to maintain PMIC register and RTC state in the absence of external power. +config QCOM_FASTRPC + tristate "Qualcomm FastRPC" + depends on ARCH_QCOM || COMPILE_TEST + depends on RPMSG + help + Provides a communication mechanism that allows for clients to + make remote method invocations across processor boundary to + applications DSP processor. Say M if you want to enable this + module. + config SGI_GRU tristate "SGI GRU driver" depends on X86_UV && SMP diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index e39ccbbc1b3a..623d002c59ce 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_PHANTOM) += phantom.o obj-$(CONFIG_QCOM_COINCELL) += qcom-coincell.o +obj-$(CONFIG_QCOM_FASTRPC) += fastrpc.o obj-$(CONFIG_SENSORS_BH1770) += bh1770glc.o obj-$(CONFIG_SENSORS_APDS990X) += apds990x.o obj-$(CONFIG_SGI_IOC4) += ioc4.o diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c new file mode 100644 index 000000000000..d744a93eb922 --- /dev/null +++ b/drivers/misc/fastrpc.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +// Copyright (c) 2018, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADSP_DOMAIN_ID (0) +#define MDSP_DOMAIN_ID (1) +#define SDSP_DOMAIN_ID (2) +#define CDSP_DOMAIN_ID (3) +#define FASTRPC_DEV_MAX 4 /* adsp, mdsp, slpi, cdsp*/ +#define FASTRPC_MAX_SESSIONS 9 /*8 compute, 1 cpz*/ +#define FASTRPC_CTX_MAX (256) +#define FASTRPC_CTXID_MASK (0xFF0) +#define FASTRPC_DEVICE_NAME "fastrpc" + +#define miscdev_to_cctx(d) container_of(d, struct fastrpc_channel_ctx, miscdev) + +static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp", + "sdsp", "cdsp"}; + +struct fastrpc_session_ctx { + struct device *dev; + int sid; + bool used; + bool valid; +}; + +struct fastrpc_channel_ctx { + int domain_id; + int sesscount; + struct rpmsg_device *rpdev; + struct fastrpc_session_ctx session[FASTRPC_MAX_SESSIONS]; + spinlock_t lock; + struct idr ctx_idr; + struct list_head users; + struct miscdevice miscdev; +}; + +struct fastrpc_user { + struct list_head user; + struct list_head maps; + struct list_head pending; + + struct fastrpc_channel_ctx *cctx; + struct fastrpc_session_ctx *sctx; + + int tgid; + int pd; + /* Lock for lists */ + spinlock_t lock; + /* lock for allocations */ + struct mutex mutex; +}; + +static struct fastrpc_session_ctx *fastrpc_session_alloc( + struct fastrpc_channel_ctx *cctx) +{ + struct fastrpc_session_ctx *session = NULL; + int i; + + spin_lock(&cctx->lock); + 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(&cctx->lock); + + return session; +} + +static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx, + struct fastrpc_session_ctx *session) +{ + spin_lock(&cctx->lock); + session->used = false; + spin_unlock(&cctx->lock); +} + +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; + + spin_lock(&cctx->lock); + list_del(&fl->user); + spin_unlock(&cctx->lock); + + fastrpc_session_free(fl->cctx, fl->sctx); + + mutex_destroy(&fl->mutex); + kfree(fl); + file->private_data = NULL; + + return 0; +} + +static int fastrpc_device_open(struct inode *inode, struct file *filp) +{ + struct fastrpc_channel_ctx *cctx = miscdev_to_cctx(filp->private_data); + struct fastrpc_user *fl = NULL; + + fl = kzalloc(sizeof(*fl), GFP_KERNEL); + if (!fl) + return -ENOMEM; + + filp->private_data = fl; + spin_lock_init(&fl->lock); + mutex_init(&fl->mutex); + INIT_LIST_HEAD(&fl->pending); + INIT_LIST_HEAD(&fl->maps); + INIT_LIST_HEAD(&fl->user); + fl->tgid = current->tgid; + fl->cctx = cctx; + spin_lock(&cctx->lock); + list_add_tail(&fl->user, &cctx->users); + spin_unlock(&cctx->lock); + fl->sctx = fastrpc_session_alloc(cctx); + + return 0; +} + +static const struct file_operations fastrpc_fops = { + .open = fastrpc_device_open, + .release = fastrpc_device_release, +}; + +static int fastrpc_cb_probe(struct platform_device *pdev) +{ + struct fastrpc_channel_ctx *cctx; + struct fastrpc_session_ctx *sess; + struct device *dev = &pdev->dev; + int i, sessions = 0; + + cctx = dev_get_drvdata(dev->parent); + if (!cctx) + return -EINVAL; + + of_property_read_u32(dev->of_node, "qcom,nsessions", &sessions); + + spin_lock(&cctx->lock); + sess = &cctx->session[cctx->sesscount]; + sess->used = false; + sess->valid = true; + sess->dev = dev; + dev_set_drvdata(dev, sess); + + if (of_property_read_u32(dev->of_node, "reg", &sess->sid)) + dev_info(dev, "FastRPC Session ID not specified in DT\n"); + + if (sessions > 0) { + struct fastrpc_session_ctx *dup_sess; + + for (i = 1; i < sessions; i++) { + if (cctx->sesscount++ >= FASTRPC_MAX_SESSIONS) + break; + dup_sess = &cctx->session[cctx->sesscount]; + memcpy(dup_sess, sess, sizeof(*dup_sess)); + } + } + cctx->sesscount++; + spin_unlock(&cctx->lock); + dma_set_mask(dev, DMA_BIT_MASK(32)); + + return 0; +} + +static int fastrpc_cb_remove(struct platform_device *pdev) +{ + struct fastrpc_channel_ctx *cctx = dev_get_drvdata(pdev->dev.parent); + struct fastrpc_session_ctx *sess = dev_get_drvdata(&pdev->dev); + int i; + + spin_lock(&cctx->lock); + for (i = 1; i < FASTRPC_MAX_SESSIONS; i++) { + if (cctx->session[i].sid == sess->sid) { + cctx->session[i].valid = false; + cctx->sesscount--; + } + } + spin_unlock(&cctx->lock); + + return 0; +} + +static const struct of_device_id fastrpc_match_table[] = { + { .compatible = "qcom,fastrpc-compute-cb", }, + {} +}; + +static struct platform_driver fastrpc_cb_driver = { + .probe = fastrpc_cb_probe, + .remove = fastrpc_cb_remove, + .driver = { + .name = "qcom,fastrpc-cb", + .of_match_table = fastrpc_match_table, + .suppress_bind_attrs = true, + }, +}; + +static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) +{ + struct device *rdev = &rpdev->dev; + struct fastrpc_channel_ctx *data; + int i, err, domain_id = 0; + const char *domain; + + data = devm_kzalloc(rdev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + err = of_property_read_string(rdev->of_node, "label", &domain); + if (err) { + dev_info(rdev, "FastRPC Domain not specified in DT\n"); + return err; + } + + for (i = 0; i < CDSP_DOMAIN_ID; i++) { + if (!strcmp(domains[i], domain)) { + domain_id = i; + break; + } + } + + if (domain_id > CDSP_DOMAIN_ID) { + dev_info(rdev, "FastRPC Invalid Domain ID %d\n", domain_id); + return -EINVAL; + } + + data->miscdev.minor = MISC_DYNAMIC_MINOR; + data->miscdev.name = kasprintf(GFP_KERNEL, "fastrpc-%s", + domains[domain_id]); + data->miscdev.fops = &fastrpc_fops; + err = misc_register(&data->miscdev); + if (err) + return err; + + dev_set_drvdata(&rpdev->dev, data); + dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32)); + INIT_LIST_HEAD(&data->users); + spin_lock_init(&data->lock); + idr_init(&data->ctx_idr); + data->domain_id = domain_id; + data->rpdev = rpdev; + + return of_platform_populate(rdev->of_node, NULL, NULL, rdev); +} + +static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) +{ + struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev); + + misc_deregister(&cctx->miscdev); + of_platform_depopulate(&rpdev->dev); + kfree(cctx); +} + +static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 addr) +{ + return 0; +} + +static const struct of_device_id fastrpc_rpmsg_of_match[] = { + { .compatible = "qcom,fastrpc" }, + { }, +}; +MODULE_DEVICE_TABLE(of, fastrpc_rpmsg_of_match); + +static struct rpmsg_driver fastrpc_driver = { + .probe = fastrpc_rpmsg_probe, + .remove = fastrpc_rpmsg_remove, + .callback = fastrpc_rpmsg_callback, + .drv = { + .name = "qcom,fastrpc", + .of_match_table = fastrpc_rpmsg_of_match, + }, +}; + +static int fastrpc_init(void) +{ + int ret; + + ret = platform_driver_register(&fastrpc_cb_driver); + if (ret < 0) { + pr_err("fastrpc: failed to register cb driver\n"); + return ret; + } + + ret = register_rpmsg_driver(&fastrpc_driver); + if (ret < 0) { + pr_err("fastrpc: failed to register rpmsg driver\n"); + platform_driver_unregister(&fastrpc_cb_driver); + return ret; + } + + return 0; +} +module_init(fastrpc_init); + +static void fastrpc_exit(void) +{ + platform_driver_unregister(&fastrpc_cb_driver); + unregister_rpmsg_driver(&fastrpc_driver); +} +module_exit(fastrpc_exit); + +MODULE_ALIAS("fastrpc:fastrpc"); +MODULE_LICENSE("GPL v2"); From patchwork Thu Jan 24 15:24:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 156482 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2087522jaa; Thu, 24 Jan 2019 07:26:05 -0800 (PST) X-Google-Smtp-Source: ALg8bN6hXjmlwp+GZE0BK0q8s6RMsQ4hEcL+YkGFBB+5zG365UaV5uXslxMC9nBiCvnG8zLcKvTH X-Received: by 2002:a17:902:b093:: with SMTP id p19mr6947843plr.135.1548343565252; Thu, 24 Jan 2019 07:26:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548343565; cv=none; d=google.com; s=arc-20160816; b=OCOcPKpEKdwssbwFPaHq0cgoutL1lpz8SfY6XmPYTpFIUfyarNpWwSt2MFDzdzVcx+ rh8zJFc2Xhv2GjLeCHqEYFSGtwnEFvvl1xmTtifehgsxznQe+q8t3vjBm65ss3otZLi5 0MCF4e+aygMufprS+vABhjOtN6pjC8ghmvJn+lCxwDLz7geVSF1BdlohSv/sWYSxA9EL 3WEsL+C7sV5Mx8/LBT2FVayUCHWaH8sveIOiX0mgQOGeCjXEQN/BvCl/GeigUlzRC/yn KO+NY9sRtXMvW9vTau98uJoIg9OUgsJIaYLYn7Pp55mRh71RNLj2NPG8Gw4pQ7Ydjtjl mKmg== 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=IaYS66AUeg4SgQnQt8AHydiuWOzD4Ix0QSds3elRmYM=; b=WUgvATMzxhfo1dJAXAj/GRLtV+KVA5thzVcYVI4CTP7NhxO2opMfSW5H6dfvVfJ1Vj KOZcSnKWVYzdlxnBEyWAqPZoMy+qqOsEHXe3EXN1FL0DVGp02g4Q85ritJCgKNQF4aZh tkCEfuj87QlasPf1lf9ET8aMFWoH/JEiq0tuAZ2m8SEmRn+ISQv1B+UJqo4CCRk19haZ zRbY18SXGoYWP0FxwK7W4iSAceixY27QdYY6LdT6l4V4GzFbUebrvjH66B15uU/RmOcG KGn7PbFdQ/GzTDBOJLkojx87PsUpvLBjm2c30Yx2UNWHh5kyErTGlx6u04CjCqMjKL30 TPoQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=evbWPKAw; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 k11si23406780pgg.430.2019.01.24.07.26.04; Thu, 24 Jan 2019 07:26:05 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=evbWPKAw; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 S1728713AbfAXP0A (ORCPT + 31 others); Thu, 24 Jan 2019 10:26:00 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:37628 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728668AbfAXPZ4 (ORCPT ); Thu, 24 Jan 2019 10:25:56 -0500 Received: by mail-wm1-f67.google.com with SMTP id g67so3478070wmd.2 for ; Thu, 24 Jan 2019 07:25:54 -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=IaYS66AUeg4SgQnQt8AHydiuWOzD4Ix0QSds3elRmYM=; b=evbWPKAwss9Fp9zia17gFFi7ygNfIgA0vdxwtf5nRmh00Kb4rOWD9vMI2ZRD8kRZ3Q MI2n6HErZsKmNhqcvU+V/rDUsAsXOxy7J29DEDiMpzRA7BeRPg/6rgvq1VeiM5v7+FO/ u25GRcu26AEW6SjCDcgV31th2K8bnFt0fZtrg= 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=IaYS66AUeg4SgQnQt8AHydiuWOzD4Ix0QSds3elRmYM=; b=Fnf8pWyzZs4n2RX6He9ELKSvWQKNPXU75o2NtAfBTrxhHTxJb6Tb0xwMbqU9y66NtE ag3oEvWy3i68LF5m7N6jiPSpMY72MVeZz+xdLdRSu4GZuH7WNrVMXBU+IeOh6chkY35o Itqy7N37BsAOoQlvR9zFvVqtS7SCxM/eeJhVoorSrmto4DsEggkYwSMqzxqEUbbxluzv oHzi9PGVzYJiU1gAcz2/yPRUsGTeuEwq2crFuqacVypnhZ7YTUdKw3qROiy3BkUFdcTF k+Vf9/9qIaGPHLKLCmbPdYfLViETXLfwOtjB70KMOTfb5zVeQ9kPByUPeVET26jf6xkU 402g== X-Gm-Message-State: AJcUukd/vJlFjHORlym12F7Fo+uLn+mnzzoV0/n03xLI+Lo8kQXdOxSR uGkoigvlTYgMKLPyhrYy0HAvMA== X-Received: by 2002:a7b:c2a9:: with SMTP id c9mr3306447wmk.44.1548343553142; Thu, 24 Jan 2019 07:25:53 -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 z12sm80371157wrh.35.2019.01.24.07.25.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 24 Jan 2019 07:25:52 -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, bkumar@qti.qualcomm.com, linux-arm-msm@vger.kernel.org, thierry.escande@linaro.org, Srinivas Kandagatla Subject: [PATCH v4 4/5] misc: fastrpc: Add support for create remote init process Date: Thu, 24 Jan 2019 15:24:11 +0000 Message-Id: <20190124152412.10503-5-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190124152412.10503-1-srinivas.kandagatla@linaro.org> References: <20190124152412.10503-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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 | 141 +++++++++++++++++++++++++++++++++++- include/uapi/misc/fastrpc.h | 10 +++ 2 files changed, 150 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 86adaad90a0c..b9972f1be9f4 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 */ @@ -60,6 +63,13 @@ #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 miscdev_to_cctx(d) container_of(d, struct fastrpc_channel_ctx, miscdev) static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp", @@ -666,7 +676,96 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, fastrpc_context_free(ctx); if (err) - dev_err(fl->sctx->dev, "Error: Invoke Failed %d\n", err); + dev_dbg(fl->sctx->dev, "Error: Invoke Failed %d\n", err); + + 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[6]; + 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; + + if (copy_from_user(&init, argp, sizeof(init))) + return -EFAULT; + + if (init.filelen > INIT_FILELEN_MAX) + return -EINVAL; + + 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) + 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[0]); + +bail: + if (map) + fastrpc_map_put(map); return err; } @@ -698,6 +797,22 @@ 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; + 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; @@ -705,6 +820,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); @@ -752,6 +869,22 @@ 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; + 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; @@ -792,6 +925,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; dev_err(fl->sctx->dev, "bad ioctl: %d\n", cmd); 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__ */