Skip to content

Commit f94666f

Browse files
ekanshibuquic-vkatoch
authored andcommitted
FROMLIST: misc: fastrpc: Remove buffer from list prior to unmap operation
fastrpc_req_munmap_impl() is called to unmap any buffer. The buffer is getting removed from the list after it is unmapped from DSP. This can create potential race conditions if multiple threads invoke unmap concurrently, where one thread may remove the entry from the list while another thread's unmap operation is still ongoing. Fix this by removing the buffer entry from the list before calling the unmap operation. If the unmap fails, the entry is re-added to the list so that userspace can retry the unmap, or alternatively, the buffer will be cleaned up during device release when the DSP process is torn down and all DSP-side mappings are freed along with remaining buffers in the list. Link: https://lore.kernel.org/all/20260526111124.515-3-jianping.li@oss.qualcomm.com/ Fixes: 2419e55 ("misc: fastrpc: add mmap/unmap support") Cc: stable@kernel.org Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com> Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com> Signed-off-by: Vinayak Katoch <vkatoch@qti.qualcomm.com>
1 parent 27c6d79 commit f94666f

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

drivers/misc/fastrpc.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,9 +2050,6 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *
20502050
&args[0]);
20512051
if (!err) {
20522052
dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
2053-
spin_lock(&fl->lock);
2054-
list_del(&buf->node);
2055-
spin_unlock(&fl->lock);
20562053
fastrpc_buf_free(buf);
20572054
} else {
20582055
dev_err(dev, "unmmap\tpt 0x%09lx ERROR\n", buf->raddr);
@@ -2066,13 +2063,15 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
20662063
struct fastrpc_buf *buf = NULL, *iter, *b;
20672064
struct fastrpc_req_munmap req;
20682065
struct device *dev = fl->sctx->dev;
2066+
int err;
20692067

20702068
if (copy_from_user(&req, argp, sizeof(req)))
20712069
return -EFAULT;
20722070

20732071
spin_lock(&fl->lock);
20742072
list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
20752073
if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
2074+
list_del(&iter->node);
20762075
buf = iter;
20772076
break;
20782077
}
@@ -2085,7 +2084,14 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
20852084
return -EINVAL;
20862085
}
20872086

2088-
return fastrpc_req_munmap_impl(fl, buf);
2087+
err = fastrpc_req_munmap_impl(fl, buf);
2088+
if (err) {
2089+
spin_lock(&fl->lock);
2090+
list_add_tail(&buf->node, &fl->mmaps);
2091+
spin_unlock(&fl->lock);
2092+
}
2093+
2094+
return err;
20892095
}
20902096

20912097
static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)

0 commit comments

Comments
 (0)