From: Vinayak Katoch <vinayak.katoch@oss.qualcomm.com>
To: Srinivas Kandagatla <srini@kernel.org>,
Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Bharath Kumar <bkumar@qti.qualcomm.com>,
Chenna Kesava Raju <chennak@qti.qualcomm.com>,
linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
Vinayak Katoch <vinayak.katoch@oss.qualcomm.com>
Subject: [PATCH v2 4/4] misc: fastrpc: add UAPI flags for extended IOVA mapping
Date: Wed, 07 Oct 2026 17:07:51 +0530 [thread overview]
Message-ID: <20261007-extended-mapping-v2-4-5dca3aa2c2d3@oss.qualcomm.com> (raw)
In-Reply-To: <20261007-extended-mapping-v2-0-5dca3aa2c2d3@oss.qualcomm.com>
Userspace has no way to request that a buffer be mapped through the
extended context bank, so large buffers cannot be placed in the wider
IOVA window even when one is available.
Add two UAPI flags:
FASTRPC_MAP_FD_EXTENDED - map immediately via the extended CB
FASTRPC_MAP_FD_DELAYED_EXTENDED - map on demand via the extended CB
When either flag is set, fastrpc_map_attach() iterates cctx->ext_cb[]
and retries on -ENOMEM, falling over to the next extended CB when one
exhausts its IOVA space. The SID offset passed to the DSP must reflect
the actual CB used, so fastrpc_compute_dma_addr() takes an explicit
session rather than always using fl->sctx — without this the DSP would
fault on access.
Store the mapping flags in struct fastrpc_map. fastrpc_map_create()
validates the cached entry's flags against the request; a mismatched
entry is dropped and a fresh attachment is made to the correct CB type,
preventing a cached regular-CB map from being returned for an
extended-CB request.
All existing call sites pass flags=0 and are unaffected.
Signed-off-by: Vinayak Katoch <vinayak.katoch@oss.qualcomm.com>
---
drivers/misc/fastrpc.c | 83 ++++++++++++++++++++++++++++++++++-----------
include/uapi/misc/fastrpc.h | 7 ++++
2 files changed, 71 insertions(+), 19 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index d40cdcd5dec3..4ba07a5b28bb 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -81,6 +81,11 @@
#define FASTRPC_MAX_DSP_ATTRIBUTES (256)
#define FASTRPC_MAX_DSP_ATTRIBUTES_LEN (sizeof(u32) * FASTRPC_MAX_DSP_ATTRIBUTES)
+/* Check if the given flag is used for extended UDMA mapping */
+#define IS_EXTENDED_MAP_FLAG(flag) \
+ ((flag) == FASTRPC_MAP_FD_EXTENDED || \
+ (flag) == FASTRPC_MAP_FD_DELAYED_EXTENDED)
+
/* Retrives number of input buffers from the scalars parameter */
#define REMOTE_SCALARS_INBUFS(sc) (((sc) >> 16) & 0x0ff)
@@ -252,6 +257,7 @@ struct fastrpc_map {
u64 len;
u64 raddr;
u32 attr;
+ u32 flags;
struct kref refcount;
};
@@ -398,7 +404,7 @@ static void fastrpc_free_map(struct kref *ref)
err = qcom_scm_assign_mem(map->dma_addr, map->len,
&src_perms, &perm, 1);
if (err) {
- dev_err(map->fl->sctx->dev,
+ dev_err(map->attach->dev,
"Failed to assign memory dma_addr %pad size 0x%llx err %d\n",
&map->dma_addr, map->len, err);
return;
@@ -882,16 +888,19 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = {
.release = fastrpc_release,
};
-static dma_addr_t fastrpc_compute_dma_addr(struct fastrpc_user *fl, dma_addr_t sg_dma_addr)
+static dma_addr_t fastrpc_compute_dma_addr(struct fastrpc_user *fl, dma_addr_t sg_dma_addr,
+ struct fastrpc_session_ctx *sess)
{
- return sg_dma_addr + fastrpc_sid_offset(fl->cctx, fl->sctx);
+ return sg_dma_addr + fastrpc_sid_offset(fl->cctx, sess);
}
-static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
- u64 len, u32 attr, struct fastrpc_map **ppmap)
+static int fastrpc_map_attach_to_dev(struct fastrpc_user *fl, int fd,
+ u64 len, u32 attr, u32 flags,
+ struct fastrpc_session_ctx *sess,
+ struct fastrpc_map **ppmap)
{
- struct fastrpc_session_ctx *sess = fl->sctx;
struct fastrpc_map *map = NULL;
+ struct device *dev = sess->dev;
struct sg_table *table;
struct scatterlist *sgl = NULL;
int err = 0, sgl_index = 0;
@@ -911,9 +920,9 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
goto get_err;
}
- map->attach = dma_buf_attach(map->buf, sess->dev);
+ map->attach = dma_buf_attach(map->buf, dev);
if (IS_ERR(map->attach)) {
- dev_err(sess->dev, "Failed to attach dmabuf\n");
+ dev_err(dev, "Failed to attach dmabuf\n");
err = PTR_ERR(map->attach);
goto attach_err;
}
@@ -928,18 +937,20 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
if (attr & FASTRPC_ATTR_SECUREMAP)
map->dma_addr = sg_phys(map->table->sgl);
else
- map->dma_addr = fastrpc_compute_dma_addr(fl, sg_dma_address(map->table->sgl));
+ map->dma_addr = fastrpc_compute_dma_addr(fl, sg_dma_address(map->table->sgl), sess);
for_each_sg(map->table->sgl, sgl, map->table->nents,
sgl_index)
map->size += sg_dma_len(sgl);
+
if (len > map->size) {
- dev_dbg(sess->dev, "Bad size passed len 0x%llx map size 0x%llx\n",
+ dev_dbg(dev, "Bad size passed len 0x%llx map size 0x%llx\n",
len, map->size);
err = -EINVAL;
goto get_err;
}
map->va = sg_virt(map->table->sgl);
map->len = len;
+ map->flags = flags;
if (attr & FASTRPC_ATTR_SECUREMAP) {
/*
@@ -956,7 +967,7 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
map->attr = attr;
err = qcom_scm_assign_mem(map->dma_addr, (u64)map->len, &src_perms, dst_perms, 2);
if (err) {
- dev_err(sess->dev,
+ dev_err(dev,
"Failed to assign memory with dma_addr %pad size 0x%llx err %d\n",
&map->dma_addr, map->len, err);
goto get_err;
@@ -979,13 +990,47 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
return err;
}
+static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
+ u64 len, u32 attr, u32 flags, struct fastrpc_map **ppmap)
+{
+ if (IS_EXTENDED_MAP_FLAG(flags)) {
+ struct fastrpc_session_ctx **ext_cb;
+ int i, count, err = -ENODEV;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&fl->cctx->lock, lock_flags);
+ count = fl->cctx->ext_cb_count;
+ ext_cb = fl->cctx->ext_cb;
+ spin_unlock_irqrestore(&fl->cctx->lock, lock_flags);
+
+ if (!count) {
+ dev_err(fl->sctx->dev, "no extended context bank found\n");
+ return -ENODEV;
+ }
+
+ for (i = 0; i < count; i++) {
+ err = fastrpc_map_attach_to_dev(fl, fd, len, attr, flags,
+ ext_cb[i], ppmap);
+ if (err != -ENOMEM)
+ break;
+ }
+ return err;
+ }
+
+ return fastrpc_map_attach_to_dev(fl, fd, len, attr, flags, fl->sctx, ppmap);
+}
+
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
- u64 len, u32 attr, struct fastrpc_map **ppmap)
+ u64 len, u32 attr, u32 flags, struct fastrpc_map **ppmap)
{
- if (!fastrpc_map_lookup(fl, fd, ppmap, true))
- return 0;
+ if (!fastrpc_map_lookup(fl, fd, ppmap, true)) {
+ if ((*ppmap)->flags == flags)
+ return 0;
+ fastrpc_map_put(*ppmap);
+ *ppmap = NULL;
+ }
- return fastrpc_map_attach(fl, fd, len, attr, ppmap);
+ return fastrpc_map_attach(fl, fd, len, attr, flags, ppmap);
}
/*
@@ -1063,10 +1108,10 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
if (i < ctx->nbufs)
err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
- ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
+ ctx->args[i].length, ctx->args[i].attr, 0, &ctx->maps[i]);
else
err = fastrpc_map_attach(ctx->fl, ctx->args[i].fd,
- ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
+ ctx->args[i].length, ctx->args[i].attr, 0, &ctx->maps[i]);
if (err) {
dev_err(dev, "Error Creating map %d\n", err);
return -EINVAL;
@@ -1615,7 +1660,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl,
fl->pd = USER_PD;
if (init.filelen && init.filefd) {
- err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map);
+ err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, 0, &map);
if (err)
goto err;
}
@@ -2221,7 +2266,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
return -EFAULT;
/* create SMMU mapping */
- err = fastrpc_map_create(fl, req.fd, req.length, 0, &map);
+ err = fastrpc_map_create(fl, req.fd, req.length, 0, req.flags, &map);
if (err) {
dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
return err;
diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h
index ba1ea5ed426c..b39c0e197a45 100644
--- a/include/uapi/misc/fastrpc.h
+++ b/include/uapi/misc/fastrpc.h
@@ -36,6 +36,11 @@
* cache maintenance for the buffer.
* @FASTRPC_MAP_FD_NOMAP: This flag is used to skip CPU mapping,
* otherwise behaves similar to FASTRPC_MAP_FD_DELAYED flag.
+ * @FASTRPC_MAP_FD_EXTENDED: Map buffer in extended SMMU IOVA space (16GB - 1TB)
+ * and DSP VA space (4GB - 512GB). Can be accessed only through uDMA.
+ * @FASTRPC_MAP_FD_DELAYED_EXTENDED: Map buffer in extended SMMU IOVA space
+ * (16GB - 1TB) but skip DSP mapping. DSP mapping will be done later by
+ * the user. Can be accessed only through uDMA.
* @FASTRPC_MAP_MAX: max count for flags
*
*/
@@ -45,6 +50,8 @@ enum fastrpc_map_flags {
FASTRPC_MAP_FD = 2,
FASTRPC_MAP_FD_DELAYED,
FASTRPC_MAP_FD_NOMAP = 16,
+ FASTRPC_MAP_FD_EXTENDED,
+ FASTRPC_MAP_FD_DELAYED_EXTENDED,
FASTRPC_MAP_MAX,
};
--
2.34.1
next prev parent reply other threads:[~2026-10-07 11:38 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-07 11:37 [PATCH v2 0/4] misc: fastrpc: add extended IOVA mapping support Vinayak Katoch
2026-10-07 11:37 ` [PATCH v2 1/4] dt-bindings: misc: qcom,fastrpc: add iommu-ranges support for context bank Vinayak Katoch
2026-10-07 11:47 ` sashiko-bot
2026-10-09 9:56 ` [PATCH v2 1/4] dt-bindings: misc: qcom, fastrpc: " Krzysztof Kozlowski
2026-10-09 9:56 ` [PATCH v2 1/4] dt-bindings: misc: qcom,fastrpc: " Krzysztof Kozlowski
2026-10-07 11:37 ` [PATCH v2 2/4] misc: fastrpc: handle multi-cell reg in context bank probe Vinayak Katoch
2026-10-07 11:50 ` sashiko-bot
2026-10-07 11:37 ` [PATCH v2 3/4] misc: fastrpc: add extended context bank support Vinayak Katoch
2026-10-07 11:52 ` sashiko-bot
2026-10-07 11:37 ` Vinayak Katoch [this message]
2026-10-07 11:49 ` [PATCH v2 4/4] misc: fastrpc: add UAPI flags for extended IOVA mapping sashiko-bot
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=20261007-extended-mapping-v2-4-5dca3aa2c2d3@oss.qualcomm.com \
--to=vinayak.katoch@oss.qualcomm.com \
--cc=arnd@arndb.de \
--cc=bkumar@qti.qualcomm.com \
--cc=chennak@qti.qualcomm.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=ekansh.gupta@oss.qualcomm.com \
--cc=gregkh@linuxfoundation.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robh@kernel.org \
--cc=srini@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.