From be33b5fa6bcc37386a7d3982ed1973e3528899dc Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Thu, 8 Apr 2021 15:04:51 +0530 Subject: [PATCH 01/10] vid_3x: Update codec caps for sdm450 target sdm450 does not support 4k resolution. So update max load and resolution accordingly. Change-Id: I340deb1a86241bc66b7593ae304eed9674a0f458 Signed-off-by: Vasantha Balla --- arch/arm64/boot/dts/qcom/sdm450.dtsi | 7 ++++++- .../media/platform/msm/vidc_3x/msm_v4l2_vidc.c | 4 +++- .../platform/msm/vidc_3x/msm_vidc_common.c | 18 ++++++++++++++++-- .../platform/msm/vidc_3x/msm_vidc_internal.h | 4 +++- .../platform/msm/vidc_3x/msm_vidc_resources.h | 3 ++- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm450.dtsi b/arch/arm64/boot/dts/qcom/sdm450.dtsi index 34c6815a912c..67177fb4076b 100644 --- a/arch/arm64/boot/dts/qcom/sdm450.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm450.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -146,3 +146,8 @@ /delete-node/ case-therm-adc; /delete-node/ case-therm-step; }; +&soc { + qcom,vidc@1d00000 { + qcom,max-hw-load = <734400>; /* 1080p@60 dec + 1080p@30 enc */ + }; +}; diff --git a/drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c index 9d05086c86ba..1c27e0822f93 100644 --- a/drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c +++ b/drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -627,6 +627,8 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) vidc_driver->capability_version = msm_vidc_read_efuse_version( pdev, core->resources.pf_cap_tbl, "efuse2"); + if (vidc_driver->capability_version) + core->resources.target_version = 1; rc = call_hfi_op(core->device, core_early_init, core->device->hfi_device_data); diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c index c0efc3b5553a..410482aad9ef 100644 --- a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -672,7 +672,7 @@ static void handle_sys_init_done(enum hal_command_response cmd, void *data) struct msm_vidc_cb_cmd_done *response = data; struct msm_vidc_core *core; struct vidc_hal_sys_init_done *sys_init_msg; - u32 index; + u32 index, i; if (!IS_HAL_SYS_CMD(cmd)) { dprintk(VIDC_ERR, "%s - invalid cmd\n", __func__); @@ -718,6 +718,20 @@ static void handle_sys_init_done(enum hal_command_response cmd, void *data) memcpy(core->capabilities, sys_init_msg->capabilities, sys_init_msg->codec_count * sizeof(struct msm_vidc_capability)); + /* override capabilities for sdm450 */ + if (core->resources.target_version == 1) { + for (i = 0; i < VIDC_MAX_SESSIONS; i++) { + if (core->capabilities[i].width.max > HD_WIDTH) + core->capabilities[i].width.max = HD_WIDTH; + if (core->capabilities[i].height.max > HD_WIDTH) + core->capabilities[i].height.max = HD_WIDTH; + + core->capabilities[i].mbs_per_frame.max = + NUM_MBS_PER_FRAME(HD_WIDTH, HD_HEIGHT); + core->resources.max_inst_count = + MAX_SUPPORTED_INSTANCES; + } + } dprintk(VIDC_DBG, "%s: supported_codecs[%d]: enc = %#x, dec = %#x\n", __func__, core->codec_count, core->enc_codec_supported, diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h b/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h index 7d711aa22ce8..9ecad404a579 100644 --- a/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, 2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, 2020,2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -45,6 +45,8 @@ #define MIN_SUPPORTED_WIDTH 32 #define MIN_SUPPORTED_HEIGHT 32 #define DEFAULT_FPS 15 +#define HD_WIDTH 1920 +#define HD_HEIGHT 1088 /* Maintains the number of FTB's between each FBD over a window */ #define DCVS_FTB_WINDOW 32 diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h b/drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h index 383aeda4d50b..eb4724253d33 100644 --- a/drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h +++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -174,6 +174,7 @@ struct msm_vidc_platform_resources { uint32_t imem_size; enum imem_type imem_type; uint32_t max_load; + uint32_t target_version; struct platform_device *pdev; struct regulator_set regulator_set; struct clock_set clock_set; From 2cbf5fb19a3cc9ccf7afb0e69e7add512046dad2 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Mon, 19 Apr 2021 10:41:01 +0530 Subject: [PATCH 02/10] diag: Use valid data_source for a valid token For a valid token indicating remote proc use data_source to indicate packet originated from dci remote source. Change-Id: I01729a905d532fae7ea046acc143598eca04460b Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index f531c384e55e..ba07d791c5b9 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1063,6 +1063,11 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, return; } + if (token != entry->client_info.token) { + mutex_unlock(&driver->dci_mutex); + return; + } + mutex_lock(&entry->buffers[data_source].buf_mutex); rsp_buf = entry->buffers[data_source].buf_cmd; From ebe002033fad520752ebbeeb7b15b98bf469c5fe Mon Sep 17 00:00:00 2001 From: Tharun Kumar Merugu Date: Fri, 5 Apr 2019 03:34:28 +0530 Subject: [PATCH 03/10] msm: adsprpc: API to get DSP capability This API will be initiated from a user application. If the DSP information is not on the kernel it will make a call to the DSP and retrieve the information. Then the information will be cached on the kernel and returned to the user program. Subsequent API calls will retrieve the previously cached information from the kernel. Change-Id: Ib89ad25e857f02f1e1ca02180c0363e1543503b4 Acked-by: Edgar Flores Signed-off-by: Tharun Kumar Merugu --- drivers/char/adsprpc.c | 176 +++++++++++++++++++++++++++++++--- drivers/char/adsprpc_compat.c | 58 ++++++++++- drivers/char/adsprpc_shared.h | 10 +- 3 files changed, 227 insertions(+), 17 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 7eaa40d7e3d0..683a033a1b53 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -32,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -51,6 +49,8 @@ #include #include #include +#include + #define TZ_PIL_PROTECT_MEM_SUBSYS_ID 0x0C #define TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID 0x0D #define TZ_PIL_AUTH_QDSP6_PROC 1 @@ -106,8 +106,9 @@ #define FASTRPC_GLINK_INTENT_NUM (16) #define PERF_KEYS \ - "count:flush:map:copy:glink:getargs:putargs:invalidate:invoke:tid:ptr" -#define FASTRPC_STATIC_HANDLE_KERNEL (1) + "count:flush:map:copy:rpmsg:getargs:putargs:invalidate:invoke:tid:ptr" +#define FASTRPC_STATIC_HANDLE_PROCESS_GROUP (1) +#define FASTRPC_STATIC_HANDLE_DSP_UTILITIES (2) #define FASTRPC_STATIC_HANDLE_LISTENER (3) #define FASTRPC_STATIC_HANDLE_MAX (20) #define FASTRPC_LATENCY_CTRL_ENB (1) @@ -285,6 +286,11 @@ struct fastrpc_glink_info { void *link_notify_handle; }; +struct fastrpc_dsp_capabilities { + uint32_t is_cached; //! Flag if dsp attributes are cached + uint32_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES]; +}; + struct fastrpc_channel_ctx { char *name; char *subsys; @@ -309,6 +315,7 @@ struct fastrpc_channel_ctx { struct fastrpc_glink_info link; /* Indicates, if channel is restricted to secure node only */ int secure; + struct fastrpc_dsp_capabilities dsp_cap_kernel; }; struct fastrpc_apps { @@ -2066,10 +2073,13 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, getnstimeofday(&invoket); if (!kernel) { - VERIFY(err, invoke->handle != FASTRPC_STATIC_HANDLE_KERNEL); + VERIFY(err, invoke->handle != + FASTRPC_STATIC_HANDLE_PROCESS_GROUP); + VERIFY(err, invoke->handle != + FASTRPC_STATIC_HANDLE_DSP_UTILITIES); if (err) { - pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d", - __func__, current->comm, cid); + pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d, handle 0x%x\n", + __func__, current->comm, cid, invoke->handle); goto bail; } } @@ -2204,7 +2214,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); - ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL; + ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0); ioctl.inv.pra = ra; ioctl.fds = NULL; @@ -2299,7 +2309,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ra[5].buf.len = sizeof(inbuf.siglen); fds[5] = 0; - ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL; + ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0); if (uproc->attrs) ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0); @@ -2385,7 +2395,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ra[2].buf.pv = (void *)pages; ra[2].buf.len = sizeof(*pages); fds[2] = 0; - ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL; + ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0); ioctl.inv.pra = ra; @@ -2421,6 +2431,119 @@ static int fastrpc_init_process(struct fastrpc_file *fl, return err; } +static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl, + uint32_t *dsp_attr, uint32_t dsp_attr_size, + uint32_t domain) +{ + int err = 0, dsp_cap_buff_size, dsp_support = 0; + struct fastrpc_ioctl_invoke_crc ioctl; + remote_arg_t ra[2]; + struct fastrpc_apps *me = &gfa; + + // Querying device about DSP support + switch (domain) { + case ADSP_DOMAIN_ID: + case SDSP_DOMAIN_ID: + case CDSP_DOMAIN_ID: + if (me->channel[domain].issubsystemup) + dsp_support = 1; + break; + case MDSP_DOMAIN_ID: + //Modem not supported for fastRPC + break; + default: + dsp_support = 0; + break; + } + dsp_attr[0] = dsp_support; + + if (dsp_support == 0) { + err = -ENOTCONN; + goto bail; + } + + err = fastrpc_channel_open(fl); + if (err) + goto bail; + + dsp_cap_buff_size = dsp_attr_size - sizeof(uint32_t); + ra[0].buf.pv = (void *)&dsp_cap_buff_size; + ra[0].buf.len = sizeof(dsp_cap_buff_size); + ra[1].buf.pv = (void *)(&dsp_attr[1]); + ra[1].buf.len = dsp_cap_buff_size * sizeof(uint32_t); + ioctl.inv.handle = FASTRPC_STATIC_HANDLE_DSP_UTILITIES; + ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 1); + ioctl.inv.pra = ra; + ioctl.fds = NULL; + ioctl.attrs = NULL; + ioctl.crc = NULL; + fl->pd = 1; + + err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl); +bail: + + if (err) + pr_err("adsprpc: %s: %s: could not obtain dsp information, err val 0x%x\n", + current->comm, __func__, err); + return err; +} + +static int fastrpc_get_info_from_kernel( + struct fastrpc_ioctl_dsp_capabilities *dsp_cap, + struct fastrpc_file *fl) +{ + int err = 0; + uint32_t domain_support; + uint32_t domain = dsp_cap->domain; + + if (!gcinfo[domain].dsp_cap_kernel.is_cached) { + /* + * Information not on kernel, query device for information + * and cache on kernel + */ + err = fastrpc_get_info_from_dsp(fl, dsp_cap->dsp_attributes, + sizeof(dsp_cap->dsp_attributes), + domain); + if (err) + goto bail; + + domain_support = dsp_cap->dsp_attributes[0]; + switch (domain_support) { + case 0: + memset(dsp_cap->dsp_attributes, 0, + sizeof(dsp_cap->dsp_attributes)); + memset(&gcinfo[domain].dsp_cap_kernel.dsp_attributes, + 0, sizeof(dsp_cap->dsp_attributes)); + break; + case 1: + memcpy(&gcinfo[domain].dsp_cap_kernel.dsp_attributes, + dsp_cap->dsp_attributes, + sizeof(dsp_cap->dsp_attributes)); + break; + default: + err = -1; + /* + * Reset is_cached flag to 0 so subsequent calls + * can try to query dsp again + */ + gcinfo[domain].dsp_cap_kernel.is_cached = 0; + pr_warn("adsprpc: %s: %s: returned bad domain support value %d\n", + current->comm, + __func__, + domain_support); + goto bail; + } + gcinfo[domain].dsp_cap_kernel.is_cached = 1; + } else { + // Information on Kernel, pass it to user + memcpy(dsp_cap->dsp_attributes, + &gcinfo[domain].dsp_cap_kernel.dsp_attributes, + sizeof(dsp_cap->dsp_attributes)); + } +bail: + return err; +} + static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) { int err = 0; @@ -2440,7 +2563,7 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) tgid = fl->tgid; ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); - ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL; + ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0); ioctl.inv.pra = ra; ioctl.fds = NULL; @@ -2486,7 +2609,7 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags, ra[2].buf.pv = (void *)&routargs; ra[2].buf.len = sizeof(routargs); - ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL; + ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; if (fl->apps->compat) ioctl.inv.sc = REMOTE_SCALARS_MAKE(4, 2, 1); else @@ -2547,7 +2670,7 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys, ra[1].buf.pv = (void *)&routargs; ra[1].buf.len = sizeof(routargs); - ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL; + ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; ioctl.inv.sc = REMOTE_SCALARS_MAKE(9, 1, 1); ioctl.inv.pra = ra; ioctl.fds = NULL; @@ -2609,7 +2732,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, uintptr_t raddr, ra[0].buf.pv = (void *)&inargs; ra[0].buf.len = sizeof(inargs); - ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL; + ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; if (fl->apps->compat) ioctl.inv.sc = REMOTE_SCALARS_MAKE(5, 1, 0); else @@ -3735,6 +3858,26 @@ static int fastrpc_internal_control(struct fastrpc_file *fl, return err; } +static int fastrpc_get_dsp_info(struct fastrpc_ioctl_dsp_capabilities *dsp_cap, + void *param, struct fastrpc_file *fl) +{ + int err = 0; + + K_COPY_FROM_USER(err, 0, dsp_cap, param, + sizeof(struct fastrpc_ioctl_dsp_capabilities)); + VERIFY(err, dsp_cap->domain < NUM_CHANNELS); + if (err) + goto bail; + + err = fastrpc_get_info_from_kernel(dsp_cap, fl); + if (err) + goto bail; + K_COPY_TO_USER(err, 0, param, dsp_cap, + sizeof(struct fastrpc_ioctl_dsp_capabilities)); +bail: + return err; +} + static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) { @@ -3748,6 +3891,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, struct fastrpc_ioctl_init_attrs init; struct fastrpc_ioctl_perf perf; struct fastrpc_ioctl_control cp; + struct fastrpc_ioctl_dsp_capabilities dsp_cap; } p; union { struct fastrpc_ioctl_mmap mmap; @@ -3958,7 +4102,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, if (err) goto bail; break; - + case FASTRPC_IOCTL_GET_DSP_INFO: + err = fastrpc_get_dsp_info(&p.dsp_cap, param, fl); + break; default: err = -ENOTTY; pr_info("bad ioctl: %d\n", ioctl_num); diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index 3b54243b2fee..3d72ad2340bf 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,6 +43,8 @@ _IOWR('R', 14, struct compat_fastrpc_ioctl_mmap_64) #define COMPAT_FASTRPC_IOCTL_MUNMAP_64 \ _IOWR('R', 15, struct compat_fastrpc_ioctl_munmap_64) +#define COMPAT_FASTRPC_IOCTL_GET_DSP_INFO \ + _IOWR('R', 16, struct compat_fastrpc_ioctl_dsp_capabilities) struct compat_remote_buf { compat_uptr_t pv; /* buffer pointer */ @@ -151,6 +153,11 @@ struct compat_fastrpc_ioctl_control { }; }; +struct compat_fastrpc_ioctl_dsp_capabilities { + compat_uint_t domain; /* DSP domain to query capabilities */ + compat_uint_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES]; +}; + static int compat_get_fastrpc_ioctl_invoke( struct compat_fastrpc_ioctl_invoke_crc __user *inv32, struct fastrpc_ioctl_invoke_crc __user **inva, @@ -389,6 +396,53 @@ static int compat_get_fastrpc_ioctl_init( return err; } +static int compat_put_fastrpc_ioctl_get_dsp_info( + struct compat_fastrpc_ioctl_dsp_capabilities __user *info32, + struct fastrpc_ioctl_dsp_capabilities __user *info) +{ + compat_uint_t u; + int err, ii; + + for (ii = 0, err = 0; ii < FASTRPC_MAX_DSP_ATTRIBUTES; ii++) { + err |= get_user(u, &info->dsp_attributes[ii]); + err |= put_user(u, &info32->dsp_attributes[ii]); + } + + return err; +} + + + +static int compat_fastrpc_get_dsp_info(struct file *filp, + unsigned long arg) +{ + struct compat_fastrpc_ioctl_dsp_capabilities __user *info32; + struct fastrpc_ioctl_dsp_capabilities __user *info; + compat_uint_t u; + long ret; + int err = 0; + + info32 = compat_ptr(arg); + VERIFY(err, NULL != (info = compat_alloc_user_space( + sizeof(*info)))); + if (err) + return -EFAULT; + + err = get_user(u, &info32->domain); + err |= put_user(u, &info->domain); + if (err) + return err; + + ret = filp->f_op->unlocked_ioctl(filp, + FASTRPC_IOCTL_GET_DSP_INFO, + (unsigned long)info); + if (ret) + return ret; + + err = compat_put_fastrpc_ioctl_get_dsp_info(info32, info); + return err; +} + long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -588,6 +642,8 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, err |= put_user(u, &perf32->numkeys); return err; } + case COMPAT_FASTRPC_IOCTL_GET_DSP_INFO: + return compat_fastrpc_get_dsp_info(filp, arg); default: return -ENOIOCTLCMD; } diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index 24fad7664204..067c2c101e87 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -32,6 +32,8 @@ #define FASTRPC_IOCTL_INVOKE_CRC _IOWR('R', 11, struct fastrpc_ioctl_invoke_crc) #define FASTRPC_IOCTL_CONTROL _IOWR('R', 12, struct fastrpc_ioctl_control) #define FASTRPC_IOCTL_MUNMAP_FD _IOWR('R', 13, struct fastrpc_ioctl_munmap_fd) +#define FASTRPC_IOCTL_GET_DSP_INFO \ + _IOWR('R', 16, struct fastrpc_ioctl_dsp_capabilities) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" @@ -269,6 +271,12 @@ struct fastrpc_ioctl_control { }; }; +#define FASTRPC_MAX_DSP_ATTRIBUTES (7) +struct fastrpc_ioctl_dsp_capabilities { + uint32_t domain; //! DSP domain to query capabilities + uint32_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES]; +}; + struct smq_null_invoke { uint64_t ctx; /* invoke caller context */ uint32_t handle; /* handle to invoke */ From ca2f74a9c2eae206571633ff6d665668ab479bb4 Mon Sep 17 00:00:00 2001 From: Monika Singh Date: Mon, 1 Feb 2021 17:02:57 +0530 Subject: [PATCH 04/10] crypto: Fix possible stack out-of-bound error Adding fix to check the upper limit on the length of the destination array while copying elements from source address to avoid stack out of bound error. Change-Id: I39d5768fa97f9d269cfb101a389bb771d13c7538 Signed-off-by: Monika Singh --- drivers/crypto/msm/qce50.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c index cf539f1107dc..3215b9543ff4 100644 --- a/drivers/crypto/msm/qce50.c +++ b/drivers/crypto/msm/qce50.c @@ -1,7 +1,7 @@ /* * QTI Crypto Engine driver. * - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -870,6 +870,11 @@ static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq, break; case CIPHER_ALG_3DES: if (creq->mode != QCE_MODE_ECB) { + if (ivsize > MAX_IV_LENGTH) { + pr_err("%s: error: Invalid length parameter\n", + __func__); + return -EINVAL; + } _byte_stream_to_net_words(enciv32, creq->iv, ivsize); pce = cmdlistinfo->encr_cntr_iv; pce->data = enciv32[0]; @@ -918,6 +923,11 @@ static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq, } } if (creq->mode != QCE_MODE_ECB) { + if (ivsize > MAX_IV_LENGTH) { + pr_err("%s: error: Invalid length parameter\n", + __func__); + return -EINVAL; + } if (creq->mode == QCE_MODE_XTS) _byte_stream_swap_to_net_words(enciv32, creq->iv, ivsize); From ebdc05e6e639103cc7cfd85a27184901804e0e01 Mon Sep 17 00:00:00 2001 From: Edgar Flores Date: Thu, 22 Aug 2019 18:12:10 -0700 Subject: [PATCH 05/10] msm: ADSPRPC: Fix buffer length for capability API Buffer size was being set incorrectly. Buffer length for dsp attributes was being set to 4 times its actual buffer size. This was causing stack-out-of-bounds when trying to copy back the buffer on function put_args. Fix is to set buffer length to the correct buffer size of dsp attributes. Change-Id: I755034ca503d58443fa6f14bf03c18d448b290b4 Signed-off-by: Edgar Flores --- drivers/char/adsprpc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 038d061bf7fd..41c2a3c1455c 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -2432,10 +2432,11 @@ static int fastrpc_init_process(struct fastrpc_file *fl, } static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl, - uint32_t *dsp_attr, uint32_t dsp_attr_size, + uint32_t *dsp_attr_buf, + uint32_t dsp_attr_buf_len, uint32_t domain) { - int err = 0, dsp_cap_buff_size, dsp_support = 0; + int err = 0, dsp_support = 0; struct fastrpc_ioctl_invoke_crc ioctl; remote_arg_t ra[2]; struct fastrpc_apps *me = &gfa; @@ -2455,7 +2456,7 @@ static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl, dsp_support = 0; break; } - dsp_attr[0] = dsp_support; + dsp_attr_buf[0] = dsp_support; if (dsp_support == 0) { err = -ENOTCONN; @@ -2466,11 +2467,10 @@ static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl, if (err) goto bail; - dsp_cap_buff_size = dsp_attr_size - sizeof(uint32_t); - ra[0].buf.pv = (void *)&dsp_cap_buff_size; - ra[0].buf.len = sizeof(dsp_cap_buff_size); - ra[1].buf.pv = (void *)(&dsp_attr[1]); - ra[1].buf.len = dsp_cap_buff_size * sizeof(uint32_t); + ra[0].buf.pv = (void *)&dsp_attr_buf_len; + ra[0].buf.len = sizeof(dsp_attr_buf_len); + ra[1].buf.pv = (void *)(&dsp_attr_buf[1]); + ra[1].buf.len = dsp_attr_buf_len * sizeof(uint32_t); ioctl.inv.handle = FASTRPC_STATIC_HANDLE_DSP_UTILITIES; ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 1); ioctl.inv.pra = ra; @@ -2502,7 +2502,7 @@ static int fastrpc_get_info_from_kernel( * and cache on kernel */ err = fastrpc_get_info_from_dsp(fl, dsp_cap->dsp_attributes, - sizeof(dsp_cap->dsp_attributes), + FASTRPC_MAX_DSP_ATTRIBUTES - 1, domain); if (err) goto bail; From 0e5769b90b1979145a33aea7a5c5add43eeb1199 Mon Sep 17 00:00:00 2001 From: Rohith Kollalsi Date: Mon, 1 Mar 2021 20:46:50 +0530 Subject: [PATCH 06/10] usb: gadget: f_cdev: Fix use after free of port in f_cdev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the configfs filesystem it’s possible to manipulate kernel object by creating/deleting folders into /config path. Here port object is created by a mkdir and leads to allocate this object, while the rmdir syscall leads to free this object. If one thread does these two operations of creation and deletion of the folder and one tries to open it, it can lead to a race condition where port object can be freed by the time it is used in f_cdev_open leading to use after free error. Fix this by using embedded struct device and the refcounting mechanism built-in which increases and decreases refcount upon creation and deletion of port and port will be freed when reference count is zero ensuring that "port" object survives until the last user releases it. Change-Id: I88701ef161c9f3215631da81c3a8d4c980d12b25 Signed-off-by: Rohith Kollalsi --- drivers/usb/gadget/function/f_cdev.c | 58 ++++++++++++++-------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c index c9bd8718230f..36ace639a817 100644 --- a/drivers/usb/gadget/function/f_cdev.c +++ b/drivers/usb/gadget/function/f_cdev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2013-2021, The Linux Foundation. All rights reserved. * Linux Foundation chooses to take subject only to the GPLv2 license terms, * and distributes only under these terms. * @@ -95,7 +95,7 @@ struct cserial { struct f_cdev { struct cdev fcdev_cdev; - struct device *dev; + struct device dev; unsigned int port_num; char name[sizeof(DEVICE_NAME) + 2]; int minor; @@ -887,13 +887,16 @@ static void cser_free_inst(struct usb_function_instance *fi) opts = container_of(fi, struct f_cdev_opts, func_inst); if (opts->port) { - device_destroy(fcdev_classp, MKDEV(major, opts->port->minor)); - cdev_del(&opts->port->fcdev_cdev); + cdev_device_del(&opts->port->fcdev_cdev, &opts->port->dev); + mutex_lock(&chardev_ida_lock); + ida_simple_remove(&chardev_ida, opts->port->minor); + mutex_unlock(&chardev_ida_lock); + usb_cser_debugfs_exit(); + put_device(&opts->port->dev); } + usb_cser_chardev_deinit(); - usb_cser_debugfs_exit(); kfree(opts->func_name); - kfree(opts->port); kfree(opts); } @@ -1114,13 +1117,10 @@ int f_cdev_open(struct inode *inode, struct file *file) struct f_cdev *port; port = container_of(inode->i_cdev, struct f_cdev, fcdev_cdev); - if (!port) { - pr_err("Port is NULL.\n"); - return -EINVAL; - } - - if (port && port->port_open) { + get_device(&port->dev); + if (port->port_open) { pr_err("port is already opened.\n"); + put_device(&port->dev); return -EBUSY; } @@ -1130,6 +1130,7 @@ int f_cdev_open(struct inode *inode, struct file *file) port->is_connected); if (ret) { pr_debug("open interrupted.\n"); + put_device(&port->dev); return ret; } @@ -1149,16 +1150,12 @@ int f_cdev_release(struct inode *inode, struct file *file) struct f_cdev *port; port = file->private_data; - if (!port) { - pr_err("port is NULL.\n"); - return -EINVAL; - } - spin_lock_irqsave(&port->port_lock, flags); port->port_open = false; port->cbits_updated = false; spin_unlock_irqrestore(&port->port_lock, flags); pr_debug("port(%s)(%pK) is closed.\n", port->name, port); + put_device(&port->dev); return 0; } @@ -1727,11 +1724,17 @@ static void usb_cser_debugfs_exit(void) debugfs_remove_recursive(debugfs.debugfs_root); } +static void cdev_device_release(struct device *dev) +{ + struct f_cdev *port = container_of(dev, struct f_cdev, dev); + + pr_debug("Free cdev port(%d)\n", port->port_num); + kfree(port); +} + static struct f_cdev *f_cdev_alloc(char *func_name, int portno) { int ret; - dev_t dev; - struct device *device; struct f_cdev *port; port = kzalloc(sizeof(struct f_cdev), GFP_KERNEL); @@ -1781,27 +1784,24 @@ static struct f_cdev *f_cdev_alloc(char *func_name, int portno) /* create char device */ cdev_init(&port->fcdev_cdev, &f_cdev_fops); - dev = MKDEV(major, port->minor); - ret = cdev_add(&port->fcdev_cdev, dev, 1); + device_initialize(&port->dev); + port->dev.class = fcdev_classp; + port->dev.parent = NULL; + port->dev.release = cdev_device_release; + port->dev.devt = MKDEV(major, port->minor); + dev_set_name(&port->dev, port->name); + ret = cdev_device_add(&port->fcdev_cdev, &port->dev); if (ret) { pr_err("Failed to add cdev for port(%s)\n", port->name); goto err_cdev_add; } - device = device_create(fcdev_classp, NULL, dev, NULL, port->name); - if (IS_ERR(device)) { - ret = PTR_ERR(device); - goto err_create_dev; - } - usb_cser_debugfs_init(port); pr_info("port_name:%s (%pK) portno:(%d)\n", port->name, port, port->port_num); return port; -err_create_dev: - cdev_del(&port->fcdev_cdev); err_cdev_add: destroy_workqueue(port->fcdev_wq); err_get_ida: From f4b9985105b85e4083e6af1e8b3f780427f11016 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Sun, 22 Nov 2020 13:03:16 +0530 Subject: [PATCH 07/10] msm: ADSPRPC: Handle third party applications Reject the session when third party applications try to spawn signed PD and channel configured as secure. Change-Id: Ic450a8c7dad430dfcdc4ae7354e29e63d9fae4a3 Acked-by: Krishnaiah Tadakamalla Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 36 ++++++++++++++++++++++++++++------- drivers/char/adsprpc_shared.h | 15 +++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 41c2a3c1455c..2c32c4a2993e 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -316,6 +316,8 @@ struct fastrpc_channel_ctx { /* Indicates, if channel is restricted to secure node only */ int secure; struct fastrpc_dsp_capabilities dsp_cap_kernel; + /* Indicates whether the channel supports unsigned PD */ + bool unsigned_support; }; struct fastrpc_apps { @@ -2039,9 +2041,12 @@ static void fastrpc_init(struct fastrpc_apps *me) me->channel[i].sesscount = 0; /* All channels are secure by default except CDSP */ me->channel[i].secure = SECURE_CHANNEL; + me->channel[i].unsigned_support = false; } /* Set CDSP channel to non secure */ me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL; + /* Set CDSP channel unsigned_support to true*/ + me->channel[CDSP_DOMAIN_ID].unsigned_support = true; } static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl); @@ -2203,6 +2208,20 @@ static int fastrpc_init_process(struct fastrpc_file *fl, struct fastrpc_buf *imem = NULL; unsigned long imem_dma_attr = 0; char *proc_name = NULL; + int unsigned_request = (uproc->attrs & FASTRPC_MODE_UNSIGNED_MODULE); + int cid = fl->cid; + struct fastrpc_channel_ctx *chan = &me->channel[cid]; + + if (chan->unsigned_support && + fl->dev_minor == MINOR_NUM_DEV) { + /* Make sure third party applications */ + /* can spawn only unsigned PD when */ + /* channel configured as secure. */ + if (chan->secure && !unsigned_request) { + err = -ECONNREFUSED; + goto bail; + } + } VERIFY(err, 0 == (err = fastrpc_channel_open(fl))); if (err) @@ -3772,6 +3791,7 @@ static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info) { int err = 0; uint32_t cid; + struct fastrpc_apps *me = &gfa; VERIFY(err, fl != NULL); if (err) @@ -3779,8 +3799,10 @@ static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info) err = fastrpc_set_process_info(fl); if (err) goto bail; + cid = *info; if (fl->cid == -1) { - cid = *info; + struct fastrpc_channel_ctx *chan = &me->channel[cid]; + VERIFY(err, cid < NUM_CHANNELS); if (err) goto bail; @@ -3788,13 +3810,13 @@ static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info) if (fl->dev_minor == MINOR_NUM_DEV && fl->apps->secure_flag == true) { /* - * For non secure device node check and make sure that - * the channel allows non-secure access - * If not, bail. Session will not start. - * cid will remain -1 and client will not be able to - * invoke any other methods without failure + * If an app is trying to offload to a secure remote + * channel by opening the non-secure device node, allow + * the access if the subsystem supports unsigned + * offload. Untrusted apps will be restricted. */ - if (fl->apps->channel[cid].secure == SECURE_CHANNEL) { + if (chan->secure == SECURE_CHANNEL && + !chan->unsigned_support) { err = -EPERM; pr_err("adsprpc: GetInfo failed dev %d, cid %d, secure %d\n", fl->dev_minor, cid, diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index 067c2c101e87..6fcf826321ec 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -325,4 +325,19 @@ static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc, return (struct smq_phy_page *)(&buf[nTotal]); } +enum fastrpc_proc_attr { + /* Macro for Debug attr */ + FASTRPC_MODE_DEBUG = 1 << 0, + /* Macro for Ptrace */ + FASTRPC_MODE_PTRACE = 1 << 1, + /* Macro for CRC Check */ + FASTRPC_MODE_CRC = 1 << 2, + /* Macro for Unsigned PD */ + FASTRPC_MODE_UNSIGNED_MODULE = 1 << 3, + /* Macro for Adaptive QoS */ + FASTRPC_MODE_ADAPTIVE_QOS = 1 << 4, + /* Macro for System Process */ + FASTRPC_MODE_SYSTEM_PROCESS = 1 << 5, +}; + #endif From ff4cf34f7eb69d0a81e18db907da56289a20369a Mon Sep 17 00:00:00 2001 From: Mahesh Voorugonda Date: Tue, 11 May 2021 14:29:44 +0530 Subject: [PATCH 08/10] msm: vidc: Enable workmode 2 for RC_OFF To support 4k@60fps RC_OFF usecases, work mode 2 is required to enable video session to schedule on dual core i.e 4k@30 on each core. Change-Id: I67b0936e996e2e439e8cdc309e818e7a718d76d5 Signed-off-by: Mahesh Voorugonda --- drivers/media/platform/msm/vidc/msm_vidc_clocks.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c index 84ba012b19ed..d01c9dfd71ac 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1094,7 +1094,8 @@ int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst) if (rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR || rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR || rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR || - rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR) + rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR || + rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) pdata.video_work_mode = VIDC_WORK_MODE_2; } else { return -EINVAL; From d1e4dff47f94821f4f16d52e5a3c49a8609594ed Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Gattupalli Date: Fri, 28 May 2021 14:19:24 +0530 Subject: [PATCH 09/10] msm: ADSPRPC: Update unsigned pd support on cDSP from kernel Query for unsigned pd support on cDSP domain and update the unsigned_support flag during fastrpc_init process. Change-Id: I61f4c748ad08155f418422183acc8473a7b0e0a8 Signed-off-by: vgattupa --- drivers/char/adsprpc.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 2c32c4a2993e..6554e717561e 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -3904,6 +3904,27 @@ static int fastrpc_get_dsp_info(struct fastrpc_ioctl_dsp_capabilities *dsp_cap, return err; } +static int fastrpc_update_cdsp_support(struct fastrpc_file *fl) +{ + struct fastrpc_ioctl_dsp_capabilities *dsp_query; + struct fastrpc_apps *me = &gfa; + int err = 0; + + VERIFY(err, NULL != (dsp_query = kzalloc(sizeof(*dsp_query), + GFP_KERNEL))); + if (err) + goto bail; + dsp_query->domain = CDSP_DOMAIN_ID; + err = fastrpc_get_info_from_kernel(dsp_query, fl); + if (err) + goto bail; + if (!(dsp_query->dsp_attributes[1])) + me->channel[CDSP_DOMAIN_ID].unsigned_support = false; +bail: + kfree(dsp_query); + return err; +} + static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) { @@ -3927,6 +3948,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data; int size = 0, err = 0; uint32_t info; + static bool isQueryDone; VERIFY(err, fl != NULL); if (err) { @@ -4127,6 +4149,11 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init))); if (err) goto bail; + if ((fl->cid == CDSP_DOMAIN_ID) && !isQueryDone) { + err = fastrpc_update_cdsp_support(fl); + if (!err) + isQueryDone = true; + } break; case FASTRPC_IOCTL_GET_DSP_INFO: err = fastrpc_get_dsp_info(&p.dsp_cap, param, fl); From b909054ebdaa22f462e96e3012666474f3e1bb49 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Thu, 10 Jun 2021 13:03:44 +0530 Subject: [PATCH 10/10] msm: adsprpc: Fix race condition in internal_control Protect add and update qos request with mutex to avoid race condition when multiple threads try to add or update request simultaneously. Change-Id: Id33b81bf85246ec69c72bad59cca068e627bb21d Acked-by: Deepika Singh Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 6554e717561e..40abe945d1ce 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -416,6 +416,7 @@ struct fastrpc_file { struct mutex perf_mutex; struct pm_qos_request pm_qos_req; int qos_request; + struct mutex pm_qos_mutex; struct mutex map_mutex; struct mutex fl_map_mutex; int refcount; @@ -3256,6 +3257,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) mutex_destroy(&fl->perf_mutex); mutex_destroy(&fl->fl_map_mutex); mutex_destroy(&fl->map_mutex); + mutex_destroy(&fl->pm_qos_mutex); kfree(fl); return 0; } @@ -3757,6 +3759,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) hlist_add_head(&fl->hn, &me->drivers); spin_unlock(&me->hlock); mutex_init(&fl->perf_mutex); + mutex_init(&fl->pm_qos_mutex); return 0; } @@ -3862,12 +3865,14 @@ static int fastrpc_internal_control(struct fastrpc_file *fl, VERIFY(err, latency != 0); if (err) goto bail; + mutex_lock(&fl->pm_qos_mutex); if (!fl->qos_request) { pm_qos_add_request(&fl->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency); fl->qos_request = 1; } else pm_qos_update_request(&fl->pm_qos_req, latency); + mutex_unlock(&fl->pm_qos_mutex); break; case FASTRPC_CONTROL_SMMU: if (!me->legacy)