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/char/adsprpc.c b/drivers/char/adsprpc.c index becb445ce93c..40abe945d1ce 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,9 @@ 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; + /* Indicates whether the channel supports unsigned PD */ + bool unsigned_support; }; struct fastrpc_apps { @@ -407,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; @@ -2032,9 +2042,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); @@ -2066,10 +2079,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; } } @@ -2193,6 +2209,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) @@ -2204,7 +2234,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 +2329,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 +2415,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 +2451,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_buf, + uint32_t dsp_attr_buf_len, + uint32_t domain) +{ + int err = 0, 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_buf[0] = dsp_support; + + if (dsp_support == 0) { + err = -ENOTCONN; + goto bail; + } + + err = fastrpc_channel_open(fl); + if (err) + goto bail; + + 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; + 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, + FASTRPC_MAX_DSP_ATTRIBUTES - 1, + 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 +2583,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 +2629,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 +2690,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 +2752,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 @@ -3114,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; } @@ -3615,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; } @@ -3649,6 +3794,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) @@ -3656,8 +3802,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; @@ -3665,13 +3813,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, @@ -3717,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) @@ -3739,6 +3889,47 @@ 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 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) { @@ -3752,6 +3943,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; @@ -3761,6 +3953,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) { @@ -3961,8 +4154,15 @@ 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); 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..6fcf826321ec 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 */ @@ -317,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 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; diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c index 2c9892abe4c2..25bb82038a97 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); 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; 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 60102dc4d4f8..09b2d64358db 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; 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: