From: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
To: "Oded Gabbay" <ogabbay@kernel.org>,
"Jonathan Corbet" <corbet@lwn.net>,
"Shuah Khan" <skhan@linuxfoundation.org>,
"Randy Dunlap" <rdunlap@infradead.org>,
"Ekansh Gupta" <ekansh.gupta@oss.qualcomm.com>,
"Srinivas Kandagatla" <srini@kernel.org>,
"Arnd Bergmann" <arnd@arndb.de>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"Sumit Semwal" <sumit.semwal@linaro.org>,
"Christian König" <christian.koenig@amd.com>,
"Philipp Stanner" <phasta@kernel.org>,
dmitry.baryshkov@oss.qualcomm.com, andersson@kernel.org,
krzk@kernel.org, rob.clark@oss.qualcomm.com, jgg@ziepe.ca
Cc: lingtong@qti.qualcomm.com, cacar@qti.qualcomm.com,
sandheep@qti.qualcomm.com,
Bharath Kumar <bkumar@qti.qualcomm.com>,
Chenna Kesava Raju <chennak@qti.qualcomm.com>,
dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org,
Bharath Kumar <quic_bkumar@quicinc.com>,
Chenna Kesava Raju <quic_chennak@quicinc.com>,
Ekansh Gupta <ekangupt@qti.qualcomm.com>
Subject: [PATCH v4 09/25] accel/qda: Add legacy FastRPC shim skeleton
Date: Mon, 02 Nov 2026 03:51:22 +0530 [thread overview]
Message-ID: <20261102-v4-v4-9-88f2f24a5f0b@qti.qualcomm.com> (raw)
In-Reply-To: <20261102-v4-v4-0-88f2f24a5f0b@qti.qualcomm.com>
Existing FastRPC user space talks to /dev/fastrpc-<dsp> through the ioctl
interface of the driver in drivers/misc/. Add a separate module that
serves that interface on top of this driver, so such user space keeps
working while it moves to the accel UAPI. It is separate so that the
driver itself does not depend on it, and so it can be left out.
The module binds the auxiliary device the driver creates per DSP domain
and gives that domain its misc node(s). As in the driver it replaces, a
channel is secure unless its DT node has qcom,non-secure-domain. ADSP,
MDSP and SDSP get a single node, secure or not according to the channel.
CDSP and GDSP support unsigned PD offload, so they always get both a
secure and a non-secure node, letting untrusted applications use the
latter on a secure channel. Nothing distinguishes the two nodes yet;
that is applied to the operations that need it as they are added.
Each open file gets a session from the driver, which also pins the DRM
device for as long as the file stays open.
Only FASTRPC_IOCTL_ALLOC_DMA_BUFF is implemented here: it allocates a
buffer and returns it as a DMA-BUF fd. FASTRPC_IOCTL_FREE_DMA_BUFF
returns -ENOTTY, as in the driver this replaces; buffers are released by
closing the fd. The fd is installed only once nothing else can fail.
Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
---
drivers/accel/qda/Kconfig | 16 +++
drivers/accel/qda/Makefile | 2 +
drivers/accel/qda/qda_fastrpc_shim.c | 268 +++++++++++++++++++++++++++++++++++
3 files changed, 286 insertions(+)
diff --git a/drivers/accel/qda/Kconfig b/drivers/accel/qda/Kconfig
index c174f9edf2d5..c440191a54ff 100644
--- a/drivers/accel/qda/Kconfig
+++ b/drivers/accel/qda/Kconfig
@@ -26,3 +26,19 @@ config DRM_ACCEL_QDA
To compile this driver as a module, choose M here: the
module will be called qda.
+
+config DRM_ACCEL_QDA_FASTRPC_SHIM
+ tristate "Qualcomm DSP accelerator legacy FastRPC compatibility shim"
+ depends on DRM_ACCEL_QDA
+ default DRM_ACCEL_QDA
+ help
+ Exposes a /dev/fastrpc-<dsp> character device per DSP domain, serving
+ the ioctl interface of the FastRPC driver in drivers/misc/ on top of
+ the QDA driver, so that existing FastRPC user space keeps working.
+
+ This is a compatibility layer for user space that has not moved to
+ the native interface in include/uapi/drm/qda_accel.h; new users
+ should use that instead.
+
+ To compile this driver as a module, choose M here: the
+ module will be called qda_fastrpc_shim.
diff --git a/drivers/accel/qda/Makefile b/drivers/accel/qda/Makefile
index a867a888c5f5..0996e4ed5798 100644
--- a/drivers/accel/qda/Makefile
+++ b/drivers/accel/qda/Makefile
@@ -16,3 +16,5 @@ qda-y := \
qda_prime.o \
qda_rpmsg.o \
qda_soc.o
+
+obj-$(CONFIG_DRM_ACCEL_QDA_FASTRPC_SHIM) += qda_fastrpc_shim.o
diff --git a/drivers/accel/qda/qda_fastrpc_shim.c b/drivers/accel/qda/qda_fastrpc_shim.c
new file mode 100644
index 000000000000..25f5c242efde
--- /dev/null
+++ b/drivers/accel/qda/qda_fastrpc_shim.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+#include <linux/array_size.h>
+#include <linux/auxiliary_bus.h>
+#include <linux/dma-buf.h>
+#include <linux/err.h>
+#include <linux/fcntl.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/limits.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <drm/drm_drv.h>
+#include <uapi/misc/fastrpc.h>
+#include "qda_drv.h"
+#include "qda_legacy_ops.h"
+
+/* State of one open /dev/fastrpc-* file */
+struct qda_shim_file {
+ struct qda_session *session;
+};
+
+/* One misc device node */
+struct qda_shim_node {
+ struct qda_shim_dev *sdev;
+ struct miscdevice miscdev;
+ char *name;
+ bool registered;
+};
+
+/*
+ * One per DSP domain, holding up to two misc nodes. As in
+ * drivers/misc/fastrpc.c, a channel is secure unless its DT node has
+ * qcom,non-secure-domain. ADSP, MDSP and SDSP get a single node, secure or
+ * not according to the channel. CDSP and GDSP, which support unsigned PD
+ * offload, always get both, so that untrusted applications can still reach
+ * the non-secure node on a secure channel.
+ *
+ * The two nodes behave identically for now; what separates them is applied
+ * to the operations that need it as those are added.
+ */
+struct qda_shim_dev {
+ struct qda_dev *qdev;
+ struct qda_shim_node nodes[2];
+};
+
+static const struct file_operations qda_shim_fops;
+
+static int qda_shim_open(struct inode *inode, struct file *file)
+{
+ struct qda_shim_node *snode = container_of(file->private_data, struct qda_shim_node,
+ miscdev);
+ struct qda_shim_file *sf;
+
+ sf = kzalloc_obj(*sf);
+ if (!sf)
+ return -ENOMEM;
+
+ sf->session = qda_legacy_ops_table.session_create(snode->sdev->qdev);
+ if (IS_ERR(sf->session)) {
+ int err = PTR_ERR(sf->session);
+
+ kfree(sf);
+ return err;
+ }
+
+ file->private_data = sf;
+
+ return 0;
+}
+
+static int qda_shim_release(struct inode *inode, struct file *file)
+{
+ struct qda_shim_file *sf = file->private_data;
+
+ qda_legacy_ops_table.session_destroy(sf->session);
+ kfree(sf);
+
+ return 0;
+}
+
+static long qda_shim_alloc_dma_buf(struct qda_shim_file *sf, void __user *argp)
+{
+ struct fastrpc_alloc_dma_buf args;
+ struct dma_buf *dmabuf;
+ int fd;
+
+ if (copy_from_user(&args, argp, sizeof(args)))
+ return -EFAULT;
+
+ /* The size is 64 bits wide on the wire but a size_t further down */
+ if (args.size > SIZE_MAX)
+ return -EINVAL;
+
+ /* args.flags is not used, as in drivers/misc/fastrpc.c */
+ dmabuf = qda_legacy_ops_table.alloc_dmabuf(sf->session, args.size);
+ if (IS_ERR(dmabuf))
+ return PTR_ERR(dmabuf);
+
+ fd = get_unused_fd_flags(O_CLOEXEC);
+ if (fd < 0) {
+ dma_buf_put(dmabuf);
+ return fd;
+ }
+
+ args.fd = fd;
+ if (copy_to_user(argp, &args, sizeof(args))) {
+ put_unused_fd(fd);
+ dma_buf_put(dmabuf);
+ return -EFAULT;
+ }
+
+ /* Publish the fd only once nothing can fail */
+ fd_install(fd, dmabuf->file);
+
+ return 0;
+}
+
+static long qda_shim_dispatch(struct qda_shim_file *sf, unsigned int cmd, void __user *argp)
+{
+ switch (cmd) {
+ case FASTRPC_IOCTL_ALLOC_DMA_BUFF:
+ return qda_shim_alloc_dma_buf(sf, argp);
+ default:
+ /*
+ * Includes FASTRPC_IOCTL_FREE_DMA_BUFF, which the driver this
+ * replaces never implemented either: buffers are released by
+ * closing their fd.
+ */
+ return -ENOTTY;
+ }
+}
+
+/*
+ * Mirrors drm_ioctl()'s unplug check. Not drm_dev_enter(): holding the SRCU
+ * read side across a wait for the DSP's reply would stall drm_dev_unplug()
+ * in qda_rpmsg_remove() for as long as the DSP takes to answer.
+ */
+static long qda_shim_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct qda_shim_file *sf = file->private_data;
+
+ if (drm_dev_is_unplugged(&sf->session->qda_dev->drm_dev))
+ return -ENODEV;
+
+ return qda_shim_dispatch(sf, cmd, (void __user *)arg);
+}
+
+static const struct file_operations qda_shim_fops = {
+ .owner = THIS_MODULE,
+ .open = qda_shim_open,
+ .release = qda_shim_release,
+ .unlocked_ioctl = qda_shim_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
+};
+
+static int qda_shim_node_register(struct qda_shim_dev *sdev, int i, bool secure)
+{
+ struct qda_shim_node *snode = &sdev->nodes[i];
+ int err;
+
+ snode->name = kasprintf(GFP_KERNEL, "fastrpc-%s%s", sdev->qdev->dsp_name,
+ secure ? "-secure" : "");
+ if (!snode->name)
+ return -ENOMEM;
+
+ snode->sdev = sdev;
+ snode->miscdev.minor = MISC_DYNAMIC_MINOR;
+ snode->miscdev.name = snode->name;
+ snode->miscdev.fops = &qda_shim_fops;
+
+ err = misc_register(&snode->miscdev);
+ if (err) {
+ kfree(snode->name);
+ snode->name = NULL;
+ return err;
+ }
+
+ snode->registered = true;
+
+ return 0;
+}
+
+/*
+ * misc_deregister() takes misc_mtx, which misc_open() holds across the
+ * lookup and our ->open(). So once it returns no open can still be using
+ * the node. Files that are already open hold neither the node nor @sdev,
+ * only their session.
+ */
+static void qda_shim_nodes_unregister(struct qda_shim_dev *sdev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sdev->nodes); i++) {
+ if (sdev->nodes[i].registered)
+ misc_deregister(&sdev->nodes[i].miscdev);
+ kfree(sdev->nodes[i].name);
+ }
+}
+
+static int qda_shim_probe(struct auxiliary_device *auxdev,
+ const struct auxiliary_device_id *id)
+{
+ struct qda_dev *qdev = dev_get_platdata(&auxdev->dev);
+ bool secure_channel = !of_property_read_bool(qdev->dev->of_node,
+ "qcom,non-secure-domain");
+ struct qda_shim_dev *sdev;
+ int err;
+
+ sdev = devm_kzalloc(&auxdev->dev, sizeof(*sdev), GFP_KERNEL);
+ if (!sdev)
+ return -ENOMEM;
+
+ sdev->qdev = qdev;
+
+ if (!strncmp(qdev->dsp_name, "cdsp", 4) || !strncmp(qdev->dsp_name, "gdsp", 4)) {
+ /* Both nodes, so signed and unsigned PDs are both reachable */
+ err = qda_shim_node_register(sdev, 0, true);
+ if (!err)
+ err = qda_shim_node_register(sdev, 1, false);
+ } else if (!strncmp(qdev->dsp_name, "adsp", 4) ||
+ !strncmp(qdev->dsp_name, "mdsp", 4) ||
+ !strncmp(qdev->dsp_name, "sdsp", 4)) {
+ err = qda_shim_node_register(sdev, 0, secure_channel);
+ } else {
+ err = -ENODEV;
+ }
+
+ if (err) {
+ dev_err(&auxdev->dev, "Failed to create %s node(s): %d\n",
+ qdev->dsp_name, err);
+ qda_shim_nodes_unregister(sdev);
+ return err;
+ }
+
+ auxiliary_set_drvdata(auxdev, sdev);
+
+ return 0;
+}
+
+static void qda_shim_remove(struct auxiliary_device *auxdev)
+{
+ qda_shim_nodes_unregister(auxiliary_get_drvdata(auxdev));
+}
+
+static const struct auxiliary_device_id qda_shim_id_table[] = {
+ { .name = QDA_DRIVER_NAME "." QDA_LEGACY_AUXDEV_NAME },
+ {},
+};
+MODULE_DEVICE_TABLE(auxiliary, qda_shim_id_table);
+
+static struct auxiliary_driver qda_shim_driver = {
+ .name = "fastrpc_shim",
+ .id_table = qda_shim_id_table,
+ .probe = qda_shim_probe,
+ .remove = qda_shim_remove,
+};
+
+module_auxiliary_driver(qda_shim_driver);
+
+MODULE_IMPORT_NS("DMA_BUF");
+MODULE_AUTHOR("Qualcomm AI Infra Team");
+MODULE_DESCRIPTION("Qualcomm DSP accelerator legacy FastRPC compatibility shim");
+MODULE_LICENSE("GPL");
--
2.34.1
next prev parent reply other threads:[~2026-11-01 22:23 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 22:21 [PATCH v4 00/25] accel/qda: Qualcomm DSP Accelerator driver Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 01/25] accel/qda: Add QDA driver documentation Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 02/25] accel/qda: Add initial QDA DRM accelerator driver Ekansh Gupta
2026-11-02 8:42 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 03/25] accel/qda: Add compute context bank devices Ekansh Gupta
2026-11-02 8:43 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 04/25] accel/qda: Assign a context bank to each session Ekansh Gupta
2026-11-02 8:45 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 05/25] accel/qda: Add UAPI header and DSP query ioctl Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 06/25] accel/qda: Add buffer allocation for the DSP Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 07/25] accel/qda: Add DMA-BUF import Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 08/25] accel/qda: Add legacy ops base and auxiliary device Ekansh Gupta
2026-11-01 22:21 ` Ekansh Gupta [this message]
2026-11-01 22:21 ` [PATCH v4 10/25] accel/qda: Add FastRPC invocation contexts Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 11/25] accel/qda: Add RPMsg send and response dispatch Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 12/25] accel/qda: Add invocation argument validation and packing Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 13/25] accel/qda: Add the invocation ioctl and teardown on unplug Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 14/25] accel/qda: Add invocation through the legacy FastRPC shim Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 15/25] accel/qda: Add DSP process creation and release Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 16/25] accel/qda: Add DSP process creation and release to the legacy shim Ekansh Gupta
2026-11-02 8:47 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 17/25] accel/qda: Add remote memory mapping to the DSP address space Ekansh Gupta
2026-11-02 9:24 ` Konrad Dybcio
2026-11-01 22:21 ` [PATCH v4 18/25] accel/qda: Add remote memory unmapping from " Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 19/25] accel/qda: Add remote memory map and unmap to the legacy shim Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 20/25] accel/qda: Add remote attach to root and sensors protection domains Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 21/25] accel/qda: Add Audio protection domain attach and its remote heap Ekansh Gupta
2026-11-02 8:43 ` Arnd Bergmann
2026-11-02 8:50 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 22/25] accel/qda: Add remote session attach to the legacy shim Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 23/25] accel/qda: Add DSP capability query Ekansh Gupta
2026-11-02 8:46 ` Arnd Bergmann
2026-11-01 22:21 ` [PATCH v4 24/25] accel/qda: Add legacy shim support for " Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 25/25] accel/qda: Add poll mode for invocation completion Ekansh Gupta
2026-11-02 8:53 ` [PATCH v4 00/25] accel/qda: Qualcomm DSP Accelerator driver Krzysztof Kozlowski
2026-11-02 10:08 ` Ekansh Gupta
2026-11-02 10:12 ` Krzysztof Kozlowski
2026-11-02 10:52 ` Ekansh Gupta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261102-v4-v4-9-88f2f24a5f0b@qti.qualcomm.com \
--to=ekansh.gupta@oss.qualcomm.com \
--cc=airlied@gmail.com \
--cc=andersson@kernel.org \
--cc=arnd@arndb.de \
--cc=bkumar@qti.qualcomm.com \
--cc=cacar@qti.qualcomm.com \
--cc=chennak@qti.qualcomm.com \
--cc=christian.koenig@amd.com \
--cc=corbet@lwn.net \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=ekangupt@qti.qualcomm.com \
--cc=gregkh@linuxfoundation.org \
--cc=jgg@ziepe.ca \
--cc=krzk@kernel.org \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=lingtong@qti.qualcomm.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=ogabbay@kernel.org \
--cc=phasta@kernel.org \
--cc=quic_bkumar@quicinc.com \
--cc=quic_chennak@quicinc.com \
--cc=rdunlap@infradead.org \
--cc=rob.clark@oss.qualcomm.com \
--cc=sandheep@qti.qualcomm.com \
--cc=simona@ffwll.ch \
--cc=skhan@linuxfoundation.org \
--cc=srini@kernel.org \
--cc=sumit.semwal@linaro.org \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®