Skip to content

Commit 5a94c05

Browse files
committed
FROMLIST: misc: fastrpc: Add missing unmapping user-requested remote heap
User request for remote heap allocation is supported using ioctl interface but support for unmap is missing. This could result in memory leak issues. Add unmap user request support for remote heap. Link: https://lore.kernel.org/all/20250513042825.2147985-6-ekansh.gupta@oss.qualcomm.com/ Fixes: 532ad70 ("misc: fastrpc: Add mmap request assigning for static PD pool") Cc: stable@kernel.org Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
1 parent 4006038 commit 5a94c05

1 file changed

Lines changed: 51 additions & 11 deletions

File tree

drivers/misc/fastrpc.c

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ struct fastrpc_buf {
197197
struct dma_buf *dmabuf;
198198
struct device *dev;
199199
void *virt;
200+
/* Type of buffer */
201+
u32 flag;
200202
u64 phys;
201203
u64 size;
202204
/* Lock for dma buf attachments */
@@ -1867,8 +1869,26 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *
18671869
err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc,
18681870
&args[0]);
18691871
if (!err) {
1870-
dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
1872+
if (buf->flag == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) {
1873+
u64 src_perms = 0;
1874+
struct qcom_scm_vmperm dst_perms;
1875+
u32 i;
1876+
1877+
for (i = 0; i < fl->cctx->vmcount; i++)
1878+
src_perms |= BIT(fl->cctx->vmperms[i].vmid);
1879+
1880+
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
1881+
dst_perms.perm = QCOM_SCM_PERM_RWX;
1882+
err = qcom_scm_assign_mem(buf->phys, (u64)buf->size,
1883+
&src_perms, &dst_perms, 1);
1884+
if (err) {
1885+
dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
1886+
buf->phys, buf->size, err);
1887+
return err;
1888+
}
1889+
}
18711890
fastrpc_buf_free(buf);
1891+
dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
18721892
} else {
18731893
dev_err(dev, "unmmap\tpt 0x%09lx ERROR\n", buf->raddr);
18741894
}
@@ -1882,6 +1902,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
18821902
struct fastrpc_req_munmap req;
18831903
struct device *dev = fl->sctx->dev;
18841904
int err;
1905+
unsigned long flags;
18851906

18861907
if (copy_from_user(&req, argp, sizeof(req)))
18871908
return -EFAULT;
@@ -1896,20 +1917,38 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
18961917
}
18971918
spin_unlock(&fl->lock);
18981919

1899-
if (!buf) {
1900-
dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n",
1901-
req.vaddrout, req.size);
1902-
return -EINVAL;
1920+
if (buf) {
1921+
err = fastrpc_req_munmap_impl(fl, buf);
1922+
if (err) {
1923+
spin_lock(&fl->lock);
1924+
list_add_tail(&buf->node, &fl->mmaps);
1925+
spin_unlock(&fl->lock);
1926+
}
1927+
return err;
19031928
}
19041929

1905-
err = fastrpc_req_munmap_impl(fl, buf);
1906-
if (err) {
1907-
spin_lock(&fl->lock);
1908-
list_add_tail(&buf->node, &fl->mmaps);
1909-
spin_unlock(&fl->lock);
1930+
spin_lock_irqsave(&fl->cctx->lock, flags);
1931+
list_for_each_entry_safe(iter, b, &fl->cctx->rhmaps, node) {
1932+
if (iter->raddr == req.vaddrout && iter->size == req.size) {
1933+
list_del(&iter->node);
1934+
buf = iter;
1935+
break;
1936+
}
19101937
}
1938+
spin_unlock_irqrestore(&fl->cctx->lock, flags);
1939+
if (buf) {
1940+
err = fastrpc_req_munmap_impl(fl, buf);
1941+
if (err) {
1942+
spin_lock_irqsave(&fl->cctx->lock, flags);
1943+
list_add_tail(&buf->node, &fl->cctx->rhmaps);
1944+
spin_unlock_irqrestore(&fl->cctx->lock, flags);
1945+
}
1946+
return err;
1947+
}
1948+
dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n",
1949+
req.vaddrout, req.size);
19111950

1912-
return err;
1951+
return -EINVAL;
19131952
}
19141953

19151954
static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
@@ -1977,6 +2016,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
19772016

19782017
/* update the buffer to be able to deallocate the memory on the DSP */
19792018
buf->raddr = (uintptr_t) rsp_msg.vaddr;
2019+
buf->flag = req.flags;
19802020

19812021
/* let the client know the address to use */
19822022
req.vaddrout = rsp_msg.vaddr;

0 commit comments

Comments
 (0)