blob: aa3859d9e97818b62d6fc6e0834c6b5b7c5519fc [file] [log] [blame]
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001/*
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302 * Copyright (c) 2012-2020, 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>
20#include <linux/fs.h>
21#include <linux/sched.h>
22#include <linux/module.h>
23#include <linux/cdev.h>
24#include <linux/list.h>
25#include <linux/hash.h>
26#include <linux/msm_ion.h>
27#include <soc/qcom/secure_buffer.h>
28#include <soc/qcom/glink.h>
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +053029#include <soc/qcom/smd.h>
Sathish Ambley69e1ab02016-10-18 10:28:15 -070030#include <soc/qcom/subsystem_notif.h>
31#include <soc/qcom/subsystem_restart.h>
Tharun Kumar Merugudf860662018-01-17 19:59:50 +053032#include <soc/qcom/service-notifier.h>
33#include <soc/qcom/service-locator.h>
Sathish Ambley69e1ab02016-10-18 10:28:15 -070034#include <linux/scatterlist.h>
35#include <linux/fs.h>
36#include <linux/uaccess.h>
37#include <linux/device.h>
38#include <linux/of.h>
39#include <linux/of_address.h>
40#include <linux/of_platform.h>
41#include <linux/dma-contiguous.h>
42#include <linux/cma.h>
43#include <linux/iommu.h>
44#include <linux/kref.h>
45#include <linux/sort.h>
46#include <linux/msm_dma_iommu_mapping.h>
47#include <asm/dma-iommu.h>
c_mtharue1a5ce12017-10-13 20:47:09 +053048#include <soc/qcom/scm.h>
Sathish Ambley69e1ab02016-10-18 10:28:15 -070049#include "adsprpc_compat.h"
50#include "adsprpc_shared.h"
c_mtharue1a5ce12017-10-13 20:47:09 +053051#include <soc/qcom/ramdump.h>
Sathish Ambley1ca68232017-01-19 10:32:55 -080052#include <linux/debugfs.h>
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +053053#include <linux/pm_qos.h>
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 \
109 "count:flush:map:copy:glink:getargs:putargs:invalidate:invoke:tid:ptr"
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +0530110#define FASTRPC_STATIC_HANDLE_KERNEL (1)
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800111#define FASTRPC_STATIC_HANDLE_LISTENER (3)
112#define FASTRPC_STATIC_HANDLE_MAX (20)
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +0530113#define FASTRPC_LATENCY_CTRL_ENB (1)
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800114
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +0530115#define INIT_FILELEN_MAX (2*1024*1024)
116#define INIT_MEMLEN_MAX (8*1024*1024)
117
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800118#define PERF_END (void)0
119
120#define PERF(enb, cnt, ff) \
121 {\
122 struct timespec startT = {0};\
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530123 int64_t *counter = cnt;\
124 if (enb && counter) {\
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800125 getnstimeofday(&startT);\
126 } \
127 ff ;\
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530128 if (enb && counter) {\
129 *counter += getnstimediff(&startT);\
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800130 } \
131 }
132
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530133#define GET_COUNTER(perf_ptr, offset) \
134 (perf_ptr != NULL ?\
135 (((offset >= 0) && (offset < PERF_KEY_MAX)) ?\
136 (int64_t *)(perf_ptr + offset)\
137 : (int64_t *)NULL) : (int64_t *)NULL)
138
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700139static int fastrpc_glink_open(int cid);
140static void fastrpc_glink_close(void *chan, int cid);
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530141static int fastrpc_pdr_notifier_cb(struct notifier_block *nb,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530142 unsigned long code,
143 void *data);
Sathish Ambley1ca68232017-01-19 10:32:55 -0800144static struct dentry *debugfs_root;
145static struct dentry *debugfs_global_file;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700146
147static inline uint64_t buf_page_start(uint64_t buf)
148{
149 uint64_t start = (uint64_t) buf & PAGE_MASK;
150 return start;
151}
152
153static inline uint64_t buf_page_offset(uint64_t buf)
154{
155 uint64_t offset = (uint64_t) buf & (PAGE_SIZE - 1);
156 return offset;
157}
158
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530159static inline uint64_t buf_num_pages(uint64_t buf, size_t len)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700160{
161 uint64_t start = buf_page_start(buf) >> PAGE_SHIFT;
162 uint64_t end = (((uint64_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530163 uint64_t nPages = end - start + 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700164 return nPages;
165}
166
167static inline uint64_t buf_page_size(uint32_t size)
168{
169 uint64_t sz = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
170
171 return sz > PAGE_SIZE ? sz : PAGE_SIZE;
172}
173
174static inline void *uint64_to_ptr(uint64_t addr)
175{
176 void *ptr = (void *)((uintptr_t)addr);
177
178 return ptr;
179}
180
181static inline uint64_t ptr_to_uint64(void *ptr)
182{
183 uint64_t addr = (uint64_t)((uintptr_t)ptr);
184
185 return addr;
186}
187
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +0530188struct secure_vm {
189 int *vmid;
190 int *vmperm;
191 int vmcount;
192};
193
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700194struct fastrpc_file;
195
196struct fastrpc_buf {
197 struct hlist_node hn;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530198 struct hlist_node hn_rem;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700199 struct fastrpc_file *fl;
200 void *virt;
201 uint64_t phys;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530202 size_t size;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530203 unsigned long dma_attr;
204 uintptr_t raddr;
205 uint32_t flags;
206 int remote;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700207};
208
209struct fastrpc_ctx_lst;
210
211struct overlap {
212 uintptr_t start;
213 uintptr_t end;
214 int raix;
215 uintptr_t mstart;
216 uintptr_t mend;
217 uintptr_t offset;
218};
219
220struct smq_invoke_ctx {
221 struct hlist_node hn;
222 struct completion work;
223 int retval;
224 int pid;
225 int tgid;
226 remote_arg_t *lpra;
227 remote_arg64_t *rpra;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +0530228 remote_arg64_t *lrpra; /* Local copy of rpra for put_args */
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700229 int *fds;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700230 struct fastrpc_mmap **maps;
231 struct fastrpc_buf *buf;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +0530232 struct fastrpc_buf *lbuf;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530233 size_t used;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700234 struct fastrpc_file *fl;
235 uint32_t sc;
236 struct overlap *overs;
237 struct overlap **overps;
238 struct smq_msg msg;
c_mtharufdac6892017-10-12 13:09:01 +0530239 unsigned int magic;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530240 unsigned int *attrs;
241 uint32_t *crc;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +0530242 uint64_t ctxid;
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +0530243 void *handle;
244 const void *ptr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700245};
246
247struct fastrpc_ctx_lst {
248 struct hlist_head pending;
249 struct hlist_head interrupted;
250};
251
252struct fastrpc_smmu {
c_mtharue1a5ce12017-10-13 20:47:09 +0530253 struct device *dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700254 struct dma_iommu_mapping *mapping;
255 int cb;
256 int enabled;
257 int faults;
258 int secure;
259 int coherent;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530260 int sharedcb;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700261};
262
263struct fastrpc_session_ctx {
264 struct device *dev;
265 struct fastrpc_smmu smmu;
266 int used;
267};
268
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530269struct fastrpc_static_pd {
270 char *spdname;
271 struct notifier_block pdrnb;
272 struct notifier_block get_service_nb;
273 void *pdrhandle;
274 int pdrcount;
275 int prevpdrcount;
276 int ispdup;
277};
278
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700279struct fastrpc_glink_info {
280 int link_state;
281 int port_state;
282 struct glink_open_config cfg;
283 struct glink_link_info link_info;
284 void *link_notify_handle;
285};
286
287struct fastrpc_channel_ctx {
288 char *name;
289 char *subsys;
290 void *chan;
291 struct device *dev;
292 struct fastrpc_session_ctx session[NUM_SESSIONS];
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530293 struct fastrpc_static_pd spd[NUM_SESSIONS];
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700294 struct completion work;
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +0530295 struct completion workport;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700296 struct notifier_block nb;
297 struct kref kref;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530298 int channel;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700299 int sesscount;
300 int ssrcount;
301 void *handle;
302 int prevssrcount;
c_mtharue1a5ce12017-10-13 20:47:09 +0530303 int issubsystemup;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700304 int vmid;
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +0530305 struct secure_vm rhvm;
c_mtharue1a5ce12017-10-13 20:47:09 +0530306 int ramdumpenabled;
307 void *remoteheap_ramdump_dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700308 struct fastrpc_glink_info link;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +0530309 /* Indicates, if channel is restricted to secure node only */
310 int secure;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700311};
312
313struct fastrpc_apps {
314 struct fastrpc_channel_ctx *channel;
315 struct cdev cdev;
316 struct class *class;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530317 struct mutex smd_mutex;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700318 struct smq_phy_page range;
319 struct hlist_head maps;
c_mtharue1a5ce12017-10-13 20:47:09 +0530320 uint32_t staticpd_flags;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700321 dev_t dev_no;
322 int compat;
323 struct hlist_head drivers;
324 spinlock_t hlock;
325 struct ion_client *client;
326 struct device *dev;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +0530327 unsigned int latency;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530328 bool glink;
329 bool legacy;
zhaochenfc798572018-08-17 15:32:37 +0800330 bool secure_flag;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +0530331 spinlock_t ctxlock;
332 struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX];
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700333};
334
335struct fastrpc_mmap {
336 struct hlist_node hn;
337 struct fastrpc_file *fl;
338 struct fastrpc_apps *apps;
339 int fd;
340 uint32_t flags;
341 struct dma_buf *buf;
342 struct sg_table *table;
343 struct dma_buf_attachment *attach;
344 struct ion_handle *handle;
345 uint64_t phys;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530346 size_t size;
347 uintptr_t va;
348 size_t len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700349 int refs;
350 uintptr_t raddr;
351 int uncached;
352 int secure;
353 uintptr_t attr;
Swathi K013c6202021-07-14 17:51:10 +0530354 bool is_filemap; /*flag to indicate map used in process init*/
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700355};
356
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530357enum fastrpc_perfkeys {
358 PERF_COUNT = 0,
359 PERF_FLUSH = 1,
360 PERF_MAP = 2,
361 PERF_COPY = 3,
362 PERF_LINK = 4,
363 PERF_GETARGS = 5,
364 PERF_PUTARGS = 6,
365 PERF_INVARGS = 7,
366 PERF_INVOKE = 8,
367 PERF_KEY_MAX = 9,
368};
369
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800370struct fastrpc_perf {
371 int64_t count;
372 int64_t flush;
373 int64_t map;
374 int64_t copy;
375 int64_t link;
376 int64_t getargs;
377 int64_t putargs;
378 int64_t invargs;
379 int64_t invoke;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530380 int64_t tid;
381 struct hlist_node hn;
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800382};
383
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700384struct fastrpc_file {
385 struct hlist_node hn;
386 spinlock_t hlock;
387 struct hlist_head maps;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530388 struct hlist_head cached_bufs;
389 struct hlist_head remote_bufs;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700390 struct fastrpc_ctx_lst clst;
391 struct fastrpc_session_ctx *sctx;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530392 struct fastrpc_buf *init_mem;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700393 struct fastrpc_session_ctx *secsctx;
394 uint32_t mode;
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800395 uint32_t profile;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +0530396 int sessionid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700397 int tgid;
398 int cid;
399 int ssrcount;
400 int pd;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530401 char *spdname;
tharun kumar9f899ea2017-07-03 17:07:03 +0530402 int file_close;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530403 int sharedcb;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700404 struct fastrpc_apps *apps;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530405 struct hlist_head perf;
Sathish Ambley1ca68232017-01-19 10:32:55 -0800406 struct dentry *debugfs_file;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530407 struct mutex perf_mutex;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +0530408 struct pm_qos_request pm_qos_req;
409 int qos_request;
Jeya R93608352021-06-10 13:03:44 +0530410 struct mutex pm_qos_mutex;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +0530411 struct mutex map_mutex;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +0530412 struct mutex fl_map_mutex;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +0530413 int refcount;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +0530414 /* Identifies the device (MINOR_NUM_DEV / MINOR_NUM_SECURE_DEV) */
415 int dev_minor;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +0530416 char *debug_buf;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700417};
418
419static struct fastrpc_apps gfa;
420
421static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = {
422 {
423 .name = "adsprpc-smd",
424 .subsys = "adsp",
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530425 .channel = SMD_APPS_QDSP,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700426 .link.link_info.edge = "lpass",
427 .link.link_info.transport = "smem",
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530428 .spd = {
429 {
430 .spdname =
431 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
432 .pdrnb.notifier_call =
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530433 fastrpc_pdr_notifier_cb,
434 },
435 {
436 .spdname =
437 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME,
438 .pdrnb.notifier_call =
439 fastrpc_pdr_notifier_cb,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530440 }
441 },
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700442 },
443 {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700444 .name = "mdsprpc-smd",
445 .subsys = "modem",
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530446 .channel = SMD_APPS_MODEM,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700447 .link.link_info.edge = "mpss",
448 .link.link_info.transport = "smem",
449 },
450 {
Sathish Ambley36849af2017-02-02 09:35:55 -0800451 .name = "sdsprpc-smd",
452 .subsys = "slpi",
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530453 .channel = SMD_APPS_DSPS,
Sathish Ambley36849af2017-02-02 09:35:55 -0800454 .link.link_info.edge = "dsps",
455 .link.link_info.transport = "smem",
Sathish Ambley36849af2017-02-02 09:35:55 -0800456 },
457 {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700458 .name = "cdsprpc-smd",
459 .subsys = "cdsp",
460 .link.link_info.edge = "cdsp",
461 .link.link_info.transport = "smem",
462 },
463};
464
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +0530465static int hlosvm[1] = {VMID_HLOS};
466static int hlosvmperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
467
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800468static inline int64_t getnstimediff(struct timespec *start)
469{
470 int64_t ns;
471 struct timespec ts, b;
472
473 getnstimeofday(&ts);
474 b = timespec_sub(ts, *start);
475 ns = timespec_to_ns(&b);
476 return ns;
477}
478
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530479static inline int64_t *getperfcounter(struct fastrpc_file *fl, int key)
480{
481 int err = 0;
482 int64_t *val = NULL;
483 struct fastrpc_perf *perf = NULL, *fperf = NULL;
484 struct hlist_node *n = NULL;
485
486 VERIFY(err, !IS_ERR_OR_NULL(fl));
487 if (err)
488 goto bail;
489
490 mutex_lock(&fl->perf_mutex);
491 hlist_for_each_entry_safe(perf, n, &fl->perf, hn) {
492 if (perf->tid == current->pid) {
493 fperf = perf;
494 break;
495 }
496 }
497
498 if (IS_ERR_OR_NULL(fperf)) {
499 fperf = kzalloc(sizeof(*fperf), GFP_KERNEL);
500
501 VERIFY(err, !IS_ERR_OR_NULL(fperf));
502 if (err) {
503 mutex_unlock(&fl->perf_mutex);
504 kfree(fperf);
505 goto bail;
506 }
507
508 fperf->tid = current->pid;
509 hlist_add_head(&fperf->hn, &fl->perf);
510 }
511
512 val = ((int64_t *)fperf) + key;
513 mutex_unlock(&fl->perf_mutex);
514bail:
515 return val;
516}
517
518
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700519static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
520{
c_mtharue1a5ce12017-10-13 20:47:09 +0530521 struct fastrpc_file *fl = buf == NULL ? NULL : buf->fl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700522 int vmid;
523
524 if (!fl)
525 return;
526 if (cache) {
527 spin_lock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530528 hlist_add_head(&buf->hn, &fl->cached_bufs);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700529 spin_unlock(&fl->hlock);
530 return;
531 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530532 if (buf->remote) {
533 spin_lock(&fl->hlock);
534 hlist_del_init(&buf->hn_rem);
535 spin_unlock(&fl->hlock);
536 buf->remote = 0;
537 buf->raddr = 0;
538 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700539 if (!IS_ERR_OR_NULL(buf->virt)) {
540 int destVM[1] = {VMID_HLOS};
541 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
542
543 if (fl->sctx->smmu.cb)
544 buf->phys &= ~((uint64_t)fl->sctx->smmu.cb << 32);
545 vmid = fl->apps->channel[fl->cid].vmid;
546 if (vmid) {
547 int srcVM[2] = {VMID_HLOS, vmid};
548
549 hyp_assign_phys(buf->phys, buf_page_size(buf->size),
550 srcVM, 2, destVM, destVMperm, 1);
551 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530552 dma_free_attrs(fl->sctx->smmu.dev, buf->size, buf->virt,
553 buf->phys, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700554 }
555 kfree(buf);
556}
557
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530558static void fastrpc_cached_buf_list_free(struct fastrpc_file *fl)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700559{
560 struct fastrpc_buf *buf, *free;
561
562 do {
563 struct hlist_node *n;
564
c_mtharue1a5ce12017-10-13 20:47:09 +0530565 free = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700566 spin_lock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530567 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700568 hlist_del_init(&buf->hn);
569 free = buf;
570 break;
571 }
572 spin_unlock(&fl->hlock);
573 if (free)
574 fastrpc_buf_free(free, 0);
575 } while (free);
576}
577
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530578static void fastrpc_remote_buf_list_free(struct fastrpc_file *fl)
579{
580 struct fastrpc_buf *buf, *free;
581
582 do {
583 struct hlist_node *n;
584
585 free = NULL;
586 spin_lock(&fl->hlock);
587 hlist_for_each_entry_safe(buf, n, &fl->remote_bufs, hn_rem) {
588 free = buf;
589 break;
590 }
591 spin_unlock(&fl->hlock);
592 if (free)
593 fastrpc_buf_free(free, 0);
594 } while (free);
595}
596
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700597static void fastrpc_mmap_add(struct fastrpc_mmap *map)
598{
c_mtharue1a5ce12017-10-13 20:47:09 +0530599 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
600 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
601 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700602
c_mtharue1a5ce12017-10-13 20:47:09 +0530603 spin_lock(&me->hlock);
604 hlist_add_head(&map->hn, &me->maps);
605 spin_unlock(&me->hlock);
606 } else {
607 struct fastrpc_file *fl = map->fl;
608
c_mtharue1a5ce12017-10-13 20:47:09 +0530609 hlist_add_head(&map->hn, &fl->maps);
c_mtharue1a5ce12017-10-13 20:47:09 +0530610 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700611}
612
c_mtharue1a5ce12017-10-13 20:47:09 +0530613static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530614 uintptr_t va, size_t len, int mflags, int refs,
c_mtharue1a5ce12017-10-13 20:47:09 +0530615 struct fastrpc_mmap **ppmap)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700616{
c_mtharue1a5ce12017-10-13 20:47:09 +0530617 struct fastrpc_apps *me = &gfa;
618 struct fastrpc_mmap *match = NULL, *map = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700619 struct hlist_node *n;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530620
621 if ((va + len) < va)
622 return -EOVERFLOW;
c_mtharue1a5ce12017-10-13 20:47:09 +0530623 if (mflags == ADSP_MMAP_HEAP_ADDR ||
624 mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
625 spin_lock(&me->hlock);
626 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
627 if (va >= map->va &&
628 va + len <= map->va + map->len &&
629 map->fd == fd) {
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530630 if (refs) {
631 if (map->refs + 1 == INT_MAX) {
632 spin_unlock(&me->hlock);
633 return -ETOOMANYREFS;
634 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530635 map->refs++;
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530636 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530637 match = map;
638 break;
639 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700640 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530641 spin_unlock(&me->hlock);
642 } else {
c_mtharue1a5ce12017-10-13 20:47:09 +0530643 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
644 if (va >= map->va &&
645 va + len <= map->va + map->len &&
646 map->fd == fd) {
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530647 if (refs) {
648 if (map->refs + 1 == INT_MAX)
649 return -ETOOMANYREFS;
c_mtharue1a5ce12017-10-13 20:47:09 +0530650 map->refs++;
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530651 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530652 match = map;
653 break;
654 }
655 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700656 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700657 if (match) {
658 *ppmap = match;
659 return 0;
660 }
661 return -ENOTTY;
662}
663
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530664static int dma_alloc_memory(dma_addr_t *region_phys, void **vaddr, size_t size,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530665 unsigned long dma_attrs)
c_mtharue1a5ce12017-10-13 20:47:09 +0530666{
667 struct fastrpc_apps *me = &gfa;
c_mtharue1a5ce12017-10-13 20:47:09 +0530668
669 if (me->dev == NULL) {
670 pr_err("device adsprpc-mem is not initialized\n");
671 return -ENODEV;
672 }
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530673 *vaddr = dma_alloc_attrs(me->dev, size, region_phys, GFP_KERNEL,
Tharun Kumar Merugu48d5ff32018-04-16 19:24:16 +0530674 dma_attrs);
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530675 if (IS_ERR_OR_NULL(*vaddr)) {
676 pr_err("adsprpc: %s: %s: dma_alloc_attrs failed for size 0x%zx, returned %pK\n",
677 current->comm, __func__, size, (*vaddr));
c_mtharue1a5ce12017-10-13 20:47:09 +0530678 return -ENOMEM;
679 }
680 return 0;
681}
682
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700683static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530684 size_t len, struct fastrpc_mmap **ppmap)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700685{
c_mtharue1a5ce12017-10-13 20:47:09 +0530686 struct fastrpc_mmap *match = NULL, *map;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700687 struct hlist_node *n;
688 struct fastrpc_apps *me = &gfa;
689
690 spin_lock(&me->hlock);
691 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
Swathi K013c6202021-07-14 17:51:10 +0530692 if (map->refs == 1 && map->raddr == va &&
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700693 map->raddr + map->len == va + len &&
Swathi K013c6202021-07-14 17:51:10 +0530694 /*Remove map if not used in process initialization*/
695 !map->is_filemap) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700696 match = map;
697 hlist_del_init(&map->hn);
698 break;
699 }
700 }
701 spin_unlock(&me->hlock);
702 if (match) {
703 *ppmap = match;
704 return 0;
705 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700706 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
Swathi K013c6202021-07-14 17:51:10 +0530707 if (map->refs == 1 && map->raddr == va &&
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700708 map->raddr + map->len == va + len &&
Swathi K013c6202021-07-14 17:51:10 +0530709 /*Remove map if not used in process initialization*/
710 !map->is_filemap) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700711 match = map;
712 hlist_del_init(&map->hn);
713 break;
714 }
715 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700716 if (match) {
717 *ppmap = match;
718 return 0;
719 }
720 return -ENOTTY;
721}
722
c_mtharu7bd6a422017-10-17 18:15:37 +0530723static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700724{
c_mtharue1a5ce12017-10-13 20:47:09 +0530725 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700726 struct fastrpc_file *fl;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530727 int vmid, cid = -1, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700728 struct fastrpc_session_ctx *sess;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700729
730 if (!map)
731 return;
732 fl = map->fl;
Jeya R85f57d32020-05-26 18:17:26 +0530733 if (fl && !(map->flags == ADSP_MMAP_HEAP_ADDR ||
734 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) {
735 cid = fl->cid;
736 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
737 if (err) {
738 err = -ECHRNG;
739 pr_err("adsprpc: ERROR:%s, Invalid channel id: %d, err:%d",
740 __func__, cid, err);
741 return;
742 }
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530743 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530744 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
745 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
746 spin_lock(&me->hlock);
747 map->refs--;
748 if (!map->refs)
749 hlist_del_init(&map->hn);
750 spin_unlock(&me->hlock);
c_mtharu7bd6a422017-10-17 18:15:37 +0530751 if (map->refs > 0)
752 return;
c_mtharue1a5ce12017-10-13 20:47:09 +0530753 } else {
c_mtharue1a5ce12017-10-13 20:47:09 +0530754 map->refs--;
755 if (!map->refs)
756 hlist_del_init(&map->hn);
c_mtharu7bd6a422017-10-17 18:15:37 +0530757 if (map->refs > 0 && !flags)
758 return;
c_mtharue1a5ce12017-10-13 20:47:09 +0530759 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530760 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
761 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700762
c_mtharue1a5ce12017-10-13 20:47:09 +0530763 if (me->dev == NULL) {
764 pr_err("failed to free remote heap allocation\n");
765 return;
766 }
767 if (map->phys) {
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +0530768 unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING |
769 DMA_ATTR_NO_KERNEL_MAPPING;
Tharun Kumar Merugu48d5ff32018-04-16 19:24:16 +0530770 dma_free_attrs(me->dev, map->size, (void *)map->va,
771 (dma_addr_t)map->phys, dma_attrs);
c_mtharue1a5ce12017-10-13 20:47:09 +0530772 }
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +0530773 } else if (map->flags == FASTRPC_DMAHANDLE_NOMAP) {
774 if (!IS_ERR_OR_NULL(map->handle))
775 ion_free(fl->apps->client, map->handle);
c_mtharue1a5ce12017-10-13 20:47:09 +0530776 } else {
777 int destVM[1] = {VMID_HLOS};
778 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
779
780 if (map->secure)
781 sess = fl->secsctx;
782 else
783 sess = fl->sctx;
784
785 if (!IS_ERR_OR_NULL(map->handle))
786 ion_free(fl->apps->client, map->handle);
787 if (sess && sess->smmu.enabled) {
788 if (map->size || map->phys)
789 msm_dma_unmap_sg(sess->smmu.dev,
790 map->table->sgl,
791 map->table->nents, DMA_BIDIRECTIONAL,
792 map->buf);
793 }
794 vmid = fl->apps->channel[fl->cid].vmid;
795 if (vmid && map->phys) {
796 int srcVM[2] = {VMID_HLOS, vmid};
797
798 hyp_assign_phys(map->phys, buf_page_size(map->size),
799 srcVM, 2, destVM, destVMperm, 1);
800 }
801
802 if (!IS_ERR_OR_NULL(map->table))
803 dma_buf_unmap_attachment(map->attach, map->table,
804 DMA_BIDIRECTIONAL);
805 if (!IS_ERR_OR_NULL(map->attach))
806 dma_buf_detach(map->buf, map->attach);
807 if (!IS_ERR_OR_NULL(map->buf))
808 dma_buf_put(map->buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700809 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700810 kfree(map);
811}
812
813static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
814 struct fastrpc_session_ctx **session);
815
816static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530817 unsigned int attr, uintptr_t va, size_t len, int mflags,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700818 struct fastrpc_mmap **ppmap)
819{
c_mtharue1a5ce12017-10-13 20:47:09 +0530820 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700821 struct fastrpc_session_ctx *sess;
822 struct fastrpc_apps *apps = fl->apps;
c_mtharue1a5ce12017-10-13 20:47:09 +0530823 struct fastrpc_mmap *map = NULL;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530824 struct fastrpc_channel_ctx *chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700825 unsigned long attrs;
c_mtharuf931ff92017-11-30 19:35:30 +0530826 dma_addr_t region_phys = 0;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530827 void *region_vaddr = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700828 unsigned long flags;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530829 int err = 0, vmid, cid = -1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700830
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530831 cid = fl->cid;
832 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
833 if (err) {
834 err = -ECHRNG;
835 goto bail;
836 }
837 chan = &apps->channel[cid];
Sathish Ambleyae5ee542017-01-16 22:24:23 -0800838 if (!fastrpc_mmap_find(fl, fd, va, len, mflags, 1, ppmap))
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700839 return 0;
840 map = kzalloc(sizeof(*map), GFP_KERNEL);
841 VERIFY(err, !IS_ERR_OR_NULL(map));
842 if (err)
843 goto bail;
844 INIT_HLIST_NODE(&map->hn);
845 map->flags = mflags;
846 map->refs = 1;
847 map->fl = fl;
848 map->fd = fd;
849 map->attr = attr;
Swathi K013c6202021-07-14 17:51:10 +0530850 map->is_filemap = false;
c_mtharue1a5ce12017-10-13 20:47:09 +0530851 if (mflags == ADSP_MMAP_HEAP_ADDR ||
852 mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530853 unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING |
854 DMA_ATTR_NO_KERNEL_MAPPING;
855
c_mtharue1a5ce12017-10-13 20:47:09 +0530856 map->apps = me;
857 map->fl = NULL;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530858 VERIFY(err, !dma_alloc_memory(&region_phys, &region_vaddr,
859 len, dma_attrs));
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700860 if (err)
861 goto bail;
c_mtharuf931ff92017-11-30 19:35:30 +0530862 map->phys = (uintptr_t)region_phys;
c_mtharue1a5ce12017-10-13 20:47:09 +0530863 map->size = len;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530864 map->va = (uintptr_t)region_vaddr;
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +0530865 } else if (mflags == FASTRPC_DMAHANDLE_NOMAP) {
866 ion_phys_addr_t iphys;
867
868 VERIFY(err, !IS_ERR_OR_NULL(map->handle =
869 ion_import_dma_buf_fd(fl->apps->client, fd)));
870 if (err)
871 goto bail;
872
873 map->uncached = 1;
874 map->buf = NULL;
875 map->attach = NULL;
876 map->table = NULL;
877 map->va = 0;
878 map->phys = 0;
879
880 err = ion_phys(fl->apps->client, map->handle,
881 &iphys, &map->size);
882 if (err)
883 goto bail;
884 map->phys = (uint64_t)iphys;
c_mtharue1a5ce12017-10-13 20:47:09 +0530885 } else {
c_mtharu7bd6a422017-10-17 18:15:37 +0530886 if (map->attr && (map->attr & FASTRPC_ATTR_KEEP_MAP)) {
887 pr_info("adsprpc: buffer mapped with persist attr %x\n",
888 (unsigned int)map->attr);
889 map->refs = 2;
890 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530891 VERIFY(err, !IS_ERR_OR_NULL(map->handle =
892 ion_import_dma_buf_fd(fl->apps->client, fd)));
893 if (err)
894 goto bail;
895 VERIFY(err, !ion_handle_get_flags(fl->apps->client, map->handle,
896 &flags));
897 if (err)
898 goto bail;
899
c_mtharue1a5ce12017-10-13 20:47:09 +0530900 map->secure = flags & ION_FLAG_SECURE;
901 if (map->secure) {
902 if (!fl->secsctx)
903 err = fastrpc_session_alloc(chan, 1,
904 &fl->secsctx);
905 if (err)
906 goto bail;
907 }
908 if (map->secure)
909 sess = fl->secsctx;
910 else
911 sess = fl->sctx;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530912
c_mtharue1a5ce12017-10-13 20:47:09 +0530913 VERIFY(err, !IS_ERR_OR_NULL(sess));
914 if (err)
915 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530916
917 map->uncached = !ION_IS_CACHED(flags);
918 if (map->attr & FASTRPC_ATTR_NOVA && !sess->smmu.coherent)
919 map->uncached = 1;
920
c_mtharue1a5ce12017-10-13 20:47:09 +0530921 VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd)));
922 if (err)
923 goto bail;
924 VERIFY(err, !IS_ERR_OR_NULL(map->attach =
925 dma_buf_attach(map->buf, sess->smmu.dev)));
926 if (err)
927 goto bail;
928 VERIFY(err, !IS_ERR_OR_NULL(map->table =
929 dma_buf_map_attachment(map->attach,
930 DMA_BIDIRECTIONAL)));
931 if (err)
932 goto bail;
933 if (sess->smmu.enabled) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700934 attrs = DMA_ATTR_EXEC_MAPPING;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +0530935
936 if (map->attr & FASTRPC_ATTR_NON_COHERENT ||
937 (sess->smmu.coherent && map->uncached))
938 attrs |= DMA_ATTR_FORCE_NON_COHERENT;
939 else if (map->attr & FASTRPC_ATTR_COHERENT)
940 attrs |= DMA_ATTR_FORCE_COHERENT;
941
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700942 VERIFY(err, map->table->nents ==
c_mtharue1a5ce12017-10-13 20:47:09 +0530943 msm_dma_map_sg_attrs(sess->smmu.dev,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700944 map->table->sgl, map->table->nents,
945 DMA_BIDIRECTIONAL, map->buf, attrs));
c_mtharue1a5ce12017-10-13 20:47:09 +0530946 if (err)
947 goto bail;
948 } else {
949 VERIFY(err, map->table->nents == 1);
950 if (err)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700951 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +0530952 }
953 map->phys = sg_dma_address(map->table->sgl);
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530954
c_mtharue1a5ce12017-10-13 20:47:09 +0530955 if (sess->smmu.cb) {
956 map->phys += ((uint64_t)sess->smmu.cb << 32);
957 map->size = sg_dma_len(map->table->sgl);
958 } else {
959 map->size = buf_page_size(len);
960 }
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530961
c_mtharue1a5ce12017-10-13 20:47:09 +0530962 vmid = fl->apps->channel[fl->cid].vmid;
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530963 if (!sess->smmu.enabled && !vmid) {
964 VERIFY(err, map->phys >= me->range.addr &&
965 map->phys + map->size <=
966 me->range.addr + me->range.size);
967 if (err) {
968 pr_err("adsprpc: mmap fail out of range\n");
969 goto bail;
970 }
971 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530972 if (vmid) {
973 int srcVM[1] = {VMID_HLOS};
974 int destVM[2] = {VMID_HLOS, vmid};
975 int destVMperm[2] = {PERM_READ | PERM_WRITE,
976 PERM_READ | PERM_WRITE | PERM_EXEC};
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700977
c_mtharue1a5ce12017-10-13 20:47:09 +0530978 VERIFY(err, !hyp_assign_phys(map->phys,
979 buf_page_size(map->size),
980 srcVM, 1, destVM, destVMperm, 2));
981 if (err)
982 goto bail;
983 }
984 map->va = va;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700985 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700986 map->len = len;
987
988 fastrpc_mmap_add(map);
989 *ppmap = map;
990
991bail:
992 if (err && map)
c_mtharu7bd6a422017-10-17 18:15:37 +0530993 fastrpc_mmap_free(map, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700994 return err;
995}
996
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530997static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530998 unsigned long dma_attr, uint32_t rflags,
999 int remote, struct fastrpc_buf **obuf)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001000{
1001 int err = 0, vmid;
c_mtharue1a5ce12017-10-13 20:47:09 +05301002 struct fastrpc_buf *buf = NULL, *fr = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001003 struct hlist_node *n;
1004
1005 VERIFY(err, size > 0);
1006 if (err)
1007 goto bail;
1008
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301009 if (!remote) {
1010 /* find the smallest buffer that fits in the cache */
1011 spin_lock(&fl->hlock);
1012 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
1013 if (buf->size >= size && (!fr || fr->size > buf->size))
1014 fr = buf;
1015 }
1016 if (fr)
1017 hlist_del_init(&fr->hn);
1018 spin_unlock(&fl->hlock);
1019 if (fr) {
1020 *obuf = fr;
1021 return 0;
1022 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001023 }
c_mtharue1a5ce12017-10-13 20:47:09 +05301024 buf = NULL;
1025 VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001026 if (err)
1027 goto bail;
1028 INIT_HLIST_NODE(&buf->hn);
1029 buf->fl = fl;
c_mtharue1a5ce12017-10-13 20:47:09 +05301030 buf->virt = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001031 buf->phys = 0;
1032 buf->size = size;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301033 buf->dma_attr = dma_attr;
1034 buf->flags = rflags;
1035 buf->raddr = 0;
1036 buf->remote = 0;
1037 buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
1038 (dma_addr_t *)&buf->phys,
1039 GFP_KERNEL, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001040 if (IS_ERR_OR_NULL(buf->virt)) {
1041 /* free cache and retry */
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301042 fastrpc_cached_buf_list_free(fl);
1043 buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
1044 (dma_addr_t *)&buf->phys,
1045 GFP_KERNEL, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001046 VERIFY(err, !IS_ERR_OR_NULL(buf->virt));
1047 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301048 if (err) {
1049 err = -ENOMEM;
1050 pr_err("adsprpc: %s: %s: dma_alloc_attrs failed for size 0x%zx\n",
1051 current->comm, __func__, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001052 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301053 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001054 if (fl->sctx->smmu.cb)
1055 buf->phys += ((uint64_t)fl->sctx->smmu.cb << 32);
1056 vmid = fl->apps->channel[fl->cid].vmid;
1057 if (vmid) {
1058 int srcVM[1] = {VMID_HLOS};
1059 int destVM[2] = {VMID_HLOS, vmid};
1060 int destVMperm[2] = {PERM_READ | PERM_WRITE,
1061 PERM_READ | PERM_WRITE | PERM_EXEC};
1062
1063 VERIFY(err, !hyp_assign_phys(buf->phys, buf_page_size(size),
1064 srcVM, 1, destVM, destVMperm, 2));
1065 if (err)
1066 goto bail;
1067 }
1068
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301069 if (remote) {
1070 INIT_HLIST_NODE(&buf->hn_rem);
1071 spin_lock(&fl->hlock);
1072 hlist_add_head(&buf->hn_rem, &fl->remote_bufs);
1073 spin_unlock(&fl->hlock);
1074 buf->remote = remote;
1075 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001076 *obuf = buf;
1077 bail:
1078 if (err && buf)
1079 fastrpc_buf_free(buf, 0);
1080 return err;
1081}
1082
1083
1084static int context_restore_interrupted(struct fastrpc_file *fl,
Sathish Ambleybae51902017-07-03 15:00:49 -07001085 struct fastrpc_ioctl_invoke_crc *inv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001086 struct smq_invoke_ctx **po)
1087{
1088 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05301089 struct smq_invoke_ctx *ctx = NULL, *ictx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001090 struct hlist_node *n;
1091 struct fastrpc_ioctl_invoke *invoke = &inv->inv;
1092
1093 spin_lock(&fl->hlock);
1094 hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
1095 if (ictx->pid == current->pid) {
1096 if (invoke->sc != ictx->sc || ictx->fl != fl)
1097 err = -1;
1098 else {
1099 ctx = ictx;
1100 hlist_del_init(&ctx->hn);
1101 hlist_add_head(&ctx->hn, &fl->clst.pending);
1102 }
1103 break;
1104 }
1105 }
1106 spin_unlock(&fl->hlock);
1107 if (ctx)
1108 *po = ctx;
1109 return err;
1110}
1111
1112#define CMP(aa, bb) ((aa) == (bb) ? 0 : (aa) < (bb) ? -1 : 1)
1113static int overlap_ptr_cmp(const void *a, const void *b)
1114{
1115 struct overlap *pa = *((struct overlap **)a);
1116 struct overlap *pb = *((struct overlap **)b);
1117 /* sort with lowest starting buffer first */
1118 int st = CMP(pa->start, pb->start);
1119 /* sort with highest ending buffer first */
1120 int ed = CMP(pb->end, pa->end);
1121 return st == 0 ? ed : st;
1122}
1123
Sathish Ambley9466d672017-01-25 10:51:55 -08001124static int context_build_overlap(struct smq_invoke_ctx *ctx)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001125{
Sathish Ambley9466d672017-01-25 10:51:55 -08001126 int i, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001127 remote_arg_t *lpra = ctx->lpra;
1128 int inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
1129 int outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc);
1130 int nbufs = inbufs + outbufs;
1131 struct overlap max;
1132
1133 for (i = 0; i < nbufs; ++i) {
1134 ctx->overs[i].start = (uintptr_t)lpra[i].buf.pv;
1135 ctx->overs[i].end = ctx->overs[i].start + lpra[i].buf.len;
Sathish Ambley9466d672017-01-25 10:51:55 -08001136 if (lpra[i].buf.len) {
1137 VERIFY(err, ctx->overs[i].end > ctx->overs[i].start);
1138 if (err)
1139 goto bail;
1140 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001141 ctx->overs[i].raix = i;
1142 ctx->overps[i] = &ctx->overs[i];
1143 }
c_mtharue1a5ce12017-10-13 20:47:09 +05301144 sort(ctx->overps, nbufs, sizeof(*ctx->overps), overlap_ptr_cmp, NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001145 max.start = 0;
1146 max.end = 0;
1147 for (i = 0; i < nbufs; ++i) {
1148 if (ctx->overps[i]->start < max.end) {
1149 ctx->overps[i]->mstart = max.end;
1150 ctx->overps[i]->mend = ctx->overps[i]->end;
1151 ctx->overps[i]->offset = max.end -
1152 ctx->overps[i]->start;
1153 if (ctx->overps[i]->end > max.end) {
1154 max.end = ctx->overps[i]->end;
1155 } else {
1156 ctx->overps[i]->mend = 0;
1157 ctx->overps[i]->mstart = 0;
1158 }
1159 } else {
1160 ctx->overps[i]->mend = ctx->overps[i]->end;
1161 ctx->overps[i]->mstart = ctx->overps[i]->start;
1162 ctx->overps[i]->offset = 0;
1163 max = *ctx->overps[i];
1164 }
1165 }
Sathish Ambley9466d672017-01-25 10:51:55 -08001166bail:
1167 return err;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001168}
1169
1170#define K_COPY_FROM_USER(err, kernel, dst, src, size) \
1171 do {\
1172 if (!(kernel))\
c_mtharue1a5ce12017-10-13 20:47:09 +05301173 VERIFY(err, 0 == copy_from_user((dst),\
1174 (void const __user *)(src),\
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001175 (size)));\
1176 else\
1177 memmove((dst), (src), (size));\
1178 } while (0)
1179
1180#define K_COPY_TO_USER(err, kernel, dst, src, size) \
1181 do {\
1182 if (!(kernel))\
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301183 VERIFY(err, 0 == copy_to_user((void __user *)(dst),\
c_mtharue1a5ce12017-10-13 20:47:09 +05301184 (src), (size)));\
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001185 else\
1186 memmove((dst), (src), (size));\
1187 } while (0)
1188
1189
1190static void context_free(struct smq_invoke_ctx *ctx);
1191
1192static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
Sathish Ambleybae51902017-07-03 15:00:49 -07001193 struct fastrpc_ioctl_invoke_crc *invokefd,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001194 struct smq_invoke_ctx **po)
1195{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301196 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301197 int err = 0, bufs, ii, size = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05301198 struct smq_invoke_ctx *ctx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001199 struct fastrpc_ctx_lst *clst = &fl->clst;
1200 struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
1201
1202 bufs = REMOTE_SCALARS_LENGTH(invoke->sc);
1203 size = bufs * sizeof(*ctx->lpra) + bufs * sizeof(*ctx->maps) +
1204 sizeof(*ctx->fds) * (bufs) +
1205 sizeof(*ctx->attrs) * (bufs) +
1206 sizeof(*ctx->overs) * (bufs) +
1207 sizeof(*ctx->overps) * (bufs);
1208
c_mtharue1a5ce12017-10-13 20:47:09 +05301209 VERIFY(err, NULL != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001210 if (err)
1211 goto bail;
1212
1213 INIT_HLIST_NODE(&ctx->hn);
1214 hlist_add_fake(&ctx->hn);
1215 ctx->fl = fl;
1216 ctx->maps = (struct fastrpc_mmap **)(&ctx[1]);
1217 ctx->lpra = (remote_arg_t *)(&ctx->maps[bufs]);
1218 ctx->fds = (int *)(&ctx->lpra[bufs]);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301219 if (me->legacy) {
1220 ctx->overs = (struct overlap *)(&ctx->fds[bufs]);
1221 ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
1222 } else {
1223 ctx->attrs = (unsigned int *)(&ctx->fds[bufs]);
1224 ctx->overs = (struct overlap *)(&ctx->attrs[bufs]);
1225 ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
1226 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001227
c_mtharue1a5ce12017-10-13 20:47:09 +05301228 K_COPY_FROM_USER(err, kernel, (void *)ctx->lpra, invoke->pra,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001229 bufs * sizeof(*ctx->lpra));
1230 if (err)
1231 goto bail;
1232
1233 if (invokefd->fds) {
1234 K_COPY_FROM_USER(err, kernel, ctx->fds, invokefd->fds,
1235 bufs * sizeof(*ctx->fds));
1236 if (err)
1237 goto bail;
1238 }
1239 if (invokefd->attrs) {
1240 K_COPY_FROM_USER(err, kernel, ctx->attrs, invokefd->attrs,
1241 bufs * sizeof(*ctx->attrs));
1242 if (err)
1243 goto bail;
1244 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001245 ctx->crc = (uint32_t *)invokefd->crc;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001246 ctx->sc = invoke->sc;
Sathish Ambley9466d672017-01-25 10:51:55 -08001247 if (bufs) {
1248 VERIFY(err, 0 == context_build_overlap(ctx));
1249 if (err)
1250 goto bail;
1251 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001252 ctx->retval = -1;
1253 ctx->pid = current->pid;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301254 ctx->tgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001255 init_completion(&ctx->work);
c_mtharufdac6892017-10-12 13:09:01 +05301256 ctx->magic = FASTRPC_CTX_MAGIC;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001257
1258 spin_lock(&fl->hlock);
1259 hlist_add_head(&ctx->hn, &clst->pending);
1260 spin_unlock(&fl->hlock);
1261
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301262 spin_lock(&me->ctxlock);
1263 for (ii = 0; ii < FASTRPC_CTX_MAX; ii++) {
1264 if (!me->ctxtable[ii]) {
1265 me->ctxtable[ii] = ctx;
1266 ctx->ctxid = (ptr_to_uint64(ctx) & ~0xFFF)|(ii << 4);
1267 break;
1268 }
1269 }
1270 spin_unlock(&me->ctxlock);
1271 VERIFY(err, ii < FASTRPC_CTX_MAX);
1272 if (err) {
1273 pr_err("adsprpc: out of context memory\n");
1274 goto bail;
1275 }
1276
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001277 *po = ctx;
1278bail:
1279 if (ctx && err)
1280 context_free(ctx);
1281 return err;
1282}
1283
1284static void context_save_interrupted(struct smq_invoke_ctx *ctx)
1285{
1286 struct fastrpc_ctx_lst *clst = &ctx->fl->clst;
1287
1288 spin_lock(&ctx->fl->hlock);
1289 hlist_del_init(&ctx->hn);
1290 hlist_add_head(&ctx->hn, &clst->interrupted);
1291 spin_unlock(&ctx->fl->hlock);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001292}
1293
1294static void context_free(struct smq_invoke_ctx *ctx)
1295{
1296 int i;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301297 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001298 int nbufs = REMOTE_SCALARS_INBUFS(ctx->sc) +
1299 REMOTE_SCALARS_OUTBUFS(ctx->sc);
1300 spin_lock(&ctx->fl->hlock);
1301 hlist_del_init(&ctx->hn);
1302 spin_unlock(&ctx->fl->hlock);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301303 mutex_lock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001304 for (i = 0; i < nbufs; ++i)
c_mtharu7bd6a422017-10-17 18:15:37 +05301305 fastrpc_mmap_free(ctx->maps[i], 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301306
1307 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001308 fastrpc_buf_free(ctx->buf, 1);
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301309 fastrpc_buf_free(ctx->lbuf, 1);
c_mtharufdac6892017-10-12 13:09:01 +05301310 ctx->magic = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301311 ctx->ctxid = 0;
1312
1313 spin_lock(&me->ctxlock);
1314 for (i = 0; i < FASTRPC_CTX_MAX; i++) {
1315 if (me->ctxtable[i] == ctx) {
1316 me->ctxtable[i] = NULL;
1317 break;
1318 }
1319 }
1320 spin_unlock(&me->ctxlock);
1321
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001322 kfree(ctx);
1323}
1324
1325static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
1326{
1327 ctx->retval = retval;
1328 complete(&ctx->work);
1329}
1330
1331
1332static void fastrpc_notify_users(struct fastrpc_file *me)
1333{
1334 struct smq_invoke_ctx *ictx;
1335 struct hlist_node *n;
1336
1337 spin_lock(&me->hlock);
1338 hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
1339 complete(&ictx->work);
1340 }
1341 hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
1342 complete(&ictx->work);
1343 }
1344 spin_unlock(&me->hlock);
1345
1346}
1347
Tharun Kumar Merugu77dd5872018-04-02 12:48:17 +05301348
1349static void fastrpc_notify_users_staticpd_pdr(struct fastrpc_file *me)
1350{
1351 struct smq_invoke_ctx *ictx;
1352 struct hlist_node *n;
1353
1354 spin_lock(&me->hlock);
1355 hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
1356 if (ictx->msg.pid)
1357 complete(&ictx->work);
1358 }
1359 hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
1360 if (ictx->msg.pid)
1361 complete(&ictx->work);
1362 }
1363 spin_unlock(&me->hlock);
1364}
1365
1366
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001367static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid)
1368{
1369 struct fastrpc_file *fl;
1370 struct hlist_node *n;
1371
1372 spin_lock(&me->hlock);
1373 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1374 if (fl->cid == cid)
1375 fastrpc_notify_users(fl);
1376 }
1377 spin_unlock(&me->hlock);
1378
1379}
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05301380
1381static void fastrpc_notify_pdr_drivers(struct fastrpc_apps *me, char *spdname)
1382{
1383 struct fastrpc_file *fl;
1384 struct hlist_node *n;
1385
1386 spin_lock(&me->hlock);
1387 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1388 if (fl->spdname && !strcmp(spdname, fl->spdname))
Tharun Kumar Merugu77dd5872018-04-02 12:48:17 +05301389 fastrpc_notify_users_staticpd_pdr(fl);
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05301390 }
1391 spin_unlock(&me->hlock);
1392
1393}
1394
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001395static void context_list_ctor(struct fastrpc_ctx_lst *me)
1396{
1397 INIT_HLIST_HEAD(&me->interrupted);
1398 INIT_HLIST_HEAD(&me->pending);
1399}
1400
1401static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
1402{
1403 struct fastrpc_ctx_lst *clst = &fl->clst;
c_mtharue1a5ce12017-10-13 20:47:09 +05301404 struct smq_invoke_ctx *ictx = NULL, *ctxfree;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001405 struct hlist_node *n;
1406
1407 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301408 ctxfree = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001409 spin_lock(&fl->hlock);
1410 hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) {
1411 hlist_del_init(&ictx->hn);
1412 ctxfree = ictx;
1413 break;
1414 }
1415 spin_unlock(&fl->hlock);
1416 if (ctxfree)
1417 context_free(ctxfree);
1418 } while (ctxfree);
1419 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301420 ctxfree = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001421 spin_lock(&fl->hlock);
1422 hlist_for_each_entry_safe(ictx, n, &clst->pending, hn) {
1423 hlist_del_init(&ictx->hn);
1424 ctxfree = ictx;
1425 break;
1426 }
1427 spin_unlock(&fl->hlock);
1428 if (ctxfree)
1429 context_free(ctxfree);
1430 } while (ctxfree);
1431}
1432
1433static int fastrpc_file_free(struct fastrpc_file *fl);
1434static void fastrpc_file_list_dtor(struct fastrpc_apps *me)
1435{
1436 struct fastrpc_file *fl, *free;
1437 struct hlist_node *n;
1438
1439 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301440 free = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001441 spin_lock(&me->hlock);
1442 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1443 hlist_del_init(&fl->hn);
1444 free = fl;
1445 break;
1446 }
1447 spin_unlock(&me->hlock);
1448 if (free)
1449 fastrpc_file_free(free);
1450 } while (free);
1451}
1452
1453static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
1454{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301455 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301456 remote_arg64_t *rpra, *lrpra;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001457 remote_arg_t *lpra = ctx->lpra;
1458 struct smq_invoke_buf *list;
1459 struct smq_phy_page *pages, *ipage;
1460 uint32_t sc = ctx->sc;
1461 int inbufs = REMOTE_SCALARS_INBUFS(sc);
1462 int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001463 int handles, bufs = inbufs + outbufs;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001464 uintptr_t args;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301465 size_t rlen = 0, copylen = 0, metalen = 0, lrpralen = 0;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001466 int i, oix;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001467 int err = 0;
1468 int mflags = 0;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001469 uint64_t *fdlist;
Sathish Ambleybae51902017-07-03 15:00:49 -07001470 uint32_t *crclist;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301471 int64_t *perf_counter = getperfcounter(ctx->fl, PERF_COUNT);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001472
1473 /* calculate size of the metadata */
c_mtharue1a5ce12017-10-13 20:47:09 +05301474 rpra = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001475 list = smq_invoke_buf_start(rpra, sc);
1476 pages = smq_phy_page_start(sc, list);
1477 ipage = pages;
1478
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301479 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001480 for (i = 0; i < bufs; ++i) {
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301481 uintptr_t buf = (uintptr_t)lpra[i].buf.pv;
1482 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001483
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301484 mutex_lock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301485 if (ctx->fds[i] && (ctx->fds[i] != -1)) {
1486 unsigned int attrs = 0;
1487
1488 if (ctx->attrs)
1489 attrs = ctx->attrs[i];
1490
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001491 fastrpc_mmap_create(ctx->fl, ctx->fds[i],
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301492 attrs, buf, len,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001493 mflags, &ctx->maps[i]);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301494 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301495 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001496 ipage += 1;
1497 }
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301498 PERF_END);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001499 handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301500 mutex_lock(&ctx->fl->fl_map_mutex);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001501 for (i = bufs; i < bufs + handles; i++) {
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +05301502 int dmaflags = 0;
1503
1504 if (ctx->attrs && (ctx->attrs[i] & FASTRPC_ATTR_NOMAP))
1505 dmaflags = FASTRPC_DMAHANDLE_NOMAP;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001506 VERIFY(err, !fastrpc_mmap_create(ctx->fl, ctx->fds[i],
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +05301507 FASTRPC_ATTR_NOVA, 0, 0, dmaflags, &ctx->maps[i]));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301508 if (err) {
1509 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001510 goto bail;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301511 }
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001512 ipage += 1;
1513 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301514 mutex_unlock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301515 if (!me->legacy) {
1516 metalen = copylen = (size_t)&ipage[0] +
1517 (sizeof(uint64_t) * M_FDLIST) +
1518 (sizeof(uint32_t) * M_CRCLIST);
1519 } else {
1520 metalen = copylen = (size_t)&ipage[0];
1521 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001522
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301523 /* allocate new local rpra buffer */
1524 lrpralen = (size_t)&list[0];
1525 if (lrpralen) {
1526 err = fastrpc_buf_alloc(ctx->fl, lrpralen, 0, 0, 0, &ctx->lbuf);
1527 if (err)
1528 goto bail;
1529 }
1530 if (ctx->lbuf->virt)
1531 memset(ctx->lbuf->virt, 0, lrpralen);
1532
1533 lrpra = ctx->lbuf->virt;
1534 ctx->lrpra = lrpra;
1535
1536 /* calculate len required for copying */
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001537 for (oix = 0; oix < inbufs + outbufs; ++oix) {
1538 int i = ctx->overps[oix]->raix;
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001539 uintptr_t mstart, mend;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301540 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001541
1542 if (!len)
1543 continue;
1544 if (ctx->maps[i])
1545 continue;
1546 if (ctx->overps[oix]->offset == 0)
1547 copylen = ALIGN(copylen, BALIGN);
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001548 mstart = ctx->overps[oix]->mstart;
1549 mend = ctx->overps[oix]->mend;
1550 VERIFY(err, (mend - mstart) <= LONG_MAX);
1551 if (err)
1552 goto bail;
1553 copylen += mend - mstart;
1554 VERIFY(err, copylen >= 0);
1555 if (err)
1556 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001557 }
1558 ctx->used = copylen;
1559
1560 /* allocate new buffer */
1561 if (copylen) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301562 err = fastrpc_buf_alloc(ctx->fl, copylen, 0, 0, 0, &ctx->buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001563 if (err)
1564 goto bail;
1565 }
Tharun Kumar Merugue3361f92017-06-22 10:45:43 +05301566 if (ctx->buf->virt && metalen <= copylen)
1567 memset(ctx->buf->virt, 0, metalen);
1568
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001569 /* copy metadata */
1570 rpra = ctx->buf->virt;
1571 ctx->rpra = rpra;
1572 list = smq_invoke_buf_start(rpra, sc);
1573 pages = smq_phy_page_start(sc, list);
1574 ipage = pages;
1575 args = (uintptr_t)ctx->buf->virt + metalen;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001576 for (i = 0; i < bufs + handles; ++i) {
1577 if (lpra[i].buf.len)
1578 list[i].num = 1;
1579 else
1580 list[i].num = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001581 list[i].pgidx = ipage - pages;
1582 ipage++;
1583 }
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05301584
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001585 /* map ion buffers */
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301586 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP),
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301587 for (i = 0; rpra && lrpra && i < inbufs + outbufs; ++i) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001588 struct fastrpc_mmap *map = ctx->maps[i];
1589 uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301590 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001591
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301592 rpra[i].buf.pv = lrpra[i].buf.pv = 0;
1593 rpra[i].buf.len = lrpra[i].buf.len = len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001594 if (!len)
1595 continue;
1596 if (map) {
1597 struct vm_area_struct *vma;
1598 uintptr_t offset;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301599 uint64_t num = buf_num_pages(buf, len);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001600 int idx = list[i].pgidx;
1601
1602 if (map->attr & FASTRPC_ATTR_NOVA) {
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001603 offset = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001604 } else {
1605 down_read(&current->mm->mmap_sem);
1606 VERIFY(err, NULL != (vma = find_vma(current->mm,
1607 map->va)));
1608 if (err) {
1609 up_read(&current->mm->mmap_sem);
1610 goto bail;
1611 }
1612 offset = buf_page_start(buf) - vma->vm_start;
1613 up_read(&current->mm->mmap_sem);
1614 VERIFY(err, offset < (uintptr_t)map->size);
1615 if (err)
1616 goto bail;
1617 }
1618 pages[idx].addr = map->phys + offset;
1619 pages[idx].size = num << PAGE_SHIFT;
1620 }
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301621 rpra[i].buf.pv = lrpra[i].buf.pv = buf;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001622 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001623 PERF_END);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001624 for (i = bufs; i < bufs + handles; ++i) {
1625 struct fastrpc_mmap *map = ctx->maps[i];
1626
1627 pages[i].addr = map->phys;
1628 pages[i].size = map->size;
1629 }
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301630 if (!me->legacy) {
1631 fdlist = (uint64_t *)&pages[bufs + handles];
1632 for (i = 0; i < M_FDLIST; i++)
1633 fdlist[i] = 0;
1634 crclist = (uint32_t *)&fdlist[M_FDLIST];
1635 memset(crclist, 0, sizeof(uint32_t)*M_CRCLIST);
1636 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001637
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001638 /* copy non ion buffers */
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301639 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_COPY),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001640 rlen = copylen - metalen;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301641 for (oix = 0; rpra && lrpra && oix < inbufs + outbufs; ++oix) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001642 int i = ctx->overps[oix]->raix;
1643 struct fastrpc_mmap *map = ctx->maps[i];
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301644 size_t mlen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001645 uint64_t buf;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301646 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001647
1648 if (!len)
1649 continue;
1650 if (map)
1651 continue;
1652 if (ctx->overps[oix]->offset == 0) {
1653 rlen -= ALIGN(args, BALIGN) - args;
1654 args = ALIGN(args, BALIGN);
1655 }
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001656 mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001657 VERIFY(err, rlen >= mlen);
1658 if (err)
1659 goto bail;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301660 rpra[i].buf.pv = lrpra[i].buf.pv =
1661 (args - ctx->overps[oix]->offset);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001662 pages[list[i].pgidx].addr = ctx->buf->phys -
1663 ctx->overps[oix]->offset +
1664 (copylen - rlen);
1665 pages[list[i].pgidx].addr =
1666 buf_page_start(pages[list[i].pgidx].addr);
1667 buf = rpra[i].buf.pv;
1668 pages[list[i].pgidx].size = buf_num_pages(buf, len) * PAGE_SIZE;
1669 if (i < inbufs) {
1670 K_COPY_FROM_USER(err, kernel, uint64_to_ptr(buf),
1671 lpra[i].buf.pv, len);
1672 if (err)
1673 goto bail;
1674 }
1675 args = args + mlen;
1676 rlen -= mlen;
1677 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001678 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001679
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301680 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_FLUSH),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001681 for (oix = 0; oix < inbufs + outbufs; ++oix) {
1682 int i = ctx->overps[oix]->raix;
1683 struct fastrpc_mmap *map = ctx->maps[i];
1684
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001685 if (map && map->uncached)
1686 continue;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301687 if (ctx->fl->sctx->smmu.coherent &&
1688 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1689 continue;
1690 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1691 continue;
1692
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301693 if (rpra && lrpra && rpra[i].buf.len &&
1694 ctx->overps[oix]->mstart) {
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301695 if (map && map->handle)
1696 msm_ion_do_cache_op(ctx->fl->apps->client,
1697 map->handle,
1698 uint64_to_ptr(rpra[i].buf.pv),
1699 rpra[i].buf.len,
1700 ION_IOC_CLEAN_INV_CACHES);
1701 else
1702 dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv),
1703 uint64_to_ptr(rpra[i].buf.pv
1704 + rpra[i].buf.len));
1705 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001706 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001707 PERF_END);
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301708 for (i = bufs; rpra && lrpra && i < bufs + handles; i++) {
1709 rpra[i].dma.fd = lrpra[i].dma.fd = ctx->fds[i];
1710 rpra[i].dma.len = lrpra[i].dma.len = (uint32_t)lpra[i].buf.len;
1711 rpra[i].dma.offset = lrpra[i].dma.offset =
1712 (uint32_t)(uintptr_t)lpra[i].buf.pv;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001713 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001714
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001715 bail:
1716 return err;
1717}
1718
1719static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
1720 remote_arg_t *upra)
1721{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301722 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001723 uint32_t sc = ctx->sc;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001724 struct smq_invoke_buf *list;
1725 struct smq_phy_page *pages;
1726 struct fastrpc_mmap *mmap;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301727 uint64_t *fdlist = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07001728 uint32_t *crclist = NULL;
1729
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301730 remote_arg64_t *rpra = ctx->lrpra;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001731 int i, inbufs, outbufs, handles;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001732 int err = 0;
1733
1734 inbufs = REMOTE_SCALARS_INBUFS(sc);
1735 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001736 handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
1737 list = smq_invoke_buf_start(ctx->rpra, sc);
1738 pages = smq_phy_page_start(sc, list);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301739 if (!me->legacy) {
1740 fdlist = (uint64_t *)(pages + inbufs + outbufs + handles);
1741 crclist = (uint32_t *)(fdlist + M_FDLIST);
1742 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001743
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001744 for (i = inbufs; i < inbufs + outbufs; ++i) {
1745 if (!ctx->maps[i]) {
1746 K_COPY_TO_USER(err, kernel,
1747 ctx->lpra[i].buf.pv,
1748 uint64_to_ptr(rpra[i].buf.pv),
1749 rpra[i].buf.len);
1750 if (err)
1751 goto bail;
1752 } else {
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301753 mutex_lock(&ctx->fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05301754 fastrpc_mmap_free(ctx->maps[i], 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301755 mutex_unlock(&ctx->fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05301756 ctx->maps[i] = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001757 }
1758 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301759 mutex_lock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301760 if (fdlist && (inbufs + outbufs + handles)) {
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001761 for (i = 0; i < M_FDLIST; i++) {
1762 if (!fdlist[i])
1763 break;
1764 if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0,
Sathish Ambleyae5ee542017-01-16 22:24:23 -08001765 0, 0, &mmap))
c_mtharu7bd6a422017-10-17 18:15:37 +05301766 fastrpc_mmap_free(mmap, 0);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001767 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001768 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301769 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambleybae51902017-07-03 15:00:49 -07001770 if (ctx->crc && crclist && rpra)
c_mtharue1a5ce12017-10-13 20:47:09 +05301771 K_COPY_TO_USER(err, kernel, ctx->crc,
Sathish Ambleybae51902017-07-03 15:00:49 -07001772 crclist, M_CRCLIST*sizeof(uint32_t));
1773
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001774 bail:
1775 return err;
1776}
1777
1778static void inv_args_pre(struct smq_invoke_ctx *ctx)
1779{
1780 int i, inbufs, outbufs;
1781 uint32_t sc = ctx->sc;
1782 remote_arg64_t *rpra = ctx->rpra;
1783 uintptr_t end;
1784
1785 inbufs = REMOTE_SCALARS_INBUFS(sc);
1786 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
1787 for (i = inbufs; i < inbufs + outbufs; ++i) {
1788 struct fastrpc_mmap *map = ctx->maps[i];
1789
1790 if (map && map->uncached)
1791 continue;
1792 if (!rpra[i].buf.len)
1793 continue;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301794 if (ctx->fl->sctx->smmu.coherent &&
1795 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1796 continue;
1797 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1798 continue;
1799
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001800 if (buf_page_start(ptr_to_uint64((void *)rpra)) ==
1801 buf_page_start(rpra[i].buf.pv))
1802 continue;
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301803 if (!IS_CACHE_ALIGNED((uintptr_t)
1804 uint64_to_ptr(rpra[i].buf.pv))) {
1805 if (map && map->handle)
1806 msm_ion_do_cache_op(ctx->fl->apps->client,
1807 map->handle,
1808 uint64_to_ptr(rpra[i].buf.pv),
1809 sizeof(uintptr_t),
1810 ION_IOC_CLEAN_INV_CACHES);
1811 else
1812 dmac_flush_range(
1813 uint64_to_ptr(rpra[i].buf.pv), (char *)
1814 uint64_to_ptr(rpra[i].buf.pv + 1));
1815 }
1816
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001817 end = (uintptr_t)uint64_to_ptr(rpra[i].buf.pv +
1818 rpra[i].buf.len);
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301819 if (!IS_CACHE_ALIGNED(end)) {
1820 if (map && map->handle)
1821 msm_ion_do_cache_op(ctx->fl->apps->client,
1822 map->handle,
1823 uint64_to_ptr(end),
1824 sizeof(uintptr_t),
1825 ION_IOC_CLEAN_INV_CACHES);
1826 else
1827 dmac_flush_range((char *)end,
1828 (char *)end + 1);
1829 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001830 }
1831}
1832
1833static void inv_args(struct smq_invoke_ctx *ctx)
1834{
1835 int i, inbufs, outbufs;
1836 uint32_t sc = ctx->sc;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301837 remote_arg64_t *rpra = ctx->lrpra;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001838
1839 inbufs = REMOTE_SCALARS_INBUFS(sc);
1840 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
1841 for (i = inbufs; i < inbufs + outbufs; ++i) {
1842 struct fastrpc_mmap *map = ctx->maps[i];
1843
1844 if (map && map->uncached)
1845 continue;
1846 if (!rpra[i].buf.len)
1847 continue;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301848 if (ctx->fl->sctx->smmu.coherent &&
1849 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1850 continue;
1851 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1852 continue;
1853
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001854 if (buf_page_start(ptr_to_uint64((void *)rpra)) ==
1855 buf_page_start(rpra[i].buf.pv)) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001856 continue;
1857 }
1858 if (map && map->handle)
1859 msm_ion_do_cache_op(ctx->fl->apps->client, map->handle,
1860 (char *)uint64_to_ptr(rpra[i].buf.pv),
1861 rpra[i].buf.len, ION_IOC_INV_CACHES);
1862 else
1863 dmac_inv_range((char *)uint64_to_ptr(rpra[i].buf.pv),
1864 (char *)uint64_to_ptr(rpra[i].buf.pv
1865 + rpra[i].buf.len));
1866 }
1867
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001868}
1869
1870static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
1871 uint32_t kernel, uint32_t handle)
1872{
1873 struct smq_msg *msg = &ctx->msg;
1874 struct fastrpc_file *fl = ctx->fl;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301875 int err = 0, len, cid = -1;
1876 struct fastrpc_channel_ctx *channel_ctx = NULL;
1877
1878 cid = fl->cid;
1879 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
1880 if (err) {
1881 err = -ECHRNG;
1882 goto bail;
1883 }
1884 channel_ctx = &fl->apps->channel[fl->cid];
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001885
c_mtharue1a5ce12017-10-13 20:47:09 +05301886 VERIFY(err, NULL != channel_ctx->chan);
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301887 if (err) {
1888 err = -ECHRNG;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001889 goto bail;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301890 }
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301891 msg->pid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001892 msg->tid = current->pid;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301893 if (fl->sessionid)
1894 msg->tid |= (1 << SESSION_ID_INDEX);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001895 if (kernel)
1896 msg->pid = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301897 msg->invoke.header.ctx = ctx->ctxid | fl->pd;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001898 msg->invoke.header.handle = handle;
1899 msg->invoke.header.sc = ctx->sc;
1900 msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0;
1901 msg->invoke.page.size = buf_page_size(ctx->used);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301902 if (fl->apps->glink) {
1903 if (fl->ssrcount != channel_ctx->ssrcount) {
1904 err = -ECONNRESET;
1905 goto bail;
1906 }
1907 VERIFY(err, channel_ctx->link.port_state ==
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001908 FASTRPC_LINK_CONNECTED);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301909 if (err)
1910 goto bail;
1911 err = glink_tx(channel_ctx->chan,
1912 (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg),
1913 GLINK_TX_REQ_INTENT);
1914 } else {
1915 spin_lock(&fl->apps->hlock);
1916 len = smd_write((smd_channel_t *)
1917 channel_ctx->chan,
1918 msg, sizeof(*msg));
1919 spin_unlock(&fl->apps->hlock);
1920 VERIFY(err, len == sizeof(*msg));
1921 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001922 bail:
1923 return err;
1924}
1925
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301926static void fastrpc_smd_read_handler(int cid)
1927{
1928 struct fastrpc_apps *me = &gfa;
1929 struct smq_invoke_rsp rsp = {0};
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301930 int ret = 0, err = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301931 uint32_t index;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301932
1933 do {
1934 ret = smd_read_from_cb(me->channel[cid].chan, &rsp,
1935 sizeof(rsp));
1936 if (ret != sizeof(rsp))
1937 break;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301938
1939 index = (uint32_t)((rsp.ctx & FASTRPC_CTXID_MASK) >> 4);
1940 VERIFY(err, index < FASTRPC_CTX_MAX);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301941 if (err)
1942 goto bail;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301943
1944 VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index]));
1945 if (err)
1946 goto bail;
1947
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05301948 VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp.ctx & ~3)) &&
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301949 me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC));
1950 if (err)
1951 goto bail;
1952
1953 context_notify_user(me->ctxtable[index], rsp.retval);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301954 } while (ret == sizeof(rsp));
1955bail:
1956 if (err)
1957 pr_err("adsprpc: invalid response or context\n");
1958
1959}
1960
1961static void smd_event_handler(void *priv, unsigned int event)
1962{
1963 struct fastrpc_apps *me = &gfa;
1964 int cid = (int)(uintptr_t)priv;
1965
1966 switch (event) {
1967 case SMD_EVENT_OPEN:
1968 complete(&me->channel[cid].workport);
1969 break;
1970 case SMD_EVENT_CLOSE:
1971 fastrpc_notify_drivers(me, cid);
1972 break;
1973 case SMD_EVENT_DATA:
1974 fastrpc_smd_read_handler(cid);
1975 break;
1976 }
1977}
1978
1979
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001980static void fastrpc_init(struct fastrpc_apps *me)
1981{
1982 int i;
1983
1984 INIT_HLIST_HEAD(&me->drivers);
Tharun Kumar Merugubcd6fbf2018-01-04 17:49:34 +05301985 INIT_HLIST_HEAD(&me->maps);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001986 spin_lock_init(&me->hlock);
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301987 spin_lock_init(&me->ctxlock);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05301988 mutex_init(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001989 me->channel = &gcinfo[0];
1990 for (i = 0; i < NUM_CHANNELS; i++) {
1991 init_completion(&me->channel[i].work);
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05301992 init_completion(&me->channel[i].workport);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001993 me->channel[i].sesscount = 0;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05301994 /* All channels are secure by default except CDSP */
1995 me->channel[i].secure = SECURE_CHANNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001996 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05301997 /* Set CDSP channel to non secure */
1998 me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001999}
2000
2001static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl);
2002
2003static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
2004 uint32_t kernel,
Sathish Ambleybae51902017-07-03 15:00:49 -07002005 struct fastrpc_ioctl_invoke_crc *inv)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002006{
c_mtharue1a5ce12017-10-13 20:47:09 +05302007 struct smq_invoke_ctx *ctx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002008 struct fastrpc_ioctl_invoke *invoke = &inv->inv;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05302009 int err = 0, cid = -1, interrupted = 0;
Maria Yu757199c2017-09-22 16:05:49 +08002010 struct timespec invoket = {0};
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05302011 int64_t *perf_counter = NULL;
2012
2013 cid = fl->cid;
2014 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
2015 if (err) {
2016 err = -ECHRNG;
2017 goto bail;
2018 }
2019 VERIFY(err, fl->sctx != NULL);
2020 if (err) {
2021 err = -EBADR;
2022 goto bail;
2023 }
2024 perf_counter = getperfcounter(fl, PERF_COUNT);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002025
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002026 if (fl->profile)
2027 getnstimeofday(&invoket);
Tharun Kumar Merugue3edf3e2017-07-27 12:34:07 +05302028
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302029 if (!kernel) {
2030 VERIFY(err, invoke->handle != FASTRPC_STATIC_HANDLE_KERNEL);
2031 if (err) {
2032 pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d",
2033 __func__, current->comm, cid);
2034 goto bail;
2035 }
2036 }
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302037
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002038 if (!kernel) {
2039 VERIFY(err, 0 == context_restore_interrupted(fl, inv,
2040 &ctx));
2041 if (err)
2042 goto bail;
2043 if (fl->sctx->smmu.faults)
2044 err = FASTRPC_ENOSUCH;
2045 if (err)
2046 goto bail;
2047 if (ctx)
2048 goto wait;
2049 }
2050
2051 VERIFY(err, 0 == context_alloc(fl, kernel, inv, &ctx));
2052 if (err)
2053 goto bail;
2054
2055 if (REMOTE_SCALARS_LENGTH(ctx->sc)) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302056 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_GETARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002057 VERIFY(err, 0 == get_args(kernel, ctx));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002058 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002059 if (err)
2060 goto bail;
2061 }
2062
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302063 if (!fl->sctx->smmu.coherent) {
2064 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002065 inv_args_pre(ctx);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302066 PERF_END);
2067 }
2068
2069 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_LINK),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002070 VERIFY(err, 0 == fastrpc_invoke_send(ctx, kernel, invoke->handle));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002071 PERF_END);
2072
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002073 if (err)
2074 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002075 wait:
2076 if (kernel)
2077 wait_for_completion(&ctx->work);
2078 else {
2079 interrupted = wait_for_completion_interruptible(&ctx->work);
2080 VERIFY(err, 0 == (err = interrupted));
2081 if (err)
2082 goto bail;
2083 }
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +05302084 if (ctx->handle)
2085 glink_rx_done(ctx->handle, ctx->ptr, true);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302086 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
Sathish Ambleyc432b502017-06-05 12:03:42 -07002087 if (!fl->sctx->smmu.coherent)
2088 inv_args(ctx);
2089 PERF_END);
2090
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002091 VERIFY(err, 0 == (err = ctx->retval));
2092 if (err)
2093 goto bail;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002094
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302095 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_PUTARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002096 VERIFY(err, 0 == put_args(kernel, ctx, invoke->pra));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002097 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002098 if (err)
2099 goto bail;
2100 bail:
2101 if (ctx && interrupted == -ERESTARTSYS)
2102 context_save_interrupted(ctx);
2103 else if (ctx)
2104 context_free(ctx);
2105 if (fl->ssrcount != fl->apps->channel[cid].ssrcount)
2106 err = ECONNRESET;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002107
2108 if (fl->profile && !interrupted) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302109 if (invoke->handle != FASTRPC_STATIC_HANDLE_LISTENER) {
2110 int64_t *count = GET_COUNTER(perf_counter, PERF_INVOKE);
2111
2112 if (count)
2113 *count += getnstimediff(&invoket);
2114 }
2115 if (invoke->handle > FASTRPC_STATIC_HANDLE_MAX) {
2116 int64_t *count = GET_COUNTER(perf_counter, PERF_COUNT);
2117
2118 if (count)
2119 *count = *count+1;
2120 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002121 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002122 return err;
2123}
2124
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302125static int fastrpc_get_adsp_session(char *name, int *session)
2126{
2127 struct fastrpc_apps *me = &gfa;
2128 int err = 0, i;
2129
2130 for (i = 0; i < NUM_SESSIONS; i++) {
2131 if (!me->channel[0].spd[i].spdname)
2132 continue;
2133 if (!strcmp(name, me->channel[0].spd[i].spdname))
2134 break;
2135 }
2136 VERIFY(err, i < NUM_SESSIONS);
2137 if (err)
2138 goto bail;
2139 *session = i;
2140bail:
2141 return err;
2142}
2143
2144static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl);
Sathish Ambley36849af2017-02-02 09:35:55 -08002145static int fastrpc_channel_open(struct fastrpc_file *fl);
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302146static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002147static int fastrpc_init_process(struct fastrpc_file *fl,
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002148 struct fastrpc_ioctl_init_attrs *uproc)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002149{
2150 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302151 struct fastrpc_apps *me = &gfa;
Sathish Ambleybae51902017-07-03 15:00:49 -07002152 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002153 struct fastrpc_ioctl_init *init = &uproc->init;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002154 struct smq_phy_page pages[1];
c_mtharue1a5ce12017-10-13 20:47:09 +05302155 struct fastrpc_mmap *file = NULL, *mem = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302156 struct fastrpc_buf *imem = NULL;
2157 unsigned long imem_dma_attr = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302158 char *proc_name = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002159
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302160 VERIFY(err, 0 == (err = fastrpc_channel_open(fl)));
Sathish Ambley36849af2017-02-02 09:35:55 -08002161 if (err)
2162 goto bail;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302163 if (init->flags == FASTRPC_INIT_ATTACH ||
2164 init->flags == FASTRPC_INIT_ATTACH_SENSORS) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002165 remote_arg_t ra[1];
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302166 int tgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002167
2168 ra[0].buf.pv = (void *)&tgid;
2169 ra[0].buf.len = sizeof(tgid);
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302170 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002171 ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
2172 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302173 ioctl.fds = NULL;
2174 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002175 ioctl.crc = NULL;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302176 if (init->flags == FASTRPC_INIT_ATTACH)
2177 fl->pd = 0;
2178 else if (init->flags == FASTRPC_INIT_ATTACH_SENSORS) {
2179 fl->spdname = SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME;
2180 fl->pd = 2;
2181 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002182 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2183 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2184 if (err)
2185 goto bail;
2186 } else if (init->flags == FASTRPC_INIT_CREATE) {
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002187 remote_arg_t ra[6];
2188 int fds[6];
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002189 int mflags = 0;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302190 int memlen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002191 struct {
2192 int pgid;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302193 unsigned int namelen;
2194 unsigned int filelen;
2195 unsigned int pageslen;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002196 int attrs;
2197 int siglen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002198 } inbuf;
2199
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302200 inbuf.pgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002201 inbuf.namelen = strlen(current->comm) + 1;
2202 inbuf.filelen = init->filelen;
2203 fl->pd = 1;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302204
Tharun Kumar Merugudf852892017-12-07 16:27:37 +05302205 VERIFY(err, access_ok(0, (void __user *)init->file,
2206 init->filelen));
2207 if (err)
2208 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002209 if (init->filelen) {
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302210 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002211 VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, 0,
2212 init->file, init->filelen, mflags, &file));
Swathi K013c6202021-07-14 17:51:10 +05302213 if (file)
2214 file->is_filemap = true;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302215 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002216 if (err)
2217 goto bail;
2218 }
2219 inbuf.pageslen = 1;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302220
2221 VERIFY(err, !init->mem);
2222 if (err) {
2223 err = -EINVAL;
2224 pr_err("adsprpc: %s: %s: ERROR: donated memory allocated in userspace\n",
2225 current->comm, __func__);
2226 goto bail;
2227 }
2228 memlen = ALIGN(max(1024*1024*3, (int)init->filelen * 4),
2229 1024*1024);
2230 imem_dma_attr = DMA_ATTR_EXEC_MAPPING |
2231 DMA_ATTR_NO_KERNEL_MAPPING |
2232 DMA_ATTR_FORCE_NON_COHERENT;
2233 err = fastrpc_buf_alloc(fl, memlen, imem_dma_attr, 0, 0, &imem);
Tharun Kumar Merugudf852892017-12-07 16:27:37 +05302234 if (err)
2235 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302236 fl->init_mem = imem;
2237
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002238 inbuf.pageslen = 1;
2239 ra[0].buf.pv = (void *)&inbuf;
2240 ra[0].buf.len = sizeof(inbuf);
2241 fds[0] = 0;
2242
2243 ra[1].buf.pv = (void *)current->comm;
2244 ra[1].buf.len = inbuf.namelen;
2245 fds[1] = 0;
2246
2247 ra[2].buf.pv = (void *)init->file;
2248 ra[2].buf.len = inbuf.filelen;
2249 fds[2] = init->filefd;
2250
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302251 pages[0].addr = imem->phys;
2252 pages[0].size = imem->size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002253 ra[3].buf.pv = (void *)pages;
2254 ra[3].buf.len = 1 * sizeof(*pages);
2255 fds[3] = 0;
2256
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002257 inbuf.attrs = uproc->attrs;
2258 ra[4].buf.pv = (void *)&(inbuf.attrs);
2259 ra[4].buf.len = sizeof(inbuf.attrs);
2260 fds[4] = 0;
2261
2262 inbuf.siglen = uproc->siglen;
2263 ra[5].buf.pv = (void *)&(inbuf.siglen);
2264 ra[5].buf.len = sizeof(inbuf.siglen);
2265 fds[5] = 0;
2266
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302267 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002268 ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0);
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002269 if (uproc->attrs)
2270 ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002271 ioctl.inv.pra = ra;
2272 ioctl.fds = fds;
c_mtharue1a5ce12017-10-13 20:47:09 +05302273 ioctl.attrs = NULL;
2274 ioctl.crc = NULL;
2275 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2276 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2277 if (err)
2278 goto bail;
2279 } else if (init->flags == FASTRPC_INIT_CREATE_STATIC) {
2280 remote_arg_t ra[3];
2281 uint64_t phys = 0;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302282 size_t size = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302283 int fds[3];
2284 struct {
2285 int pgid;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302286 unsigned int namelen;
2287 unsigned int pageslen;
c_mtharue1a5ce12017-10-13 20:47:09 +05302288 } inbuf;
2289
2290 if (!init->filelen)
2291 goto bail;
2292
Jeya R26177c92021-04-09 13:22:31 +05302293 proc_name = kzalloc(init->filelen + 1, GFP_KERNEL);
c_mtharue1a5ce12017-10-13 20:47:09 +05302294 VERIFY(err, !IS_ERR_OR_NULL(proc_name));
2295 if (err)
2296 goto bail;
2297 VERIFY(err, 0 == copy_from_user((void *)proc_name,
2298 (void __user *)init->file, init->filelen));
2299 if (err)
2300 goto bail;
2301
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302302 fl->pd = 1;
c_mtharue1a5ce12017-10-13 20:47:09 +05302303 inbuf.pgid = current->tgid;
c_mtharu81a0aa72017-11-07 16:13:21 +05302304 inbuf.namelen = init->filelen;
c_mtharue1a5ce12017-10-13 20:47:09 +05302305 inbuf.pageslen = 0;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302306
2307 if (!strcmp(proc_name, "audiopd")) {
2308 fl->spdname = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME;
2309 VERIFY(err, !fastrpc_mmap_remove_pdr(fl));
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05302310 if (err)
2311 goto bail;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302312 }
2313
c_mtharue1a5ce12017-10-13 20:47:09 +05302314 if (!me->staticpd_flags) {
2315 inbuf.pageslen = 1;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302316 mutex_lock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302317 VERIFY(err, !fastrpc_mmap_create(fl, -1, 0, init->mem,
2318 init->memlen, ADSP_MMAP_REMOTE_HEAP_ADDR,
2319 &mem));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302320 mutex_unlock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302321 if (err)
2322 goto bail;
2323 phys = mem->phys;
2324 size = mem->size;
2325 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302326 hlosvm, 1, me->channel[fl->cid].rhvm.vmid,
2327 me->channel[fl->cid].rhvm.vmperm,
2328 me->channel[fl->cid].rhvm.vmcount));
c_mtharue1a5ce12017-10-13 20:47:09 +05302329 if (err) {
2330 pr_err("ADSPRPC: hyp_assign_phys fail err %d",
2331 err);
2332 pr_err("map->phys %llx, map->size %d\n",
2333 phys, (int)size);
2334 goto bail;
2335 }
2336 me->staticpd_flags = 1;
2337 }
2338
2339 ra[0].buf.pv = (void *)&inbuf;
2340 ra[0].buf.len = sizeof(inbuf);
2341 fds[0] = 0;
2342
2343 ra[1].buf.pv = (void *)proc_name;
2344 ra[1].buf.len = inbuf.namelen;
2345 fds[1] = 0;
2346
2347 pages[0].addr = phys;
2348 pages[0].size = size;
2349
2350 ra[2].buf.pv = (void *)pages;
2351 ra[2].buf.len = sizeof(*pages);
2352 fds[2] = 0;
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302353 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
c_mtharue1a5ce12017-10-13 20:47:09 +05302354
2355 ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
2356 ioctl.inv.pra = ra;
2357 ioctl.fds = NULL;
2358 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002359 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002360 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2361 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2362 if (err)
2363 goto bail;
2364 } else {
2365 err = -ENOTTY;
2366 }
2367bail:
c_mtharud91205a2017-11-07 16:01:06 +05302368 kfree(proc_name);
c_mtharue1a5ce12017-10-13 20:47:09 +05302369 if (err && (init->flags == FASTRPC_INIT_CREATE_STATIC))
2370 me->staticpd_flags = 0;
2371 if (mem && err) {
2372 if (mem->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
2373 hyp_assign_phys(mem->phys, (uint64_t)mem->size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302374 me->channel[fl->cid].rhvm.vmid,
2375 me->channel[fl->cid].rhvm.vmcount,
2376 hlosvm, hlosvmperm, 1);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302377 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302378 fastrpc_mmap_free(mem, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302379 mutex_unlock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302380 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302381 if (file) {
2382 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302383 fastrpc_mmap_free(file, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302384 mutex_unlock(&fl->fl_map_mutex);
2385 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002386 return err;
2387}
2388
2389static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
2390{
2391 int err = 0;
Sathish Ambleybae51902017-07-03 15:00:49 -07002392 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002393 remote_arg_t ra[1];
2394 int tgid = 0;
2395
Sathish Ambley36849af2017-02-02 09:35:55 -08002396 VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS);
2397 if (err)
2398 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05302399 VERIFY(err, fl->apps->channel[fl->cid].chan != NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002400 if (err)
2401 goto bail;
2402 tgid = fl->tgid;
2403 ra[0].buf.pv = (void *)&tgid;
2404 ra[0].buf.len = sizeof(tgid);
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302405 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002406 ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
2407 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302408 ioctl.fds = NULL;
2409 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002410 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002411 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2412 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2413bail:
2414 return err;
2415}
2416
2417static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302418 uintptr_t va, uint64_t phys,
2419 size_t size, uintptr_t *raddr)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002420{
Sathish Ambleybae51902017-07-03 15:00:49 -07002421 struct fastrpc_ioctl_invoke_crc ioctl;
c_mtharu63ffc012017-11-16 15:26:56 +05302422 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002423 struct smq_phy_page page;
2424 int num = 1;
2425 remote_arg_t ra[3];
2426 int err = 0;
2427 struct {
2428 int pid;
2429 uint32_t flags;
2430 uintptr_t vaddrin;
2431 int num;
2432 } inargs;
2433 struct {
2434 uintptr_t vaddrout;
2435 } routargs;
2436
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302437 inargs.pid = fl->tgid;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302438 inargs.vaddrin = (uintptr_t)va;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002439 inargs.flags = flags;
2440 inargs.num = fl->apps->compat ? num * sizeof(page) : num;
2441 ra[0].buf.pv = (void *)&inargs;
2442 ra[0].buf.len = sizeof(inargs);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302443 page.addr = phys;
2444 page.size = size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002445 ra[1].buf.pv = (void *)&page;
2446 ra[1].buf.len = num * sizeof(page);
2447
2448 ra[2].buf.pv = (void *)&routargs;
2449 ra[2].buf.len = sizeof(routargs);
2450
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302451 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002452 if (fl->apps->compat)
2453 ioctl.inv.sc = REMOTE_SCALARS_MAKE(4, 2, 1);
2454 else
2455 ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
2456 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302457 ioctl.fds = NULL;
2458 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002459 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002460 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2461 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302462 *raddr = (uintptr_t)routargs.vaddrout;
c_mtharue1a5ce12017-10-13 20:47:09 +05302463 if (err)
2464 goto bail;
2465 if (flags == ADSP_MMAP_HEAP_ADDR) {
2466 struct scm_desc desc = {0};
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002467
c_mtharue1a5ce12017-10-13 20:47:09 +05302468 desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302469 desc.args[1] = phys;
2470 desc.args[2] = size;
c_mtharue1a5ce12017-10-13 20:47:09 +05302471 desc.arginfo = SCM_ARGS(3);
2472 err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
2473 TZ_PIL_PROTECT_MEM_SUBSYS_ID), &desc);
2474 } else if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302475 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302476 hlosvm, 1, me->channel[fl->cid].rhvm.vmid,
2477 me->channel[fl->cid].rhvm.vmperm,
2478 me->channel[fl->cid].rhvm.vmcount));
c_mtharue1a5ce12017-10-13 20:47:09 +05302479 if (err)
2480 goto bail;
2481 }
2482bail:
2483 return err;
2484}
2485
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302486static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys,
2487 size_t size, uint32_t flags)
c_mtharue1a5ce12017-10-13 20:47:09 +05302488{
2489 int err = 0;
c_mtharu63ffc012017-11-16 15:26:56 +05302490 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302491 int tgid = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302492 int destVM[1] = {VMID_HLOS};
2493 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
2494
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302495 if (flags == ADSP_MMAP_HEAP_ADDR) {
c_mtharue1a5ce12017-10-13 20:47:09 +05302496 struct fastrpc_ioctl_invoke_crc ioctl;
2497 struct scm_desc desc = {0};
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302498 remote_arg_t ra[2];
2499
c_mtharue1a5ce12017-10-13 20:47:09 +05302500 struct {
2501 uint8_t skey;
2502 } routargs;
2503
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302504 if (fl == NULL)
2505 goto bail;
2506 tgid = fl->tgid;
2507 ra[0].buf.pv = (void *)&tgid;
2508 ra[0].buf.len = sizeof(tgid);
2509 ra[1].buf.pv = (void *)&routargs;
2510 ra[1].buf.len = sizeof(routargs);
c_mtharue1a5ce12017-10-13 20:47:09 +05302511
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302512 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302513 ioctl.inv.sc = REMOTE_SCALARS_MAKE(9, 1, 1);
c_mtharue1a5ce12017-10-13 20:47:09 +05302514 ioctl.inv.pra = ra;
2515 ioctl.fds = NULL;
2516 ioctl.attrs = NULL;
2517 ioctl.crc = NULL;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302518
c_mtharue1a5ce12017-10-13 20:47:09 +05302519
2520 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2521 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
Mohammed Nayeem Ur Rahman80f45dc2019-09-23 19:35:19 +05302522 if (err == AEE_EUNSUPPORTED) {
2523 remote_arg_t ra[1];
2524
2525 pr_warn("ADSPRPC:Failed to get security key with updated remote call, falling back to older method");
2526 ra[0].buf.pv = (void *)&routargs;
2527 ra[0].buf.len = sizeof(routargs);
2528 ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1);
2529 ioctl.inv.pra = ra;
2530 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2531 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2532 }
c_mtharue1a5ce12017-10-13 20:47:09 +05302533 if (err)
2534 goto bail;
Mohammed Nayeem Ur Rahman80f45dc2019-09-23 19:35:19 +05302535
c_mtharue1a5ce12017-10-13 20:47:09 +05302536 desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302537 desc.args[1] = phys;
2538 desc.args[2] = size;
c_mtharue1a5ce12017-10-13 20:47:09 +05302539 desc.args[3] = routargs.skey;
2540 desc.arginfo = SCM_ARGS(4);
2541 err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
2542 TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID), &desc);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302543 } else if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
2544 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302545 me->channel[fl->cid].rhvm.vmid,
2546 me->channel[fl->cid].rhvm.vmcount,
2547 destVM, destVMperm, 1));
c_mtharue1a5ce12017-10-13 20:47:09 +05302548 if (err)
2549 goto bail;
2550 }
2551
2552bail:
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002553 return err;
2554}
2555
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302556static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, uintptr_t raddr,
2557 uint64_t phys, size_t size, uint32_t flags)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002558{
Sathish Ambleybae51902017-07-03 15:00:49 -07002559 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002560 remote_arg_t ra[1];
2561 int err = 0;
2562 struct {
2563 int pid;
2564 uintptr_t vaddrout;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302565 size_t size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002566 } inargs;
2567
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302568 inargs.pid = fl->tgid;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302569 inargs.size = size;
2570 inargs.vaddrout = raddr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002571 ra[0].buf.pv = (void *)&inargs;
2572 ra[0].buf.len = sizeof(inargs);
2573
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302574 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002575 if (fl->apps->compat)
2576 ioctl.inv.sc = REMOTE_SCALARS_MAKE(5, 1, 0);
2577 else
2578 ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
2579 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302580 ioctl.fds = NULL;
2581 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002582 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002583 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2584 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
c_mtharue1a5ce12017-10-13 20:47:09 +05302585 if (err)
2586 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302587 if (flags == ADSP_MMAP_HEAP_ADDR ||
2588 flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
2589 VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, phys, size, flags));
c_mtharue1a5ce12017-10-13 20:47:09 +05302590 if (err)
2591 goto bail;
2592 }
2593bail:
2594 return err;
2595}
2596
2597static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
2598{
2599 struct fastrpc_mmap *match = NULL, *map = NULL;
2600 struct hlist_node *n = NULL;
2601 int err = 0, ret = 0;
2602 struct fastrpc_apps *me = &gfa;
2603 struct ramdump_segment *ramdump_segments_rh = NULL;
2604
2605 do {
2606 match = NULL;
2607 spin_lock(&me->hlock);
2608 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
2609 match = map;
2610 hlist_del_init(&map->hn);
2611 break;
2612 }
2613 spin_unlock(&me->hlock);
2614
2615 if (match) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302616 VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, match->phys,
2617 match->size, match->flags));
c_mtharue1a5ce12017-10-13 20:47:09 +05302618 if (err)
2619 goto bail;
2620 if (me->channel[0].ramdumpenabled) {
2621 ramdump_segments_rh = kcalloc(1,
2622 sizeof(struct ramdump_segment), GFP_KERNEL);
2623 if (ramdump_segments_rh) {
2624 ramdump_segments_rh->address =
2625 match->phys;
2626 ramdump_segments_rh->size = match->size;
2627 ret = do_elf_ramdump(
2628 me->channel[0].remoteheap_ramdump_dev,
2629 ramdump_segments_rh, 1);
2630 if (ret < 0)
2631 pr_err("ADSPRPC: unable to dump heap");
2632 kfree(ramdump_segments_rh);
2633 }
2634 }
c_mtharu7bd6a422017-10-17 18:15:37 +05302635 fastrpc_mmap_free(match, 0);
c_mtharue1a5ce12017-10-13 20:47:09 +05302636 }
2637 } while (match);
2638bail:
2639 if (err && match)
2640 fastrpc_mmap_add(match);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002641 return err;
2642}
2643
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302644static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl)
2645{
2646 struct fastrpc_apps *me = &gfa;
2647 int session = 0, err = 0;
2648
2649 VERIFY(err, !fastrpc_get_adsp_session(
2650 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
2651 if (err)
2652 goto bail;
2653 if (me->channel[fl->cid].spd[session].pdrcount !=
2654 me->channel[fl->cid].spd[session].prevpdrcount) {
2655 if (fastrpc_mmap_remove_ssr(fl))
2656 pr_err("ADSPRPC: SSR: Failed to unmap remote heap\n");
2657 me->channel[fl->cid].spd[session].prevpdrcount =
2658 me->channel[fl->cid].spd[session].pdrcount;
2659 }
2660 if (!me->channel[fl->cid].spd[session].ispdup) {
2661 VERIFY(err, 0);
2662 if (err) {
2663 err = -ENOTCONN;
2664 goto bail;
2665 }
2666 }
2667bail:
2668 return err;
2669}
2670
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002671static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302672 size_t len, struct fastrpc_mmap **ppmap);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002673
2674static void fastrpc_mmap_add(struct fastrpc_mmap *map);
2675
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05302676static inline void get_fastrpc_ioctl_mmap_64(
2677 struct fastrpc_ioctl_mmap_64 *mmap64,
2678 struct fastrpc_ioctl_mmap *immap)
2679{
2680 immap->fd = mmap64->fd;
2681 immap->flags = mmap64->flags;
2682 immap->vaddrin = (uintptr_t)mmap64->vaddrin;
2683 immap->size = mmap64->size;
2684}
2685
2686static inline void put_fastrpc_ioctl_mmap_64(
2687 struct fastrpc_ioctl_mmap_64 *mmap64,
2688 struct fastrpc_ioctl_mmap *immap)
2689{
2690 mmap64->vaddrout = (uint64_t)immap->vaddrout;
2691}
2692
2693static inline void get_fastrpc_ioctl_munmap_64(
2694 struct fastrpc_ioctl_munmap_64 *munmap64,
2695 struct fastrpc_ioctl_munmap *imunmap)
2696{
2697 imunmap->vaddrout = (uintptr_t)munmap64->vaddrout;
2698 imunmap->size = munmap64->size;
2699}
2700
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002701static int fastrpc_internal_munmap(struct fastrpc_file *fl,
2702 struct fastrpc_ioctl_munmap *ud)
2703{
2704 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302705 struct fastrpc_mmap *map = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302706 struct fastrpc_buf *rbuf = NULL, *free = NULL;
2707 struct hlist_node *n;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002708
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302709 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302710
2711 spin_lock(&fl->hlock);
2712 hlist_for_each_entry_safe(rbuf, n, &fl->remote_bufs, hn_rem) {
2713 if (rbuf->raddr && (rbuf->flags == ADSP_MMAP_ADD_PAGES)) {
2714 if ((rbuf->raddr == ud->vaddrout) &&
2715 (rbuf->size == ud->size)) {
2716 free = rbuf;
2717 break;
2718 }
2719 }
2720 }
2721 spin_unlock(&fl->hlock);
2722
2723 if (free) {
2724 VERIFY(err, !fastrpc_munmap_on_dsp(fl, free->raddr,
2725 free->phys, free->size, free->flags));
2726 if (err)
2727 goto bail;
2728 fastrpc_buf_free(rbuf, 0);
2729 mutex_unlock(&fl->map_mutex);
2730 return err;
2731 }
2732
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302733 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002734 VERIFY(err, !fastrpc_mmap_remove(fl, ud->vaddrout, ud->size, &map));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302735 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002736 if (err)
2737 goto bail;
Vamsi krishna Gattupalli3fed6e32020-12-02 12:59:03 +05302738 if (map) {
2739 VERIFY(err, !fastrpc_munmap_on_dsp(fl, map->raddr,
2740 map->phys, map->size, map->flags));
2741 if (err)
2742 goto bail;
2743 mutex_lock(&fl->fl_map_mutex);
2744 fastrpc_mmap_free(map, 0);
2745 mutex_unlock(&fl->fl_map_mutex);
2746 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002747bail:
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302748 if (err && map) {
2749 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002750 fastrpc_mmap_add(map);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302751 mutex_unlock(&fl->fl_map_mutex);
2752 }
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302753 mutex_unlock(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002754 return err;
2755}
2756
c_mtharu7bd6a422017-10-17 18:15:37 +05302757static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl,
2758 struct fastrpc_ioctl_munmap_fd *ud) {
2759 int err = 0;
2760 struct fastrpc_mmap *map = NULL;
2761
2762 VERIFY(err, (fl && ud));
2763 if (err)
2764 goto bail;
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302765 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302766 mutex_lock(&fl->fl_map_mutex);
Tharun Kumar Merugu09fc6152018-02-16 13:13:12 +05302767 if (fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map)) {
2768 pr_err("adsprpc: mapping not found to unmap %d va %llx %x\n",
c_mtharu7bd6a422017-10-17 18:15:37 +05302769 ud->fd, (unsigned long long)ud->va,
2770 (unsigned int)ud->len);
2771 err = -1;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302772 mutex_unlock(&fl->fl_map_mutex);
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302773 mutex_unlock(&fl->map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302774 goto bail;
2775 }
2776 if (map)
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302777 fastrpc_mmap_free(map, 0);
2778 mutex_unlock(&fl->fl_map_mutex);
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302779 mutex_unlock(&fl->map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302780bail:
2781 return err;
2782}
2783
2784
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002785static int fastrpc_internal_mmap(struct fastrpc_file *fl,
2786 struct fastrpc_ioctl_mmap *ud)
2787{
2788
c_mtharue1a5ce12017-10-13 20:47:09 +05302789 struct fastrpc_mmap *map = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302790 struct fastrpc_buf *rbuf = NULL;
2791 unsigned long dma_attr = 0;
2792 uintptr_t raddr = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002793 int err = 0;
2794
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302795 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302796 if (ud->flags == ADSP_MMAP_ADD_PAGES) {
2797 if (ud->vaddrin) {
2798 err = -EINVAL;
2799 pr_err("adsprpc: %s: %s: ERROR: adding user allocated pages is not supported\n",
2800 current->comm, __func__);
2801 goto bail;
2802 }
2803 dma_attr = DMA_ATTR_EXEC_MAPPING |
2804 DMA_ATTR_NO_KERNEL_MAPPING |
2805 DMA_ATTR_FORCE_NON_COHERENT;
2806 err = fastrpc_buf_alloc(fl, ud->size, dma_attr, ud->flags,
2807 1, &rbuf);
2808 if (err)
2809 goto bail;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302810 err = fastrpc_mmap_on_dsp(fl, ud->flags, 0,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302811 rbuf->phys, rbuf->size, &raddr);
2812 if (err)
2813 goto bail;
2814 rbuf->raddr = raddr;
2815 } else {
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302816
2817 uintptr_t va_to_dsp;
2818
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302819 mutex_lock(&fl->fl_map_mutex);
2820 if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin,
2821 ud->size, ud->flags, 1, &map)) {
Mohammed Nayeem Ur Rahmanaf5f6102019-10-09 13:36:52 +05302822 ud->vaddrout = map->raddr;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302823 mutex_unlock(&fl->fl_map_mutex);
2824 mutex_unlock(&fl->map_mutex);
2825 return 0;
2826 }
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302827
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302828 VERIFY(err, !fastrpc_mmap_create(fl, ud->fd, 0,
2829 (uintptr_t)ud->vaddrin, ud->size,
2830 ud->flags, &map));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302831 mutex_unlock(&fl->fl_map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302832 if (err)
2833 goto bail;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302834
2835 if (ud->flags == ADSP_MMAP_HEAP_ADDR ||
2836 ud->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
2837 va_to_dsp = 0;
2838 else
2839 va_to_dsp = (uintptr_t)map->va;
2840 VERIFY(err, 0 == fastrpc_mmap_on_dsp(fl, ud->flags, va_to_dsp,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302841 map->phys, map->size, &raddr));
2842 if (err)
2843 goto bail;
2844 map->raddr = raddr;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302845 }
Mohammed Nayeem Ur Rahman3ac5d322018-09-24 13:54:08 +05302846 ud->vaddrout = raddr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002847 bail:
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302848 if (err && map) {
2849 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302850 fastrpc_mmap_free(map, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302851 mutex_unlock(&fl->fl_map_mutex);
2852 }
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302853 mutex_unlock(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002854 return err;
2855}
2856
2857static void fastrpc_channel_close(struct kref *kref)
2858{
2859 struct fastrpc_apps *me = &gfa;
2860 struct fastrpc_channel_ctx *ctx;
2861 int cid;
2862
2863 ctx = container_of(kref, struct fastrpc_channel_ctx, kref);
2864 cid = ctx - &gcinfo[0];
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05302865 if (me->glink) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05302866 fastrpc_glink_close(ctx->chan, cid);
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05302867 ctx->chan = NULL;
2868 }
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302869 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002870 pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
2871 MAJOR(me->dev_no), cid);
2872}
2873
2874static void fastrpc_context_list_dtor(struct fastrpc_file *fl);
2875
2876static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan,
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302877 int secure, int sharedcb, struct fastrpc_session_ctx **session)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002878{
2879 struct fastrpc_apps *me = &gfa;
2880 int idx = 0, err = 0;
2881
2882 if (chan->sesscount) {
2883 for (idx = 0; idx < chan->sesscount; ++idx) {
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302884 if ((sharedcb && chan->session[idx].smmu.sharedcb) ||
2885 (!chan->session[idx].used &&
2886 chan->session[idx].smmu.secure
2887 == secure && !sharedcb)) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002888 chan->session[idx].used = 1;
2889 break;
2890 }
2891 }
2892 VERIFY(err, idx < chan->sesscount);
2893 if (err)
2894 goto bail;
2895 chan->session[idx].smmu.faults = 0;
2896 } else {
2897 VERIFY(err, me->dev != NULL);
2898 if (err)
2899 goto bail;
2900 chan->session[0].dev = me->dev;
c_mtharue1a5ce12017-10-13 20:47:09 +05302901 chan->session[0].smmu.dev = me->dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002902 }
2903
2904 *session = &chan->session[idx];
2905 bail:
2906 return err;
2907}
2908
c_mtharue1a5ce12017-10-13 20:47:09 +05302909static bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv,
2910 size_t size)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002911{
2912 if (glink_queue_rx_intent(h, NULL, size))
2913 return false;
2914 return true;
2915}
2916
c_mtharue1a5ce12017-10-13 20:47:09 +05302917static void fastrpc_glink_notify_tx_done(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002918 const void *pkt_priv, const void *ptr)
2919{
2920}
2921
c_mtharue1a5ce12017-10-13 20:47:09 +05302922static void fastrpc_glink_notify_rx(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002923 const void *pkt_priv, const void *ptr, size_t size)
2924{
2925 struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302926 struct fastrpc_apps *me = &gfa;
2927 uint32_t index;
c_mtharufdac6892017-10-12 13:09:01 +05302928 int err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002929
c_mtharufdac6892017-10-12 13:09:01 +05302930 VERIFY(err, (rsp && size >= sizeof(*rsp)));
2931 if (err)
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302932 goto bail;
2933
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302934 index = (uint32_t)((rsp->ctx & FASTRPC_CTXID_MASK) >> 4);
2935 VERIFY(err, index < FASTRPC_CTX_MAX);
c_mtharufdac6892017-10-12 13:09:01 +05302936 if (err)
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302937 goto bail;
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302938
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302939 VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index]));
2940 if (err)
2941 goto bail;
2942
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302943 VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp->ctx & ~3)) &&
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302944 me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC));
2945 if (err)
2946 goto bail;
2947
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +05302948 me->ctxtable[index]->handle = handle;
2949 me->ctxtable[index]->ptr = ptr;
2950
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302951 context_notify_user(me->ctxtable[index], rsp->retval);
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302952bail:
c_mtharufdac6892017-10-12 13:09:01 +05302953 if (err)
2954 pr_err("adsprpc: invalid response or context\n");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002955}
2956
c_mtharue1a5ce12017-10-13 20:47:09 +05302957static void fastrpc_glink_notify_state(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002958 unsigned int event)
2959{
2960 struct fastrpc_apps *me = &gfa;
2961 int cid = (int)(uintptr_t)priv;
2962 struct fastrpc_glink_info *link;
2963
2964 if (cid < 0 || cid >= NUM_CHANNELS)
2965 return;
2966 link = &me->channel[cid].link;
2967 switch (event) {
2968 case GLINK_CONNECTED:
2969 link->port_state = FASTRPC_LINK_CONNECTED;
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05302970 complete(&me->channel[cid].workport);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002971 break;
2972 case GLINK_LOCAL_DISCONNECTED:
2973 link->port_state = FASTRPC_LINK_DISCONNECTED;
2974 break;
2975 case GLINK_REMOTE_DISCONNECTED:
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002976 break;
2977 default:
2978 break;
2979 }
2980}
2981
2982static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
2983 struct fastrpc_session_ctx **session)
2984{
2985 int err = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302986 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002987
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302988 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002989 if (!*session)
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302990 err = fastrpc_session_alloc_locked(chan, secure, 0, session);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302991 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002992 return err;
2993}
2994
2995static void fastrpc_session_free(struct fastrpc_channel_ctx *chan,
2996 struct fastrpc_session_ctx *session)
2997{
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302998 struct fastrpc_apps *me = &gfa;
2999
3000 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003001 session->used = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303002 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003003}
3004
3005static int fastrpc_file_free(struct fastrpc_file *fl)
3006{
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303007 struct hlist_node *n = NULL;
Tharun Kumar Merugu3e966762018-04-04 10:56:44 +05303008 struct fastrpc_mmap *map = NULL, *lmap = NULL;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303009 struct fastrpc_perf *perf = NULL, *fperf = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003010 int cid;
3011
3012 if (!fl)
3013 return 0;
3014 cid = fl->cid;
3015
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05303016 (void)fastrpc_release_current_dsp_process(fl);
3017
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003018 spin_lock(&fl->apps->hlock);
3019 hlist_del_init(&fl->hn);
3020 spin_unlock(&fl->apps->hlock);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303021 kfree(fl->debug_buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003022
Sathish Ambleyd7fbcbb2017-03-08 10:55:48 -08003023 if (!fl->sctx) {
3024 kfree(fl);
3025 return 0;
3026 }
tharun kumar9f899ea2017-07-03 17:07:03 +05303027 spin_lock(&fl->hlock);
3028 fl->file_close = 1;
3029 spin_unlock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303030 if (!IS_ERR_OR_NULL(fl->init_mem))
3031 fastrpc_buf_free(fl->init_mem, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003032 fastrpc_context_list_dtor(fl);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303033 fastrpc_cached_buf_list_free(fl);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303034 mutex_lock(&fl->fl_map_mutex);
Tharun Kumar Merugu3e966762018-04-04 10:56:44 +05303035 do {
3036 lmap = NULL;
3037 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3038 hlist_del_init(&map->hn);
3039 lmap = map;
3040 break;
3041 }
3042 fastrpc_mmap_free(lmap, 1);
3043 } while (lmap);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303044 mutex_unlock(&fl->fl_map_mutex);
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303045 if (fl->refcount && (fl->ssrcount == fl->apps->channel[cid].ssrcount))
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003046 kref_put_mutex(&fl->apps->channel[cid].kref,
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303047 fastrpc_channel_close, &fl->apps->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003048 if (fl->sctx)
3049 fastrpc_session_free(&fl->apps->channel[cid], fl->sctx);
3050 if (fl->secsctx)
3051 fastrpc_session_free(&fl->apps->channel[cid], fl->secsctx);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303052
3053 mutex_lock(&fl->perf_mutex);
3054 do {
3055 struct hlist_node *pn = NULL;
3056
3057 fperf = NULL;
3058 hlist_for_each_entry_safe(perf, pn, &fl->perf, hn) {
3059 hlist_del_init(&perf->hn);
3060 fperf = perf;
3061 break;
3062 }
3063 kfree(fperf);
3064 } while (fperf);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303065 fastrpc_remote_buf_list_free(fl);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303066 mutex_unlock(&fl->perf_mutex);
3067 mutex_destroy(&fl->perf_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303068 mutex_destroy(&fl->fl_map_mutex);
Tharun Kumar Merugu8714e642018-05-17 15:21:08 +05303069 mutex_destroy(&fl->map_mutex);
Jeya R93608352021-06-10 13:03:44 +05303070 mutex_destroy(&fl->pm_qos_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003071 kfree(fl);
3072 return 0;
3073}
3074
3075static int fastrpc_device_release(struct inode *inode, struct file *file)
3076{
3077 struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
3078
3079 if (fl) {
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303080 if (fl->qos_request && pm_qos_request_active(&fl->pm_qos_req))
3081 pm_qos_remove_request(&fl->pm_qos_req);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003082 if (fl->debugfs_file != NULL)
3083 debugfs_remove(fl->debugfs_file);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003084 fastrpc_file_free(fl);
c_mtharue1a5ce12017-10-13 20:47:09 +05303085 file->private_data = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003086 }
3087 return 0;
3088}
3089
3090static void fastrpc_link_state_handler(struct glink_link_state_cb_info *cb_info,
3091 void *priv)
3092{
3093 struct fastrpc_apps *me = &gfa;
3094 int cid = (int)((uintptr_t)priv);
3095 struct fastrpc_glink_info *link;
3096
3097 if (cid < 0 || cid >= NUM_CHANNELS)
3098 return;
3099
3100 link = &me->channel[cid].link;
3101 switch (cb_info->link_state) {
3102 case GLINK_LINK_STATE_UP:
3103 link->link_state = FASTRPC_LINK_STATE_UP;
3104 complete(&me->channel[cid].work);
3105 break;
3106 case GLINK_LINK_STATE_DOWN:
3107 link->link_state = FASTRPC_LINK_STATE_DOWN;
3108 break;
3109 default:
3110 pr_err("adsprpc: unknown link state %d\n", cb_info->link_state);
3111 break;
3112 }
3113}
3114
3115static int fastrpc_glink_register(int cid, struct fastrpc_apps *me)
3116{
3117 int err = 0;
3118 struct fastrpc_glink_info *link;
3119
3120 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3121 if (err)
3122 goto bail;
3123
3124 link = &me->channel[cid].link;
3125 if (link->link_notify_handle != NULL)
3126 goto bail;
3127
3128 link->link_info.glink_link_state_notif_cb = fastrpc_link_state_handler;
3129 link->link_notify_handle = glink_register_link_state_cb(
3130 &link->link_info,
3131 (void *)((uintptr_t)cid));
3132 VERIFY(err, !IS_ERR_OR_NULL(me->channel[cid].link.link_notify_handle));
3133 if (err) {
3134 link->link_notify_handle = NULL;
3135 goto bail;
3136 }
3137 VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work,
3138 RPC_TIMEOUT));
3139bail:
3140 return err;
3141}
3142
3143static void fastrpc_glink_close(void *chan, int cid)
3144{
3145 int err = 0;
3146 struct fastrpc_glink_info *link;
3147
3148 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3149 if (err)
3150 return;
3151 link = &gfa.channel[cid].link;
3152
c_mtharu314a4202017-11-15 22:09:17 +05303153 if (link->port_state == FASTRPC_LINK_CONNECTED ||
3154 link->port_state == FASTRPC_LINK_REMOTE_DISCONNECTING) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003155 link->port_state = FASTRPC_LINK_DISCONNECTING;
3156 glink_close(chan);
3157 }
3158}
3159
3160static int fastrpc_glink_open(int cid)
3161{
3162 int err = 0;
3163 void *handle = NULL;
3164 struct fastrpc_apps *me = &gfa;
3165 struct glink_open_config *cfg;
3166 struct fastrpc_glink_info *link;
3167
3168 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3169 if (err)
3170 goto bail;
3171 link = &me->channel[cid].link;
3172 cfg = &me->channel[cid].link.cfg;
3173 VERIFY(err, (link->link_state == FASTRPC_LINK_STATE_UP));
3174 if (err)
3175 goto bail;
3176
Tharun Kumar Meruguca0db5262017-05-10 12:53:12 +05303177 VERIFY(err, (link->port_state == FASTRPC_LINK_DISCONNECTED));
3178 if (err)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003179 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003180
3181 link->port_state = FASTRPC_LINK_CONNECTING;
3182 cfg->priv = (void *)(uintptr_t)cid;
3183 cfg->edge = gcinfo[cid].link.link_info.edge;
3184 cfg->transport = gcinfo[cid].link.link_info.transport;
3185 cfg->name = FASTRPC_GLINK_GUID;
3186 cfg->notify_rx = fastrpc_glink_notify_rx;
3187 cfg->notify_tx_done = fastrpc_glink_notify_tx_done;
3188 cfg->notify_state = fastrpc_glink_notify_state;
3189 cfg->notify_rx_intent_req = fastrpc_glink_notify_rx_intent_req;
3190 handle = glink_open(cfg);
3191 VERIFY(err, !IS_ERR_OR_NULL(handle));
c_mtharu6e1d26b2017-10-09 16:05:24 +05303192 if (err) {
3193 if (link->port_state == FASTRPC_LINK_CONNECTING)
3194 link->port_state = FASTRPC_LINK_DISCONNECTED;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003195 goto bail;
c_mtharu6e1d26b2017-10-09 16:05:24 +05303196 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003197 me->channel[cid].chan = handle;
3198bail:
3199 return err;
3200}
3201
Sathish Ambley1ca68232017-01-19 10:32:55 -08003202static int fastrpc_debugfs_open(struct inode *inode, struct file *filp)
3203{
3204 filp->private_data = inode->i_private;
3205 return 0;
3206}
3207
3208static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
3209 size_t count, loff_t *position)
3210{
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303211 struct fastrpc_apps *me = &gfa;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003212 struct fastrpc_file *fl = filp->private_data;
3213 struct hlist_node *n;
c_mtharue1a5ce12017-10-13 20:47:09 +05303214 struct fastrpc_buf *buf = NULL;
3215 struct fastrpc_mmap *map = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303216 struct fastrpc_mmap *gmaps = NULL;
c_mtharue1a5ce12017-10-13 20:47:09 +05303217 struct smq_invoke_ctx *ictx = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303218 struct fastrpc_channel_ctx *chan = NULL;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003219 unsigned int len = 0;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303220 int i, j, sess_used = 0, ret = 0;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003221 char *fileinfo = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303222 char single_line[UL_SIZE] = "----------------";
3223 char title[UL_SIZE] = "=========================";
Sathish Ambley1ca68232017-01-19 10:32:55 -08003224
3225 fileinfo = kzalloc(DEBUGFS_SIZE, GFP_KERNEL);
3226 if (!fileinfo)
3227 goto bail;
3228 if (fl == NULL) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303229 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3230 "\n%s %s %s\n", title, " CHANNEL INFO ", title);
3231 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3232 "%-8s|%-9s|%-9s|%-14s|%-9s|%-13s\n",
3233 "susbsys", "refcount", "sesscount", "issubsystemup",
3234 "ssrcount", "session_used");
3235 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3236 "-%s%s%s%s-\n", single_line, single_line,
3237 single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003238 for (i = 0; i < NUM_CHANNELS; i++) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303239 sess_used = 0;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003240 chan = &gcinfo[i];
3241 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303242 DEBUGFS_SIZE - len, "%-8s", chan->subsys);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003243 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303244 DEBUGFS_SIZE - len, "|%-9d",
3245 chan->kref.refcount.counter);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303246 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303247 DEBUGFS_SIZE - len, "|%-9d",
3248 chan->sesscount);
3249 len += scnprintf(fileinfo + len,
3250 DEBUGFS_SIZE - len, "|%-14d",
3251 chan->issubsystemup);
3252 len += scnprintf(fileinfo + len,
3253 DEBUGFS_SIZE - len, "|%-9d",
3254 chan->ssrcount);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003255 for (j = 0; j < chan->sesscount; j++) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303256 sess_used += chan->session[j].used;
3257 }
3258 len += scnprintf(fileinfo + len,
3259 DEBUGFS_SIZE - len, "|%-13d\n", sess_used);
3260
3261 }
3262 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3263 "\n%s%s%s\n", "=============",
3264 " CMA HEAP ", "==============");
3265 len += scnprintf(fileinfo + len,
3266 DEBUGFS_SIZE - len, "%-20s|%-20s\n", "addr", "size");
3267 len += scnprintf(fileinfo + len,
3268 DEBUGFS_SIZE - len, "--%s%s---\n",
3269 single_line, single_line);
3270 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3271 "0x%-18llX", me->range.addr);
3272 len += scnprintf(fileinfo + len,
3273 DEBUGFS_SIZE - len, "|0x%-18llX\n", me->range.size);
3274 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3275 "\n==========%s %s %s===========\n",
3276 title, " GMAPS ", title);
3277 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3278 "%-20s|%-20s|%-20s|%-20s\n",
3279 "fd", "phys", "size", "va");
3280 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3281 "%s%s%s%s%s\n", single_line, single_line,
3282 single_line, single_line, single_line);
3283 hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
3284 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3285 "%-20d|0x%-18llX|0x%-18X|0x%-20lX\n\n",
3286 gmaps->fd, gmaps->phys,
3287 (uint32_t)gmaps->size,
3288 gmaps->va);
3289 }
3290 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3291 "%-20s|%-20s|%-20s|%-20s\n",
3292 "len", "refs", "raddr", "flags");
3293 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3294 "%s%s%s%s%s\n", single_line, single_line,
3295 single_line, single_line, single_line);
3296 hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
3297 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3298 "0x%-18X|%-20d|%-20lu|%-20u\n",
3299 (uint32_t)gmaps->len, gmaps->refs,
3300 gmaps->raddr, gmaps->flags);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003301 }
3302 } else {
3303 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303304 "\n%s %13s %d\n", "cid", ":", fl->cid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003305 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303306 "%s %12s %d\n", "tgid", ":", fl->tgid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003307 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303308 "%s %7s %d\n", "sessionid", ":", fl->sessionid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003309 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303310 "%s %8s %d\n", "ssrcount", ":", fl->ssrcount);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303311 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303312 "%s %8s %d\n", "refcount", ":", fl->refcount);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003313 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303314 "%s %14s %d\n", "pd", ":", fl->pd);
3315 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3316 "%s %9s %s\n", "spdname", ":", fl->spdname);
3317 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3318 "%s %6s %d\n", "file_close", ":", fl->file_close);
3319 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3320 "%s %8s %d\n", "sharedcb", ":", fl->sharedcb);
3321 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3322 "%s %9s %d\n", "profile", ":", fl->profile);
3323 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3324 "%s %3s %d\n", "smmu.coherent", ":",
3325 fl->sctx->smmu.coherent);
3326 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3327 "%s %4s %d\n", "smmu.enabled", ":",
3328 fl->sctx->smmu.enabled);
3329 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3330 "%s %9s %d\n", "smmu.cb", ":", fl->sctx->smmu.cb);
3331 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3332 "%s %5s %d\n", "smmu.secure", ":",
3333 fl->sctx->smmu.secure);
3334 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3335 "%s %5s %d\n", "smmu.faults", ":",
3336 fl->sctx->smmu.faults);
3337 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3338 "%s %s %d\n", "link.link_state",
3339 ":", *&me->channel[fl->cid].link.link_state);
3340
3341 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3342 "\n=======%s %s %s======\n", title,
3343 " LIST OF MAPS ", title);
3344
3345 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3346 "%-20s|%-20s|%-20s\n", "va", "phys", "size");
3347 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3348 "%s%s%s%s%s\n",
3349 single_line, single_line, single_line,
3350 single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003351 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303352 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3353 "0x%-20lX|0x%-20llX|0x%-20zu\n\n",
3354 map->va, map->phys,
3355 map->size);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003356 }
3357 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303358 "%-20s|%-20s|%-20s|%-20s\n",
3359 "len", "refs",
3360 "raddr", "uncached");
3361 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3362 "%s%s%s%s%s\n",
3363 single_line, single_line, single_line,
3364 single_line, single_line);
3365 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3366 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3367 "%-20zu|%-20d|0x%-20lX|%-20d\n\n",
3368 map->len, map->refs, map->raddr,
3369 map->uncached);
3370 }
3371 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3372 "%-20s|%-20s\n", "secure", "attr");
3373 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3374 "%s%s%s%s%s\n",
3375 single_line, single_line, single_line,
3376 single_line, single_line);
3377 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3378 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3379 "%-20d|0x%-20lX\n\n",
3380 map->secure, map->attr);
3381 }
3382 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303383 "%s %d\n\n",
3384 "KERNEL MEMORY ALLOCATION:", 1);
3385 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303386 "\n======%s %s %s======\n", title,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303387 " LIST OF CACHED BUFS ", title);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303388 spin_lock(&fl->hlock);
3389 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303390 "%-19s|%-19s|%-19s|%-19s\n",
3391 "virt", "phys", "size", "dma_attr");
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303392 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3393 "%s%s%s%s%s\n", single_line, single_line,
3394 single_line, single_line, single_line);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303395 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303396 len += scnprintf(fileinfo + len,
3397 DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303398 "0x%-17p|0x%-17llX|%-19zu|0x%-17lX\n",
3399 buf->virt, (uint64_t)buf->phys, buf->size,
3400 buf->dma_attr);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303401 }
3402 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3403 "\n%s %s %s\n", title,
3404 " LIST OF PENDING SMQCONTEXTS ", title);
3405
3406 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3407 "%-20s|%-10s|%-10s|%-10s|%-20s\n",
3408 "sc", "pid", "tgid", "used", "ctxid");
3409 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3410 "%s%s%s%s%s\n", single_line, single_line,
3411 single_line, single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003412 hlist_for_each_entry_safe(ictx, n, &fl->clst.pending, hn) {
3413 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303414 "0x%-18X|%-10d|%-10d|%-10zu|0x%-20llX\n\n",
3415 ictx->sc, ictx->pid, ictx->tgid,
3416 ictx->used, ictx->ctxid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003417 }
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303418
Sathish Ambley1ca68232017-01-19 10:32:55 -08003419 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303420 "\n%s %s %s\n", title,
3421 " LIST OF INTERRUPTED SMQCONTEXTS ", title);
3422
3423 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3424 "%-20s|%-10s|%-10s|%-10s|%-20s\n",
3425 "sc", "pid", "tgid", "used", "ctxid");
3426 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3427 "%s%s%s%s%s\n", single_line, single_line,
3428 single_line, single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003429 hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303430 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3431 "%-20u|%-20d|%-20d|%-20zu|0x%-20llX\n\n",
3432 ictx->sc, ictx->pid, ictx->tgid,
3433 ictx->used, ictx->ctxid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003434 }
3435 spin_unlock(&fl->hlock);
3436 }
3437 if (len > DEBUGFS_SIZE)
3438 len = DEBUGFS_SIZE;
3439 ret = simple_read_from_buffer(buffer, count, position, fileinfo, len);
3440 kfree(fileinfo);
3441bail:
3442 return ret;
3443}
3444
3445static const struct file_operations debugfs_fops = {
3446 .open = fastrpc_debugfs_open,
3447 .read = fastrpc_debugfs_read,
3448};
Sathish Ambley36849af2017-02-02 09:35:55 -08003449static int fastrpc_channel_open(struct fastrpc_file *fl)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003450{
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003451 struct fastrpc_apps *me = &gfa;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303452 int cid = -1, ii, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003453
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303454 mutex_lock(&me->smd_mutex);
3455
Sathish Ambley36849af2017-02-02 09:35:55 -08003456 VERIFY(err, fl && fl->sctx);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003457 if (err)
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303458 goto bail;
Sathish Ambley36849af2017-02-02 09:35:55 -08003459 cid = fl->cid;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303460 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
3461 if (err) {
3462 err = -ECHRNG;
c_mtharu314a4202017-11-15 22:09:17 +05303463 goto bail;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303464 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303465 if (me->channel[cid].ssrcount !=
3466 me->channel[cid].prevssrcount) {
3467 if (!me->channel[cid].issubsystemup) {
3468 VERIFY(err, 0);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303469 if (err) {
3470 err = -ENOTCONN;
c_mtharue1a5ce12017-10-13 20:47:09 +05303471 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303472 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303473 }
3474 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003475 fl->ssrcount = me->channel[cid].ssrcount;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303476 fl->refcount = 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003477 if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) ||
c_mtharue1a5ce12017-10-13 20:47:09 +05303478 (me->channel[cid].chan == NULL)) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303479 if (me->glink) {
3480 VERIFY(err, 0 == fastrpc_glink_register(cid, me));
3481 if (err)
3482 goto bail;
3483 VERIFY(err, 0 == fastrpc_glink_open(cid));
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303484 VERIFY(err,
3485 wait_for_completion_timeout(&me->channel[cid].workport,
3486 RPC_TIMEOUT));
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303487 } else {
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303488 if (me->channel[cid].chan == NULL) {
3489 VERIFY(err, !smd_named_open_on_edge(
3490 FASTRPC_SMD_GUID,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303491 gcinfo[cid].channel,
3492 (smd_channel_t **)&me->channel[cid].chan,
3493 (void *)(uintptr_t)cid,
3494 smd_event_handler));
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05303495 VERIFY(err,
3496 wait_for_completion_timeout(&me->channel[cid].workport,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003497 RPC_TIMEOUT));
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303498
3499 }
3500 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003501 if (err) {
c_mtharue1a5ce12017-10-13 20:47:09 +05303502 me->channel[cid].chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003503 goto bail;
3504 }
3505 kref_init(&me->channel[cid].kref);
3506 pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name,
3507 MAJOR(me->dev_no), cid);
Tharun Kumar Meruguc42c6e22018-05-29 15:50:46 +05303508
3509 for (ii = 0; ii < FASTRPC_GLINK_INTENT_NUM && me->glink; ii++)
3510 glink_queue_rx_intent(me->channel[cid].chan, NULL,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303511 FASTRPC_GLINK_INTENT_LEN);
Tharun Kumar Meruguc42c6e22018-05-29 15:50:46 +05303512
Tharun Kumar Merugud86fc8c2018-01-04 16:35:31 +05303513 if (cid == 0 && me->channel[cid].ssrcount !=
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003514 me->channel[cid].prevssrcount) {
c_mtharue1a5ce12017-10-13 20:47:09 +05303515 if (fastrpc_mmap_remove_ssr(fl))
3516 pr_err("ADSPRPC: SSR: Failed to unmap remote heap\n");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003517 me->channel[cid].prevssrcount =
3518 me->channel[cid].ssrcount;
3519 }
3520 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003521
3522bail:
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303523 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003524 return err;
3525}
3526
Sathish Ambley36849af2017-02-02 09:35:55 -08003527static int fastrpc_device_open(struct inode *inode, struct file *filp)
3528{
3529 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05303530 struct fastrpc_file *fl = NULL;
Sathish Ambley36849af2017-02-02 09:35:55 -08003531 struct fastrpc_apps *me = &gfa;
3532
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303533 /*
3534 * Indicates the device node opened
3535 * MINOR_NUM_DEV or MINOR_NUM_SECURE_DEV
3536 */
3537 int dev_minor = MINOR(inode->i_rdev);
3538
3539 VERIFY(err, ((dev_minor == MINOR_NUM_DEV) ||
3540 (dev_minor == MINOR_NUM_SECURE_DEV)));
3541 if (err) {
3542 pr_err("adsprpc: Invalid dev minor num %d\n", dev_minor);
3543 return err;
3544 }
3545
c_mtharue1a5ce12017-10-13 20:47:09 +05303546 VERIFY(err, NULL != (fl = kzalloc(sizeof(*fl), GFP_KERNEL)));
Sathish Ambley36849af2017-02-02 09:35:55 -08003547 if (err)
3548 return err;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303549
Sathish Ambley36849af2017-02-02 09:35:55 -08003550 context_list_ctor(&fl->clst);
3551 spin_lock_init(&fl->hlock);
3552 INIT_HLIST_HEAD(&fl->maps);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303553 INIT_HLIST_HEAD(&fl->perf);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303554 INIT_HLIST_HEAD(&fl->cached_bufs);
3555 INIT_HLIST_HEAD(&fl->remote_bufs);
Sathish Ambley36849af2017-02-02 09:35:55 -08003556 INIT_HLIST_NODE(&fl->hn);
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05303557 fl->sessionid = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003558 fl->apps = me;
3559 fl->mode = FASTRPC_MODE_SERIAL;
3560 fl->cid = -1;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303561 fl->dev_minor = dev_minor;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303562 fl->init_mem = NULL;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303563 fl->qos_request = 0;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303564 fl->refcount = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003565 filp->private_data = fl;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05303566 mutex_init(&fl->map_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303567 mutex_init(&fl->fl_map_mutex);
Sathish Ambley36849af2017-02-02 09:35:55 -08003568 spin_lock(&me->hlock);
3569 hlist_add_head(&fl->hn, &me->drivers);
3570 spin_unlock(&me->hlock);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303571 mutex_init(&fl->perf_mutex);
Jeya R93608352021-06-10 13:03:44 +05303572 mutex_init(&fl->pm_qos_mutex);
Sathish Ambley36849af2017-02-02 09:35:55 -08003573 return 0;
3574}
3575
Edgar Flores1a772fa2020-02-07 14:59:29 -08003576static int fastrpc_set_process_info(struct fastrpc_file *fl)
3577{
3578 int err = 0, buf_size = 0;
3579 char strpid[PID_SIZE];
3580
3581 fl->tgid = current->tgid;
3582 snprintf(strpid, PID_SIZE, "%d", current->pid);
3583 buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
3584 fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
3585 if (!fl->debug_buf) {
3586 err = -ENOMEM;
3587 return err;
3588 }
3589 snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
3590 current->comm, "_", current->pid);
3591 fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
3592 debugfs_root, fl, &debugfs_fops);
3593 if (!fl->debugfs_file)
3594 pr_warn("Error: %s: %s: failed to create debugfs file %s\n",
3595 current->comm, __func__, fl->debug_buf);
3596 return err;
3597}
3598
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003599static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
3600{
3601 int err = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003602 uint32_t cid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003603
c_mtharue1a5ce12017-10-13 20:47:09 +05303604 VERIFY(err, fl != NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003605 if (err)
3606 goto bail;
Edgar Flores1a772fa2020-02-07 14:59:29 -08003607 err = fastrpc_set_process_info(fl);
3608 if (err)
3609 goto bail;
Sathish Ambley36849af2017-02-02 09:35:55 -08003610 if (fl->cid == -1) {
3611 cid = *info;
3612 VERIFY(err, cid < NUM_CHANNELS);
3613 if (err)
3614 goto bail;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303615 /* Check to see if the device node is non-secure */
zhaochenfc798572018-08-17 15:32:37 +08003616 if (fl->dev_minor == MINOR_NUM_DEV &&
3617 fl->apps->secure_flag == true) {
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303618 /*
3619 * For non secure device node check and make sure that
3620 * the channel allows non-secure access
3621 * If not, bail. Session will not start.
3622 * cid will remain -1 and client will not be able to
3623 * invoke any other methods without failure
3624 */
3625 if (fl->apps->channel[cid].secure == SECURE_CHANNEL) {
3626 err = -EPERM;
3627 pr_err("adsprpc: GetInfo failed dev %d, cid %d, secure %d\n",
3628 fl->dev_minor, cid,
3629 fl->apps->channel[cid].secure);
3630 goto bail;
3631 }
3632 }
Sathish Ambley36849af2017-02-02 09:35:55 -08003633 fl->cid = cid;
3634 fl->ssrcount = fl->apps->channel[cid].ssrcount;
3635 VERIFY(err, !fastrpc_session_alloc_locked(
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303636 &fl->apps->channel[cid], 0, fl->sharedcb, &fl->sctx));
Sathish Ambley36849af2017-02-02 09:35:55 -08003637 if (err)
3638 goto bail;
3639 }
Tharun Kumar Merugu80be7d62017-08-02 11:03:22 +05303640 VERIFY(err, fl->sctx != NULL);
3641 if (err)
3642 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003643 *info = (fl->sctx->smmu.enabled ? 1 : 0);
3644bail:
3645 return err;
3646}
3647
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303648static int fastrpc_internal_control(struct fastrpc_file *fl,
3649 struct fastrpc_ioctl_control *cp)
3650{
Mohammed Nayeem Ur Rahman18d633f2019-05-28 15:11:40 +05303651 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303652 int err = 0;
3653 int latency;
3654
3655 VERIFY(err, !IS_ERR_OR_NULL(fl) && !IS_ERR_OR_NULL(fl->apps));
3656 if (err)
3657 goto bail;
3658 VERIFY(err, !IS_ERR_OR_NULL(cp));
3659 if (err)
3660 goto bail;
3661
3662 switch (cp->req) {
3663 case FASTRPC_CONTROL_LATENCY:
3664 latency = cp->lp.enable == FASTRPC_LATENCY_CTRL_ENB ?
3665 fl->apps->latency : PM_QOS_DEFAULT_VALUE;
3666 VERIFY(err, latency != 0);
3667 if (err)
3668 goto bail;
Jeya R93608352021-06-10 13:03:44 +05303669 mutex_lock(&fl->pm_qos_mutex);
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303670 if (!fl->qos_request) {
3671 pm_qos_add_request(&fl->pm_qos_req,
3672 PM_QOS_CPU_DMA_LATENCY, latency);
3673 fl->qos_request = 1;
3674 } else
3675 pm_qos_update_request(&fl->pm_qos_req, latency);
Jeya R93608352021-06-10 13:03:44 +05303676 mutex_unlock(&fl->pm_qos_mutex);
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303677 break;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303678 case FASTRPC_CONTROL_SMMU:
Mohammed Nayeem Ur Rahman18d633f2019-05-28 15:11:40 +05303679 if (!me->legacy)
3680 fl->sharedcb = cp->smmu.sharedcb;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303681 break;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303682 case FASTRPC_CONTROL_KALLOC:
3683 cp->kalloc.kalloc_support = 1;
3684 break;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303685 default:
3686 err = -ENOTTY;
3687 break;
3688 }
3689bail:
3690 return err;
3691}
3692
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003693static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
3694 unsigned long ioctl_param)
3695{
3696 union {
Sathish Ambleybae51902017-07-03 15:00:49 -07003697 struct fastrpc_ioctl_invoke_crc inv;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003698 struct fastrpc_ioctl_mmap mmap;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303699 struct fastrpc_ioctl_mmap_64 mmap64;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003700 struct fastrpc_ioctl_munmap munmap;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303701 struct fastrpc_ioctl_munmap_64 munmap64;
c_mtharu7bd6a422017-10-17 18:15:37 +05303702 struct fastrpc_ioctl_munmap_fd munmap_fd;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08003703 struct fastrpc_ioctl_init_attrs init;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003704 struct fastrpc_ioctl_perf perf;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303705 struct fastrpc_ioctl_control cp;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003706 } p;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303707 union {
3708 struct fastrpc_ioctl_mmap mmap;
3709 struct fastrpc_ioctl_munmap munmap;
3710 } i;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003711 void *param = (char *)ioctl_param;
3712 struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
3713 int size = 0, err = 0;
3714 uint32_t info;
3715
c_mtharue1a5ce12017-10-13 20:47:09 +05303716 p.inv.fds = NULL;
3717 p.inv.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07003718 p.inv.crc = NULL;
tharun kumar9f899ea2017-07-03 17:07:03 +05303719 spin_lock(&fl->hlock);
3720 if (fl->file_close == 1) {
3721 err = EBADF;
3722 pr_warn("ADSPRPC: fastrpc_device_release is happening, So not sending any new requests to DSP");
3723 spin_unlock(&fl->hlock);
3724 goto bail;
3725 }
3726 spin_unlock(&fl->hlock);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003727
3728 switch (ioctl_num) {
3729 case FASTRPC_IOCTL_INVOKE:
3730 size = sizeof(struct fastrpc_ioctl_invoke);
Sathish Ambleybae51902017-07-03 15:00:49 -07003731 /* fall through */
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003732 case FASTRPC_IOCTL_INVOKE_FD:
3733 if (!size)
3734 size = sizeof(struct fastrpc_ioctl_invoke_fd);
3735 /* fall through */
3736 case FASTRPC_IOCTL_INVOKE_ATTRS:
3737 if (!size)
3738 size = sizeof(struct fastrpc_ioctl_invoke_attrs);
Sathish Ambleybae51902017-07-03 15:00:49 -07003739 /* fall through */
3740 case FASTRPC_IOCTL_INVOKE_CRC:
3741 if (!size)
3742 size = sizeof(struct fastrpc_ioctl_invoke_crc);
c_mtharue1a5ce12017-10-13 20:47:09 +05303743 K_COPY_FROM_USER(err, 0, &p.inv, param, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003744 if (err)
3745 goto bail;
3746 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode,
3747 0, &p.inv)));
3748 if (err)
3749 goto bail;
3750 break;
3751 case FASTRPC_IOCTL_MMAP:
c_mtharue1a5ce12017-10-13 20:47:09 +05303752 K_COPY_FROM_USER(err, 0, &p.mmap, param,
3753 sizeof(p.mmap));
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05303754 if (err)
3755 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003756 VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap)));
3757 if (err)
3758 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05303759 K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003760 if (err)
3761 goto bail;
3762 break;
3763 case FASTRPC_IOCTL_MUNMAP:
c_mtharue1a5ce12017-10-13 20:47:09 +05303764 K_COPY_FROM_USER(err, 0, &p.munmap, param,
3765 sizeof(p.munmap));
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05303766 if (err)
3767 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003768 VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
3769 &p.munmap)));
3770 if (err)
3771 goto bail;
3772 break;
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303773 case FASTRPC_IOCTL_MMAP_64:
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303774 K_COPY_FROM_USER(err, 0, &p.mmap64, param,
3775 sizeof(p.mmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303776 if (err)
3777 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303778 get_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
3779 VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &i.mmap)));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303780 if (err)
3781 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303782 put_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
3783 K_COPY_TO_USER(err, 0, param, &p.mmap64, sizeof(p.mmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303784 if (err)
3785 goto bail;
3786 break;
3787 case FASTRPC_IOCTL_MUNMAP_64:
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303788 K_COPY_FROM_USER(err, 0, &p.munmap64, param,
3789 sizeof(p.munmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303790 if (err)
3791 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303792 get_fastrpc_ioctl_munmap_64(&p.munmap64, &i.munmap);
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303793 VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303794 &i.munmap)));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303795 if (err)
3796 goto bail;
3797 break;
c_mtharu7bd6a422017-10-17 18:15:37 +05303798 case FASTRPC_IOCTL_MUNMAP_FD:
3799 K_COPY_FROM_USER(err, 0, &p.munmap_fd, param,
3800 sizeof(p.munmap_fd));
3801 if (err)
3802 goto bail;
3803 VERIFY(err, 0 == (err = fastrpc_internal_munmap_fd(fl,
3804 &p.munmap_fd)));
3805 if (err)
3806 goto bail;
3807 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003808 case FASTRPC_IOCTL_SETMODE:
3809 switch ((uint32_t)ioctl_param) {
3810 case FASTRPC_MODE_PARALLEL:
3811 case FASTRPC_MODE_SERIAL:
3812 fl->mode = (uint32_t)ioctl_param;
3813 break;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003814 case FASTRPC_MODE_PROFILE:
3815 fl->profile = (uint32_t)ioctl_param;
3816 break;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05303817 case FASTRPC_MODE_SESSION:
3818 fl->sessionid = 1;
3819 fl->tgid |= (1 << SESSION_ID_INDEX);
3820 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003821 default:
3822 err = -ENOTTY;
3823 break;
3824 }
3825 break;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003826 case FASTRPC_IOCTL_GETPERF:
c_mtharue1a5ce12017-10-13 20:47:09 +05303827 K_COPY_FROM_USER(err, 0, &p.perf,
3828 param, sizeof(p.perf));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003829 if (err)
3830 goto bail;
3831 p.perf.numkeys = sizeof(struct fastrpc_perf)/sizeof(int64_t);
3832 if (p.perf.keys) {
3833 char *keys = PERF_KEYS;
3834
c_mtharue1a5ce12017-10-13 20:47:09 +05303835 K_COPY_TO_USER(err, 0, (void *)p.perf.keys,
3836 keys, strlen(keys)+1);
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003837 if (err)
3838 goto bail;
3839 }
3840 if (p.perf.data) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303841 struct fastrpc_perf *perf = NULL, *fperf = NULL;
3842 struct hlist_node *n = NULL;
3843
3844 mutex_lock(&fl->perf_mutex);
3845 hlist_for_each_entry_safe(perf, n, &fl->perf, hn) {
3846 if (perf->tid == current->pid) {
3847 fperf = perf;
3848 break;
3849 }
3850 }
3851
3852 mutex_unlock(&fl->perf_mutex);
3853
3854 if (fperf) {
3855 K_COPY_TO_USER(err, 0, (void *)p.perf.data,
3856 fperf, sizeof(*fperf));
3857 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003858 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303859 K_COPY_TO_USER(err, 0, param, &p.perf, sizeof(p.perf));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003860 if (err)
3861 goto bail;
3862 break;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303863 case FASTRPC_IOCTL_CONTROL:
c_mtharue1a5ce12017-10-13 20:47:09 +05303864 K_COPY_FROM_USER(err, 0, &p.cp, param,
3865 sizeof(p.cp));
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303866 if (err)
3867 goto bail;
3868 VERIFY(err, 0 == (err = fastrpc_internal_control(fl, &p.cp)));
3869 if (err)
3870 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303871 if (p.cp.req == FASTRPC_CONTROL_KALLOC) {
3872 K_COPY_TO_USER(err, 0, param, &p.cp, sizeof(p.cp));
3873 if (err)
3874 goto bail;
3875 }
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303876 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003877 case FASTRPC_IOCTL_GETINFO:
c_mtharue1a5ce12017-10-13 20:47:09 +05303878 K_COPY_FROM_USER(err, 0, &info, param, sizeof(info));
Sathish Ambley36849af2017-02-02 09:35:55 -08003879 if (err)
3880 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003881 VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info)));
3882 if (err)
3883 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05303884 K_COPY_TO_USER(err, 0, param, &info, sizeof(info));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003885 if (err)
3886 goto bail;
3887 break;
3888 case FASTRPC_IOCTL_INIT:
Sathish Ambleyd6300c32017-01-18 09:50:43 -08003889 p.init.attrs = 0;
3890 p.init.siglen = 0;
3891 size = sizeof(struct fastrpc_ioctl_init);
3892 /* fall through */
3893 case FASTRPC_IOCTL_INIT_ATTRS:
3894 if (!size)
3895 size = sizeof(struct fastrpc_ioctl_init_attrs);
c_mtharue1a5ce12017-10-13 20:47:09 +05303896 K_COPY_FROM_USER(err, 0, &p.init, param, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003897 if (err)
3898 goto bail;
Tharun Kumar Merugu4ea0eac2017-08-22 11:42:51 +05303899 VERIFY(err, p.init.init.filelen >= 0 &&
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05303900 p.init.init.filelen < INIT_FILELEN_MAX);
3901 if (err)
3902 goto bail;
3903 VERIFY(err, p.init.init.memlen >= 0 &&
3904 p.init.init.memlen < INIT_MEMLEN_MAX);
Tharun Kumar Merugu4ea0eac2017-08-22 11:42:51 +05303905 if (err)
3906 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303907 VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003908 if (err)
3909 goto bail;
3910 break;
3911
3912 default:
3913 err = -ENOTTY;
3914 pr_info("bad ioctl: %d\n", ioctl_num);
3915 break;
3916 }
3917 bail:
3918 return err;
3919}
3920
3921static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
3922 unsigned long code,
3923 void *data)
3924{
3925 struct fastrpc_apps *me = &gfa;
3926 struct fastrpc_channel_ctx *ctx;
c_mtharue1a5ce12017-10-13 20:47:09 +05303927 struct notif_data *notifdata = data;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003928 int cid;
3929
3930 ctx = container_of(nb, struct fastrpc_channel_ctx, nb);
3931 cid = ctx - &me->channel[0];
3932 if (code == SUBSYS_BEFORE_SHUTDOWN) {
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303933 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003934 ctx->ssrcount++;
c_mtharue1a5ce12017-10-13 20:47:09 +05303935 ctx->issubsystemup = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303936 if (ctx->chan) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303937 if (me->glink)
3938 fastrpc_glink_close(ctx->chan, cid);
3939 else
3940 smd_close(ctx->chan);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303941 ctx->chan = NULL;
3942 pr_info("'restart notifier: closed /dev/%s c %d %d'\n",
3943 gcinfo[cid].name, MAJOR(me->dev_no), cid);
3944 }
3945 mutex_unlock(&me->smd_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05303946 if (cid == 0)
3947 me->staticpd_flags = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003948 fastrpc_notify_drivers(me, cid);
c_mtharue1a5ce12017-10-13 20:47:09 +05303949 } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) {
3950 if (me->channel[0].remoteheap_ramdump_dev &&
3951 notifdata->enable_ramdump) {
3952 me->channel[0].ramdumpenabled = 1;
3953 }
3954 } else if (code == SUBSYS_AFTER_POWERUP) {
3955 ctx->issubsystemup = 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003956 }
3957
3958 return NOTIFY_DONE;
3959}
3960
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303961static int fastrpc_pdr_notifier_cb(struct notifier_block *pdrnb,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05303962 unsigned long code,
3963 void *data)
3964{
3965 struct fastrpc_apps *me = &gfa;
3966 struct fastrpc_static_pd *spd;
3967 struct notif_data *notifdata = data;
3968
3969 spd = container_of(pdrnb, struct fastrpc_static_pd, pdrnb);
3970 if (code == SERVREG_NOTIF_SERVICE_STATE_DOWN_V01) {
3971 mutex_lock(&me->smd_mutex);
3972 spd->pdrcount++;
3973 spd->ispdup = 0;
3974 pr_info("ADSPRPC: Audio PDR notifier %d %s\n",
3975 MAJOR(me->dev_no), spd->spdname);
3976 mutex_unlock(&me->smd_mutex);
3977 if (!strcmp(spd->spdname,
3978 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME))
3979 me->staticpd_flags = 0;
3980 fastrpc_notify_pdr_drivers(me, spd->spdname);
3981 } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) {
3982 if (me->channel[0].remoteheap_ramdump_dev &&
3983 notifdata->enable_ramdump) {
3984 me->channel[0].ramdumpenabled = 1;
3985 }
3986 } else if (code == SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
3987 spd->ispdup = 1;
3988 }
3989
3990 return NOTIFY_DONE;
3991}
3992
3993static int fastrpc_get_service_location_notify(struct notifier_block *nb,
3994 unsigned long opcode, void *data)
3995{
3996 struct fastrpc_static_pd *spd;
3997 struct pd_qmi_client_data *pdr = data;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303998 int curr_state = 0, i = 0;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05303999
4000 spd = container_of(nb, struct fastrpc_static_pd, get_service_nb);
4001 if (opcode == LOCATOR_DOWN) {
4002 pr_err("ADSPRPC: Audio PD restart notifier locator down\n");
4003 return NOTIFY_DONE;
4004 }
4005
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304006 for (i = 0; i < pdr->total_domains; i++) {
4007 if ((!strcmp(pdr->domain_list[i].name,
4008 "msm/adsp/audio_pd")) ||
4009 (!strcmp(pdr->domain_list[i].name,
4010 "msm/adsp/sensor_pd"))) {
4011 spd->pdrhandle =
4012 service_notif_register_notifier(
4013 pdr->domain_list[i].name,
4014 pdr->domain_list[i].instance_id,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304015 &spd->pdrnb, &curr_state);
Tharun Kumar Meruguad4beb82018-05-10 19:51:48 +05304016 if (IS_ERR(spd->pdrhandle)) {
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304017 pr_err("ADSPRPC: Unable to register notifier\n");
Tharun Kumar Meruguad4beb82018-05-10 19:51:48 +05304018 } else if (curr_state ==
4019 SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
4020 pr_info("ADSPRPC: STATE_UP_V01 received\n");
4021 spd->ispdup = 1;
4022 } else if (curr_state ==
4023 SERVREG_NOTIF_SERVICE_STATE_UNINIT_V01) {
4024 pr_info("ADSPRPC: STATE_UNINIT_V01 received\n");
4025 }
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304026 break;
4027 }
4028 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304029
4030 return NOTIFY_DONE;
4031}
4032
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004033static const struct file_operations fops = {
4034 .open = fastrpc_device_open,
4035 .release = fastrpc_device_release,
4036 .unlocked_ioctl = fastrpc_device_ioctl,
4037 .compat_ioctl = compat_fastrpc_device_ioctl,
4038};
4039
4040static const struct of_device_id fastrpc_match_table[] = {
4041 { .compatible = "qcom,msm-fastrpc-adsp", },
4042 { .compatible = "qcom,msm-fastrpc-compute", },
4043 { .compatible = "qcom,msm-fastrpc-compute-cb", },
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304044 { .compatible = "qcom,msm-fastrpc-legacy-compute", },
4045 { .compatible = "qcom,msm-fastrpc-legacy-compute-cb", },
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004046 { .compatible = "qcom,msm-adsprpc-mem-region", },
4047 {}
4048};
4049
4050static int fastrpc_cb_probe(struct device *dev)
4051{
4052 struct fastrpc_channel_ctx *chan;
4053 struct fastrpc_session_ctx *sess;
4054 struct of_phandle_args iommuspec;
4055 const char *name;
4056 unsigned int start = 0x80000000;
4057 int err = 0, i;
4058 int secure_vmid = VMID_CP_PIXEL;
4059
c_mtharue1a5ce12017-10-13 20:47:09 +05304060 VERIFY(err, NULL != (name = of_get_property(dev->of_node,
4061 "label", NULL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004062 if (err)
4063 goto bail;
4064 for (i = 0; i < NUM_CHANNELS; i++) {
4065 if (!gcinfo[i].name)
4066 continue;
4067 if (!strcmp(name, gcinfo[i].name))
4068 break;
4069 }
4070 VERIFY(err, i < NUM_CHANNELS);
4071 if (err)
4072 goto bail;
4073 chan = &gcinfo[i];
4074 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4075 if (err)
4076 goto bail;
4077
4078 VERIFY(err, !of_parse_phandle_with_args(dev->of_node, "iommus",
4079 "#iommu-cells", 0, &iommuspec));
4080 if (err)
4081 goto bail;
4082 sess = &chan->session[chan->sesscount];
4083 sess->smmu.cb = iommuspec.args[0] & 0xf;
4084 sess->used = 0;
4085 sess->smmu.coherent = of_property_read_bool(dev->of_node,
4086 "dma-coherent");
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304087 sess->smmu.sharedcb = of_property_read_bool(dev->of_node,
4088 "shared-cb");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004089 sess->smmu.secure = of_property_read_bool(dev->of_node,
4090 "qcom,secure-context-bank");
4091 if (sess->smmu.secure)
4092 start = 0x60000000;
4093 VERIFY(err, !IS_ERR_OR_NULL(sess->smmu.mapping =
4094 arm_iommu_create_mapping(&platform_bus_type,
Tharun Kumar Meruguca183f92017-04-27 17:43:27 +05304095 start, 0x78000000)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004096 if (err)
4097 goto bail;
4098
4099 if (sess->smmu.secure)
4100 iommu_domain_set_attr(sess->smmu.mapping->domain,
4101 DOMAIN_ATTR_SECURE_VMID,
4102 &secure_vmid);
4103
4104 VERIFY(err, !arm_iommu_attach_device(dev, sess->smmu.mapping));
4105 if (err)
4106 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05304107 sess->smmu.dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004108 sess->smmu.enabled = 1;
4109 chan->sesscount++;
Sathish Ambley1ca68232017-01-19 10:32:55 -08004110 debugfs_global_file = debugfs_create_file("global", 0644, debugfs_root,
4111 NULL, &debugfs_fops);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004112bail:
4113 return err;
4114}
4115
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304116static int fastrpc_cb_legacy_probe(struct device *dev)
4117{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304118 struct fastrpc_channel_ctx *chan;
4119 struct fastrpc_session_ctx *first_sess = NULL, *sess = NULL;
4120 const char *name;
4121 unsigned int *sids = NULL, sids_size = 0;
4122 int err = 0, ret = 0, i;
4123
4124 unsigned int start = 0x80000000;
4125
4126 VERIFY(err, NULL != (name = of_get_property(dev->of_node,
4127 "label", NULL)));
4128 if (err)
4129 goto bail;
4130
4131 for (i = 0; i < NUM_CHANNELS; i++) {
4132 if (!gcinfo[i].name)
4133 continue;
4134 if (!strcmp(name, gcinfo[i].name))
4135 break;
4136 }
4137 VERIFY(err, i < NUM_CHANNELS);
4138 if (err)
4139 goto bail;
4140
4141 chan = &gcinfo[i];
4142 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4143 if (err)
4144 goto bail;
4145
4146 first_sess = &chan->session[chan->sesscount];
4147
4148 VERIFY(err, NULL != of_get_property(dev->of_node,
4149 "sids", &sids_size));
4150 if (err)
4151 goto bail;
4152
4153 VERIFY(err, NULL != (sids = kzalloc(sids_size, GFP_KERNEL)));
4154 if (err)
4155 goto bail;
4156 ret = of_property_read_u32_array(dev->of_node, "sids", sids,
4157 sids_size/sizeof(unsigned int));
4158 if (ret)
4159 goto bail;
4160
4161 VERIFY(err, !IS_ERR_OR_NULL(first_sess->smmu.mapping =
4162 arm_iommu_create_mapping(&platform_bus_type,
4163 start, 0x78000000)));
4164 if (err)
4165 goto bail;
4166
4167 VERIFY(err, !arm_iommu_attach_device(dev, first_sess->smmu.mapping));
4168 if (err)
4169 goto bail;
4170
4171
4172 for (i = 0; i < sids_size/sizeof(unsigned int); i++) {
4173 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4174 if (err)
4175 goto bail;
4176 sess = &chan->session[chan->sesscount];
4177 sess->smmu.cb = sids[i];
4178 sess->smmu.dev = dev;
4179 sess->smmu.mapping = first_sess->smmu.mapping;
4180 sess->smmu.enabled = 1;
4181 sess->used = 0;
4182 sess->smmu.coherent = false;
4183 sess->smmu.secure = false;
4184 chan->sesscount++;
4185 }
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304186bail:
4187 kfree(sids);
4188 return err;
4189}
4190
4191
4192
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304193static void init_secure_vmid_list(struct device *dev, char *prop_name,
4194 struct secure_vm *destvm)
4195{
4196 int err = 0;
4197 u32 len = 0, i = 0;
4198 u32 *rhvmlist = NULL;
4199 u32 *rhvmpermlist = NULL;
4200
4201 if (!of_find_property(dev->of_node, prop_name, &len))
4202 goto bail;
4203 if (len == 0)
4204 goto bail;
4205 len /= sizeof(u32);
4206 VERIFY(err, NULL != (rhvmlist = kcalloc(len, sizeof(u32), GFP_KERNEL)));
4207 if (err)
4208 goto bail;
4209 VERIFY(err, NULL != (rhvmpermlist = kcalloc(len, sizeof(u32),
4210 GFP_KERNEL)));
4211 if (err)
4212 goto bail;
4213 for (i = 0; i < len; i++) {
4214 err = of_property_read_u32_index(dev->of_node, prop_name, i,
4215 &rhvmlist[i]);
4216 rhvmpermlist[i] = PERM_READ | PERM_WRITE | PERM_EXEC;
4217 pr_info("ADSPRPC: Secure VMID = %d", rhvmlist[i]);
4218 if (err) {
4219 pr_err("ADSPRPC: Failed to read VMID\n");
4220 goto bail;
4221 }
4222 }
4223 destvm->vmid = rhvmlist;
4224 destvm->vmperm = rhvmpermlist;
4225 destvm->vmcount = len;
4226bail:
4227 if (err) {
4228 kfree(rhvmlist);
4229 kfree(rhvmpermlist);
4230 }
4231}
4232
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304233static void configure_secure_channels(uint32_t secure_domains)
4234{
4235 struct fastrpc_apps *me = &gfa;
4236 int ii = 0;
4237 /*
4238 * secure_domains contains the bitmask of the secure channels
4239 * Bit 0 - ADSP
4240 * Bit 1 - MDSP
4241 * Bit 2 - SLPI
4242 * Bit 3 - CDSP
4243 */
4244 for (ii = ADSP_DOMAIN_ID; ii <= CDSP_DOMAIN_ID; ++ii) {
4245 int secure = (secure_domains >> ii) & 0x01;
4246
4247 me->channel[ii].secure = secure;
4248 }
4249}
4250
4251
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004252static int fastrpc_probe(struct platform_device *pdev)
4253{
4254 int err = 0;
4255 struct fastrpc_apps *me = &gfa;
4256 struct device *dev = &pdev->dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004257 struct device_node *ion_node, *node;
4258 struct platform_device *ion_pdev;
4259 struct cma *cma;
4260 uint32_t val;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304261 int ret = 0;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304262 uint32_t secure_domains;
c_mtharu63ffc012017-11-16 15:26:56 +05304263
4264 if (of_device_is_compatible(dev->of_node,
4265 "qcom,msm-fastrpc-compute")) {
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304266 init_secure_vmid_list(dev, "qcom,adsp-remoteheap-vmid",
4267 &gcinfo[0].rhvm);
c_mtharu63ffc012017-11-16 15:26:56 +05304268
c_mtharu63ffc012017-11-16 15:26:56 +05304269
4270 of_property_read_u32(dev->of_node, "qcom,rpc-latency-us",
4271 &me->latency);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304272 if (of_get_property(dev->of_node,
4273 "qcom,secure-domains", NULL) != NULL) {
4274 VERIFY(err, !of_property_read_u32(dev->of_node,
4275 "qcom,secure-domains",
4276 &secure_domains));
zhaochenfc798572018-08-17 15:32:37 +08004277 if (!err) {
4278 me->secure_flag = true;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304279 configure_secure_channels(secure_domains);
zhaochenfc798572018-08-17 15:32:37 +08004280 } else {
4281 me->secure_flag = false;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304282 pr_info("adsprpc: unable to read the domain configuration from dts\n");
zhaochenfc798572018-08-17 15:32:37 +08004283 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304284 }
c_mtharu63ffc012017-11-16 15:26:56 +05304285 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004286 if (of_device_is_compatible(dev->of_node,
4287 "qcom,msm-fastrpc-compute-cb"))
4288 return fastrpc_cb_probe(dev);
4289
4290 if (of_device_is_compatible(dev->of_node,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304291 "qcom,msm-fastrpc-legacy-compute")) {
4292 me->glink = false;
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304293 me->legacy = 1;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304294 }
4295
4296 if (of_device_is_compatible(dev->of_node,
4297 "qcom,msm-fastrpc-legacy-compute-cb")){
4298 return fastrpc_cb_legacy_probe(dev);
4299 }
4300
4301 if (of_device_is_compatible(dev->of_node,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004302 "qcom,msm-adsprpc-mem-region")) {
4303 me->dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004304 ion_node = of_find_compatible_node(NULL, NULL, "qcom,msm-ion");
4305 if (ion_node) {
4306 for_each_available_child_of_node(ion_node, node) {
4307 if (of_property_read_u32(node, "reg", &val))
4308 continue;
4309 if (val != ION_ADSP_HEAP_ID)
4310 continue;
4311 ion_pdev = of_find_device_by_node(node);
4312 if (!ion_pdev)
4313 break;
4314 cma = dev_get_cma_area(&ion_pdev->dev);
4315 if (cma) {
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304316 me->range.addr = cma_get_base(cma);
4317 me->range.size =
4318 (size_t)cma_get_size(cma);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004319 }
4320 break;
4321 }
4322 }
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304323 if (me->range.addr && !of_property_read_bool(dev->of_node,
Tharun Kumar Merugu6b7a4a22018-01-17 16:08:07 +05304324 "restrict-access")) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004325 int srcVM[1] = {VMID_HLOS};
4326 int destVM[4] = {VMID_HLOS, VMID_MSS_MSA, VMID_SSC_Q6,
4327 VMID_ADSP_Q6};
Sathish Ambley84d11862017-05-15 14:36:05 -07004328 int destVMperm[4] = {PERM_READ | PERM_WRITE | PERM_EXEC,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004329 PERM_READ | PERM_WRITE | PERM_EXEC,
4330 PERM_READ | PERM_WRITE | PERM_EXEC,
4331 PERM_READ | PERM_WRITE | PERM_EXEC,
4332 };
4333
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304334 VERIFY(err, !hyp_assign_phys(me->range.addr,
4335 me->range.size, srcVM, 1,
4336 destVM, destVMperm, 4));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004337 if (err)
4338 goto bail;
4339 }
4340 return 0;
4341 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304342 if (of_property_read_bool(dev->of_node,
4343 "qcom,fastrpc-adsp-audio-pdr")) {
4344 int session;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004345
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304346 VERIFY(err, !fastrpc_get_adsp_session(
4347 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
4348 if (err)
4349 goto spdbail;
4350 me->channel[0].spd[session].get_service_nb.notifier_call =
4351 fastrpc_get_service_location_notify;
4352 ret = get_service_location(
4353 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
4354 AUDIO_PDR_ADSP_SERVICE_NAME,
4355 &me->channel[0].spd[session].get_service_nb);
4356 if (ret)
4357 pr_err("ADSPRPC: Get service location failed: %d\n",
4358 ret);
4359 }
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304360 if (of_property_read_bool(dev->of_node,
4361 "qcom,fastrpc-adsp-sensors-pdr")) {
4362 int session;
4363
4364 VERIFY(err, !fastrpc_get_adsp_session(
4365 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
4366 if (err)
4367 goto spdbail;
4368 me->channel[0].spd[session].get_service_nb.notifier_call =
4369 fastrpc_get_service_location_notify;
4370 ret = get_service_location(
4371 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME,
4372 SENSORS_PDR_ADSP_SERVICE_NAME,
4373 &me->channel[0].spd[session].get_service_nb);
4374 if (ret)
4375 pr_err("ADSPRPC: Get service location failed: %d\n",
4376 ret);
4377 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304378spdbail:
4379 err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004380 VERIFY(err, !of_platform_populate(pdev->dev.of_node,
4381 fastrpc_match_table,
4382 NULL, &pdev->dev));
4383 if (err)
4384 goto bail;
4385bail:
4386 return err;
4387}
4388
4389static void fastrpc_deinit(void)
4390{
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304391 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004392 struct fastrpc_channel_ctx *chan = gcinfo;
4393 int i, j;
4394
4395 for (i = 0; i < NUM_CHANNELS; i++, chan++) {
4396 if (chan->chan) {
4397 kref_put_mutex(&chan->kref,
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304398 fastrpc_channel_close, &me->smd_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05304399 chan->chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004400 }
4401 for (j = 0; j < NUM_SESSIONS; j++) {
4402 struct fastrpc_session_ctx *sess = &chan->session[j];
c_mtharue1a5ce12017-10-13 20:47:09 +05304403 if (sess->smmu.dev) {
4404 arm_iommu_detach_device(sess->smmu.dev);
4405 sess->smmu.dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004406 }
4407 if (sess->smmu.mapping) {
4408 arm_iommu_release_mapping(sess->smmu.mapping);
c_mtharue1a5ce12017-10-13 20:47:09 +05304409 sess->smmu.mapping = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004410 }
4411 }
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304412 kfree(chan->rhvm.vmid);
4413 kfree(chan->rhvm.vmperm);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004414 }
4415}
4416
4417static struct platform_driver fastrpc_driver = {
4418 .probe = fastrpc_probe,
4419 .driver = {
4420 .name = "fastrpc",
4421 .owner = THIS_MODULE,
4422 .of_match_table = fastrpc_match_table,
4423 },
4424};
4425
4426static int __init fastrpc_device_init(void)
4427{
4428 struct fastrpc_apps *me = &gfa;
c_mtharue1a5ce12017-10-13 20:47:09 +05304429 struct device *dev = NULL;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304430 struct device *secure_dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004431 int err = 0, i;
4432
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05304433 debugfs_root = debugfs_create_dir("adsprpc", NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004434 memset(me, 0, sizeof(*me));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004435 fastrpc_init(me);
4436 me->dev = NULL;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304437 me->glink = true;
zhaochenfc798572018-08-17 15:32:37 +08004438 me->secure_flag = false;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004439 VERIFY(err, 0 == platform_driver_register(&fastrpc_driver));
4440 if (err)
4441 goto register_bail;
4442 VERIFY(err, 0 == alloc_chrdev_region(&me->dev_no, 0, NUM_CHANNELS,
4443 DEVICE_NAME));
4444 if (err)
4445 goto alloc_chrdev_bail;
4446 cdev_init(&me->cdev, &fops);
4447 me->cdev.owner = THIS_MODULE;
4448 VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0),
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304449 NUM_DEVICES));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004450 if (err)
4451 goto cdev_init_bail;
4452 me->class = class_create(THIS_MODULE, "fastrpc");
4453 VERIFY(err, !IS_ERR(me->class));
4454 if (err)
4455 goto class_create_bail;
4456 me->compat = (fops.compat_ioctl == NULL) ? 0 : 1;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304457
4458 /*
4459 * Create devices and register with sysfs
4460 * Create first device with minor number 0
4461 */
Sathish Ambley36849af2017-02-02 09:35:55 -08004462 dev = device_create(me->class, NULL,
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304463 MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV),
4464 NULL, DEVICE_NAME);
Sathish Ambley36849af2017-02-02 09:35:55 -08004465 VERIFY(err, !IS_ERR_OR_NULL(dev));
4466 if (err)
4467 goto device_create_bail;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304468
4469 /* Create secure device with minor number for secure device */
4470 secure_dev = device_create(me->class, NULL,
4471 MKDEV(MAJOR(me->dev_no), MINOR_NUM_SECURE_DEV),
4472 NULL, DEVICE_NAME_SECURE);
4473 VERIFY(err, !IS_ERR_OR_NULL(secure_dev));
4474 if (err)
4475 goto device_create_bail;
4476
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004477 for (i = 0; i < NUM_CHANNELS; i++) {
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304478 me->channel[i].dev = secure_dev;
4479 if (i == CDSP_DOMAIN_ID)
4480 me->channel[i].dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004481 me->channel[i].ssrcount = 0;
4482 me->channel[i].prevssrcount = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05304483 me->channel[i].issubsystemup = 1;
4484 me->channel[i].ramdumpenabled = 0;
4485 me->channel[i].remoteheap_ramdump_dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004486 me->channel[i].nb.notifier_call = fastrpc_restart_notifier_cb;
4487 me->channel[i].handle = subsys_notif_register_notifier(
4488 gcinfo[i].subsys,
4489 &me->channel[i].nb);
4490 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004491 me->client = msm_ion_client_create(DEVICE_NAME);
4492 VERIFY(err, !IS_ERR_OR_NULL(me->client));
4493 if (err)
4494 goto device_create_bail;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05304495
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004496 return 0;
4497device_create_bail:
4498 for (i = 0; i < NUM_CHANNELS; i++) {
Sathish Ambley36849af2017-02-02 09:35:55 -08004499 if (me->channel[i].handle)
4500 subsys_notif_unregister_notifier(me->channel[i].handle,
4501 &me->channel[i].nb);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004502 }
Sathish Ambley36849af2017-02-02 09:35:55 -08004503 if (!IS_ERR_OR_NULL(dev))
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304504 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4505 MINOR_NUM_DEV));
4506 if (!IS_ERR_OR_NULL(secure_dev))
4507 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4508 MINOR_NUM_SECURE_DEV));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004509 class_destroy(me->class);
4510class_create_bail:
4511 cdev_del(&me->cdev);
4512cdev_init_bail:
4513 unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
4514alloc_chrdev_bail:
4515register_bail:
4516 fastrpc_deinit();
4517 return err;
4518}
4519
4520static void __exit fastrpc_device_exit(void)
4521{
4522 struct fastrpc_apps *me = &gfa;
4523 int i;
4524
4525 fastrpc_file_list_dtor(me);
4526 fastrpc_deinit();
4527 for (i = 0; i < NUM_CHANNELS; i++) {
4528 if (!gcinfo[i].name)
4529 continue;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004530 subsys_notif_unregister_notifier(me->channel[i].handle,
4531 &me->channel[i].nb);
4532 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304533
4534 /* Destroy the secure and non secure devices */
4535 device_destroy(me->class, MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV));
4536 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4537 MINOR_NUM_SECURE_DEV));
4538
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004539 class_destroy(me->class);
4540 cdev_del(&me->cdev);
4541 unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
4542 ion_client_destroy(me->client);
Sathish Ambley1ca68232017-01-19 10:32:55 -08004543 debugfs_remove_recursive(debugfs_root);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004544}
4545
4546late_initcall(fastrpc_device_init);
4547module_exit(fastrpc_device_exit);
4548
4549MODULE_LICENSE("GPL v2");