Loading drivers/char/adsprpc.c +60 −25 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include <linux/dma-buf.h> #include <linux/dma-mapping.h> Loading Loading @@ -156,6 +156,8 @@ (int64_t *)(perf_ptr + offset)\ : (int64_t *)NULL) : (int64_t *)NULL) #define IS_ASYNC_FASTRPC_AVAILABLE (0) static int fastrpc_pdr_notifier_cb(struct notifier_block *nb, unsigned long code, void *data); Loading Loading @@ -2709,36 +2711,62 @@ static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl, } static int fastrpc_get_info_from_kernel( struct fastrpc_ioctl_dsp_capabilities *dsp_cap, struct fastrpc_ioctl_remote_dsp_capability *dsp_cap, struct fastrpc_file *fl) { int err = 0; uint32_t domain_support; uint32_t domain = dsp_cap->domain; uint32_t async_capability = IS_ASYNC_FASTRPC_AVAILABLE; struct fastrpc_dsp_capabilities *dsp_cap_ptr; VERIFY(err, dsp_cap->domain < NUM_CHANNELS); if (!gcinfo[domain].dsp_cap_kernel.is_cached) { /* * Check if number of attribute IDs obtained from userspace * is less than the number of attribute IDs supported by * kernel */ if (dsp_cap->attribute_ID >= FASTRPC_MAX_DSP_ATTRIBUTES) { err = EOVERFLOW; dsp_cap->capability = 0; goto bail; } dsp_cap_ptr = &gcinfo[domain].dsp_cap_kernel; if (!dsp_cap_ptr->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, err = fastrpc_get_info_from_dsp(fl, dsp_cap_ptr->dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES - 1, domain); if (err) goto bail; domain_support = dsp_cap->dsp_attributes[0]; domain_support = dsp_cap_ptr->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)); memset(&dsp_cap_ptr->dsp_attributes, 0, sizeof(dsp_cap_ptr->dsp_attributes)); memset(&dsp_cap->capability, 0, sizeof(dsp_cap->capability)); break; case 1: memcpy(&gcinfo[domain].dsp_cap_kernel.dsp_attributes, dsp_cap->dsp_attributes, sizeof(dsp_cap->dsp_attributes)); async_capability = async_capability && dsp_cap_ptr->dsp_attributes[ASYNC_FASTRPC_CAP]; dsp_cap_ptr->dsp_attributes[ASYNC_FASTRPC_CAP] = async_capability; memcpy(&dsp_cap->capability, &dsp_cap_ptr->dsp_attributes[dsp_cap->attribute_ID], sizeof(dsp_cap->capability)); break; default: err = -1; Loading @@ -2746,19 +2774,19 @@ static int fastrpc_get_info_from_kernel( * Reset is_cached flag to 0 so subsequent calls * can try to query dsp again */ gcinfo[domain].dsp_cap_kernel.is_cached = 0; dsp_cap_ptr->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; dsp_cap_ptr->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)); memcpy(&dsp_cap->capability, &dsp_cap_ptr->dsp_attributes[dsp_cap->attribute_ID], sizeof(dsp_cap->capability)); } bail: return err; Loading Loading @@ -4041,13 +4069,15 @@ static int fastrpc_control(struct fastrpc_ioctl_control *cp, bail: return err; } static int fastrpc_get_dsp_info(struct fastrpc_ioctl_dsp_capabilities *dsp_cap, static int fastrpc_get_dsp_info( struct fastrpc_ioctl_remote_dsp_capability *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)); sizeof(struct fastrpc_ioctl_remote_dsp_capability)); VERIFY(err, dsp_cap->domain < NUM_CHANNELS); if (err) goto bail; Loading @@ -4055,8 +4085,13 @@ static int fastrpc_get_dsp_info(struct fastrpc_ioctl_dsp_capabilities *dsp_cap, 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)); K_COPY_TO_USER( err, 0, &((struct fastrpc_ioctl_remote_dsp_capability *) param)->capability, &dsp_cap->capability, sizeof(dsp_cap->capability)); bail: return err; } Loading @@ -4074,7 +4109,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; struct fastrpc_ioctl_remote_dsp_capability dsp_cap; } p; union { struct fastrpc_ioctl_mmap mmap; Loading drivers/char/adsprpc_compat.c +27 −18 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. */ #include <linux/compat.h> #include <linux/fs.h> Loading Loading @@ -35,7 +35,8 @@ #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) _IOWR('R', 17, \ struct compat_fastrpc_ioctl_remote_dsp_capability) struct compat_remote_buf { compat_uptr_t pv; /* buffer pointer */ Loading Loading @@ -138,9 +139,22 @@ 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]; struct compat_fastrpc_ioctl_remote_dsp_capability { /* * @param[in]: DSP domain ADSP_DOMAIN_ID, * SDSP_DOMAIN_ID, or CDSP_DOMAIN_ID */ compat_uint_t domain; /* * @param[in]: One of the DSP attributes * from enum remote_dsp_attributes */ compat_uint_t attribute_ID; /* * @param[out]: Result of the DSP * capability query based on attribute_ID */ compat_uint_t capability; }; static int compat_get_fastrpc_ioctl_invoke( Loading Loading @@ -382,19 +396,14 @@ static int compat_get_fastrpc_ioctl_init( } static int compat_put_fastrpc_ioctl_get_dsp_info( struct compat_fastrpc_ioctl_dsp_capabilities __user *info32, struct fastrpc_ioctl_dsp_capabilities __user *info) struct compat_fastrpc_ioctl_remote_dsp_capability __user *info32, struct fastrpc_ioctl_remote_dsp_capability __user *info) { compat_uint_t u, *dsp_attr, *dsp_attr_32; int err, ii; dsp_attr = info->dsp_attributes; dsp_attr_32 = info32->dsp_attributes; for (ii = 0, err = 0; ii < FASTRPC_MAX_DSP_ATTRIBUTES; ii++) { err |= get_user(u, dsp_attr++); err |= put_user(u, dsp_attr_32++); } compat_uint_t u; int err = 0; err |= get_user(u, &info->capability); err |= put_user(u, &info32->capability); return err; } Loading Loading @@ -466,8 +475,8 @@ static int compat_fastrpc_getperf(struct file *filp, 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 *info; struct compat_fastrpc_ioctl_remote_dsp_capability __user *info32; struct fastrpc_ioctl_remote_dsp_capability *info; compat_uint_t u; long ret; int err = 0; Loading drivers/char/adsprpc_shared.h +9 −6 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef ADSPRPC_SHARED_H #define ADSPRPC_SHARED_H Loading @@ -24,7 +24,7 @@ #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) _IOWR('R', 17, struct fastrpc_ioctl_remote_dsp_capability) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" Loading Loading @@ -263,10 +263,13 @@ 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]; #define FASTRPC_MAX_DSP_ATTRIBUTES (9) #define ASYNC_FASTRPC_CAP (8) struct fastrpc_ioctl_remote_dsp_capability { uint32_t domain; uint32_t attribute_ID; uint32_t capability; }; struct smq_null_invoke { Loading Loading
drivers/char/adsprpc.c +60 −25 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include <linux/dma-buf.h> #include <linux/dma-mapping.h> Loading Loading @@ -156,6 +156,8 @@ (int64_t *)(perf_ptr + offset)\ : (int64_t *)NULL) : (int64_t *)NULL) #define IS_ASYNC_FASTRPC_AVAILABLE (0) static int fastrpc_pdr_notifier_cb(struct notifier_block *nb, unsigned long code, void *data); Loading Loading @@ -2709,36 +2711,62 @@ static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl, } static int fastrpc_get_info_from_kernel( struct fastrpc_ioctl_dsp_capabilities *dsp_cap, struct fastrpc_ioctl_remote_dsp_capability *dsp_cap, struct fastrpc_file *fl) { int err = 0; uint32_t domain_support; uint32_t domain = dsp_cap->domain; uint32_t async_capability = IS_ASYNC_FASTRPC_AVAILABLE; struct fastrpc_dsp_capabilities *dsp_cap_ptr; VERIFY(err, dsp_cap->domain < NUM_CHANNELS); if (!gcinfo[domain].dsp_cap_kernel.is_cached) { /* * Check if number of attribute IDs obtained from userspace * is less than the number of attribute IDs supported by * kernel */ if (dsp_cap->attribute_ID >= FASTRPC_MAX_DSP_ATTRIBUTES) { err = EOVERFLOW; dsp_cap->capability = 0; goto bail; } dsp_cap_ptr = &gcinfo[domain].dsp_cap_kernel; if (!dsp_cap_ptr->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, err = fastrpc_get_info_from_dsp(fl, dsp_cap_ptr->dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES - 1, domain); if (err) goto bail; domain_support = dsp_cap->dsp_attributes[0]; domain_support = dsp_cap_ptr->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)); memset(&dsp_cap_ptr->dsp_attributes, 0, sizeof(dsp_cap_ptr->dsp_attributes)); memset(&dsp_cap->capability, 0, sizeof(dsp_cap->capability)); break; case 1: memcpy(&gcinfo[domain].dsp_cap_kernel.dsp_attributes, dsp_cap->dsp_attributes, sizeof(dsp_cap->dsp_attributes)); async_capability = async_capability && dsp_cap_ptr->dsp_attributes[ASYNC_FASTRPC_CAP]; dsp_cap_ptr->dsp_attributes[ASYNC_FASTRPC_CAP] = async_capability; memcpy(&dsp_cap->capability, &dsp_cap_ptr->dsp_attributes[dsp_cap->attribute_ID], sizeof(dsp_cap->capability)); break; default: err = -1; Loading @@ -2746,19 +2774,19 @@ static int fastrpc_get_info_from_kernel( * Reset is_cached flag to 0 so subsequent calls * can try to query dsp again */ gcinfo[domain].dsp_cap_kernel.is_cached = 0; dsp_cap_ptr->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; dsp_cap_ptr->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)); memcpy(&dsp_cap->capability, &dsp_cap_ptr->dsp_attributes[dsp_cap->attribute_ID], sizeof(dsp_cap->capability)); } bail: return err; Loading Loading @@ -4041,13 +4069,15 @@ static int fastrpc_control(struct fastrpc_ioctl_control *cp, bail: return err; } static int fastrpc_get_dsp_info(struct fastrpc_ioctl_dsp_capabilities *dsp_cap, static int fastrpc_get_dsp_info( struct fastrpc_ioctl_remote_dsp_capability *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)); sizeof(struct fastrpc_ioctl_remote_dsp_capability)); VERIFY(err, dsp_cap->domain < NUM_CHANNELS); if (err) goto bail; Loading @@ -4055,8 +4085,13 @@ static int fastrpc_get_dsp_info(struct fastrpc_ioctl_dsp_capabilities *dsp_cap, 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)); K_COPY_TO_USER( err, 0, &((struct fastrpc_ioctl_remote_dsp_capability *) param)->capability, &dsp_cap->capability, sizeof(dsp_cap->capability)); bail: return err; } Loading @@ -4074,7 +4109,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; struct fastrpc_ioctl_remote_dsp_capability dsp_cap; } p; union { struct fastrpc_ioctl_mmap mmap; Loading
drivers/char/adsprpc_compat.c +27 −18 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. */ #include <linux/compat.h> #include <linux/fs.h> Loading Loading @@ -35,7 +35,8 @@ #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) _IOWR('R', 17, \ struct compat_fastrpc_ioctl_remote_dsp_capability) struct compat_remote_buf { compat_uptr_t pv; /* buffer pointer */ Loading Loading @@ -138,9 +139,22 @@ 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]; struct compat_fastrpc_ioctl_remote_dsp_capability { /* * @param[in]: DSP domain ADSP_DOMAIN_ID, * SDSP_DOMAIN_ID, or CDSP_DOMAIN_ID */ compat_uint_t domain; /* * @param[in]: One of the DSP attributes * from enum remote_dsp_attributes */ compat_uint_t attribute_ID; /* * @param[out]: Result of the DSP * capability query based on attribute_ID */ compat_uint_t capability; }; static int compat_get_fastrpc_ioctl_invoke( Loading Loading @@ -382,19 +396,14 @@ static int compat_get_fastrpc_ioctl_init( } static int compat_put_fastrpc_ioctl_get_dsp_info( struct compat_fastrpc_ioctl_dsp_capabilities __user *info32, struct fastrpc_ioctl_dsp_capabilities __user *info) struct compat_fastrpc_ioctl_remote_dsp_capability __user *info32, struct fastrpc_ioctl_remote_dsp_capability __user *info) { compat_uint_t u, *dsp_attr, *dsp_attr_32; int err, ii; dsp_attr = info->dsp_attributes; dsp_attr_32 = info32->dsp_attributes; for (ii = 0, err = 0; ii < FASTRPC_MAX_DSP_ATTRIBUTES; ii++) { err |= get_user(u, dsp_attr++); err |= put_user(u, dsp_attr_32++); } compat_uint_t u; int err = 0; err |= get_user(u, &info->capability); err |= put_user(u, &info32->capability); return err; } Loading Loading @@ -466,8 +475,8 @@ static int compat_fastrpc_getperf(struct file *filp, 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 *info; struct compat_fastrpc_ioctl_remote_dsp_capability __user *info32; struct fastrpc_ioctl_remote_dsp_capability *info; compat_uint_t u; long ret; int err = 0; Loading
drivers/char/adsprpc_shared.h +9 −6 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef ADSPRPC_SHARED_H #define ADSPRPC_SHARED_H Loading @@ -24,7 +24,7 @@ #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) _IOWR('R', 17, struct fastrpc_ioctl_remote_dsp_capability) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" Loading Loading @@ -263,10 +263,13 @@ 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]; #define FASTRPC_MAX_DSP_ATTRIBUTES (9) #define ASYNC_FASTRPC_CAP (8) struct fastrpc_ioctl_remote_dsp_capability { uint32_t domain; uint32_t attribute_ID; uint32_t capability; }; struct smq_null_invoke { Loading