blob: b3d3cd6ca413b193a6f9732f2ef4e1041cbb9922 [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;
354};
355
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530356enum fastrpc_perfkeys {
357 PERF_COUNT = 0,
358 PERF_FLUSH = 1,
359 PERF_MAP = 2,
360 PERF_COPY = 3,
361 PERF_LINK = 4,
362 PERF_GETARGS = 5,
363 PERF_PUTARGS = 6,
364 PERF_INVARGS = 7,
365 PERF_INVOKE = 8,
366 PERF_KEY_MAX = 9,
367};
368
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800369struct fastrpc_perf {
370 int64_t count;
371 int64_t flush;
372 int64_t map;
373 int64_t copy;
374 int64_t link;
375 int64_t getargs;
376 int64_t putargs;
377 int64_t invargs;
378 int64_t invoke;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530379 int64_t tid;
380 struct hlist_node hn;
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800381};
382
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700383struct fastrpc_file {
384 struct hlist_node hn;
385 spinlock_t hlock;
386 struct hlist_head maps;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530387 struct hlist_head cached_bufs;
388 struct hlist_head remote_bufs;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700389 struct fastrpc_ctx_lst clst;
390 struct fastrpc_session_ctx *sctx;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530391 struct fastrpc_buf *init_mem;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700392 struct fastrpc_session_ctx *secsctx;
393 uint32_t mode;
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800394 uint32_t profile;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +0530395 int sessionid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700396 int tgid;
397 int cid;
398 int ssrcount;
399 int pd;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530400 char *spdname;
tharun kumar9f899ea2017-07-03 17:07:03 +0530401 int file_close;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530402 int sharedcb;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700403 struct fastrpc_apps *apps;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530404 struct hlist_head perf;
Sathish Ambley1ca68232017-01-19 10:32:55 -0800405 struct dentry *debugfs_file;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530406 struct mutex perf_mutex;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +0530407 struct pm_qos_request pm_qos_req;
408 int qos_request;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +0530409 struct mutex map_mutex;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +0530410 struct mutex fl_map_mutex;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +0530411 int refcount;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +0530412 /* Identifies the device (MINOR_NUM_DEV / MINOR_NUM_SECURE_DEV) */
413 int dev_minor;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +0530414 char *debug_buf;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700415};
416
417static struct fastrpc_apps gfa;
418
419static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = {
420 {
421 .name = "adsprpc-smd",
422 .subsys = "adsp",
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530423 .channel = SMD_APPS_QDSP,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700424 .link.link_info.edge = "lpass",
425 .link.link_info.transport = "smem",
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530426 .spd = {
427 {
428 .spdname =
429 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
430 .pdrnb.notifier_call =
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +0530431 fastrpc_pdr_notifier_cb,
432 },
433 {
434 .spdname =
435 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME,
436 .pdrnb.notifier_call =
437 fastrpc_pdr_notifier_cb,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +0530438 }
439 },
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700440 },
441 {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700442 .name = "mdsprpc-smd",
443 .subsys = "modem",
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530444 .channel = SMD_APPS_MODEM,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700445 .link.link_info.edge = "mpss",
446 .link.link_info.transport = "smem",
447 },
448 {
Sathish Ambley36849af2017-02-02 09:35:55 -0800449 .name = "sdsprpc-smd",
450 .subsys = "slpi",
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +0530451 .channel = SMD_APPS_DSPS,
Sathish Ambley36849af2017-02-02 09:35:55 -0800452 .link.link_info.edge = "dsps",
453 .link.link_info.transport = "smem",
Sathish Ambley36849af2017-02-02 09:35:55 -0800454 },
455 {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700456 .name = "cdsprpc-smd",
457 .subsys = "cdsp",
458 .link.link_info.edge = "cdsp",
459 .link.link_info.transport = "smem",
460 },
461};
462
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +0530463static int hlosvm[1] = {VMID_HLOS};
464static int hlosvmperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
465
Sathish Ambleya21b5b52017-01-11 16:11:01 -0800466static inline int64_t getnstimediff(struct timespec *start)
467{
468 int64_t ns;
469 struct timespec ts, b;
470
471 getnstimeofday(&ts);
472 b = timespec_sub(ts, *start);
473 ns = timespec_to_ns(&b);
474 return ns;
475}
476
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +0530477static inline int64_t *getperfcounter(struct fastrpc_file *fl, int key)
478{
479 int err = 0;
480 int64_t *val = NULL;
481 struct fastrpc_perf *perf = NULL, *fperf = NULL;
482 struct hlist_node *n = NULL;
483
484 VERIFY(err, !IS_ERR_OR_NULL(fl));
485 if (err)
486 goto bail;
487
488 mutex_lock(&fl->perf_mutex);
489 hlist_for_each_entry_safe(perf, n, &fl->perf, hn) {
490 if (perf->tid == current->pid) {
491 fperf = perf;
492 break;
493 }
494 }
495
496 if (IS_ERR_OR_NULL(fperf)) {
497 fperf = kzalloc(sizeof(*fperf), GFP_KERNEL);
498
499 VERIFY(err, !IS_ERR_OR_NULL(fperf));
500 if (err) {
501 mutex_unlock(&fl->perf_mutex);
502 kfree(fperf);
503 goto bail;
504 }
505
506 fperf->tid = current->pid;
507 hlist_add_head(&fperf->hn, &fl->perf);
508 }
509
510 val = ((int64_t *)fperf) + key;
511 mutex_unlock(&fl->perf_mutex);
512bail:
513 return val;
514}
515
516
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700517static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
518{
c_mtharue1a5ce12017-10-13 20:47:09 +0530519 struct fastrpc_file *fl = buf == NULL ? NULL : buf->fl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700520 int vmid;
521
522 if (!fl)
523 return;
524 if (cache) {
525 spin_lock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530526 hlist_add_head(&buf->hn, &fl->cached_bufs);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700527 spin_unlock(&fl->hlock);
528 return;
529 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530530 if (buf->remote) {
531 spin_lock(&fl->hlock);
532 hlist_del_init(&buf->hn_rem);
533 spin_unlock(&fl->hlock);
534 buf->remote = 0;
535 buf->raddr = 0;
536 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700537 if (!IS_ERR_OR_NULL(buf->virt)) {
538 int destVM[1] = {VMID_HLOS};
539 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
540
541 if (fl->sctx->smmu.cb)
542 buf->phys &= ~((uint64_t)fl->sctx->smmu.cb << 32);
543 vmid = fl->apps->channel[fl->cid].vmid;
544 if (vmid) {
545 int srcVM[2] = {VMID_HLOS, vmid};
546
547 hyp_assign_phys(buf->phys, buf_page_size(buf->size),
548 srcVM, 2, destVM, destVMperm, 1);
549 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530550 dma_free_attrs(fl->sctx->smmu.dev, buf->size, buf->virt,
551 buf->phys, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700552 }
553 kfree(buf);
554}
555
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530556static void fastrpc_cached_buf_list_free(struct fastrpc_file *fl)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700557{
558 struct fastrpc_buf *buf, *free;
559
560 do {
561 struct hlist_node *n;
562
c_mtharue1a5ce12017-10-13 20:47:09 +0530563 free = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700564 spin_lock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530565 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700566 hlist_del_init(&buf->hn);
567 free = buf;
568 break;
569 }
570 spin_unlock(&fl->hlock);
571 if (free)
572 fastrpc_buf_free(free, 0);
573 } while (free);
574}
575
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530576static void fastrpc_remote_buf_list_free(struct fastrpc_file *fl)
577{
578 struct fastrpc_buf *buf, *free;
579
580 do {
581 struct hlist_node *n;
582
583 free = NULL;
584 spin_lock(&fl->hlock);
585 hlist_for_each_entry_safe(buf, n, &fl->remote_bufs, hn_rem) {
586 free = buf;
587 break;
588 }
589 spin_unlock(&fl->hlock);
590 if (free)
591 fastrpc_buf_free(free, 0);
592 } while (free);
593}
594
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700595static void fastrpc_mmap_add(struct fastrpc_mmap *map)
596{
c_mtharue1a5ce12017-10-13 20:47:09 +0530597 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
598 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
599 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700600
c_mtharue1a5ce12017-10-13 20:47:09 +0530601 spin_lock(&me->hlock);
602 hlist_add_head(&map->hn, &me->maps);
603 spin_unlock(&me->hlock);
604 } else {
605 struct fastrpc_file *fl = map->fl;
606
c_mtharue1a5ce12017-10-13 20:47:09 +0530607 hlist_add_head(&map->hn, &fl->maps);
c_mtharue1a5ce12017-10-13 20:47:09 +0530608 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700609}
610
c_mtharue1a5ce12017-10-13 20:47:09 +0530611static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530612 uintptr_t va, size_t len, int mflags, int refs,
c_mtharue1a5ce12017-10-13 20:47:09 +0530613 struct fastrpc_mmap **ppmap)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700614{
c_mtharue1a5ce12017-10-13 20:47:09 +0530615 struct fastrpc_apps *me = &gfa;
616 struct fastrpc_mmap *match = NULL, *map = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700617 struct hlist_node *n;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530618
619 if ((va + len) < va)
620 return -EOVERFLOW;
c_mtharue1a5ce12017-10-13 20:47:09 +0530621 if (mflags == ADSP_MMAP_HEAP_ADDR ||
622 mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
623 spin_lock(&me->hlock);
624 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
625 if (va >= map->va &&
626 va + len <= map->va + map->len &&
627 map->fd == fd) {
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530628 if (refs) {
629 if (map->refs + 1 == INT_MAX) {
630 spin_unlock(&me->hlock);
631 return -ETOOMANYREFS;
632 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530633 map->refs++;
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530634 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530635 match = map;
636 break;
637 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700638 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530639 spin_unlock(&me->hlock);
640 } else {
c_mtharue1a5ce12017-10-13 20:47:09 +0530641 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
642 if (va >= map->va &&
643 va + len <= map->va + map->len &&
644 map->fd == fd) {
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530645 if (refs) {
646 if (map->refs + 1 == INT_MAX)
647 return -ETOOMANYREFS;
c_mtharue1a5ce12017-10-13 20:47:09 +0530648 map->refs++;
Tharun Kumar Merugu496ad342019-06-06 15:01:42 +0530649 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530650 match = map;
651 break;
652 }
653 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700654 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700655 if (match) {
656 *ppmap = match;
657 return 0;
658 }
659 return -ENOTTY;
660}
661
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530662static int dma_alloc_memory(dma_addr_t *region_phys, void **vaddr, size_t size,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530663 unsigned long dma_attrs)
c_mtharue1a5ce12017-10-13 20:47:09 +0530664{
665 struct fastrpc_apps *me = &gfa;
c_mtharue1a5ce12017-10-13 20:47:09 +0530666
667 if (me->dev == NULL) {
668 pr_err("device adsprpc-mem is not initialized\n");
669 return -ENODEV;
670 }
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530671 *vaddr = dma_alloc_attrs(me->dev, size, region_phys, GFP_KERNEL,
Tharun Kumar Merugu48d5ff32018-04-16 19:24:16 +0530672 dma_attrs);
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530673 if (IS_ERR_OR_NULL(*vaddr)) {
674 pr_err("adsprpc: %s: %s: dma_alloc_attrs failed for size 0x%zx, returned %pK\n",
675 current->comm, __func__, size, (*vaddr));
c_mtharue1a5ce12017-10-13 20:47:09 +0530676 return -ENOMEM;
677 }
678 return 0;
679}
680
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700681static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530682 size_t len, struct fastrpc_mmap **ppmap)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700683{
c_mtharue1a5ce12017-10-13 20:47:09 +0530684 struct fastrpc_mmap *match = NULL, *map;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700685 struct hlist_node *n;
686 struct fastrpc_apps *me = &gfa;
687
688 spin_lock(&me->hlock);
689 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
690 if (map->raddr == va &&
691 map->raddr + map->len == va + len &&
692 map->refs == 1) {
693 match = map;
694 hlist_del_init(&map->hn);
695 break;
696 }
697 }
698 spin_unlock(&me->hlock);
699 if (match) {
700 *ppmap = match;
701 return 0;
702 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700703 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
704 if (map->raddr == va &&
705 map->raddr + map->len == va + len &&
706 map->refs == 1) {
707 match = map;
708 hlist_del_init(&map->hn);
709 break;
710 }
711 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700712 if (match) {
713 *ppmap = match;
714 return 0;
715 }
716 return -ENOTTY;
717}
718
c_mtharu7bd6a422017-10-17 18:15:37 +0530719static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700720{
c_mtharue1a5ce12017-10-13 20:47:09 +0530721 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700722 struct fastrpc_file *fl;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530723 int vmid, cid = -1, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700724 struct fastrpc_session_ctx *sess;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700725
726 if (!map)
727 return;
728 fl = map->fl;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530729 cid = fl->cid;
730 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
731 if (err) {
732 err = -ECHRNG;
733 pr_err("adsprpc: ERROR:%s, Invalid channel id: %d, err:%d",
734 __func__, cid, err);
735 return;
736 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530737 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
738 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
739 spin_lock(&me->hlock);
740 map->refs--;
741 if (!map->refs)
742 hlist_del_init(&map->hn);
743 spin_unlock(&me->hlock);
c_mtharu7bd6a422017-10-17 18:15:37 +0530744 if (map->refs > 0)
745 return;
c_mtharue1a5ce12017-10-13 20:47:09 +0530746 } else {
c_mtharue1a5ce12017-10-13 20:47:09 +0530747 map->refs--;
748 if (!map->refs)
749 hlist_del_init(&map->hn);
c_mtharu7bd6a422017-10-17 18:15:37 +0530750 if (map->refs > 0 && !flags)
751 return;
c_mtharue1a5ce12017-10-13 20:47:09 +0530752 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530753 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
754 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700755
c_mtharue1a5ce12017-10-13 20:47:09 +0530756 if (me->dev == NULL) {
757 pr_err("failed to free remote heap allocation\n");
758 return;
759 }
760 if (map->phys) {
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +0530761 unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING |
762 DMA_ATTR_NO_KERNEL_MAPPING;
Tharun Kumar Merugu48d5ff32018-04-16 19:24:16 +0530763 dma_free_attrs(me->dev, map->size, (void *)map->va,
764 (dma_addr_t)map->phys, dma_attrs);
c_mtharue1a5ce12017-10-13 20:47:09 +0530765 }
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +0530766 } else if (map->flags == FASTRPC_DMAHANDLE_NOMAP) {
767 if (!IS_ERR_OR_NULL(map->handle))
768 ion_free(fl->apps->client, map->handle);
c_mtharue1a5ce12017-10-13 20:47:09 +0530769 } else {
770 int destVM[1] = {VMID_HLOS};
771 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
772
773 if (map->secure)
774 sess = fl->secsctx;
775 else
776 sess = fl->sctx;
777
778 if (!IS_ERR_OR_NULL(map->handle))
779 ion_free(fl->apps->client, map->handle);
780 if (sess && sess->smmu.enabled) {
781 if (map->size || map->phys)
782 msm_dma_unmap_sg(sess->smmu.dev,
783 map->table->sgl,
784 map->table->nents, DMA_BIDIRECTIONAL,
785 map->buf);
786 }
787 vmid = fl->apps->channel[fl->cid].vmid;
788 if (vmid && map->phys) {
789 int srcVM[2] = {VMID_HLOS, vmid};
790
791 hyp_assign_phys(map->phys, buf_page_size(map->size),
792 srcVM, 2, destVM, destVMperm, 1);
793 }
794
795 if (!IS_ERR_OR_NULL(map->table))
796 dma_buf_unmap_attachment(map->attach, map->table,
797 DMA_BIDIRECTIONAL);
798 if (!IS_ERR_OR_NULL(map->attach))
799 dma_buf_detach(map->buf, map->attach);
800 if (!IS_ERR_OR_NULL(map->buf))
801 dma_buf_put(map->buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700802 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700803 kfree(map);
804}
805
806static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
807 struct fastrpc_session_ctx **session);
808
809static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530810 unsigned int attr, uintptr_t va, size_t len, int mflags,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700811 struct fastrpc_mmap **ppmap)
812{
c_mtharue1a5ce12017-10-13 20:47:09 +0530813 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700814 struct fastrpc_session_ctx *sess;
815 struct fastrpc_apps *apps = fl->apps;
c_mtharue1a5ce12017-10-13 20:47:09 +0530816 struct fastrpc_mmap *map = NULL;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530817 struct fastrpc_channel_ctx *chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700818 unsigned long attrs;
c_mtharuf931ff92017-11-30 19:35:30 +0530819 dma_addr_t region_phys = 0;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530820 void *region_vaddr = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700821 unsigned long flags;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530822 int err = 0, vmid, cid = -1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700823
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530824 cid = fl->cid;
825 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
826 if (err) {
827 err = -ECHRNG;
828 goto bail;
829 }
830 chan = &apps->channel[cid];
Sathish Ambleyae5ee542017-01-16 22:24:23 -0800831 if (!fastrpc_mmap_find(fl, fd, va, len, mflags, 1, ppmap))
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700832 return 0;
833 map = kzalloc(sizeof(*map), GFP_KERNEL);
834 VERIFY(err, !IS_ERR_OR_NULL(map));
835 if (err)
836 goto bail;
837 INIT_HLIST_NODE(&map->hn);
838 map->flags = mflags;
839 map->refs = 1;
840 map->fl = fl;
841 map->fd = fd;
842 map->attr = attr;
c_mtharue1a5ce12017-10-13 20:47:09 +0530843 if (mflags == ADSP_MMAP_HEAP_ADDR ||
844 mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530845 unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING |
846 DMA_ATTR_NO_KERNEL_MAPPING;
847
c_mtharue1a5ce12017-10-13 20:47:09 +0530848 map->apps = me;
849 map->fl = NULL;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530850 VERIFY(err, !dma_alloc_memory(&region_phys, &region_vaddr,
851 len, dma_attrs));
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700852 if (err)
853 goto bail;
c_mtharuf931ff92017-11-30 19:35:30 +0530854 map->phys = (uintptr_t)region_phys;
c_mtharue1a5ce12017-10-13 20:47:09 +0530855 map->size = len;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530856 map->va = (uintptr_t)region_vaddr;
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +0530857 } else if (mflags == FASTRPC_DMAHANDLE_NOMAP) {
858 ion_phys_addr_t iphys;
859
860 VERIFY(err, !IS_ERR_OR_NULL(map->handle =
861 ion_import_dma_buf_fd(fl->apps->client, fd)));
862 if (err)
863 goto bail;
864
865 map->uncached = 1;
866 map->buf = NULL;
867 map->attach = NULL;
868 map->table = NULL;
869 map->va = 0;
870 map->phys = 0;
871
872 err = ion_phys(fl->apps->client, map->handle,
873 &iphys, &map->size);
874 if (err)
875 goto bail;
876 map->phys = (uint64_t)iphys;
c_mtharue1a5ce12017-10-13 20:47:09 +0530877 } else {
c_mtharu7bd6a422017-10-17 18:15:37 +0530878 if (map->attr && (map->attr & FASTRPC_ATTR_KEEP_MAP)) {
879 pr_info("adsprpc: buffer mapped with persist attr %x\n",
880 (unsigned int)map->attr);
881 map->refs = 2;
882 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530883 VERIFY(err, !IS_ERR_OR_NULL(map->handle =
884 ion_import_dma_buf_fd(fl->apps->client, fd)));
885 if (err)
886 goto bail;
887 VERIFY(err, !ion_handle_get_flags(fl->apps->client, map->handle,
888 &flags));
889 if (err)
890 goto bail;
891
c_mtharue1a5ce12017-10-13 20:47:09 +0530892 map->secure = flags & ION_FLAG_SECURE;
893 if (map->secure) {
894 if (!fl->secsctx)
895 err = fastrpc_session_alloc(chan, 1,
896 &fl->secsctx);
897 if (err)
898 goto bail;
899 }
900 if (map->secure)
901 sess = fl->secsctx;
902 else
903 sess = fl->sctx;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530904
c_mtharue1a5ce12017-10-13 20:47:09 +0530905 VERIFY(err, !IS_ERR_OR_NULL(sess));
906 if (err)
907 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530908
909 map->uncached = !ION_IS_CACHED(flags);
910 if (map->attr & FASTRPC_ATTR_NOVA && !sess->smmu.coherent)
911 map->uncached = 1;
912
c_mtharue1a5ce12017-10-13 20:47:09 +0530913 VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd)));
914 if (err)
915 goto bail;
916 VERIFY(err, !IS_ERR_OR_NULL(map->attach =
917 dma_buf_attach(map->buf, sess->smmu.dev)));
918 if (err)
919 goto bail;
920 VERIFY(err, !IS_ERR_OR_NULL(map->table =
921 dma_buf_map_attachment(map->attach,
922 DMA_BIDIRECTIONAL)));
923 if (err)
924 goto bail;
925 if (sess->smmu.enabled) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700926 attrs = DMA_ATTR_EXEC_MAPPING;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +0530927
928 if (map->attr & FASTRPC_ATTR_NON_COHERENT ||
929 (sess->smmu.coherent && map->uncached))
930 attrs |= DMA_ATTR_FORCE_NON_COHERENT;
931 else if (map->attr & FASTRPC_ATTR_COHERENT)
932 attrs |= DMA_ATTR_FORCE_COHERENT;
933
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700934 VERIFY(err, map->table->nents ==
c_mtharue1a5ce12017-10-13 20:47:09 +0530935 msm_dma_map_sg_attrs(sess->smmu.dev,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700936 map->table->sgl, map->table->nents,
937 DMA_BIDIRECTIONAL, map->buf, attrs));
c_mtharue1a5ce12017-10-13 20:47:09 +0530938 if (err)
939 goto bail;
940 } else {
941 VERIFY(err, map->table->nents == 1);
942 if (err)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700943 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +0530944 }
945 map->phys = sg_dma_address(map->table->sgl);
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530946
c_mtharue1a5ce12017-10-13 20:47:09 +0530947 if (sess->smmu.cb) {
948 map->phys += ((uint64_t)sess->smmu.cb << 32);
949 map->size = sg_dma_len(map->table->sgl);
950 } else {
951 map->size = buf_page_size(len);
952 }
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530953
c_mtharue1a5ce12017-10-13 20:47:09 +0530954 vmid = fl->apps->channel[fl->cid].vmid;
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530955 if (!sess->smmu.enabled && !vmid) {
956 VERIFY(err, map->phys >= me->range.addr &&
957 map->phys + map->size <=
958 me->range.addr + me->range.size);
959 if (err) {
960 pr_err("adsprpc: mmap fail out of range\n");
961 goto bail;
962 }
963 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530964 if (vmid) {
965 int srcVM[1] = {VMID_HLOS};
966 int destVM[2] = {VMID_HLOS, vmid};
967 int destVMperm[2] = {PERM_READ | PERM_WRITE,
968 PERM_READ | PERM_WRITE | PERM_EXEC};
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700969
c_mtharue1a5ce12017-10-13 20:47:09 +0530970 VERIFY(err, !hyp_assign_phys(map->phys,
971 buf_page_size(map->size),
972 srcVM, 1, destVM, destVMperm, 2));
973 if (err)
974 goto bail;
975 }
976 map->va = va;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700977 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700978 map->len = len;
979
980 fastrpc_mmap_add(map);
981 *ppmap = map;
982
983bail:
984 if (err && map)
c_mtharu7bd6a422017-10-17 18:15:37 +0530985 fastrpc_mmap_free(map, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700986 return err;
987}
988
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530989static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530990 unsigned long dma_attr, uint32_t rflags,
991 int remote, struct fastrpc_buf **obuf)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700992{
993 int err = 0, vmid;
c_mtharue1a5ce12017-10-13 20:47:09 +0530994 struct fastrpc_buf *buf = NULL, *fr = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700995 struct hlist_node *n;
996
997 VERIFY(err, size > 0);
998 if (err)
999 goto bail;
1000
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301001 if (!remote) {
1002 /* find the smallest buffer that fits in the cache */
1003 spin_lock(&fl->hlock);
1004 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
1005 if (buf->size >= size && (!fr || fr->size > buf->size))
1006 fr = buf;
1007 }
1008 if (fr)
1009 hlist_del_init(&fr->hn);
1010 spin_unlock(&fl->hlock);
1011 if (fr) {
1012 *obuf = fr;
1013 return 0;
1014 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001015 }
c_mtharue1a5ce12017-10-13 20:47:09 +05301016 buf = NULL;
1017 VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001018 if (err)
1019 goto bail;
1020 INIT_HLIST_NODE(&buf->hn);
1021 buf->fl = fl;
c_mtharue1a5ce12017-10-13 20:47:09 +05301022 buf->virt = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001023 buf->phys = 0;
1024 buf->size = size;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301025 buf->dma_attr = dma_attr;
1026 buf->flags = rflags;
1027 buf->raddr = 0;
1028 buf->remote = 0;
1029 buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
1030 (dma_addr_t *)&buf->phys,
1031 GFP_KERNEL, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001032 if (IS_ERR_OR_NULL(buf->virt)) {
1033 /* free cache and retry */
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301034 fastrpc_cached_buf_list_free(fl);
1035 buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
1036 (dma_addr_t *)&buf->phys,
1037 GFP_KERNEL, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001038 VERIFY(err, !IS_ERR_OR_NULL(buf->virt));
1039 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301040 if (err) {
1041 err = -ENOMEM;
1042 pr_err("adsprpc: %s: %s: dma_alloc_attrs failed for size 0x%zx\n",
1043 current->comm, __func__, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001044 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301045 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001046 if (fl->sctx->smmu.cb)
1047 buf->phys += ((uint64_t)fl->sctx->smmu.cb << 32);
1048 vmid = fl->apps->channel[fl->cid].vmid;
1049 if (vmid) {
1050 int srcVM[1] = {VMID_HLOS};
1051 int destVM[2] = {VMID_HLOS, vmid};
1052 int destVMperm[2] = {PERM_READ | PERM_WRITE,
1053 PERM_READ | PERM_WRITE | PERM_EXEC};
1054
1055 VERIFY(err, !hyp_assign_phys(buf->phys, buf_page_size(size),
1056 srcVM, 1, destVM, destVMperm, 2));
1057 if (err)
1058 goto bail;
1059 }
1060
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301061 if (remote) {
1062 INIT_HLIST_NODE(&buf->hn_rem);
1063 spin_lock(&fl->hlock);
1064 hlist_add_head(&buf->hn_rem, &fl->remote_bufs);
1065 spin_unlock(&fl->hlock);
1066 buf->remote = remote;
1067 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001068 *obuf = buf;
1069 bail:
1070 if (err && buf)
1071 fastrpc_buf_free(buf, 0);
1072 return err;
1073}
1074
1075
1076static int context_restore_interrupted(struct fastrpc_file *fl,
Sathish Ambleybae51902017-07-03 15:00:49 -07001077 struct fastrpc_ioctl_invoke_crc *inv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001078 struct smq_invoke_ctx **po)
1079{
1080 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05301081 struct smq_invoke_ctx *ctx = NULL, *ictx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001082 struct hlist_node *n;
1083 struct fastrpc_ioctl_invoke *invoke = &inv->inv;
1084
1085 spin_lock(&fl->hlock);
1086 hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
1087 if (ictx->pid == current->pid) {
1088 if (invoke->sc != ictx->sc || ictx->fl != fl)
1089 err = -1;
1090 else {
1091 ctx = ictx;
1092 hlist_del_init(&ctx->hn);
1093 hlist_add_head(&ctx->hn, &fl->clst.pending);
1094 }
1095 break;
1096 }
1097 }
1098 spin_unlock(&fl->hlock);
1099 if (ctx)
1100 *po = ctx;
1101 return err;
1102}
1103
1104#define CMP(aa, bb) ((aa) == (bb) ? 0 : (aa) < (bb) ? -1 : 1)
1105static int overlap_ptr_cmp(const void *a, const void *b)
1106{
1107 struct overlap *pa = *((struct overlap **)a);
1108 struct overlap *pb = *((struct overlap **)b);
1109 /* sort with lowest starting buffer first */
1110 int st = CMP(pa->start, pb->start);
1111 /* sort with highest ending buffer first */
1112 int ed = CMP(pb->end, pa->end);
1113 return st == 0 ? ed : st;
1114}
1115
Sathish Ambley9466d672017-01-25 10:51:55 -08001116static int context_build_overlap(struct smq_invoke_ctx *ctx)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001117{
Sathish Ambley9466d672017-01-25 10:51:55 -08001118 int i, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001119 remote_arg_t *lpra = ctx->lpra;
1120 int inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
1121 int outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc);
1122 int nbufs = inbufs + outbufs;
1123 struct overlap max;
1124
1125 for (i = 0; i < nbufs; ++i) {
1126 ctx->overs[i].start = (uintptr_t)lpra[i].buf.pv;
1127 ctx->overs[i].end = ctx->overs[i].start + lpra[i].buf.len;
Sathish Ambley9466d672017-01-25 10:51:55 -08001128 if (lpra[i].buf.len) {
1129 VERIFY(err, ctx->overs[i].end > ctx->overs[i].start);
1130 if (err)
1131 goto bail;
1132 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001133 ctx->overs[i].raix = i;
1134 ctx->overps[i] = &ctx->overs[i];
1135 }
c_mtharue1a5ce12017-10-13 20:47:09 +05301136 sort(ctx->overps, nbufs, sizeof(*ctx->overps), overlap_ptr_cmp, NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001137 max.start = 0;
1138 max.end = 0;
1139 for (i = 0; i < nbufs; ++i) {
1140 if (ctx->overps[i]->start < max.end) {
1141 ctx->overps[i]->mstart = max.end;
1142 ctx->overps[i]->mend = ctx->overps[i]->end;
1143 ctx->overps[i]->offset = max.end -
1144 ctx->overps[i]->start;
1145 if (ctx->overps[i]->end > max.end) {
1146 max.end = ctx->overps[i]->end;
1147 } else {
1148 ctx->overps[i]->mend = 0;
1149 ctx->overps[i]->mstart = 0;
1150 }
1151 } else {
1152 ctx->overps[i]->mend = ctx->overps[i]->end;
1153 ctx->overps[i]->mstart = ctx->overps[i]->start;
1154 ctx->overps[i]->offset = 0;
1155 max = *ctx->overps[i];
1156 }
1157 }
Sathish Ambley9466d672017-01-25 10:51:55 -08001158bail:
1159 return err;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001160}
1161
1162#define K_COPY_FROM_USER(err, kernel, dst, src, size) \
1163 do {\
1164 if (!(kernel))\
c_mtharue1a5ce12017-10-13 20:47:09 +05301165 VERIFY(err, 0 == copy_from_user((dst),\
1166 (void const __user *)(src),\
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001167 (size)));\
1168 else\
1169 memmove((dst), (src), (size));\
1170 } while (0)
1171
1172#define K_COPY_TO_USER(err, kernel, dst, src, size) \
1173 do {\
1174 if (!(kernel))\
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301175 VERIFY(err, 0 == copy_to_user((void __user *)(dst),\
c_mtharue1a5ce12017-10-13 20:47:09 +05301176 (src), (size)));\
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001177 else\
1178 memmove((dst), (src), (size));\
1179 } while (0)
1180
1181
1182static void context_free(struct smq_invoke_ctx *ctx);
1183
1184static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
Sathish Ambleybae51902017-07-03 15:00:49 -07001185 struct fastrpc_ioctl_invoke_crc *invokefd,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001186 struct smq_invoke_ctx **po)
1187{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301188 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301189 int err = 0, bufs, ii, size = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05301190 struct smq_invoke_ctx *ctx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001191 struct fastrpc_ctx_lst *clst = &fl->clst;
1192 struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
1193
1194 bufs = REMOTE_SCALARS_LENGTH(invoke->sc);
1195 size = bufs * sizeof(*ctx->lpra) + bufs * sizeof(*ctx->maps) +
1196 sizeof(*ctx->fds) * (bufs) +
1197 sizeof(*ctx->attrs) * (bufs) +
1198 sizeof(*ctx->overs) * (bufs) +
1199 sizeof(*ctx->overps) * (bufs);
1200
c_mtharue1a5ce12017-10-13 20:47:09 +05301201 VERIFY(err, NULL != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001202 if (err)
1203 goto bail;
1204
1205 INIT_HLIST_NODE(&ctx->hn);
1206 hlist_add_fake(&ctx->hn);
1207 ctx->fl = fl;
1208 ctx->maps = (struct fastrpc_mmap **)(&ctx[1]);
1209 ctx->lpra = (remote_arg_t *)(&ctx->maps[bufs]);
1210 ctx->fds = (int *)(&ctx->lpra[bufs]);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301211 if (me->legacy) {
1212 ctx->overs = (struct overlap *)(&ctx->fds[bufs]);
1213 ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
1214 } else {
1215 ctx->attrs = (unsigned int *)(&ctx->fds[bufs]);
1216 ctx->overs = (struct overlap *)(&ctx->attrs[bufs]);
1217 ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
1218 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001219
c_mtharue1a5ce12017-10-13 20:47:09 +05301220 K_COPY_FROM_USER(err, kernel, (void *)ctx->lpra, invoke->pra,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001221 bufs * sizeof(*ctx->lpra));
1222 if (err)
1223 goto bail;
1224
1225 if (invokefd->fds) {
1226 K_COPY_FROM_USER(err, kernel, ctx->fds, invokefd->fds,
1227 bufs * sizeof(*ctx->fds));
1228 if (err)
1229 goto bail;
1230 }
1231 if (invokefd->attrs) {
1232 K_COPY_FROM_USER(err, kernel, ctx->attrs, invokefd->attrs,
1233 bufs * sizeof(*ctx->attrs));
1234 if (err)
1235 goto bail;
1236 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001237 ctx->crc = (uint32_t *)invokefd->crc;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001238 ctx->sc = invoke->sc;
Sathish Ambley9466d672017-01-25 10:51:55 -08001239 if (bufs) {
1240 VERIFY(err, 0 == context_build_overlap(ctx));
1241 if (err)
1242 goto bail;
1243 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001244 ctx->retval = -1;
1245 ctx->pid = current->pid;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301246 ctx->tgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001247 init_completion(&ctx->work);
c_mtharufdac6892017-10-12 13:09:01 +05301248 ctx->magic = FASTRPC_CTX_MAGIC;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001249
1250 spin_lock(&fl->hlock);
1251 hlist_add_head(&ctx->hn, &clst->pending);
1252 spin_unlock(&fl->hlock);
1253
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301254 spin_lock(&me->ctxlock);
1255 for (ii = 0; ii < FASTRPC_CTX_MAX; ii++) {
1256 if (!me->ctxtable[ii]) {
1257 me->ctxtable[ii] = ctx;
1258 ctx->ctxid = (ptr_to_uint64(ctx) & ~0xFFF)|(ii << 4);
1259 break;
1260 }
1261 }
1262 spin_unlock(&me->ctxlock);
1263 VERIFY(err, ii < FASTRPC_CTX_MAX);
1264 if (err) {
1265 pr_err("adsprpc: out of context memory\n");
1266 goto bail;
1267 }
1268
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001269 *po = ctx;
1270bail:
1271 if (ctx && err)
1272 context_free(ctx);
1273 return err;
1274}
1275
1276static void context_save_interrupted(struct smq_invoke_ctx *ctx)
1277{
1278 struct fastrpc_ctx_lst *clst = &ctx->fl->clst;
1279
1280 spin_lock(&ctx->fl->hlock);
1281 hlist_del_init(&ctx->hn);
1282 hlist_add_head(&ctx->hn, &clst->interrupted);
1283 spin_unlock(&ctx->fl->hlock);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001284}
1285
1286static void context_free(struct smq_invoke_ctx *ctx)
1287{
1288 int i;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301289 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001290 int nbufs = REMOTE_SCALARS_INBUFS(ctx->sc) +
1291 REMOTE_SCALARS_OUTBUFS(ctx->sc);
1292 spin_lock(&ctx->fl->hlock);
1293 hlist_del_init(&ctx->hn);
1294 spin_unlock(&ctx->fl->hlock);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301295 mutex_lock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001296 for (i = 0; i < nbufs; ++i)
c_mtharu7bd6a422017-10-17 18:15:37 +05301297 fastrpc_mmap_free(ctx->maps[i], 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301298
1299 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001300 fastrpc_buf_free(ctx->buf, 1);
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301301 fastrpc_buf_free(ctx->lbuf, 1);
c_mtharufdac6892017-10-12 13:09:01 +05301302 ctx->magic = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301303 ctx->ctxid = 0;
1304
1305 spin_lock(&me->ctxlock);
1306 for (i = 0; i < FASTRPC_CTX_MAX; i++) {
1307 if (me->ctxtable[i] == ctx) {
1308 me->ctxtable[i] = NULL;
1309 break;
1310 }
1311 }
1312 spin_unlock(&me->ctxlock);
1313
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001314 kfree(ctx);
1315}
1316
1317static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
1318{
1319 ctx->retval = retval;
1320 complete(&ctx->work);
1321}
1322
1323
1324static void fastrpc_notify_users(struct fastrpc_file *me)
1325{
1326 struct smq_invoke_ctx *ictx;
1327 struct hlist_node *n;
1328
1329 spin_lock(&me->hlock);
1330 hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
1331 complete(&ictx->work);
1332 }
1333 hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
1334 complete(&ictx->work);
1335 }
1336 spin_unlock(&me->hlock);
1337
1338}
1339
Tharun Kumar Merugu77dd5872018-04-02 12:48:17 +05301340
1341static void fastrpc_notify_users_staticpd_pdr(struct fastrpc_file *me)
1342{
1343 struct smq_invoke_ctx *ictx;
1344 struct hlist_node *n;
1345
1346 spin_lock(&me->hlock);
1347 hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
1348 if (ictx->msg.pid)
1349 complete(&ictx->work);
1350 }
1351 hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
1352 if (ictx->msg.pid)
1353 complete(&ictx->work);
1354 }
1355 spin_unlock(&me->hlock);
1356}
1357
1358
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001359static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid)
1360{
1361 struct fastrpc_file *fl;
1362 struct hlist_node *n;
1363
1364 spin_lock(&me->hlock);
1365 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1366 if (fl->cid == cid)
1367 fastrpc_notify_users(fl);
1368 }
1369 spin_unlock(&me->hlock);
1370
1371}
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05301372
1373static void fastrpc_notify_pdr_drivers(struct fastrpc_apps *me, char *spdname)
1374{
1375 struct fastrpc_file *fl;
1376 struct hlist_node *n;
1377
1378 spin_lock(&me->hlock);
1379 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1380 if (fl->spdname && !strcmp(spdname, fl->spdname))
Tharun Kumar Merugu77dd5872018-04-02 12:48:17 +05301381 fastrpc_notify_users_staticpd_pdr(fl);
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05301382 }
1383 spin_unlock(&me->hlock);
1384
1385}
1386
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001387static void context_list_ctor(struct fastrpc_ctx_lst *me)
1388{
1389 INIT_HLIST_HEAD(&me->interrupted);
1390 INIT_HLIST_HEAD(&me->pending);
1391}
1392
1393static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
1394{
1395 struct fastrpc_ctx_lst *clst = &fl->clst;
c_mtharue1a5ce12017-10-13 20:47:09 +05301396 struct smq_invoke_ctx *ictx = NULL, *ctxfree;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001397 struct hlist_node *n;
1398
1399 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301400 ctxfree = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001401 spin_lock(&fl->hlock);
1402 hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) {
1403 hlist_del_init(&ictx->hn);
1404 ctxfree = ictx;
1405 break;
1406 }
1407 spin_unlock(&fl->hlock);
1408 if (ctxfree)
1409 context_free(ctxfree);
1410 } while (ctxfree);
1411 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301412 ctxfree = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001413 spin_lock(&fl->hlock);
1414 hlist_for_each_entry_safe(ictx, n, &clst->pending, hn) {
1415 hlist_del_init(&ictx->hn);
1416 ctxfree = ictx;
1417 break;
1418 }
1419 spin_unlock(&fl->hlock);
1420 if (ctxfree)
1421 context_free(ctxfree);
1422 } while (ctxfree);
1423}
1424
1425static int fastrpc_file_free(struct fastrpc_file *fl);
1426static void fastrpc_file_list_dtor(struct fastrpc_apps *me)
1427{
1428 struct fastrpc_file *fl, *free;
1429 struct hlist_node *n;
1430
1431 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301432 free = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001433 spin_lock(&me->hlock);
1434 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1435 hlist_del_init(&fl->hn);
1436 free = fl;
1437 break;
1438 }
1439 spin_unlock(&me->hlock);
1440 if (free)
1441 fastrpc_file_free(free);
1442 } while (free);
1443}
1444
1445static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
1446{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301447 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301448 remote_arg64_t *rpra, *lrpra;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001449 remote_arg_t *lpra = ctx->lpra;
1450 struct smq_invoke_buf *list;
1451 struct smq_phy_page *pages, *ipage;
1452 uint32_t sc = ctx->sc;
1453 int inbufs = REMOTE_SCALARS_INBUFS(sc);
1454 int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001455 int handles, bufs = inbufs + outbufs;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001456 uintptr_t args;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301457 size_t rlen = 0, copylen = 0, metalen = 0, lrpralen = 0;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001458 int i, oix;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001459 int err = 0;
1460 int mflags = 0;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001461 uint64_t *fdlist;
Sathish Ambleybae51902017-07-03 15:00:49 -07001462 uint32_t *crclist;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301463 int64_t *perf_counter = getperfcounter(ctx->fl, PERF_COUNT);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001464
1465 /* calculate size of the metadata */
c_mtharue1a5ce12017-10-13 20:47:09 +05301466 rpra = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001467 list = smq_invoke_buf_start(rpra, sc);
1468 pages = smq_phy_page_start(sc, list);
1469 ipage = pages;
1470
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301471 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001472 for (i = 0; i < bufs; ++i) {
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301473 uintptr_t buf = (uintptr_t)lpra[i].buf.pv;
1474 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001475
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301476 mutex_lock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301477 if (ctx->fds[i] && (ctx->fds[i] != -1)) {
1478 unsigned int attrs = 0;
1479
1480 if (ctx->attrs)
1481 attrs = ctx->attrs[i];
1482
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001483 fastrpc_mmap_create(ctx->fl, ctx->fds[i],
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301484 attrs, buf, len,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001485 mflags, &ctx->maps[i]);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301486 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301487 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001488 ipage += 1;
1489 }
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301490 PERF_END);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001491 handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301492 mutex_lock(&ctx->fl->fl_map_mutex);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001493 for (i = bufs; i < bufs + handles; i++) {
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +05301494 int dmaflags = 0;
1495
1496 if (ctx->attrs && (ctx->attrs[i] & FASTRPC_ATTR_NOMAP))
1497 dmaflags = FASTRPC_DMAHANDLE_NOMAP;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001498 VERIFY(err, !fastrpc_mmap_create(ctx->fl, ctx->fds[i],
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +05301499 FASTRPC_ATTR_NOVA, 0, 0, dmaflags, &ctx->maps[i]));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301500 if (err) {
1501 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001502 goto bail;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301503 }
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001504 ipage += 1;
1505 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301506 mutex_unlock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301507 if (!me->legacy) {
1508 metalen = copylen = (size_t)&ipage[0] +
1509 (sizeof(uint64_t) * M_FDLIST) +
1510 (sizeof(uint32_t) * M_CRCLIST);
1511 } else {
1512 metalen = copylen = (size_t)&ipage[0];
1513 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001514
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301515 /* allocate new local rpra buffer */
1516 lrpralen = (size_t)&list[0];
1517 if (lrpralen) {
1518 err = fastrpc_buf_alloc(ctx->fl, lrpralen, 0, 0, 0, &ctx->lbuf);
1519 if (err)
1520 goto bail;
1521 }
1522 if (ctx->lbuf->virt)
1523 memset(ctx->lbuf->virt, 0, lrpralen);
1524
1525 lrpra = ctx->lbuf->virt;
1526 ctx->lrpra = lrpra;
1527
1528 /* calculate len required for copying */
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001529 for (oix = 0; oix < inbufs + outbufs; ++oix) {
1530 int i = ctx->overps[oix]->raix;
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001531 uintptr_t mstart, mend;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301532 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001533
1534 if (!len)
1535 continue;
1536 if (ctx->maps[i])
1537 continue;
1538 if (ctx->overps[oix]->offset == 0)
1539 copylen = ALIGN(copylen, BALIGN);
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001540 mstart = ctx->overps[oix]->mstart;
1541 mend = ctx->overps[oix]->mend;
1542 VERIFY(err, (mend - mstart) <= LONG_MAX);
1543 if (err)
1544 goto bail;
1545 copylen += mend - mstart;
1546 VERIFY(err, copylen >= 0);
1547 if (err)
1548 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001549 }
1550 ctx->used = copylen;
1551
1552 /* allocate new buffer */
1553 if (copylen) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301554 err = fastrpc_buf_alloc(ctx->fl, copylen, 0, 0, 0, &ctx->buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001555 if (err)
1556 goto bail;
1557 }
Tharun Kumar Merugue3361f92017-06-22 10:45:43 +05301558 if (ctx->buf->virt && metalen <= copylen)
1559 memset(ctx->buf->virt, 0, metalen);
1560
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001561 /* copy metadata */
1562 rpra = ctx->buf->virt;
1563 ctx->rpra = rpra;
1564 list = smq_invoke_buf_start(rpra, sc);
1565 pages = smq_phy_page_start(sc, list);
1566 ipage = pages;
1567 args = (uintptr_t)ctx->buf->virt + metalen;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001568 for (i = 0; i < bufs + handles; ++i) {
1569 if (lpra[i].buf.len)
1570 list[i].num = 1;
1571 else
1572 list[i].num = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001573 list[i].pgidx = ipage - pages;
1574 ipage++;
1575 }
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05301576
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001577 /* map ion buffers */
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301578 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP),
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301579 for (i = 0; rpra && lrpra && i < inbufs + outbufs; ++i) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001580 struct fastrpc_mmap *map = ctx->maps[i];
1581 uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301582 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001583
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301584 rpra[i].buf.pv = lrpra[i].buf.pv = 0;
1585 rpra[i].buf.len = lrpra[i].buf.len = len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001586 if (!len)
1587 continue;
1588 if (map) {
1589 struct vm_area_struct *vma;
1590 uintptr_t offset;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301591 uint64_t num = buf_num_pages(buf, len);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001592 int idx = list[i].pgidx;
1593
1594 if (map->attr & FASTRPC_ATTR_NOVA) {
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001595 offset = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001596 } else {
1597 down_read(&current->mm->mmap_sem);
1598 VERIFY(err, NULL != (vma = find_vma(current->mm,
1599 map->va)));
1600 if (err) {
1601 up_read(&current->mm->mmap_sem);
1602 goto bail;
1603 }
1604 offset = buf_page_start(buf) - vma->vm_start;
1605 up_read(&current->mm->mmap_sem);
1606 VERIFY(err, offset < (uintptr_t)map->size);
1607 if (err)
1608 goto bail;
1609 }
1610 pages[idx].addr = map->phys + offset;
1611 pages[idx].size = num << PAGE_SHIFT;
1612 }
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301613 rpra[i].buf.pv = lrpra[i].buf.pv = buf;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001614 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001615 PERF_END);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001616 for (i = bufs; i < bufs + handles; ++i) {
1617 struct fastrpc_mmap *map = ctx->maps[i];
1618
1619 pages[i].addr = map->phys;
1620 pages[i].size = map->size;
1621 }
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301622 if (!me->legacy) {
1623 fdlist = (uint64_t *)&pages[bufs + handles];
1624 for (i = 0; i < M_FDLIST; i++)
1625 fdlist[i] = 0;
1626 crclist = (uint32_t *)&fdlist[M_FDLIST];
1627 memset(crclist, 0, sizeof(uint32_t)*M_CRCLIST);
1628 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001629
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001630 /* copy non ion buffers */
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301631 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_COPY),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001632 rlen = copylen - metalen;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301633 for (oix = 0; rpra && lrpra && oix < inbufs + outbufs; ++oix) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001634 int i = ctx->overps[oix]->raix;
1635 struct fastrpc_mmap *map = ctx->maps[i];
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301636 size_t mlen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001637 uint64_t buf;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301638 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001639
1640 if (!len)
1641 continue;
1642 if (map)
1643 continue;
1644 if (ctx->overps[oix]->offset == 0) {
1645 rlen -= ALIGN(args, BALIGN) - args;
1646 args = ALIGN(args, BALIGN);
1647 }
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001648 mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001649 VERIFY(err, rlen >= mlen);
1650 if (err)
1651 goto bail;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301652 rpra[i].buf.pv = lrpra[i].buf.pv =
1653 (args - ctx->overps[oix]->offset);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001654 pages[list[i].pgidx].addr = ctx->buf->phys -
1655 ctx->overps[oix]->offset +
1656 (copylen - rlen);
1657 pages[list[i].pgidx].addr =
1658 buf_page_start(pages[list[i].pgidx].addr);
1659 buf = rpra[i].buf.pv;
1660 pages[list[i].pgidx].size = buf_num_pages(buf, len) * PAGE_SIZE;
1661 if (i < inbufs) {
1662 K_COPY_FROM_USER(err, kernel, uint64_to_ptr(buf),
1663 lpra[i].buf.pv, len);
1664 if (err)
1665 goto bail;
1666 }
1667 args = args + mlen;
1668 rlen -= mlen;
1669 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001670 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001671
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301672 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_FLUSH),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001673 for (oix = 0; oix < inbufs + outbufs; ++oix) {
1674 int i = ctx->overps[oix]->raix;
1675 struct fastrpc_mmap *map = ctx->maps[i];
1676
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001677 if (map && map->uncached)
1678 continue;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301679 if (ctx->fl->sctx->smmu.coherent &&
1680 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1681 continue;
1682 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1683 continue;
1684
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301685 if (rpra && lrpra && rpra[i].buf.len &&
1686 ctx->overps[oix]->mstart) {
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301687 if (map && map->handle)
1688 msm_ion_do_cache_op(ctx->fl->apps->client,
1689 map->handle,
1690 uint64_to_ptr(rpra[i].buf.pv),
1691 rpra[i].buf.len,
1692 ION_IOC_CLEAN_INV_CACHES);
1693 else
1694 dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv),
1695 uint64_to_ptr(rpra[i].buf.pv
1696 + rpra[i].buf.len));
1697 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001698 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001699 PERF_END);
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301700 for (i = bufs; rpra && lrpra && i < bufs + handles; i++) {
1701 rpra[i].dma.fd = lrpra[i].dma.fd = ctx->fds[i];
1702 rpra[i].dma.len = lrpra[i].dma.len = (uint32_t)lpra[i].buf.len;
1703 rpra[i].dma.offset = lrpra[i].dma.offset =
1704 (uint32_t)(uintptr_t)lpra[i].buf.pv;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001705 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001706
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001707 bail:
1708 return err;
1709}
1710
1711static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
1712 remote_arg_t *upra)
1713{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301714 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001715 uint32_t sc = ctx->sc;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001716 struct smq_invoke_buf *list;
1717 struct smq_phy_page *pages;
1718 struct fastrpc_mmap *mmap;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301719 uint64_t *fdlist = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07001720 uint32_t *crclist = NULL;
1721
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301722 remote_arg64_t *rpra = ctx->lrpra;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001723 int i, inbufs, outbufs, handles;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001724 int err = 0;
1725
1726 inbufs = REMOTE_SCALARS_INBUFS(sc);
1727 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001728 handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
1729 list = smq_invoke_buf_start(ctx->rpra, sc);
1730 pages = smq_phy_page_start(sc, list);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301731 if (!me->legacy) {
1732 fdlist = (uint64_t *)(pages + inbufs + outbufs + handles);
1733 crclist = (uint32_t *)(fdlist + M_FDLIST);
1734 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001735
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001736 for (i = inbufs; i < inbufs + outbufs; ++i) {
1737 if (!ctx->maps[i]) {
1738 K_COPY_TO_USER(err, kernel,
1739 ctx->lpra[i].buf.pv,
1740 uint64_to_ptr(rpra[i].buf.pv),
1741 rpra[i].buf.len);
1742 if (err)
1743 goto bail;
1744 } else {
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301745 mutex_lock(&ctx->fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05301746 fastrpc_mmap_free(ctx->maps[i], 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301747 mutex_unlock(&ctx->fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05301748 ctx->maps[i] = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001749 }
1750 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301751 mutex_lock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301752 if (fdlist && (inbufs + outbufs + handles)) {
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001753 for (i = 0; i < M_FDLIST; i++) {
1754 if (!fdlist[i])
1755 break;
1756 if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0,
Sathish Ambleyae5ee542017-01-16 22:24:23 -08001757 0, 0, &mmap))
c_mtharu7bd6a422017-10-17 18:15:37 +05301758 fastrpc_mmap_free(mmap, 0);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001759 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001760 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301761 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambleybae51902017-07-03 15:00:49 -07001762 if (ctx->crc && crclist && rpra)
c_mtharue1a5ce12017-10-13 20:47:09 +05301763 K_COPY_TO_USER(err, kernel, ctx->crc,
Sathish Ambleybae51902017-07-03 15:00:49 -07001764 crclist, M_CRCLIST*sizeof(uint32_t));
1765
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001766 bail:
1767 return err;
1768}
1769
1770static void inv_args_pre(struct smq_invoke_ctx *ctx)
1771{
1772 int i, inbufs, outbufs;
1773 uint32_t sc = ctx->sc;
1774 remote_arg64_t *rpra = ctx->rpra;
1775 uintptr_t end;
1776
1777 inbufs = REMOTE_SCALARS_INBUFS(sc);
1778 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
1779 for (i = inbufs; i < inbufs + outbufs; ++i) {
1780 struct fastrpc_mmap *map = ctx->maps[i];
1781
1782 if (map && map->uncached)
1783 continue;
1784 if (!rpra[i].buf.len)
1785 continue;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301786 if (ctx->fl->sctx->smmu.coherent &&
1787 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1788 continue;
1789 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1790 continue;
1791
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001792 if (buf_page_start(ptr_to_uint64((void *)rpra)) ==
1793 buf_page_start(rpra[i].buf.pv))
1794 continue;
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301795 if (!IS_CACHE_ALIGNED((uintptr_t)
1796 uint64_to_ptr(rpra[i].buf.pv))) {
1797 if (map && map->handle)
1798 msm_ion_do_cache_op(ctx->fl->apps->client,
1799 map->handle,
1800 uint64_to_ptr(rpra[i].buf.pv),
1801 sizeof(uintptr_t),
1802 ION_IOC_CLEAN_INV_CACHES);
1803 else
1804 dmac_flush_range(
1805 uint64_to_ptr(rpra[i].buf.pv), (char *)
1806 uint64_to_ptr(rpra[i].buf.pv + 1));
1807 }
1808
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001809 end = (uintptr_t)uint64_to_ptr(rpra[i].buf.pv +
1810 rpra[i].buf.len);
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301811 if (!IS_CACHE_ALIGNED(end)) {
1812 if (map && map->handle)
1813 msm_ion_do_cache_op(ctx->fl->apps->client,
1814 map->handle,
1815 uint64_to_ptr(end),
1816 sizeof(uintptr_t),
1817 ION_IOC_CLEAN_INV_CACHES);
1818 else
1819 dmac_flush_range((char *)end,
1820 (char *)end + 1);
1821 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001822 }
1823}
1824
1825static void inv_args(struct smq_invoke_ctx *ctx)
1826{
1827 int i, inbufs, outbufs;
1828 uint32_t sc = ctx->sc;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301829 remote_arg64_t *rpra = ctx->lrpra;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001830
1831 inbufs = REMOTE_SCALARS_INBUFS(sc);
1832 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
1833 for (i = inbufs; i < inbufs + outbufs; ++i) {
1834 struct fastrpc_mmap *map = ctx->maps[i];
1835
1836 if (map && map->uncached)
1837 continue;
1838 if (!rpra[i].buf.len)
1839 continue;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301840 if (ctx->fl->sctx->smmu.coherent &&
1841 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1842 continue;
1843 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1844 continue;
1845
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001846 if (buf_page_start(ptr_to_uint64((void *)rpra)) ==
1847 buf_page_start(rpra[i].buf.pv)) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001848 continue;
1849 }
1850 if (map && map->handle)
1851 msm_ion_do_cache_op(ctx->fl->apps->client, map->handle,
1852 (char *)uint64_to_ptr(rpra[i].buf.pv),
1853 rpra[i].buf.len, ION_IOC_INV_CACHES);
1854 else
1855 dmac_inv_range((char *)uint64_to_ptr(rpra[i].buf.pv),
1856 (char *)uint64_to_ptr(rpra[i].buf.pv
1857 + rpra[i].buf.len));
1858 }
1859
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001860}
1861
1862static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
1863 uint32_t kernel, uint32_t handle)
1864{
1865 struct smq_msg *msg = &ctx->msg;
1866 struct fastrpc_file *fl = ctx->fl;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301867 int err = 0, len, cid = -1;
1868 struct fastrpc_channel_ctx *channel_ctx = NULL;
1869
1870 cid = fl->cid;
1871 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
1872 if (err) {
1873 err = -ECHRNG;
1874 goto bail;
1875 }
1876 channel_ctx = &fl->apps->channel[fl->cid];
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001877
c_mtharue1a5ce12017-10-13 20:47:09 +05301878 VERIFY(err, NULL != channel_ctx->chan);
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301879 if (err) {
1880 err = -ECHRNG;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001881 goto bail;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301882 }
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301883 msg->pid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001884 msg->tid = current->pid;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301885 if (fl->sessionid)
1886 msg->tid |= (1 << SESSION_ID_INDEX);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001887 if (kernel)
1888 msg->pid = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301889 msg->invoke.header.ctx = ctx->ctxid | fl->pd;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001890 msg->invoke.header.handle = handle;
1891 msg->invoke.header.sc = ctx->sc;
1892 msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0;
1893 msg->invoke.page.size = buf_page_size(ctx->used);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301894 if (fl->apps->glink) {
1895 if (fl->ssrcount != channel_ctx->ssrcount) {
1896 err = -ECONNRESET;
1897 goto bail;
1898 }
1899 VERIFY(err, channel_ctx->link.port_state ==
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001900 FASTRPC_LINK_CONNECTED);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301901 if (err)
1902 goto bail;
1903 err = glink_tx(channel_ctx->chan,
1904 (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg),
1905 GLINK_TX_REQ_INTENT);
1906 } else {
1907 spin_lock(&fl->apps->hlock);
1908 len = smd_write((smd_channel_t *)
1909 channel_ctx->chan,
1910 msg, sizeof(*msg));
1911 spin_unlock(&fl->apps->hlock);
1912 VERIFY(err, len == sizeof(*msg));
1913 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001914 bail:
1915 return err;
1916}
1917
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301918static void fastrpc_smd_read_handler(int cid)
1919{
1920 struct fastrpc_apps *me = &gfa;
1921 struct smq_invoke_rsp rsp = {0};
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301922 int ret = 0, err = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301923 uint32_t index;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301924
1925 do {
1926 ret = smd_read_from_cb(me->channel[cid].chan, &rsp,
1927 sizeof(rsp));
1928 if (ret != sizeof(rsp))
1929 break;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301930
1931 index = (uint32_t)((rsp.ctx & FASTRPC_CTXID_MASK) >> 4);
1932 VERIFY(err, index < FASTRPC_CTX_MAX);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301933 if (err)
1934 goto bail;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301935
1936 VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index]));
1937 if (err)
1938 goto bail;
1939
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05301940 VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp.ctx & ~3)) &&
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301941 me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC));
1942 if (err)
1943 goto bail;
1944
1945 context_notify_user(me->ctxtable[index], rsp.retval);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301946 } while (ret == sizeof(rsp));
1947bail:
1948 if (err)
1949 pr_err("adsprpc: invalid response or context\n");
1950
1951}
1952
1953static void smd_event_handler(void *priv, unsigned int event)
1954{
1955 struct fastrpc_apps *me = &gfa;
1956 int cid = (int)(uintptr_t)priv;
1957
1958 switch (event) {
1959 case SMD_EVENT_OPEN:
1960 complete(&me->channel[cid].workport);
1961 break;
1962 case SMD_EVENT_CLOSE:
1963 fastrpc_notify_drivers(me, cid);
1964 break;
1965 case SMD_EVENT_DATA:
1966 fastrpc_smd_read_handler(cid);
1967 break;
1968 }
1969}
1970
1971
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001972static void fastrpc_init(struct fastrpc_apps *me)
1973{
1974 int i;
1975
1976 INIT_HLIST_HEAD(&me->drivers);
Tharun Kumar Merugubcd6fbf2018-01-04 17:49:34 +05301977 INIT_HLIST_HEAD(&me->maps);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001978 spin_lock_init(&me->hlock);
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301979 spin_lock_init(&me->ctxlock);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05301980 mutex_init(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001981 me->channel = &gcinfo[0];
1982 for (i = 0; i < NUM_CHANNELS; i++) {
1983 init_completion(&me->channel[i].work);
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05301984 init_completion(&me->channel[i].workport);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001985 me->channel[i].sesscount = 0;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05301986 /* All channels are secure by default except CDSP */
1987 me->channel[i].secure = SECURE_CHANNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001988 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05301989 /* Set CDSP channel to non secure */
1990 me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001991}
1992
1993static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl);
1994
1995static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
1996 uint32_t kernel,
Sathish Ambleybae51902017-07-03 15:00:49 -07001997 struct fastrpc_ioctl_invoke_crc *inv)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001998{
c_mtharue1a5ce12017-10-13 20:47:09 +05301999 struct smq_invoke_ctx *ctx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002000 struct fastrpc_ioctl_invoke *invoke = &inv->inv;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05302001 int err = 0, cid = -1, interrupted = 0;
Maria Yu757199c2017-09-22 16:05:49 +08002002 struct timespec invoket = {0};
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05302003 int64_t *perf_counter = NULL;
2004
2005 cid = fl->cid;
2006 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
2007 if (err) {
2008 err = -ECHRNG;
2009 goto bail;
2010 }
2011 VERIFY(err, fl->sctx != NULL);
2012 if (err) {
2013 err = -EBADR;
2014 goto bail;
2015 }
2016 perf_counter = getperfcounter(fl, PERF_COUNT);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002017
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002018 if (fl->profile)
2019 getnstimeofday(&invoket);
Tharun Kumar Merugue3edf3e2017-07-27 12:34:07 +05302020
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302021 if (!kernel) {
2022 VERIFY(err, invoke->handle != FASTRPC_STATIC_HANDLE_KERNEL);
2023 if (err) {
2024 pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d",
2025 __func__, current->comm, cid);
2026 goto bail;
2027 }
2028 }
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302029
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002030 if (!kernel) {
2031 VERIFY(err, 0 == context_restore_interrupted(fl, inv,
2032 &ctx));
2033 if (err)
2034 goto bail;
2035 if (fl->sctx->smmu.faults)
2036 err = FASTRPC_ENOSUCH;
2037 if (err)
2038 goto bail;
2039 if (ctx)
2040 goto wait;
2041 }
2042
2043 VERIFY(err, 0 == context_alloc(fl, kernel, inv, &ctx));
2044 if (err)
2045 goto bail;
2046
2047 if (REMOTE_SCALARS_LENGTH(ctx->sc)) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302048 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_GETARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002049 VERIFY(err, 0 == get_args(kernel, ctx));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002050 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002051 if (err)
2052 goto bail;
2053 }
2054
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302055 if (!fl->sctx->smmu.coherent) {
2056 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002057 inv_args_pre(ctx);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302058 PERF_END);
2059 }
2060
2061 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_LINK),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002062 VERIFY(err, 0 == fastrpc_invoke_send(ctx, kernel, invoke->handle));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002063 PERF_END);
2064
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002065 if (err)
2066 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002067 wait:
2068 if (kernel)
2069 wait_for_completion(&ctx->work);
2070 else {
2071 interrupted = wait_for_completion_interruptible(&ctx->work);
2072 VERIFY(err, 0 == (err = interrupted));
2073 if (err)
2074 goto bail;
2075 }
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +05302076 if (ctx->handle)
2077 glink_rx_done(ctx->handle, ctx->ptr, true);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302078 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
Sathish Ambleyc432b502017-06-05 12:03:42 -07002079 if (!fl->sctx->smmu.coherent)
2080 inv_args(ctx);
2081 PERF_END);
2082
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002083 VERIFY(err, 0 == (err = ctx->retval));
2084 if (err)
2085 goto bail;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002086
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302087 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_PUTARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002088 VERIFY(err, 0 == put_args(kernel, ctx, invoke->pra));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002089 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002090 if (err)
2091 goto bail;
2092 bail:
2093 if (ctx && interrupted == -ERESTARTSYS)
2094 context_save_interrupted(ctx);
2095 else if (ctx)
2096 context_free(ctx);
2097 if (fl->ssrcount != fl->apps->channel[cid].ssrcount)
2098 err = ECONNRESET;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002099
2100 if (fl->profile && !interrupted) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302101 if (invoke->handle != FASTRPC_STATIC_HANDLE_LISTENER) {
2102 int64_t *count = GET_COUNTER(perf_counter, PERF_INVOKE);
2103
2104 if (count)
2105 *count += getnstimediff(&invoket);
2106 }
2107 if (invoke->handle > FASTRPC_STATIC_HANDLE_MAX) {
2108 int64_t *count = GET_COUNTER(perf_counter, PERF_COUNT);
2109
2110 if (count)
2111 *count = *count+1;
2112 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002113 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002114 return err;
2115}
2116
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302117static int fastrpc_get_adsp_session(char *name, int *session)
2118{
2119 struct fastrpc_apps *me = &gfa;
2120 int err = 0, i;
2121
2122 for (i = 0; i < NUM_SESSIONS; i++) {
2123 if (!me->channel[0].spd[i].spdname)
2124 continue;
2125 if (!strcmp(name, me->channel[0].spd[i].spdname))
2126 break;
2127 }
2128 VERIFY(err, i < NUM_SESSIONS);
2129 if (err)
2130 goto bail;
2131 *session = i;
2132bail:
2133 return err;
2134}
2135
2136static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl);
Sathish Ambley36849af2017-02-02 09:35:55 -08002137static int fastrpc_channel_open(struct fastrpc_file *fl);
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302138static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002139static int fastrpc_init_process(struct fastrpc_file *fl,
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002140 struct fastrpc_ioctl_init_attrs *uproc)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002141{
2142 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302143 struct fastrpc_apps *me = &gfa;
Sathish Ambleybae51902017-07-03 15:00:49 -07002144 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002145 struct fastrpc_ioctl_init *init = &uproc->init;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002146 struct smq_phy_page pages[1];
c_mtharue1a5ce12017-10-13 20:47:09 +05302147 struct fastrpc_mmap *file = NULL, *mem = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302148 struct fastrpc_buf *imem = NULL;
2149 unsigned long imem_dma_attr = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302150 char *proc_name = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002151
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302152 VERIFY(err, 0 == (err = fastrpc_channel_open(fl)));
Sathish Ambley36849af2017-02-02 09:35:55 -08002153 if (err)
2154 goto bail;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302155 if (init->flags == FASTRPC_INIT_ATTACH ||
2156 init->flags == FASTRPC_INIT_ATTACH_SENSORS) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002157 remote_arg_t ra[1];
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302158 int tgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002159
2160 ra[0].buf.pv = (void *)&tgid;
2161 ra[0].buf.len = sizeof(tgid);
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302162 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002163 ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
2164 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302165 ioctl.fds = NULL;
2166 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002167 ioctl.crc = NULL;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302168 if (init->flags == FASTRPC_INIT_ATTACH)
2169 fl->pd = 0;
2170 else if (init->flags == FASTRPC_INIT_ATTACH_SENSORS) {
2171 fl->spdname = SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME;
2172 fl->pd = 2;
2173 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002174 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2175 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2176 if (err)
2177 goto bail;
2178 } else if (init->flags == FASTRPC_INIT_CREATE) {
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002179 remote_arg_t ra[6];
2180 int fds[6];
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002181 int mflags = 0;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302182 int memlen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002183 struct {
2184 int pgid;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302185 unsigned int namelen;
2186 unsigned int filelen;
2187 unsigned int pageslen;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002188 int attrs;
2189 int siglen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002190 } inbuf;
2191
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302192 inbuf.pgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002193 inbuf.namelen = strlen(current->comm) + 1;
2194 inbuf.filelen = init->filelen;
2195 fl->pd = 1;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302196
Tharun Kumar Merugudf852892017-12-07 16:27:37 +05302197 VERIFY(err, access_ok(0, (void __user *)init->file,
2198 init->filelen));
2199 if (err)
2200 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002201 if (init->filelen) {
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302202 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002203 VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, 0,
2204 init->file, init->filelen, mflags, &file));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302205 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002206 if (err)
2207 goto bail;
2208 }
2209 inbuf.pageslen = 1;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302210
2211 VERIFY(err, !init->mem);
2212 if (err) {
2213 err = -EINVAL;
2214 pr_err("adsprpc: %s: %s: ERROR: donated memory allocated in userspace\n",
2215 current->comm, __func__);
2216 goto bail;
2217 }
2218 memlen = ALIGN(max(1024*1024*3, (int)init->filelen * 4),
2219 1024*1024);
2220 imem_dma_attr = DMA_ATTR_EXEC_MAPPING |
2221 DMA_ATTR_NO_KERNEL_MAPPING |
2222 DMA_ATTR_FORCE_NON_COHERENT;
2223 err = fastrpc_buf_alloc(fl, memlen, imem_dma_attr, 0, 0, &imem);
Tharun Kumar Merugudf852892017-12-07 16:27:37 +05302224 if (err)
2225 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302226 fl->init_mem = imem;
2227
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002228 inbuf.pageslen = 1;
2229 ra[0].buf.pv = (void *)&inbuf;
2230 ra[0].buf.len = sizeof(inbuf);
2231 fds[0] = 0;
2232
2233 ra[1].buf.pv = (void *)current->comm;
2234 ra[1].buf.len = inbuf.namelen;
2235 fds[1] = 0;
2236
2237 ra[2].buf.pv = (void *)init->file;
2238 ra[2].buf.len = inbuf.filelen;
2239 fds[2] = init->filefd;
2240
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302241 pages[0].addr = imem->phys;
2242 pages[0].size = imem->size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002243 ra[3].buf.pv = (void *)pages;
2244 ra[3].buf.len = 1 * sizeof(*pages);
2245 fds[3] = 0;
2246
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002247 inbuf.attrs = uproc->attrs;
2248 ra[4].buf.pv = (void *)&(inbuf.attrs);
2249 ra[4].buf.len = sizeof(inbuf.attrs);
2250 fds[4] = 0;
2251
2252 inbuf.siglen = uproc->siglen;
2253 ra[5].buf.pv = (void *)&(inbuf.siglen);
2254 ra[5].buf.len = sizeof(inbuf.siglen);
2255 fds[5] = 0;
2256
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302257 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002258 ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0);
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002259 if (uproc->attrs)
2260 ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002261 ioctl.inv.pra = ra;
2262 ioctl.fds = fds;
c_mtharue1a5ce12017-10-13 20:47:09 +05302263 ioctl.attrs = NULL;
2264 ioctl.crc = NULL;
2265 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2266 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2267 if (err)
2268 goto bail;
2269 } else if (init->flags == FASTRPC_INIT_CREATE_STATIC) {
2270 remote_arg_t ra[3];
2271 uint64_t phys = 0;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302272 size_t size = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302273 int fds[3];
2274 struct {
2275 int pgid;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302276 unsigned int namelen;
2277 unsigned int pageslen;
c_mtharue1a5ce12017-10-13 20:47:09 +05302278 } inbuf;
2279
2280 if (!init->filelen)
2281 goto bail;
2282
2283 proc_name = kzalloc(init->filelen, GFP_KERNEL);
2284 VERIFY(err, !IS_ERR_OR_NULL(proc_name));
2285 if (err)
2286 goto bail;
2287 VERIFY(err, 0 == copy_from_user((void *)proc_name,
2288 (void __user *)init->file, init->filelen));
2289 if (err)
2290 goto bail;
2291
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302292 fl->pd = 1;
c_mtharue1a5ce12017-10-13 20:47:09 +05302293 inbuf.pgid = current->tgid;
c_mtharu81a0aa72017-11-07 16:13:21 +05302294 inbuf.namelen = init->filelen;
c_mtharue1a5ce12017-10-13 20:47:09 +05302295 inbuf.pageslen = 0;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302296
2297 if (!strcmp(proc_name, "audiopd")) {
2298 fl->spdname = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME;
2299 VERIFY(err, !fastrpc_mmap_remove_pdr(fl));
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05302300 if (err)
2301 goto bail;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302302 }
2303
c_mtharue1a5ce12017-10-13 20:47:09 +05302304 if (!me->staticpd_flags) {
2305 inbuf.pageslen = 1;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302306 mutex_lock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302307 VERIFY(err, !fastrpc_mmap_create(fl, -1, 0, init->mem,
2308 init->memlen, ADSP_MMAP_REMOTE_HEAP_ADDR,
2309 &mem));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302310 mutex_unlock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302311 if (err)
2312 goto bail;
2313 phys = mem->phys;
2314 size = mem->size;
2315 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302316 hlosvm, 1, me->channel[fl->cid].rhvm.vmid,
2317 me->channel[fl->cid].rhvm.vmperm,
2318 me->channel[fl->cid].rhvm.vmcount));
c_mtharue1a5ce12017-10-13 20:47:09 +05302319 if (err) {
2320 pr_err("ADSPRPC: hyp_assign_phys fail err %d",
2321 err);
2322 pr_err("map->phys %llx, map->size %d\n",
2323 phys, (int)size);
2324 goto bail;
2325 }
2326 me->staticpd_flags = 1;
2327 }
2328
2329 ra[0].buf.pv = (void *)&inbuf;
2330 ra[0].buf.len = sizeof(inbuf);
2331 fds[0] = 0;
2332
2333 ra[1].buf.pv = (void *)proc_name;
2334 ra[1].buf.len = inbuf.namelen;
2335 fds[1] = 0;
2336
2337 pages[0].addr = phys;
2338 pages[0].size = size;
2339
2340 ra[2].buf.pv = (void *)pages;
2341 ra[2].buf.len = sizeof(*pages);
2342 fds[2] = 0;
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302343 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
c_mtharue1a5ce12017-10-13 20:47:09 +05302344
2345 ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
2346 ioctl.inv.pra = ra;
2347 ioctl.fds = NULL;
2348 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002349 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002350 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2351 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2352 if (err)
2353 goto bail;
2354 } else {
2355 err = -ENOTTY;
2356 }
2357bail:
c_mtharud91205a2017-11-07 16:01:06 +05302358 kfree(proc_name);
c_mtharue1a5ce12017-10-13 20:47:09 +05302359 if (err && (init->flags == FASTRPC_INIT_CREATE_STATIC))
2360 me->staticpd_flags = 0;
2361 if (mem && err) {
2362 if (mem->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
2363 hyp_assign_phys(mem->phys, (uint64_t)mem->size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302364 me->channel[fl->cid].rhvm.vmid,
2365 me->channel[fl->cid].rhvm.vmcount,
2366 hlosvm, hlosvmperm, 1);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302367 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302368 fastrpc_mmap_free(mem, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302369 mutex_unlock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302370 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302371 if (file) {
2372 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302373 fastrpc_mmap_free(file, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302374 mutex_unlock(&fl->fl_map_mutex);
2375 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002376 return err;
2377}
2378
2379static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
2380{
2381 int err = 0;
Sathish Ambleybae51902017-07-03 15:00:49 -07002382 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002383 remote_arg_t ra[1];
2384 int tgid = 0;
2385
Sathish Ambley36849af2017-02-02 09:35:55 -08002386 VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS);
2387 if (err)
2388 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05302389 VERIFY(err, fl->apps->channel[fl->cid].chan != NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002390 if (err)
2391 goto bail;
2392 tgid = fl->tgid;
2393 ra[0].buf.pv = (void *)&tgid;
2394 ra[0].buf.len = sizeof(tgid);
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302395 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002396 ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
2397 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302398 ioctl.fds = NULL;
2399 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002400 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002401 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2402 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2403bail:
2404 return err;
2405}
2406
2407static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302408 uintptr_t va, uint64_t phys,
2409 size_t size, uintptr_t *raddr)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002410{
Sathish Ambleybae51902017-07-03 15:00:49 -07002411 struct fastrpc_ioctl_invoke_crc ioctl;
c_mtharu63ffc012017-11-16 15:26:56 +05302412 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002413 struct smq_phy_page page;
2414 int num = 1;
2415 remote_arg_t ra[3];
2416 int err = 0;
2417 struct {
2418 int pid;
2419 uint32_t flags;
2420 uintptr_t vaddrin;
2421 int num;
2422 } inargs;
2423 struct {
2424 uintptr_t vaddrout;
2425 } routargs;
2426
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302427 inargs.pid = fl->tgid;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302428 inargs.vaddrin = (uintptr_t)va;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002429 inargs.flags = flags;
2430 inargs.num = fl->apps->compat ? num * sizeof(page) : num;
2431 ra[0].buf.pv = (void *)&inargs;
2432 ra[0].buf.len = sizeof(inargs);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302433 page.addr = phys;
2434 page.size = size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002435 ra[1].buf.pv = (void *)&page;
2436 ra[1].buf.len = num * sizeof(page);
2437
2438 ra[2].buf.pv = (void *)&routargs;
2439 ra[2].buf.len = sizeof(routargs);
2440
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302441 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002442 if (fl->apps->compat)
2443 ioctl.inv.sc = REMOTE_SCALARS_MAKE(4, 2, 1);
2444 else
2445 ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
2446 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302447 ioctl.fds = NULL;
2448 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002449 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002450 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2451 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302452 *raddr = (uintptr_t)routargs.vaddrout;
c_mtharue1a5ce12017-10-13 20:47:09 +05302453 if (err)
2454 goto bail;
2455 if (flags == ADSP_MMAP_HEAP_ADDR) {
2456 struct scm_desc desc = {0};
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002457
c_mtharue1a5ce12017-10-13 20:47:09 +05302458 desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302459 desc.args[1] = phys;
2460 desc.args[2] = size;
c_mtharue1a5ce12017-10-13 20:47:09 +05302461 desc.arginfo = SCM_ARGS(3);
2462 err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
2463 TZ_PIL_PROTECT_MEM_SUBSYS_ID), &desc);
2464 } else if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302465 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302466 hlosvm, 1, me->channel[fl->cid].rhvm.vmid,
2467 me->channel[fl->cid].rhvm.vmperm,
2468 me->channel[fl->cid].rhvm.vmcount));
c_mtharue1a5ce12017-10-13 20:47:09 +05302469 if (err)
2470 goto bail;
2471 }
2472bail:
2473 return err;
2474}
2475
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302476static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys,
2477 size_t size, uint32_t flags)
c_mtharue1a5ce12017-10-13 20:47:09 +05302478{
2479 int err = 0;
c_mtharu63ffc012017-11-16 15:26:56 +05302480 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302481 int tgid = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302482 int destVM[1] = {VMID_HLOS};
2483 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
2484
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302485 if (flags == ADSP_MMAP_HEAP_ADDR) {
c_mtharue1a5ce12017-10-13 20:47:09 +05302486 struct fastrpc_ioctl_invoke_crc ioctl;
2487 struct scm_desc desc = {0};
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302488 remote_arg_t ra[2];
2489
c_mtharue1a5ce12017-10-13 20:47:09 +05302490 struct {
2491 uint8_t skey;
2492 } routargs;
2493
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302494 if (fl == NULL)
2495 goto bail;
2496 tgid = fl->tgid;
2497 ra[0].buf.pv = (void *)&tgid;
2498 ra[0].buf.len = sizeof(tgid);
2499 ra[1].buf.pv = (void *)&routargs;
2500 ra[1].buf.len = sizeof(routargs);
c_mtharue1a5ce12017-10-13 20:47:09 +05302501
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302502 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302503 ioctl.inv.sc = REMOTE_SCALARS_MAKE(9, 1, 1);
c_mtharue1a5ce12017-10-13 20:47:09 +05302504 ioctl.inv.pra = ra;
2505 ioctl.fds = NULL;
2506 ioctl.attrs = NULL;
2507 ioctl.crc = NULL;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302508
c_mtharue1a5ce12017-10-13 20:47:09 +05302509
2510 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2511 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
Mohammed Nayeem Ur Rahman80f45dc2019-09-23 19:35:19 +05302512 if (err == AEE_EUNSUPPORTED) {
2513 remote_arg_t ra[1];
2514
2515 pr_warn("ADSPRPC:Failed to get security key with updated remote call, falling back to older method");
2516 ra[0].buf.pv = (void *)&routargs;
2517 ra[0].buf.len = sizeof(routargs);
2518 ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1);
2519 ioctl.inv.pra = ra;
2520 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2521 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2522 }
c_mtharue1a5ce12017-10-13 20:47:09 +05302523 if (err)
2524 goto bail;
Mohammed Nayeem Ur Rahman80f45dc2019-09-23 19:35:19 +05302525
c_mtharue1a5ce12017-10-13 20:47:09 +05302526 desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302527 desc.args[1] = phys;
2528 desc.args[2] = size;
c_mtharue1a5ce12017-10-13 20:47:09 +05302529 desc.args[3] = routargs.skey;
2530 desc.arginfo = SCM_ARGS(4);
2531 err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
2532 TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID), &desc);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302533 } else if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
2534 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302535 me->channel[fl->cid].rhvm.vmid,
2536 me->channel[fl->cid].rhvm.vmcount,
2537 destVM, destVMperm, 1));
c_mtharue1a5ce12017-10-13 20:47:09 +05302538 if (err)
2539 goto bail;
2540 }
2541
2542bail:
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002543 return err;
2544}
2545
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302546static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, uintptr_t raddr,
2547 uint64_t phys, size_t size, uint32_t flags)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002548{
Sathish Ambleybae51902017-07-03 15:00:49 -07002549 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002550 remote_arg_t ra[1];
2551 int err = 0;
2552 struct {
2553 int pid;
2554 uintptr_t vaddrout;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302555 size_t size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002556 } inargs;
2557
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302558 inargs.pid = fl->tgid;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302559 inargs.size = size;
2560 inargs.vaddrout = raddr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002561 ra[0].buf.pv = (void *)&inargs;
2562 ra[0].buf.len = sizeof(inargs);
2563
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302564 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002565 if (fl->apps->compat)
2566 ioctl.inv.sc = REMOTE_SCALARS_MAKE(5, 1, 0);
2567 else
2568 ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
2569 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302570 ioctl.fds = NULL;
2571 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002572 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002573 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2574 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
c_mtharue1a5ce12017-10-13 20:47:09 +05302575 if (err)
2576 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302577 if (flags == ADSP_MMAP_HEAP_ADDR ||
2578 flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
2579 VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, phys, size, flags));
c_mtharue1a5ce12017-10-13 20:47:09 +05302580 if (err)
2581 goto bail;
2582 }
2583bail:
2584 return err;
2585}
2586
2587static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
2588{
2589 struct fastrpc_mmap *match = NULL, *map = NULL;
2590 struct hlist_node *n = NULL;
2591 int err = 0, ret = 0;
2592 struct fastrpc_apps *me = &gfa;
2593 struct ramdump_segment *ramdump_segments_rh = NULL;
2594
2595 do {
2596 match = NULL;
2597 spin_lock(&me->hlock);
2598 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
2599 match = map;
2600 hlist_del_init(&map->hn);
2601 break;
2602 }
2603 spin_unlock(&me->hlock);
2604
2605 if (match) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302606 VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, match->phys,
2607 match->size, match->flags));
c_mtharue1a5ce12017-10-13 20:47:09 +05302608 if (err)
2609 goto bail;
2610 if (me->channel[0].ramdumpenabled) {
2611 ramdump_segments_rh = kcalloc(1,
2612 sizeof(struct ramdump_segment), GFP_KERNEL);
2613 if (ramdump_segments_rh) {
2614 ramdump_segments_rh->address =
2615 match->phys;
2616 ramdump_segments_rh->size = match->size;
2617 ret = do_elf_ramdump(
2618 me->channel[0].remoteheap_ramdump_dev,
2619 ramdump_segments_rh, 1);
2620 if (ret < 0)
2621 pr_err("ADSPRPC: unable to dump heap");
2622 kfree(ramdump_segments_rh);
2623 }
2624 }
c_mtharu7bd6a422017-10-17 18:15:37 +05302625 fastrpc_mmap_free(match, 0);
c_mtharue1a5ce12017-10-13 20:47:09 +05302626 }
2627 } while (match);
2628bail:
2629 if (err && match)
2630 fastrpc_mmap_add(match);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002631 return err;
2632}
2633
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302634static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl)
2635{
2636 struct fastrpc_apps *me = &gfa;
2637 int session = 0, err = 0;
2638
2639 VERIFY(err, !fastrpc_get_adsp_session(
2640 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
2641 if (err)
2642 goto bail;
2643 if (me->channel[fl->cid].spd[session].pdrcount !=
2644 me->channel[fl->cid].spd[session].prevpdrcount) {
2645 if (fastrpc_mmap_remove_ssr(fl))
2646 pr_err("ADSPRPC: SSR: Failed to unmap remote heap\n");
2647 me->channel[fl->cid].spd[session].prevpdrcount =
2648 me->channel[fl->cid].spd[session].pdrcount;
2649 }
2650 if (!me->channel[fl->cid].spd[session].ispdup) {
2651 VERIFY(err, 0);
2652 if (err) {
2653 err = -ENOTCONN;
2654 goto bail;
2655 }
2656 }
2657bail:
2658 return err;
2659}
2660
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002661static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302662 size_t len, struct fastrpc_mmap **ppmap);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002663
2664static void fastrpc_mmap_add(struct fastrpc_mmap *map);
2665
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05302666static inline void get_fastrpc_ioctl_mmap_64(
2667 struct fastrpc_ioctl_mmap_64 *mmap64,
2668 struct fastrpc_ioctl_mmap *immap)
2669{
2670 immap->fd = mmap64->fd;
2671 immap->flags = mmap64->flags;
2672 immap->vaddrin = (uintptr_t)mmap64->vaddrin;
2673 immap->size = mmap64->size;
2674}
2675
2676static inline void put_fastrpc_ioctl_mmap_64(
2677 struct fastrpc_ioctl_mmap_64 *mmap64,
2678 struct fastrpc_ioctl_mmap *immap)
2679{
2680 mmap64->vaddrout = (uint64_t)immap->vaddrout;
2681}
2682
2683static inline void get_fastrpc_ioctl_munmap_64(
2684 struct fastrpc_ioctl_munmap_64 *munmap64,
2685 struct fastrpc_ioctl_munmap *imunmap)
2686{
2687 imunmap->vaddrout = (uintptr_t)munmap64->vaddrout;
2688 imunmap->size = munmap64->size;
2689}
2690
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002691static int fastrpc_internal_munmap(struct fastrpc_file *fl,
2692 struct fastrpc_ioctl_munmap *ud)
2693{
2694 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302695 struct fastrpc_mmap *map = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302696 struct fastrpc_buf *rbuf = NULL, *free = NULL;
2697 struct hlist_node *n;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002698
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302699 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302700
2701 spin_lock(&fl->hlock);
2702 hlist_for_each_entry_safe(rbuf, n, &fl->remote_bufs, hn_rem) {
2703 if (rbuf->raddr && (rbuf->flags == ADSP_MMAP_ADD_PAGES)) {
2704 if ((rbuf->raddr == ud->vaddrout) &&
2705 (rbuf->size == ud->size)) {
2706 free = rbuf;
2707 break;
2708 }
2709 }
2710 }
2711 spin_unlock(&fl->hlock);
2712
2713 if (free) {
2714 VERIFY(err, !fastrpc_munmap_on_dsp(fl, free->raddr,
2715 free->phys, free->size, free->flags));
2716 if (err)
2717 goto bail;
2718 fastrpc_buf_free(rbuf, 0);
2719 mutex_unlock(&fl->map_mutex);
2720 return err;
2721 }
2722
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302723 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002724 VERIFY(err, !fastrpc_mmap_remove(fl, ud->vaddrout, ud->size, &map));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302725 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002726 if (err)
2727 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302728 VERIFY(err, !fastrpc_munmap_on_dsp(fl, map->raddr,
2729 map->phys, map->size, map->flags));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002730 if (err)
2731 goto bail;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302732 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302733 fastrpc_mmap_free(map, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302734 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002735bail:
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302736 if (err && map) {
2737 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002738 fastrpc_mmap_add(map);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302739 mutex_unlock(&fl->fl_map_mutex);
2740 }
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302741 mutex_unlock(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002742 return err;
2743}
2744
c_mtharu7bd6a422017-10-17 18:15:37 +05302745static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl,
2746 struct fastrpc_ioctl_munmap_fd *ud) {
2747 int err = 0;
2748 struct fastrpc_mmap *map = NULL;
2749
2750 VERIFY(err, (fl && ud));
2751 if (err)
2752 goto bail;
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302753 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302754 mutex_lock(&fl->fl_map_mutex);
Tharun Kumar Merugu09fc6152018-02-16 13:13:12 +05302755 if (fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map)) {
2756 pr_err("adsprpc: mapping not found to unmap %d va %llx %x\n",
c_mtharu7bd6a422017-10-17 18:15:37 +05302757 ud->fd, (unsigned long long)ud->va,
2758 (unsigned int)ud->len);
2759 err = -1;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302760 mutex_unlock(&fl->fl_map_mutex);
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302761 mutex_unlock(&fl->map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302762 goto bail;
2763 }
2764 if (map)
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302765 fastrpc_mmap_free(map, 0);
2766 mutex_unlock(&fl->fl_map_mutex);
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302767 mutex_unlock(&fl->map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302768bail:
2769 return err;
2770}
2771
2772
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002773static int fastrpc_internal_mmap(struct fastrpc_file *fl,
2774 struct fastrpc_ioctl_mmap *ud)
2775{
2776
c_mtharue1a5ce12017-10-13 20:47:09 +05302777 struct fastrpc_mmap *map = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302778 struct fastrpc_buf *rbuf = NULL;
2779 unsigned long dma_attr = 0;
2780 uintptr_t raddr = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002781 int err = 0;
2782
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302783 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302784 if (ud->flags == ADSP_MMAP_ADD_PAGES) {
2785 if (ud->vaddrin) {
2786 err = -EINVAL;
2787 pr_err("adsprpc: %s: %s: ERROR: adding user allocated pages is not supported\n",
2788 current->comm, __func__);
2789 goto bail;
2790 }
2791 dma_attr = DMA_ATTR_EXEC_MAPPING |
2792 DMA_ATTR_NO_KERNEL_MAPPING |
2793 DMA_ATTR_FORCE_NON_COHERENT;
2794 err = fastrpc_buf_alloc(fl, ud->size, dma_attr, ud->flags,
2795 1, &rbuf);
2796 if (err)
2797 goto bail;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302798 err = fastrpc_mmap_on_dsp(fl, ud->flags, 0,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302799 rbuf->phys, rbuf->size, &raddr);
2800 if (err)
2801 goto bail;
2802 rbuf->raddr = raddr;
2803 } else {
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302804
2805 uintptr_t va_to_dsp;
2806
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302807 mutex_lock(&fl->fl_map_mutex);
2808 if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin,
2809 ud->size, ud->flags, 1, &map)) {
Mohammed Nayeem Ur Rahmanaf5f6102019-10-09 13:36:52 +05302810 ud->vaddrout = map->raddr;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302811 mutex_unlock(&fl->fl_map_mutex);
2812 mutex_unlock(&fl->map_mutex);
2813 return 0;
2814 }
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302815
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302816 VERIFY(err, !fastrpc_mmap_create(fl, ud->fd, 0,
2817 (uintptr_t)ud->vaddrin, ud->size,
2818 ud->flags, &map));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302819 mutex_unlock(&fl->fl_map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302820 if (err)
2821 goto bail;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302822
2823 if (ud->flags == ADSP_MMAP_HEAP_ADDR ||
2824 ud->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
2825 va_to_dsp = 0;
2826 else
2827 va_to_dsp = (uintptr_t)map->va;
2828 VERIFY(err, 0 == fastrpc_mmap_on_dsp(fl, ud->flags, va_to_dsp,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302829 map->phys, map->size, &raddr));
2830 if (err)
2831 goto bail;
2832 map->raddr = raddr;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302833 }
Mohammed Nayeem Ur Rahman3ac5d322018-09-24 13:54:08 +05302834 ud->vaddrout = raddr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002835 bail:
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302836 if (err && map) {
2837 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302838 fastrpc_mmap_free(map, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302839 mutex_unlock(&fl->fl_map_mutex);
2840 }
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302841 mutex_unlock(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002842 return err;
2843}
2844
2845static void fastrpc_channel_close(struct kref *kref)
2846{
2847 struct fastrpc_apps *me = &gfa;
2848 struct fastrpc_channel_ctx *ctx;
2849 int cid;
2850
2851 ctx = container_of(kref, struct fastrpc_channel_ctx, kref);
2852 cid = ctx - &gcinfo[0];
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05302853 if (me->glink) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05302854 fastrpc_glink_close(ctx->chan, cid);
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05302855 ctx->chan = NULL;
2856 }
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302857 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002858 pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
2859 MAJOR(me->dev_no), cid);
2860}
2861
2862static void fastrpc_context_list_dtor(struct fastrpc_file *fl);
2863
2864static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan,
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302865 int secure, int sharedcb, struct fastrpc_session_ctx **session)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002866{
2867 struct fastrpc_apps *me = &gfa;
2868 int idx = 0, err = 0;
2869
2870 if (chan->sesscount) {
2871 for (idx = 0; idx < chan->sesscount; ++idx) {
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302872 if ((sharedcb && chan->session[idx].smmu.sharedcb) ||
2873 (!chan->session[idx].used &&
2874 chan->session[idx].smmu.secure
2875 == secure && !sharedcb)) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002876 chan->session[idx].used = 1;
2877 break;
2878 }
2879 }
2880 VERIFY(err, idx < chan->sesscount);
2881 if (err)
2882 goto bail;
2883 chan->session[idx].smmu.faults = 0;
2884 } else {
2885 VERIFY(err, me->dev != NULL);
2886 if (err)
2887 goto bail;
2888 chan->session[0].dev = me->dev;
c_mtharue1a5ce12017-10-13 20:47:09 +05302889 chan->session[0].smmu.dev = me->dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002890 }
2891
2892 *session = &chan->session[idx];
2893 bail:
2894 return err;
2895}
2896
c_mtharue1a5ce12017-10-13 20:47:09 +05302897static bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv,
2898 size_t size)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002899{
2900 if (glink_queue_rx_intent(h, NULL, size))
2901 return false;
2902 return true;
2903}
2904
c_mtharue1a5ce12017-10-13 20:47:09 +05302905static void fastrpc_glink_notify_tx_done(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002906 const void *pkt_priv, const void *ptr)
2907{
2908}
2909
c_mtharue1a5ce12017-10-13 20:47:09 +05302910static void fastrpc_glink_notify_rx(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002911 const void *pkt_priv, const void *ptr, size_t size)
2912{
2913 struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302914 struct fastrpc_apps *me = &gfa;
2915 uint32_t index;
c_mtharufdac6892017-10-12 13:09:01 +05302916 int err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002917
c_mtharufdac6892017-10-12 13:09:01 +05302918 VERIFY(err, (rsp && size >= sizeof(*rsp)));
2919 if (err)
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302920 goto bail;
2921
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302922 index = (uint32_t)((rsp->ctx & FASTRPC_CTXID_MASK) >> 4);
2923 VERIFY(err, index < FASTRPC_CTX_MAX);
c_mtharufdac6892017-10-12 13:09:01 +05302924 if (err)
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302925 goto bail;
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302926
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302927 VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index]));
2928 if (err)
2929 goto bail;
2930
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302931 VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp->ctx & ~3)) &&
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302932 me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC));
2933 if (err)
2934 goto bail;
2935
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +05302936 me->ctxtable[index]->handle = handle;
2937 me->ctxtable[index]->ptr = ptr;
2938
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302939 context_notify_user(me->ctxtable[index], rsp->retval);
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302940bail:
c_mtharufdac6892017-10-12 13:09:01 +05302941 if (err)
2942 pr_err("adsprpc: invalid response or context\n");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002943}
2944
c_mtharue1a5ce12017-10-13 20:47:09 +05302945static void fastrpc_glink_notify_state(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002946 unsigned int event)
2947{
2948 struct fastrpc_apps *me = &gfa;
2949 int cid = (int)(uintptr_t)priv;
2950 struct fastrpc_glink_info *link;
2951
2952 if (cid < 0 || cid >= NUM_CHANNELS)
2953 return;
2954 link = &me->channel[cid].link;
2955 switch (event) {
2956 case GLINK_CONNECTED:
2957 link->port_state = FASTRPC_LINK_CONNECTED;
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05302958 complete(&me->channel[cid].workport);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002959 break;
2960 case GLINK_LOCAL_DISCONNECTED:
2961 link->port_state = FASTRPC_LINK_DISCONNECTED;
2962 break;
2963 case GLINK_REMOTE_DISCONNECTED:
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002964 break;
2965 default:
2966 break;
2967 }
2968}
2969
2970static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
2971 struct fastrpc_session_ctx **session)
2972{
2973 int err = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302974 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002975
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302976 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002977 if (!*session)
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302978 err = fastrpc_session_alloc_locked(chan, secure, 0, session);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302979 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002980 return err;
2981}
2982
2983static void fastrpc_session_free(struct fastrpc_channel_ctx *chan,
2984 struct fastrpc_session_ctx *session)
2985{
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302986 struct fastrpc_apps *me = &gfa;
2987
2988 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002989 session->used = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302990 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002991}
2992
2993static int fastrpc_file_free(struct fastrpc_file *fl)
2994{
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302995 struct hlist_node *n = NULL;
Tharun Kumar Merugu3e966762018-04-04 10:56:44 +05302996 struct fastrpc_mmap *map = NULL, *lmap = NULL;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302997 struct fastrpc_perf *perf = NULL, *fperf = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002998 int cid;
2999
3000 if (!fl)
3001 return 0;
3002 cid = fl->cid;
3003
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05303004 (void)fastrpc_release_current_dsp_process(fl);
3005
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003006 spin_lock(&fl->apps->hlock);
3007 hlist_del_init(&fl->hn);
3008 spin_unlock(&fl->apps->hlock);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303009 kfree(fl->debug_buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003010
Sathish Ambleyd7fbcbb2017-03-08 10:55:48 -08003011 if (!fl->sctx) {
3012 kfree(fl);
3013 return 0;
3014 }
tharun kumar9f899ea2017-07-03 17:07:03 +05303015 spin_lock(&fl->hlock);
3016 fl->file_close = 1;
3017 spin_unlock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303018 if (!IS_ERR_OR_NULL(fl->init_mem))
3019 fastrpc_buf_free(fl->init_mem, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003020 fastrpc_context_list_dtor(fl);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303021 fastrpc_cached_buf_list_free(fl);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303022 mutex_lock(&fl->fl_map_mutex);
Tharun Kumar Merugu3e966762018-04-04 10:56:44 +05303023 do {
3024 lmap = NULL;
3025 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3026 hlist_del_init(&map->hn);
3027 lmap = map;
3028 break;
3029 }
3030 fastrpc_mmap_free(lmap, 1);
3031 } while (lmap);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303032 mutex_unlock(&fl->fl_map_mutex);
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303033 if (fl->refcount && (fl->ssrcount == fl->apps->channel[cid].ssrcount))
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003034 kref_put_mutex(&fl->apps->channel[cid].kref,
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303035 fastrpc_channel_close, &fl->apps->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003036 if (fl->sctx)
3037 fastrpc_session_free(&fl->apps->channel[cid], fl->sctx);
3038 if (fl->secsctx)
3039 fastrpc_session_free(&fl->apps->channel[cid], fl->secsctx);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303040
3041 mutex_lock(&fl->perf_mutex);
3042 do {
3043 struct hlist_node *pn = NULL;
3044
3045 fperf = NULL;
3046 hlist_for_each_entry_safe(perf, pn, &fl->perf, hn) {
3047 hlist_del_init(&perf->hn);
3048 fperf = perf;
3049 break;
3050 }
3051 kfree(fperf);
3052 } while (fperf);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303053 fastrpc_remote_buf_list_free(fl);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303054 mutex_unlock(&fl->perf_mutex);
3055 mutex_destroy(&fl->perf_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303056 mutex_destroy(&fl->fl_map_mutex);
Tharun Kumar Merugu8714e642018-05-17 15:21:08 +05303057 mutex_destroy(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003058 kfree(fl);
3059 return 0;
3060}
3061
3062static int fastrpc_device_release(struct inode *inode, struct file *file)
3063{
3064 struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
3065
3066 if (fl) {
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303067 if (fl->qos_request && pm_qos_request_active(&fl->pm_qos_req))
3068 pm_qos_remove_request(&fl->pm_qos_req);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003069 if (fl->debugfs_file != NULL)
3070 debugfs_remove(fl->debugfs_file);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003071 fastrpc_file_free(fl);
c_mtharue1a5ce12017-10-13 20:47:09 +05303072 file->private_data = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003073 }
3074 return 0;
3075}
3076
3077static void fastrpc_link_state_handler(struct glink_link_state_cb_info *cb_info,
3078 void *priv)
3079{
3080 struct fastrpc_apps *me = &gfa;
3081 int cid = (int)((uintptr_t)priv);
3082 struct fastrpc_glink_info *link;
3083
3084 if (cid < 0 || cid >= NUM_CHANNELS)
3085 return;
3086
3087 link = &me->channel[cid].link;
3088 switch (cb_info->link_state) {
3089 case GLINK_LINK_STATE_UP:
3090 link->link_state = FASTRPC_LINK_STATE_UP;
3091 complete(&me->channel[cid].work);
3092 break;
3093 case GLINK_LINK_STATE_DOWN:
3094 link->link_state = FASTRPC_LINK_STATE_DOWN;
3095 break;
3096 default:
3097 pr_err("adsprpc: unknown link state %d\n", cb_info->link_state);
3098 break;
3099 }
3100}
3101
3102static int fastrpc_glink_register(int cid, struct fastrpc_apps *me)
3103{
3104 int err = 0;
3105 struct fastrpc_glink_info *link;
3106
3107 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3108 if (err)
3109 goto bail;
3110
3111 link = &me->channel[cid].link;
3112 if (link->link_notify_handle != NULL)
3113 goto bail;
3114
3115 link->link_info.glink_link_state_notif_cb = fastrpc_link_state_handler;
3116 link->link_notify_handle = glink_register_link_state_cb(
3117 &link->link_info,
3118 (void *)((uintptr_t)cid));
3119 VERIFY(err, !IS_ERR_OR_NULL(me->channel[cid].link.link_notify_handle));
3120 if (err) {
3121 link->link_notify_handle = NULL;
3122 goto bail;
3123 }
3124 VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work,
3125 RPC_TIMEOUT));
3126bail:
3127 return err;
3128}
3129
3130static void fastrpc_glink_close(void *chan, int cid)
3131{
3132 int err = 0;
3133 struct fastrpc_glink_info *link;
3134
3135 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3136 if (err)
3137 return;
3138 link = &gfa.channel[cid].link;
3139
c_mtharu314a4202017-11-15 22:09:17 +05303140 if (link->port_state == FASTRPC_LINK_CONNECTED ||
3141 link->port_state == FASTRPC_LINK_REMOTE_DISCONNECTING) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003142 link->port_state = FASTRPC_LINK_DISCONNECTING;
3143 glink_close(chan);
3144 }
3145}
3146
3147static int fastrpc_glink_open(int cid)
3148{
3149 int err = 0;
3150 void *handle = NULL;
3151 struct fastrpc_apps *me = &gfa;
3152 struct glink_open_config *cfg;
3153 struct fastrpc_glink_info *link;
3154
3155 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3156 if (err)
3157 goto bail;
3158 link = &me->channel[cid].link;
3159 cfg = &me->channel[cid].link.cfg;
3160 VERIFY(err, (link->link_state == FASTRPC_LINK_STATE_UP));
3161 if (err)
3162 goto bail;
3163
Tharun Kumar Meruguca0db5262017-05-10 12:53:12 +05303164 VERIFY(err, (link->port_state == FASTRPC_LINK_DISCONNECTED));
3165 if (err)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003166 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003167
3168 link->port_state = FASTRPC_LINK_CONNECTING;
3169 cfg->priv = (void *)(uintptr_t)cid;
3170 cfg->edge = gcinfo[cid].link.link_info.edge;
3171 cfg->transport = gcinfo[cid].link.link_info.transport;
3172 cfg->name = FASTRPC_GLINK_GUID;
3173 cfg->notify_rx = fastrpc_glink_notify_rx;
3174 cfg->notify_tx_done = fastrpc_glink_notify_tx_done;
3175 cfg->notify_state = fastrpc_glink_notify_state;
3176 cfg->notify_rx_intent_req = fastrpc_glink_notify_rx_intent_req;
3177 handle = glink_open(cfg);
3178 VERIFY(err, !IS_ERR_OR_NULL(handle));
c_mtharu6e1d26b2017-10-09 16:05:24 +05303179 if (err) {
3180 if (link->port_state == FASTRPC_LINK_CONNECTING)
3181 link->port_state = FASTRPC_LINK_DISCONNECTED;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003182 goto bail;
c_mtharu6e1d26b2017-10-09 16:05:24 +05303183 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003184 me->channel[cid].chan = handle;
3185bail:
3186 return err;
3187}
3188
Sathish Ambley1ca68232017-01-19 10:32:55 -08003189static int fastrpc_debugfs_open(struct inode *inode, struct file *filp)
3190{
3191 filp->private_data = inode->i_private;
3192 return 0;
3193}
3194
3195static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
3196 size_t count, loff_t *position)
3197{
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303198 struct fastrpc_apps *me = &gfa;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003199 struct fastrpc_file *fl = filp->private_data;
3200 struct hlist_node *n;
c_mtharue1a5ce12017-10-13 20:47:09 +05303201 struct fastrpc_buf *buf = NULL;
3202 struct fastrpc_mmap *map = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303203 struct fastrpc_mmap *gmaps = NULL;
c_mtharue1a5ce12017-10-13 20:47:09 +05303204 struct smq_invoke_ctx *ictx = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303205 struct fastrpc_channel_ctx *chan = NULL;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003206 unsigned int len = 0;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303207 int i, j, sess_used = 0, ret = 0;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003208 char *fileinfo = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303209 char single_line[UL_SIZE] = "----------------";
3210 char title[UL_SIZE] = "=========================";
Sathish Ambley1ca68232017-01-19 10:32:55 -08003211
3212 fileinfo = kzalloc(DEBUGFS_SIZE, GFP_KERNEL);
3213 if (!fileinfo)
3214 goto bail;
3215 if (fl == NULL) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303216 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3217 "\n%s %s %s\n", title, " CHANNEL INFO ", title);
3218 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3219 "%-8s|%-9s|%-9s|%-14s|%-9s|%-13s\n",
3220 "susbsys", "refcount", "sesscount", "issubsystemup",
3221 "ssrcount", "session_used");
3222 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3223 "-%s%s%s%s-\n", single_line, single_line,
3224 single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003225 for (i = 0; i < NUM_CHANNELS; i++) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303226 sess_used = 0;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003227 chan = &gcinfo[i];
3228 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303229 DEBUGFS_SIZE - len, "%-8s", chan->subsys);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003230 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303231 DEBUGFS_SIZE - len, "|%-9d",
3232 chan->kref.refcount.counter);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303233 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303234 DEBUGFS_SIZE - len, "|%-9d",
3235 chan->sesscount);
3236 len += scnprintf(fileinfo + len,
3237 DEBUGFS_SIZE - len, "|%-14d",
3238 chan->issubsystemup);
3239 len += scnprintf(fileinfo + len,
3240 DEBUGFS_SIZE - len, "|%-9d",
3241 chan->ssrcount);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003242 for (j = 0; j < chan->sesscount; j++) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303243 sess_used += chan->session[j].used;
3244 }
3245 len += scnprintf(fileinfo + len,
3246 DEBUGFS_SIZE - len, "|%-13d\n", sess_used);
3247
3248 }
3249 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3250 "\n%s%s%s\n", "=============",
3251 " CMA HEAP ", "==============");
3252 len += scnprintf(fileinfo + len,
3253 DEBUGFS_SIZE - len, "%-20s|%-20s\n", "addr", "size");
3254 len += scnprintf(fileinfo + len,
3255 DEBUGFS_SIZE - len, "--%s%s---\n",
3256 single_line, single_line);
3257 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3258 "0x%-18llX", me->range.addr);
3259 len += scnprintf(fileinfo + len,
3260 DEBUGFS_SIZE - len, "|0x%-18llX\n", me->range.size);
3261 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3262 "\n==========%s %s %s===========\n",
3263 title, " GMAPS ", title);
3264 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3265 "%-20s|%-20s|%-20s|%-20s\n",
3266 "fd", "phys", "size", "va");
3267 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3268 "%s%s%s%s%s\n", single_line, single_line,
3269 single_line, single_line, single_line);
3270 hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
3271 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3272 "%-20d|0x%-18llX|0x%-18X|0x%-20lX\n\n",
3273 gmaps->fd, gmaps->phys,
3274 (uint32_t)gmaps->size,
3275 gmaps->va);
3276 }
3277 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3278 "%-20s|%-20s|%-20s|%-20s\n",
3279 "len", "refs", "raddr", "flags");
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 "0x%-18X|%-20d|%-20lu|%-20u\n",
3286 (uint32_t)gmaps->len, gmaps->refs,
3287 gmaps->raddr, gmaps->flags);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003288 }
3289 } else {
3290 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303291 "\n%s %13s %d\n", "cid", ":", fl->cid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003292 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303293 "%s %12s %d\n", "tgid", ":", fl->tgid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003294 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303295 "%s %7s %d\n", "sessionid", ":", fl->sessionid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003296 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303297 "%s %8s %d\n", "ssrcount", ":", fl->ssrcount);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303298 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303299 "%s %8s %d\n", "refcount", ":", fl->refcount);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003300 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303301 "%s %14s %d\n", "pd", ":", fl->pd);
3302 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3303 "%s %9s %s\n", "spdname", ":", fl->spdname);
3304 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3305 "%s %6s %d\n", "file_close", ":", fl->file_close);
3306 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3307 "%s %8s %d\n", "sharedcb", ":", fl->sharedcb);
3308 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3309 "%s %9s %d\n", "profile", ":", fl->profile);
3310 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3311 "%s %3s %d\n", "smmu.coherent", ":",
3312 fl->sctx->smmu.coherent);
3313 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3314 "%s %4s %d\n", "smmu.enabled", ":",
3315 fl->sctx->smmu.enabled);
3316 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3317 "%s %9s %d\n", "smmu.cb", ":", fl->sctx->smmu.cb);
3318 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3319 "%s %5s %d\n", "smmu.secure", ":",
3320 fl->sctx->smmu.secure);
3321 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3322 "%s %5s %d\n", "smmu.faults", ":",
3323 fl->sctx->smmu.faults);
3324 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3325 "%s %s %d\n", "link.link_state",
3326 ":", *&me->channel[fl->cid].link.link_state);
3327
3328 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3329 "\n=======%s %s %s======\n", title,
3330 " LIST OF MAPS ", title);
3331
3332 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3333 "%-20s|%-20s|%-20s\n", "va", "phys", "size");
3334 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3335 "%s%s%s%s%s\n",
3336 single_line, single_line, single_line,
3337 single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003338 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303339 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3340 "0x%-20lX|0x%-20llX|0x%-20zu\n\n",
3341 map->va, map->phys,
3342 map->size);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003343 }
3344 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303345 "%-20s|%-20s|%-20s|%-20s\n",
3346 "len", "refs",
3347 "raddr", "uncached");
3348 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3349 "%s%s%s%s%s\n",
3350 single_line, single_line, single_line,
3351 single_line, single_line);
3352 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3353 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3354 "%-20zu|%-20d|0x%-20lX|%-20d\n\n",
3355 map->len, map->refs, map->raddr,
3356 map->uncached);
3357 }
3358 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3359 "%-20s|%-20s\n", "secure", "attr");
3360 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3361 "%s%s%s%s%s\n",
3362 single_line, single_line, single_line,
3363 single_line, single_line);
3364 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3365 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3366 "%-20d|0x%-20lX\n\n",
3367 map->secure, map->attr);
3368 }
3369 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303370 "%s %d\n\n",
3371 "KERNEL MEMORY ALLOCATION:", 1);
3372 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303373 "\n======%s %s %s======\n", title,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303374 " LIST OF CACHED BUFS ", title);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303375 spin_lock(&fl->hlock);
3376 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303377 "%-19s|%-19s|%-19s|%-19s\n",
3378 "virt", "phys", "size", "dma_attr");
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303379 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3380 "%s%s%s%s%s\n", single_line, single_line,
3381 single_line, single_line, single_line);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303382 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303383 len += scnprintf(fileinfo + len,
3384 DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303385 "0x%-17p|0x%-17llX|%-19zu|0x%-17lX\n",
3386 buf->virt, (uint64_t)buf->phys, buf->size,
3387 buf->dma_attr);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303388 }
3389 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3390 "\n%s %s %s\n", title,
3391 " LIST OF PENDING SMQCONTEXTS ", title);
3392
3393 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3394 "%-20s|%-10s|%-10s|%-10s|%-20s\n",
3395 "sc", "pid", "tgid", "used", "ctxid");
3396 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3397 "%s%s%s%s%s\n", single_line, single_line,
3398 single_line, single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003399 hlist_for_each_entry_safe(ictx, n, &fl->clst.pending, hn) {
3400 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303401 "0x%-18X|%-10d|%-10d|%-10zu|0x%-20llX\n\n",
3402 ictx->sc, ictx->pid, ictx->tgid,
3403 ictx->used, ictx->ctxid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003404 }
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303405
Sathish Ambley1ca68232017-01-19 10:32:55 -08003406 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303407 "\n%s %s %s\n", title,
3408 " LIST OF INTERRUPTED SMQCONTEXTS ", title);
3409
3410 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3411 "%-20s|%-10s|%-10s|%-10s|%-20s\n",
3412 "sc", "pid", "tgid", "used", "ctxid");
3413 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3414 "%s%s%s%s%s\n", single_line, single_line,
3415 single_line, single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003416 hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303417 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3418 "%-20u|%-20d|%-20d|%-20zu|0x%-20llX\n\n",
3419 ictx->sc, ictx->pid, ictx->tgid,
3420 ictx->used, ictx->ctxid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003421 }
3422 spin_unlock(&fl->hlock);
3423 }
3424 if (len > DEBUGFS_SIZE)
3425 len = DEBUGFS_SIZE;
3426 ret = simple_read_from_buffer(buffer, count, position, fileinfo, len);
3427 kfree(fileinfo);
3428bail:
3429 return ret;
3430}
3431
3432static const struct file_operations debugfs_fops = {
3433 .open = fastrpc_debugfs_open,
3434 .read = fastrpc_debugfs_read,
3435};
Sathish Ambley36849af2017-02-02 09:35:55 -08003436static int fastrpc_channel_open(struct fastrpc_file *fl)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003437{
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003438 struct fastrpc_apps *me = &gfa;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303439 int cid = -1, ii, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003440
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303441 mutex_lock(&me->smd_mutex);
3442
Sathish Ambley36849af2017-02-02 09:35:55 -08003443 VERIFY(err, fl && fl->sctx);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003444 if (err)
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303445 goto bail;
Sathish Ambley36849af2017-02-02 09:35:55 -08003446 cid = fl->cid;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303447 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
3448 if (err) {
3449 err = -ECHRNG;
c_mtharu314a4202017-11-15 22:09:17 +05303450 goto bail;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303451 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303452 if (me->channel[cid].ssrcount !=
3453 me->channel[cid].prevssrcount) {
3454 if (!me->channel[cid].issubsystemup) {
3455 VERIFY(err, 0);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303456 if (err) {
3457 err = -ENOTCONN;
c_mtharue1a5ce12017-10-13 20:47:09 +05303458 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303459 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303460 }
3461 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003462 fl->ssrcount = me->channel[cid].ssrcount;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303463 fl->refcount = 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003464 if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) ||
c_mtharue1a5ce12017-10-13 20:47:09 +05303465 (me->channel[cid].chan == NULL)) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303466 if (me->glink) {
3467 VERIFY(err, 0 == fastrpc_glink_register(cid, me));
3468 if (err)
3469 goto bail;
3470 VERIFY(err, 0 == fastrpc_glink_open(cid));
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303471 VERIFY(err,
3472 wait_for_completion_timeout(&me->channel[cid].workport,
3473 RPC_TIMEOUT));
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303474 } else {
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303475 if (me->channel[cid].chan == NULL) {
3476 VERIFY(err, !smd_named_open_on_edge(
3477 FASTRPC_SMD_GUID,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303478 gcinfo[cid].channel,
3479 (smd_channel_t **)&me->channel[cid].chan,
3480 (void *)(uintptr_t)cid,
3481 smd_event_handler));
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05303482 VERIFY(err,
3483 wait_for_completion_timeout(&me->channel[cid].workport,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003484 RPC_TIMEOUT));
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303485
3486 }
3487 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003488 if (err) {
c_mtharue1a5ce12017-10-13 20:47:09 +05303489 me->channel[cid].chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003490 goto bail;
3491 }
3492 kref_init(&me->channel[cid].kref);
3493 pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name,
3494 MAJOR(me->dev_no), cid);
Tharun Kumar Meruguc42c6e22018-05-29 15:50:46 +05303495
3496 for (ii = 0; ii < FASTRPC_GLINK_INTENT_NUM && me->glink; ii++)
3497 glink_queue_rx_intent(me->channel[cid].chan, NULL,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303498 FASTRPC_GLINK_INTENT_LEN);
Tharun Kumar Meruguc42c6e22018-05-29 15:50:46 +05303499
Tharun Kumar Merugud86fc8c2018-01-04 16:35:31 +05303500 if (cid == 0 && me->channel[cid].ssrcount !=
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003501 me->channel[cid].prevssrcount) {
c_mtharue1a5ce12017-10-13 20:47:09 +05303502 if (fastrpc_mmap_remove_ssr(fl))
3503 pr_err("ADSPRPC: SSR: Failed to unmap remote heap\n");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003504 me->channel[cid].prevssrcount =
3505 me->channel[cid].ssrcount;
3506 }
3507 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003508
3509bail:
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303510 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003511 return err;
3512}
3513
Sathish Ambley36849af2017-02-02 09:35:55 -08003514static int fastrpc_device_open(struct inode *inode, struct file *filp)
3515{
3516 int err = 0;
Sathish Ambley567012b2017-03-06 11:55:04 -08003517 struct dentry *debugfs_file;
c_mtharue1a5ce12017-10-13 20:47:09 +05303518 struct fastrpc_file *fl = NULL;
Sathish Ambley36849af2017-02-02 09:35:55 -08003519 struct fastrpc_apps *me = &gfa;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303520 char strpid[PID_SIZE];
3521 int buf_size = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003522
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303523 /*
3524 * Indicates the device node opened
3525 * MINOR_NUM_DEV or MINOR_NUM_SECURE_DEV
3526 */
3527 int dev_minor = MINOR(inode->i_rdev);
3528
3529 VERIFY(err, ((dev_minor == MINOR_NUM_DEV) ||
3530 (dev_minor == MINOR_NUM_SECURE_DEV)));
3531 if (err) {
3532 pr_err("adsprpc: Invalid dev minor num %d\n", dev_minor);
3533 return err;
3534 }
3535
c_mtharue1a5ce12017-10-13 20:47:09 +05303536 VERIFY(err, NULL != (fl = kzalloc(sizeof(*fl), GFP_KERNEL)));
Sathish Ambley36849af2017-02-02 09:35:55 -08003537 if (err)
3538 return err;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303539 snprintf(strpid, PID_SIZE, "%d", current->pid);
Mohammed Nayeem Ur Rahman2d65b4a2018-10-10 16:34:37 +05303540 buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303541 fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
3542 snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
3543 current->comm, "_", current->pid);
3544 debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
3545 debugfs_root, fl, &debugfs_fops);
3546
Sathish Ambley36849af2017-02-02 09:35:55 -08003547 context_list_ctor(&fl->clst);
3548 spin_lock_init(&fl->hlock);
3549 INIT_HLIST_HEAD(&fl->maps);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303550 INIT_HLIST_HEAD(&fl->perf);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303551 INIT_HLIST_HEAD(&fl->cached_bufs);
3552 INIT_HLIST_HEAD(&fl->remote_bufs);
Sathish Ambley36849af2017-02-02 09:35:55 -08003553 INIT_HLIST_NODE(&fl->hn);
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05303554 fl->sessionid = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003555 fl->tgid = current->tgid;
3556 fl->apps = me;
3557 fl->mode = FASTRPC_MODE_SERIAL;
3558 fl->cid = -1;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303559 fl->dev_minor = dev_minor;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303560 fl->init_mem = NULL;
Sathish Ambley567012b2017-03-06 11:55:04 -08003561 if (debugfs_file != NULL)
3562 fl->debugfs_file = debugfs_file;
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);
Sathish Ambley36849af2017-02-02 09:35:55 -08003572 return 0;
3573}
3574
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003575static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
3576{
3577 int err = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003578 uint32_t cid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003579
c_mtharue1a5ce12017-10-13 20:47:09 +05303580 VERIFY(err, fl != NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003581 if (err)
3582 goto bail;
Sathish Ambley36849af2017-02-02 09:35:55 -08003583 if (fl->cid == -1) {
3584 cid = *info;
3585 VERIFY(err, cid < NUM_CHANNELS);
3586 if (err)
3587 goto bail;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303588 /* Check to see if the device node is non-secure */
zhaochenfc798572018-08-17 15:32:37 +08003589 if (fl->dev_minor == MINOR_NUM_DEV &&
3590 fl->apps->secure_flag == true) {
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303591 /*
3592 * For non secure device node check and make sure that
3593 * the channel allows non-secure access
3594 * If not, bail. Session will not start.
3595 * cid will remain -1 and client will not be able to
3596 * invoke any other methods without failure
3597 */
3598 if (fl->apps->channel[cid].secure == SECURE_CHANNEL) {
3599 err = -EPERM;
3600 pr_err("adsprpc: GetInfo failed dev %d, cid %d, secure %d\n",
3601 fl->dev_minor, cid,
3602 fl->apps->channel[cid].secure);
3603 goto bail;
3604 }
3605 }
Sathish Ambley36849af2017-02-02 09:35:55 -08003606 fl->cid = cid;
3607 fl->ssrcount = fl->apps->channel[cid].ssrcount;
3608 VERIFY(err, !fastrpc_session_alloc_locked(
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303609 &fl->apps->channel[cid], 0, fl->sharedcb, &fl->sctx));
Sathish Ambley36849af2017-02-02 09:35:55 -08003610 if (err)
3611 goto bail;
3612 }
Tharun Kumar Merugu80be7d62017-08-02 11:03:22 +05303613 VERIFY(err, fl->sctx != NULL);
3614 if (err)
3615 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003616 *info = (fl->sctx->smmu.enabled ? 1 : 0);
3617bail:
3618 return err;
3619}
3620
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303621static int fastrpc_internal_control(struct fastrpc_file *fl,
3622 struct fastrpc_ioctl_control *cp)
3623{
Mohammed Nayeem Ur Rahman18d633f2019-05-28 15:11:40 +05303624 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303625 int err = 0;
3626 int latency;
3627
3628 VERIFY(err, !IS_ERR_OR_NULL(fl) && !IS_ERR_OR_NULL(fl->apps));
3629 if (err)
3630 goto bail;
3631 VERIFY(err, !IS_ERR_OR_NULL(cp));
3632 if (err)
3633 goto bail;
3634
3635 switch (cp->req) {
3636 case FASTRPC_CONTROL_LATENCY:
3637 latency = cp->lp.enable == FASTRPC_LATENCY_CTRL_ENB ?
3638 fl->apps->latency : PM_QOS_DEFAULT_VALUE;
3639 VERIFY(err, latency != 0);
3640 if (err)
3641 goto bail;
3642 if (!fl->qos_request) {
3643 pm_qos_add_request(&fl->pm_qos_req,
3644 PM_QOS_CPU_DMA_LATENCY, latency);
3645 fl->qos_request = 1;
3646 } else
3647 pm_qos_update_request(&fl->pm_qos_req, latency);
3648 break;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303649 case FASTRPC_CONTROL_SMMU:
Mohammed Nayeem Ur Rahman18d633f2019-05-28 15:11:40 +05303650 if (!me->legacy)
3651 fl->sharedcb = cp->smmu.sharedcb;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303652 break;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303653 case FASTRPC_CONTROL_KALLOC:
3654 cp->kalloc.kalloc_support = 1;
3655 break;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303656 default:
3657 err = -ENOTTY;
3658 break;
3659 }
3660bail:
3661 return err;
3662}
3663
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003664static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
3665 unsigned long ioctl_param)
3666{
3667 union {
Sathish Ambleybae51902017-07-03 15:00:49 -07003668 struct fastrpc_ioctl_invoke_crc inv;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003669 struct fastrpc_ioctl_mmap mmap;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303670 struct fastrpc_ioctl_mmap_64 mmap64;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003671 struct fastrpc_ioctl_munmap munmap;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303672 struct fastrpc_ioctl_munmap_64 munmap64;
c_mtharu7bd6a422017-10-17 18:15:37 +05303673 struct fastrpc_ioctl_munmap_fd munmap_fd;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08003674 struct fastrpc_ioctl_init_attrs init;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003675 struct fastrpc_ioctl_perf perf;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303676 struct fastrpc_ioctl_control cp;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003677 } p;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303678 union {
3679 struct fastrpc_ioctl_mmap mmap;
3680 struct fastrpc_ioctl_munmap munmap;
3681 } i;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003682 void *param = (char *)ioctl_param;
3683 struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
3684 int size = 0, err = 0;
3685 uint32_t info;
3686
c_mtharue1a5ce12017-10-13 20:47:09 +05303687 p.inv.fds = NULL;
3688 p.inv.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07003689 p.inv.crc = NULL;
tharun kumar9f899ea2017-07-03 17:07:03 +05303690 spin_lock(&fl->hlock);
3691 if (fl->file_close == 1) {
3692 err = EBADF;
3693 pr_warn("ADSPRPC: fastrpc_device_release is happening, So not sending any new requests to DSP");
3694 spin_unlock(&fl->hlock);
3695 goto bail;
3696 }
3697 spin_unlock(&fl->hlock);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003698
3699 switch (ioctl_num) {
3700 case FASTRPC_IOCTL_INVOKE:
3701 size = sizeof(struct fastrpc_ioctl_invoke);
Sathish Ambleybae51902017-07-03 15:00:49 -07003702 /* fall through */
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003703 case FASTRPC_IOCTL_INVOKE_FD:
3704 if (!size)
3705 size = sizeof(struct fastrpc_ioctl_invoke_fd);
3706 /* fall through */
3707 case FASTRPC_IOCTL_INVOKE_ATTRS:
3708 if (!size)
3709 size = sizeof(struct fastrpc_ioctl_invoke_attrs);
Sathish Ambleybae51902017-07-03 15:00:49 -07003710 /* fall through */
3711 case FASTRPC_IOCTL_INVOKE_CRC:
3712 if (!size)
3713 size = sizeof(struct fastrpc_ioctl_invoke_crc);
c_mtharue1a5ce12017-10-13 20:47:09 +05303714 K_COPY_FROM_USER(err, 0, &p.inv, param, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003715 if (err)
3716 goto bail;
3717 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode,
3718 0, &p.inv)));
3719 if (err)
3720 goto bail;
3721 break;
3722 case FASTRPC_IOCTL_MMAP:
c_mtharue1a5ce12017-10-13 20:47:09 +05303723 K_COPY_FROM_USER(err, 0, &p.mmap, param,
3724 sizeof(p.mmap));
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05303725 if (err)
3726 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003727 VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap)));
3728 if (err)
3729 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05303730 K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003731 if (err)
3732 goto bail;
3733 break;
3734 case FASTRPC_IOCTL_MUNMAP:
c_mtharue1a5ce12017-10-13 20:47:09 +05303735 K_COPY_FROM_USER(err, 0, &p.munmap, param,
3736 sizeof(p.munmap));
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05303737 if (err)
3738 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003739 VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
3740 &p.munmap)));
3741 if (err)
3742 goto bail;
3743 break;
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303744 case FASTRPC_IOCTL_MMAP_64:
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303745 K_COPY_FROM_USER(err, 0, &p.mmap64, param,
3746 sizeof(p.mmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303747 if (err)
3748 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303749 get_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
3750 VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &i.mmap)));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303751 if (err)
3752 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303753 put_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
3754 K_COPY_TO_USER(err, 0, param, &p.mmap64, sizeof(p.mmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303755 if (err)
3756 goto bail;
3757 break;
3758 case FASTRPC_IOCTL_MUNMAP_64:
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303759 K_COPY_FROM_USER(err, 0, &p.munmap64, param,
3760 sizeof(p.munmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303761 if (err)
3762 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303763 get_fastrpc_ioctl_munmap_64(&p.munmap64, &i.munmap);
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303764 VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303765 &i.munmap)));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303766 if (err)
3767 goto bail;
3768 break;
c_mtharu7bd6a422017-10-17 18:15:37 +05303769 case FASTRPC_IOCTL_MUNMAP_FD:
3770 K_COPY_FROM_USER(err, 0, &p.munmap_fd, param,
3771 sizeof(p.munmap_fd));
3772 if (err)
3773 goto bail;
3774 VERIFY(err, 0 == (err = fastrpc_internal_munmap_fd(fl,
3775 &p.munmap_fd)));
3776 if (err)
3777 goto bail;
3778 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003779 case FASTRPC_IOCTL_SETMODE:
3780 switch ((uint32_t)ioctl_param) {
3781 case FASTRPC_MODE_PARALLEL:
3782 case FASTRPC_MODE_SERIAL:
3783 fl->mode = (uint32_t)ioctl_param;
3784 break;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003785 case FASTRPC_MODE_PROFILE:
3786 fl->profile = (uint32_t)ioctl_param;
3787 break;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05303788 case FASTRPC_MODE_SESSION:
3789 fl->sessionid = 1;
3790 fl->tgid |= (1 << SESSION_ID_INDEX);
3791 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003792 default:
3793 err = -ENOTTY;
3794 break;
3795 }
3796 break;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003797 case FASTRPC_IOCTL_GETPERF:
c_mtharue1a5ce12017-10-13 20:47:09 +05303798 K_COPY_FROM_USER(err, 0, &p.perf,
3799 param, sizeof(p.perf));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003800 if (err)
3801 goto bail;
3802 p.perf.numkeys = sizeof(struct fastrpc_perf)/sizeof(int64_t);
3803 if (p.perf.keys) {
3804 char *keys = PERF_KEYS;
3805
c_mtharue1a5ce12017-10-13 20:47:09 +05303806 K_COPY_TO_USER(err, 0, (void *)p.perf.keys,
3807 keys, strlen(keys)+1);
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003808 if (err)
3809 goto bail;
3810 }
3811 if (p.perf.data) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303812 struct fastrpc_perf *perf = NULL, *fperf = NULL;
3813 struct hlist_node *n = NULL;
3814
3815 mutex_lock(&fl->perf_mutex);
3816 hlist_for_each_entry_safe(perf, n, &fl->perf, hn) {
3817 if (perf->tid == current->pid) {
3818 fperf = perf;
3819 break;
3820 }
3821 }
3822
3823 mutex_unlock(&fl->perf_mutex);
3824
3825 if (fperf) {
3826 K_COPY_TO_USER(err, 0, (void *)p.perf.data,
3827 fperf, sizeof(*fperf));
3828 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003829 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303830 K_COPY_TO_USER(err, 0, param, &p.perf, sizeof(p.perf));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003831 if (err)
3832 goto bail;
3833 break;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303834 case FASTRPC_IOCTL_CONTROL:
c_mtharue1a5ce12017-10-13 20:47:09 +05303835 K_COPY_FROM_USER(err, 0, &p.cp, param,
3836 sizeof(p.cp));
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303837 if (err)
3838 goto bail;
3839 VERIFY(err, 0 == (err = fastrpc_internal_control(fl, &p.cp)));
3840 if (err)
3841 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303842 if (p.cp.req == FASTRPC_CONTROL_KALLOC) {
3843 K_COPY_TO_USER(err, 0, param, &p.cp, sizeof(p.cp));
3844 if (err)
3845 goto bail;
3846 }
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303847 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003848 case FASTRPC_IOCTL_GETINFO:
c_mtharue1a5ce12017-10-13 20:47:09 +05303849 K_COPY_FROM_USER(err, 0, &info, param, sizeof(info));
Sathish Ambley36849af2017-02-02 09:35:55 -08003850 if (err)
3851 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003852 VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info)));
3853 if (err)
3854 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05303855 K_COPY_TO_USER(err, 0, param, &info, sizeof(info));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003856 if (err)
3857 goto bail;
3858 break;
3859 case FASTRPC_IOCTL_INIT:
Sathish Ambleyd6300c32017-01-18 09:50:43 -08003860 p.init.attrs = 0;
3861 p.init.siglen = 0;
3862 size = sizeof(struct fastrpc_ioctl_init);
3863 /* fall through */
3864 case FASTRPC_IOCTL_INIT_ATTRS:
3865 if (!size)
3866 size = sizeof(struct fastrpc_ioctl_init_attrs);
c_mtharue1a5ce12017-10-13 20:47:09 +05303867 K_COPY_FROM_USER(err, 0, &p.init, param, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003868 if (err)
3869 goto bail;
Tharun Kumar Merugu4ea0eac2017-08-22 11:42:51 +05303870 VERIFY(err, p.init.init.filelen >= 0 &&
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05303871 p.init.init.filelen < INIT_FILELEN_MAX);
3872 if (err)
3873 goto bail;
3874 VERIFY(err, p.init.init.memlen >= 0 &&
3875 p.init.init.memlen < INIT_MEMLEN_MAX);
Tharun Kumar Merugu4ea0eac2017-08-22 11:42:51 +05303876 if (err)
3877 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303878 VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003879 if (err)
3880 goto bail;
3881 break;
3882
3883 default:
3884 err = -ENOTTY;
3885 pr_info("bad ioctl: %d\n", ioctl_num);
3886 break;
3887 }
3888 bail:
3889 return err;
3890}
3891
3892static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
3893 unsigned long code,
3894 void *data)
3895{
3896 struct fastrpc_apps *me = &gfa;
3897 struct fastrpc_channel_ctx *ctx;
c_mtharue1a5ce12017-10-13 20:47:09 +05303898 struct notif_data *notifdata = data;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003899 int cid;
3900
3901 ctx = container_of(nb, struct fastrpc_channel_ctx, nb);
3902 cid = ctx - &me->channel[0];
3903 if (code == SUBSYS_BEFORE_SHUTDOWN) {
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303904 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003905 ctx->ssrcount++;
c_mtharue1a5ce12017-10-13 20:47:09 +05303906 ctx->issubsystemup = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303907 if (ctx->chan) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303908 if (me->glink)
3909 fastrpc_glink_close(ctx->chan, cid);
3910 else
3911 smd_close(ctx->chan);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303912 ctx->chan = NULL;
3913 pr_info("'restart notifier: closed /dev/%s c %d %d'\n",
3914 gcinfo[cid].name, MAJOR(me->dev_no), cid);
3915 }
3916 mutex_unlock(&me->smd_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05303917 if (cid == 0)
3918 me->staticpd_flags = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003919 fastrpc_notify_drivers(me, cid);
c_mtharue1a5ce12017-10-13 20:47:09 +05303920 } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) {
3921 if (me->channel[0].remoteheap_ramdump_dev &&
3922 notifdata->enable_ramdump) {
3923 me->channel[0].ramdumpenabled = 1;
3924 }
3925 } else if (code == SUBSYS_AFTER_POWERUP) {
3926 ctx->issubsystemup = 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003927 }
3928
3929 return NOTIFY_DONE;
3930}
3931
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303932static int fastrpc_pdr_notifier_cb(struct notifier_block *pdrnb,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05303933 unsigned long code,
3934 void *data)
3935{
3936 struct fastrpc_apps *me = &gfa;
3937 struct fastrpc_static_pd *spd;
3938 struct notif_data *notifdata = data;
3939
3940 spd = container_of(pdrnb, struct fastrpc_static_pd, pdrnb);
3941 if (code == SERVREG_NOTIF_SERVICE_STATE_DOWN_V01) {
3942 mutex_lock(&me->smd_mutex);
3943 spd->pdrcount++;
3944 spd->ispdup = 0;
3945 pr_info("ADSPRPC: Audio PDR notifier %d %s\n",
3946 MAJOR(me->dev_no), spd->spdname);
3947 mutex_unlock(&me->smd_mutex);
3948 if (!strcmp(spd->spdname,
3949 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME))
3950 me->staticpd_flags = 0;
3951 fastrpc_notify_pdr_drivers(me, spd->spdname);
3952 } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) {
3953 if (me->channel[0].remoteheap_ramdump_dev &&
3954 notifdata->enable_ramdump) {
3955 me->channel[0].ramdumpenabled = 1;
3956 }
3957 } else if (code == SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
3958 spd->ispdup = 1;
3959 }
3960
3961 return NOTIFY_DONE;
3962}
3963
3964static int fastrpc_get_service_location_notify(struct notifier_block *nb,
3965 unsigned long opcode, void *data)
3966{
3967 struct fastrpc_static_pd *spd;
3968 struct pd_qmi_client_data *pdr = data;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303969 int curr_state = 0, i = 0;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05303970
3971 spd = container_of(nb, struct fastrpc_static_pd, get_service_nb);
3972 if (opcode == LOCATOR_DOWN) {
3973 pr_err("ADSPRPC: Audio PD restart notifier locator down\n");
3974 return NOTIFY_DONE;
3975 }
3976
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303977 for (i = 0; i < pdr->total_domains; i++) {
3978 if ((!strcmp(pdr->domain_list[i].name,
3979 "msm/adsp/audio_pd")) ||
3980 (!strcmp(pdr->domain_list[i].name,
3981 "msm/adsp/sensor_pd"))) {
3982 spd->pdrhandle =
3983 service_notif_register_notifier(
3984 pdr->domain_list[i].name,
3985 pdr->domain_list[i].instance_id,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05303986 &spd->pdrnb, &curr_state);
Tharun Kumar Meruguad4beb82018-05-10 19:51:48 +05303987 if (IS_ERR(spd->pdrhandle)) {
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303988 pr_err("ADSPRPC: Unable to register notifier\n");
Tharun Kumar Meruguad4beb82018-05-10 19:51:48 +05303989 } else if (curr_state ==
3990 SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
3991 pr_info("ADSPRPC: STATE_UP_V01 received\n");
3992 spd->ispdup = 1;
3993 } else if (curr_state ==
3994 SERVREG_NOTIF_SERVICE_STATE_UNINIT_V01) {
3995 pr_info("ADSPRPC: STATE_UNINIT_V01 received\n");
3996 }
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303997 break;
3998 }
3999 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304000
4001 return NOTIFY_DONE;
4002}
4003
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004004static const struct file_operations fops = {
4005 .open = fastrpc_device_open,
4006 .release = fastrpc_device_release,
4007 .unlocked_ioctl = fastrpc_device_ioctl,
4008 .compat_ioctl = compat_fastrpc_device_ioctl,
4009};
4010
4011static const struct of_device_id fastrpc_match_table[] = {
4012 { .compatible = "qcom,msm-fastrpc-adsp", },
4013 { .compatible = "qcom,msm-fastrpc-compute", },
4014 { .compatible = "qcom,msm-fastrpc-compute-cb", },
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304015 { .compatible = "qcom,msm-fastrpc-legacy-compute", },
4016 { .compatible = "qcom,msm-fastrpc-legacy-compute-cb", },
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004017 { .compatible = "qcom,msm-adsprpc-mem-region", },
4018 {}
4019};
4020
4021static int fastrpc_cb_probe(struct device *dev)
4022{
4023 struct fastrpc_channel_ctx *chan;
4024 struct fastrpc_session_ctx *sess;
4025 struct of_phandle_args iommuspec;
4026 const char *name;
4027 unsigned int start = 0x80000000;
4028 int err = 0, i;
4029 int secure_vmid = VMID_CP_PIXEL;
4030
c_mtharue1a5ce12017-10-13 20:47:09 +05304031 VERIFY(err, NULL != (name = of_get_property(dev->of_node,
4032 "label", NULL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004033 if (err)
4034 goto bail;
4035 for (i = 0; i < NUM_CHANNELS; i++) {
4036 if (!gcinfo[i].name)
4037 continue;
4038 if (!strcmp(name, gcinfo[i].name))
4039 break;
4040 }
4041 VERIFY(err, i < NUM_CHANNELS);
4042 if (err)
4043 goto bail;
4044 chan = &gcinfo[i];
4045 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4046 if (err)
4047 goto bail;
4048
4049 VERIFY(err, !of_parse_phandle_with_args(dev->of_node, "iommus",
4050 "#iommu-cells", 0, &iommuspec));
4051 if (err)
4052 goto bail;
4053 sess = &chan->session[chan->sesscount];
4054 sess->smmu.cb = iommuspec.args[0] & 0xf;
4055 sess->used = 0;
4056 sess->smmu.coherent = of_property_read_bool(dev->of_node,
4057 "dma-coherent");
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304058 sess->smmu.sharedcb = of_property_read_bool(dev->of_node,
4059 "shared-cb");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004060 sess->smmu.secure = of_property_read_bool(dev->of_node,
4061 "qcom,secure-context-bank");
4062 if (sess->smmu.secure)
4063 start = 0x60000000;
4064 VERIFY(err, !IS_ERR_OR_NULL(sess->smmu.mapping =
4065 arm_iommu_create_mapping(&platform_bus_type,
Tharun Kumar Meruguca183f92017-04-27 17:43:27 +05304066 start, 0x78000000)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004067 if (err)
4068 goto bail;
4069
4070 if (sess->smmu.secure)
4071 iommu_domain_set_attr(sess->smmu.mapping->domain,
4072 DOMAIN_ATTR_SECURE_VMID,
4073 &secure_vmid);
4074
4075 VERIFY(err, !arm_iommu_attach_device(dev, sess->smmu.mapping));
4076 if (err)
4077 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05304078 sess->smmu.dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004079 sess->smmu.enabled = 1;
4080 chan->sesscount++;
Sathish Ambley1ca68232017-01-19 10:32:55 -08004081 debugfs_global_file = debugfs_create_file("global", 0644, debugfs_root,
4082 NULL, &debugfs_fops);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004083bail:
4084 return err;
4085}
4086
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304087static int fastrpc_cb_legacy_probe(struct device *dev)
4088{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304089 struct fastrpc_channel_ctx *chan;
4090 struct fastrpc_session_ctx *first_sess = NULL, *sess = NULL;
4091 const char *name;
4092 unsigned int *sids = NULL, sids_size = 0;
4093 int err = 0, ret = 0, i;
4094
4095 unsigned int start = 0x80000000;
4096
4097 VERIFY(err, NULL != (name = of_get_property(dev->of_node,
4098 "label", NULL)));
4099 if (err)
4100 goto bail;
4101
4102 for (i = 0; i < NUM_CHANNELS; i++) {
4103 if (!gcinfo[i].name)
4104 continue;
4105 if (!strcmp(name, gcinfo[i].name))
4106 break;
4107 }
4108 VERIFY(err, i < NUM_CHANNELS);
4109 if (err)
4110 goto bail;
4111
4112 chan = &gcinfo[i];
4113 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4114 if (err)
4115 goto bail;
4116
4117 first_sess = &chan->session[chan->sesscount];
4118
4119 VERIFY(err, NULL != of_get_property(dev->of_node,
4120 "sids", &sids_size));
4121 if (err)
4122 goto bail;
4123
4124 VERIFY(err, NULL != (sids = kzalloc(sids_size, GFP_KERNEL)));
4125 if (err)
4126 goto bail;
4127 ret = of_property_read_u32_array(dev->of_node, "sids", sids,
4128 sids_size/sizeof(unsigned int));
4129 if (ret)
4130 goto bail;
4131
4132 VERIFY(err, !IS_ERR_OR_NULL(first_sess->smmu.mapping =
4133 arm_iommu_create_mapping(&platform_bus_type,
4134 start, 0x78000000)));
4135 if (err)
4136 goto bail;
4137
4138 VERIFY(err, !arm_iommu_attach_device(dev, first_sess->smmu.mapping));
4139 if (err)
4140 goto bail;
4141
4142
4143 for (i = 0; i < sids_size/sizeof(unsigned int); i++) {
4144 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4145 if (err)
4146 goto bail;
4147 sess = &chan->session[chan->sesscount];
4148 sess->smmu.cb = sids[i];
4149 sess->smmu.dev = dev;
4150 sess->smmu.mapping = first_sess->smmu.mapping;
4151 sess->smmu.enabled = 1;
4152 sess->used = 0;
4153 sess->smmu.coherent = false;
4154 sess->smmu.secure = false;
4155 chan->sesscount++;
4156 }
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304157bail:
4158 kfree(sids);
4159 return err;
4160}
4161
4162
4163
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304164static void init_secure_vmid_list(struct device *dev, char *prop_name,
4165 struct secure_vm *destvm)
4166{
4167 int err = 0;
4168 u32 len = 0, i = 0;
4169 u32 *rhvmlist = NULL;
4170 u32 *rhvmpermlist = NULL;
4171
4172 if (!of_find_property(dev->of_node, prop_name, &len))
4173 goto bail;
4174 if (len == 0)
4175 goto bail;
4176 len /= sizeof(u32);
4177 VERIFY(err, NULL != (rhvmlist = kcalloc(len, sizeof(u32), GFP_KERNEL)));
4178 if (err)
4179 goto bail;
4180 VERIFY(err, NULL != (rhvmpermlist = kcalloc(len, sizeof(u32),
4181 GFP_KERNEL)));
4182 if (err)
4183 goto bail;
4184 for (i = 0; i < len; i++) {
4185 err = of_property_read_u32_index(dev->of_node, prop_name, i,
4186 &rhvmlist[i]);
4187 rhvmpermlist[i] = PERM_READ | PERM_WRITE | PERM_EXEC;
4188 pr_info("ADSPRPC: Secure VMID = %d", rhvmlist[i]);
4189 if (err) {
4190 pr_err("ADSPRPC: Failed to read VMID\n");
4191 goto bail;
4192 }
4193 }
4194 destvm->vmid = rhvmlist;
4195 destvm->vmperm = rhvmpermlist;
4196 destvm->vmcount = len;
4197bail:
4198 if (err) {
4199 kfree(rhvmlist);
4200 kfree(rhvmpermlist);
4201 }
4202}
4203
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304204static void configure_secure_channels(uint32_t secure_domains)
4205{
4206 struct fastrpc_apps *me = &gfa;
4207 int ii = 0;
4208 /*
4209 * secure_domains contains the bitmask of the secure channels
4210 * Bit 0 - ADSP
4211 * Bit 1 - MDSP
4212 * Bit 2 - SLPI
4213 * Bit 3 - CDSP
4214 */
4215 for (ii = ADSP_DOMAIN_ID; ii <= CDSP_DOMAIN_ID; ++ii) {
4216 int secure = (secure_domains >> ii) & 0x01;
4217
4218 me->channel[ii].secure = secure;
4219 }
4220}
4221
4222
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004223static int fastrpc_probe(struct platform_device *pdev)
4224{
4225 int err = 0;
4226 struct fastrpc_apps *me = &gfa;
4227 struct device *dev = &pdev->dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004228 struct device_node *ion_node, *node;
4229 struct platform_device *ion_pdev;
4230 struct cma *cma;
4231 uint32_t val;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304232 int ret = 0;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304233 uint32_t secure_domains;
c_mtharu63ffc012017-11-16 15:26:56 +05304234
4235 if (of_device_is_compatible(dev->of_node,
4236 "qcom,msm-fastrpc-compute")) {
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304237 init_secure_vmid_list(dev, "qcom,adsp-remoteheap-vmid",
4238 &gcinfo[0].rhvm);
c_mtharu63ffc012017-11-16 15:26:56 +05304239
c_mtharu63ffc012017-11-16 15:26:56 +05304240
4241 of_property_read_u32(dev->of_node, "qcom,rpc-latency-us",
4242 &me->latency);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304243 if (of_get_property(dev->of_node,
4244 "qcom,secure-domains", NULL) != NULL) {
4245 VERIFY(err, !of_property_read_u32(dev->of_node,
4246 "qcom,secure-domains",
4247 &secure_domains));
zhaochenfc798572018-08-17 15:32:37 +08004248 if (!err) {
4249 me->secure_flag = true;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304250 configure_secure_channels(secure_domains);
zhaochenfc798572018-08-17 15:32:37 +08004251 } else {
4252 me->secure_flag = false;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304253 pr_info("adsprpc: unable to read the domain configuration from dts\n");
zhaochenfc798572018-08-17 15:32:37 +08004254 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304255 }
c_mtharu63ffc012017-11-16 15:26:56 +05304256 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004257 if (of_device_is_compatible(dev->of_node,
4258 "qcom,msm-fastrpc-compute-cb"))
4259 return fastrpc_cb_probe(dev);
4260
4261 if (of_device_is_compatible(dev->of_node,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304262 "qcom,msm-fastrpc-legacy-compute")) {
4263 me->glink = false;
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304264 me->legacy = 1;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304265 }
4266
4267 if (of_device_is_compatible(dev->of_node,
4268 "qcom,msm-fastrpc-legacy-compute-cb")){
4269 return fastrpc_cb_legacy_probe(dev);
4270 }
4271
4272 if (of_device_is_compatible(dev->of_node,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004273 "qcom,msm-adsprpc-mem-region")) {
4274 me->dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004275 ion_node = of_find_compatible_node(NULL, NULL, "qcom,msm-ion");
4276 if (ion_node) {
4277 for_each_available_child_of_node(ion_node, node) {
4278 if (of_property_read_u32(node, "reg", &val))
4279 continue;
4280 if (val != ION_ADSP_HEAP_ID)
4281 continue;
4282 ion_pdev = of_find_device_by_node(node);
4283 if (!ion_pdev)
4284 break;
4285 cma = dev_get_cma_area(&ion_pdev->dev);
4286 if (cma) {
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304287 me->range.addr = cma_get_base(cma);
4288 me->range.size =
4289 (size_t)cma_get_size(cma);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004290 }
4291 break;
4292 }
4293 }
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304294 if (me->range.addr && !of_property_read_bool(dev->of_node,
Tharun Kumar Merugu6b7a4a22018-01-17 16:08:07 +05304295 "restrict-access")) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004296 int srcVM[1] = {VMID_HLOS};
4297 int destVM[4] = {VMID_HLOS, VMID_MSS_MSA, VMID_SSC_Q6,
4298 VMID_ADSP_Q6};
Sathish Ambley84d11862017-05-15 14:36:05 -07004299 int destVMperm[4] = {PERM_READ | PERM_WRITE | PERM_EXEC,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004300 PERM_READ | PERM_WRITE | PERM_EXEC,
4301 PERM_READ | PERM_WRITE | PERM_EXEC,
4302 PERM_READ | PERM_WRITE | PERM_EXEC,
4303 };
4304
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304305 VERIFY(err, !hyp_assign_phys(me->range.addr,
4306 me->range.size, srcVM, 1,
4307 destVM, destVMperm, 4));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004308 if (err)
4309 goto bail;
4310 }
4311 return 0;
4312 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304313 if (of_property_read_bool(dev->of_node,
4314 "qcom,fastrpc-adsp-audio-pdr")) {
4315 int session;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004316
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304317 VERIFY(err, !fastrpc_get_adsp_session(
4318 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
4319 if (err)
4320 goto spdbail;
4321 me->channel[0].spd[session].get_service_nb.notifier_call =
4322 fastrpc_get_service_location_notify;
4323 ret = get_service_location(
4324 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
4325 AUDIO_PDR_ADSP_SERVICE_NAME,
4326 &me->channel[0].spd[session].get_service_nb);
4327 if (ret)
4328 pr_err("ADSPRPC: Get service location failed: %d\n",
4329 ret);
4330 }
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304331 if (of_property_read_bool(dev->of_node,
4332 "qcom,fastrpc-adsp-sensors-pdr")) {
4333 int session;
4334
4335 VERIFY(err, !fastrpc_get_adsp_session(
4336 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
4337 if (err)
4338 goto spdbail;
4339 me->channel[0].spd[session].get_service_nb.notifier_call =
4340 fastrpc_get_service_location_notify;
4341 ret = get_service_location(
4342 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME,
4343 SENSORS_PDR_ADSP_SERVICE_NAME,
4344 &me->channel[0].spd[session].get_service_nb);
4345 if (ret)
4346 pr_err("ADSPRPC: Get service location failed: %d\n",
4347 ret);
4348 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304349spdbail:
4350 err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004351 VERIFY(err, !of_platform_populate(pdev->dev.of_node,
4352 fastrpc_match_table,
4353 NULL, &pdev->dev));
4354 if (err)
4355 goto bail;
4356bail:
4357 return err;
4358}
4359
4360static void fastrpc_deinit(void)
4361{
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304362 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004363 struct fastrpc_channel_ctx *chan = gcinfo;
4364 int i, j;
4365
4366 for (i = 0; i < NUM_CHANNELS; i++, chan++) {
4367 if (chan->chan) {
4368 kref_put_mutex(&chan->kref,
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304369 fastrpc_channel_close, &me->smd_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05304370 chan->chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004371 }
4372 for (j = 0; j < NUM_SESSIONS; j++) {
4373 struct fastrpc_session_ctx *sess = &chan->session[j];
c_mtharue1a5ce12017-10-13 20:47:09 +05304374 if (sess->smmu.dev) {
4375 arm_iommu_detach_device(sess->smmu.dev);
4376 sess->smmu.dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004377 }
4378 if (sess->smmu.mapping) {
4379 arm_iommu_release_mapping(sess->smmu.mapping);
c_mtharue1a5ce12017-10-13 20:47:09 +05304380 sess->smmu.mapping = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004381 }
4382 }
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304383 kfree(chan->rhvm.vmid);
4384 kfree(chan->rhvm.vmperm);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004385 }
4386}
4387
4388static struct platform_driver fastrpc_driver = {
4389 .probe = fastrpc_probe,
4390 .driver = {
4391 .name = "fastrpc",
4392 .owner = THIS_MODULE,
4393 .of_match_table = fastrpc_match_table,
4394 },
4395};
4396
4397static int __init fastrpc_device_init(void)
4398{
4399 struct fastrpc_apps *me = &gfa;
c_mtharue1a5ce12017-10-13 20:47:09 +05304400 struct device *dev = NULL;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304401 struct device *secure_dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004402 int err = 0, i;
4403
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05304404 debugfs_root = debugfs_create_dir("adsprpc", NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004405 memset(me, 0, sizeof(*me));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004406 fastrpc_init(me);
4407 me->dev = NULL;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304408 me->glink = true;
zhaochenfc798572018-08-17 15:32:37 +08004409 me->secure_flag = false;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004410 VERIFY(err, 0 == platform_driver_register(&fastrpc_driver));
4411 if (err)
4412 goto register_bail;
4413 VERIFY(err, 0 == alloc_chrdev_region(&me->dev_no, 0, NUM_CHANNELS,
4414 DEVICE_NAME));
4415 if (err)
4416 goto alloc_chrdev_bail;
4417 cdev_init(&me->cdev, &fops);
4418 me->cdev.owner = THIS_MODULE;
4419 VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0),
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304420 NUM_DEVICES));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004421 if (err)
4422 goto cdev_init_bail;
4423 me->class = class_create(THIS_MODULE, "fastrpc");
4424 VERIFY(err, !IS_ERR(me->class));
4425 if (err)
4426 goto class_create_bail;
4427 me->compat = (fops.compat_ioctl == NULL) ? 0 : 1;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304428
4429 /*
4430 * Create devices and register with sysfs
4431 * Create first device with minor number 0
4432 */
Sathish Ambley36849af2017-02-02 09:35:55 -08004433 dev = device_create(me->class, NULL,
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304434 MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV),
4435 NULL, DEVICE_NAME);
Sathish Ambley36849af2017-02-02 09:35:55 -08004436 VERIFY(err, !IS_ERR_OR_NULL(dev));
4437 if (err)
4438 goto device_create_bail;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304439
4440 /* Create secure device with minor number for secure device */
4441 secure_dev = device_create(me->class, NULL,
4442 MKDEV(MAJOR(me->dev_no), MINOR_NUM_SECURE_DEV),
4443 NULL, DEVICE_NAME_SECURE);
4444 VERIFY(err, !IS_ERR_OR_NULL(secure_dev));
4445 if (err)
4446 goto device_create_bail;
4447
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004448 for (i = 0; i < NUM_CHANNELS; i++) {
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304449 me->channel[i].dev = secure_dev;
4450 if (i == CDSP_DOMAIN_ID)
4451 me->channel[i].dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004452 me->channel[i].ssrcount = 0;
4453 me->channel[i].prevssrcount = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05304454 me->channel[i].issubsystemup = 1;
4455 me->channel[i].ramdumpenabled = 0;
4456 me->channel[i].remoteheap_ramdump_dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004457 me->channel[i].nb.notifier_call = fastrpc_restart_notifier_cb;
4458 me->channel[i].handle = subsys_notif_register_notifier(
4459 gcinfo[i].subsys,
4460 &me->channel[i].nb);
4461 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004462 me->client = msm_ion_client_create(DEVICE_NAME);
4463 VERIFY(err, !IS_ERR_OR_NULL(me->client));
4464 if (err)
4465 goto device_create_bail;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05304466
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004467 return 0;
4468device_create_bail:
4469 for (i = 0; i < NUM_CHANNELS; i++) {
Sathish Ambley36849af2017-02-02 09:35:55 -08004470 if (me->channel[i].handle)
4471 subsys_notif_unregister_notifier(me->channel[i].handle,
4472 &me->channel[i].nb);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004473 }
Sathish Ambley36849af2017-02-02 09:35:55 -08004474 if (!IS_ERR_OR_NULL(dev))
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304475 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4476 MINOR_NUM_DEV));
4477 if (!IS_ERR_OR_NULL(secure_dev))
4478 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4479 MINOR_NUM_SECURE_DEV));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004480 class_destroy(me->class);
4481class_create_bail:
4482 cdev_del(&me->cdev);
4483cdev_init_bail:
4484 unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
4485alloc_chrdev_bail:
4486register_bail:
4487 fastrpc_deinit();
4488 return err;
4489}
4490
4491static void __exit fastrpc_device_exit(void)
4492{
4493 struct fastrpc_apps *me = &gfa;
4494 int i;
4495
4496 fastrpc_file_list_dtor(me);
4497 fastrpc_deinit();
4498 for (i = 0; i < NUM_CHANNELS; i++) {
4499 if (!gcinfo[i].name)
4500 continue;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004501 subsys_notif_unregister_notifier(me->channel[i].handle,
4502 &me->channel[i].nb);
4503 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304504
4505 /* Destroy the secure and non secure devices */
4506 device_destroy(me->class, MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV));
4507 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4508 MINOR_NUM_SECURE_DEV));
4509
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004510 class_destroy(me->class);
4511 cdev_del(&me->cdev);
4512 unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
4513 ion_client_destroy(me->client);
Sathish Ambley1ca68232017-01-19 10:32:55 -08004514 debugfs_remove_recursive(debugfs_root);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004515}
4516
4517late_initcall(fastrpc_device_init);
4518module_exit(fastrpc_device_exit);
4519
4520MODULE_LICENSE("GPL v2");