[PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers

Ekansh Gupta posted 3 patches 1 month, 1 week ago
[PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers
Posted by Ekansh Gupta 1 month, 1 week ago
Currently, FastRPC only supports mapping buffers allocated by the
kernel. This limits flexibility for applications that allocate memory
in userspace using rpcmem or DMABUF and need to share it with the DSP.
Add support for mapping and unmapping userspace-allocated buffers to
the DSP through SMMU. This includes handling map requests for rpcmem
and DMABUF-backed memory and providing corresponding unmap
functionality.

Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
---
 drivers/misc/fastrpc.c | 97 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 86 insertions(+), 11 deletions(-)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 24064efe5dd8..b677e485bade 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1854,8 +1854,10 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *
 static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
 {
 	struct fastrpc_buf *buf = NULL, *iter, *b;
+	struct fastrpc_map *map = NULL, *iterm, *m;
 	struct fastrpc_req_munmap req;
 	struct device *dev = fl->sctx->dev;
+	int err;
 
 	if (copy_from_user(&req, argp, sizeof(req)))
 		return -EFAULT;
@@ -1869,13 +1871,42 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
 	}
 	spin_unlock(&fl->lock);
 
-	if (!buf) {
-		dev_err(dev, "buffer not found: addr=%p [len=0x%08llx]\n",
+	if (buf) {
+		err = fastrpc_req_munmap_impl(fl, buf);
+		if (err) {
+			spin_lock(&fl->lock);
+			list_add_tail(&buf->node, &fl->mmaps);
+			spin_unlock(&fl->lock);
+		}
+		return err;
+	}
+
+	spin_lock(&fl->lock);
+	list_for_each_entry_safe(iterm, m, &fl->maps, node) {
+		if (iterm->raddr == req.vaddrout) {
+			map = iterm;
+			list_del(&iterm->node);
+			break;
+		}
+	}
+	spin_unlock(&fl->lock);
+	if (!map) {
+		dev_dbg(dev, "buffer/map not found addr=%p len=0x%08llx\n",
 			(void *)(unsigned long)req.vaddrout, req.size);
 		return -EINVAL;
 	}
 
-	return fastrpc_req_munmap_impl(fl, buf);
+	err = fastrpc_req_munmap_dsp(fl, map->raddr, map->size);
+	if (err) {
+		dev_dbg(dev, "unmap error: fd=%d, raddr=%p\n",
+			map->fd, (void *)(unsigned long)map->raddr);
+		spin_lock(&fl->lock);
+		list_add_tail(&map->node, &fl->maps);
+		spin_unlock(&fl->lock);
+	} else {
+		fastrpc_map_put(map);
+	}
+	return err;
 }
 
 static int fastrpc_req_map_dsp(struct fastrpc_user *fl, u64 phys,
@@ -1989,25 +2020,69 @@ static int fastrpc_req_buf_alloc(struct fastrpc_user *fl,
 	return err;
 }
 
-static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
+static int fastrpc_req_map_create(struct fastrpc_user *fl,
+				  struct fastrpc_req_mmap req,
+				  char __user *argp)
 {
-	struct fastrpc_req_mmap req;
+	struct fastrpc_map *map = NULL;
+	struct device *dev = fl->sctx->dev;
+	u64 raddr = 0;
 	int err;
 
-	if (copy_from_user(&req, argp, sizeof(req)))
-		return -EFAULT;
+	err = fastrpc_map_create(fl, req.fd, req.size, 0, &map);
+	if (err) {
+		dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
+		return err;
+	}
+
+	err = fastrpc_req_map_dsp(fl, map->phys, map->size, req.flags,
+				  req.vaddrin, &raddr);
+	if (err)
+		goto err_invoke;
 
-	if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) {
-		dev_err(fl->sctx->dev, "flag not supported 0x%x\n", req.flags);
+	/* update the buffer to be able to deallocate the memory on the DSP */
+	map->raddr = (u64)raddr;
 
-		return -EINVAL;
+	/* let the client know the address to use */
+	req.vaddrout = raddr;
+	dev_dbg(dev, "mmap OK: raddr=%p [len=0x%08llx]\n",
+		(void *)(unsigned long)map->raddr, map->size);
+
+	if (copy_to_user(argp, &req, sizeof(req))) {
+		err = -EFAULT;
+		goto err_copy;
 	}
 
-	err = fastrpc_req_buf_alloc(fl, req, argp);
+	return 0;
+err_copy:
+	fastrpc_req_munmap_dsp(fl, map->raddr, map->size);
+err_invoke:
+	fastrpc_map_put(map);
 
 	return err;
 }
 
+static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
+{
+	struct fastrpc_req_mmap req;
+	int err;
+
+	if (copy_from_user(&req, argp, sizeof(req)))
+		return -EFAULT;
+
+	if ((req.flags == ADSP_MMAP_ADD_PAGES ||
+	     req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) {
+		err = fastrpc_req_buf_alloc(fl, req, argp);
+		if (err)
+			return err;
+	} else {
+		err = fastrpc_req_map_create(fl, req, argp);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
 static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_mem_unmap *req)
 {
 	struct fastrpc_invoke_args args[1] = { [0] = { 0 } };
-- 
2.34.1
Re: [PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers
Posted by Dmitry Baryshkov 1 month ago
On Tue, Dec 30, 2025 at 04:32:25PM +0530, Ekansh Gupta wrote:
> Currently, FastRPC only supports mapping buffers allocated by the
> kernel. This limits flexibility for applications that allocate memory
> in userspace using rpcmem or DMABUF and need to share it with the DSP.

Hmm, for DMABUF we need _import_ support rather than support for mapping
of userspace-allocated buffers.

> Add support for mapping and unmapping userspace-allocated buffers to
> the DSP through SMMU. This includes handling map requests for rpcmem
> and DMABUF-backed memory and providing corresponding unmap
> functionality.

For me this definitely looks like a step back. For drm/accel we are
going to have GEM-managed buffers only. Why do we need to handle
userspace-allocated buffers here?

> 
> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
> ---
>  drivers/misc/fastrpc.c | 97 +++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 86 insertions(+), 11 deletions(-)
> 
> @@ -1989,25 +2020,69 @@ static int fastrpc_req_buf_alloc(struct fastrpc_user *fl,
>  	return err;
>  }
>  
> -static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
> +static int fastrpc_req_map_create(struct fastrpc_user *fl,
> +				  struct fastrpc_req_mmap req,
> +				  char __user *argp)
>  {
> -	struct fastrpc_req_mmap req;
> +	struct fastrpc_map *map = NULL;
> +	struct device *dev = fl->sctx->dev;
> +	u64 raddr = 0;
>  	int err;
>  
> -	if (copy_from_user(&req, argp, sizeof(req)))
> -		return -EFAULT;
> +	err = fastrpc_map_create(fl, req.fd, req.size, 0, &map);
> +	if (err) {
> +		dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
> +		return err;
> +	}
> +
> +	err = fastrpc_req_map_dsp(fl, map->phys, map->size, req.flags,
> +				  req.vaddrin, &raddr);
> +	if (err)
> +		goto err_invoke;
>  
> -	if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) {
> -		dev_err(fl->sctx->dev, "flag not supported 0x%x\n", req.flags);
> +	/* update the buffer to be able to deallocate the memory on the DSP */
> +	map->raddr = (u64)raddr;

Which type are you converting? And why?

>  
> -		return -EINVAL;
> +	/* let the client know the address to use */
> +	req.vaddrout = raddr;
> +	dev_dbg(dev, "mmap OK: raddr=%p [len=0x%08llx]\n",
> +		(void *)(unsigned long)map->raddr, map->size);
> +
> +	if (copy_to_user(argp, &req, sizeof(req))) {
> +		err = -EFAULT;
> +		goto err_copy;
>  	}
>  
> -	err = fastrpc_req_buf_alloc(fl, req, argp);
> +	return 0;
> +err_copy:
> +	fastrpc_req_munmap_dsp(fl, map->raddr, map->size);
> +err_invoke:
> +	fastrpc_map_put(map);
>  
>  	return err;
>  }
>  
> +static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
> +{
> +	struct fastrpc_req_mmap req;
> +	int err;
> +
> +	if (copy_from_user(&req, argp, sizeof(req)))
> +		return -EFAULT;
> +
> +	if ((req.flags == ADSP_MMAP_ADD_PAGES ||
> +	     req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) {

Side note: why are these flags not defined in the uABI header?

> +		err = fastrpc_req_buf_alloc(fl, req, argp);
> +		if (err)
> +			return err;

-- 
With best wishes
Dmitry
Re: [PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers
Posted by Ekansh Gupta 1 week, 4 days ago

On 1/6/2026 8:21 AM, Dmitry Baryshkov wrote:
> On Tue, Dec 30, 2025 at 04:32:25PM +0530, Ekansh Gupta wrote:
>> Currently, FastRPC only supports mapping buffers allocated by the
>> kernel. This limits flexibility for applications that allocate memory
>> in userspace using rpcmem or DMABUF and need to share it with the DSP.
> Hmm, for DMABUF we need _import_ support rather than support for mapping
> of userspace-allocated buffers.
>
>> Add support for mapping and unmapping userspace-allocated buffers to
>> the DSP through SMMU. This includes handling map requests for rpcmem
>> and DMABUF-backed memory and providing corresponding unmap
>> functionality.
> For me this definitely looks like a step back. For drm/accel we are
> going to have GEM-managed buffers only. Why do we need to handle
> userspace-allocated buffers here?
That's correct, GEM-PRIME will handle it properly. Here, the reason to add this
change is to enable routing of DSP logs to HLOS which is done by using a shared
buffer between userspace process and DSP PD. The buffer can be allocated from
both fastrpc driver's DMA-BUF or DMABUF heap(eg. system heap).

So this shared buffer is getting mapped to both process's IOMMU device and DSP PD
with this change.
>
>> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
>> ---
>>  drivers/misc/fastrpc.c | 97 +++++++++++++++++++++++++++++++++++++-----
>>  1 file changed, 86 insertions(+), 11 deletions(-)
>>
>> @@ -1989,25 +2020,69 @@ static int fastrpc_req_buf_alloc(struct fastrpc_user *fl,
>>  	return err;
>>  }
>>  
>> -static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
>> +static int fastrpc_req_map_create(struct fastrpc_user *fl,
>> +				  struct fastrpc_req_mmap req,
>> +				  char __user *argp)
>>  {
>> -	struct fastrpc_req_mmap req;
>> +	struct fastrpc_map *map = NULL;
>> +	struct device *dev = fl->sctx->dev;
>> +	u64 raddr = 0;
>>  	int err;
>>  
>> -	if (copy_from_user(&req, argp, sizeof(req)))
>> -		return -EFAULT;
>> +	err = fastrpc_map_create(fl, req.fd, req.size, 0, &map);
>> +	if (err) {
>> +		dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
>> +		return err;
>> +	}
>> +
>> +	err = fastrpc_req_map_dsp(fl, map->phys, map->size, req.flags,
>> +				  req.vaddrin, &raddr);
>> +	if (err)
>> +		goto err_invoke;
>>  
>> -	if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) {
>> -		dev_err(fl->sctx->dev, "flag not supported 0x%x\n", req.flags);
>> +	/* update the buffer to be able to deallocate the memory on the DSP */
>> +	map->raddr = (u64)raddr;
> Which type are you converting? And why?
I'll drop this.
>
>>  
>> -		return -EINVAL;
>> +	/* let the client know the address to use */
>> +	req.vaddrout = raddr;
>> +	dev_dbg(dev, "mmap OK: raddr=%p [len=0x%08llx]\n",
>> +		(void *)(unsigned long)map->raddr, map->size);
>> +
>> +	if (copy_to_user(argp, &req, sizeof(req))) {
>> +		err = -EFAULT;
>> +		goto err_copy;
>>  	}
>>  
>> -	err = fastrpc_req_buf_alloc(fl, req, argp);
>> +	return 0;
>> +err_copy:
>> +	fastrpc_req_munmap_dsp(fl, map->raddr, map->size);
>> +err_invoke:
>> +	fastrpc_map_put(map);
>>  
>>  	return err;
>>  }
>>  
>> +static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
>> +{
>> +	struct fastrpc_req_mmap req;
>> +	int err;
>> +
>> +	if (copy_from_user(&req, argp, sizeof(req)))
>> +		return -EFAULT;
>> +
>> +	if ((req.flags == ADSP_MMAP_ADD_PAGES ||
>> +	     req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) {
> Side note: why are these flags not defined in the uABI header?
Ack. These should be part of uABI. I'll create a separate patch for this.
>
>> +		err = fastrpc_req_buf_alloc(fl, req, argp);
>> +		if (err)
>> +			return err;
Re: [PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers
Posted by Dmitry Baryshkov 1 week, 3 days ago
On Thu, Jan 29, 2026 at 04:09:41PM +0530, Ekansh Gupta wrote:
> 
> 
> On 1/6/2026 8:21 AM, Dmitry Baryshkov wrote:
> > On Tue, Dec 30, 2025 at 04:32:25PM +0530, Ekansh Gupta wrote:
> >> Currently, FastRPC only supports mapping buffers allocated by the
> >> kernel. This limits flexibility for applications that allocate memory
> >> in userspace using rpcmem or DMABUF and need to share it with the DSP.
> > Hmm, for DMABUF we need _import_ support rather than support for mapping
> > of userspace-allocated buffers.
> >
> >> Add support for mapping and unmapping userspace-allocated buffers to
> >> the DSP through SMMU. This includes handling map requests for rpcmem
> >> and DMABUF-backed memory and providing corresponding unmap
> >> functionality.
> > For me this definitely looks like a step back. For drm/accel we are
> > going to have GEM-managed buffers only. Why do we need to handle
> > userspace-allocated buffers here?
> That's correct, GEM-PRIME will handle it properly. Here, the reason to add this
> change is to enable routing of DSP logs to HLOS which is done by using a shared
> buffer between userspace process and DSP PD. The buffer can be allocated from
> both fastrpc driver's DMA-BUF or DMABUF heap(eg. system heap).
> 
> So this shared buffer is getting mapped to both process's IOMMU device and DSP PD
> with this change.

So, you have the DMA-BUF buffer. Instead of mapping it from userspace
with unclean semantics, please import the buffer.

> >
> >> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
> >> ---
> >>  drivers/misc/fastrpc.c | 97 +++++++++++++++++++++++++++++++++++++-----
> >>  1 file changed, 86 insertions(+), 11 deletions(-)
> >>

-- 
With best wishes
Dmitry
Re: [PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers
Posted by Ekansh Gupta 1 week, 2 days ago

On 1/30/2026 7:59 AM, Dmitry Baryshkov wrote:
> On Thu, Jan 29, 2026 at 04:09:41PM +0530, Ekansh Gupta wrote:
>>
>> On 1/6/2026 8:21 AM, Dmitry Baryshkov wrote:
>>> On Tue, Dec 30, 2025 at 04:32:25PM +0530, Ekansh Gupta wrote:
>>>> Currently, FastRPC only supports mapping buffers allocated by the
>>>> kernel. This limits flexibility for applications that allocate memory
>>>> in userspace using rpcmem or DMABUF and need to share it with the DSP.
>>> Hmm, for DMABUF we need _import_ support rather than support for mapping
>>> of userspace-allocated buffers.
>>>
>>>> Add support for mapping and unmapping userspace-allocated buffers to
>>>> the DSP through SMMU. This includes handling map requests for rpcmem
>>>> and DMABUF-backed memory and providing corresponding unmap
>>>> functionality.
>>> For me this definitely looks like a step back. For drm/accel we are
>>> going to have GEM-managed buffers only. Why do we need to handle
>>> userspace-allocated buffers here?
>> That's correct, GEM-PRIME will handle it properly. Here, the reason to add this
>> change is to enable routing of DSP logs to HLOS which is done by using a shared
>> buffer between userspace process and DSP PD. The buffer can be allocated from
>> both fastrpc driver's DMA-BUF or DMABUF heap(eg. system heap).
>>
>> So this shared buffer is getting mapped to both process's IOMMU device and DSP PD
>> with this change.
> So, you have the DMA-BUF buffer. Instead of mapping it from userspace
> with unclean semantics, please import the buffer.
I'm assuming fastrpc_map_create is sort of importing the buffer by calling
dma_buf_map_attachment. Is this not the correct understanding? This assumption
is based on the existing part inside fastrpc_get_args, where fastrpc_map_create is
getting called for each of user passed DMA-BUF.

Moving to accel based driver is going to standardize this as the .gem_prime_import
implementation is going to handle this case.

//Ekansh

>
>>>> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
>>>> ---
>>>>  drivers/misc/fastrpc.c | 97 +++++++++++++++++++++++++++++++++++++-----
>>>>  1 file changed, 86 insertions(+), 11 deletions(-)
>>>>
Re: [PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers
Posted by Dmitry Baryshkov 9 hours ago
On Fri, Jan 30, 2026 at 05:27:37PM +0530, Ekansh Gupta wrote:
> 
> 
> On 1/30/2026 7:59 AM, Dmitry Baryshkov wrote:
> > On Thu, Jan 29, 2026 at 04:09:41PM +0530, Ekansh Gupta wrote:
> >>
> >> On 1/6/2026 8:21 AM, Dmitry Baryshkov wrote:
> >>> On Tue, Dec 30, 2025 at 04:32:25PM +0530, Ekansh Gupta wrote:
> >>>> Currently, FastRPC only supports mapping buffers allocated by the
> >>>> kernel. This limits flexibility for applications that allocate memory
> >>>> in userspace using rpcmem or DMABUF and need to share it with the DSP.
> >>> Hmm, for DMABUF we need _import_ support rather than support for mapping
> >>> of userspace-allocated buffers.
> >>>
> >>>> Add support for mapping and unmapping userspace-allocated buffers to
> >>>> the DSP through SMMU. This includes handling map requests for rpcmem
> >>>> and DMABUF-backed memory and providing corresponding unmap
> >>>> functionality.
> >>> For me this definitely looks like a step back. For drm/accel we are
> >>> going to have GEM-managed buffers only. Why do we need to handle
> >>> userspace-allocated buffers here?
> >> That's correct, GEM-PRIME will handle it properly. Here, the reason to add this
> >> change is to enable routing of DSP logs to HLOS which is done by using a shared
> >> buffer between userspace process and DSP PD. The buffer can be allocated from
> >> both fastrpc driver's DMA-BUF or DMABUF heap(eg. system heap).
> >>
> >> So this shared buffer is getting mapped to both process's IOMMU device and DSP PD
> >> with this change.
> > So, you have the DMA-BUF buffer. Instead of mapping it from userspace
> > with unclean semantics, please import the buffer.
> I'm assuming fastrpc_map_create is sort of importing the buffer by calling
> dma_buf_map_attachment. Is this not the correct understanding? This assumption
> is based on the existing part inside fastrpc_get_args, where fastrpc_map_create is
> getting called for each of user passed DMA-BUF.

I was thinking about dma_buf_attach() rather than
dma_buf_map_attachment().

> 
> Moving to accel based driver is going to standardize this as the .gem_prime_import
> implementation is going to handle this case.
> 
> //Ekansh
> 
> >
> >>>> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
> >>>> ---
> >>>>  drivers/misc/fastrpc.c | 97 +++++++++++++++++++++++++++++++++++++-----
> >>>>  1 file changed, 86 insertions(+), 11 deletions(-)
> >>>>
> 

-- 
With best wishes
Dmitry
Re: [PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers
Posted by Rob Clark 1 week, 3 days ago
On Thu, Jan 29, 2026 at 2:39 AM Ekansh Gupta
<ekansh.gupta@oss.qualcomm.com> wrote:
>
>
>
> On 1/6/2026 8:21 AM, Dmitry Baryshkov wrote:
> > On Tue, Dec 30, 2025 at 04:32:25PM +0530, Ekansh Gupta wrote:
> >> Currently, FastRPC only supports mapping buffers allocated by the
> >> kernel. This limits flexibility for applications that allocate memory
> >> in userspace using rpcmem or DMABUF and need to share it with the DSP.
> > Hmm, for DMABUF we need _import_ support rather than support for mapping
> > of userspace-allocated buffers.
> >
> >> Add support for mapping and unmapping userspace-allocated buffers to
> >> the DSP through SMMU. This includes handling map requests for rpcmem
> >> and DMABUF-backed memory and providing corresponding unmap
> >> functionality.
> > For me this definitely looks like a step back. For drm/accel we are
> > going to have GEM-managed buffers only. Why do we need to handle
> > userspace-allocated buffers here?
> That's correct, GEM-PRIME will handle it properly. Here, the reason to add this
> change is to enable routing of DSP logs to HLOS which is done by using a shared
> buffer between userspace process and DSP PD. The buffer can be allocated from
> both fastrpc driver's DMA-BUF or DMABUF heap(eg. system heap).
>
> So this shared buffer is getting mapped to both process's IOMMU device and DSP PD
> with this change.

So, a mmap'd dma-buf is not necessarily pinned.  Or even backed with
pages.  So you wouldn't want to try to map a userspace vaddr from a
dma-buf to the device.

But looking at the patch, this looks more like mapping an imported
dmabuf?  Presumably going thru dma_buf_map_attachment() somewhere in
the existing fastrpc code?

BR,
-R

> >
> >> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
> >> ---
> >>  drivers/misc/fastrpc.c | 97 +++++++++++++++++++++++++++++++++++++-----
> >>  1 file changed, 86 insertions(+), 11 deletions(-)
> >>
> >> @@ -1989,25 +2020,69 @@ static int fastrpc_req_buf_alloc(struct fastrpc_user *fl,
> >>      return err;
> >>  }
> >>
> >> -static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
> >> +static int fastrpc_req_map_create(struct fastrpc_user *fl,
> >> +                              struct fastrpc_req_mmap req,
> >> +                              char __user *argp)
> >>  {
> >> -    struct fastrpc_req_mmap req;
> >> +    struct fastrpc_map *map = NULL;
> >> +    struct device *dev = fl->sctx->dev;
> >> +    u64 raddr = 0;
> >>      int err;
> >>
> >> -    if (copy_from_user(&req, argp, sizeof(req)))
> >> -            return -EFAULT;
> >> +    err = fastrpc_map_create(fl, req.fd, req.size, 0, &map);
> >> +    if (err) {
> >> +            dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
> >> +            return err;
> >> +    }
> >> +
> >> +    err = fastrpc_req_map_dsp(fl, map->phys, map->size, req.flags,
> >> +                              req.vaddrin, &raddr);
> >> +    if (err)
> >> +            goto err_invoke;
> >>
> >> -    if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) {
> >> -            dev_err(fl->sctx->dev, "flag not supported 0x%x\n", req.flags);
> >> +    /* update the buffer to be able to deallocate the memory on the DSP */
> >> +    map->raddr = (u64)raddr;
> > Which type are you converting? And why?
> I'll drop this.
> >
> >>
> >> -            return -EINVAL;
> >> +    /* let the client know the address to use */
> >> +    req.vaddrout = raddr;
> >> +    dev_dbg(dev, "mmap OK: raddr=%p [len=0x%08llx]\n",
> >> +            (void *)(unsigned long)map->raddr, map->size);
> >> +
> >> +    if (copy_to_user(argp, &req, sizeof(req))) {
> >> +            err = -EFAULT;
> >> +            goto err_copy;
> >>      }
> >>
> >> -    err = fastrpc_req_buf_alloc(fl, req, argp);
> >> +    return 0;
> >> +err_copy:
> >> +    fastrpc_req_munmap_dsp(fl, map->raddr, map->size);
> >> +err_invoke:
> >> +    fastrpc_map_put(map);
> >>
> >>      return err;
> >>  }
> >>
> >> +static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
> >> +{
> >> +    struct fastrpc_req_mmap req;
> >> +    int err;
> >> +
> >> +    if (copy_from_user(&req, argp, sizeof(req)))
> >> +            return -EFAULT;
> >> +
> >> +    if ((req.flags == ADSP_MMAP_ADD_PAGES ||
> >> +         req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) {
> > Side note: why are these flags not defined in the uABI header?
> Ack. These should be part of uABI. I'll create a separate patch for this.
> >
> >> +            err = fastrpc_req_buf_alloc(fl, req, argp);
> >> +            if (err)
> >> +                    return err;
>
Re: [PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers
Posted by Ekansh Gupta 1 week, 2 days ago

On 1/30/2026 3:41 AM, Rob Clark wrote:
> On Thu, Jan 29, 2026 at 2:39 AM Ekansh Gupta
> <ekansh.gupta@oss.qualcomm.com> wrote:
>>
>>
>> On 1/6/2026 8:21 AM, Dmitry Baryshkov wrote:
>>> On Tue, Dec 30, 2025 at 04:32:25PM +0530, Ekansh Gupta wrote:
>>>> Currently, FastRPC only supports mapping buffers allocated by the
>>>> kernel. This limits flexibility for applications that allocate memory
>>>> in userspace using rpcmem or DMABUF and need to share it with the DSP.
>>> Hmm, for DMABUF we need _import_ support rather than support for mapping
>>> of userspace-allocated buffers.
>>>
>>>> Add support for mapping and unmapping userspace-allocated buffers to
>>>> the DSP through SMMU. This includes handling map requests for rpcmem
>>>> and DMABUF-backed memory and providing corresponding unmap
>>>> functionality.
>>> For me this definitely looks like a step back. For drm/accel we are
>>> going to have GEM-managed buffers only. Why do we need to handle
>>> userspace-allocated buffers here?
>> That's correct, GEM-PRIME will handle it properly. Here, the reason to add this
>> change is to enable routing of DSP logs to HLOS which is done by using a shared
>> buffer between userspace process and DSP PD. The buffer can be allocated from
>> both fastrpc driver's DMA-BUF or DMABUF heap(eg. system heap).
>>
>> So this shared buffer is getting mapped to both process's IOMMU device and DSP PD
>> with this change.
> So, a mmap'd dma-buf is not necessarily pinned.  Or even backed with
> pages.  So you wouldn't want to try to map a userspace vaddr from a
> dma-buf to the device.
>
> But looking at the patch, this looks more like mapping an imported
> dmabuf?  Presumably going thru dma_buf_map_attachment() somewhere in
> the existing fastrpc code?
yes, when the fd is passed to this call, first fastrpc_map_create is called which is
calling dma_buf_map_attachment[1]. After this the buffer is mapped onto DSP.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/misc/fastrpc.c#n781

>
> BR,
> -R
>
>>>> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
>>>> ---
>>>>  drivers/misc/fastrpc.c | 97 +++++++++++++++++++++++++++++++++++++-----
>>>>  1 file changed, 86 insertions(+), 11 deletions(-)
>>>>
>>>> @@ -1989,25 +2020,69 @@ static int fastrpc_req_buf_alloc(struct fastrpc_user *fl,
>>>>      return err;
>>>>  }
>>>>
>>>> -static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
>>>> +static int fastrpc_req_map_create(struct fastrpc_user *fl,
>>>> +                              struct fastrpc_req_mmap req,
>>>> +                              char __user *argp)
>>>>  {
>>>> -    struct fastrpc_req_mmap req;
>>>> +    struct fastrpc_map *map = NULL;
>>>> +    struct device *dev = fl->sctx->dev;
>>>> +    u64 raddr = 0;
>>>>      int err;
>>>>
>>>> -    if (copy_from_user(&req, argp, sizeof(req)))
>>>> -            return -EFAULT;
>>>> +    err = fastrpc_map_create(fl, req.fd, req.size, 0, &map);
>>>> +    if (err) {
>>>> +            dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
>>>> +            return err;
>>>> +    }
>>>> +
>>>> +    err = fastrpc_req_map_dsp(fl, map->phys, map->size, req.flags,
>>>> +                              req.vaddrin, &raddr);
>>>> +    if (err)
>>>> +            goto err_invoke;
>>>>
>>>> -    if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) {
>>>> -            dev_err(fl->sctx->dev, "flag not supported 0x%x\n", req.flags);
>>>> +    /* update the buffer to be able to deallocate the memory on the DSP */
>>>> +    map->raddr = (u64)raddr;
>>> Which type are you converting? And why?
>> I'll drop this.
>>>> -            return -EINVAL;
>>>> +    /* let the client know the address to use */
>>>> +    req.vaddrout = raddr;
>>>> +    dev_dbg(dev, "mmap OK: raddr=%p [len=0x%08llx]\n",
>>>> +            (void *)(unsigned long)map->raddr, map->size);
>>>> +
>>>> +    if (copy_to_user(argp, &req, sizeof(req))) {
>>>> +            err = -EFAULT;
>>>> +            goto err_copy;
>>>>      }
>>>>
>>>> -    err = fastrpc_req_buf_alloc(fl, req, argp);
>>>> +    return 0;
>>>> +err_copy:
>>>> +    fastrpc_req_munmap_dsp(fl, map->raddr, map->size);
>>>> +err_invoke:
>>>> +    fastrpc_map_put(map);
>>>>
>>>>      return err;
>>>>  }
>>>>
>>>> +static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
>>>> +{
>>>> +    struct fastrpc_req_mmap req;
>>>> +    int err;
>>>> +
>>>> +    if (copy_from_user(&req, argp, sizeof(req)))
>>>> +            return -EFAULT;
>>>> +
>>>> +    if ((req.flags == ADSP_MMAP_ADD_PAGES ||
>>>> +         req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) {
>>> Side note: why are these flags not defined in the uABI header?
>> Ack. These should be part of uABI. I'll create a separate patch for this.
>>>> +            err = fastrpc_req_buf_alloc(fl, req, argp);
>>>> +            if (err)
>>>> +                    return err;

Re: [PATCH v3 3/3] misc: fastrpc: Support mapping userspace-allocated buffers
Posted by David Laight 1 week, 3 days ago
On Thu, 29 Jan 2026 14:11:12 -0800
Rob Clark <rob.clark@oss.qualcomm.com> wrote:


> But looking at the patch, this looks more like mapping an imported
> dmabuf?  Presumably going thru dma_buf_map_attachment() somewhere in
> the existing fastrpc code?

I think I might have had a related problem.
I used dma_alloc_coherent() to get multiple 16kB blocks of kernel memory that
a device can access. The device has an internal 'mmu' that makes them logically
contiguous (from the device point of view).
I then wanted to mmap() a 4k (page) aligned sub-range of that kernel memory
into userspace so that it saw part of the same logically contiguous memory
as the on-device hardware.
Different parts of the devices (max 512 * 16kB) master window are used for
different things, so mmap() offset zero is different for different mmap() requests.
One of the 'old' methods still works provided the pages are physically
contiguous - which isn't the default for systems with an iommu.
IIRC there is a function that will map a single dma_alloc_coherent() allocated
buffer into userspace - but that doesn't let you offset the addresses
not join up multiple buffers.
I can't have been the only person trying to do that?

	David