2022-11-25 07:27:40

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 00/10] misc: fastrpc: patches for 6.2

Hi Greg,

Here are some fastrpc patches which add new feature to handle Audio
Protection Domain. Along with it there is one locking update on dma-buf
and an update to bindings.

Could you please queue them up for 6.2.

Thanks,
Srini


changes since v1:
dropped a dmabuf lock patch.

Abel Vesa (10):
dt-bindings: misc: qcom,fastrpc: increase allowed iommus entries
misc: fastrpc: Rename audio protection domain to root
misc: fastrpc: Add reserved mem support
misc: fastrpc: Add fastrpc_remote_heap_alloc
misc: fastrpc: Use fastrpc_map_put in fastrpc_map_create on fail
misc: fastrpc: Rework fastrpc_req_munmap
misc: fastrpc: Add support for audiopd
misc: fastrpc: Safekeep mmaps on interrupted invoke
misc: fastrpc: Add mmap request assigning for static PD pool
misc: fastrpc: Add dma_mask to fastrpc_channel_ctx

.../bindings/misc/qcom,fastrpc.yaml | 2 +-
drivers/misc/fastrpc.c | 260 +++++++++++++++---
include/uapi/misc/fastrpc.h | 7 +
3 files changed, 236 insertions(+), 33 deletions(-)

--
2.25.1


2022-11-25 07:29:18

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 10/10] misc: fastrpc: Add dma_mask to fastrpc_channel_ctx

From: Abel Vesa <[email protected]>

dma_set_mask_and_coherent only updates the mask to which the device
dma_mask pointer points to. Add a dma_mask to the channel ctx and set
the device dma_mask to point to that, otherwise the dma_set_mask will
return an error and the dma_set_coherent_mask will be skipped too.

Signed-off-by: Abel Vesa <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
drivers/misc/fastrpc.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 4b05cbd6083d..8dc6f8f932db 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -278,6 +278,7 @@ struct fastrpc_channel_ctx {
struct list_head invoke_interrupted_mmaps;
bool secure;
bool unsigned_support;
+ u64 dma_mask;
};

struct fastrpc_device {
@@ -2306,6 +2307,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
kref_init(&data->refcount);

dev_set_drvdata(&rpdev->dev, data);
+ rdev->dma_mask = &data->dma_mask;
dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32));
INIT_LIST_HEAD(&data->users);
INIT_LIST_HEAD(&data->invoke_interrupted_mmaps);
--
2.25.1

2022-11-25 07:33:09

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 02/10] misc: fastrpc: Rename audio protection domain to root

From: Abel Vesa <[email protected]>

The AUDIO_PD will be done via static pd, so the proper name here is
actually ROOT_PD.

Signed-off-by: Abel Vesa <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
drivers/misc/fastrpc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 80811e852d8f..f80a00e9f508 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -83,7 +83,7 @@
#define FASTRPC_RMID_INIT_MEM_UNMAP 11

/* Protection Domain(PD) ids */
-#define AUDIO_PD (0) /* also GUEST_OS PD? */
+#define ROOT_PD (0)
#define USER_PD (1)
#define SENSORS_PD (2)

@@ -1889,7 +1889,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
err = fastrpc_invoke(fl, argp);
break;
case FASTRPC_IOCTL_INIT_ATTACH:
- err = fastrpc_init_attach(fl, AUDIO_PD);
+ err = fastrpc_init_attach(fl, ROOT_PD);
break;
case FASTRPC_IOCTL_INIT_ATTACH_SNS:
err = fastrpc_init_attach(fl, SENSORS_PD);
--
2.25.1

2022-11-25 07:42:11

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 03/10] misc: fastrpc: Add reserved mem support

From: Abel Vesa <[email protected]>

The reserved mem support is needed for CMA heap support, which will be
used by AUDIOPD.

Signed-off-by: Abel Vesa <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
drivers/misc/fastrpc.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index f80a00e9f508..395036a10e15 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/qcom_scm.h>
#include <uapi/misc/fastrpc.h>
+#include <linux/of_reserved_mem.h>

#define ADSP_DOMAIN_ID (0)
#define MDSP_DOMAIN_ID (1)
@@ -2068,6 +2069,9 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
return -EINVAL;
}

+ if (of_reserved_mem_device_init_by_idx(rdev, rdev->of_node, 0))
+ dev_info(rdev, "no reserved DMA memory for FASTRPC\n");
+
vmcount = of_property_read_variable_u32_array(rdev->of_node,
"qcom,vmids", &vmids[0], 0, FASTRPC_MAX_VMIDS);
if (vmcount < 0)
--
2.25.1

2022-11-25 07:46:54

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 04/10] misc: fastrpc: Add fastrpc_remote_heap_alloc

From: Abel Vesa <[email protected]>

Split fastrpc_buf_alloc in such a way it allows allocation of remote
heap too and add fastrpc_remote_heap_alloc to do so.

Signed-off-by: Abel Vesa <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
drivers/misc/fastrpc.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 395036a10e15..9e83743eaca1 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -379,7 +379,7 @@ static void fastrpc_buf_free(struct fastrpc_buf *buf)
kfree(buf);
}

-static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev,
+static int __fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev,
u64 size, struct fastrpc_buf **obuf)
{
struct fastrpc_buf *buf;
@@ -407,14 +407,37 @@ static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev,
return -ENOMEM;
}

+ *obuf = buf;
+
+ return 0;
+}
+
+static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev,
+ u64 size, struct fastrpc_buf **obuf)
+{
+ int ret;
+ struct fastrpc_buf *buf;
+
+ ret = __fastrpc_buf_alloc(fl, dev, size, obuf);
+ if (ret)
+ return ret;
+
+ buf = *obuf;
+
if (fl->sctx && fl->sctx->sid)
buf->phys += ((u64)fl->sctx->sid << 32);

- *obuf = buf;
-
return 0;
}

+static int fastrpc_remote_heap_alloc(struct fastrpc_user *fl, struct device *dev,
+ u64 size, struct fastrpc_buf **obuf)
+{
+ struct device *rdev = &fl->cctx->rpdev->dev;
+
+ return __fastrpc_buf_alloc(fl, rdev, size, obuf);
+}
+
static void fastrpc_channel_ctx_free(struct kref *ref)
{
struct fastrpc_channel_ctx *cctx;
--
2.25.1

2022-11-25 07:54:13

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 09/10] misc: fastrpc: Add mmap request assigning for static PD pool

From: Abel Vesa <[email protected]>

If the mmap request is to add pages and thre are VMIDs associated with
that context, do a call to SCM to reassign that memory. Do not do this
for remote heap allocation, that is done on init create static process
only.

Signed-off-by: Abel Vesa <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
drivers/misc/fastrpc.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 2dc9946c3d23..4b05cbd6083d 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1842,8 +1842,9 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
if (copy_from_user(&req, argp, sizeof(req)))
return -EFAULT;

- if (req.flags != ADSP_MMAP_ADD_PAGES) {
+ if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) {
dev_err(dev, "flag not supported 0x%x\n", req.flags);
+
return -EINVAL;
}

@@ -1889,6 +1890,22 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
/* let the client know the address to use */
req.vaddrout = rsp_msg.vaddr;

+ /* Add memory to static PD pool, protection thru hypervisor */
+ if (req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) {
+ struct qcom_scm_vmperm perm;
+ int err = 0;
+
+ perm.vmid = QCOM_SCM_VMID_HLOS;
+ perm.perm = QCOM_SCM_PERM_RWX;
+ err = qcom_scm_assign_mem(buf->phys, buf->size,
+ &(fl->cctx->vmperms[0].vmid), &perm, 1);
+ if (err) {
+ dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d",
+ buf->phys, buf->size, err);
+ goto err_assign;
+ }
+ }
+
spin_lock(&fl->lock);
list_add_tail(&buf->node, &fl->mmaps);
spin_unlock(&fl->lock);
--
2.25.1

2022-11-25 07:55:58

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 07/10] misc: fastrpc: Add support for audiopd

From: Abel Vesa <[email protected]>

In order to be able to start the adsp listener for audiopd using adsprpcd,
we need to add the corresponding ioctl for creating a static process.
On that ioctl call we need to allocate the heap. Allocating the heap needs
to be happening only once and needs to be kept between different device
open calls, so attach it to the channel context to make sure that remains
until the RPMSG driver is removed. Then, if there are any VMIDs associated
with the static ADSP process, do a call to SCM to assign it.
And then, send all the necessary info related to heap to the DSP.

Signed-off-by: Abel Vesa <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
drivers/misc/fastrpc.c | 135 ++++++++++++++++++++++++++++++++++++
include/uapi/misc/fastrpc.h | 7 ++
2 files changed, 142 insertions(+)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index a1e916902deb..b123b6783920 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -37,8 +37,20 @@
#define FASTRPC_DSP_UTILITIES_HANDLE 2
#define FASTRPC_CTXID_MASK (0xFF0)
#define INIT_FILELEN_MAX (2 * 1024 * 1024)
+#define INIT_FILE_NAMELEN_MAX (128)
#define FASTRPC_DEVICE_NAME "fastrpc"
+
+/* Add memory to static PD pool, protection thru XPU */
+#define ADSP_MMAP_HEAP_ADDR 4
+/* MAP static DMA buffer on DSP User PD */
+#define ADSP_MMAP_DMA_BUFFER 6
+/* Add memory to static PD pool protection thru hypervisor */
+#define ADSP_MMAP_REMOTE_HEAP_ADDR 8
+/* Add memory to userPD pool, for user heap */
#define ADSP_MMAP_ADD_PAGES 0x1000
+/* Add memory to userPD pool, for LLC heap */
+#define ADSP_MMAP_ADD_PAGES_LLC 0x3000,
+
#define DSP_UNSUPPORTED_API (0x80000414)
/* MAX NUMBER of DSP ATTRIBUTES SUPPORTED */
#define FASTRPC_MAX_DSP_ATTRIBUTES (256)
@@ -72,6 +84,7 @@
FASTRPC_BUILD_SCALARS(0, method, in, out, 0, 0)

#define FASTRPC_CREATE_PROCESS_NARGS 6
+#define FASTRPC_CREATE_STATIC_PROCESS_NARGS 3
/* Remote Method id table */
#define FASTRPC_RMID_INIT_ATTACH 0
#define FASTRPC_RMID_INIT_RELEASE 1
@@ -261,6 +274,7 @@ struct fastrpc_channel_ctx {
u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
struct fastrpc_device *secure_fdevice;
struct fastrpc_device *fdevice;
+ struct fastrpc_buf *remote_heap;
bool secure;
bool unsigned_support;
};
@@ -1167,6 +1181,7 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
spin_unlock(&fl->lock);
fastrpc_context_put(ctx);
}
+
if (err)
dev_dbg(fl->sctx->dev, "Error: Invoke Failed %d\n", err);

@@ -1191,6 +1206,120 @@ static bool is_session_rejected(struct fastrpc_user *fl, bool unsigned_pd_reques
return false;
}

+static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
+ char __user *argp)
+{
+ struct fastrpc_init_create_static init;
+ struct fastrpc_invoke_args *args;
+ struct fastrpc_phy_page pages[1];
+ char *name;
+ int err;
+ struct {
+ int pgid;
+ u32 namelen;
+ u32 pageslen;
+ } inbuf;
+ u32 sc;
+
+ args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+
+ if (copy_from_user(&init, argp, sizeof(init))) {
+ err = -EFAULT;
+ goto err;
+ }
+
+ if (init.namelen > INIT_FILE_NAMELEN_MAX) {
+ err = -EINVAL;
+ goto err;
+ }
+
+ name = kzalloc(init.namelen, GFP_KERNEL);
+ if (!name) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ if (copy_from_user(name, (void __user *)(uintptr_t)init.name, init.namelen)) {
+ err = -EFAULT;
+ goto err_name;
+ }
+
+ if (!fl->cctx->remote_heap) {
+ err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
+ &fl->cctx->remote_heap);
+ if (err)
+ goto err_name;
+
+ /* Map if we have any heap VMIDs associated with this ADSP Static Process. */
+ if (fl->cctx->vmcount) {
+ unsigned int perms = BIT(QCOM_SCM_VMID_HLOS);
+
+ err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
+ (u64)fl->cctx->remote_heap->size, &perms,
+ fl->cctx->vmperms, fl->cctx->vmcount);
+ if (err) {
+ dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d",
+ fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
+ goto err_map;
+ }
+ }
+ }
+
+ inbuf.pgid = fl->tgid;
+ inbuf.namelen = init.namelen;
+ inbuf.pageslen = 0;
+ fl->pd = USER_PD;
+
+ args[0].ptr = (u64)(uintptr_t)&inbuf;
+ args[0].length = sizeof(inbuf);
+ args[0].fd = -1;
+
+ args[1].ptr = (u64)(uintptr_t)name;
+ args[1].length = inbuf.namelen;
+ args[1].fd = -1;
+
+ pages[0].addr = fl->cctx->remote_heap->phys;
+ pages[0].size = fl->cctx->remote_heap->size;
+
+ args[2].ptr = (u64)(uintptr_t) pages;
+ args[2].length = sizeof(*pages);
+ args[2].fd = -1;
+
+ sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_STATIC, 3, 0);
+
+ err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
+ sc, args);
+ if (err)
+ goto err_invoke;
+
+ kfree(args);
+
+ return 0;
+err_invoke:
+ if (fl->cctx->vmcount) {
+ struct qcom_scm_vmperm perm;
+
+ perm.vmid = QCOM_SCM_VMID_HLOS;
+ perm.perm = QCOM_SCM_PERM_RWX;
+ err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
+ (u64)fl->cctx->remote_heap->size,
+ &(fl->cctx->vmperms[0].vmid), &perm, 1);
+ if (err)
+ dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d",
+ fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
+ }
+err_map:
+ fastrpc_buf_free(fl->cctx->remote_heap);
+err_name:
+ kfree(name);
+err:
+ kfree(args);
+
+ return err;
+}
+
static int fastrpc_init_create_process(struct fastrpc_user *fl,
char __user *argp)
{
@@ -1918,6 +2047,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
case FASTRPC_IOCTL_INIT_ATTACH_SNS:
err = fastrpc_init_attach(fl, SENSORS_PD);
break;
+ case FASTRPC_IOCTL_INIT_CREATE_STATIC:
+ err = fastrpc_init_create_static_process(fl, argp);
+ break;
case FASTRPC_IOCTL_INIT_CREATE:
err = fastrpc_init_create_process(fl, argp);
break;
@@ -2187,6 +2319,9 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
if (cctx->secure_fdevice)
misc_deregister(&cctx->secure_fdevice->miscdev);

+ if (cctx->remote_heap)
+ fastrpc_buf_free(cctx->remote_heap);
+
of_platform_depopulate(&rpdev->dev);

cctx->rpdev = NULL;
diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h
index 5e29f2cfa42d..f33d914d8f46 100644
--- a/include/uapi/misc/fastrpc.h
+++ b/include/uapi/misc/fastrpc.h
@@ -13,6 +13,7 @@
#define FASTRPC_IOCTL_MMAP _IOWR('R', 6, struct fastrpc_req_mmap)
#define FASTRPC_IOCTL_MUNMAP _IOWR('R', 7, struct fastrpc_req_munmap)
#define FASTRPC_IOCTL_INIT_ATTACH_SNS _IO('R', 8)
+#define FASTRPC_IOCTL_INIT_CREATE_STATIC _IOWR('R', 9, struct fastrpc_init_create_static)
#define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map)
#define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap)
#define FASTRPC_IOCTL_GET_DSP_INFO _IOWR('R', 13, struct fastrpc_ioctl_capability)
@@ -87,6 +88,12 @@ struct fastrpc_init_create {
__u64 file; /* pointer to elf file */
};

+struct fastrpc_init_create_static {
+ __u32 namelen; /* length of pd process name */
+ __u32 memlen;
+ __u64 name; /* pd process name */
+};
+
struct fastrpc_alloc_dma_buf {
__s32 fd; /* fd */
__u32 flags; /* flags to map with */
--
2.25.1

2022-11-25 08:02:57

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 01/10] dt-bindings: misc: qcom,fastrpc: increase allowed iommus entries

From: Abel Vesa <[email protected]>

The fastrpc components on the SM8550 SoC can require up to 3 IOMMU
entries, this bumps the maxItems to 3 for this purpose.

Signed-off-by: Abel Vesa <[email protected]>
Signed-off-by: Neil Armstrong <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml
index d7576f8ac94b..1ab9588cdd89 100644
--- a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml
+++ b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml
@@ -79,7 +79,7 @@ patternProperties:

iommus:
minItems: 1
- maxItems: 2
+ maxItems: 3

qcom,nsessions:
$ref: /schemas/types.yaml#/definitions/uint32
--
2.25.1

2022-11-25 08:03:00

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 06/10] misc: fastrpc: Rework fastrpc_req_munmap

From: Abel Vesa <[email protected]>

Move the lookup of the munmap request to the fastrpc_req_munmap and pass
on only the buf to the lower level fastrpc_req_munmap_impl. That way
we can use the lower level fastrpc_req_munmap_impl on error path in
fastrpc_req_mmap to free the buf without searching for the munmap
request it belongs to.

Signed-off-by: Abel Vesa <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
drivers/misc/fastrpc.c | 47 +++++++++++++++++++++---------------------
1 file changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 0d9f1eb9a0ed..a1e916902deb 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1630,30 +1630,14 @@ static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp)
return 0;
}

-static int fastrpc_req_munmap_impl(struct fastrpc_user *fl,
- struct fastrpc_req_munmap *req)
+static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *buf)
{
struct fastrpc_invoke_args args[1] = { [0] = { 0 } };
- struct fastrpc_buf *buf = NULL, *iter, *b;
struct fastrpc_munmap_req_msg req_msg;
struct device *dev = fl->sctx->dev;
int err;
u32 sc;

- spin_lock(&fl->lock);
- list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
- if ((iter->raddr == req->vaddrout) && (iter->size == req->size)) {
- buf = iter;
- break;
- }
- }
- spin_unlock(&fl->lock);
-
- if (!buf) {
- dev_err(dev, "mmap not in list\n");
- return -EINVAL;
- }
-
req_msg.pgid = fl->tgid;
req_msg.size = buf->size;
req_msg.vaddr = buf->raddr;
@@ -1679,12 +1663,29 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl,

static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
{
+ struct fastrpc_buf *buf = NULL, *iter, *b;
struct fastrpc_req_munmap req;
+ struct device *dev = fl->sctx->dev;

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

- return fastrpc_req_munmap_impl(fl, &req);
+ spin_lock(&fl->lock);
+ list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
+ if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
+ buf = iter;
+ break;
+ }
+ }
+ spin_unlock(&fl->lock);
+
+ if (!buf) {
+ dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n",
+ req.vaddrout, req.size);
+ return -EINVAL;
+ }
+
+ return fastrpc_req_munmap_impl(fl, buf);
}

static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
@@ -1693,7 +1694,6 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
struct fastrpc_buf *buf = NULL;
struct fastrpc_mmap_req_msg req_msg;
struct fastrpc_mmap_rsp_msg rsp_msg;
- struct fastrpc_req_munmap req_unmap;
struct fastrpc_phy_page pages;
struct fastrpc_req_mmap req;
struct device *dev = fl->sctx->dev;
@@ -1755,11 +1755,8 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
spin_unlock(&fl->lock);

if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
- /* unmap the memory and release the buffer */
- req_unmap.vaddrout = buf->raddr;
- req_unmap.size = buf->size;
- fastrpc_req_munmap_impl(fl, &req_unmap);
- return -EFAULT;
+ err = -EFAULT;
+ goto err_assign;
}

dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n",
@@ -1767,6 +1764,8 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)

return 0;

+err_assign:
+ fastrpc_req_munmap_impl(fl, buf);
err_invoke:
fastrpc_buf_free(buf);

--
2.25.1

2022-11-25 08:09:22

by Srinivas Kandagatla

[permalink] [raw]
Subject: [PATCH v2 05/10] misc: fastrpc: Use fastrpc_map_put in fastrpc_map_create on fail

From: Abel Vesa <[email protected]>

Move the kref_init right after the allocation so that we can use
fastrpc_map_put on any following error case.

Signed-off-by: Abel Vesa <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
drivers/misc/fastrpc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 9e83743eaca1..0d9f1eb9a0ed 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -745,6 +745,8 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
return -ENOMEM;

INIT_LIST_HEAD(&map->node);
+ kref_init(&map->refcount);
+
map->fl = fl;
map->fd = fd;
map->buf = dma_buf_get(fd);
@@ -771,7 +773,6 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
map->size = len;
map->va = sg_virt(map->table->sgl);
map->len = len;
- kref_init(&map->refcount);

if (attr & FASTRPC_ATTR_SECUREMAP) {
/*
@@ -801,7 +802,7 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
attach_err:
dma_buf_put(map->buf);
get_err:
- kfree(map);
+ fastrpc_map_put(map);

return err;
}
--
2.25.1