blob: 642bd4a47fd5e18c73d2e404e6b58ea0ec17d7da [file] [log] [blame]
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001/*
Jeya Rb70b4ad2021-01-25 10:28:42 -08002 * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14#include <linux/dma-buf.h>
15#include <linux/dma-mapping.h>
16#include <linux/slab.h>
17#include <linux/completion.h>
18#include <linux/pagemap.h>
19#include <linux/mm.h>
Sathish Ambley69e1ab02016-10-18 10:28:15 -070020#include <linux/sched.h>
21#include <linux/module.h>
22#include <linux/cdev.h>
23#include <linux/list.h>
24#include <linux/hash.h>
25#include <linux/msm_ion.h>
26#include <soc/qcom/secure_buffer.h>
27#include <soc/qcom/glink.h>
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +053028#include <soc/qcom/smd.h>
Sathish Ambley69e1ab02016-10-18 10:28:15 -070029#include <soc/qcom/subsystem_notif.h>
30#include <soc/qcom/subsystem_restart.h>
Tharun Kumar Merugudf860662018-01-17 19:59:50 +053031#include <soc/qcom/service-notifier.h>
32#include <soc/qcom/service-locator.h>
Sathish Ambley69e1ab02016-10-18 10:28:15 -070033#include <linux/scatterlist.h>
Sathish Ambley69e1ab02016-10-18 10:28:15 -070034#include <linux/uaccess.h>
35#include <linux/device.h>
36#include <linux/of.h>
37#include <linux/of_address.h>
38#include <linux/of_platform.h>
39#include <linux/dma-contiguous.h>
40#include <linux/cma.h>
41#include <linux/iommu.h>
42#include <linux/kref.h>
43#include <linux/sort.h>
44#include <linux/msm_dma_iommu_mapping.h>
45#include <asm/dma-iommu.h>
c_mtharue1a5ce12017-10-13 20:47:09 +053046#include <soc/qcom/scm.h>
Sathish Ambley69e1ab02016-10-18 10:28:15 -070047#include "adsprpc_compat.h"
48#include "adsprpc_shared.h"
c_mtharue1a5ce12017-10-13 20:47:09 +053049#include <soc/qcom/ramdump.h>
Sathish Ambley1ca68232017-01-19 10:32:55 -080050#include <linux/debugfs.h>
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +053051#include <linux/pm_qos.h>
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +053052#include <linux/stat.h>
53
Sathish Ambley69e1ab02016-10-18 10:28:15 -070054#define TZ_PIL_PROTECT_MEM_SUBSYS_ID 0x0C
55#define TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID 0x0D
56#define TZ_PIL_AUTH_QDSP6_PROC 1
c_mtharue1a5ce12017-10-13 20:47:09 +053057#define ADSP_MMAP_HEAP_ADDR 4
58#define ADSP_MMAP_REMOTE_HEAP_ADDR 8
Tharun Kumar Merugue073de72018-07-30 23:57:47 +053059#define ADSP_MMAP_ADD_PAGES 0x1000
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +053060#define FASTRPC_DMAHANDLE_NOMAP (16)
61
Sathish Ambley69e1ab02016-10-18 10:28:15 -070062#define FASTRPC_ENOSUCH 39
63#define VMID_SSC_Q6 5
64#define VMID_ADSP_Q6 6
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +053065#define DEBUGFS_SIZE 3072
66#define UL_SIZE 25
67#define PID_SIZE 10
Sathish Ambley69e1ab02016-10-18 10:28:15 -070068
Tharun Kumar Merugudf860662018-01-17 19:59:50 +053069#define AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME "audio_pdr_adsprpc"
70#define AUDIO_PDR_ADSP_SERVICE_NAME "avs/audio"
71
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +053072#define SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME "sensors_pdr_adsprpc"
73#define SENSORS_PDR_ADSP_SERVICE_NAME "tms/servreg"
74
Sathish Ambley69e1ab02016-10-18 10:28:15 -070075#define RPC_TIMEOUT (5 * HZ)
76#define BALIGN 128
77#define NUM_CHANNELS 4 /* adsp, mdsp, slpi, cdsp*/
78#define NUM_SESSIONS 9 /*8 compute, 1 cpz*/
Sathish Ambleybae51902017-07-03 15:00:49 -070079#define M_FDLIST (16)
80#define M_CRCLIST (64)
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +053081#define SESSION_ID_INDEX (30)
c_mtharufdac6892017-10-12 13:09:01 +053082#define FASTRPC_CTX_MAGIC (0xbeeddeed)
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +053083#define FASTRPC_CTX_MAX (256)
84#define FASTRPC_CTXID_MASK (0xFF0)
Tharun Kumar Merugud996b262018-07-18 22:28:53 +053085#define NUM_DEVICES 2 /* adsprpc-smd, adsprpc-smd-secure */
86#define MINOR_NUM_DEV 0
87#define MINOR_NUM_SECURE_DEV 1
88#define NON_SECURE_CHANNEL 0
89#define SECURE_CHANNEL 1
90
91#define ADSP_DOMAIN_ID (0)
92#define MDSP_DOMAIN_ID (1)
93#define SDSP_DOMAIN_ID (2)
94#define CDSP_DOMAIN_ID (3)
Sathish Ambley69e1ab02016-10-18 10:28:15 -070095
96#define IS_CACHE_ALIGNED(x) (((x) & ((L1_CACHE_BYTES)-1)) == 0)
97
98#define FASTRPC_LINK_STATE_DOWN (0x0)
99#define FASTRPC_LINK_STATE_UP (0x1)
100#define FASTRPC_LINK_DISCONNECTED (0x0)
101#define FASTRPC_LINK_CONNECTING (0x1)
102#define FASTRPC_LINK_CONNECTED (0x3)
103#define FASTRPC_LINK_DISCONNECTING (0x7)
c_mtharu314a4202017-11-15 22:09:17 +0530104#define FASTRPC_LINK_REMOTE_DISCONNECTING (0x8)
105#define FASTRPC_GLINK_INTENT_LEN (64)
Tharun Kumar Meruguc42c6e22018-05-29 15:50:46 +0530106#define FASTRPC_GLINK_INTENT_NUM (16)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700107
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530108#define PERF_KEYS \
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +0530109 "count:flush:map:copy:rpmsg:getargs:putargs:invalidate:invoke:tid:ptr"
110#define FASTRPC_STATIC_HANDLE_PROCESS_GROUP (1)
111#define FASTRPC_STATIC_HANDLE_DSP_UTILITIES (2)
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800112#define FASTRPC_STATIC_HANDLE_LISTENER (3)
113#define FASTRPC_STATIC_HANDLE_MAX (20)
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +0530114#define FASTRPC_LATENCY_CTRL_ENB (1)
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800115
Mohammed Nayeem Ur Rahman62f7f9c2020-04-13 11:16:19 +0530116#define MAX_SIZE_LIMIT (0x78000000)
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +0530117#define INIT_FILELEN_MAX (2*1024*1024)
118#define INIT_MEMLEN_MAX (8*1024*1024)
119
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800120#define PERF_END (void)0
121
122#define PERF(enb, cnt, ff) \
123 {\
124 struct timespec startT = {0};\
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530125 int64_t *counter = cnt;\
126 if (enb && counter) {\
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800127 getnstimeofday(&startT);\
128 } \
129 ff ;\
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530130 if (enb && counter) {\
131 *counter += getnstimediff(&startT);\
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800132 } \
133 }
134
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530135#define GET_COUNTER(perf_ptr, offset) \
136 (perf_ptr != NULL ?\
137 (((offset >= 0) && (offset < PERF_KEY_MAX)) ?\
138 (int64_t *)(perf_ptr + offset)\
139 : (int64_t *)NULL) : (int64_t *)NULL)
140
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700141static int fastrpc_glink_open(int cid);
142static void fastrpc_glink_close(void *chan, int cid);
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530143static int fastrpc_pdr_notifier_cb(struct notifier_block *nb,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530144 unsigned long code,
145 void *data);
Sathish Ambley1ca68232017-01-19 10:32:55 -0800146static struct dentry *debugfs_root;
147static struct dentry *debugfs_global_file;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700148
149static inline uint64_t buf_page_start(uint64_t buf)
150{
151 uint64_t start = (uint64_t) buf & PAGE_MASK;
152 return start;
153}
154
155static inline uint64_t buf_page_offset(uint64_t buf)
156{
157 uint64_t offset = (uint64_t) buf & (PAGE_SIZE - 1);
158 return offset;
159}
160
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530161static inline uint64_t buf_num_pages(uint64_t buf, size_t len)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700162{
163 uint64_t start = buf_page_start(buf) >> PAGE_SHIFT;
164 uint64_t end = (((uint64_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530165 uint64_t nPages = end - start + 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700166 return nPages;
167}
168
169static inline uint64_t buf_page_size(uint32_t size)
170{
171 uint64_t sz = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
172
173 return sz > PAGE_SIZE ? sz : PAGE_SIZE;
174}
175
176static inline void *uint64_to_ptr(uint64_t addr)
177{
178 void *ptr = (void *)((uintptr_t)addr);
179
180 return ptr;
181}
182
183static inline uint64_t ptr_to_uint64(void *ptr)
184{
185 uint64_t addr = (uint64_t)((uintptr_t)ptr);
186
187 return addr;
188}
189
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +0530190struct secure_vm {
191 int *vmid;
192 int *vmperm;
193 int vmcount;
194};
195
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700196struct fastrpc_file;
197
198struct fastrpc_buf {
199 struct hlist_node hn;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530200 struct hlist_node hn_rem;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700201 struct fastrpc_file *fl;
202 void *virt;
203 uint64_t phys;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530204 size_t size;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530205 unsigned long dma_attr;
206 uintptr_t raddr;
207 uint32_t flags;
208 int remote;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700209};
210
211struct fastrpc_ctx_lst;
212
213struct overlap {
214 uintptr_t start;
215 uintptr_t end;
216 int raix;
217 uintptr_t mstart;
218 uintptr_t mend;
219 uintptr_t offset;
220};
221
222struct smq_invoke_ctx {
223 struct hlist_node hn;
224 struct completion work;
225 int retval;
226 int pid;
227 int tgid;
228 remote_arg_t *lpra;
229 remote_arg64_t *rpra;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +0530230 remote_arg64_t *lrpra; /* Local copy of rpra for put_args */
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700231 int *fds;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700232 struct fastrpc_mmap **maps;
233 struct fastrpc_buf *buf;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +0530234 struct fastrpc_buf *lbuf;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530235 size_t used;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700236 struct fastrpc_file *fl;
237 uint32_t sc;
238 struct overlap *overs;
239 struct overlap **overps;
240 struct smq_msg msg;
c_mtharufdac6892017-10-12 13:09:01 +0530241 unsigned int magic;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530242 unsigned int *attrs;
243 uint32_t *crc;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +0530244 uint64_t ctxid;
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +0530245 void *handle;
246 const void *ptr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700247};
248
249struct fastrpc_ctx_lst {
250 struct hlist_head pending;
251 struct hlist_head interrupted;
252};
253
254struct fastrpc_smmu {
c_mtharue1a5ce12017-10-13 20:47:09 +0530255 struct device *dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700256 struct dma_iommu_mapping *mapping;
257 int cb;
258 int enabled;
259 int faults;
260 int secure;
261 int coherent;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530262 int sharedcb;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700263};
264
265struct fastrpc_session_ctx {
266 struct device *dev;
267 struct fastrpc_smmu smmu;
268 int used;
269};
270
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530271struct fastrpc_static_pd {
272 char *spdname;
273 struct notifier_block pdrnb;
274 struct notifier_block get_service_nb;
275 void *pdrhandle;
276 int pdrcount;
277 int prevpdrcount;
278 int ispdup;
279};
280
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700281struct fastrpc_glink_info {
282 int link_state;
283 int port_state;
284 struct glink_open_config cfg;
285 struct glink_link_info link_info;
286 void *link_notify_handle;
287};
288
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +0530289struct fastrpc_dsp_capabilities {
290 uint32_t is_cached; //! Flag if dsp attributes are cached
291 uint32_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
292};
293
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700294struct fastrpc_channel_ctx {
295 char *name;
296 char *subsys;
297 void *chan;
298 struct device *dev;
299 struct fastrpc_session_ctx session[NUM_SESSIONS];
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530300 struct fastrpc_static_pd spd[NUM_SESSIONS];
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700301 struct completion work;
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +0530302 struct completion workport;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700303 struct notifier_block nb;
304 struct kref kref;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530305 int channel;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700306 int sesscount;
307 int ssrcount;
308 void *handle;
309 int prevssrcount;
c_mtharue1a5ce12017-10-13 20:47:09 +0530310 int issubsystemup;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700311 int vmid;
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +0530312 struct secure_vm rhvm;
c_mtharue1a5ce12017-10-13 20:47:09 +0530313 int ramdumpenabled;
314 void *remoteheap_ramdump_dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700315 struct fastrpc_glink_info link;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +0530316 /* Indicates, if channel is restricted to secure node only */
317 int secure;
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +0530318 struct fastrpc_dsp_capabilities dsp_cap_kernel;
Jeya Rf4b99852020-11-22 13:03:16 +0530319 /* Indicates whether the channel supports unsigned PD */
320 bool unsigned_support;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700321};
322
323struct fastrpc_apps {
324 struct fastrpc_channel_ctx *channel;
325 struct cdev cdev;
326 struct class *class;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530327 struct mutex smd_mutex;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700328 struct smq_phy_page range;
329 struct hlist_head maps;
c_mtharue1a5ce12017-10-13 20:47:09 +0530330 uint32_t staticpd_flags;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700331 dev_t dev_no;
332 int compat;
333 struct hlist_head drivers;
334 spinlock_t hlock;
335 struct ion_client *client;
336 struct device *dev;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +0530337 unsigned int latency;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530338 bool glink;
339 bool legacy;
zhaochenfc798572018-08-17 15:32:37 +0800340 bool secure_flag;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +0530341 spinlock_t ctxlock;
342 struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX];
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700343};
344
345struct fastrpc_mmap {
346 struct hlist_node hn;
347 struct fastrpc_file *fl;
348 struct fastrpc_apps *apps;
349 int fd;
350 uint32_t flags;
351 struct dma_buf *buf;
352 struct sg_table *table;
353 struct dma_buf_attachment *attach;
354 struct ion_handle *handle;
355 uint64_t phys;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530356 size_t size;
357 uintptr_t va;
358 size_t len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700359 int refs;
360 uintptr_t raddr;
361 int uncached;
362 int secure;
363 uintptr_t attr;
Swathi K59d96fe2021-07-14 17:51:10 +0530364 bool is_filemap; /*flag to indicate map used in process init*/
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700365};
366
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530367enum fastrpc_perfkeys {
368 PERF_COUNT = 0,
369 PERF_FLUSH = 1,
370 PERF_MAP = 2,
371 PERF_COPY = 3,
372 PERF_LINK = 4,
373 PERF_GETARGS = 5,
374 PERF_PUTARGS = 6,
375 PERF_INVARGS = 7,
376 PERF_INVOKE = 8,
377 PERF_KEY_MAX = 9,
378};
379
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800380struct fastrpc_perf {
381 int64_t count;
382 int64_t flush;
383 int64_t map;
384 int64_t copy;
385 int64_t link;
386 int64_t getargs;
387 int64_t putargs;
388 int64_t invargs;
389 int64_t invoke;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530390 int64_t tid;
391 struct hlist_node hn;
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800392};
393
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700394struct fastrpc_file {
395 struct hlist_node hn;
396 spinlock_t hlock;
397 struct hlist_head maps;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530398 struct hlist_head cached_bufs;
399 struct hlist_head remote_bufs;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700400 struct fastrpc_ctx_lst clst;
401 struct fastrpc_session_ctx *sctx;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530402 struct fastrpc_buf *init_mem;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700403 struct fastrpc_session_ctx *secsctx;
404 uint32_t mode;
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800405 uint32_t profile;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +0530406 int sessionid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700407 int tgid;
408 int cid;
409 int ssrcount;
410 int pd;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530411 char *spdname;
tharun kumar9f899ea2017-07-03 17:07:03 +0530412 int file_close;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530413 int sharedcb;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700414 struct fastrpc_apps *apps;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530415 struct hlist_head perf;
Sathish Ambley1ca68232017-01-19 10:32:55 -0800416 struct dentry *debugfs_file;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530417 struct mutex perf_mutex;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +0530418 struct pm_qos_request pm_qos_req;
419 int qos_request;
Jeya R1b85ca52021-06-10 13:03:44 +0530420 struct mutex pm_qos_mutex;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +0530421 struct mutex map_mutex;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +0530422 struct mutex fl_map_mutex;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +0530423 int refcount;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +0530424 /* Identifies the device (MINOR_NUM_DEV / MINOR_NUM_SECURE_DEV) */
425 int dev_minor;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +0530426 char *debug_buf;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700427};
428
429static struct fastrpc_apps gfa;
430
431static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = {
432 {
433 .name = "adsprpc-smd",
434 .subsys = "adsp",
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530435 .channel = SMD_APPS_QDSP,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700436 .link.link_info.edge = "lpass",
437 .link.link_info.transport = "smem",
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530438 .spd = {
439 {
440 .spdname =
441 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
442 .pdrnb.notifier_call =
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530443 fastrpc_pdr_notifier_cb,
444 },
445 {
446 .spdname =
447 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME,
448 .pdrnb.notifier_call =
449 fastrpc_pdr_notifier_cb,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530450 }
451 },
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700452 },
453 {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700454 .name = "mdsprpc-smd",
455 .subsys = "modem",
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530456 .channel = SMD_APPS_MODEM,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700457 .link.link_info.edge = "mpss",
458 .link.link_info.transport = "smem",
459 },
460 {
Sathish Ambley36849af2017-02-02 09:35:55 -0800461 .name = "sdsprpc-smd",
462 .subsys = "slpi",
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530463 .channel = SMD_APPS_DSPS,
Sathish Ambley36849af2017-02-02 09:35:55 -0800464 .link.link_info.edge = "dsps",
465 .link.link_info.transport = "smem",
Sathish Ambley36849af2017-02-02 09:35:55 -0800466 },
467 {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700468 .name = "cdsprpc-smd",
469 .subsys = "cdsp",
470 .link.link_info.edge = "cdsp",
471 .link.link_info.transport = "smem",
472 },
473};
474
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +0530475static int hlosvm[1] = {VMID_HLOS};
476static int hlosvmperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
477
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800478static inline int64_t getnstimediff(struct timespec *start)
479{
480 int64_t ns;
481 struct timespec ts, b;
482
483 getnstimeofday(&ts);
484 b = timespec_sub(ts, *start);
485 ns = timespec_to_ns(&b);
486 return ns;
487}
488
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530489static inline int64_t *getperfcounter(struct fastrpc_file *fl, int key)
490{
491 int err = 0;
492 int64_t *val = NULL;
493 struct fastrpc_perf *perf = NULL, *fperf = NULL;
494 struct hlist_node *n = NULL;
495
496 VERIFY(err, !IS_ERR_OR_NULL(fl));
497 if (err)
498 goto bail;
499
500 mutex_lock(&fl->perf_mutex);
501 hlist_for_each_entry_safe(perf, n, &fl->perf, hn) {
502 if (perf->tid == current->pid) {
503 fperf = perf;
504 break;
505 }
506 }
507
508 if (IS_ERR_OR_NULL(fperf)) {
509 fperf = kzalloc(sizeof(*fperf), GFP_KERNEL);
510
511 VERIFY(err, !IS_ERR_OR_NULL(fperf));
512 if (err) {
513 mutex_unlock(&fl->perf_mutex);
514 kfree(fperf);
515 goto bail;
516 }
517
518 fperf->tid = current->pid;
519 hlist_add_head(&fperf->hn, &fl->perf);
520 }
521
522 val = ((int64_t *)fperf) + key;
523 mutex_unlock(&fl->perf_mutex);
524bail:
525 return val;
526}
527
528
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700529static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
530{
c_mtharue1a5ce12017-10-13 20:47:09 +0530531 struct fastrpc_file *fl = buf == NULL ? NULL : buf->fl;
Jeya R984a1a32021-01-18 15:38:07 +0530532 int vmid, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700533
534 if (!fl)
535 return;
536 if (cache) {
537 spin_lock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530538 hlist_add_head(&buf->hn, &fl->cached_bufs);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700539 spin_unlock(&fl->hlock);
540 return;
541 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530542 if (buf->remote) {
543 spin_lock(&fl->hlock);
544 hlist_del_init(&buf->hn_rem);
545 spin_unlock(&fl->hlock);
546 buf->remote = 0;
547 buf->raddr = 0;
548 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700549 if (!IS_ERR_OR_NULL(buf->virt)) {
550 int destVM[1] = {VMID_HLOS};
551 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
552
Jeya R984a1a32021-01-18 15:38:07 +0530553 VERIFY(err, fl->sctx != NULL);
554 if (err)
555 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700556 if (fl->sctx->smmu.cb)
557 buf->phys &= ~((uint64_t)fl->sctx->smmu.cb << 32);
558 vmid = fl->apps->channel[fl->cid].vmid;
559 if (vmid) {
560 int srcVM[2] = {VMID_HLOS, vmid};
561
562 hyp_assign_phys(buf->phys, buf_page_size(buf->size),
563 srcVM, 2, destVM, destVMperm, 1);
564 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530565 dma_free_attrs(fl->sctx->smmu.dev, buf->size, buf->virt,
566 buf->phys, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700567 }
Jeya R984a1a32021-01-18 15:38:07 +0530568bail:
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700569 kfree(buf);
570}
571
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530572static void fastrpc_cached_buf_list_free(struct fastrpc_file *fl)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700573{
574 struct fastrpc_buf *buf, *free;
575
576 do {
577 struct hlist_node *n;
578
c_mtharue1a5ce12017-10-13 20:47:09 +0530579 free = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700580 spin_lock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530581 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700582 hlist_del_init(&buf->hn);
583 free = buf;
584 break;
585 }
586 spin_unlock(&fl->hlock);
587 if (free)
588 fastrpc_buf_free(free, 0);
589 } while (free);
590}
591
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530592static void fastrpc_remote_buf_list_free(struct fastrpc_file *fl)
593{
594 struct fastrpc_buf *buf, *free;
595
596 do {
597 struct hlist_node *n;
598
599 free = NULL;
600 spin_lock(&fl->hlock);
601 hlist_for_each_entry_safe(buf, n, &fl->remote_bufs, hn_rem) {
602 free = buf;
603 break;
604 }
605 spin_unlock(&fl->hlock);
606 if (free)
607 fastrpc_buf_free(free, 0);
608 } while (free);
609}
610
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700611static void fastrpc_mmap_add(struct fastrpc_mmap *map)
612{
c_mtharue1a5ce12017-10-13 20:47:09 +0530613 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
614 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
615 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700616
c_mtharue1a5ce12017-10-13 20:47:09 +0530617 spin_lock(&me->hlock);
618 hlist_add_head(&map->hn, &me->maps);
619 spin_unlock(&me->hlock);
620 } else {
621 struct fastrpc_file *fl = map->fl;
622
c_mtharue1a5ce12017-10-13 20:47:09 +0530623 hlist_add_head(&map->hn, &fl->maps);
c_mtharue1a5ce12017-10-13 20:47:09 +0530624 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700625}
626
c_mtharue1a5ce12017-10-13 20:47:09 +0530627static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530628 uintptr_t va, size_t len, int mflags, int refs,
c_mtharue1a5ce12017-10-13 20:47:09 +0530629 struct fastrpc_mmap **ppmap)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700630{
c_mtharue1a5ce12017-10-13 20:47:09 +0530631 struct fastrpc_apps *me = &gfa;
632 struct fastrpc_mmap *match = NULL, *map = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700633 struct hlist_node *n;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530634
635 if ((va + len) < va)
636 return -EOVERFLOW;
c_mtharue1a5ce12017-10-13 20:47:09 +0530637 if (mflags == ADSP_MMAP_HEAP_ADDR ||
638 mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
639 spin_lock(&me->hlock);
640 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
641 if (va >= map->va &&
642 va + len <= map->va + map->len &&
643 map->fd == fd) {
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530644 if (refs) {
645 if (map->refs + 1 == INT_MAX) {
646 spin_unlock(&me->hlock);
647 return -ETOOMANYREFS;
648 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530649 map->refs++;
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530650 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530651 match = map;
652 break;
653 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700654 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530655 spin_unlock(&me->hlock);
656 } else {
c_mtharue1a5ce12017-10-13 20:47:09 +0530657 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
658 if (va >= map->va &&
659 va + len <= map->va + map->len &&
660 map->fd == fd) {
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530661 if (refs) {
662 if (map->refs + 1 == INT_MAX)
663 return -ETOOMANYREFS;
c_mtharue1a5ce12017-10-13 20:47:09 +0530664 map->refs++;
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530665 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530666 match = map;
667 break;
668 }
669 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700670 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700671 if (match) {
672 *ppmap = match;
673 return 0;
674 }
675 return -ENOTTY;
676}
677
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530678static int dma_alloc_memory(dma_addr_t *region_phys, void **vaddr, size_t size,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530679 unsigned long dma_attrs)
c_mtharue1a5ce12017-10-13 20:47:09 +0530680{
Jeya Re9310762020-07-29 12:10:54 +0530681 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +0530682 struct fastrpc_apps *me = &gfa;
c_mtharue1a5ce12017-10-13 20:47:09 +0530683
684 if (me->dev == NULL) {
685 pr_err("device adsprpc-mem is not initialized\n");
686 return -ENODEV;
687 }
Jeya Re9310762020-07-29 12:10:54 +0530688 VERIFY(err, size > 0 && size < MAX_SIZE_LIMIT);
689 if (err) {
690 err = -EFAULT;
691 pr_err("adsprpc: %s: invalid allocation size 0x%zx\n",
692 __func__, size);
693 return err;
694 }
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530695 *vaddr = dma_alloc_attrs(me->dev, size, region_phys, GFP_KERNEL,
Tharun Kumar Merugu48d5ff32018-04-16 19:24:16 +0530696 dma_attrs);
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530697 if (IS_ERR_OR_NULL(*vaddr)) {
698 pr_err("adsprpc: %s: %s: dma_alloc_attrs failed for size 0x%zx, returned %pK\n",
699 current->comm, __func__, size, (*vaddr));
c_mtharue1a5ce12017-10-13 20:47:09 +0530700 return -ENOMEM;
701 }
702 return 0;
703}
704
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700705static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530706 size_t len, struct fastrpc_mmap **ppmap)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700707{
c_mtharue1a5ce12017-10-13 20:47:09 +0530708 struct fastrpc_mmap *match = NULL, *map;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700709 struct hlist_node *n;
710 struct fastrpc_apps *me = &gfa;
711
712 spin_lock(&me->hlock);
713 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
Swathi K59d96fe2021-07-14 17:51:10 +0530714 if (map->refs == 1 && map->raddr == va &&
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700715 map->raddr + map->len == va + len &&
Swathi K59d96fe2021-07-14 17:51:10 +0530716 /*Remove map if not used in process initialization*/
717 !map->is_filemap) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700718 match = map;
719 hlist_del_init(&map->hn);
720 break;
721 }
722 }
723 spin_unlock(&me->hlock);
724 if (match) {
725 *ppmap = match;
726 return 0;
727 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700728 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
Swathi K59d96fe2021-07-14 17:51:10 +0530729 if (map->refs == 1 && map->raddr == va &&
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700730 map->raddr + map->len == va + len &&
Swathi K59d96fe2021-07-14 17:51:10 +0530731 /*Remove map if not used in process initialization*/
732 !map->is_filemap) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700733 match = map;
734 hlist_del_init(&map->hn);
735 break;
736 }
737 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700738 if (match) {
739 *ppmap = match;
740 return 0;
741 }
742 return -ENOTTY;
743}
744
c_mtharu7bd6a422017-10-17 18:15:37 +0530745static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700746{
c_mtharue1a5ce12017-10-13 20:47:09 +0530747 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700748 struct fastrpc_file *fl;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530749 int vmid, cid = -1, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700750 struct fastrpc_session_ctx *sess;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700751
752 if (!map)
753 return;
754 fl = map->fl;
Jeya R3dc4bc52021-02-09 02:35:41 -0800755 /* remote heap and dynamic loading memory
756 * maps expected to initialize with NULL
757 */
758 if (!fl && !(map->flags == ADSP_MMAP_HEAP_ADDR ||
759 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR))
Jeya Rb70b4ad2021-01-25 10:28:42 -0800760 return;
Jeya R3dc4bc52021-02-09 02:35:41 -0800761 if (fl && !(map->flags == ADSP_MMAP_HEAP_ADDR ||
Jeya Rccafee22020-05-26 18:17:26 +0530762 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) {
763 cid = fl->cid;
764 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
765 if (err) {
766 err = -ECHRNG;
767 pr_err("adsprpc: ERROR:%s, Invalid channel id: %d, err:%d",
768 __func__, cid, err);
769 return;
770 }
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530771 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530772 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
773 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
774 spin_lock(&me->hlock);
775 map->refs--;
776 if (!map->refs)
777 hlist_del_init(&map->hn);
778 spin_unlock(&me->hlock);
c_mtharu7bd6a422017-10-17 18:15:37 +0530779 if (map->refs > 0)
780 return;
c_mtharue1a5ce12017-10-13 20:47:09 +0530781 } else {
c_mtharue1a5ce12017-10-13 20:47:09 +0530782 map->refs--;
783 if (!map->refs)
784 hlist_del_init(&map->hn);
c_mtharu7bd6a422017-10-17 18:15:37 +0530785 if (map->refs > 0 && !flags)
786 return;
c_mtharue1a5ce12017-10-13 20:47:09 +0530787 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530788 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
789 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700790
c_mtharue1a5ce12017-10-13 20:47:09 +0530791 if (me->dev == NULL) {
792 pr_err("failed to free remote heap allocation\n");
793 return;
794 }
795 if (map->phys) {
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +0530796 unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING |
797 DMA_ATTR_NO_KERNEL_MAPPING;
Tharun Kumar Merugu48d5ff32018-04-16 19:24:16 +0530798 dma_free_attrs(me->dev, map->size, (void *)map->va,
799 (dma_addr_t)map->phys, dma_attrs);
c_mtharue1a5ce12017-10-13 20:47:09 +0530800 }
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +0530801 } else if (map->flags == FASTRPC_DMAHANDLE_NOMAP) {
802 if (!IS_ERR_OR_NULL(map->handle))
803 ion_free(fl->apps->client, map->handle);
c_mtharue1a5ce12017-10-13 20:47:09 +0530804 } else {
805 int destVM[1] = {VMID_HLOS};
806 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
807
808 if (map->secure)
809 sess = fl->secsctx;
810 else
811 sess = fl->sctx;
812
813 if (!IS_ERR_OR_NULL(map->handle))
814 ion_free(fl->apps->client, map->handle);
815 if (sess && sess->smmu.enabled) {
816 if (map->size || map->phys)
817 msm_dma_unmap_sg(sess->smmu.dev,
818 map->table->sgl,
819 map->table->nents, DMA_BIDIRECTIONAL,
820 map->buf);
821 }
822 vmid = fl->apps->channel[fl->cid].vmid;
823 if (vmid && map->phys) {
824 int srcVM[2] = {VMID_HLOS, vmid};
825
826 hyp_assign_phys(map->phys, buf_page_size(map->size),
827 srcVM, 2, destVM, destVMperm, 1);
828 }
829
830 if (!IS_ERR_OR_NULL(map->table))
831 dma_buf_unmap_attachment(map->attach, map->table,
832 DMA_BIDIRECTIONAL);
833 if (!IS_ERR_OR_NULL(map->attach))
834 dma_buf_detach(map->buf, map->attach);
835 if (!IS_ERR_OR_NULL(map->buf))
836 dma_buf_put(map->buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700837 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700838 kfree(map);
839}
840
841static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
842 struct fastrpc_session_ctx **session);
843
844static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530845 unsigned int attr, uintptr_t va, size_t len, int mflags,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700846 struct fastrpc_mmap **ppmap)
847{
c_mtharue1a5ce12017-10-13 20:47:09 +0530848 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700849 struct fastrpc_session_ctx *sess;
850 struct fastrpc_apps *apps = fl->apps;
c_mtharue1a5ce12017-10-13 20:47:09 +0530851 struct fastrpc_mmap *map = NULL;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530852 struct fastrpc_channel_ctx *chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700853 unsigned long attrs;
c_mtharuf931ff92017-11-30 19:35:30 +0530854 dma_addr_t region_phys = 0;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530855 void *region_vaddr = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700856 unsigned long flags;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530857 int err = 0, vmid, cid = -1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700858
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530859 cid = fl->cid;
860 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
861 if (err) {
862 err = -ECHRNG;
863 goto bail;
864 }
865 chan = &apps->channel[cid];
Sathish Ambleyae5ee542017-01-16 22:24:23 -0800866 if (!fastrpc_mmap_find(fl, fd, va, len, mflags, 1, ppmap))
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700867 return 0;
868 map = kzalloc(sizeof(*map), GFP_KERNEL);
869 VERIFY(err, !IS_ERR_OR_NULL(map));
870 if (err)
871 goto bail;
872 INIT_HLIST_NODE(&map->hn);
873 map->flags = mflags;
874 map->refs = 1;
875 map->fl = fl;
876 map->fd = fd;
877 map->attr = attr;
Swathi K59d96fe2021-07-14 17:51:10 +0530878 map->is_filemap = false;
c_mtharue1a5ce12017-10-13 20:47:09 +0530879 if (mflags == ADSP_MMAP_HEAP_ADDR ||
880 mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530881 unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING |
882 DMA_ATTR_NO_KERNEL_MAPPING;
883
c_mtharue1a5ce12017-10-13 20:47:09 +0530884 map->apps = me;
885 map->fl = NULL;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530886 VERIFY(err, !dma_alloc_memory(&region_phys, &region_vaddr,
887 len, dma_attrs));
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700888 if (err)
889 goto bail;
c_mtharuf931ff92017-11-30 19:35:30 +0530890 map->phys = (uintptr_t)region_phys;
c_mtharue1a5ce12017-10-13 20:47:09 +0530891 map->size = len;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530892 map->va = (uintptr_t)region_vaddr;
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +0530893 } else if (mflags == FASTRPC_DMAHANDLE_NOMAP) {
894 ion_phys_addr_t iphys;
895
896 VERIFY(err, !IS_ERR_OR_NULL(map->handle =
897 ion_import_dma_buf_fd(fl->apps->client, fd)));
898 if (err)
899 goto bail;
900
901 map->uncached = 1;
902 map->buf = NULL;
903 map->attach = NULL;
904 map->table = NULL;
905 map->va = 0;
906 map->phys = 0;
907
908 err = ion_phys(fl->apps->client, map->handle,
909 &iphys, &map->size);
910 if (err)
911 goto bail;
912 map->phys = (uint64_t)iphys;
c_mtharue1a5ce12017-10-13 20:47:09 +0530913 } else {
c_mtharu7bd6a422017-10-17 18:15:37 +0530914 if (map->attr && (map->attr & FASTRPC_ATTR_KEEP_MAP)) {
915 pr_info("adsprpc: buffer mapped with persist attr %x\n",
916 (unsigned int)map->attr);
917 map->refs = 2;
918 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530919 VERIFY(err, !IS_ERR_OR_NULL(map->handle =
920 ion_import_dma_buf_fd(fl->apps->client, fd)));
921 if (err)
922 goto bail;
923 VERIFY(err, !ion_handle_get_flags(fl->apps->client, map->handle,
924 &flags));
925 if (err)
926 goto bail;
927
c_mtharue1a5ce12017-10-13 20:47:09 +0530928 map->secure = flags & ION_FLAG_SECURE;
929 if (map->secure) {
930 if (!fl->secsctx)
931 err = fastrpc_session_alloc(chan, 1,
932 &fl->secsctx);
933 if (err)
934 goto bail;
935 }
936 if (map->secure)
937 sess = fl->secsctx;
938 else
939 sess = fl->sctx;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530940
c_mtharue1a5ce12017-10-13 20:47:09 +0530941 VERIFY(err, !IS_ERR_OR_NULL(sess));
942 if (err)
943 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530944
945 map->uncached = !ION_IS_CACHED(flags);
946 if (map->attr & FASTRPC_ATTR_NOVA && !sess->smmu.coherent)
947 map->uncached = 1;
948
c_mtharue1a5ce12017-10-13 20:47:09 +0530949 VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd)));
950 if (err)
951 goto bail;
952 VERIFY(err, !IS_ERR_OR_NULL(map->attach =
953 dma_buf_attach(map->buf, sess->smmu.dev)));
954 if (err)
955 goto bail;
956 VERIFY(err, !IS_ERR_OR_NULL(map->table =
957 dma_buf_map_attachment(map->attach,
958 DMA_BIDIRECTIONAL)));
959 if (err)
960 goto bail;
961 if (sess->smmu.enabled) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700962 attrs = DMA_ATTR_EXEC_MAPPING;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +0530963
964 if (map->attr & FASTRPC_ATTR_NON_COHERENT ||
965 (sess->smmu.coherent && map->uncached))
966 attrs |= DMA_ATTR_FORCE_NON_COHERENT;
967 else if (map->attr & FASTRPC_ATTR_COHERENT)
968 attrs |= DMA_ATTR_FORCE_COHERENT;
969
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700970 VERIFY(err, map->table->nents ==
c_mtharue1a5ce12017-10-13 20:47:09 +0530971 msm_dma_map_sg_attrs(sess->smmu.dev,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700972 map->table->sgl, map->table->nents,
973 DMA_BIDIRECTIONAL, map->buf, attrs));
c_mtharue1a5ce12017-10-13 20:47:09 +0530974 if (err)
975 goto bail;
976 } else {
977 VERIFY(err, map->table->nents == 1);
978 if (err)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700979 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +0530980 }
981 map->phys = sg_dma_address(map->table->sgl);
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530982
c_mtharue1a5ce12017-10-13 20:47:09 +0530983 if (sess->smmu.cb) {
984 map->phys += ((uint64_t)sess->smmu.cb << 32);
985 map->size = sg_dma_len(map->table->sgl);
986 } else {
987 map->size = buf_page_size(len);
988 }
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530989
Mohammed Nayeem Ur Rahman62f7f9c2020-04-13 11:16:19 +0530990 VERIFY(err, map->size >= len && map->size < MAX_SIZE_LIMIT);
991 if (err) {
992 err = -EFAULT;
993 goto bail;
994 }
995
c_mtharue1a5ce12017-10-13 20:47:09 +0530996 vmid = fl->apps->channel[fl->cid].vmid;
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530997 if (!sess->smmu.enabled && !vmid) {
998 VERIFY(err, map->phys >= me->range.addr &&
999 map->phys + map->size <=
1000 me->range.addr + me->range.size);
1001 if (err) {
1002 pr_err("adsprpc: mmap fail out of range\n");
1003 goto bail;
1004 }
1005 }
c_mtharue1a5ce12017-10-13 20:47:09 +05301006 if (vmid) {
1007 int srcVM[1] = {VMID_HLOS};
1008 int destVM[2] = {VMID_HLOS, vmid};
1009 int destVMperm[2] = {PERM_READ | PERM_WRITE,
1010 PERM_READ | PERM_WRITE | PERM_EXEC};
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001011
c_mtharue1a5ce12017-10-13 20:47:09 +05301012 VERIFY(err, !hyp_assign_phys(map->phys,
1013 buf_page_size(map->size),
1014 srcVM, 1, destVM, destVMperm, 2));
1015 if (err)
1016 goto bail;
1017 }
1018 map->va = va;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001019 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001020 map->len = len;
1021
1022 fastrpc_mmap_add(map);
1023 *ppmap = map;
1024
1025bail:
1026 if (err && map)
c_mtharu7bd6a422017-10-17 18:15:37 +05301027 fastrpc_mmap_free(map, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001028 return err;
1029}
1030
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301031static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301032 unsigned long dma_attr, uint32_t rflags,
1033 int remote, struct fastrpc_buf **obuf)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001034{
1035 int err = 0, vmid;
c_mtharue1a5ce12017-10-13 20:47:09 +05301036 struct fastrpc_buf *buf = NULL, *fr = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001037 struct hlist_node *n;
1038
Mohammed Nayeem Ur Rahman62f7f9c2020-04-13 11:16:19 +05301039 VERIFY(err, size > 0 && size < MAX_SIZE_LIMIT);
1040 if (err) {
1041 err = -EFAULT;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001042 goto bail;
Mohammed Nayeem Ur Rahman62f7f9c2020-04-13 11:16:19 +05301043 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001044
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301045 if (!remote) {
1046 /* find the smallest buffer that fits in the cache */
1047 spin_lock(&fl->hlock);
1048 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
1049 if (buf->size >= size && (!fr || fr->size > buf->size))
1050 fr = buf;
1051 }
1052 if (fr)
1053 hlist_del_init(&fr->hn);
1054 spin_unlock(&fl->hlock);
1055 if (fr) {
1056 *obuf = fr;
1057 return 0;
1058 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001059 }
c_mtharue1a5ce12017-10-13 20:47:09 +05301060 buf = NULL;
1061 VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001062 if (err)
1063 goto bail;
1064 INIT_HLIST_NODE(&buf->hn);
1065 buf->fl = fl;
c_mtharue1a5ce12017-10-13 20:47:09 +05301066 buf->virt = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001067 buf->phys = 0;
1068 buf->size = size;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301069 buf->dma_attr = dma_attr;
1070 buf->flags = rflags;
1071 buf->raddr = 0;
1072 buf->remote = 0;
Jeya R984a1a32021-01-18 15:38:07 +05301073 VERIFY(err, fl && fl->sctx != NULL);
1074 if (err) {
1075 err = -EBADR;
1076 goto bail;
1077 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301078 buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
1079 (dma_addr_t *)&buf->phys,
1080 GFP_KERNEL, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001081 if (IS_ERR_OR_NULL(buf->virt)) {
1082 /* free cache and retry */
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301083 fastrpc_cached_buf_list_free(fl);
1084 buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
1085 (dma_addr_t *)&buf->phys,
1086 GFP_KERNEL, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001087 VERIFY(err, !IS_ERR_OR_NULL(buf->virt));
1088 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301089 if (err) {
1090 err = -ENOMEM;
1091 pr_err("adsprpc: %s: %s: dma_alloc_attrs failed for size 0x%zx\n",
1092 current->comm, __func__, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001093 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301094 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001095 if (fl->sctx->smmu.cb)
1096 buf->phys += ((uint64_t)fl->sctx->smmu.cb << 32);
1097 vmid = fl->apps->channel[fl->cid].vmid;
1098 if (vmid) {
1099 int srcVM[1] = {VMID_HLOS};
1100 int destVM[2] = {VMID_HLOS, vmid};
1101 int destVMperm[2] = {PERM_READ | PERM_WRITE,
1102 PERM_READ | PERM_WRITE | PERM_EXEC};
1103
1104 VERIFY(err, !hyp_assign_phys(buf->phys, buf_page_size(size),
1105 srcVM, 1, destVM, destVMperm, 2));
1106 if (err)
1107 goto bail;
1108 }
1109
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301110 if (remote) {
1111 INIT_HLIST_NODE(&buf->hn_rem);
1112 spin_lock(&fl->hlock);
1113 hlist_add_head(&buf->hn_rem, &fl->remote_bufs);
1114 spin_unlock(&fl->hlock);
1115 buf->remote = remote;
1116 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001117 *obuf = buf;
1118 bail:
1119 if (err && buf)
1120 fastrpc_buf_free(buf, 0);
1121 return err;
1122}
1123
1124
1125static int context_restore_interrupted(struct fastrpc_file *fl,
Sathish Ambleybae51902017-07-03 15:00:49 -07001126 struct fastrpc_ioctl_invoke_crc *inv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001127 struct smq_invoke_ctx **po)
1128{
1129 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05301130 struct smq_invoke_ctx *ctx = NULL, *ictx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001131 struct hlist_node *n;
1132 struct fastrpc_ioctl_invoke *invoke = &inv->inv;
1133
1134 spin_lock(&fl->hlock);
1135 hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
1136 if (ictx->pid == current->pid) {
1137 if (invoke->sc != ictx->sc || ictx->fl != fl)
1138 err = -1;
1139 else {
1140 ctx = ictx;
1141 hlist_del_init(&ctx->hn);
1142 hlist_add_head(&ctx->hn, &fl->clst.pending);
1143 }
1144 break;
1145 }
1146 }
1147 spin_unlock(&fl->hlock);
1148 if (ctx)
1149 *po = ctx;
1150 return err;
1151}
1152
1153#define CMP(aa, bb) ((aa) == (bb) ? 0 : (aa) < (bb) ? -1 : 1)
1154static int overlap_ptr_cmp(const void *a, const void *b)
1155{
1156 struct overlap *pa = *((struct overlap **)a);
1157 struct overlap *pb = *((struct overlap **)b);
1158 /* sort with lowest starting buffer first */
1159 int st = CMP(pa->start, pb->start);
1160 /* sort with highest ending buffer first */
1161 int ed = CMP(pb->end, pa->end);
1162 return st == 0 ? ed : st;
1163}
1164
Sathish Ambley9466d672017-01-25 10:51:55 -08001165static int context_build_overlap(struct smq_invoke_ctx *ctx)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001166{
Sathish Ambley9466d672017-01-25 10:51:55 -08001167 int i, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001168 remote_arg_t *lpra = ctx->lpra;
1169 int inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
1170 int outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc);
1171 int nbufs = inbufs + outbufs;
1172 struct overlap max;
1173
1174 for (i = 0; i < nbufs; ++i) {
1175 ctx->overs[i].start = (uintptr_t)lpra[i].buf.pv;
1176 ctx->overs[i].end = ctx->overs[i].start + lpra[i].buf.len;
Sathish Ambley9466d672017-01-25 10:51:55 -08001177 if (lpra[i].buf.len) {
1178 VERIFY(err, ctx->overs[i].end > ctx->overs[i].start);
1179 if (err)
1180 goto bail;
1181 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001182 ctx->overs[i].raix = i;
1183 ctx->overps[i] = &ctx->overs[i];
1184 }
c_mtharue1a5ce12017-10-13 20:47:09 +05301185 sort(ctx->overps, nbufs, sizeof(*ctx->overps), overlap_ptr_cmp, NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001186 max.start = 0;
1187 max.end = 0;
1188 for (i = 0; i < nbufs; ++i) {
1189 if (ctx->overps[i]->start < max.end) {
1190 ctx->overps[i]->mstart = max.end;
1191 ctx->overps[i]->mend = ctx->overps[i]->end;
1192 ctx->overps[i]->offset = max.end -
1193 ctx->overps[i]->start;
1194 if (ctx->overps[i]->end > max.end) {
1195 max.end = ctx->overps[i]->end;
1196 } else {
1197 ctx->overps[i]->mend = 0;
1198 ctx->overps[i]->mstart = 0;
1199 }
1200 } else {
1201 ctx->overps[i]->mend = ctx->overps[i]->end;
1202 ctx->overps[i]->mstart = ctx->overps[i]->start;
1203 ctx->overps[i]->offset = 0;
1204 max = *ctx->overps[i];
1205 }
1206 }
Sathish Ambley9466d672017-01-25 10:51:55 -08001207bail:
1208 return err;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001209}
1210
1211#define K_COPY_FROM_USER(err, kernel, dst, src, size) \
1212 do {\
1213 if (!(kernel))\
c_mtharue1a5ce12017-10-13 20:47:09 +05301214 VERIFY(err, 0 == copy_from_user((dst),\
1215 (void const __user *)(src),\
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001216 (size)));\
1217 else\
1218 memmove((dst), (src), (size));\
1219 } while (0)
1220
1221#define K_COPY_TO_USER(err, kernel, dst, src, size) \
1222 do {\
1223 if (!(kernel))\
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301224 VERIFY(err, 0 == copy_to_user((void __user *)(dst),\
c_mtharue1a5ce12017-10-13 20:47:09 +05301225 (src), (size)));\
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001226 else\
1227 memmove((dst), (src), (size));\
1228 } while (0)
1229
1230
1231static void context_free(struct smq_invoke_ctx *ctx);
1232
1233static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
Sathish Ambleybae51902017-07-03 15:00:49 -07001234 struct fastrpc_ioctl_invoke_crc *invokefd,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001235 struct smq_invoke_ctx **po)
1236{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301237 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301238 int err = 0, bufs, ii, size = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05301239 struct smq_invoke_ctx *ctx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001240 struct fastrpc_ctx_lst *clst = &fl->clst;
1241 struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
Jeya R8fa59d62020-11-04 20:42:59 +05301242 unsigned long irq_flags = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001243
1244 bufs = REMOTE_SCALARS_LENGTH(invoke->sc);
1245 size = bufs * sizeof(*ctx->lpra) + bufs * sizeof(*ctx->maps) +
1246 sizeof(*ctx->fds) * (bufs) +
1247 sizeof(*ctx->attrs) * (bufs) +
1248 sizeof(*ctx->overs) * (bufs) +
1249 sizeof(*ctx->overps) * (bufs);
1250
c_mtharue1a5ce12017-10-13 20:47:09 +05301251 VERIFY(err, NULL != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001252 if (err)
1253 goto bail;
1254
1255 INIT_HLIST_NODE(&ctx->hn);
1256 hlist_add_fake(&ctx->hn);
1257 ctx->fl = fl;
1258 ctx->maps = (struct fastrpc_mmap **)(&ctx[1]);
1259 ctx->lpra = (remote_arg_t *)(&ctx->maps[bufs]);
1260 ctx->fds = (int *)(&ctx->lpra[bufs]);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301261 if (me->legacy) {
1262 ctx->overs = (struct overlap *)(&ctx->fds[bufs]);
1263 ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
1264 } else {
1265 ctx->attrs = (unsigned int *)(&ctx->fds[bufs]);
1266 ctx->overs = (struct overlap *)(&ctx->attrs[bufs]);
1267 ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
1268 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001269
c_mtharue1a5ce12017-10-13 20:47:09 +05301270 K_COPY_FROM_USER(err, kernel, (void *)ctx->lpra, invoke->pra,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001271 bufs * sizeof(*ctx->lpra));
1272 if (err)
1273 goto bail;
1274
1275 if (invokefd->fds) {
1276 K_COPY_FROM_USER(err, kernel, ctx->fds, invokefd->fds,
1277 bufs * sizeof(*ctx->fds));
1278 if (err)
1279 goto bail;
1280 }
1281 if (invokefd->attrs) {
1282 K_COPY_FROM_USER(err, kernel, ctx->attrs, invokefd->attrs,
1283 bufs * sizeof(*ctx->attrs));
1284 if (err)
1285 goto bail;
1286 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001287 ctx->crc = (uint32_t *)invokefd->crc;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001288 ctx->sc = invoke->sc;
Sathish Ambley9466d672017-01-25 10:51:55 -08001289 if (bufs) {
1290 VERIFY(err, 0 == context_build_overlap(ctx));
1291 if (err)
1292 goto bail;
1293 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001294 ctx->retval = -1;
1295 ctx->pid = current->pid;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301296 ctx->tgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001297 init_completion(&ctx->work);
c_mtharufdac6892017-10-12 13:09:01 +05301298 ctx->magic = FASTRPC_CTX_MAGIC;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001299
1300 spin_lock(&fl->hlock);
1301 hlist_add_head(&ctx->hn, &clst->pending);
1302 spin_unlock(&fl->hlock);
1303
Jeya R8fa59d62020-11-04 20:42:59 +05301304 spin_lock_irqsave(&me->ctxlock, irq_flags);
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301305 for (ii = 0; ii < FASTRPC_CTX_MAX; ii++) {
1306 if (!me->ctxtable[ii]) {
1307 me->ctxtable[ii] = ctx;
1308 ctx->ctxid = (ptr_to_uint64(ctx) & ~0xFFF)|(ii << 4);
1309 break;
1310 }
1311 }
Jeya R8fa59d62020-11-04 20:42:59 +05301312 spin_unlock_irqrestore(&me->ctxlock, irq_flags);
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301313 VERIFY(err, ii < FASTRPC_CTX_MAX);
1314 if (err) {
1315 pr_err("adsprpc: out of context memory\n");
1316 goto bail;
1317 }
1318
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001319 *po = ctx;
1320bail:
1321 if (ctx && err)
1322 context_free(ctx);
1323 return err;
1324}
1325
1326static void context_save_interrupted(struct smq_invoke_ctx *ctx)
1327{
1328 struct fastrpc_ctx_lst *clst = &ctx->fl->clst;
1329
1330 spin_lock(&ctx->fl->hlock);
1331 hlist_del_init(&ctx->hn);
1332 hlist_add_head(&ctx->hn, &clst->interrupted);
1333 spin_unlock(&ctx->fl->hlock);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001334}
1335
1336static void context_free(struct smq_invoke_ctx *ctx)
1337{
1338 int i;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301339 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001340 int nbufs = REMOTE_SCALARS_INBUFS(ctx->sc) +
1341 REMOTE_SCALARS_OUTBUFS(ctx->sc);
Jeya R8fa59d62020-11-04 20:42:59 +05301342 unsigned long irq_flags = 0;
1343 void *handle = NULL;
1344 const void *ptr = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001345 spin_lock(&ctx->fl->hlock);
1346 hlist_del_init(&ctx->hn);
1347 spin_unlock(&ctx->fl->hlock);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301348 mutex_lock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001349 for (i = 0; i < nbufs; ++i)
c_mtharu7bd6a422017-10-17 18:15:37 +05301350 fastrpc_mmap_free(ctx->maps[i], 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301351
1352 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001353 fastrpc_buf_free(ctx->buf, 1);
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301354 fastrpc_buf_free(ctx->lbuf, 1);
c_mtharufdac6892017-10-12 13:09:01 +05301355 ctx->magic = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301356 ctx->ctxid = 0;
1357
Jeya R8fa59d62020-11-04 20:42:59 +05301358 spin_lock_irqsave(&me->ctxlock, irq_flags);
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301359 for (i = 0; i < FASTRPC_CTX_MAX; i++) {
1360 if (me->ctxtable[i] == ctx) {
Jeya R8fa59d62020-11-04 20:42:59 +05301361 handle = me->ctxtable[i]->handle;
1362 ptr = me->ctxtable[i]->ptr;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301363 me->ctxtable[i] = NULL;
1364 break;
1365 }
1366 }
Jeya R8fa59d62020-11-04 20:42:59 +05301367 spin_unlock_irqrestore(&me->ctxlock, irq_flags);
1368 if (handle) {
1369 glink_rx_done(handle, ptr, true);
1370 handle = NULL;
1371 }
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301372
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001373 kfree(ctx);
1374}
1375
1376static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
1377{
1378 ctx->retval = retval;
1379 complete(&ctx->work);
1380}
1381
1382
1383static void fastrpc_notify_users(struct fastrpc_file *me)
1384{
1385 struct smq_invoke_ctx *ictx;
1386 struct hlist_node *n;
1387
1388 spin_lock(&me->hlock);
1389 hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
1390 complete(&ictx->work);
1391 }
1392 hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
1393 complete(&ictx->work);
1394 }
1395 spin_unlock(&me->hlock);
1396
1397}
1398
Tharun Kumar Merugu77dd5872018-04-02 12:48:17 +05301399
1400static void fastrpc_notify_users_staticpd_pdr(struct fastrpc_file *me)
1401{
1402 struct smq_invoke_ctx *ictx;
1403 struct hlist_node *n;
1404
1405 spin_lock(&me->hlock);
1406 hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
1407 if (ictx->msg.pid)
1408 complete(&ictx->work);
1409 }
1410 hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
1411 if (ictx->msg.pid)
1412 complete(&ictx->work);
1413 }
1414 spin_unlock(&me->hlock);
1415}
1416
1417
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001418static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid)
1419{
1420 struct fastrpc_file *fl;
1421 struct hlist_node *n;
1422
1423 spin_lock(&me->hlock);
1424 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1425 if (fl->cid == cid)
1426 fastrpc_notify_users(fl);
1427 }
1428 spin_unlock(&me->hlock);
1429
1430}
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05301431
1432static void fastrpc_notify_pdr_drivers(struct fastrpc_apps *me, char *spdname)
1433{
1434 struct fastrpc_file *fl;
1435 struct hlist_node *n;
1436
1437 spin_lock(&me->hlock);
1438 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1439 if (fl->spdname && !strcmp(spdname, fl->spdname))
Tharun Kumar Merugu77dd5872018-04-02 12:48:17 +05301440 fastrpc_notify_users_staticpd_pdr(fl);
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05301441 }
1442 spin_unlock(&me->hlock);
1443
1444}
1445
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001446static void context_list_ctor(struct fastrpc_ctx_lst *me)
1447{
1448 INIT_HLIST_HEAD(&me->interrupted);
1449 INIT_HLIST_HEAD(&me->pending);
1450}
1451
1452static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
1453{
1454 struct fastrpc_ctx_lst *clst = &fl->clst;
c_mtharue1a5ce12017-10-13 20:47:09 +05301455 struct smq_invoke_ctx *ictx = NULL, *ctxfree;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001456 struct hlist_node *n;
1457
1458 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301459 ctxfree = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001460 spin_lock(&fl->hlock);
1461 hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) {
1462 hlist_del_init(&ictx->hn);
1463 ctxfree = ictx;
1464 break;
1465 }
1466 spin_unlock(&fl->hlock);
1467 if (ctxfree)
1468 context_free(ctxfree);
1469 } while (ctxfree);
1470 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301471 ctxfree = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001472 spin_lock(&fl->hlock);
1473 hlist_for_each_entry_safe(ictx, n, &clst->pending, hn) {
1474 hlist_del_init(&ictx->hn);
1475 ctxfree = ictx;
1476 break;
1477 }
1478 spin_unlock(&fl->hlock);
1479 if (ctxfree)
1480 context_free(ctxfree);
1481 } while (ctxfree);
1482}
1483
1484static int fastrpc_file_free(struct fastrpc_file *fl);
1485static void fastrpc_file_list_dtor(struct fastrpc_apps *me)
1486{
1487 struct fastrpc_file *fl, *free;
1488 struct hlist_node *n;
1489
1490 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301491 free = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001492 spin_lock(&me->hlock);
1493 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1494 hlist_del_init(&fl->hn);
1495 free = fl;
1496 break;
1497 }
1498 spin_unlock(&me->hlock);
1499 if (free)
1500 fastrpc_file_free(free);
1501 } while (free);
1502}
1503
1504static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
1505{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301506 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301507 remote_arg64_t *rpra, *lrpra;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001508 remote_arg_t *lpra = ctx->lpra;
1509 struct smq_invoke_buf *list;
1510 struct smq_phy_page *pages, *ipage;
1511 uint32_t sc = ctx->sc;
1512 int inbufs = REMOTE_SCALARS_INBUFS(sc);
1513 int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001514 int handles, bufs = inbufs + outbufs;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001515 uintptr_t args;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301516 size_t rlen = 0, copylen = 0, metalen = 0, lrpralen = 0;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001517 int i, oix;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001518 int err = 0;
1519 int mflags = 0;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001520 uint64_t *fdlist;
Sathish Ambleybae51902017-07-03 15:00:49 -07001521 uint32_t *crclist;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301522 int64_t *perf_counter = getperfcounter(ctx->fl, PERF_COUNT);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001523
1524 /* calculate size of the metadata */
c_mtharue1a5ce12017-10-13 20:47:09 +05301525 rpra = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001526 list = smq_invoke_buf_start(rpra, sc);
1527 pages = smq_phy_page_start(sc, list);
1528 ipage = pages;
1529
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301530 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001531 for (i = 0; i < bufs; ++i) {
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301532 uintptr_t buf = (uintptr_t)lpra[i].buf.pv;
1533 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001534
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301535 mutex_lock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301536 if (ctx->fds[i] && (ctx->fds[i] != -1)) {
1537 unsigned int attrs = 0;
1538
1539 if (ctx->attrs)
1540 attrs = ctx->attrs[i];
1541
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001542 fastrpc_mmap_create(ctx->fl, ctx->fds[i],
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301543 attrs, buf, len,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001544 mflags, &ctx->maps[i]);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301545 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301546 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001547 ipage += 1;
1548 }
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301549 PERF_END);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001550 handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301551 mutex_lock(&ctx->fl->fl_map_mutex);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001552 for (i = bufs; i < bufs + handles; i++) {
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +05301553 int dmaflags = 0;
1554
1555 if (ctx->attrs && (ctx->attrs[i] & FASTRPC_ATTR_NOMAP))
1556 dmaflags = FASTRPC_DMAHANDLE_NOMAP;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001557 VERIFY(err, !fastrpc_mmap_create(ctx->fl, ctx->fds[i],
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +05301558 FASTRPC_ATTR_NOVA, 0, 0, dmaflags, &ctx->maps[i]));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301559 if (err) {
1560 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001561 goto bail;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301562 }
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001563 ipage += 1;
1564 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301565 mutex_unlock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301566 if (!me->legacy) {
1567 metalen = copylen = (size_t)&ipage[0] +
1568 (sizeof(uint64_t) * M_FDLIST) +
1569 (sizeof(uint32_t) * M_CRCLIST);
1570 } else {
1571 metalen = copylen = (size_t)&ipage[0];
1572 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001573
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301574 /* allocate new local rpra buffer */
1575 lrpralen = (size_t)&list[0];
1576 if (lrpralen) {
1577 err = fastrpc_buf_alloc(ctx->fl, lrpralen, 0, 0, 0, &ctx->lbuf);
1578 if (err)
1579 goto bail;
1580 }
1581 if (ctx->lbuf->virt)
1582 memset(ctx->lbuf->virt, 0, lrpralen);
1583
1584 lrpra = ctx->lbuf->virt;
1585 ctx->lrpra = lrpra;
1586
1587 /* calculate len required for copying */
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001588 for (oix = 0; oix < inbufs + outbufs; ++oix) {
1589 int i = ctx->overps[oix]->raix;
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001590 uintptr_t mstart, mend;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301591 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001592
1593 if (!len)
1594 continue;
1595 if (ctx->maps[i])
1596 continue;
1597 if (ctx->overps[oix]->offset == 0)
1598 copylen = ALIGN(copylen, BALIGN);
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001599 mstart = ctx->overps[oix]->mstart;
1600 mend = ctx->overps[oix]->mend;
1601 VERIFY(err, (mend - mstart) <= LONG_MAX);
1602 if (err)
1603 goto bail;
1604 copylen += mend - mstart;
1605 VERIFY(err, copylen >= 0);
1606 if (err)
1607 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001608 }
1609 ctx->used = copylen;
1610
1611 /* allocate new buffer */
1612 if (copylen) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301613 err = fastrpc_buf_alloc(ctx->fl, copylen, 0, 0, 0, &ctx->buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001614 if (err)
1615 goto bail;
1616 }
Tharun Kumar Merugue3361f92017-06-22 10:45:43 +05301617 if (ctx->buf->virt && metalen <= copylen)
1618 memset(ctx->buf->virt, 0, metalen);
1619
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001620 /* copy metadata */
1621 rpra = ctx->buf->virt;
1622 ctx->rpra = rpra;
1623 list = smq_invoke_buf_start(rpra, sc);
1624 pages = smq_phy_page_start(sc, list);
1625 ipage = pages;
1626 args = (uintptr_t)ctx->buf->virt + metalen;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001627 for (i = 0; i < bufs + handles; ++i) {
1628 if (lpra[i].buf.len)
1629 list[i].num = 1;
1630 else
1631 list[i].num = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001632 list[i].pgidx = ipage - pages;
1633 ipage++;
1634 }
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05301635
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001636 /* map ion buffers */
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301637 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP),
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301638 for (i = 0; rpra && lrpra && i < inbufs + outbufs; ++i) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001639 struct fastrpc_mmap *map = ctx->maps[i];
1640 uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301641 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001642
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301643 rpra[i].buf.pv = lrpra[i].buf.pv = 0;
1644 rpra[i].buf.len = lrpra[i].buf.len = len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001645 if (!len)
1646 continue;
1647 if (map) {
1648 struct vm_area_struct *vma;
1649 uintptr_t offset;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301650 uint64_t num = buf_num_pages(buf, len);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001651 int idx = list[i].pgidx;
1652
1653 if (map->attr & FASTRPC_ATTR_NOVA) {
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001654 offset = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001655 } else {
1656 down_read(&current->mm->mmap_sem);
1657 VERIFY(err, NULL != (vma = find_vma(current->mm,
1658 map->va)));
1659 if (err) {
1660 up_read(&current->mm->mmap_sem);
1661 goto bail;
1662 }
1663 offset = buf_page_start(buf) - vma->vm_start;
1664 up_read(&current->mm->mmap_sem);
1665 VERIFY(err, offset < (uintptr_t)map->size);
1666 if (err)
1667 goto bail;
1668 }
1669 pages[idx].addr = map->phys + offset;
1670 pages[idx].size = num << PAGE_SHIFT;
1671 }
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301672 rpra[i].buf.pv = lrpra[i].buf.pv = buf;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001673 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001674 PERF_END);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001675 for (i = bufs; i < bufs + handles; ++i) {
1676 struct fastrpc_mmap *map = ctx->maps[i];
Jeya R4c7abf22020-07-23 16:00:50 +05301677 if (map) {
1678 pages[i].addr = map->phys;
1679 pages[i].size = map->size;
1680 }
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001681 }
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301682 if (!me->legacy) {
1683 fdlist = (uint64_t *)&pages[bufs + handles];
1684 for (i = 0; i < M_FDLIST; i++)
1685 fdlist[i] = 0;
1686 crclist = (uint32_t *)&fdlist[M_FDLIST];
1687 memset(crclist, 0, sizeof(uint32_t)*M_CRCLIST);
1688 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001689
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001690 /* copy non ion buffers */
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301691 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_COPY),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001692 rlen = copylen - metalen;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301693 for (oix = 0; rpra && lrpra && oix < inbufs + outbufs; ++oix) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001694 int i = ctx->overps[oix]->raix;
1695 struct fastrpc_mmap *map = ctx->maps[i];
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301696 size_t mlen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001697 uint64_t buf;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301698 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001699
1700 if (!len)
1701 continue;
1702 if (map)
1703 continue;
1704 if (ctx->overps[oix]->offset == 0) {
1705 rlen -= ALIGN(args, BALIGN) - args;
1706 args = ALIGN(args, BALIGN);
1707 }
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001708 mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001709 VERIFY(err, rlen >= mlen);
1710 if (err)
1711 goto bail;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301712 rpra[i].buf.pv = lrpra[i].buf.pv =
1713 (args - ctx->overps[oix]->offset);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001714 pages[list[i].pgidx].addr = ctx->buf->phys -
1715 ctx->overps[oix]->offset +
1716 (copylen - rlen);
1717 pages[list[i].pgidx].addr =
1718 buf_page_start(pages[list[i].pgidx].addr);
1719 buf = rpra[i].buf.pv;
1720 pages[list[i].pgidx].size = buf_num_pages(buf, len) * PAGE_SIZE;
1721 if (i < inbufs) {
1722 K_COPY_FROM_USER(err, kernel, uint64_to_ptr(buf),
1723 lpra[i].buf.pv, len);
1724 if (err)
1725 goto bail;
1726 }
1727 args = args + mlen;
1728 rlen -= mlen;
1729 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001730 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001731
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301732 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_FLUSH),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001733 for (oix = 0; oix < inbufs + outbufs; ++oix) {
1734 int i = ctx->overps[oix]->raix;
1735 struct fastrpc_mmap *map = ctx->maps[i];
1736
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001737 if (map && map->uncached)
1738 continue;
Jeya R984a1a32021-01-18 15:38:07 +05301739 if (ctx->fl->sctx && ctx->fl->sctx->smmu.coherent &&
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301740 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1741 continue;
1742 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1743 continue;
1744
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301745 if (rpra && lrpra && rpra[i].buf.len &&
1746 ctx->overps[oix]->mstart) {
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301747 if (map && map->handle)
1748 msm_ion_do_cache_op(ctx->fl->apps->client,
1749 map->handle,
1750 uint64_to_ptr(rpra[i].buf.pv),
1751 rpra[i].buf.len,
1752 ION_IOC_CLEAN_INV_CACHES);
1753 else
1754 dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv),
1755 uint64_to_ptr(rpra[i].buf.pv
1756 + rpra[i].buf.len));
1757 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001758 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001759 PERF_END);
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301760 for (i = bufs; rpra && lrpra && i < bufs + handles; i++) {
Jeya R4c7abf22020-07-23 16:00:50 +05301761 if (ctx->fds)
1762 rpra[i].dma.fd = lrpra[i].dma.fd = ctx->fds[i];
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301763 rpra[i].dma.len = lrpra[i].dma.len = (uint32_t)lpra[i].buf.len;
1764 rpra[i].dma.offset = lrpra[i].dma.offset =
1765 (uint32_t)(uintptr_t)lpra[i].buf.pv;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001766 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001767
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001768 bail:
1769 return err;
1770}
1771
1772static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
1773 remote_arg_t *upra)
1774{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301775 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001776 uint32_t sc = ctx->sc;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001777 struct smq_invoke_buf *list;
1778 struct smq_phy_page *pages;
1779 struct fastrpc_mmap *mmap;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301780 uint64_t *fdlist = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07001781 uint32_t *crclist = NULL;
1782
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301783 remote_arg64_t *rpra = ctx->lrpra;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001784 int i, inbufs, outbufs, handles;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001785 int err = 0;
1786
1787 inbufs = REMOTE_SCALARS_INBUFS(sc);
1788 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001789 handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
1790 list = smq_invoke_buf_start(ctx->rpra, sc);
1791 pages = smq_phy_page_start(sc, list);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301792 if (!me->legacy) {
1793 fdlist = (uint64_t *)(pages + inbufs + outbufs + handles);
1794 crclist = (uint32_t *)(fdlist + M_FDLIST);
1795 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001796
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001797 for (i = inbufs; i < inbufs + outbufs; ++i) {
1798 if (!ctx->maps[i]) {
1799 K_COPY_TO_USER(err, kernel,
1800 ctx->lpra[i].buf.pv,
1801 uint64_to_ptr(rpra[i].buf.pv),
1802 rpra[i].buf.len);
1803 if (err)
1804 goto bail;
1805 } else {
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301806 mutex_lock(&ctx->fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05301807 fastrpc_mmap_free(ctx->maps[i], 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301808 mutex_unlock(&ctx->fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05301809 ctx->maps[i] = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001810 }
1811 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301812 mutex_lock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301813 if (fdlist && (inbufs + outbufs + handles)) {
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001814 for (i = 0; i < M_FDLIST; i++) {
1815 if (!fdlist[i])
1816 break;
1817 if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0,
Sathish Ambleyae5ee542017-01-16 22:24:23 -08001818 0, 0, &mmap))
c_mtharu7bd6a422017-10-17 18:15:37 +05301819 fastrpc_mmap_free(mmap, 0);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001820 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001821 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301822 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambleybae51902017-07-03 15:00:49 -07001823 if (ctx->crc && crclist && rpra)
c_mtharue1a5ce12017-10-13 20:47:09 +05301824 K_COPY_TO_USER(err, kernel, ctx->crc,
Sathish Ambleybae51902017-07-03 15:00:49 -07001825 crclist, M_CRCLIST*sizeof(uint32_t));
1826
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001827 bail:
1828 return err;
1829}
1830
1831static void inv_args_pre(struct smq_invoke_ctx *ctx)
1832{
1833 int i, inbufs, outbufs;
1834 uint32_t sc = ctx->sc;
1835 remote_arg64_t *rpra = ctx->rpra;
1836 uintptr_t end;
1837
1838 inbufs = REMOTE_SCALARS_INBUFS(sc);
1839 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
1840 for (i = inbufs; i < inbufs + outbufs; ++i) {
1841 struct fastrpc_mmap *map = ctx->maps[i];
1842
1843 if (map && map->uncached)
1844 continue;
1845 if (!rpra[i].buf.len)
1846 continue;
Jeya R984a1a32021-01-18 15:38:07 +05301847 if (ctx->fl && ctx->fl->sctx && ctx->fl->sctx->smmu.coherent &&
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301848 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1849 continue;
1850 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1851 continue;
1852
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001853 if (buf_page_start(ptr_to_uint64((void *)rpra)) ==
1854 buf_page_start(rpra[i].buf.pv))
1855 continue;
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301856 if (!IS_CACHE_ALIGNED((uintptr_t)
1857 uint64_to_ptr(rpra[i].buf.pv))) {
1858 if (map && map->handle)
1859 msm_ion_do_cache_op(ctx->fl->apps->client,
1860 map->handle,
1861 uint64_to_ptr(rpra[i].buf.pv),
1862 sizeof(uintptr_t),
1863 ION_IOC_CLEAN_INV_CACHES);
1864 else
1865 dmac_flush_range(
1866 uint64_to_ptr(rpra[i].buf.pv), (char *)
1867 uint64_to_ptr(rpra[i].buf.pv + 1));
1868 }
1869
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001870 end = (uintptr_t)uint64_to_ptr(rpra[i].buf.pv +
1871 rpra[i].buf.len);
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301872 if (!IS_CACHE_ALIGNED(end)) {
1873 if (map && map->handle)
1874 msm_ion_do_cache_op(ctx->fl->apps->client,
1875 map->handle,
1876 uint64_to_ptr(end),
1877 sizeof(uintptr_t),
1878 ION_IOC_CLEAN_INV_CACHES);
1879 else
1880 dmac_flush_range((char *)end,
1881 (char *)end + 1);
1882 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001883 }
1884}
1885
1886static void inv_args(struct smq_invoke_ctx *ctx)
1887{
1888 int i, inbufs, outbufs;
1889 uint32_t sc = ctx->sc;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301890 remote_arg64_t *rpra = ctx->lrpra;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001891
1892 inbufs = REMOTE_SCALARS_INBUFS(sc);
1893 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
1894 for (i = inbufs; i < inbufs + outbufs; ++i) {
1895 struct fastrpc_mmap *map = ctx->maps[i];
1896
1897 if (map && map->uncached)
1898 continue;
1899 if (!rpra[i].buf.len)
1900 continue;
Jeya R984a1a32021-01-18 15:38:07 +05301901 if (ctx->fl && ctx->fl->sctx && ctx->fl->sctx->smmu.coherent &&
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301902 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1903 continue;
1904 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1905 continue;
1906
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001907 if (buf_page_start(ptr_to_uint64((void *)rpra)) ==
1908 buf_page_start(rpra[i].buf.pv)) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001909 continue;
1910 }
1911 if (map && map->handle)
1912 msm_ion_do_cache_op(ctx->fl->apps->client, map->handle,
1913 (char *)uint64_to_ptr(rpra[i].buf.pv),
1914 rpra[i].buf.len, ION_IOC_INV_CACHES);
1915 else
1916 dmac_inv_range((char *)uint64_to_ptr(rpra[i].buf.pv),
1917 (char *)uint64_to_ptr(rpra[i].buf.pv
1918 + rpra[i].buf.len));
1919 }
1920
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001921}
1922
1923static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
1924 uint32_t kernel, uint32_t handle)
1925{
1926 struct smq_msg *msg = &ctx->msg;
1927 struct fastrpc_file *fl = ctx->fl;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301928 int err = 0, len, cid = -1;
1929 struct fastrpc_channel_ctx *channel_ctx = NULL;
1930
1931 cid = fl->cid;
1932 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
1933 if (err) {
1934 err = -ECHRNG;
1935 goto bail;
1936 }
1937 channel_ctx = &fl->apps->channel[fl->cid];
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001938
c_mtharue1a5ce12017-10-13 20:47:09 +05301939 VERIFY(err, NULL != channel_ctx->chan);
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301940 if (err) {
1941 err = -ECHRNG;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001942 goto bail;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301943 }
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301944 msg->pid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001945 msg->tid = current->pid;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301946 if (fl->sessionid)
1947 msg->tid |= (1 << SESSION_ID_INDEX);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001948 if (kernel)
1949 msg->pid = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301950 msg->invoke.header.ctx = ctx->ctxid | fl->pd;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001951 msg->invoke.header.handle = handle;
1952 msg->invoke.header.sc = ctx->sc;
1953 msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0;
1954 msg->invoke.page.size = buf_page_size(ctx->used);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301955 if (fl->apps->glink) {
1956 if (fl->ssrcount != channel_ctx->ssrcount) {
1957 err = -ECONNRESET;
1958 goto bail;
1959 }
1960 VERIFY(err, channel_ctx->link.port_state ==
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001961 FASTRPC_LINK_CONNECTED);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301962 if (err)
1963 goto bail;
1964 err = glink_tx(channel_ctx->chan,
1965 (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg),
1966 GLINK_TX_REQ_INTENT);
1967 } else {
1968 spin_lock(&fl->apps->hlock);
1969 len = smd_write((smd_channel_t *)
1970 channel_ctx->chan,
1971 msg, sizeof(*msg));
1972 spin_unlock(&fl->apps->hlock);
1973 VERIFY(err, len == sizeof(*msg));
1974 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001975 bail:
1976 return err;
1977}
1978
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301979static void fastrpc_smd_read_handler(int cid)
1980{
1981 struct fastrpc_apps *me = &gfa;
1982 struct smq_invoke_rsp rsp = {0};
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301983 int ret = 0, err = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301984 uint32_t index;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301985
1986 do {
1987 ret = smd_read_from_cb(me->channel[cid].chan, &rsp,
1988 sizeof(rsp));
1989 if (ret != sizeof(rsp))
1990 break;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301991
1992 index = (uint32_t)((rsp.ctx & FASTRPC_CTXID_MASK) >> 4);
1993 VERIFY(err, index < FASTRPC_CTX_MAX);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301994 if (err)
1995 goto bail;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301996
1997 VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index]));
1998 if (err)
1999 goto bail;
2000
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302001 VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp.ctx & ~3)) &&
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302002 me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC));
2003 if (err)
2004 goto bail;
2005
2006 context_notify_user(me->ctxtable[index], rsp.retval);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05302007 } while (ret == sizeof(rsp));
2008bail:
2009 if (err)
2010 pr_err("adsprpc: invalid response or context\n");
2011
2012}
2013
2014static void smd_event_handler(void *priv, unsigned int event)
2015{
2016 struct fastrpc_apps *me = &gfa;
2017 int cid = (int)(uintptr_t)priv;
2018
2019 switch (event) {
2020 case SMD_EVENT_OPEN:
2021 complete(&me->channel[cid].workport);
2022 break;
2023 case SMD_EVENT_CLOSE:
2024 fastrpc_notify_drivers(me, cid);
2025 break;
2026 case SMD_EVENT_DATA:
2027 fastrpc_smd_read_handler(cid);
2028 break;
2029 }
2030}
2031
2032
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002033static void fastrpc_init(struct fastrpc_apps *me)
2034{
2035 int i;
2036
2037 INIT_HLIST_HEAD(&me->drivers);
Tharun Kumar Merugubcd6fbf2018-01-04 17:49:34 +05302038 INIT_HLIST_HEAD(&me->maps);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002039 spin_lock_init(&me->hlock);
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302040 spin_lock_init(&me->ctxlock);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302041 mutex_init(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002042 me->channel = &gcinfo[0];
2043 for (i = 0; i < NUM_CHANNELS; i++) {
2044 init_completion(&me->channel[i].work);
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05302045 init_completion(&me->channel[i].workport);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002046 me->channel[i].sesscount = 0;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05302047 /* All channels are secure by default except CDSP */
2048 me->channel[i].secure = SECURE_CHANNEL;
Jeya Rf4b99852020-11-22 13:03:16 +05302049 me->channel[i].unsigned_support = false;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002050 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05302051 /* Set CDSP channel to non secure */
2052 me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
Jeya Rf4b99852020-11-22 13:03:16 +05302053 /* Set CDSP channel unsigned_support to true*/
2054 me->channel[CDSP_DOMAIN_ID].unsigned_support = true;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002055}
2056
2057static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl);
2058
2059static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
2060 uint32_t kernel,
Sathish Ambleybae51902017-07-03 15:00:49 -07002061 struct fastrpc_ioctl_invoke_crc *inv)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002062{
c_mtharue1a5ce12017-10-13 20:47:09 +05302063 struct smq_invoke_ctx *ctx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002064 struct fastrpc_ioctl_invoke *invoke = &inv->inv;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05302065 int err = 0, cid = -1, interrupted = 0;
Maria Yu757199c2017-09-22 16:05:49 +08002066 struct timespec invoket = {0};
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05302067 int64_t *perf_counter = NULL;
2068
2069 cid = fl->cid;
2070 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
2071 if (err) {
2072 err = -ECHRNG;
2073 goto bail;
2074 }
2075 VERIFY(err, fl->sctx != NULL);
2076 if (err) {
2077 err = -EBADR;
2078 goto bail;
2079 }
2080 perf_counter = getperfcounter(fl, PERF_COUNT);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002081
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002082 if (fl->profile)
2083 getnstimeofday(&invoket);
Tharun Kumar Merugue3edf3e2017-07-27 12:34:07 +05302084
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302085 if (!kernel) {
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302086 VERIFY(err, invoke->handle !=
2087 FASTRPC_STATIC_HANDLE_PROCESS_GROUP);
2088 VERIFY(err, invoke->handle !=
2089 FASTRPC_STATIC_HANDLE_DSP_UTILITIES);
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302090 if (err) {
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302091 pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d, handle 0x%x\n",
2092 __func__, current->comm, cid, invoke->handle);
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302093 goto bail;
2094 }
2095 }
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302096
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002097 if (!kernel) {
2098 VERIFY(err, 0 == context_restore_interrupted(fl, inv,
2099 &ctx));
2100 if (err)
2101 goto bail;
2102 if (fl->sctx->smmu.faults)
2103 err = FASTRPC_ENOSUCH;
2104 if (err)
2105 goto bail;
2106 if (ctx)
2107 goto wait;
2108 }
2109
2110 VERIFY(err, 0 == context_alloc(fl, kernel, inv, &ctx));
2111 if (err)
2112 goto bail;
2113
2114 if (REMOTE_SCALARS_LENGTH(ctx->sc)) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302115 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_GETARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002116 VERIFY(err, 0 == get_args(kernel, ctx));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002117 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002118 if (err)
2119 goto bail;
2120 }
2121
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302122 if (!fl->sctx->smmu.coherent) {
2123 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002124 inv_args_pre(ctx);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302125 PERF_END);
2126 }
2127
2128 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_LINK),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002129 VERIFY(err, 0 == fastrpc_invoke_send(ctx, kernel, invoke->handle));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002130 PERF_END);
2131
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002132 if (err)
2133 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002134 wait:
2135 if (kernel)
2136 wait_for_completion(&ctx->work);
2137 else {
2138 interrupted = wait_for_completion_interruptible(&ctx->work);
2139 VERIFY(err, 0 == (err = interrupted));
2140 if (err)
2141 goto bail;
2142 }
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302143 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
Sathish Ambleyc432b502017-06-05 12:03:42 -07002144 if (!fl->sctx->smmu.coherent)
2145 inv_args(ctx);
2146 PERF_END);
2147
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002148 VERIFY(err, 0 == (err = ctx->retval));
2149 if (err)
2150 goto bail;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002151
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302152 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_PUTARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002153 VERIFY(err, 0 == put_args(kernel, ctx, invoke->pra));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002154 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002155 if (err)
2156 goto bail;
2157 bail:
2158 if (ctx && interrupted == -ERESTARTSYS)
2159 context_save_interrupted(ctx);
2160 else if (ctx)
2161 context_free(ctx);
2162 if (fl->ssrcount != fl->apps->channel[cid].ssrcount)
2163 err = ECONNRESET;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002164
2165 if (fl->profile && !interrupted) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302166 if (invoke->handle != FASTRPC_STATIC_HANDLE_LISTENER) {
2167 int64_t *count = GET_COUNTER(perf_counter, PERF_INVOKE);
2168
2169 if (count)
2170 *count += getnstimediff(&invoket);
2171 }
2172 if (invoke->handle > FASTRPC_STATIC_HANDLE_MAX) {
2173 int64_t *count = GET_COUNTER(perf_counter, PERF_COUNT);
2174
2175 if (count)
2176 *count = *count+1;
2177 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002178 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002179 return err;
2180}
2181
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302182static int fastrpc_get_adsp_session(char *name, int *session)
2183{
2184 struct fastrpc_apps *me = &gfa;
2185 int err = 0, i;
2186
2187 for (i = 0; i < NUM_SESSIONS; i++) {
2188 if (!me->channel[0].spd[i].spdname)
2189 continue;
2190 if (!strcmp(name, me->channel[0].spd[i].spdname))
2191 break;
2192 }
2193 VERIFY(err, i < NUM_SESSIONS);
2194 if (err)
2195 goto bail;
2196 *session = i;
2197bail:
2198 return err;
2199}
2200
2201static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl);
Sathish Ambley36849af2017-02-02 09:35:55 -08002202static int fastrpc_channel_open(struct fastrpc_file *fl);
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302203static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002204static int fastrpc_init_process(struct fastrpc_file *fl,
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002205 struct fastrpc_ioctl_init_attrs *uproc)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002206{
2207 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302208 struct fastrpc_apps *me = &gfa;
Sathish Ambleybae51902017-07-03 15:00:49 -07002209 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002210 struct fastrpc_ioctl_init *init = &uproc->init;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002211 struct smq_phy_page pages[1];
c_mtharue1a5ce12017-10-13 20:47:09 +05302212 struct fastrpc_mmap *file = NULL, *mem = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302213 struct fastrpc_buf *imem = NULL;
2214 unsigned long imem_dma_attr = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302215 char *proc_name = NULL;
Jeya Rf4b99852020-11-22 13:03:16 +05302216 int unsigned_request = (uproc->attrs & FASTRPC_MODE_UNSIGNED_MODULE);
2217 int cid = fl->cid;
2218 struct fastrpc_channel_ctx *chan = &me->channel[cid];
2219
2220 if (chan->unsigned_support &&
2221 fl->dev_minor == MINOR_NUM_DEV) {
2222 /* Make sure third party applications */
2223 /* can spawn only unsigned PD when */
2224 /* channel configured as secure. */
2225 if (chan->secure && !unsigned_request) {
2226 err = -ECONNREFUSED;
2227 goto bail;
2228 }
2229 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002230
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302231 VERIFY(err, 0 == (err = fastrpc_channel_open(fl)));
Sathish Ambley36849af2017-02-02 09:35:55 -08002232 if (err)
2233 goto bail;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302234 if (init->flags == FASTRPC_INIT_ATTACH ||
2235 init->flags == FASTRPC_INIT_ATTACH_SENSORS) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002236 remote_arg_t ra[1];
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302237 int tgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002238
2239 ra[0].buf.pv = (void *)&tgid;
2240 ra[0].buf.len = sizeof(tgid);
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302241 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002242 ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
2243 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302244 ioctl.fds = NULL;
2245 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002246 ioctl.crc = NULL;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302247 if (init->flags == FASTRPC_INIT_ATTACH)
2248 fl->pd = 0;
2249 else if (init->flags == FASTRPC_INIT_ATTACH_SENSORS) {
2250 fl->spdname = SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME;
2251 fl->pd = 2;
2252 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002253 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2254 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2255 if (err)
2256 goto bail;
2257 } else if (init->flags == FASTRPC_INIT_CREATE) {
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002258 remote_arg_t ra[6];
2259 int fds[6];
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002260 int mflags = 0;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302261 int memlen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002262 struct {
2263 int pgid;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302264 unsigned int namelen;
2265 unsigned int filelen;
2266 unsigned int pageslen;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002267 int attrs;
2268 int siglen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002269 } inbuf;
2270
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302271 inbuf.pgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002272 inbuf.namelen = strlen(current->comm) + 1;
2273 inbuf.filelen = init->filelen;
2274 fl->pd = 1;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302275
Tharun Kumar Merugudf852892017-12-07 16:27:37 +05302276 VERIFY(err, access_ok(0, (void __user *)init->file,
2277 init->filelen));
2278 if (err)
2279 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002280 if (init->filelen) {
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302281 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002282 VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, 0,
2283 init->file, init->filelen, mflags, &file));
Swathi K59d96fe2021-07-14 17:51:10 +05302284 if (file)
2285 file->is_filemap = true;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302286 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002287 if (err)
2288 goto bail;
2289 }
2290 inbuf.pageslen = 1;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302291
2292 VERIFY(err, !init->mem);
2293 if (err) {
2294 err = -EINVAL;
2295 pr_err("adsprpc: %s: %s: ERROR: donated memory allocated in userspace\n",
2296 current->comm, __func__);
2297 goto bail;
2298 }
2299 memlen = ALIGN(max(1024*1024*3, (int)init->filelen * 4),
2300 1024*1024);
2301 imem_dma_attr = DMA_ATTR_EXEC_MAPPING |
2302 DMA_ATTR_NO_KERNEL_MAPPING |
2303 DMA_ATTR_FORCE_NON_COHERENT;
2304 err = fastrpc_buf_alloc(fl, memlen, imem_dma_attr, 0, 0, &imem);
Tharun Kumar Merugudf852892017-12-07 16:27:37 +05302305 if (err)
2306 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302307 fl->init_mem = imem;
2308
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002309 inbuf.pageslen = 1;
2310 ra[0].buf.pv = (void *)&inbuf;
2311 ra[0].buf.len = sizeof(inbuf);
2312 fds[0] = 0;
2313
2314 ra[1].buf.pv = (void *)current->comm;
2315 ra[1].buf.len = inbuf.namelen;
2316 fds[1] = 0;
2317
2318 ra[2].buf.pv = (void *)init->file;
2319 ra[2].buf.len = inbuf.filelen;
2320 fds[2] = init->filefd;
2321
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302322 pages[0].addr = imem->phys;
2323 pages[0].size = imem->size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002324 ra[3].buf.pv = (void *)pages;
2325 ra[3].buf.len = 1 * sizeof(*pages);
2326 fds[3] = 0;
2327
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002328 inbuf.attrs = uproc->attrs;
2329 ra[4].buf.pv = (void *)&(inbuf.attrs);
2330 ra[4].buf.len = sizeof(inbuf.attrs);
2331 fds[4] = 0;
2332
2333 inbuf.siglen = uproc->siglen;
2334 ra[5].buf.pv = (void *)&(inbuf.siglen);
2335 ra[5].buf.len = sizeof(inbuf.siglen);
2336 fds[5] = 0;
2337
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302338 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002339 ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0);
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002340 if (uproc->attrs)
2341 ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002342 ioctl.inv.pra = ra;
2343 ioctl.fds = fds;
c_mtharue1a5ce12017-10-13 20:47:09 +05302344 ioctl.attrs = NULL;
2345 ioctl.crc = NULL;
2346 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2347 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2348 if (err)
2349 goto bail;
2350 } else if (init->flags == FASTRPC_INIT_CREATE_STATIC) {
2351 remote_arg_t ra[3];
2352 uint64_t phys = 0;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302353 size_t size = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302354 int fds[3];
2355 struct {
2356 int pgid;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302357 unsigned int namelen;
2358 unsigned int pageslen;
c_mtharue1a5ce12017-10-13 20:47:09 +05302359 } inbuf;
2360
2361 if (!init->filelen)
2362 goto bail;
2363
Jeya Rb30f0862021-04-09 13:22:31 +05302364 proc_name = kzalloc(init->filelen + 1, GFP_KERNEL);
c_mtharue1a5ce12017-10-13 20:47:09 +05302365 VERIFY(err, !IS_ERR_OR_NULL(proc_name));
2366 if (err)
2367 goto bail;
2368 VERIFY(err, 0 == copy_from_user((void *)proc_name,
2369 (void __user *)init->file, init->filelen));
2370 if (err)
2371 goto bail;
2372
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302373 fl->pd = 1;
c_mtharue1a5ce12017-10-13 20:47:09 +05302374 inbuf.pgid = current->tgid;
c_mtharu81a0aa72017-11-07 16:13:21 +05302375 inbuf.namelen = init->filelen;
c_mtharue1a5ce12017-10-13 20:47:09 +05302376 inbuf.pageslen = 0;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302377
2378 if (!strcmp(proc_name, "audiopd")) {
2379 fl->spdname = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME;
2380 VERIFY(err, !fastrpc_mmap_remove_pdr(fl));
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05302381 if (err)
2382 goto bail;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302383 }
2384
c_mtharue1a5ce12017-10-13 20:47:09 +05302385 if (!me->staticpd_flags) {
2386 inbuf.pageslen = 1;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302387 mutex_lock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302388 VERIFY(err, !fastrpc_mmap_create(fl, -1, 0, init->mem,
2389 init->memlen, ADSP_MMAP_REMOTE_HEAP_ADDR,
2390 &mem));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302391 mutex_unlock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302392 if (err)
2393 goto bail;
2394 phys = mem->phys;
2395 size = mem->size;
2396 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302397 hlosvm, 1, me->channel[fl->cid].rhvm.vmid,
2398 me->channel[fl->cid].rhvm.vmperm,
2399 me->channel[fl->cid].rhvm.vmcount));
c_mtharue1a5ce12017-10-13 20:47:09 +05302400 if (err) {
2401 pr_err("ADSPRPC: hyp_assign_phys fail err %d",
2402 err);
2403 pr_err("map->phys %llx, map->size %d\n",
2404 phys, (int)size);
2405 goto bail;
2406 }
2407 me->staticpd_flags = 1;
2408 }
2409
2410 ra[0].buf.pv = (void *)&inbuf;
2411 ra[0].buf.len = sizeof(inbuf);
2412 fds[0] = 0;
2413
2414 ra[1].buf.pv = (void *)proc_name;
2415 ra[1].buf.len = inbuf.namelen;
2416 fds[1] = 0;
2417
2418 pages[0].addr = phys;
2419 pages[0].size = size;
2420
2421 ra[2].buf.pv = (void *)pages;
2422 ra[2].buf.len = sizeof(*pages);
2423 fds[2] = 0;
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302424 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
c_mtharue1a5ce12017-10-13 20:47:09 +05302425
2426 ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
2427 ioctl.inv.pra = ra;
2428 ioctl.fds = NULL;
2429 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002430 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002431 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2432 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2433 if (err)
2434 goto bail;
2435 } else {
2436 err = -ENOTTY;
2437 }
2438bail:
c_mtharud91205a2017-11-07 16:01:06 +05302439 kfree(proc_name);
c_mtharue1a5ce12017-10-13 20:47:09 +05302440 if (err && (init->flags == FASTRPC_INIT_CREATE_STATIC))
2441 me->staticpd_flags = 0;
2442 if (mem && err) {
2443 if (mem->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
2444 hyp_assign_phys(mem->phys, (uint64_t)mem->size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302445 me->channel[fl->cid].rhvm.vmid,
2446 me->channel[fl->cid].rhvm.vmcount,
2447 hlosvm, hlosvmperm, 1);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302448 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302449 fastrpc_mmap_free(mem, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302450 mutex_unlock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302451 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302452 if (file) {
2453 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302454 fastrpc_mmap_free(file, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302455 mutex_unlock(&fl->fl_map_mutex);
2456 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002457 return err;
2458}
2459
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302460static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl,
Edgar Floresebdc05e2019-08-22 18:12:10 -07002461 uint32_t *dsp_attr_buf,
2462 uint32_t dsp_attr_buf_len,
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302463 uint32_t domain)
2464{
Edgar Floresebdc05e2019-08-22 18:12:10 -07002465 int err = 0, dsp_support = 0;
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302466 struct fastrpc_ioctl_invoke_crc ioctl;
2467 remote_arg_t ra[2];
2468 struct fastrpc_apps *me = &gfa;
2469
2470 // Querying device about DSP support
2471 switch (domain) {
2472 case ADSP_DOMAIN_ID:
2473 case SDSP_DOMAIN_ID:
2474 case CDSP_DOMAIN_ID:
2475 if (me->channel[domain].issubsystemup)
2476 dsp_support = 1;
2477 break;
2478 case MDSP_DOMAIN_ID:
2479 //Modem not supported for fastRPC
2480 break;
2481 default:
2482 dsp_support = 0;
2483 break;
2484 }
Edgar Floresebdc05e2019-08-22 18:12:10 -07002485 dsp_attr_buf[0] = dsp_support;
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302486
2487 if (dsp_support == 0) {
2488 err = -ENOTCONN;
2489 goto bail;
2490 }
2491
2492 err = fastrpc_channel_open(fl);
2493 if (err)
2494 goto bail;
2495
Edgar Floresebdc05e2019-08-22 18:12:10 -07002496 ra[0].buf.pv = (void *)&dsp_attr_buf_len;
2497 ra[0].buf.len = sizeof(dsp_attr_buf_len);
2498 ra[1].buf.pv = (void *)(&dsp_attr_buf[1]);
2499 ra[1].buf.len = dsp_attr_buf_len * sizeof(uint32_t);
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302500 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_DSP_UTILITIES;
2501 ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 1);
2502 ioctl.inv.pra = ra;
2503 ioctl.fds = NULL;
2504 ioctl.attrs = NULL;
2505 ioctl.crc = NULL;
2506 fl->pd = 1;
2507
2508 err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl);
2509bail:
2510
2511 if (err)
2512 pr_err("adsprpc: %s: %s: could not obtain dsp information, err val 0x%x\n",
2513 current->comm, __func__, err);
2514 return err;
2515}
2516
2517static int fastrpc_get_info_from_kernel(
2518 struct fastrpc_ioctl_dsp_capabilities *dsp_cap,
2519 struct fastrpc_file *fl)
2520{
2521 int err = 0;
2522 uint32_t domain_support;
2523 uint32_t domain = dsp_cap->domain;
2524
2525 if (!gcinfo[domain].dsp_cap_kernel.is_cached) {
2526 /*
2527 * Information not on kernel, query device for information
2528 * and cache on kernel
2529 */
2530 err = fastrpc_get_info_from_dsp(fl, dsp_cap->dsp_attributes,
Edgar Floresebdc05e2019-08-22 18:12:10 -07002531 FASTRPC_MAX_DSP_ATTRIBUTES - 1,
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302532 domain);
2533 if (err)
2534 goto bail;
2535
2536 domain_support = dsp_cap->dsp_attributes[0];
2537 switch (domain_support) {
2538 case 0:
2539 memset(dsp_cap->dsp_attributes, 0,
2540 sizeof(dsp_cap->dsp_attributes));
2541 memset(&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
2542 0, sizeof(dsp_cap->dsp_attributes));
2543 break;
2544 case 1:
2545 memcpy(&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
2546 dsp_cap->dsp_attributes,
2547 sizeof(dsp_cap->dsp_attributes));
2548 break;
2549 default:
2550 err = -1;
2551 /*
2552 * Reset is_cached flag to 0 so subsequent calls
2553 * can try to query dsp again
2554 */
2555 gcinfo[domain].dsp_cap_kernel.is_cached = 0;
2556 pr_warn("adsprpc: %s: %s: returned bad domain support value %d\n",
2557 current->comm,
2558 __func__,
2559 domain_support);
2560 goto bail;
2561 }
2562 gcinfo[domain].dsp_cap_kernel.is_cached = 1;
2563 } else {
2564 // Information on Kernel, pass it to user
2565 memcpy(dsp_cap->dsp_attributes,
2566 &gcinfo[domain].dsp_cap_kernel.dsp_attributes,
2567 sizeof(dsp_cap->dsp_attributes));
2568 }
2569bail:
2570 return err;
2571}
2572
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002573static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
2574{
2575 int err = 0;
Sathish Ambleybae51902017-07-03 15:00:49 -07002576 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002577 remote_arg_t ra[1];
2578 int tgid = 0;
2579
Sathish Ambley36849af2017-02-02 09:35:55 -08002580 VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS);
2581 if (err)
2582 goto bail;
Jeya R984a1a32021-01-18 15:38:07 +05302583 VERIFY(err, fl->sctx != NULL);
2584 if (err)
2585 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05302586 VERIFY(err, fl->apps->channel[fl->cid].chan != NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002587 if (err)
2588 goto bail;
2589 tgid = fl->tgid;
2590 ra[0].buf.pv = (void *)&tgid;
2591 ra[0].buf.len = sizeof(tgid);
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302592 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002593 ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
2594 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302595 ioctl.fds = NULL;
2596 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002597 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002598 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2599 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2600bail:
2601 return err;
2602}
2603
2604static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302605 uintptr_t va, uint64_t phys,
2606 size_t size, uintptr_t *raddr)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002607{
Sathish Ambleybae51902017-07-03 15:00:49 -07002608 struct fastrpc_ioctl_invoke_crc ioctl;
c_mtharu63ffc012017-11-16 15:26:56 +05302609 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002610 struct smq_phy_page page;
2611 int num = 1;
2612 remote_arg_t ra[3];
2613 int err = 0;
2614 struct {
2615 int pid;
2616 uint32_t flags;
2617 uintptr_t vaddrin;
2618 int num;
2619 } inargs;
2620 struct {
2621 uintptr_t vaddrout;
2622 } routargs;
2623
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302624 inargs.pid = fl->tgid;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302625 inargs.vaddrin = (uintptr_t)va;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002626 inargs.flags = flags;
2627 inargs.num = fl->apps->compat ? num * sizeof(page) : num;
2628 ra[0].buf.pv = (void *)&inargs;
2629 ra[0].buf.len = sizeof(inargs);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302630 page.addr = phys;
2631 page.size = size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002632 ra[1].buf.pv = (void *)&page;
2633 ra[1].buf.len = num * sizeof(page);
2634
2635 ra[2].buf.pv = (void *)&routargs;
2636 ra[2].buf.len = sizeof(routargs);
2637
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302638 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002639 if (fl->apps->compat)
2640 ioctl.inv.sc = REMOTE_SCALARS_MAKE(4, 2, 1);
2641 else
2642 ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
2643 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302644 ioctl.fds = NULL;
2645 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002646 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002647 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2648 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302649 *raddr = (uintptr_t)routargs.vaddrout;
c_mtharue1a5ce12017-10-13 20:47:09 +05302650 if (err)
2651 goto bail;
2652 if (flags == ADSP_MMAP_HEAP_ADDR) {
2653 struct scm_desc desc = {0};
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002654
c_mtharue1a5ce12017-10-13 20:47:09 +05302655 desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302656 desc.args[1] = phys;
2657 desc.args[2] = size;
c_mtharue1a5ce12017-10-13 20:47:09 +05302658 desc.arginfo = SCM_ARGS(3);
2659 err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
2660 TZ_PIL_PROTECT_MEM_SUBSYS_ID), &desc);
2661 } else if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302662 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302663 hlosvm, 1, me->channel[fl->cid].rhvm.vmid,
2664 me->channel[fl->cid].rhvm.vmperm,
2665 me->channel[fl->cid].rhvm.vmcount));
c_mtharue1a5ce12017-10-13 20:47:09 +05302666 if (err)
2667 goto bail;
2668 }
2669bail:
2670 return err;
2671}
2672
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302673static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys,
2674 size_t size, uint32_t flags)
c_mtharue1a5ce12017-10-13 20:47:09 +05302675{
2676 int err = 0;
c_mtharu63ffc012017-11-16 15:26:56 +05302677 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302678 int tgid = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302679 int destVM[1] = {VMID_HLOS};
2680 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
2681
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302682 if (flags == ADSP_MMAP_HEAP_ADDR) {
c_mtharue1a5ce12017-10-13 20:47:09 +05302683 struct fastrpc_ioctl_invoke_crc ioctl;
2684 struct scm_desc desc = {0};
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302685 remote_arg_t ra[2];
2686
c_mtharue1a5ce12017-10-13 20:47:09 +05302687 struct {
2688 uint8_t skey;
2689 } routargs;
2690
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302691 if (fl == NULL)
2692 goto bail;
2693 tgid = fl->tgid;
2694 ra[0].buf.pv = (void *)&tgid;
2695 ra[0].buf.len = sizeof(tgid);
2696 ra[1].buf.pv = (void *)&routargs;
2697 ra[1].buf.len = sizeof(routargs);
c_mtharue1a5ce12017-10-13 20:47:09 +05302698
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302699 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302700 ioctl.inv.sc = REMOTE_SCALARS_MAKE(9, 1, 1);
c_mtharue1a5ce12017-10-13 20:47:09 +05302701 ioctl.inv.pra = ra;
2702 ioctl.fds = NULL;
2703 ioctl.attrs = NULL;
2704 ioctl.crc = NULL;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302705
c_mtharue1a5ce12017-10-13 20:47:09 +05302706
2707 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2708 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
Mohammed Nayeem Ur Rahman80f45dc2019-09-23 19:35:19 +05302709 if (err == AEE_EUNSUPPORTED) {
2710 remote_arg_t ra[1];
2711
2712 pr_warn("ADSPRPC:Failed to get security key with updated remote call, falling back to older method");
2713 ra[0].buf.pv = (void *)&routargs;
2714 ra[0].buf.len = sizeof(routargs);
2715 ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1);
2716 ioctl.inv.pra = ra;
2717 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2718 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2719 }
c_mtharue1a5ce12017-10-13 20:47:09 +05302720 if (err)
2721 goto bail;
Mohammed Nayeem Ur Rahman80f45dc2019-09-23 19:35:19 +05302722
c_mtharue1a5ce12017-10-13 20:47:09 +05302723 desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302724 desc.args[1] = phys;
2725 desc.args[2] = size;
c_mtharue1a5ce12017-10-13 20:47:09 +05302726 desc.args[3] = routargs.skey;
2727 desc.arginfo = SCM_ARGS(4);
2728 err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
2729 TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID), &desc);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302730 } else if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
2731 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302732 me->channel[fl->cid].rhvm.vmid,
2733 me->channel[fl->cid].rhvm.vmcount,
2734 destVM, destVMperm, 1));
c_mtharue1a5ce12017-10-13 20:47:09 +05302735 if (err)
2736 goto bail;
2737 }
2738
2739bail:
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002740 return err;
2741}
2742
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302743static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, uintptr_t raddr,
2744 uint64_t phys, size_t size, uint32_t flags)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002745{
Sathish Ambleybae51902017-07-03 15:00:49 -07002746 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002747 remote_arg_t ra[1];
2748 int err = 0;
2749 struct {
2750 int pid;
2751 uintptr_t vaddrout;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302752 size_t size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002753 } inargs;
2754
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302755 inargs.pid = fl->tgid;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302756 inargs.size = size;
2757 inargs.vaddrout = raddr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002758 ra[0].buf.pv = (void *)&inargs;
2759 ra[0].buf.len = sizeof(inargs);
2760
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05302761 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002762 if (fl->apps->compat)
2763 ioctl.inv.sc = REMOTE_SCALARS_MAKE(5, 1, 0);
2764 else
2765 ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
2766 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302767 ioctl.fds = NULL;
2768 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002769 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002770 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2771 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
c_mtharue1a5ce12017-10-13 20:47:09 +05302772 if (err)
2773 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302774 if (flags == ADSP_MMAP_HEAP_ADDR ||
2775 flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
2776 VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, phys, size, flags));
c_mtharue1a5ce12017-10-13 20:47:09 +05302777 if (err)
2778 goto bail;
2779 }
2780bail:
2781 return err;
2782}
2783
2784static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
2785{
2786 struct fastrpc_mmap *match = NULL, *map = NULL;
2787 struct hlist_node *n = NULL;
2788 int err = 0, ret = 0;
2789 struct fastrpc_apps *me = &gfa;
2790 struct ramdump_segment *ramdump_segments_rh = NULL;
2791
2792 do {
2793 match = NULL;
2794 spin_lock(&me->hlock);
2795 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
2796 match = map;
2797 hlist_del_init(&map->hn);
2798 break;
2799 }
2800 spin_unlock(&me->hlock);
2801
2802 if (match) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302803 VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, match->phys,
2804 match->size, match->flags));
c_mtharue1a5ce12017-10-13 20:47:09 +05302805 if (err)
2806 goto bail;
2807 if (me->channel[0].ramdumpenabled) {
2808 ramdump_segments_rh = kcalloc(1,
2809 sizeof(struct ramdump_segment), GFP_KERNEL);
2810 if (ramdump_segments_rh) {
2811 ramdump_segments_rh->address =
2812 match->phys;
2813 ramdump_segments_rh->size = match->size;
2814 ret = do_elf_ramdump(
2815 me->channel[0].remoteheap_ramdump_dev,
2816 ramdump_segments_rh, 1);
2817 if (ret < 0)
2818 pr_err("ADSPRPC: unable to dump heap");
2819 kfree(ramdump_segments_rh);
2820 }
2821 }
c_mtharu7bd6a422017-10-17 18:15:37 +05302822 fastrpc_mmap_free(match, 0);
c_mtharue1a5ce12017-10-13 20:47:09 +05302823 }
2824 } while (match);
2825bail:
2826 if (err && match)
2827 fastrpc_mmap_add(match);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002828 return err;
2829}
2830
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302831static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl)
2832{
2833 struct fastrpc_apps *me = &gfa;
2834 int session = 0, err = 0;
2835
2836 VERIFY(err, !fastrpc_get_adsp_session(
2837 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
2838 if (err)
2839 goto bail;
2840 if (me->channel[fl->cid].spd[session].pdrcount !=
2841 me->channel[fl->cid].spd[session].prevpdrcount) {
2842 if (fastrpc_mmap_remove_ssr(fl))
2843 pr_err("ADSPRPC: SSR: Failed to unmap remote heap\n");
2844 me->channel[fl->cid].spd[session].prevpdrcount =
2845 me->channel[fl->cid].spd[session].pdrcount;
2846 }
2847 if (!me->channel[fl->cid].spd[session].ispdup) {
2848 VERIFY(err, 0);
2849 if (err) {
2850 err = -ENOTCONN;
2851 goto bail;
2852 }
2853 }
2854bail:
2855 return err;
2856}
2857
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002858static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302859 size_t len, struct fastrpc_mmap **ppmap);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002860
2861static void fastrpc_mmap_add(struct fastrpc_mmap *map);
2862
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05302863static inline void get_fastrpc_ioctl_mmap_64(
2864 struct fastrpc_ioctl_mmap_64 *mmap64,
2865 struct fastrpc_ioctl_mmap *immap)
2866{
2867 immap->fd = mmap64->fd;
2868 immap->flags = mmap64->flags;
2869 immap->vaddrin = (uintptr_t)mmap64->vaddrin;
2870 immap->size = mmap64->size;
2871}
2872
2873static inline void put_fastrpc_ioctl_mmap_64(
2874 struct fastrpc_ioctl_mmap_64 *mmap64,
2875 struct fastrpc_ioctl_mmap *immap)
2876{
2877 mmap64->vaddrout = (uint64_t)immap->vaddrout;
2878}
2879
2880static inline void get_fastrpc_ioctl_munmap_64(
2881 struct fastrpc_ioctl_munmap_64 *munmap64,
2882 struct fastrpc_ioctl_munmap *imunmap)
2883{
2884 imunmap->vaddrout = (uintptr_t)munmap64->vaddrout;
2885 imunmap->size = munmap64->size;
2886}
2887
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002888static int fastrpc_internal_munmap(struct fastrpc_file *fl,
2889 struct fastrpc_ioctl_munmap *ud)
2890{
2891 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302892 struct fastrpc_mmap *map = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302893 struct fastrpc_buf *rbuf = NULL, *free = NULL;
2894 struct hlist_node *n;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002895
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302896 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302897
2898 spin_lock(&fl->hlock);
2899 hlist_for_each_entry_safe(rbuf, n, &fl->remote_bufs, hn_rem) {
2900 if (rbuf->raddr && (rbuf->flags == ADSP_MMAP_ADD_PAGES)) {
2901 if ((rbuf->raddr == ud->vaddrout) &&
2902 (rbuf->size == ud->size)) {
2903 free = rbuf;
2904 break;
2905 }
2906 }
2907 }
2908 spin_unlock(&fl->hlock);
2909
2910 if (free) {
2911 VERIFY(err, !fastrpc_munmap_on_dsp(fl, free->raddr,
2912 free->phys, free->size, free->flags));
2913 if (err)
2914 goto bail;
2915 fastrpc_buf_free(rbuf, 0);
2916 mutex_unlock(&fl->map_mutex);
2917 return err;
2918 }
2919
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302920 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002921 VERIFY(err, !fastrpc_mmap_remove(fl, ud->vaddrout, ud->size, &map));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302922 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002923 if (err)
2924 goto bail;
Vamsi krishna Gattupalli4e87ecb2020-12-14 11:06:27 +05302925 VERIFY(err, map != NULL);
2926 if (err) {
2927 err = -EINVAL;
2928 goto bail;
2929 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302930 VERIFY(err, !fastrpc_munmap_on_dsp(fl, map->raddr,
Vamsi krishna Gattupalli4e87ecb2020-12-14 11:06:27 +05302931 map->phys, map->size, map->flags));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002932 if (err)
2933 goto bail;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302934 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302935 fastrpc_mmap_free(map, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302936 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002937bail:
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302938 if (err && map) {
2939 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002940 fastrpc_mmap_add(map);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302941 mutex_unlock(&fl->fl_map_mutex);
2942 }
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302943 mutex_unlock(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002944 return err;
2945}
2946
c_mtharu7bd6a422017-10-17 18:15:37 +05302947static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl,
2948 struct fastrpc_ioctl_munmap_fd *ud) {
2949 int err = 0;
2950 struct fastrpc_mmap *map = NULL;
2951
2952 VERIFY(err, (fl && ud));
2953 if (err)
2954 goto bail;
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302955 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302956 mutex_lock(&fl->fl_map_mutex);
Tharun Kumar Merugu09fc6152018-02-16 13:13:12 +05302957 if (fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map)) {
2958 pr_err("adsprpc: mapping not found to unmap %d va %llx %x\n",
c_mtharu7bd6a422017-10-17 18:15:37 +05302959 ud->fd, (unsigned long long)ud->va,
2960 (unsigned int)ud->len);
2961 err = -1;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302962 mutex_unlock(&fl->fl_map_mutex);
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302963 mutex_unlock(&fl->map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302964 goto bail;
2965 }
2966 if (map)
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302967 fastrpc_mmap_free(map, 0);
2968 mutex_unlock(&fl->fl_map_mutex);
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302969 mutex_unlock(&fl->map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302970bail:
2971 return err;
2972}
2973
2974
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002975static int fastrpc_internal_mmap(struct fastrpc_file *fl,
2976 struct fastrpc_ioctl_mmap *ud)
2977{
2978
c_mtharue1a5ce12017-10-13 20:47:09 +05302979 struct fastrpc_mmap *map = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302980 struct fastrpc_buf *rbuf = NULL;
2981 unsigned long dma_attr = 0;
2982 uintptr_t raddr = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002983 int err = 0;
2984
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302985 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302986 if (ud->flags == ADSP_MMAP_ADD_PAGES) {
2987 if (ud->vaddrin) {
2988 err = -EINVAL;
2989 pr_err("adsprpc: %s: %s: ERROR: adding user allocated pages is not supported\n",
2990 current->comm, __func__);
2991 goto bail;
2992 }
2993 dma_attr = DMA_ATTR_EXEC_MAPPING |
2994 DMA_ATTR_NO_KERNEL_MAPPING |
2995 DMA_ATTR_FORCE_NON_COHERENT;
2996 err = fastrpc_buf_alloc(fl, ud->size, dma_attr, ud->flags,
2997 1, &rbuf);
2998 if (err)
2999 goto bail;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05303000 err = fastrpc_mmap_on_dsp(fl, ud->flags, 0,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303001 rbuf->phys, rbuf->size, &raddr);
3002 if (err)
3003 goto bail;
3004 rbuf->raddr = raddr;
3005 } else {
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05303006
3007 uintptr_t va_to_dsp;
3008
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303009 mutex_lock(&fl->fl_map_mutex);
3010 if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin,
3011 ud->size, ud->flags, 1, &map)) {
Mohammed Nayeem Ur Rahmanaf5f6102019-10-09 13:36:52 +05303012 ud->vaddrout = map->raddr;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303013 mutex_unlock(&fl->fl_map_mutex);
3014 mutex_unlock(&fl->map_mutex);
3015 return 0;
3016 }
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05303017
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303018 VERIFY(err, !fastrpc_mmap_create(fl, ud->fd, 0,
3019 (uintptr_t)ud->vaddrin, ud->size,
3020 ud->flags, &map));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303021 mutex_unlock(&fl->fl_map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303022 if (err)
3023 goto bail;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05303024
3025 if (ud->flags == ADSP_MMAP_HEAP_ADDR ||
3026 ud->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
3027 va_to_dsp = 0;
3028 else
3029 va_to_dsp = (uintptr_t)map->va;
3030 VERIFY(err, 0 == fastrpc_mmap_on_dsp(fl, ud->flags, va_to_dsp,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303031 map->phys, map->size, &raddr));
3032 if (err)
3033 goto bail;
3034 map->raddr = raddr;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05303035 }
Mohammed Nayeem Ur Rahman3ac5d322018-09-24 13:54:08 +05303036 ud->vaddrout = raddr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003037 bail:
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303038 if (err && map) {
3039 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05303040 fastrpc_mmap_free(map, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303041 mutex_unlock(&fl->fl_map_mutex);
3042 }
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05303043 mutex_unlock(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003044 return err;
3045}
3046
3047static void fastrpc_channel_close(struct kref *kref)
3048{
3049 struct fastrpc_apps *me = &gfa;
3050 struct fastrpc_channel_ctx *ctx;
3051 int cid;
3052
3053 ctx = container_of(kref, struct fastrpc_channel_ctx, kref);
3054 cid = ctx - &gcinfo[0];
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303055 if (me->glink) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303056 fastrpc_glink_close(ctx->chan, cid);
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303057 ctx->chan = NULL;
3058 }
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303059 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003060 pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
3061 MAJOR(me->dev_no), cid);
3062}
3063
3064static void fastrpc_context_list_dtor(struct fastrpc_file *fl);
3065
3066static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan,
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303067 int secure, int sharedcb, struct fastrpc_session_ctx **session)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003068{
3069 struct fastrpc_apps *me = &gfa;
3070 int idx = 0, err = 0;
3071
3072 if (chan->sesscount) {
3073 for (idx = 0; idx < chan->sesscount; ++idx) {
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303074 if ((sharedcb && chan->session[idx].smmu.sharedcb) ||
3075 (!chan->session[idx].used &&
3076 chan->session[idx].smmu.secure
3077 == secure && !sharedcb)) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003078 chan->session[idx].used = 1;
3079 break;
3080 }
3081 }
3082 VERIFY(err, idx < chan->sesscount);
3083 if (err)
3084 goto bail;
3085 chan->session[idx].smmu.faults = 0;
3086 } else {
3087 VERIFY(err, me->dev != NULL);
3088 if (err)
3089 goto bail;
3090 chan->session[0].dev = me->dev;
c_mtharue1a5ce12017-10-13 20:47:09 +05303091 chan->session[0].smmu.dev = me->dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003092 }
3093
3094 *session = &chan->session[idx];
3095 bail:
3096 return err;
3097}
3098
c_mtharue1a5ce12017-10-13 20:47:09 +05303099static bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv,
3100 size_t size)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003101{
3102 if (glink_queue_rx_intent(h, NULL, size))
3103 return false;
3104 return true;
3105}
3106
c_mtharue1a5ce12017-10-13 20:47:09 +05303107static void fastrpc_glink_notify_tx_done(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003108 const void *pkt_priv, const void *ptr)
3109{
3110}
3111
c_mtharue1a5ce12017-10-13 20:47:09 +05303112static void fastrpc_glink_notify_rx(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003113 const void *pkt_priv, const void *ptr, size_t size)
3114{
3115 struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05303116 struct fastrpc_apps *me = &gfa;
3117 uint32_t index;
c_mtharufdac6892017-10-12 13:09:01 +05303118 int err = 0;
Jeya R8fa59d62020-11-04 20:42:59 +05303119 unsigned long irq_flags = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003120
c_mtharufdac6892017-10-12 13:09:01 +05303121 VERIFY(err, (rsp && size >= sizeof(*rsp)));
3122 if (err)
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05303123 goto bail;
3124
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05303125 index = (uint32_t)((rsp->ctx & FASTRPC_CTXID_MASK) >> 4);
3126 VERIFY(err, index < FASTRPC_CTX_MAX);
c_mtharufdac6892017-10-12 13:09:01 +05303127 if (err)
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05303128 goto bail;
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05303129
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05303130 VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index]));
3131 if (err)
3132 goto bail;
3133
Jeya R8fa59d62020-11-04 20:42:59 +05303134 spin_lock_irqsave(&me->ctxlock, irq_flags);
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303135 VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp->ctx & ~3)) &&
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05303136 me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC));
Jeya R8fa59d62020-11-04 20:42:59 +05303137 if (err) {
3138 spin_unlock_irqrestore(&me->ctxlock, irq_flags);
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05303139 goto bail;
Jeya R8fa59d62020-11-04 20:42:59 +05303140 }
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +05303141 me->ctxtable[index]->handle = handle;
3142 me->ctxtable[index]->ptr = ptr;
Jeya R8fa59d62020-11-04 20:42:59 +05303143 spin_unlock_irqrestore(&me->ctxlock, irq_flags);
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +05303144
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05303145 context_notify_user(me->ctxtable[index], rsp->retval);
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05303146bail:
Jeya R859f8012020-08-09 02:09:14 +05303147 if (err) {
3148 glink_rx_done(handle, ptr, true);
c_mtharufdac6892017-10-12 13:09:01 +05303149 pr_err("adsprpc: invalid response or context\n");
Jeya R859f8012020-08-09 02:09:14 +05303150 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003151}
3152
c_mtharue1a5ce12017-10-13 20:47:09 +05303153static void fastrpc_glink_notify_state(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003154 unsigned int event)
3155{
3156 struct fastrpc_apps *me = &gfa;
3157 int cid = (int)(uintptr_t)priv;
3158 struct fastrpc_glink_info *link;
3159
3160 if (cid < 0 || cid >= NUM_CHANNELS)
3161 return;
3162 link = &me->channel[cid].link;
3163 switch (event) {
3164 case GLINK_CONNECTED:
3165 link->port_state = FASTRPC_LINK_CONNECTED;
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05303166 complete(&me->channel[cid].workport);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003167 break;
3168 case GLINK_LOCAL_DISCONNECTED:
3169 link->port_state = FASTRPC_LINK_DISCONNECTED;
3170 break;
3171 case GLINK_REMOTE_DISCONNECTED:
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003172 break;
3173 default:
3174 break;
3175 }
3176}
3177
3178static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
3179 struct fastrpc_session_ctx **session)
3180{
3181 int err = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303182 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003183
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303184 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003185 if (!*session)
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303186 err = fastrpc_session_alloc_locked(chan, secure, 0, session);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303187 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003188 return err;
3189}
3190
3191static void fastrpc_session_free(struct fastrpc_channel_ctx *chan,
3192 struct fastrpc_session_ctx *session)
3193{
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303194 struct fastrpc_apps *me = &gfa;
3195
3196 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003197 session->used = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303198 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003199}
3200
3201static int fastrpc_file_free(struct fastrpc_file *fl)
3202{
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303203 struct hlist_node *n = NULL;
Tharun Kumar Merugu3e966762018-04-04 10:56:44 +05303204 struct fastrpc_mmap *map = NULL, *lmap = NULL;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303205 struct fastrpc_perf *perf = NULL, *fperf = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003206 int cid;
3207
3208 if (!fl)
3209 return 0;
3210 cid = fl->cid;
3211
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05303212 (void)fastrpc_release_current_dsp_process(fl);
3213
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003214 spin_lock(&fl->apps->hlock);
3215 hlist_del_init(&fl->hn);
3216 spin_unlock(&fl->apps->hlock);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303217 kfree(fl->debug_buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003218
Sathish Ambleyd7fbcbb2017-03-08 10:55:48 -08003219 if (!fl->sctx) {
3220 kfree(fl);
3221 return 0;
3222 }
tharun kumar9f899ea2017-07-03 17:07:03 +05303223 spin_lock(&fl->hlock);
3224 fl->file_close = 1;
3225 spin_unlock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303226 if (!IS_ERR_OR_NULL(fl->init_mem))
3227 fastrpc_buf_free(fl->init_mem, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003228 fastrpc_context_list_dtor(fl);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303229 fastrpc_cached_buf_list_free(fl);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303230 mutex_lock(&fl->fl_map_mutex);
Tharun Kumar Merugu3e966762018-04-04 10:56:44 +05303231 do {
3232 lmap = NULL;
3233 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3234 hlist_del_init(&map->hn);
3235 lmap = map;
3236 break;
3237 }
3238 fastrpc_mmap_free(lmap, 1);
3239 } while (lmap);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303240 mutex_unlock(&fl->fl_map_mutex);
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303241 if (fl->refcount && (fl->ssrcount == fl->apps->channel[cid].ssrcount))
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003242 kref_put_mutex(&fl->apps->channel[cid].kref,
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303243 fastrpc_channel_close, &fl->apps->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003244 if (fl->sctx)
3245 fastrpc_session_free(&fl->apps->channel[cid], fl->sctx);
3246 if (fl->secsctx)
3247 fastrpc_session_free(&fl->apps->channel[cid], fl->secsctx);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303248
3249 mutex_lock(&fl->perf_mutex);
3250 do {
3251 struct hlist_node *pn = NULL;
3252
3253 fperf = NULL;
3254 hlist_for_each_entry_safe(perf, pn, &fl->perf, hn) {
3255 hlist_del_init(&perf->hn);
3256 fperf = perf;
3257 break;
3258 }
3259 kfree(fperf);
3260 } while (fperf);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303261 fastrpc_remote_buf_list_free(fl);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303262 mutex_unlock(&fl->perf_mutex);
3263 mutex_destroy(&fl->perf_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303264 mutex_destroy(&fl->fl_map_mutex);
Tharun Kumar Merugu8714e642018-05-17 15:21:08 +05303265 mutex_destroy(&fl->map_mutex);
Jeya R1b85ca52021-06-10 13:03:44 +05303266 mutex_destroy(&fl->pm_qos_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003267 kfree(fl);
3268 return 0;
3269}
3270
3271static int fastrpc_device_release(struct inode *inode, struct file *file)
3272{
3273 struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
3274
3275 if (fl) {
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303276 if (fl->qos_request && pm_qos_request_active(&fl->pm_qos_req))
3277 pm_qos_remove_request(&fl->pm_qos_req);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003278 if (fl->debugfs_file != NULL)
3279 debugfs_remove(fl->debugfs_file);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003280 fastrpc_file_free(fl);
c_mtharue1a5ce12017-10-13 20:47:09 +05303281 file->private_data = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003282 }
3283 return 0;
3284}
3285
3286static void fastrpc_link_state_handler(struct glink_link_state_cb_info *cb_info,
3287 void *priv)
3288{
3289 struct fastrpc_apps *me = &gfa;
3290 int cid = (int)((uintptr_t)priv);
3291 struct fastrpc_glink_info *link;
3292
3293 if (cid < 0 || cid >= NUM_CHANNELS)
3294 return;
3295
3296 link = &me->channel[cid].link;
3297 switch (cb_info->link_state) {
3298 case GLINK_LINK_STATE_UP:
3299 link->link_state = FASTRPC_LINK_STATE_UP;
3300 complete(&me->channel[cid].work);
3301 break;
3302 case GLINK_LINK_STATE_DOWN:
3303 link->link_state = FASTRPC_LINK_STATE_DOWN;
3304 break;
3305 default:
3306 pr_err("adsprpc: unknown link state %d\n", cb_info->link_state);
3307 break;
3308 }
3309}
3310
3311static int fastrpc_glink_register(int cid, struct fastrpc_apps *me)
3312{
3313 int err = 0;
3314 struct fastrpc_glink_info *link;
3315
3316 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3317 if (err)
3318 goto bail;
3319
3320 link = &me->channel[cid].link;
3321 if (link->link_notify_handle != NULL)
3322 goto bail;
3323
3324 link->link_info.glink_link_state_notif_cb = fastrpc_link_state_handler;
3325 link->link_notify_handle = glink_register_link_state_cb(
3326 &link->link_info,
3327 (void *)((uintptr_t)cid));
3328 VERIFY(err, !IS_ERR_OR_NULL(me->channel[cid].link.link_notify_handle));
3329 if (err) {
3330 link->link_notify_handle = NULL;
3331 goto bail;
3332 }
3333 VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work,
3334 RPC_TIMEOUT));
3335bail:
3336 return err;
3337}
3338
3339static void fastrpc_glink_close(void *chan, int cid)
3340{
3341 int err = 0;
3342 struct fastrpc_glink_info *link;
3343
3344 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3345 if (err)
3346 return;
3347 link = &gfa.channel[cid].link;
3348
c_mtharu314a4202017-11-15 22:09:17 +05303349 if (link->port_state == FASTRPC_LINK_CONNECTED ||
3350 link->port_state == FASTRPC_LINK_REMOTE_DISCONNECTING) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003351 link->port_state = FASTRPC_LINK_DISCONNECTING;
3352 glink_close(chan);
3353 }
3354}
3355
3356static int fastrpc_glink_open(int cid)
3357{
3358 int err = 0;
3359 void *handle = NULL;
3360 struct fastrpc_apps *me = &gfa;
3361 struct glink_open_config *cfg;
3362 struct fastrpc_glink_info *link;
3363
3364 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3365 if (err)
3366 goto bail;
3367 link = &me->channel[cid].link;
3368 cfg = &me->channel[cid].link.cfg;
3369 VERIFY(err, (link->link_state == FASTRPC_LINK_STATE_UP));
3370 if (err)
3371 goto bail;
3372
Tharun Kumar Meruguca0db5262017-05-10 12:53:12 +05303373 VERIFY(err, (link->port_state == FASTRPC_LINK_DISCONNECTED));
3374 if (err)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003375 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003376
3377 link->port_state = FASTRPC_LINK_CONNECTING;
3378 cfg->priv = (void *)(uintptr_t)cid;
3379 cfg->edge = gcinfo[cid].link.link_info.edge;
3380 cfg->transport = gcinfo[cid].link.link_info.transport;
3381 cfg->name = FASTRPC_GLINK_GUID;
3382 cfg->notify_rx = fastrpc_glink_notify_rx;
3383 cfg->notify_tx_done = fastrpc_glink_notify_tx_done;
3384 cfg->notify_state = fastrpc_glink_notify_state;
3385 cfg->notify_rx_intent_req = fastrpc_glink_notify_rx_intent_req;
3386 handle = glink_open(cfg);
3387 VERIFY(err, !IS_ERR_OR_NULL(handle));
c_mtharu6e1d26b2017-10-09 16:05:24 +05303388 if (err) {
3389 if (link->port_state == FASTRPC_LINK_CONNECTING)
3390 link->port_state = FASTRPC_LINK_DISCONNECTED;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003391 goto bail;
c_mtharu6e1d26b2017-10-09 16:05:24 +05303392 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003393 me->channel[cid].chan = handle;
3394bail:
3395 return err;
3396}
3397
Sathish Ambley1ca68232017-01-19 10:32:55 -08003398static int fastrpc_debugfs_open(struct inode *inode, struct file *filp)
3399{
3400 filp->private_data = inode->i_private;
3401 return 0;
3402}
3403
3404static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
3405 size_t count, loff_t *position)
3406{
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303407 struct fastrpc_apps *me = &gfa;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003408 struct fastrpc_file *fl = filp->private_data;
3409 struct hlist_node *n;
c_mtharue1a5ce12017-10-13 20:47:09 +05303410 struct fastrpc_buf *buf = NULL;
3411 struct fastrpc_mmap *map = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303412 struct fastrpc_mmap *gmaps = NULL;
c_mtharue1a5ce12017-10-13 20:47:09 +05303413 struct smq_invoke_ctx *ictx = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303414 struct fastrpc_channel_ctx *chan = NULL;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003415 unsigned int len = 0;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303416 int i, j, sess_used = 0, ret = 0;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003417 char *fileinfo = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303418 char single_line[UL_SIZE] = "----------------";
3419 char title[UL_SIZE] = "=========================";
Sathish Ambley1ca68232017-01-19 10:32:55 -08003420
3421 fileinfo = kzalloc(DEBUGFS_SIZE, GFP_KERNEL);
3422 if (!fileinfo)
3423 goto bail;
3424 if (fl == NULL) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303425 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3426 "\n%s %s %s\n", title, " CHANNEL INFO ", title);
3427 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3428 "%-8s|%-9s|%-9s|%-14s|%-9s|%-13s\n",
3429 "susbsys", "refcount", "sesscount", "issubsystemup",
3430 "ssrcount", "session_used");
3431 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3432 "-%s%s%s%s-\n", single_line, single_line,
3433 single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003434 for (i = 0; i < NUM_CHANNELS; i++) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303435 sess_used = 0;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003436 chan = &gcinfo[i];
3437 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303438 DEBUGFS_SIZE - len, "%-8s", chan->subsys);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003439 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303440 DEBUGFS_SIZE - len, "|%-9d",
3441 chan->kref.refcount.counter);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303442 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303443 DEBUGFS_SIZE - len, "|%-9d",
3444 chan->sesscount);
3445 len += scnprintf(fileinfo + len,
3446 DEBUGFS_SIZE - len, "|%-14d",
3447 chan->issubsystemup);
3448 len += scnprintf(fileinfo + len,
3449 DEBUGFS_SIZE - len, "|%-9d",
3450 chan->ssrcount);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003451 for (j = 0; j < chan->sesscount; j++) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303452 sess_used += chan->session[j].used;
3453 }
3454 len += scnprintf(fileinfo + len,
3455 DEBUGFS_SIZE - len, "|%-13d\n", sess_used);
3456
3457 }
3458 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3459 "\n%s%s%s\n", "=============",
3460 " CMA HEAP ", "==============");
3461 len += scnprintf(fileinfo + len,
3462 DEBUGFS_SIZE - len, "%-20s|%-20s\n", "addr", "size");
3463 len += scnprintf(fileinfo + len,
3464 DEBUGFS_SIZE - len, "--%s%s---\n",
3465 single_line, single_line);
3466 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3467 "0x%-18llX", me->range.addr);
3468 len += scnprintf(fileinfo + len,
3469 DEBUGFS_SIZE - len, "|0x%-18llX\n", me->range.size);
3470 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3471 "\n==========%s %s %s===========\n",
3472 title, " GMAPS ", title);
3473 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3474 "%-20s|%-20s|%-20s|%-20s\n",
3475 "fd", "phys", "size", "va");
3476 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3477 "%s%s%s%s%s\n", single_line, single_line,
3478 single_line, single_line, single_line);
3479 hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
3480 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3481 "%-20d|0x%-18llX|0x%-18X|0x%-20lX\n\n",
3482 gmaps->fd, gmaps->phys,
3483 (uint32_t)gmaps->size,
3484 gmaps->va);
3485 }
3486 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3487 "%-20s|%-20s|%-20s|%-20s\n",
3488 "len", "refs", "raddr", "flags");
3489 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3490 "%s%s%s%s%s\n", single_line, single_line,
3491 single_line, single_line, single_line);
3492 hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
3493 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3494 "0x%-18X|%-20d|%-20lu|%-20u\n",
3495 (uint32_t)gmaps->len, gmaps->refs,
3496 gmaps->raddr, gmaps->flags);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003497 }
3498 } else {
3499 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303500 "\n%s %13s %d\n", "cid", ":", fl->cid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003501 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303502 "%s %12s %d\n", "tgid", ":", fl->tgid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003503 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303504 "%s %7s %d\n", "sessionid", ":", fl->sessionid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003505 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303506 "%s %8s %d\n", "ssrcount", ":", fl->ssrcount);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303507 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303508 "%s %8s %d\n", "refcount", ":", fl->refcount);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003509 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303510 "%s %14s %d\n", "pd", ":", fl->pd);
3511 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3512 "%s %9s %s\n", "spdname", ":", fl->spdname);
3513 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3514 "%s %6s %d\n", "file_close", ":", fl->file_close);
3515 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3516 "%s %8s %d\n", "sharedcb", ":", fl->sharedcb);
3517 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3518 "%s %9s %d\n", "profile", ":", fl->profile);
3519 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3520 "%s %3s %d\n", "smmu.coherent", ":",
3521 fl->sctx->smmu.coherent);
3522 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3523 "%s %4s %d\n", "smmu.enabled", ":",
3524 fl->sctx->smmu.enabled);
3525 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3526 "%s %9s %d\n", "smmu.cb", ":", fl->sctx->smmu.cb);
3527 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3528 "%s %5s %d\n", "smmu.secure", ":",
3529 fl->sctx->smmu.secure);
3530 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3531 "%s %5s %d\n", "smmu.faults", ":",
3532 fl->sctx->smmu.faults);
3533 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3534 "%s %s %d\n", "link.link_state",
3535 ":", *&me->channel[fl->cid].link.link_state);
3536
3537 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3538 "\n=======%s %s %s======\n", title,
3539 " LIST OF MAPS ", title);
3540
3541 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3542 "%-20s|%-20s|%-20s\n", "va", "phys", "size");
3543 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3544 "%s%s%s%s%s\n",
3545 single_line, single_line, single_line,
3546 single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003547 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303548 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3549 "0x%-20lX|0x%-20llX|0x%-20zu\n\n",
3550 map->va, map->phys,
3551 map->size);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003552 }
3553 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303554 "%-20s|%-20s|%-20s|%-20s\n",
3555 "len", "refs",
3556 "raddr", "uncached");
3557 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3558 "%s%s%s%s%s\n",
3559 single_line, single_line, single_line,
3560 single_line, single_line);
3561 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3562 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3563 "%-20zu|%-20d|0x%-20lX|%-20d\n\n",
3564 map->len, map->refs, map->raddr,
3565 map->uncached);
3566 }
3567 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3568 "%-20s|%-20s\n", "secure", "attr");
3569 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3570 "%s%s%s%s%s\n",
3571 single_line, single_line, single_line,
3572 single_line, single_line);
3573 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3574 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3575 "%-20d|0x%-20lX\n\n",
3576 map->secure, map->attr);
3577 }
3578 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303579 "%s %d\n\n",
3580 "KERNEL MEMORY ALLOCATION:", 1);
3581 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303582 "\n======%s %s %s======\n", title,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303583 " LIST OF CACHED BUFS ", title);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303584 spin_lock(&fl->hlock);
3585 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303586 "%-19s|%-19s|%-19s|%-19s\n",
3587 "virt", "phys", "size", "dma_attr");
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303588 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3589 "%s%s%s%s%s\n", single_line, single_line,
3590 single_line, single_line, single_line);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303591 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303592 len += scnprintf(fileinfo + len,
3593 DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303594 "0x%-17p|0x%-17llX|%-19zu|0x%-17lX\n",
3595 buf->virt, (uint64_t)buf->phys, buf->size,
3596 buf->dma_attr);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303597 }
3598 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3599 "\n%s %s %s\n", title,
3600 " LIST OF PENDING SMQCONTEXTS ", title);
3601
3602 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3603 "%-20s|%-10s|%-10s|%-10s|%-20s\n",
3604 "sc", "pid", "tgid", "used", "ctxid");
3605 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3606 "%s%s%s%s%s\n", single_line, single_line,
3607 single_line, single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003608 hlist_for_each_entry_safe(ictx, n, &fl->clst.pending, hn) {
3609 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303610 "0x%-18X|%-10d|%-10d|%-10zu|0x%-20llX\n\n",
3611 ictx->sc, ictx->pid, ictx->tgid,
3612 ictx->used, ictx->ctxid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003613 }
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303614
Sathish Ambley1ca68232017-01-19 10:32:55 -08003615 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303616 "\n%s %s %s\n", title,
3617 " LIST OF INTERRUPTED SMQCONTEXTS ", title);
3618
3619 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3620 "%-20s|%-10s|%-10s|%-10s|%-20s\n",
3621 "sc", "pid", "tgid", "used", "ctxid");
3622 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3623 "%s%s%s%s%s\n", single_line, single_line,
3624 single_line, single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003625 hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303626 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3627 "%-20u|%-20d|%-20d|%-20zu|0x%-20llX\n\n",
3628 ictx->sc, ictx->pid, ictx->tgid,
3629 ictx->used, ictx->ctxid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003630 }
3631 spin_unlock(&fl->hlock);
3632 }
3633 if (len > DEBUGFS_SIZE)
3634 len = DEBUGFS_SIZE;
3635 ret = simple_read_from_buffer(buffer, count, position, fileinfo, len);
3636 kfree(fileinfo);
3637bail:
3638 return ret;
3639}
3640
3641static const struct file_operations debugfs_fops = {
3642 .open = fastrpc_debugfs_open,
3643 .read = fastrpc_debugfs_read,
3644};
Sathish Ambley36849af2017-02-02 09:35:55 -08003645static int fastrpc_channel_open(struct fastrpc_file *fl)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003646{
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003647 struct fastrpc_apps *me = &gfa;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303648 int cid = -1, ii, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003649
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303650 mutex_lock(&me->smd_mutex);
3651
Sathish Ambley36849af2017-02-02 09:35:55 -08003652 VERIFY(err, fl && fl->sctx);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003653 if (err)
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303654 goto bail;
Sathish Ambley36849af2017-02-02 09:35:55 -08003655 cid = fl->cid;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303656 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
3657 if (err) {
3658 err = -ECHRNG;
c_mtharu314a4202017-11-15 22:09:17 +05303659 goto bail;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303660 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303661 if (me->channel[cid].ssrcount !=
3662 me->channel[cid].prevssrcount) {
3663 if (!me->channel[cid].issubsystemup) {
3664 VERIFY(err, 0);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303665 if (err) {
3666 err = -ENOTCONN;
c_mtharue1a5ce12017-10-13 20:47:09 +05303667 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303668 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303669 }
3670 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003671 fl->ssrcount = me->channel[cid].ssrcount;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303672 fl->refcount = 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003673 if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) ||
c_mtharue1a5ce12017-10-13 20:47:09 +05303674 (me->channel[cid].chan == NULL)) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303675 if (me->glink) {
3676 VERIFY(err, 0 == fastrpc_glink_register(cid, me));
3677 if (err)
3678 goto bail;
3679 VERIFY(err, 0 == fastrpc_glink_open(cid));
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303680 VERIFY(err,
3681 wait_for_completion_timeout(&me->channel[cid].workport,
3682 RPC_TIMEOUT));
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303683 } else {
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303684 if (me->channel[cid].chan == NULL) {
3685 VERIFY(err, !smd_named_open_on_edge(
3686 FASTRPC_SMD_GUID,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303687 gcinfo[cid].channel,
3688 (smd_channel_t **)&me->channel[cid].chan,
3689 (void *)(uintptr_t)cid,
3690 smd_event_handler));
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05303691 VERIFY(err,
3692 wait_for_completion_timeout(&me->channel[cid].workport,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003693 RPC_TIMEOUT));
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303694
3695 }
3696 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003697 if (err) {
c_mtharue1a5ce12017-10-13 20:47:09 +05303698 me->channel[cid].chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003699 goto bail;
3700 }
3701 kref_init(&me->channel[cid].kref);
3702 pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name,
3703 MAJOR(me->dev_no), cid);
Tharun Kumar Meruguc42c6e22018-05-29 15:50:46 +05303704
3705 for (ii = 0; ii < FASTRPC_GLINK_INTENT_NUM && me->glink; ii++)
3706 glink_queue_rx_intent(me->channel[cid].chan, NULL,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303707 FASTRPC_GLINK_INTENT_LEN);
Tharun Kumar Meruguc42c6e22018-05-29 15:50:46 +05303708
Tharun Kumar Merugud86fc8c2018-01-04 16:35:31 +05303709 if (cid == 0 && me->channel[cid].ssrcount !=
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003710 me->channel[cid].prevssrcount) {
c_mtharue1a5ce12017-10-13 20:47:09 +05303711 if (fastrpc_mmap_remove_ssr(fl))
3712 pr_err("ADSPRPC: SSR: Failed to unmap remote heap\n");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003713 me->channel[cid].prevssrcount =
3714 me->channel[cid].ssrcount;
3715 }
3716 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003717
3718bail:
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303719 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003720 return err;
3721}
3722
Sathish Ambley36849af2017-02-02 09:35:55 -08003723static int fastrpc_device_open(struct inode *inode, struct file *filp)
3724{
3725 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05303726 struct fastrpc_file *fl = NULL;
Sathish Ambley36849af2017-02-02 09:35:55 -08003727 struct fastrpc_apps *me = &gfa;
3728
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303729 /*
3730 * Indicates the device node opened
3731 * MINOR_NUM_DEV or MINOR_NUM_SECURE_DEV
3732 */
3733 int dev_minor = MINOR(inode->i_rdev);
3734
3735 VERIFY(err, ((dev_minor == MINOR_NUM_DEV) ||
3736 (dev_minor == MINOR_NUM_SECURE_DEV)));
3737 if (err) {
3738 pr_err("adsprpc: Invalid dev minor num %d\n", dev_minor);
3739 return err;
3740 }
3741
c_mtharue1a5ce12017-10-13 20:47:09 +05303742 VERIFY(err, NULL != (fl = kzalloc(sizeof(*fl), GFP_KERNEL)));
Sathish Ambley36849af2017-02-02 09:35:55 -08003743 if (err)
3744 return err;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303745
Sathish Ambley36849af2017-02-02 09:35:55 -08003746 context_list_ctor(&fl->clst);
3747 spin_lock_init(&fl->hlock);
3748 INIT_HLIST_HEAD(&fl->maps);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303749 INIT_HLIST_HEAD(&fl->perf);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303750 INIT_HLIST_HEAD(&fl->cached_bufs);
3751 INIT_HLIST_HEAD(&fl->remote_bufs);
Sathish Ambley36849af2017-02-02 09:35:55 -08003752 INIT_HLIST_NODE(&fl->hn);
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05303753 fl->sessionid = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003754 fl->apps = me;
3755 fl->mode = FASTRPC_MODE_SERIAL;
3756 fl->cid = -1;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303757 fl->dev_minor = dev_minor;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303758 fl->init_mem = NULL;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303759 fl->qos_request = 0;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303760 fl->refcount = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003761 filp->private_data = fl;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05303762 mutex_init(&fl->map_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303763 mutex_init(&fl->fl_map_mutex);
Sathish Ambley36849af2017-02-02 09:35:55 -08003764 spin_lock(&me->hlock);
3765 hlist_add_head(&fl->hn, &me->drivers);
3766 spin_unlock(&me->hlock);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303767 mutex_init(&fl->perf_mutex);
Jeya R1b85ca52021-06-10 13:03:44 +05303768 mutex_init(&fl->pm_qos_mutex);
Sathish Ambley36849af2017-02-02 09:35:55 -08003769 return 0;
3770}
3771
Edgar Flores1a772fa2020-02-07 14:59:29 -08003772static int fastrpc_set_process_info(struct fastrpc_file *fl)
3773{
3774 int err = 0, buf_size = 0;
3775 char strpid[PID_SIZE];
Jeya Rc6995932021-03-18 14:04:49 +05303776 char cur_comm[TASK_COMM_LEN];
Edgar Flores1a772fa2020-02-07 14:59:29 -08003777
Jeya Rc6995932021-03-18 14:04:49 +05303778 memcpy(cur_comm, current->comm, TASK_COMM_LEN);
3779 cur_comm[TASK_COMM_LEN-1] = '\0';
Edgar Flores1a772fa2020-02-07 14:59:29 -08003780 fl->tgid = current->tgid;
3781 snprintf(strpid, PID_SIZE, "%d", current->pid);
Jeya Rc6995932021-03-18 14:04:49 +05303782 buf_size = strlen(cur_comm) + strlen("_") + strlen(strpid) + 1;
Edgar Flores1a772fa2020-02-07 14:59:29 -08003783 fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
3784 if (!fl->debug_buf) {
3785 err = -ENOMEM;
3786 return err;
3787 }
Jeya Rc6995932021-03-18 14:04:49 +05303788 snprintf(fl->debug_buf, buf_size, "%.10s%s%d",
3789 cur_comm, "_", current->pid);
Edgar Flores1a772fa2020-02-07 14:59:29 -08003790 fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
3791 debugfs_root, fl, &debugfs_fops);
3792 if (!fl->debugfs_file)
3793 pr_warn("Error: %s: %s: failed to create debugfs file %s\n",
Jeya Rc6995932021-03-18 14:04:49 +05303794 cur_comm, __func__, fl->debug_buf);
3795
Edgar Flores1a772fa2020-02-07 14:59:29 -08003796 return err;
3797}
3798
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003799static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
3800{
3801 int err = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003802 uint32_t cid;
Jeya Rf4b99852020-11-22 13:03:16 +05303803 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003804
c_mtharue1a5ce12017-10-13 20:47:09 +05303805 VERIFY(err, fl != NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003806 if (err)
3807 goto bail;
Edgar Flores1a772fa2020-02-07 14:59:29 -08003808 err = fastrpc_set_process_info(fl);
3809 if (err)
3810 goto bail;
Jeya Rf4b99852020-11-22 13:03:16 +05303811 cid = *info;
Sathish Ambley36849af2017-02-02 09:35:55 -08003812 if (fl->cid == -1) {
Jeya Rf4b99852020-11-22 13:03:16 +05303813 struct fastrpc_channel_ctx *chan = &me->channel[cid];
3814
Sathish Ambley36849af2017-02-02 09:35:55 -08003815 VERIFY(err, cid < NUM_CHANNELS);
3816 if (err)
3817 goto bail;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303818 /* Check to see if the device node is non-secure */
zhaochenfc798572018-08-17 15:32:37 +08003819 if (fl->dev_minor == MINOR_NUM_DEV &&
3820 fl->apps->secure_flag == true) {
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303821 /*
Jeya Rf4b99852020-11-22 13:03:16 +05303822 * If an app is trying to offload to a secure remote
3823 * channel by opening the non-secure device node, allow
3824 * the access if the subsystem supports unsigned
3825 * offload. Untrusted apps will be restricted.
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303826 */
Jeya Rf4b99852020-11-22 13:03:16 +05303827 if (chan->secure == SECURE_CHANNEL &&
3828 !chan->unsigned_support) {
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303829 err = -EPERM;
3830 pr_err("adsprpc: GetInfo failed dev %d, cid %d, secure %d\n",
3831 fl->dev_minor, cid,
3832 fl->apps->channel[cid].secure);
3833 goto bail;
3834 }
3835 }
Sathish Ambley36849af2017-02-02 09:35:55 -08003836 fl->cid = cid;
3837 fl->ssrcount = fl->apps->channel[cid].ssrcount;
3838 VERIFY(err, !fastrpc_session_alloc_locked(
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303839 &fl->apps->channel[cid], 0, fl->sharedcb, &fl->sctx));
Sathish Ambley36849af2017-02-02 09:35:55 -08003840 if (err)
3841 goto bail;
3842 }
Tharun Kumar Merugu80be7d62017-08-02 11:03:22 +05303843 VERIFY(err, fl->sctx != NULL);
Jeya R984a1a32021-01-18 15:38:07 +05303844 if (err) {
3845 err = -EBADR;
Tharun Kumar Merugu80be7d62017-08-02 11:03:22 +05303846 goto bail;
Jeya R984a1a32021-01-18 15:38:07 +05303847 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003848 *info = (fl->sctx->smmu.enabled ? 1 : 0);
3849bail:
3850 return err;
3851}
3852
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303853static int fastrpc_internal_control(struct fastrpc_file *fl,
3854 struct fastrpc_ioctl_control *cp)
3855{
Mohammed Nayeem Ur Rahman18d633f2019-05-28 15:11:40 +05303856 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303857 int err = 0;
3858 int latency;
3859
3860 VERIFY(err, !IS_ERR_OR_NULL(fl) && !IS_ERR_OR_NULL(fl->apps));
3861 if (err)
3862 goto bail;
3863 VERIFY(err, !IS_ERR_OR_NULL(cp));
3864 if (err)
3865 goto bail;
3866
3867 switch (cp->req) {
3868 case FASTRPC_CONTROL_LATENCY:
3869 latency = cp->lp.enable == FASTRPC_LATENCY_CTRL_ENB ?
3870 fl->apps->latency : PM_QOS_DEFAULT_VALUE;
3871 VERIFY(err, latency != 0);
3872 if (err)
3873 goto bail;
Jeya R1b85ca52021-06-10 13:03:44 +05303874 mutex_lock(&fl->pm_qos_mutex);
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303875 if (!fl->qos_request) {
3876 pm_qos_add_request(&fl->pm_qos_req,
3877 PM_QOS_CPU_DMA_LATENCY, latency);
3878 fl->qos_request = 1;
3879 } else
3880 pm_qos_update_request(&fl->pm_qos_req, latency);
Jeya R1b85ca52021-06-10 13:03:44 +05303881 mutex_unlock(&fl->pm_qos_mutex);
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303882 break;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303883 case FASTRPC_CONTROL_SMMU:
Mohammed Nayeem Ur Rahman18d633f2019-05-28 15:11:40 +05303884 if (!me->legacy)
3885 fl->sharedcb = cp->smmu.sharedcb;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303886 break;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303887 case FASTRPC_CONTROL_KALLOC:
3888 cp->kalloc.kalloc_support = 1;
3889 break;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303890 default:
3891 err = -ENOTTY;
3892 break;
3893 }
3894bail:
3895 return err;
3896}
3897
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05303898static int fastrpc_get_dsp_info(struct fastrpc_ioctl_dsp_capabilities *dsp_cap,
3899 void *param, struct fastrpc_file *fl)
3900{
3901 int err = 0;
3902
3903 K_COPY_FROM_USER(err, 0, dsp_cap, param,
3904 sizeof(struct fastrpc_ioctl_dsp_capabilities));
3905 VERIFY(err, dsp_cap->domain < NUM_CHANNELS);
3906 if (err)
3907 goto bail;
3908
3909 err = fastrpc_get_info_from_kernel(dsp_cap, fl);
3910 if (err)
3911 goto bail;
3912 K_COPY_TO_USER(err, 0, param, dsp_cap,
3913 sizeof(struct fastrpc_ioctl_dsp_capabilities));
3914bail:
3915 return err;
3916}
3917
Vamsi Krishna Gattupallid1e4dff2021-05-28 14:19:24 +05303918static int fastrpc_update_cdsp_support(struct fastrpc_file *fl)
3919{
3920 struct fastrpc_ioctl_dsp_capabilities *dsp_query;
3921 struct fastrpc_apps *me = &gfa;
3922 int err = 0;
3923
3924 VERIFY(err, NULL != (dsp_query = kzalloc(sizeof(*dsp_query),
3925 GFP_KERNEL)));
3926 if (err)
3927 goto bail;
3928 dsp_query->domain = CDSP_DOMAIN_ID;
3929 err = fastrpc_get_info_from_kernel(dsp_query, fl);
3930 if (err)
3931 goto bail;
3932 if (!(dsp_query->dsp_attributes[1]))
3933 me->channel[CDSP_DOMAIN_ID].unsigned_support = false;
3934bail:
3935 kfree(dsp_query);
3936 return err;
3937}
3938
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003939static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
3940 unsigned long ioctl_param)
3941{
3942 union {
Sathish Ambleybae51902017-07-03 15:00:49 -07003943 struct fastrpc_ioctl_invoke_crc inv;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003944 struct fastrpc_ioctl_mmap mmap;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303945 struct fastrpc_ioctl_mmap_64 mmap64;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003946 struct fastrpc_ioctl_munmap munmap;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303947 struct fastrpc_ioctl_munmap_64 munmap64;
c_mtharu7bd6a422017-10-17 18:15:37 +05303948 struct fastrpc_ioctl_munmap_fd munmap_fd;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08003949 struct fastrpc_ioctl_init_attrs init;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003950 struct fastrpc_ioctl_perf perf;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303951 struct fastrpc_ioctl_control cp;
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05303952 struct fastrpc_ioctl_dsp_capabilities dsp_cap;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003953 } p;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303954 union {
3955 struct fastrpc_ioctl_mmap mmap;
3956 struct fastrpc_ioctl_munmap munmap;
3957 } i;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003958 void *param = (char *)ioctl_param;
3959 struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
vgattupa02170ba2021-06-30 14:25:33 +05303960 int size = 0, err = 0, req_complete = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003961 uint32_t info;
Vamsi Krishna Gattupallid1e4dff2021-05-28 14:19:24 +05303962 static bool isQueryDone;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003963
Jeya Rb70b4ad2021-01-25 10:28:42 -08003964 VERIFY(err, fl != NULL);
3965 if (err) {
3966 err = -EBADR;
3967 goto bail;
3968 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303969 p.inv.fds = NULL;
3970 p.inv.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07003971 p.inv.crc = NULL;
tharun kumar9f899ea2017-07-03 17:07:03 +05303972 spin_lock(&fl->hlock);
3973 if (fl->file_close == 1) {
3974 err = EBADF;
3975 pr_warn("ADSPRPC: fastrpc_device_release is happening, So not sending any new requests to DSP");
3976 spin_unlock(&fl->hlock);
3977 goto bail;
3978 }
3979 spin_unlock(&fl->hlock);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003980
3981 switch (ioctl_num) {
3982 case FASTRPC_IOCTL_INVOKE:
3983 size = sizeof(struct fastrpc_ioctl_invoke);
Sathish Ambleybae51902017-07-03 15:00:49 -07003984 /* fall through */
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003985 case FASTRPC_IOCTL_INVOKE_FD:
3986 if (!size)
3987 size = sizeof(struct fastrpc_ioctl_invoke_fd);
3988 /* fall through */
3989 case FASTRPC_IOCTL_INVOKE_ATTRS:
3990 if (!size)
3991 size = sizeof(struct fastrpc_ioctl_invoke_attrs);
Sathish Ambleybae51902017-07-03 15:00:49 -07003992 /* fall through */
3993 case FASTRPC_IOCTL_INVOKE_CRC:
3994 if (!size)
3995 size = sizeof(struct fastrpc_ioctl_invoke_crc);
c_mtharue1a5ce12017-10-13 20:47:09 +05303996 K_COPY_FROM_USER(err, 0, &p.inv, param, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003997 if (err)
3998 goto bail;
3999 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode,
4000 0, &p.inv)));
4001 if (err)
4002 goto bail;
4003 break;
4004 case FASTRPC_IOCTL_MMAP:
c_mtharue1a5ce12017-10-13 20:47:09 +05304005 K_COPY_FROM_USER(err, 0, &p.mmap, param,
4006 sizeof(p.mmap));
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05304007 if (err)
4008 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004009 VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap)));
4010 if (err)
4011 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05304012 K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004013 if (err)
4014 goto bail;
4015 break;
4016 case FASTRPC_IOCTL_MUNMAP:
c_mtharue1a5ce12017-10-13 20:47:09 +05304017 K_COPY_FROM_USER(err, 0, &p.munmap, param,
4018 sizeof(p.munmap));
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05304019 if (err)
4020 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004021 VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
4022 &p.munmap)));
4023 if (err)
4024 goto bail;
4025 break;
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05304026 case FASTRPC_IOCTL_MMAP_64:
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05304027 K_COPY_FROM_USER(err, 0, &p.mmap64, param,
4028 sizeof(p.mmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05304029 if (err)
4030 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05304031 get_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
4032 VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &i.mmap)));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05304033 if (err)
4034 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05304035 put_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
4036 K_COPY_TO_USER(err, 0, param, &p.mmap64, sizeof(p.mmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05304037 if (err)
4038 goto bail;
4039 break;
4040 case FASTRPC_IOCTL_MUNMAP_64:
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05304041 K_COPY_FROM_USER(err, 0, &p.munmap64, param,
4042 sizeof(p.munmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05304043 if (err)
4044 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05304045 get_fastrpc_ioctl_munmap_64(&p.munmap64, &i.munmap);
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05304046 VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05304047 &i.munmap)));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05304048 if (err)
4049 goto bail;
4050 break;
c_mtharu7bd6a422017-10-17 18:15:37 +05304051 case FASTRPC_IOCTL_MUNMAP_FD:
4052 K_COPY_FROM_USER(err, 0, &p.munmap_fd, param,
4053 sizeof(p.munmap_fd));
4054 if (err)
4055 goto bail;
4056 VERIFY(err, 0 == (err = fastrpc_internal_munmap_fd(fl,
4057 &p.munmap_fd)));
4058 if (err)
4059 goto bail;
4060 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004061 case FASTRPC_IOCTL_SETMODE:
4062 switch ((uint32_t)ioctl_param) {
4063 case FASTRPC_MODE_PARALLEL:
4064 case FASTRPC_MODE_SERIAL:
4065 fl->mode = (uint32_t)ioctl_param;
4066 break;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08004067 case FASTRPC_MODE_PROFILE:
4068 fl->profile = (uint32_t)ioctl_param;
4069 break;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05304070 case FASTRPC_MODE_SESSION:
4071 fl->sessionid = 1;
4072 fl->tgid |= (1 << SESSION_ID_INDEX);
4073 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004074 default:
4075 err = -ENOTTY;
4076 break;
4077 }
4078 break;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08004079 case FASTRPC_IOCTL_GETPERF:
c_mtharue1a5ce12017-10-13 20:47:09 +05304080 K_COPY_FROM_USER(err, 0, &p.perf,
4081 param, sizeof(p.perf));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08004082 if (err)
4083 goto bail;
4084 p.perf.numkeys = sizeof(struct fastrpc_perf)/sizeof(int64_t);
4085 if (p.perf.keys) {
4086 char *keys = PERF_KEYS;
4087
c_mtharue1a5ce12017-10-13 20:47:09 +05304088 K_COPY_TO_USER(err, 0, (void *)p.perf.keys,
4089 keys, strlen(keys)+1);
Sathish Ambleya21b5b52017-01-11 16:11:01 -08004090 if (err)
4091 goto bail;
4092 }
4093 if (p.perf.data) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05304094 struct fastrpc_perf *perf = NULL, *fperf = NULL;
4095 struct hlist_node *n = NULL;
4096
4097 mutex_lock(&fl->perf_mutex);
4098 hlist_for_each_entry_safe(perf, n, &fl->perf, hn) {
4099 if (perf->tid == current->pid) {
4100 fperf = perf;
4101 break;
4102 }
4103 }
4104
4105 mutex_unlock(&fl->perf_mutex);
4106
4107 if (fperf) {
4108 K_COPY_TO_USER(err, 0, (void *)p.perf.data,
4109 fperf, sizeof(*fperf));
4110 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08004111 }
c_mtharue1a5ce12017-10-13 20:47:09 +05304112 K_COPY_TO_USER(err, 0, param, &p.perf, sizeof(p.perf));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08004113 if (err)
4114 goto bail;
4115 break;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05304116 case FASTRPC_IOCTL_CONTROL:
c_mtharue1a5ce12017-10-13 20:47:09 +05304117 K_COPY_FROM_USER(err, 0, &p.cp, param,
4118 sizeof(p.cp));
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05304119 if (err)
4120 goto bail;
4121 VERIFY(err, 0 == (err = fastrpc_internal_control(fl, &p.cp)));
4122 if (err)
4123 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05304124 if (p.cp.req == FASTRPC_CONTROL_KALLOC) {
4125 K_COPY_TO_USER(err, 0, param, &p.cp, sizeof(p.cp));
4126 if (err)
4127 goto bail;
4128 }
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05304129 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004130 case FASTRPC_IOCTL_GETINFO:
c_mtharue1a5ce12017-10-13 20:47:09 +05304131 K_COPY_FROM_USER(err, 0, &info, param, sizeof(info));
Sathish Ambley36849af2017-02-02 09:35:55 -08004132 if (err)
4133 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004134 VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info)));
4135 if (err)
4136 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05304137 K_COPY_TO_USER(err, 0, param, &info, sizeof(info));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004138 if (err)
4139 goto bail;
4140 break;
4141 case FASTRPC_IOCTL_INIT:
Sathish Ambleyd6300c32017-01-18 09:50:43 -08004142 p.init.attrs = 0;
4143 p.init.siglen = 0;
4144 size = sizeof(struct fastrpc_ioctl_init);
4145 /* fall through */
4146 case FASTRPC_IOCTL_INIT_ATTRS:
4147 if (!size)
4148 size = sizeof(struct fastrpc_ioctl_init_attrs);
c_mtharue1a5ce12017-10-13 20:47:09 +05304149 K_COPY_FROM_USER(err, 0, &p.init, param, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004150 if (err)
4151 goto bail;
Tharun Kumar Merugu4ea0eac2017-08-22 11:42:51 +05304152 VERIFY(err, p.init.init.filelen >= 0 &&
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05304153 p.init.init.filelen < INIT_FILELEN_MAX);
4154 if (err)
4155 goto bail;
4156 VERIFY(err, p.init.init.memlen >= 0 &&
4157 p.init.init.memlen < INIT_MEMLEN_MAX);
Tharun Kumar Merugu4ea0eac2017-08-22 11:42:51 +05304158 if (err)
4159 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304160 VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004161 if (err)
4162 goto bail;
Vamsi Krishna Gattupallid1e4dff2021-05-28 14:19:24 +05304163 if ((fl->cid == CDSP_DOMAIN_ID) && !isQueryDone) {
vgattupa02170ba2021-06-30 14:25:33 +05304164 req_complete = fastrpc_update_cdsp_support(fl);
4165 if (!req_complete)
Vamsi Krishna Gattupallid1e4dff2021-05-28 14:19:24 +05304166 isQueryDone = true;
4167 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004168 break;
Tharun Kumar Meruguebe00202019-04-05 03:34:28 +05304169 case FASTRPC_IOCTL_GET_DSP_INFO:
4170 err = fastrpc_get_dsp_info(&p.dsp_cap, param, fl);
4171 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004172 default:
4173 err = -ENOTTY;
4174 pr_info("bad ioctl: %d\n", ioctl_num);
4175 break;
4176 }
4177 bail:
4178 return err;
4179}
4180
4181static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
4182 unsigned long code,
4183 void *data)
4184{
4185 struct fastrpc_apps *me = &gfa;
4186 struct fastrpc_channel_ctx *ctx;
c_mtharue1a5ce12017-10-13 20:47:09 +05304187 struct notif_data *notifdata = data;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004188 int cid;
4189
4190 ctx = container_of(nb, struct fastrpc_channel_ctx, nb);
4191 cid = ctx - &me->channel[0];
4192 if (code == SUBSYS_BEFORE_SHUTDOWN) {
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304193 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004194 ctx->ssrcount++;
c_mtharue1a5ce12017-10-13 20:47:09 +05304195 ctx->issubsystemup = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304196 if (ctx->chan) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304197 if (me->glink)
4198 fastrpc_glink_close(ctx->chan, cid);
4199 else
4200 smd_close(ctx->chan);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304201 ctx->chan = NULL;
4202 pr_info("'restart notifier: closed /dev/%s c %d %d'\n",
4203 gcinfo[cid].name, MAJOR(me->dev_no), cid);
4204 }
4205 mutex_unlock(&me->smd_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05304206 if (cid == 0)
4207 me->staticpd_flags = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004208 fastrpc_notify_drivers(me, cid);
c_mtharue1a5ce12017-10-13 20:47:09 +05304209 } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) {
4210 if (me->channel[0].remoteheap_ramdump_dev &&
4211 notifdata->enable_ramdump) {
4212 me->channel[0].ramdumpenabled = 1;
4213 }
4214 } else if (code == SUBSYS_AFTER_POWERUP) {
4215 ctx->issubsystemup = 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004216 }
4217
4218 return NOTIFY_DONE;
4219}
4220
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304221static int fastrpc_pdr_notifier_cb(struct notifier_block *pdrnb,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304222 unsigned long code,
4223 void *data)
4224{
4225 struct fastrpc_apps *me = &gfa;
4226 struct fastrpc_static_pd *spd;
4227 struct notif_data *notifdata = data;
4228
4229 spd = container_of(pdrnb, struct fastrpc_static_pd, pdrnb);
4230 if (code == SERVREG_NOTIF_SERVICE_STATE_DOWN_V01) {
4231 mutex_lock(&me->smd_mutex);
4232 spd->pdrcount++;
4233 spd->ispdup = 0;
4234 pr_info("ADSPRPC: Audio PDR notifier %d %s\n",
4235 MAJOR(me->dev_no), spd->spdname);
4236 mutex_unlock(&me->smd_mutex);
4237 if (!strcmp(spd->spdname,
4238 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME))
4239 me->staticpd_flags = 0;
4240 fastrpc_notify_pdr_drivers(me, spd->spdname);
4241 } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) {
4242 if (me->channel[0].remoteheap_ramdump_dev &&
4243 notifdata->enable_ramdump) {
4244 me->channel[0].ramdumpenabled = 1;
4245 }
4246 } else if (code == SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
4247 spd->ispdup = 1;
4248 }
4249
4250 return NOTIFY_DONE;
4251}
4252
4253static int fastrpc_get_service_location_notify(struct notifier_block *nb,
Vamsi krishna Gattupalli4c11c602020-08-25 19:34:14 +05304254 unsigned long opcode, void *data)
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304255{
4256 struct fastrpc_static_pd *spd;
4257 struct pd_qmi_client_data *pdr = data;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304258 int curr_state = 0, i = 0;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304259
4260 spd = container_of(nb, struct fastrpc_static_pd, get_service_nb);
4261 if (opcode == LOCATOR_DOWN) {
4262 pr_err("ADSPRPC: Audio PD restart notifier locator down\n");
4263 return NOTIFY_DONE;
4264 }
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304265 for (i = 0; i < pdr->total_domains; i++) {
Vamsi krishna Gattupalli4c11c602020-08-25 19:34:14 +05304266 if ((!strcmp(spd->spdname, "audio_pdr_adsprpc"))
4267 && (!strcmp(pdr->domain_list[i].name,
4268 "msm/adsp/audio_pd"))) {
4269 goto pdr_register;
4270 } else if ((!strcmp(spd->spdname, "sensors_pdr_adsprpc"))
4271 && (!strcmp(pdr->domain_list[i].name,
4272 "msm/adsp/sensor_pd"))) {
4273 goto pdr_register;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304274 }
4275 }
Vamsi krishna Gattupalli4c11c602020-08-25 19:34:14 +05304276 return NOTIFY_DONE;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304277
Vamsi krishna Gattupalli4c11c602020-08-25 19:34:14 +05304278pdr_register:
4279 if (!spd->pdrhandle) {
4280 spd->pdrhandle =
4281 service_notif_register_notifier(
4282 pdr->domain_list[i].name,
4283 pdr->domain_list[i].instance_id,
4284 &spd->pdrnb, &curr_state);
4285 } else {
4286 pr_err("ADSPRPC: %s is already registered\n", spd->spdname);
4287 }
4288
4289 if (IS_ERR(spd->pdrhandle))
4290 pr_err("ADSPRPC: Unable to register notifier\n");
4291
4292 if (curr_state == SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
4293 pr_info("ADSPRPC: %s is up\n", spd->spdname);
4294 spd->ispdup = 1;
4295 } else if (curr_state == SERVREG_NOTIF_SERVICE_STATE_UNINIT_V01) {
4296 pr_info("ADSPRPC: %s is uninitialzed\n", spd->spdname);
4297 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304298 return NOTIFY_DONE;
4299}
4300
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004301static const struct file_operations fops = {
4302 .open = fastrpc_device_open,
4303 .release = fastrpc_device_release,
4304 .unlocked_ioctl = fastrpc_device_ioctl,
4305 .compat_ioctl = compat_fastrpc_device_ioctl,
4306};
4307
4308static const struct of_device_id fastrpc_match_table[] = {
4309 { .compatible = "qcom,msm-fastrpc-adsp", },
4310 { .compatible = "qcom,msm-fastrpc-compute", },
4311 { .compatible = "qcom,msm-fastrpc-compute-cb", },
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304312 { .compatible = "qcom,msm-fastrpc-legacy-compute", },
4313 { .compatible = "qcom,msm-fastrpc-legacy-compute-cb", },
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004314 { .compatible = "qcom,msm-adsprpc-mem-region", },
4315 {}
4316};
4317
4318static int fastrpc_cb_probe(struct device *dev)
4319{
4320 struct fastrpc_channel_ctx *chan;
4321 struct fastrpc_session_ctx *sess;
4322 struct of_phandle_args iommuspec;
4323 const char *name;
4324 unsigned int start = 0x80000000;
4325 int err = 0, i;
4326 int secure_vmid = VMID_CP_PIXEL;
4327
c_mtharue1a5ce12017-10-13 20:47:09 +05304328 VERIFY(err, NULL != (name = of_get_property(dev->of_node,
4329 "label", NULL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004330 if (err)
4331 goto bail;
4332 for (i = 0; i < NUM_CHANNELS; i++) {
4333 if (!gcinfo[i].name)
4334 continue;
4335 if (!strcmp(name, gcinfo[i].name))
4336 break;
4337 }
4338 VERIFY(err, i < NUM_CHANNELS);
4339 if (err)
4340 goto bail;
4341 chan = &gcinfo[i];
4342 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4343 if (err)
4344 goto bail;
4345
4346 VERIFY(err, !of_parse_phandle_with_args(dev->of_node, "iommus",
4347 "#iommu-cells", 0, &iommuspec));
4348 if (err)
4349 goto bail;
4350 sess = &chan->session[chan->sesscount];
4351 sess->smmu.cb = iommuspec.args[0] & 0xf;
4352 sess->used = 0;
4353 sess->smmu.coherent = of_property_read_bool(dev->of_node,
4354 "dma-coherent");
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304355 sess->smmu.sharedcb = of_property_read_bool(dev->of_node,
4356 "shared-cb");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004357 sess->smmu.secure = of_property_read_bool(dev->of_node,
4358 "qcom,secure-context-bank");
4359 if (sess->smmu.secure)
4360 start = 0x60000000;
4361 VERIFY(err, !IS_ERR_OR_NULL(sess->smmu.mapping =
4362 arm_iommu_create_mapping(&platform_bus_type,
Mohammed Nayeem Ur Rahman62f7f9c2020-04-13 11:16:19 +05304363 start, MAX_SIZE_LIMIT)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004364 if (err)
4365 goto bail;
4366
4367 if (sess->smmu.secure)
4368 iommu_domain_set_attr(sess->smmu.mapping->domain,
4369 DOMAIN_ATTR_SECURE_VMID,
4370 &secure_vmid);
4371
4372 VERIFY(err, !arm_iommu_attach_device(dev, sess->smmu.mapping));
4373 if (err)
4374 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05304375 sess->smmu.dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004376 sess->smmu.enabled = 1;
4377 chan->sesscount++;
Sathish Ambley1ca68232017-01-19 10:32:55 -08004378 debugfs_global_file = debugfs_create_file("global", 0644, debugfs_root,
4379 NULL, &debugfs_fops);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004380bail:
4381 return err;
4382}
4383
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304384static int fastrpc_cb_legacy_probe(struct device *dev)
4385{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304386 struct fastrpc_channel_ctx *chan;
4387 struct fastrpc_session_ctx *first_sess = NULL, *sess = NULL;
4388 const char *name;
4389 unsigned int *sids = NULL, sids_size = 0;
4390 int err = 0, ret = 0, i;
4391
4392 unsigned int start = 0x80000000;
4393
4394 VERIFY(err, NULL != (name = of_get_property(dev->of_node,
4395 "label", NULL)));
4396 if (err)
4397 goto bail;
4398
4399 for (i = 0; i < NUM_CHANNELS; i++) {
4400 if (!gcinfo[i].name)
4401 continue;
4402 if (!strcmp(name, gcinfo[i].name))
4403 break;
4404 }
4405 VERIFY(err, i < NUM_CHANNELS);
4406 if (err)
4407 goto bail;
4408
4409 chan = &gcinfo[i];
4410 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4411 if (err)
4412 goto bail;
4413
4414 first_sess = &chan->session[chan->sesscount];
4415
4416 VERIFY(err, NULL != of_get_property(dev->of_node,
4417 "sids", &sids_size));
4418 if (err)
4419 goto bail;
4420
4421 VERIFY(err, NULL != (sids = kzalloc(sids_size, GFP_KERNEL)));
4422 if (err)
4423 goto bail;
4424 ret = of_property_read_u32_array(dev->of_node, "sids", sids,
4425 sids_size/sizeof(unsigned int));
4426 if (ret)
4427 goto bail;
4428
4429 VERIFY(err, !IS_ERR_OR_NULL(first_sess->smmu.mapping =
4430 arm_iommu_create_mapping(&platform_bus_type,
4431 start, 0x78000000)));
4432 if (err)
4433 goto bail;
4434
4435 VERIFY(err, !arm_iommu_attach_device(dev, first_sess->smmu.mapping));
4436 if (err)
4437 goto bail;
4438
4439
4440 for (i = 0; i < sids_size/sizeof(unsigned int); i++) {
4441 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4442 if (err)
4443 goto bail;
4444 sess = &chan->session[chan->sesscount];
4445 sess->smmu.cb = sids[i];
4446 sess->smmu.dev = dev;
4447 sess->smmu.mapping = first_sess->smmu.mapping;
4448 sess->smmu.enabled = 1;
4449 sess->used = 0;
4450 sess->smmu.coherent = false;
4451 sess->smmu.secure = false;
4452 chan->sesscount++;
4453 }
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304454bail:
4455 kfree(sids);
4456 return err;
4457}
4458
4459
4460
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304461static void init_secure_vmid_list(struct device *dev, char *prop_name,
4462 struct secure_vm *destvm)
4463{
4464 int err = 0;
4465 u32 len = 0, i = 0;
4466 u32 *rhvmlist = NULL;
4467 u32 *rhvmpermlist = NULL;
4468
4469 if (!of_find_property(dev->of_node, prop_name, &len))
4470 goto bail;
4471 if (len == 0)
4472 goto bail;
4473 len /= sizeof(u32);
4474 VERIFY(err, NULL != (rhvmlist = kcalloc(len, sizeof(u32), GFP_KERNEL)));
4475 if (err)
4476 goto bail;
4477 VERIFY(err, NULL != (rhvmpermlist = kcalloc(len, sizeof(u32),
4478 GFP_KERNEL)));
4479 if (err)
4480 goto bail;
4481 for (i = 0; i < len; i++) {
4482 err = of_property_read_u32_index(dev->of_node, prop_name, i,
4483 &rhvmlist[i]);
4484 rhvmpermlist[i] = PERM_READ | PERM_WRITE | PERM_EXEC;
4485 pr_info("ADSPRPC: Secure VMID = %d", rhvmlist[i]);
4486 if (err) {
4487 pr_err("ADSPRPC: Failed to read VMID\n");
4488 goto bail;
4489 }
4490 }
4491 destvm->vmid = rhvmlist;
4492 destvm->vmperm = rhvmpermlist;
4493 destvm->vmcount = len;
4494bail:
4495 if (err) {
4496 kfree(rhvmlist);
4497 kfree(rhvmpermlist);
4498 }
4499}
4500
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304501static void configure_secure_channels(uint32_t secure_domains)
4502{
4503 struct fastrpc_apps *me = &gfa;
4504 int ii = 0;
4505 /*
4506 * secure_domains contains the bitmask of the secure channels
4507 * Bit 0 - ADSP
4508 * Bit 1 - MDSP
4509 * Bit 2 - SLPI
4510 * Bit 3 - CDSP
4511 */
4512 for (ii = ADSP_DOMAIN_ID; ii <= CDSP_DOMAIN_ID; ++ii) {
4513 int secure = (secure_domains >> ii) & 0x01;
4514
4515 me->channel[ii].secure = secure;
4516 }
4517}
4518
4519
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004520static int fastrpc_probe(struct platform_device *pdev)
4521{
4522 int err = 0;
4523 struct fastrpc_apps *me = &gfa;
4524 struct device *dev = &pdev->dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004525 struct device_node *ion_node, *node;
4526 struct platform_device *ion_pdev;
4527 struct cma *cma;
4528 uint32_t val;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304529 int ret = 0;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304530 uint32_t secure_domains;
c_mtharu63ffc012017-11-16 15:26:56 +05304531
4532 if (of_device_is_compatible(dev->of_node,
4533 "qcom,msm-fastrpc-compute")) {
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304534 init_secure_vmid_list(dev, "qcom,adsp-remoteheap-vmid",
4535 &gcinfo[0].rhvm);
c_mtharu63ffc012017-11-16 15:26:56 +05304536
c_mtharu63ffc012017-11-16 15:26:56 +05304537
4538 of_property_read_u32(dev->of_node, "qcom,rpc-latency-us",
4539 &me->latency);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304540 if (of_get_property(dev->of_node,
4541 "qcom,secure-domains", NULL) != NULL) {
4542 VERIFY(err, !of_property_read_u32(dev->of_node,
4543 "qcom,secure-domains",
4544 &secure_domains));
zhaochenfc798572018-08-17 15:32:37 +08004545 if (!err) {
4546 me->secure_flag = true;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304547 configure_secure_channels(secure_domains);
zhaochenfc798572018-08-17 15:32:37 +08004548 } else {
4549 me->secure_flag = false;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304550 pr_info("adsprpc: unable to read the domain configuration from dts\n");
zhaochenfc798572018-08-17 15:32:37 +08004551 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304552 }
c_mtharu63ffc012017-11-16 15:26:56 +05304553 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004554 if (of_device_is_compatible(dev->of_node,
4555 "qcom,msm-fastrpc-compute-cb"))
4556 return fastrpc_cb_probe(dev);
4557
4558 if (of_device_is_compatible(dev->of_node,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304559 "qcom,msm-fastrpc-legacy-compute")) {
4560 me->glink = false;
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304561 me->legacy = 1;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304562 }
4563
4564 if (of_device_is_compatible(dev->of_node,
4565 "qcom,msm-fastrpc-legacy-compute-cb")){
4566 return fastrpc_cb_legacy_probe(dev);
4567 }
4568
4569 if (of_device_is_compatible(dev->of_node,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004570 "qcom,msm-adsprpc-mem-region")) {
4571 me->dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004572 ion_node = of_find_compatible_node(NULL, NULL, "qcom,msm-ion");
4573 if (ion_node) {
4574 for_each_available_child_of_node(ion_node, node) {
4575 if (of_property_read_u32(node, "reg", &val))
4576 continue;
4577 if (val != ION_ADSP_HEAP_ID)
4578 continue;
4579 ion_pdev = of_find_device_by_node(node);
4580 if (!ion_pdev)
4581 break;
4582 cma = dev_get_cma_area(&ion_pdev->dev);
4583 if (cma) {
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304584 me->range.addr = cma_get_base(cma);
4585 me->range.size =
4586 (size_t)cma_get_size(cma);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004587 }
4588 break;
4589 }
4590 }
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304591 if (me->range.addr && !of_property_read_bool(dev->of_node,
Tharun Kumar Merugu6b7a4a22018-01-17 16:08:07 +05304592 "restrict-access")) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004593 int srcVM[1] = {VMID_HLOS};
4594 int destVM[4] = {VMID_HLOS, VMID_MSS_MSA, VMID_SSC_Q6,
4595 VMID_ADSP_Q6};
Sathish Ambley84d11862017-05-15 14:36:05 -07004596 int destVMperm[4] = {PERM_READ | PERM_WRITE | PERM_EXEC,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004597 PERM_READ | PERM_WRITE | PERM_EXEC,
4598 PERM_READ | PERM_WRITE | PERM_EXEC,
4599 PERM_READ | PERM_WRITE | PERM_EXEC,
4600 };
4601
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304602 VERIFY(err, !hyp_assign_phys(me->range.addr,
4603 me->range.size, srcVM, 1,
4604 destVM, destVMperm, 4));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004605 if (err)
4606 goto bail;
4607 }
4608 return 0;
4609 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304610 if (of_property_read_bool(dev->of_node,
4611 "qcom,fastrpc-adsp-audio-pdr")) {
4612 int session;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004613
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304614 VERIFY(err, !fastrpc_get_adsp_session(
4615 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
4616 if (err)
4617 goto spdbail;
4618 me->channel[0].spd[session].get_service_nb.notifier_call =
4619 fastrpc_get_service_location_notify;
4620 ret = get_service_location(
4621 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
4622 AUDIO_PDR_ADSP_SERVICE_NAME,
4623 &me->channel[0].spd[session].get_service_nb);
4624 if (ret)
4625 pr_err("ADSPRPC: Get service location failed: %d\n",
4626 ret);
4627 }
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304628 if (of_property_read_bool(dev->of_node,
4629 "qcom,fastrpc-adsp-sensors-pdr")) {
4630 int session;
4631
4632 VERIFY(err, !fastrpc_get_adsp_session(
4633 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
4634 if (err)
4635 goto spdbail;
4636 me->channel[0].spd[session].get_service_nb.notifier_call =
4637 fastrpc_get_service_location_notify;
4638 ret = get_service_location(
4639 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME,
4640 SENSORS_PDR_ADSP_SERVICE_NAME,
4641 &me->channel[0].spd[session].get_service_nb);
4642 if (ret)
4643 pr_err("ADSPRPC: Get service location failed: %d\n",
4644 ret);
4645 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304646spdbail:
4647 err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004648 VERIFY(err, !of_platform_populate(pdev->dev.of_node,
4649 fastrpc_match_table,
4650 NULL, &pdev->dev));
4651 if (err)
4652 goto bail;
4653bail:
4654 return err;
4655}
4656
4657static void fastrpc_deinit(void)
4658{
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304659 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004660 struct fastrpc_channel_ctx *chan = gcinfo;
4661 int i, j;
4662
4663 for (i = 0; i < NUM_CHANNELS; i++, chan++) {
4664 if (chan->chan) {
4665 kref_put_mutex(&chan->kref,
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304666 fastrpc_channel_close, &me->smd_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05304667 chan->chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004668 }
4669 for (j = 0; j < NUM_SESSIONS; j++) {
4670 struct fastrpc_session_ctx *sess = &chan->session[j];
c_mtharue1a5ce12017-10-13 20:47:09 +05304671 if (sess->smmu.dev) {
4672 arm_iommu_detach_device(sess->smmu.dev);
4673 sess->smmu.dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004674 }
4675 if (sess->smmu.mapping) {
4676 arm_iommu_release_mapping(sess->smmu.mapping);
c_mtharue1a5ce12017-10-13 20:47:09 +05304677 sess->smmu.mapping = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004678 }
4679 }
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304680 kfree(chan->rhvm.vmid);
4681 kfree(chan->rhvm.vmperm);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004682 }
4683}
4684
4685static struct platform_driver fastrpc_driver = {
4686 .probe = fastrpc_probe,
4687 .driver = {
4688 .name = "fastrpc",
4689 .owner = THIS_MODULE,
4690 .of_match_table = fastrpc_match_table,
4691 },
4692};
4693
4694static int __init fastrpc_device_init(void)
4695{
4696 struct fastrpc_apps *me = &gfa;
c_mtharue1a5ce12017-10-13 20:47:09 +05304697 struct device *dev = NULL;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304698 struct device *secure_dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004699 int err = 0, i;
4700
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05304701 debugfs_root = debugfs_create_dir("adsprpc", NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004702 memset(me, 0, sizeof(*me));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004703 fastrpc_init(me);
4704 me->dev = NULL;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304705 me->glink = true;
zhaochenfc798572018-08-17 15:32:37 +08004706 me->secure_flag = false;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004707 VERIFY(err, 0 == platform_driver_register(&fastrpc_driver));
4708 if (err)
4709 goto register_bail;
4710 VERIFY(err, 0 == alloc_chrdev_region(&me->dev_no, 0, NUM_CHANNELS,
4711 DEVICE_NAME));
4712 if (err)
4713 goto alloc_chrdev_bail;
4714 cdev_init(&me->cdev, &fops);
4715 me->cdev.owner = THIS_MODULE;
4716 VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0),
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304717 NUM_DEVICES));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004718 if (err)
4719 goto cdev_init_bail;
4720 me->class = class_create(THIS_MODULE, "fastrpc");
4721 VERIFY(err, !IS_ERR(me->class));
4722 if (err)
4723 goto class_create_bail;
4724 me->compat = (fops.compat_ioctl == NULL) ? 0 : 1;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304725
4726 /*
4727 * Create devices and register with sysfs
4728 * Create first device with minor number 0
4729 */
Sathish Ambley36849af2017-02-02 09:35:55 -08004730 dev = device_create(me->class, NULL,
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304731 MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV),
4732 NULL, DEVICE_NAME);
Sathish Ambley36849af2017-02-02 09:35:55 -08004733 VERIFY(err, !IS_ERR_OR_NULL(dev));
4734 if (err)
4735 goto device_create_bail;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304736
4737 /* Create secure device with minor number for secure device */
4738 secure_dev = device_create(me->class, NULL,
4739 MKDEV(MAJOR(me->dev_no), MINOR_NUM_SECURE_DEV),
4740 NULL, DEVICE_NAME_SECURE);
4741 VERIFY(err, !IS_ERR_OR_NULL(secure_dev));
4742 if (err)
4743 goto device_create_bail;
4744
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004745 for (i = 0; i < NUM_CHANNELS; i++) {
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304746 me->channel[i].dev = secure_dev;
4747 if (i == CDSP_DOMAIN_ID)
4748 me->channel[i].dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004749 me->channel[i].ssrcount = 0;
4750 me->channel[i].prevssrcount = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05304751 me->channel[i].issubsystemup = 1;
4752 me->channel[i].ramdumpenabled = 0;
4753 me->channel[i].remoteheap_ramdump_dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004754 me->channel[i].nb.notifier_call = fastrpc_restart_notifier_cb;
4755 me->channel[i].handle = subsys_notif_register_notifier(
4756 gcinfo[i].subsys,
4757 &me->channel[i].nb);
4758 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004759 me->client = msm_ion_client_create(DEVICE_NAME);
4760 VERIFY(err, !IS_ERR_OR_NULL(me->client));
4761 if (err)
4762 goto device_create_bail;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05304763
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004764 return 0;
4765device_create_bail:
4766 for (i = 0; i < NUM_CHANNELS; i++) {
Sathish Ambley36849af2017-02-02 09:35:55 -08004767 if (me->channel[i].handle)
4768 subsys_notif_unregister_notifier(me->channel[i].handle,
4769 &me->channel[i].nb);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004770 }
Sathish Ambley36849af2017-02-02 09:35:55 -08004771 if (!IS_ERR_OR_NULL(dev))
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304772 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4773 MINOR_NUM_DEV));
4774 if (!IS_ERR_OR_NULL(secure_dev))
4775 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4776 MINOR_NUM_SECURE_DEV));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004777 class_destroy(me->class);
4778class_create_bail:
4779 cdev_del(&me->cdev);
4780cdev_init_bail:
4781 unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
4782alloc_chrdev_bail:
4783register_bail:
4784 fastrpc_deinit();
4785 return err;
4786}
4787
4788static void __exit fastrpc_device_exit(void)
4789{
4790 struct fastrpc_apps *me = &gfa;
4791 int i;
4792
4793 fastrpc_file_list_dtor(me);
4794 fastrpc_deinit();
4795 for (i = 0; i < NUM_CHANNELS; i++) {
4796 if (!gcinfo[i].name)
4797 continue;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004798 subsys_notif_unregister_notifier(me->channel[i].handle,
4799 &me->channel[i].nb);
4800 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304801
4802 /* Destroy the secure and non secure devices */
4803 device_destroy(me->class, MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV));
4804 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4805 MINOR_NUM_SECURE_DEV));
4806
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004807 class_destroy(me->class);
4808 cdev_del(&me->cdev);
4809 unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
4810 ion_client_destroy(me->client);
Sathish Ambley1ca68232017-01-19 10:32:55 -08004811 debugfs_remove_recursive(debugfs_root);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004812}
4813
4814late_initcall(fastrpc_device_init);
4815module_exit(fastrpc_device_exit);
4816
4817MODULE_LICENSE("GPL v2");