From patchwork Fri Dec 7 16:35:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 153173 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp703555ljp; Fri, 7 Dec 2018 08:35:25 -0800 (PST) X-Google-Smtp-Source: AFSGD/Vpalpi13UEpROsKX6IlNGcGEL3b0YLokBaU6/8TEgJcANRTEq6EvJsP0PEAQSkUIXqBMez X-Received: by 2002:a17:902:4025:: with SMTP id b34mr2793210pld.181.1544200525607; Fri, 07 Dec 2018 08:35:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544200525; cv=none; d=google.com; s=arc-20160816; b=fPMMBDfRrO0EHb+i2xlQKNUsB8WbGlWsUQEmIzpynEConlvUCxqpdYHZsd0c3hmob7 Po681bmgRA/KgrsLmkzxg4ftrLOWKAYrTzkY96nOxeAOvo2bO0Sk9F8kchhRekGdA8Kq AttdqQ21GLjG06OjNnpHKcAxWR75qUCHhVD2M/8DibIBioswzfnPaMD0wxFGzqz68ybX uUikeAf98bJ7tvmdWCq6E+ZtgeaBGTd3viNEjUBOTy71U84ki3AVMYpMlQmQ7FoerLR8 ynXpG7Jw2feOI2DM4pHSumKNA/UUAgKZJD9JZYfA128+opBoLFnESH9MkXJOrv9FvK9i BSXQ== 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=GjxMI89DvPAZnhOIEoj6bLz5gHp2ueDx3cr6cnwUctc=; b=L221z54FkaEy07BnBE1+dxqFEU5sMMPYVbOXH/47rZeNffTR7vi4XYE2QEkHAN4M8c SCCxERZkVwmtgPv4B5XacnVxvY2BGM0qn88cntaB7mlWd+EEexhsA5lm7h+40b/D8anh oj29TfmUBN+ym+DTiz0i67ZT4w7eYJx5wZ5oH5tm7uqIDIwt4nChD6SpCuFchxv9wwjc KqPAemstAQH7e+y9gdAU/7CD8kmdh9IDFeALiKxndsieIuUJNYxlZJpDgVnrq62L59wp mU4LK+pJdnoy176OHU18wCh7PfG+5Z/zpN7mySXYxF5zZt6GZeO1XutLRpOR5szCj2Mn EdzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZZG+dnTL; 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 14si2941246pgx.178.2018.12.07.08.35.25; Fri, 07 Dec 2018 08:35:25 -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=ZZG+dnTL; 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 S1726224AbeLGQfY (ORCPT + 31 others); Fri, 7 Dec 2018 11:35:24 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:40757 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726124AbeLGQfU (ORCPT ); Fri, 7 Dec 2018 11:35:20 -0500 Received: by mail-wr1-f67.google.com with SMTP id p4so4382161wrt.7 for ; Fri, 07 Dec 2018 08:35:19 -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=GjxMI89DvPAZnhOIEoj6bLz5gHp2ueDx3cr6cnwUctc=; b=ZZG+dnTLN/AgzqGWs+iivvi4u+Fcd6nN+bw6vH4XzZXdMC5os/JmEpF5iTS3EtMoGG T+kqZbc+eU3zb/hmFK1OhuxQ6liiPDcJLqytp1Q/Ob2MyCwKCd9aRDrD8AFTkLCvDAty /wEeq6nzCHmZJ0QothFu/HRZPBqcbHSaY0RL8= 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=GjxMI89DvPAZnhOIEoj6bLz5gHp2ueDx3cr6cnwUctc=; b=kc4d3RcQCWzYTWruMArRw24egmMsJ4vW5UHgzyo3zzqGQl1C09RIeeJ9dxcmH/ETCo 5STLkJYPIwvvO9Kymgzk400OEbK/0CDGra0XTefxVmxmGcts/sdB9JrIio+swwN+ko3i b6QZa4rJNyy7YlTcJQpdgi1C/dBGzrtpE8+eg4a+wdQDhIxXX48K0z/BCtCy/8OjQbeo ydxcAJ70U7SZAid07TJstmOOXSi7PgPmGW+We+efcKmgGeA2LEdE6RFjRDfqQd0x/EQs zl0H8CpilH/qZr8f5kKNXSgBfwiu7lu7P6Fd8dPk8EX3N9/iTvIEGJPDO5SltXw8K6Mx 4R7g== X-Gm-Message-State: AA+aEWZ3c3mELQYMtD1k2Cjih+ToU8wkpJBrv16tgtowFNujylDMnPBO EIxeyqU80ndO2Xy6lP5kDC6iRA== X-Received: by 2002:adf:ea11:: with SMTP id q17mr2307626wrm.328.1544200518646; Fri, 07 Dec 2018 08:35:18 -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 w6sm4268752wme.46.2018.12.07.08.35.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 07 Dec 2018 08:35:18 -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: [PATCH v2 1/6] misc: dt-bindings: Add Qualcomm Fastrpc bindings Date: Fri, 7 Dec 2018 16:35:08 +0000 Message-Id: <20181207163513.16412-2-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181207163513.16412-1-srinivas.kandagatla@linaro.org> References: <20181207163513.16412-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 The FastRPC driver implements an IPC (Inter-Processor Communication) mechanism that allows for clients to transparently make remote method invocations across DSP and APPS boundaries. This enables developers to offload tasks to the DSP and free up the application processor for other tasks. Co-developed-by: Thierry Escande Signed-off-by: Thierry Escande Signed-off-by: Srinivas Kandagatla --- .../devicetree/bindings/misc/qcom,fastrpc.txt | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 Documentation/devicetree/bindings/misc/qcom,fastrpc.txt -- 2.19.2 diff --git a/Documentation/devicetree/bindings/misc/qcom,fastrpc.txt b/Documentation/devicetree/bindings/misc/qcom,fastrpc.txt new file mode 100644 index 000000000000..06e8c25839d5 --- /dev/null +++ b/Documentation/devicetree/bindings/misc/qcom,fastrpc.txt @@ -0,0 +1,73 @@ +Qualcomm Technologies, Inc. FastRPC Driver + +The FastRPC driver implements an IPC (Inter-Processor Communication) +mechanism that allows for clients to transparently make remote method +invocations across DSP and APPS boundaries. This enables developers +to offload tasks to the DSP and free up the application processor for +other tasks. + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,fastrpc" + +- reg + Usage: required + Value type: + Definition: DSP Processor ID. + Possible values are : + 0 - ADSP + 1 - MDSP + 2 - SDSP + 3 - CDSP + += COMPUTE BANKS +Each subnode of the Fastrpc node represents compute context banks available +on the dsp. The name of the nodes are not important. The properties of these +nodes are defined by the individual bindings for the specific service +- All Compute context banks MUST contain the following property: + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,fastrpc-compute-cb" + +- reg + Usage: required + Value type: + Definition: Context Bank ID. + +- secured: + Usage: Optional + Value type: + Defination: Indicating context bank is secured + +- nsessions: + Usage: Optional + Value type: + Defination: A value indicating how many sessions can share this + context bank. Defaults to 'One' when this property + is not specified. + +Example: + +fastrpc { + compatible = "qcom,fastrpc"; + qcom,smd-channels = "fastrpcsmd-apps-dsp"; + reg = <0>; /* DOMAIN_ADSP */ + #address-cells = <1>; + #size-cells = <0>; + + cb@1 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <1>; + iommus = <&lpass_q6_smmu 1>; + }; + + cb@2 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <2>; + iommus = <&lpass_q6_smmu 2>; + }; + ... +}; From patchwork Fri Dec 7 16:35:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 153177 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp703916ljp; Fri, 7 Dec 2018 08:35:46 -0800 (PST) X-Google-Smtp-Source: AFSGD/XKPVgwG2MVbcMKSuf+vw+RTNzfINc2cuwr4Mft6GIMyPgbLb2QfhI3I4Rq5Sk2pr3W55pJ X-Received: by 2002:a63:a16:: with SMTP id 22mr2581339pgk.318.1544200546160; Fri, 07 Dec 2018 08:35:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544200546; cv=none; d=google.com; s=arc-20160816; b=C0n5w2dTNaB96lBs2vClnR3qhKw+7Hb2pEpYcJYZDfhRdu+1UrVh/2N7KnshvjRUPH 8nqbzUzaTvzNujhriVZJDLcqHinXVA+Dh2KuC11x0ZM+7wMP38NYwSt3AXhC/s43+zmx nZhvirqf+KCVuRAX9OhxRIaDBw6ycchR9Q3kMzj2Rm4DPT7Cepf50cA0TK3ygjQI/bvN pYaG82z4UfJu04JXwPsglyZzn94CBLb1GlYdZ03OTI785/SivTIwdMLU1TX8kJYbSTHl KZeP7f2WAXtmSjGmbqhLBbXilgtf8N1PcFhoM3fYjkYl3ADm4Ig/L1kb1wIbHjVeNrUn eHIA== 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=cAXi+ASHzDiWoNZ9nvermzRNOAAXGYqjUY99XxDx92M=; b=AxMMWKPB/L/zQ4ji6yP+/QmWF2eqdl+GcY+k5e/+qyFchSHUP4wumLc5afw/skWr+Q ZFV1YgbeGm9Uuw3oGNdSctNgWZn/cYLsl/vxbVyincM60gsvSpoPtsI0UnJROUCM6qYq 0dHz1f9ynLQaDj71GOHe4XTarJ3i+D0KVr5KJxd8OiPwqeIwp3ZU7+b35K/kh6lOmxF2 onBIpJwHG56TaQJDGCXi44RP7DMEIjYwIW+xXGs/oBvJQoV1xWd/oAYy3f1y84zby8oa A+bslSgC04XR6u40bmdEzfU3N2AmAoT+HRcDjwbPoSHCxYqrsYLe9YAiWNuLBF4sPcXy C2lw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dMvRy9dr; 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 o7si3182502pgg.118.2018.12.07.08.35.45; Fri, 07 Dec 2018 08:35:46 -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=dMvRy9dr; 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 S1726245AbeLGQf0 (ORCPT + 31 others); Fri, 7 Dec 2018 11:35:26 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:32881 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726067AbeLGQfX (ORCPT ); Fri, 7 Dec 2018 11:35:23 -0500 Received: by mail-wr1-f68.google.com with SMTP id c14so4426236wrr.0 for ; Fri, 07 Dec 2018 08:35:21 -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=cAXi+ASHzDiWoNZ9nvermzRNOAAXGYqjUY99XxDx92M=; b=dMvRy9dr9QXQGjgrdblqBD0LJJmvr+ILUyyLujC+fpZfb/1FQHhHRk9GxvCXa75DR/ YzV+Scp8qO0K1G10juj6CZVRNhvt14aLQ7i/m8XxBOZiWKW6gQjhljp8WaxF2+cTl3KU wtvH4eNPaPx8nLBVzq7nT9kFwgS6impGOw/1Q= 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=cAXi+ASHzDiWoNZ9nvermzRNOAAXGYqjUY99XxDx92M=; b=OAnfZK4uXbSthwBWJY7XkHx1wP++yEoMObkEU8hrdw9CRnocxUKAeonedxYbdygS7B lvI6bA6q/9brFZhjq2XWRzH/NshFQ7arnFrALA8vuKkMuKRGxvHRypZR8IFiOzyX96um iKUzfwjkQ3SHWXN1I93pdwKGpbcSDETt3Ektimt6InrHBXpu8f34VyN8qwFn5FkbXNIG IGcdvheWbB35nTh2eTqyoBZpMwxxnSA3Rr9NJG/h5AUfNZo3YLnEfBw3O5MSUiNcyM8C KoBWnVqN8LXkuzwkYOTP7z2n7FfFMv0riYHu7ijCY2L8Sbadtu8uDU1iIYYkN/9wLh7f Iaew== X-Gm-Message-State: AA+aEWbYRCO8Re1fkcKfCy4SvMWkqQ3KQwwwj000S0vrXcL3QA5seApk Z7KRyaHozFgQhwhCMdf+lNbBqRxOW3s= X-Received: by 2002:adf:8143:: with SMTP id 61mr2298617wrm.47.1544200520033; Fri, 07 Dec 2018 08:35:20 -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 w6sm4268752wme.46.2018.12.07.08.35.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 07 Dec 2018 08:35:19 -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: [PATCH v2 2/6] misc: fastrpc: Add Qualcomm fastrpc basic driver model Date: Fri, 7 Dec 2018 16:35:09 +0000 Message-Id: <20181207163513.16412-3-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181207163513.16412-1-srinivas.kandagatla@linaro.org> References: <20181207163513.16412-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. Signed-off-by: Srinivas Kandagatla Co-developed-by: Thierry Escande Signed-off-by: Thierry Escande --- drivers/misc/Kconfig | 10 ++ drivers/misc/Makefile | 1 + drivers/misc/fastrpc.c | 319 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+) create mode 100644 drivers/misc/fastrpc.c -- 2.19.2 diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 3726eacdf65d..ad1f8f93a413 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 af22bbc3d00c..6f9a79d86c7d 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..7fc2b381074d --- /dev/null +++ b/drivers/misc/fastrpc.c @@ -0,0 +1,319 @@ +// 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; + bool secure; +}; + +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, + int secure) +{ + 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].secure == secure) { + 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, 0); + + 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, "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); + sess->secure = of_property_read_bool(dev->of_node, "secured"); + + if (of_property_read_u32(dev->of_node, "reg", &sess->sid)) + dev_err(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 err, domain_id; + + data = devm_kzalloc(rdev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + err = of_property_read_u32(rdev->of_node, "reg", &domain_id); + if (err) { + dev_err(rdev, "FastRPC Domain ID not specified in DT\n"); + return err; + } + + if (domain_id > CDSP_DOMAIN_ID) { + dev_err(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 Fri Dec 7 16:35:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 153175 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp703807ljp; Fri, 7 Dec 2018 08:35:40 -0800 (PST) X-Google-Smtp-Source: AFSGD/VvnZkS+FDUCexOhN3Y7wyFCHU9nAvh2MxqfWgS5mrbmnUubGgLTNcby7eI/umc8RvIlwaO X-Received: by 2002:a63:1204:: with SMTP id h4mr2567265pgl.51.1544200540559; Fri, 07 Dec 2018 08:35:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544200540; cv=none; d=google.com; s=arc-20160816; b=1BmJueP883ecxaoKEnLV255FemOLOj9jOZDv4KXh5Tj5cmt0AbeWNgnoNixm3AHchf g1PLoT+N3ZZqOwDoOSnJasJb+fMe5+e9BoAOTdvmnA7PDcOAzBwwsn1EWleeYmKGu9yQ oJqyqpyp/UWw+XGP/1oBaGZX+UsIXAQYZ8slwwwHZ2eLovo16NBNH5FK2XN2m86sVJE8 rbcs2JeobC/tpPbSof0K5qH9lN1Ept55hRygh4AreTFfL7jnDVScHWeQgSmSIDbtFnNT L74mHjJW0cVU1l21x4t0UHD1xoxMEEubchSrlikOaHfN2B36n9DP8N1RbX5DQFpYp2Zx xewg== 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=j7ztlxgaaKMqUIDeki3W+ij7QaeiY1jkJ4bd1JObo+A=; b=TgV1EaWdZkI9CsBuhG5D4NJM6QJIDtxbyPm2D55NDv6vDbJl25e4wDAWWdZUKvB3eX QIMxx4qRG5araOh4M2cOoOvtFz5Lfboo/Q8rSyBsKnbZdOgm26TpSkOETf2ZPNBzEcCh IhjHqGZCG4Ho7qebbGKYeBW2Rvfnl9A3KDLjWec0NUmclNQDgWDHdGMPCD2n1ni/YK6v Yskm+7x9uR5LXdRuzuxiJKZ3vDHhn86YLvHtX4NiNLTFwa9QkQViy1/hjWic9Do5gKk6 DjT6WvTRZ5xTl4+XD5e9tFjtM6J7Ja//q3LeJGVxp10ieX/KDjVSGndXqVjOchnYmdAQ MiwQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Y8QccUdj; 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 s59si3289345plb.237.2018.12.07.08.35.40; Fri, 07 Dec 2018 08:35:40 -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=Y8QccUdj; 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 S1726251AbeLGQf2 (ORCPT + 31 others); Fri, 7 Dec 2018 11:35:28 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:38373 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726182AbeLGQfY (ORCPT ); Fri, 7 Dec 2018 11:35:24 -0500 Received: by mail-wr1-f67.google.com with SMTP id v13so4390364wrw.5 for ; Fri, 07 Dec 2018 08:35:22 -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=j7ztlxgaaKMqUIDeki3W+ij7QaeiY1jkJ4bd1JObo+A=; b=Y8QccUdjSjXxiylMXTAJLs2UsJvmUzRkSH+OXpispczd4AJC3UCID3uERp6VVDlwFF Hw6glsUxhAl0JloeOK/BUDlSUWt8lVAs2gF6PKALSZZCyS83Skf/QhBa/B/mmcNcA1xA fhneyaacfodPhUV2qDJrSJQeqVObJUQ5Mch8c= 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=j7ztlxgaaKMqUIDeki3W+ij7QaeiY1jkJ4bd1JObo+A=; b=sNeKFfy8CYIA8YgKLdUe2jPMXrTtlacpjcqsbUOEnMcOLPXtoalOEsKbh6jcAI7jZ0 Z61KKzYHiO2+0lwvHW+6o4mj1G/oNETfIox3hFeOtkVppJSLkKi67h8FEbsGR+YsJvez XfWKbp6EeoAeQg4nemiQrR/zLD6RnVtsI29QkkNuKTnGO0VHQdS0zaqeeR1v1hE+etDT nv7TI/thU9fPR+tlz7kUxV4Rv4o7T+U30cdu8jfaIdAZaGYRN3RalAqTd/AxDK2AWjLL MYqxc+FhTLwnpmWICciTGla1sdRXNNLfU5FkdjRR9eYJHwb5AQnoMDeMKbxisLeCQ74h 1SFA== X-Gm-Message-State: AA+aEWbS15Qtd87qjRaKm8MTpthcnQCxi35aG4PJFwj/AebXNIgMRPPJ 3pWLIOnXvBIL4NsNoarrEIsgfw== X-Received: by 2002:adf:db51:: with SMTP id f17mr2257639wrj.90.1544200521315; Fri, 07 Dec 2018 08:35:21 -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 w6sm4268752wme.46.2018.12.07.08.35.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 07 Dec 2018 08:35:20 -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: [PATCH v2 3/6] misc: fastrpc: Add support for context Invoke method Date: Fri, 7 Dec 2018 16:35:10 +0000 Message-Id: <20181207163513.16412-4-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181207163513.16412-1-srinivas.kandagatla@linaro.org> References: <20181207163513.16412-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 compute context invoke method on the remote processor (DSP). This involves setting up the functions input and output arguments, input and output handles and mapping the dmabuf fd for the argument/handle buffers. 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 | 716 ++++++++++++++++++++++++++++++++++++ include/uapi/misc/fastrpc.h | 22 ++ 2 files changed, 738 insertions(+) create mode 100644 include/uapi/misc/fastrpc.h -- 2.19.2 diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 7fc2b381074d..46435813785d 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -2,7 +2,9 @@ // Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. // Copyright (c) 2018, Linaro Limited +#include #include +#include #include #include #include @@ -14,6 +16,7 @@ #include #include #include +#include #define ADSP_DOMAIN_ID (0) #define MDSP_DOMAIN_ID (1) @@ -21,14 +24,119 @@ #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_ALIGN 128 +#define FASTRPC_MAX_FDLIST 16 +#define FASTRPC_MAX_CRCLIST 64 +#define FASTRPC_PHYS(p) ((p) & 0xffffffff) #define FASTRPC_CTX_MAX (256) #define FASTRPC_CTXID_MASK (0xFF0) #define FASTRPC_DEVICE_NAME "fastrpc" +/* Retrives number of input buffers from the scalars parameter */ +#define REMOTE_SCALARS_INBUFS(sc) (((sc) >> 16) & 0x0ff) + +/* Retrives number of output buffers from the scalars parameter */ +#define REMOTE_SCALARS_OUTBUFS(sc) (((sc) >> 8) & 0x0ff) + +/* Retrives number of input handles from the scalars parameter */ +#define REMOTE_SCALARS_INHANDLES(sc) (((sc) >> 4) & 0x0f) + +/* Retrives number of output handles from the scalars parameter */ +#define REMOTE_SCALARS_OUTHANDLES(sc) ((sc) & 0x0f) + +#define REMOTE_SCALARS_LENGTH(sc) (REMOTE_SCALARS_INBUFS(sc) + \ + REMOTE_SCALARS_OUTBUFS(sc) + \ + REMOTE_SCALARS_INHANDLES(sc)+ \ + REMOTE_SCALARS_OUTHANDLES(sc)) + +#define FASTRPC_BUILD_SCALARS(attr, method, in, out, oin, oout) \ + ((((uint32_t) (attr) & 0x07) << 29) | \ + (((uint32_t) (method) & 0x1f) << 24) | \ + (((uint32_t) (in) & 0xff) << 16) | \ + (((uint32_t) (out) & 0xff) << 8) | \ + (((uint32_t) (oin) & 0x0f) << 4) | \ + ((uint32_t) (oout) & 0x0f)) + +#define FASTRPC_SCALARS(method, in, out) \ + FASTRPC_BUILD_SCALARS(0, method, in, out, 0, 0) + #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_phy_page { + uint64_t addr; /* physical address */ + uint64_t size; /* size of contiguous region */ +}; + +struct fastrpc_invoke_buf { + int num; /* number of contiguous regions */ + int pgidx; /* index to start of contiguous region */ +}; + +struct fastrpc_remote_arg { + uint64_t pv; + uint64_t len; +}; + +struct fastrpc_msg { + uint32_t pid; /* process group id */ + uint32_t tid; /* thread id */ + uint64_t ctx; /* invoke caller context */ + uint32_t handle; /* handle to invoke */ + uint32_t sc; /* scalars structure describing the data */ + uint64_t addr; /* physical address */ + uint64_t size; /* size of contiguous region */ +}; + +struct fastrpc_invoke_rsp { + uint64_t ctx; /* invoke caller context */ + int retval; /* invoke return value */ +}; + +struct fastrpc_buf { + struct fastrpc_user *fl; + struct device *dev; + void *virt; + uint64_t phys; + size_t size; +}; + +struct fastrpc_map { + struct list_head node; + struct fastrpc_user *fl; + int fd; + struct dma_buf *buf; + struct sg_table *table; + struct dma_buf_attachment *attach; + uint64_t phys; + size_t size; + void *va; + size_t len; + struct kref refcount; +}; + +struct fastrpc_invoke_ctx { + struct fastrpc_user *fl; + struct list_head node; /* list of ctxs */ + struct completion work; + int retval; + int pid; + int tgid; + uint32_t sc; + struct fastrpc_msg msg; + uint64_t ctxid; + size_t used_sz; + + int nscalars; + int nbufs; + uint32_t *crc; + + struct fastrpc_remote_arg *rpra; + struct fastrpc_map **maps; + struct fastrpc_buf *buf; + struct fastrpc_invoke_args *args; +}; struct fastrpc_session_ctx { struct device *dev; @@ -56,6 +164,7 @@ struct fastrpc_user { struct fastrpc_channel_ctx *cctx; struct fastrpc_session_ctx *sctx; + struct fastrpc_buf *init_mem; int tgid; int pd; @@ -65,6 +174,508 @@ struct fastrpc_user { struct mutex mutex; }; +static void fastrpc_free_map(struct kref *ref) +{ + struct fastrpc_map *map; + + map = container_of(ref, struct fastrpc_map, refcount); + + list_del(&map->node); + + if (map->table) { + dma_buf_unmap_attachment(map->attach, map->table, + DMA_BIDIRECTIONAL); + dma_buf_detach(map->buf, map->attach); + dma_buf_put(map->buf); + } + + kfree(map); +} + +static void fastrpc_map_put(struct fastrpc_map *map) +{ + struct fastrpc_user *fl; + + if (map) { + fl = map->fl; + mutex_lock(&fl->mutex); + kref_put(&map->refcount, fastrpc_free_map); + mutex_unlock(&fl->mutex); + } +} + +static int fastrpc_map_get(struct fastrpc_user *fl, int fd, size_t len, + struct fastrpc_map **ppmap) +{ + struct fastrpc_map *map = NULL, *n; + + mutex_lock(&fl->mutex); + list_for_each_entry_safe(map, n, &fl->maps, node) { + if (map->fd == fd) { + kref_get(&map->refcount); + *ppmap = map; + mutex_unlock(&fl->mutex); + return 0; + } + } + mutex_unlock(&fl->mutex); + + return -ENOENT; +} + +static void fastrpc_buf_free(struct fastrpc_buf *buf) +{ + dma_free_coherent(buf->dev, buf->size, buf->virt, + FASTRPC_PHYS(buf->phys)); + kfree(buf); +} + +static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, + size_t size, struct fastrpc_buf **obuf) +{ + struct fastrpc_buf *buf; + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf->fl = fl; + buf->virt = NULL; + buf->phys = 0; + buf->size = size; + buf->dev = dev; + + buf->virt = dma_alloc_coherent(dev, buf->size, (dma_addr_t *)&buf->phys, + GFP_KERNEL); + if (!buf->virt) + return -ENOMEM; + + if (fl->sctx && fl->sctx->sid) + buf->phys += ((uint64_t)fl->sctx->sid << 32); + + *obuf = buf; + + return 0; +} + +static void fastrpc_context_free(struct fastrpc_invoke_ctx *ctx) +{ + struct fastrpc_channel_ctx *cctx = ctx->fl->cctx; + struct fastrpc_user *user = ctx->fl; + int scalars = REMOTE_SCALARS_LENGTH(ctx->sc); + int i; + + spin_lock(&user->lock); + list_del(&ctx->node); + spin_unlock(&user->lock); + + for (i = 0; i < scalars; i++) { + if (ctx->maps[i]) + fastrpc_map_put(ctx->maps[i]); + } + + if (ctx->buf) + fastrpc_buf_free(ctx->buf); + + spin_lock(&cctx->lock); + idr_remove(&cctx->ctx_idr, ctx->ctxid >> 4); + spin_unlock(&cctx->lock); + + kfree(ctx->maps); + kfree(ctx); +} + +static struct fastrpc_invoke_ctx * +fastrpc_context_alloc(struct fastrpc_user *user, uint32_t kernel, + struct fastrpc_invoke *inv) +{ + struct fastrpc_channel_ctx *cctx = user->cctx; + struct fastrpc_invoke_ctx *ctx = NULL; + int bufs, ret; + int err = 0; + + bufs = REMOTE_SCALARS_LENGTH(inv->sc); + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&ctx->node); + ctx->fl = user; + ctx->nscalars = bufs; + ctx->nbufs = REMOTE_SCALARS_INBUFS(inv->sc) + + REMOTE_SCALARS_OUTBUFS(inv->sc); + + if (ctx->nscalars) { + ctx->maps = kcalloc(ctx->nscalars, + sizeof(*ctx->maps), GFP_KERNEL); + if (!ctx->maps) { + kfree(ctx); + return ERR_PTR(-ENOMEM); + } + ctx->args = inv->args; + } + + ctx->sc = inv->sc; + ctx->retval = -1; + ctx->pid = current->pid; + ctx->tgid = user->tgid; + init_completion(&ctx->work); + + spin_lock(&user->lock); + list_add_tail(&ctx->node, &user->pending); + spin_unlock(&user->lock); + + spin_lock(&cctx->lock); + ret = idr_alloc_cyclic(&cctx->ctx_idr, ctx, 1, + FASTRPC_CTX_MAX, GFP_ATOMIC); + if (ret < 0) { + spin_unlock(&cctx->lock); + err = ret; + goto err_idr; + } + ctx->ctxid = ret << 4; + spin_unlock(&cctx->lock); + + return ctx; +err_idr: + spin_lock(&user->lock); + list_del(&ctx->node); + spin_unlock(&user->lock); + kfree(ctx->maps); + kfree(ctx); + + return ERR_PTR(err); +} + +static int fastrpc_map_create(struct fastrpc_user *fl, int fd, + size_t len, struct fastrpc_map **ppmap) +{ + struct fastrpc_session_ctx *sess = fl->sctx; + struct fastrpc_map *map = NULL; + int err = 0; + + if (!fastrpc_map_get(fl, fd, len, ppmap)) + return 0; + + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (!map) + return -ENOMEM; + + INIT_LIST_HEAD(&map->node); + map->fl = fl; + map->fd = fd; + map->buf = dma_buf_get(fd); + if (!map->buf) { + err = -EINVAL; + goto get_err; + } + + map->attach = dma_buf_attach(map->buf, sess->dev); + if (IS_ERR(map->attach)) { + dev_err(sess->dev, "Failed to attach dmabuf\n"); + err = PTR_ERR(map->attach); + goto attach_err; + } + + map->table = dma_buf_map_attachment(map->attach, DMA_BIDIRECTIONAL); + if (IS_ERR(map->table)) { + err = PTR_ERR(map->table); + goto map_err; + } + + map->phys = sg_dma_address(map->table->sgl); + map->phys += ((uint64_t)fl->sctx->sid << 32); + map->size = len; + map->va = sg_virt(map->table->sgl); + map->len = len; + kref_init(&map->refcount); + + spin_lock(&fl->lock); + list_add_tail(&map->node, &fl->maps); + spin_unlock(&fl->lock); + *ppmap = map; + + return 0; + +map_err: + dma_buf_detach(map->buf, map->attach); +attach_err: + dma_buf_put(map->buf); +get_err: + kfree(map); + + return err; +} + +/* + * Fastrpc payload buffer with metadata looks like: + * + * >>>>>> START of METADATA <<<<<<<<< + * +---------------------------------+ + * | Arguments | + * | type:(struct fastrpc_remote_arg)| + * | (0 - N) | + * +---------------------------------+ + * | Invoke Buffer list | + * | type:(struct fastrpc_invoke_buf)| + * | (0 - N) | + * +---------------------------------+ + * | Page info list | + * | type:(struct fastrpc_phy_page) | + * | (0 - N) | + * +---------------------------------+ + * | Optional info | + * |(can be specific to SoC/Firmware)| + * +---------------------------------+ + * >>>>>>>> END of METADATA <<<<<<<<< + * +---------------------------------+ + * | Inline ARGS | + * | (0-N) | + * +---------------------------------+ + */ + +static int fastrpc_get_meta_size(struct fastrpc_invoke_ctx *ctx) +{ + int size = 0; + + size = (sizeof(struct fastrpc_remote_arg) + + sizeof(struct fastrpc_invoke_buf) + + sizeof(struct fastrpc_phy_page)) * ctx->nscalars + + sizeof(uint64_t) * FASTRPC_MAX_FDLIST + + sizeof(uint32_t) * FASTRPC_MAX_CRCLIST; + + return size; +} + +static int fastrpc_get_payload_size(struct fastrpc_invoke_ctx *ctx, int metalen) +{ + int i, size = 0; + + size = ALIGN(metalen, FASTRPC_ALIGN); + for (i = 0; i < ctx->nscalars; i++) { + if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1) { + size = ALIGN(size, FASTRPC_ALIGN); + size += ctx->args[i].length; + } + } + + return size; +} + +static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx) +{ + struct device *dev = ctx->fl->sctx->dev; + int i, err; + + for (i = 0; i < ctx->nscalars; ++i) { + if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1 || + ctx->args[i].length == 0) + continue; + + err = fastrpc_map_create(ctx->fl, ctx->args[i].fd, + ctx->args[i].length, &ctx->maps[i]); + if (err) { + dev_err(dev, "Error Creating map %d\n", err); + return -EINVAL; + } + + } + return 0; +} + +static int fastrpc_get_args(uint32_t kernel, struct fastrpc_invoke_ctx *ctx) +{ + struct device *dev = ctx->fl->sctx->dev; + struct fastrpc_remote_arg *rpra; + struct fastrpc_invoke_buf *list; + struct fastrpc_phy_page *pages; + uintptr_t args; + size_t rlen = 0, pkt_size = 0, metalen = 0; + int inbufs, i, err = 0; + + inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); + metalen = fastrpc_get_meta_size(ctx); + pkt_size = fastrpc_get_payload_size(ctx, metalen); + fastrpc_create_maps(ctx); + ctx->used_sz = pkt_size; + + err = fastrpc_buf_alloc(ctx->fl, dev, pkt_size, &ctx->buf); + if (err) + goto bail; + + rpra = ctx->buf->virt; + list = ctx->buf->virt + ctx->nscalars * sizeof(*rpra); + pages = ctx->buf->virt + ctx->nscalars * (sizeof(*list) + + sizeof(*rpra)); + args = (uintptr_t)ctx->buf->virt + metalen; + rlen = pkt_size - metalen; + ctx->rpra = rpra; + + for (i = 0; i < ctx->nbufs; ++i) { + size_t len = ctx->args[i].length; + + rpra[i].pv = 0; + rpra[i].len = len; + list[i].num = len ? 1 : 0; + list[i].pgidx = i; + + if (!len) + continue; + + pages[i].size = roundup(len, PAGE_SIZE); + + if (ctx->maps[i]) { + rpra[i].pv = (uint64_t) ctx->args[i].ptr; + pages[i].addr = ctx->maps[i]->phys; + } else { + rlen -= ALIGN(args, FASTRPC_ALIGN) - args; + args = ALIGN(args, FASTRPC_ALIGN); + if (rlen < len) + goto bail; + + rpra[i].pv = (args); + pages[i].addr = ctx->buf->phys + (pkt_size - rlen); + pages[i].addr = pages[i].addr & PAGE_MASK; + args = args + len; + rlen -= len; + } + + if (i < inbufs && !ctx->maps[i]) { + if (!kernel) { + err = copy_from_user((void *)rpra[i].pv, + (void __user *)ctx->args[i].ptr, + ctx->args[i].length); + if (err) + goto bail; + } else { + memcpy((void *)rpra[i].pv, ctx->args[i].ptr, + ctx->args[i].length); + } + } + } + + for (i = ctx->nbufs; i < ctx->nscalars; ++i) { + rpra[i].pv = (uint64_t) ctx->args[i].ptr; + rpra[i].len = ctx->args[i].length; + list[i].num = ctx->args[i].length ? 1 : 0; + list[i].pgidx = i; + pages[i].addr = ctx->maps[i]->phys; + pages[i].size = ctx->maps[i]->size; + } + +bail: + if (err) + dev_err(dev, "Error: get invoke args failed:%d\n", err); + + return err; +} + +static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, + uint32_t kernel) +{ + struct fastrpc_remote_arg *rpra = ctx->rpra; + struct device *dev = ctx->fl->sctx->dev; + int i, inbufs, err; + + inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); + + for (i = inbufs; i < ctx->nbufs; ++i) { + if (ctx->maps[i]) { + fastrpc_map_put(ctx->maps[i]); + ctx->maps[i] = NULL; + continue; + } + + if (!kernel) { + err = copy_to_user((void __user *)ctx->args[i].ptr, + (void *)rpra[i].pv, rpra[i].len); + if (err) { + dev_err(dev, "Error: copy buffer %d\n", err); + return err; + } + } else { + memcpy(ctx->args[i].ptr, (void *)rpra[i].pv, + rpra[i].len); + } + } + + return 0; +} + +static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, + struct fastrpc_invoke_ctx *ctx, + uint32_t kernel, uint32_t handle) +{ + struct fastrpc_channel_ctx *cctx; + struct fastrpc_user *fl = ctx->fl; + struct fastrpc_msg *msg = &ctx->msg; + + cctx = fl->cctx; + msg->pid = fl->tgid; + msg->tid = current->pid; + + if (kernel) + msg->pid = 0; + + msg->ctx = ctx->ctxid | fl->pd; + msg->handle = handle; + msg->sc = ctx->sc; + msg->addr = ctx->buf ? ctx->buf->phys : 0; + msg->size = roundup(ctx->used_sz, PAGE_SIZE); + + return rpmsg_send(cctx->rpdev->ept, (void *)msg, sizeof(*msg)); +} + +static int fastrpc_internal_invoke(struct fastrpc_user *fl, + uint32_t kernel, + struct fastrpc_invoke *inv) +{ + struct fastrpc_invoke_ctx *ctx = NULL; + int err = 0; + + if (!fl->sctx) + return -EINVAL; + + ctx = fastrpc_context_alloc(fl, kernel, inv); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + if (ctx->nscalars) { + err = fastrpc_get_args(kernel, ctx); + if (err) + goto bail; + } + /* Send invoke buffer to remote dsp */ + err = fastrpc_invoke_send(fl->sctx, ctx, kernel, inv->handle); + if (err) + goto bail; + + /* Wait for remote dsp to respond or time out */ + err = wait_for_completion_interruptible(&ctx->work); + if (err) + goto bail; + + /* Check the response from remote dsp */ + err = ctx->retval; + if (err) + goto bail; + + /* populate all the output buffers with results */ + err = fastrpc_put_args(ctx, kernel); + if (err) + goto bail; + + /* We are done with this compute, release it now! */ +bail: + if (ctx) + fastrpc_context_free(ctx); + + if (err) + dev_err(fl->sctx->dev, "Error: Invoke Failed %d\n", err); + + return err; +} + static struct fastrpc_session_ctx *fastrpc_session_alloc( struct fastrpc_channel_ctx *cctx, int secure) @@ -98,11 +709,22 @@ 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; spin_lock(&cctx->lock); list_del(&fl->user); spin_unlock(&cctx->lock); + if (fl->init_mem) + fastrpc_buf_free(fl->init_mem); + + list_for_each_entry_safe(ctx, n, &fl->pending, node) + fastrpc_context_free(ctx); + + list_for_each_entry_safe(map, m, &fl->maps, node) + fastrpc_map_put(map); + fastrpc_session_free(fl->cctx, fl->sctx); mutex_destroy(&fl->mutex); @@ -137,9 +759,62 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) return 0; } +static long fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) +{ + struct fastrpc_invoke_args *args = NULL; + struct fastrpc_invoke inv; + int nscalars, err; + + if (copy_from_user(&inv, argp, sizeof(inv))) + return -EFAULT; + + nscalars = REMOTE_SCALARS_LENGTH(inv.sc); + if (nscalars) { + args = kcalloc(nscalars, sizeof(*args), GFP_KERNEL); + if (!args) + return -ENOMEM; + + if (copy_from_user(args, (void __user *)inv.args, + nscalars * sizeof(*args))) { + kfree(args); + return -EFAULT; + } + } + + inv.args = args; + err = fastrpc_internal_invoke(fl, 0, &inv); + kfree(args); + + return err; +} + +static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data; + char __user *argp = (char __user *)arg; + int err; + + switch (cmd) { + case FASTRPC_IOCTL_INVOKE: + err = fastrpc_invoke(fl, argp); + break; + default: + err = -ENOTTY; + dev_err(fl->sctx->dev, "bad ioctl: %d\n", cmd); + break; + } + + if (err) + dev_err(fl->sctx->dev, "Error: IOCTL Failed with %d\n", err); + + return err; +} + static const struct file_operations fastrpc_fops = { .open = fastrpc_device_open, .release = fastrpc_device_release, + .unlocked_ioctl = fastrpc_device_ioctl, }; static int fastrpc_cb_probe(struct platform_device *pdev) @@ -256,9 +931,25 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) return of_platform_populate(rdev->of_node, NULL, NULL, rdev); } +static void fastrpc_notify_users(struct fastrpc_user *user) +{ + struct fastrpc_invoke_ctx *ctx, *n; + + spin_lock(&user->lock); + list_for_each_entry_safe(ctx, n, &user->pending, node) + 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); + struct fastrpc_user *user, *n; + + spin_lock(&cctx->lock); + list_for_each_entry_safe(user, n, &cctx->users, user) + fastrpc_notify_users(user); + spin_unlock(&cctx->lock); misc_deregister(&cctx->miscdev); of_platform_depopulate(&rpdev->dev); @@ -268,6 +959,31 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) 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_ctx *ctx; + unsigned long flags; + int ctxid; + + if (rsp && len < sizeof(*rsp)) { + dev_err(&rpdev->dev, "invalid response or context\n"); + return -EINVAL; + } + + ctxid = (uint32_t)((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; + } + + ctx->retval = rsp->retval; + complete(&ctx->work); + return 0; } diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h new file mode 100644 index 000000000000..0b408ba62482 --- /dev/null +++ b/include/uapi/misc/fastrpc.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __QCOM_FASTRPC_H__ +#define __QCOM_FASTRPC_H__ + +#include + +#define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_invoke) + +struct fastrpc_invoke_args { + __s32 fd; + size_t length; + void *ptr; +}; + +struct fastrpc_invoke { + __u32 handle; + __u32 sc; + struct fastrpc_invoke_args *args; +}; + +#endif /* __QCOM_FASTRPC_H__ */ From patchwork Fri Dec 7 16:35:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 153178 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp703991ljp; Fri, 7 Dec 2018 08:35:49 -0800 (PST) X-Google-Smtp-Source: AFSGD/UvNBk6fGo3AryhZtjvMwwI5ZokheUJU6zLQY456WURTq1k/tDqzfjtLl6nzovgWJ+bkWIo X-Received: by 2002:a17:902:b7c7:: with SMTP id v7mr2783150plz.75.1544200549771; Fri, 07 Dec 2018 08:35:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544200549; cv=none; d=google.com; s=arc-20160816; b=AzySv6t2RzZqbLA1hkVlMXWAk/RtMgX+BCrMIiYgmAKIeO4Pzn9eEstR/zfcyYuPRu qKbtFmCCa3ANqdAAT4LX/c5VcrbnIYeMRmF9tmSzQg64BItpiWH27XbwDDTg4XlsVGlH wCP4SEUqby+bgPXmBLJVqXZ3n1b+OyhsLGRtKzubHyAZBbgJyninzOKtdCVzCJog3nbY FfVQYCLUviZsJPZ5ly7hoHIKdJAS3p75dKUaUi0kW+TfjqdBGgusn+n213iwTKYSGEk3 2OA5Xcc6LuTC4DLOv4jQ02FNoASUsRDTo2Zeo4yssjXUhoyTzSJJxPeMkmdngG6sGmbL PIzA== 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=JSj3fdMMzho6wZgYvLNiLtO6E/C345g53NObmvAcTok=; b=ZYpJmNrR4cjOhrAaGpXa7dz3Dp68KiT6h86l0lgd1omWE0XSY+8S0DSm2doAVrogAr wyt9paAURTlG4LrbWMski3MkWA1KsP1gJ0WvFvZHyyKlJzg2wJLF2PShj9X6Y+E4pVf5 l4sPLU82PKgAlg6ov+4zVaQgs6u7hgt4QN/NvDQ+FAKiLTVyTTyHm5DJIpEMaA5qaSNu hD5/i6IYF52cOwkGnjO/BN2jPbmbGG/PcqxQT4XY1kvrO7NIWHNiwnhrapFK6yTEVauP AsSBZkIV15B4mqXYSGEmzp83wJglOj2NVW35gTAxGIUHruADEfR0micJd6VQ9hVLCzjG aPGQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=cv6iGX4t; 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 o7si3182502pgg.118.2018.12.07.08.35.49; Fri, 07 Dec 2018 08:35:49 -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=cv6iGX4t; 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 S1726304AbeLGQfs (ORCPT + 31 others); Fri, 7 Dec 2018 11:35:48 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:45043 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726203AbeLGQfZ (ORCPT ); Fri, 7 Dec 2018 11:35:25 -0500 Received: by mail-wr1-f65.google.com with SMTP id z5so4353702wrt.11 for ; Fri, 07 Dec 2018 08:35:23 -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=JSj3fdMMzho6wZgYvLNiLtO6E/C345g53NObmvAcTok=; b=cv6iGX4t19Rk0mRaqsNePtGHFTt7bRRHnusH2il0AIpA/wJHey9d7U6tqhzl2cdsc9 F+ZDTij3C/e6+8JtG/lZgvNEC9ErinkH+F+xlHgKWaDXfWDkCebrXdh6n3SjgprByQba KMe8o8fyGCMJABZazK1hDtAQOU+HVISB/qTVg= 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=JSj3fdMMzho6wZgYvLNiLtO6E/C345g53NObmvAcTok=; b=VnmVZnDOT3OJW4kiHCBJTKWswrhcSlY6In0beSwl9PJ0EP69O8EFtujZ0uDaoaQSyA xZnu2nFaF06nhTGL1EhH4rJm7cqm1F1MN7DEbstZnsVoYcwjZLBl6c4Ua1jXfcO45SwI g67Qak6/D69+xHqkcd/i49Rs3ffak9GiwX1kYItoUaIOn96NhMXb03HsB+mSL29boaGn K+tWdq78M8HsjZ/wmKBDRMoLEzp78TvpnaKlV9wPUnGHCaub4Ooq545D5AnFSrF/Ob4L 5FrN6AkhBXSbc8O7jEbR/9qS0CsPv2xSb8q8TtLQXjZpmidwIG/MEWWIUCl3O85ws6ls 5NxA== X-Gm-Message-State: AA+aEWaB8xEYc7uxgkE2Ms8iobYvaiaKCMQ6WtB4P32rWoVWMJxnmFJW 1WpqFzPMYQLb0hBfBX7YH0dgBw== X-Received: by 2002:adf:aac6:: with SMTP id i6mr2339945wrc.216.1544200522552; Fri, 07 Dec 2018 08:35:22 -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 w6sm4268752wme.46.2018.12.07.08.35.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 07 Dec 2018 08:35:21 -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: [PATCH v2 4/6] misc: fastrpc: Add support for create remote init process Date: Fri, 7 Dec 2018 16:35:11 +0000 Message-Id: <20181207163513.16412-5-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181207163513.16412-1-srinivas.kandagatla@linaro.org> References: <20181207163513.16412-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 | 140 ++++++++++++++++++++++++++++++++++++ include/uapi/misc/fastrpc.h | 12 ++++ 2 files changed, 152 insertions(+) -- 2.19.2 diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 46435813785d..fda674e9efe2 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", @@ -676,6 +686,94 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, return err; } +static long 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_invoke inv; + struct fastrpc_map *map = NULL; + struct fastrpc_buf *imem = NULL; + int err, memlen; + struct { + int pgid; + unsigned int namelen; + unsigned int filelen; + unsigned int pageslen; + int attrs; + int siglen; + } inbuf; + + err = copy_from_user(&init, argp, sizeof(init)); + if (err) + goto bail; + + if (init.filelen > INIT_FILELEN_MAX || + init.memlen > INIT_MEMLEN_MAX) + 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) + goto bail; + + fl->init_mem = imem; + args[0].ptr = &inbuf; + args[0].length = sizeof(inbuf); + args[0].fd = -1; + + args[1].ptr = current->comm; + args[1].length = inbuf.namelen; + args[1].fd = -1; + + args[2].ptr = (void *)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 = pages; + args[3].length = 1 * sizeof(*pages); + args[3].fd = -1; + + args[4].ptr = &inbuf.attrs; + args[4].length = sizeof(inbuf.attrs); + args[4].fd = -1; + + args[5].ptr = &inbuf.siglen; + args[5].length = sizeof(inbuf.siglen); + args[5].fd = -1; + + inv.handle = 1; + inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0); + if (init.attrs) + inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 6, 0); + inv.args = &args[0]; + err = fastrpc_internal_invoke(fl, 1, &inv); +bail: + if (map) + fastrpc_map_put(map); + + return err; +} + static struct fastrpc_session_ctx *fastrpc_session_alloc( struct fastrpc_channel_ctx *cctx, int secure) @@ -705,6 +803,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 inv; + struct fastrpc_invoke_args args[1]; + int tgid = 0; + + tgid = fl->tgid; + args[0].ptr = &tgid; + args[0].length = sizeof(tgid); + args[0].fd = -1; + inv.handle = 1; + inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0); + inv.args = &args[0]; + + return fastrpc_internal_invoke(fl, 1, &inv); +} + static int fastrpc_device_release(struct inode *inode, struct file *file) { struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data; @@ -712,6 +827,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); @@ -759,6 +876,23 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) return 0; } +static long fastrpc_init_attach(struct fastrpc_user *fl) +{ + struct fastrpc_invoke_args args[1]; + struct fastrpc_invoke inv; + int tgid = fl->tgid; + + args[0].ptr = &tgid; + args[0].length = sizeof(tgid); + args[0].fd = -1; + inv.handle = FASTRPC_INIT_HANDLE; + inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0); + inv.args = &args[0]; + fl->pd = 0; + + return fastrpc_internal_invoke(fl, 1, &inv); +} + static long fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_invoke_args *args = NULL; @@ -799,6 +933,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 0b408ba62482..2f0afa5dab1f 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 { __s32 fd; @@ -19,4 +21,14 @@ struct fastrpc_invoke { struct fastrpc_invoke_args *args; }; +struct fastrpc_init_create { + __u32 filelen; /* elf file length */ + __u32 filefd; /* fd for the file */ + __u32 memlen; /* mem length */ + __u32 memfd; /* fd for the mem */ + __u32 attrs; + __u32 siglen; + __u64 file; /* pointer to elf file */ +}; + #endif /* __QCOM_FASTRPC_H__ */ From patchwork Fri Dec 7 16:35:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 153176 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp703820ljp; Fri, 7 Dec 2018 08:35:41 -0800 (PST) X-Google-Smtp-Source: AFSGD/W5nEfLWDgXFBj8fna0SSMBjvvBJOK+3ywjgFTw65H6Zir8RN0mwOev/vVKxJ7Oh4wOiHIZ X-Received: by 2002:a63:1904:: with SMTP id z4mr2480187pgl.135.1544200541387; Fri, 07 Dec 2018 08:35:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544200541; cv=none; d=google.com; s=arc-20160816; b=awlcYE3C0sNsJPiy5+p6/vbT9rSzk8rqutCH5DzitoFo6yteFeaCudclngRvQM+ww7 9/jD2Exhz3OTfpLm8CPKpXl3z5INPe4TeocztJkYcMxnnTVyi48HNtTDLYIJGDXCeoJs gVXt3M86m59TdXAjpxo+aYslzx7iwQ7JtmdGpttH94kG5PKS8MBX8kzg1K9R3BqJVLkm YjLwYApTFdKgrcONWZV7MJ5sUDo/EjM1FgHZhq2nwIz1vDZKrRtIgwdDgo8lkg21cqWS q0UhZrzX45sCvfCYlGiUaNuu6cd5Nqx+5xlVgRPRVsjhohO0dl73BLsQiU6/tNdYqKDD mh/A== 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=UQ+PJLKTzPpPTHfRUO6Ar2xCC5SpgIGYufiOB0FS4tU=; b=DvJ3xHn++nWOhVVwSSLlSHmMw+X/bvCyw5+rRMfx6NpNdF3eAU6TK0A39fgYNqOUd2 frrsSHV1sOnqH8ujOT1fVcsr7q3B9VPDWTDaL+cpxwvpTveO8S5PecDJdmROyHQmiU/F ElrGbYnqzBL4Bz6uN/FVXqBSOK4mQM/PfVEi+zjW1dFrvdPx0TjpbOvDBOzU3waZgJV3 9sB+TmWdlkOhCz7HnVlGuhbXpbcaN+9oVyYuyH3kLj6f7iYyLN/vpo247liVeZ+gFOlk DptkYurS3Y8xRrbxd8J9nsrmh4A5awbdFH2CXhQbB3pvYurHTKPXoAD8u2lA14StBTtC SZ8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gl2pWT01; 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 s59si3289345plb.237.2018.12.07.08.35.41; Fri, 07 Dec 2018 08:35:41 -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=gl2pWT01; 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 S1726275AbeLGQfd (ORCPT + 31 others); Fri, 7 Dec 2018 11:35:33 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:40966 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726234AbeLGQf0 (ORCPT ); Fri, 7 Dec 2018 11:35:26 -0500 Received: by mail-wr1-f65.google.com with SMTP id x10so4374100wrs.8 for ; Fri, 07 Dec 2018 08:35:25 -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=UQ+PJLKTzPpPTHfRUO6Ar2xCC5SpgIGYufiOB0FS4tU=; b=gl2pWT01E6DtIS0VB3E+M3TdRA2UczDDViVaFKLZICkugVcs3tMZgr6DqD6QEuS/f8 OKBSETt6bnVUol7H2Yby/FbXMJlhYzhH+2OE2/BruiKeZyIrhb6urrG7tDGDB6TUsu05 F0tKmuPQKlUKkBBeS9IbdgxqmI8N8L5IdgdH0= 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=UQ+PJLKTzPpPTHfRUO6Ar2xCC5SpgIGYufiOB0FS4tU=; b=GpWRWh5jb4qqZdbGU4nwi+uDL42YH7PiJA+r6UN0NYBwBAsmaMSUOp+vo9vN092o9I 5KO2lmTqyOpabEs67bZJITssY5BAwGdNnDLmhbUOVjuHBLQLcr8eGy5e4czQi++uiMgO GdLv1NW3GaIxY/0eX4+WRdtfoubcWzPvAgagnxpJY7+UEykSFROhKUj4NFkVm6uQ7spV 4BbvzEAQS+dxx0a/ERAQBaCVo9TiMNgsuqu9pvryJ4A0PmnabNch6/QuxM6k0C9TErlO FqtHO78TDH+hb657l1hkrth9W0s4UH6FfJ3vfNeqEqsFrU0brvhwfSaCeOJU/bCvDTj9 Ayiw== X-Gm-Message-State: AA+aEWY4dRZRoqVvgzgB7eVUUnReipSD/WUS4Udy97fiBmylMuMWbNSY wf2hF1tdLWkM7pVRy72tLab0kg== X-Received: by 2002:adf:b783:: with SMTP id s3mr2518323wre.274.1544200524816; Fri, 07 Dec 2018 08:35:24 -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 w6sm4268752wme.46.2018.12.07.08.35.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 07 Dec 2018 08:35:24 -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: [PATCH v2 6/6] misc: fastrpc: Add support for compat ioctls Date: Fri, 7 Dec 2018 16:35:13 +0000 Message-Id: <20181207163513.16412-7-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181207163513.16412-1-srinivas.kandagatla@linaro.org> References: <20181207163513.16412-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 for compat ioctl from 32 bits userland to Qualcomm fastrpc driver. Supported ioctls in this change are INIT, INVOKE, and ALLOC/FREE_DMA. 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 | 71 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) -- 2.19.2 diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 5ea2bba1e4bd..f36657263183 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -2,6 +2,7 @@ // Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. // Copyright (c) 2018, Linaro Limited +#include #include #include #include @@ -194,6 +195,22 @@ struct fastrpc_user { struct mutex mutex; }; +#ifdef CONFIG_COMPAT + +#define FASTRPC_IOCTL_INVOKE32 _IOWR('R', 3, struct fastrpc_invoke32) +struct fastrpc_invoke_args32 { + __s32 fd; + compat_size_t length; + compat_caddr_t ptr; +}; + +struct fastrpc_invoke32 { + __u32 handle; + __u32 sc; + compat_uptr_t args; +}; +#endif + static void fastrpc_free_map(struct kref *ref) { struct fastrpc_map *map; @@ -1092,6 +1109,52 @@ static long fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) return err; } +#ifdef CONFIG_COMPAT +static long fastrpc_invoke32(struct fastrpc_user *fl, compat_uptr_t arg) +{ + struct fastrpc_invoke_args32 *args32 = NULL; + struct fastrpc_invoke_args *args = NULL; + struct fastrpc_invoke32 inv32; + struct fastrpc_invoke inv; + int i, ret, nscalars; + + if (copy_from_user(&inv32, compat_ptr(arg), sizeof(inv32))) + return -EFAULT; + + inv.handle = inv32.handle; + inv.sc = inv32.sc; + inv.args = NULL; + nscalars = REMOTE_SCALARS_LENGTH(inv.sc); + + if (nscalars) { + args32 = kcalloc(nscalars, sizeof(*args32), GFP_KERNEL); + if (!args32) + return -ENOMEM; + + if (copy_from_user(args32, compat_ptr(inv32.args), + nscalars * sizeof(*args32))) + return -EFAULT; + + args = kcalloc(nscalars, sizeof(*args), GFP_KERNEL); + if (!args) + return -ENOMEM; + + for (i = 0; i < nscalars; i++) { + args[i].length = args32[i].length; + args[i].ptr = (void *)(unsigned long)args32[i].ptr; + args[i].fd = args32[i].fd; + } + inv.args = &args[0]; + } + + ret = fastrpc_internal_invoke(fl, 0, &inv); + kfree(args32); + kfree(args); + + return ret; +} +#endif + static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1103,6 +1166,11 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, case FASTRPC_IOCTL_INVOKE: err = fastrpc_invoke(fl, argp); break; +#ifdef CONFIG_COMPAT + case FASTRPC_IOCTL_INVOKE32: + err = fastrpc_invoke32(fl, ptr_to_compat(argp)); + break; +#endif case FASTRPC_IOCTL_INIT_ATTACH: err = fastrpc_init_attach(fl); break; @@ -1131,6 +1199,9 @@ static const struct file_operations fastrpc_fops = { .open = fastrpc_device_open, .release = fastrpc_device_release, .unlocked_ioctl = fastrpc_device_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = fastrpc_device_ioctl, +#endif }; static int fastrpc_cb_probe(struct platform_device *pdev)